?? max3ds.as
字號:
package org.papervision3d.objects.parsers{ import flash.events.Event; import flash.events.IOErrorEvent; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.utils.ByteArray; import flash.utils.Endian; import org.papervision3d.core.geom.TriangleMesh3D; import org.papervision3d.core.geom.renderables.Triangle3D; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.core.math.NumberUV; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.events.FileLoadEvent; import org.papervision3d.materials.BitmapFileMaterial; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.DisplayObject3D; /** * 3DS File parser. * * @author Tim Knip (based on Away3D's Max3DS class : http://away3d.com) */ public class Max3DS extends DisplayObject3D { /** */ public var filename:String; /** * Constuctor * * @param name */ public function Max3DS(name:String=null) { super(name); _textureExtensionReplacements = new Object(); } /** * Load. * * @param asset * @param materials * @param textureDir */ public function load(asset:*, materials:MaterialsList=null, textureDir:String="./image/"):void { this.materials = materials || new MaterialsList(); _textureDir = textureDir || _textureDir; if(asset is ByteArray) { this.filename = "NoName.3ds"; parse(ByteArray(asset)); } else if(asset is String) { this.filename = String(asset); var loader:URLLoader = new URLLoader(); loader.dataFormat = URLLoaderDataFormat.BINARY; loader.addEventListener(Event.COMPLETE, onFileLoadComplete); loader.addEventListener(IOErrorEvent.IO_ERROR, onFileLoadError); loader.load(new URLRequest(this.filename)); } else throw new Error("Need String or ByteArray!"); } /** * Replaces a texture extension with an alternative extension. * * @param originalExtension For example "bmp", "gif", etc * @param preferredExtension For example "png" */ public function replaceTextureExtension(originalExtension:String, preferredExtension:String="png"):void { _textureExtensionReplacements[originalExtension] = preferredExtension; } /** * Build a mesh * * @param meshData */ private function buildMesh(meshData:MeshData):void { var i:int; var mesh:TriangleMesh3D = new TriangleMesh3D(null, meshData.vertices, [], meshData.name); for(i = 0; i < meshData.faces.length; i++) { var f:Array = meshData.faces[i]; var v0:Vertex3D = mesh.geometry.vertices[f[0]]; var v1:Vertex3D = mesh.geometry.vertices[f[1]]; var v2:Vertex3D = mesh.geometry.vertices[f[2]]; var hasUV:Boolean = (meshData.uvs.length == meshData.vertices.length); var t0:NumberUV = hasUV ? meshData.uvs[f[0]] : new NumberUV(); var t1:NumberUV = hasUV ? meshData.uvs[f[1]] : new NumberUV(); var t2:NumberUV = hasUV ? meshData.uvs[f[2]] : new NumberUV(); mesh.geometry.faces.push(new Triangle3D(mesh, [v0, v1, v2], null, [t0, t1, t2])); } for(i = 0; i < meshData.materials.length; i++) { var mat:MaterialData = meshData.materials[i]; var material:MaterialObject3D = this.materials.getMaterialByName(mat.name) || MaterialObject3D.DEFAULT; for(var j:int = 0; j < mat.faces.length; j++) { var faceIdx:int = mat.faces[j]; var tri:Triangle3D = mesh.geometry.faces[faceIdx]; tri.material = material; } } mesh.geometry.ready = true; mesh.rotationX = 90; mesh.rotationY = 180; addChild(mesh); } /** * * @param event */ private function onFileLoadComplete(event:Event=null):void { var loader:URLLoader = event.target as URLLoader; parse(ByteArray(loader.data)); } /** * * @param event */ private function onFileLoadError(event:IOErrorEvent):void { dispatchEvent(new FileLoadEvent(FileLoadEvent.LOAD_ERROR, this.filename)); } /** * Parse. * * @param data */ private function parse(data:ByteArray):void { if(!data) throw new Error("Invalid ByteArray!"); _data = data; _data.endian = Endian.LITTLE_ENDIAN; _data.position = 0; //first chunk is always the primary, so we simply read it and parse it var chunk:Chunk3ds = new Chunk3ds(); readChunk(chunk); parse3DS(chunk); dispatchEvent(new FileLoadEvent(FileLoadEvent.LOAD_COMPLETE, this.filename)); } /** * Read the base 3DS object. * * @param chunk * */ private function parse3DS(chunk:Chunk3ds):void { while (chunk.bytesRead < chunk.length) { var subChunk:Chunk3ds = new Chunk3ds(); readChunk(subChunk); switch (subChunk.id) { case EDIT3DS: parseEdit3DS(subChunk); break; case KEYF3DS: skipChunk(subChunk); break; default: skipChunk(subChunk); } chunk.bytesRead += subChunk.length; } } /** * Read the Edit chunk * * @param chunk */ private function parseEdit3DS(chunk:Chunk3ds):void { while (chunk.bytesRead < chunk.length) { var subChunk:Chunk3ds = new Chunk3ds(); readChunk(subChunk); switch (subChunk.id) { case MATERIAL: parseMaterial(subChunk); //skipChunk(subChunk); break; case MESH: var meshData:MeshData = new MeshData(); meshData.name = readASCIIZString(_data); subChunk.bytesRead += meshData.name.length + 1; meshData.vertices = new Array(); meshData.faces = new Array(); meshData.uvs = new Array(); meshData.materials = new Array(); parseMesh(subChunk, meshData); buildMesh(meshData); break; default: skipChunk(subChunk); } chunk.bytesRead += subChunk.length; } } /** * Read a material chunk. * * @param chunk */ private function parseMaterial(chunk:Chunk3ds):String { var ret:String = null; var mat:Object = new Object(); var subChunk:Chunk3ds = new Chunk3ds(); var colorChunk:Chunk3ds = new Chunk3ds(); mat.textures = new Array(); while (chunk.bytesRead < chunk.length) { readChunk(subChunk); var p:uint = 0; switch(subChunk.id) { case MAT_NAME: mat.name = readASCIIZString(_data); //trace(mat.name); subChunk.bytesRead = subChunk.length; break; case MAT_AMBIENT: p = _data.position; readChunk(colorChunk); mat.ambient = readColor(colorChunk); _data.position = p + colorChunk.length; //trace("ambient:"+mat.ambient.toString(16)); break; case MAT_DIFFUSE: p = _data.position; readChunk(colorChunk); mat.diffuse = readColor(colorChunk); _data.position = p + colorChunk.length; //trace("diffuse:"+mat.diffuse.toString(16)); break; case MAT_SPECULAR: p = _data.position; readChunk(colorChunk); mat.specular = readColor(colorChunk); _data.position = p + colorChunk.length; //trace("specular:"+mat.specular.toString(16)); break; case MAT_TEXMAP: mat.textures.push(parseMaterial(subChunk)); break; case MAT_TEXFLNM: ret = readASCIIZString(_data); subChunk.bytesRead = subChunk.length; break; default: skipChunk(subChunk); } chunk.bytesRead += subChunk.length; } if(mat.name && !this.materials.getMaterialByName(mat.name)) { if(mat.textures.length) { var bitmap:String = mat.textures[0].toLowerCase(); for(var ext:String in _textureExtensionReplacements) { if(bitmap.indexOf("."+ext) == -1) continue; var pattern:RegExp = new RegExp("\."+ext, "i"); bitmap = bitmap.replace(pattern, "."+_textureExtensionReplacements[ext]); } this.materials.addMaterial(new BitmapFileMaterial(_textureDir+bitmap), mat.name); } else if(mat.diffuse) { this.materials.addMaterial(new ColorMaterial(mat.diffuse), mat.name); } } return ret; } private function parseMesh(chunk:Chunk3ds, meshData:MeshData):void {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -