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;
}
}
}