package away3d.exporters { import flash.system.*; import away3d.core.base.Vertex; import away3d.core.base.UV; import away3d.core.base.Mesh; import away3d.core.base.Geometry; import away3d.core.base.Object3D; import away3d.containers.ObjectContainer3D; import away3d.core.base.Face; import away3d.core.math.Number3D; import away3d.arcane; import away3d.animators.utils.PathUtils; use namespace arcane; /** * Class ObjExporter generates a string in the WaveFront obj format representing the object3D(s). Paste to a texteditor and save as filename.obj. * */ public class ObjExporter { private var objString:String; private var gcount:int = 0; private var indV:int = 0; private var indVn:int = 0; private var indVt:int = 0; private var indF:int = 0; private var _scaling:Number; private var _righthanded:Boolean; private var nRotation:Number3D = new Number3D(); private function write(object3d:Object3D):void { var aV:Array = []; var aVn:Array = []; var aVt:Array = []; var aF:Array = []; objString +="\n"; var aFaces:Array = (object3d as Mesh).faces; var face:Face; var n0:Number3D; var n1:Number3D; var n2:Number3D; var geometry:Geometry = (object3d as Mesh).geometry; var va:int; var vb:int; var vc:int; var vta:int; var vtb:int; var vtc:int; var na:int; var nb:int; var nc:int; nRotation.x = object3d.rotationX; nRotation.y = object3d.rotationY; nRotation.z = object3d.rotationZ; var nPos:Number3D = object3d.scenePosition; var tmp:Number3D = new Number3D(); var j:int; var aRef:Array = [vc, vb, va]; for(var i:int = 0; i-1;--j){ tmp.x = (face["v"+j].x + nPos.x) *_scaling; tmp.y = (face["v"+j].y + nPos.y) *_scaling; tmp.z = (face["v"+j].z + nPos.z) *_scaling; tmp = PathUtils.rotatePoint(tmp, nRotation); if(_righthanded){ //will add Y up var //tmp.y *= -1; tmp.x *= -1; tmp.z *= -1; } aRef[j] = checkDoubles( aV, ("v "+tmp.x.toFixed(10)+" "+tmp.y.toFixed(10)+" "+tmp.z.toFixed(10)+"\n") ); } vta = checkDoubles( aVt, ("vt "+(_righthanded? 1-face.uv2.u : face.uv2.u)+" "+(_righthanded? face.uv2.v : 1-face.uv2.v)+"\n")); vtb = checkDoubles( aVt, ("vt "+(_righthanded? 1-face.uv1.u : face.uv1.u)+" "+(_righthanded? face.uv1.v : 1-face.uv1.v)+"\n")); vtc = checkDoubles( aVt, ("vt "+(_righthanded? 1-face.uv0.u : face.uv0.u)+" "+(_righthanded? face.uv0.v : 1-face.uv0.v)+"\n")); n0 = geometry.getVertexNormal(face.v0); n1 = geometry.getVertexNormal(face.v1); n2 = geometry.getVertexNormal(face.v2); na = checkDoubles( aVn, ("vn "+n2.x.toFixed(15)+" "+n2.y.toFixed(15)+" "+n2.z.toFixed(15)+"\n") ); nb = checkDoubles( aVn, ("vn "+n1.x.toFixed(15)+" "+n1.y.toFixed(15)+" "+n1.z.toFixed(15)+"\n") ); nc = checkDoubles( aVn, ("vn "+n0.x.toFixed(15)+" "+n0.y.toFixed(15)+" "+n0.z.toFixed(15)+"\n") ); aF.push("f "+(aRef[2]+indV)+"/"+(vta+indVt)+"/"+(na+indVn)+" "+(aRef[1]+indV)+"/"+(vtb+indVt)+"/"+(nb+indVn)+" "+(aRef[0]+indV)+"/"+(vtc+indVt)+"/"+(nc+indVn)+"\n"); } indV += aV.length; indVn += aVn.length; indVt += aVt.length; indF += aF.length; objString += "# Number of vertices: "+aV.length+"\n"; for( i = 0; i < aV.length ; ++i){ objString += aV[i]; } objString += "\n# Number of Normals: "+aVn.length+"\n"; for( i = 0; i < aVn.length ; ++i){ objString += aVn[i]; } objString += "\n# Number of Texture Vertices: "+aVt.length+"\n"; for( i = 0; i < aVt.length ; ++i){ objString += aVt[i]; } objString += "\n# Number of Polygons: "+aF.length+"\n"; for( i = 0; i < aF.length ; ++i){ objString += aF[i]; } } private function checkDoubles(arr:Array, string:String):int { for(var i:int = 0;i