obj文件格式
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# 创建的文件:04.06.2012 11:16:43
mtllib aa.mtl
#
# object Box001
#
v -14.0142 -4.2691 13.9796
v 13.5541 -4.2691 13.9796
v -14.0142 -4.2691 -13.5887
v 13.5541 -4.2691 -13.5887
v -14.0142 23.2992 13.9796
v 13.5541 23.2992 13.9796
v -14.0142 23.2992 -13.5887
v 13.5541 23.2992 -13.5887
# 8 vertices
vt 1.0000 0.0000 0.0000
vt 1.0000 1.0000 0.0000
vt 0.0000 1.0000 0.0000
vt 0.0000 0.0000 0.0000
# 4 texture coords
g Box001
usemtl Material__25
f 1/1 3/2 4/3
f 4/3 2/4 1/1
f 5/4 6/1 8/2
f 8/2 7/3 5/4
f 1/4 2/1 6/2
f 6/2 5/3 1/4
f 2/4 4/1 8/2
f 8/2 6/3 2/4
f 4/4 3/1 7/2
f 7/2 8/3 4/4
f 3/4 1/1 5/2
f 5/2 7/3 3/4
# 12 faces
上面的数据都不可直接使用,
v 代表顶点 vt代表贴图 两个都可以当作哈希表,
f /前面为索引 /后面为贴图,
顶点和贴图根据f参数查找前面的表生成一份数据,
索引为f的个数.文件解析类
package { import flash.display3D.Context3D; import flash.display3D.IndexBuffer3D; import flash.display3D.VertexBuffer3D; import flash.utils.ByteArray; /** * @author:Gaara * 2012-6-2 * * Obj文件解析类 **/ public class ObjParser { /** 换行 分隔符 **/ private var NEWLINE:String = "\r\n"; /** 参数 分隔符 **/ private var SEPARATION:String = " "; /** 顶点标志 **/ private var VERTEX:String = "v"; /** 贴图标志 **/ private var TEXTURE:String = "vt"; /** 面标志 **/ private var FACE:String = "f"; private var context3D:Context3D; /** 顶点数据 **/ private var vertices:Vector.<Number>; /** 贴图基础数据 **/ private var texturesBase:Vector.<Number>; /** 索引数据 **/ private var indexs:Vector.<uint>; /** 贴图数据数据 **/ private var textures:Vector.<int>; /** 返回的数据 **/ private var vertexBuff3D:VertexBuffer3D; private var indexBuff3D:IndexBuffer3D; private var uvBuff3D:VertexBuffer3D; public function ObjParser(objClass:Class,context3D:Context3D) { this.context3D = context3D; var obj:ByteArray = new objClass; var contentStr:String = obj.readUTFBytes(obj.length); vertices = new Vector.<Number>; texturesBase = new Vector.<Number>; indexs = new Vector.<uint>; textures = new Vector.<int>; var conArr:Array = contentStr.split(NEWLINE); handleStrArr(conArr); } /** * 功能:处理字符串数组 * 参数: **/ private function handleStrArr(strArr:Array):void { for each (var str:String in strArr) { var preStr:String = str.split(" ")[0]; if(preStr == VERTEX){ vertexTexturesHandle(str,vertices); } else if(preStr == TEXTURE){ vertexTexturesHandle(str,texturesBase); } else if(preStr == FACE){ faceHandle(str); } } trace("obj解析完成"); } /** * 功能:添加顶点函数 * 参数: **/ private function vertexTexturesHandle(content:String,vec:Vector.<Number>):void { var strArr:Array = content.split(SEPARATION); for each (var str:String in strArr) { if(str != VERTEX && str != TEXTURE && str !=""){ vec.push(Number(str)); } } } /** * 功能:添加三角形数据函数 * 参数: **/ private function faceHandle(content:String):void { var strArr:Array = content.split(SEPARATION); var tempArr:Array; for each (var str:String in strArr) { if(str != FACE && str !=""){ tempArr = str.split("\/"); indexs.push(tempArr[0]-1); textures.push(tempArr[1]-1); } } } /** * 功能:返回顶点数据 * 参数: **/ public function get positionsBuffer():VertexBuffer3D { if(vertexBuff3D != null){ return vertexBuff3D; } var positionBuffer:Vector.<Number> = new Vector.<Number>; for each (var i:int in indexs) { positionBuffer.push(vertices[i*3],vertices[i*3+1],vertices[i*3+2]); } var vertexCount:uint = positionBuffer.length/3; vertexBuff3D = context3D.createVertexBuffer(vertexCount,3); vertexBuff3D.uploadFromVector(positionBuffer,0,vertexCount); return vertexBuff3D; } /** * 功能:索引 * 参数: **/ public function get indexBuffer():IndexBuffer3D { if(indexBuff3D){ return indexBuff3D; } var indexBufferVec:Vector.<uint> = new Vector.<uint>; for (var i:int = 0; i < indexs.length; i++) { indexBufferVec.push(i); } indexBuff3D = context3D.createIndexBuffer(indexBufferVec.length); indexBuff3D.uploadFromVector(indexBufferVec,0,indexBufferVec.length); return indexBuff3D; } /** * 功能:贴图数据 * 参数: **/ public function get uvBuffer():VertexBuffer3D { if(uvBuff3D){ return uvBuff3D; } var uvBufferVec:Vector.<Number> = new Vector.<Number>; for each (var i:int in textures) { uvBufferVec.push(1-texturesBase[i*3],1-texturesBase[i*3+1]); } var uvsCount:uint = uvBufferVec.length/2; uvBuff3D = context3D.createVertexBuffer(uvsCount,2); uvBuff3D.uploadFromVector(uvBufferVec,0,uvsCount); return uvBuff3D; } } }