📄 md2.as
字号:
/*
* PAPER ON ERVIS NPAPER ISION PE IS ON PERVI IO APER SI PA
* AP VI ONPA RV IO PA SI PA ER SI NP PE ON AP VI ION AP
* PERVI ON PE VISIO APER IONPA RV IO PA RVIS NP PE IS ONPAPE
* ER NPAPER IS PE ON PE ISIO AP IO PA ER SI NP PER
* RV PA RV SI ERVISI NP ER IO PE VISIO AP VISI PA RV3D
* ______________________________________________________________________
* papervision3d.org + blog.papervision3d.org + osflash.org/papervision3d
*
* Copyright 2006 (c) Carlos Ulloa Matesanz, noventaynueve.com.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package org.papervision3d.objects.parsers
{
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.utils.Endian;
import org.papervision3d.animation.controllers.MorphController;
import org.papervision3d.animation.controllers.SimpleController;
import org.papervision3d.animation.core.AnimationEngine;
import org.papervision3d.events.AnimationEvent;
import org.papervision3d.Papervision3D;
import org.papervision3d.animation.core.AnimationFrame;
import org.papervision3d.core.*;
import org.papervision3d.core.geom.AnimatedMesh3D;
import org.papervision3d.core.geom.renderables.*;
import org.papervision3d.core.proto.MaterialObject3D;
/**
* Loades Quake 2 MD2 file with animation!
* </p>
* Please feel free to use, but please mention me!
* </p>
* @author Philippe Ajoux (philippe.ajoux@gmail.com) adapted by Tim Knip(tim.knip at gmail.com).
* @website www.d3s.net
* @version 04.11.07:11:56
*/
public class MD2 extends AnimatedMesh3D
{
/**
* Variables used in the loading of the file
*/
private var file:String;
private var loader:URLLoader;
private var loadScale:Number;
/**
* MD2 Header data
* These are all the variables found in the md2_header_t
* C style struct that starts every MD2 file.
*/
private var ident:int, version:int;
private var skinwidth:int, skinheight:int;
private var framesize:int;
private var num_skins:int, num_vertices:int, num_st:int;
private var num_tris:int, num_glcmds:int, num_frames:int;
private var offset_skins:int, offset_st:int, offset_tris:int;
private var offset_frames:int, offset_glcmds:int, offset_end:int;
private var fps:int;
/**
* <p>MD2 class lets you load a Quake 2 MD2 file with animation!</p>
*/
public function MD2(material:MaterialObject3D, filename:String, fps:int = 6, scale:Number = 1, initObject:Object = null)
{
super(material, new Array(), new Array());
this.loadScale = scale;
this.file = filename;
this.fps = Math.min(fps, 1000/AnimationEngine.TICK);
this.visible = false;
load(filename);
}
/**
* Mirrored from Ase, Wavefron, and Max3DS
*/
private function load(filename:String):void
{
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, parse);
loader.addEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
try
{
loader.load(new URLRequest(filename));
}
catch(e:Error)
{
Papervision3D.log("error in loading MD2 file (" + filename + ")");
}
}
/**
* Parse the MD2 file. This is actually pretty straight forward.
* Only complicated parts (bit convoluded) are the frame loading
* and "metaface" loading. Hey, it works, use it =)
*/
private function parse(event:Event):void
{
var i:int, j:int, uvs:Array = new Array();
var data:ByteArray = loader.data;
var metaface:Object;
data.endian = Endian.LITTLE_ENDIAN;
// Read the header and make sure it is valid MD2 file
readMd2Header(data);
if (ident != 844121161 || version != 8)
throw new Error("error loading MD2 file (" + file + "): Not a valid MD2 file/bad version");
//---Vertice setup
// be sure to allocate memory for the vertices to the object
for (i = 0; i < num_vertices; i++)
geometry.vertices.push(new Vertex3D());
//---UV coordinates
data.position = offset_st;
for (i = 0; i < num_st; i++)
{
var uv:NumberUV = new NumberUV(data.readShort() / skinwidth, data.readShort() / skinheight);
//uv.u = 1 - uv.u;
uv.v = 1 - uv.v;
uvs.push(uv);
}
//---Frame animation data
data.position = offset_frames;
readFrames(data);
//---Faces
// make sure to push the faces with allocated vertices to the object!
data.position = offset_tris;
for (i = 0; i < num_tris; i++)
{
metaface = {a: data.readUnsignedShort(), b: data.readUnsignedShort(), c: data.readUnsignedShort(),
ta: data.readUnsignedShort(), tb: data.readUnsignedShort(), tc: data.readUnsignedShort()};
var v0:Vertex3D = geometry.vertices[metaface.a];
var v1:Vertex3D = geometry.vertices[metaface.b];
var v2:Vertex3D = geometry.vertices[metaface.c];
var uv0:NumberUV = uvs[metaface.ta];
var uv1:NumberUV = uvs[metaface.tb];
var uv2:NumberUV = uvs[metaface.tc];
geometry.faces.push(new Triangle3D(this, [v0, v1, v2], material, [uv0, uv1, uv2]));
}
geometry.ready = true;
loader.close();
visible = true;
Papervision3D.log("Parsed MD2: " + file + "\n vertices:" +
geometry.vertices.length + "\n texture vertices:" + uvs.length +
"\n faces:" + geometry.faces.length + "\n frames: " );
dispatchEvent(new Event(Event.COMPLETE));
}
/**
* Reads in all the frames
*/
private function readFrames(data:ByteArray):void
{
var sx:Number, sy:Number, sz:Number;
var tx:Number, ty:Number, tz:Number;
var verts:Array, frame:AnimationFrame;
var i:int, j:int, char:int;
var engineFPS:Number = 1000 / AnimationEngine.TICK;
var duration:uint = Math.floor(engineFPS / this.fps);
var controller:MorphController = new MorphController( this.geometry );
var t:uint = 0;
for (i = 0; i < num_frames; i++, t += duration)
{
frame = new AnimationFrame(t, duration);
sx = data.readFloat();
sy = data.readFloat();
sz = data.readFloat();
tx = data.readFloat();
ty = data.readFloat();
tz = data.readFloat();
for (j = 0; j < 16; j++)
if ((char = data.readUnsignedByte()) != 0)
frame.name += String.fromCharCode(char);
// Note, the extra data.position++ in the for loop is there
// to skip over a byte that holds the "vertex normal index"
for (j = 0; j < num_vertices; j++, data.position++)
{
var v:Vertex3D = new Vertex3D(
((sx * data.readUnsignedByte()) + tx) * loadScale,
((sy * data.readUnsignedByte()) + ty) * loadScale,
((sz * data.readUnsignedByte()) + tz) * loadScale);
if( i == 1 )
{
this.geometry.vertices[j].x = v.x;
this.geometry.vertices[j].y = v.y;
this.geometry.vertices[j].z = v.z;
}
frame.values.push(v);
}
controller.addFrame( frame );
}
this.addController(controller);
}
/**
* Reads in all that MD2 Header data that is declared as private variables.
* I know its a lot, and it looks ugly, but only way to do it in Flash
*/
private function readMd2Header(data:ByteArray):void
{
ident = data.readInt();
version = data.readInt();
skinwidth = data.readInt();
skinheight = data.readInt();
framesize = data.readInt();
num_skins = data.readInt();
num_vertices = data.readInt();
num_st = data.readInt();
num_tris = data.readInt();
num_glcmds = data.readInt();
num_frames = data.readInt();
offset_skins = data.readInt();
offset_st = data.readInt();
offset_tris = data.readInt();
offset_frames = data.readInt();
offset_glcmds = data.readInt();
offset_end = data.readInt();
}
/**
*
* @param event
* @return
*/
private function loadProgressHandler( event:ProgressEvent ):void
{
dispatchEvent(event);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -