package org.papervision3d.core.proto { import flash.events.EventDispatcher; import flash.utils.Dictionary; import org.papervision3d.core.geom.renderables.Triangle3D; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.core.math.AxisAlignedBoundingBox; import org.papervision3d.core.math.BoundingSphere; import org.papervision3d.core.math.Matrix3D; import org.papervision3d.objects.DisplayObject3D; /** * The GeometryObject3D class contains the mesh definition of an object. */ public class GeometryObject3D extends EventDispatcher { protected var _boundingSphere:BoundingSphere; protected var _boundingSphereDirty :Boolean = true; protected var _aabb:AxisAlignedBoundingBox; protected var _aabbDirty:Boolean = true; private var _numInstances:uint = 0; // TODO - pretty sure this is never used... obsolete? /** * */ public var dirty:Boolean; /** * An array of Face3D objects for the faces of the mesh. */ public var faces:Array; /** * An array of vertices. */ public var vertices :Array; public var _ready:Boolean = false; public function GeometryObject3D( ):void { dirty = true; } public function transformVertices(transformation:Matrix3D ):void { var m11 :Number = transformation.n11, m12 :Number = transformation.n12, m13 :Number = transformation.n13, m21 :Number = transformation.n21, m22 :Number = transformation.n22, m23 :Number = transformation.n23, m31 :Number = transformation.n31, m32 :Number = transformation.n32, m33 :Number = transformation.n33, m14 :Number = transformation.n14, m24 :Number = transformation.n24, m34 :Number = transformation.n34, i :int = vertices.length, vertex :org.papervision3d.core.geom.renderables.Vertex3D; while( vertex = vertices[--i] ) { // Center position var vx :Number = vertex.x; var vy :Number = vertex.y; var vz :Number = vertex.z; var tx :Number = vx * m11 + vy * m12 + vz * m13 + m14; var ty :Number = vx * m21 + vy * m22 + vz * m23 + m24; var tz :Number = vx * m31 + vy * m32 + vz * m33 + m34; vertex.x = tx; vertex.y = ty; vertex.z = tz; } } public function transformUV( material:MaterialObject3D ):void { if( material.bitmap ) for( var i:String in this.faces ) faces[i].transformUV( material ); } private function createVertexNormals():void { var tempVertices:Dictionary = new Dictionary(true); var face:Triangle3D; var vertex3D:Vertex3D; for each(face in faces){ face.v0.connectedFaces[face] = face; face.v1.connectedFaces[face] = face; face.v2.connectedFaces[face] = face; tempVertices[face.v0] = face.v0; tempVertices[face.v1] = face.v1; tempVertices[face.v2] = face.v2; } for each (vertex3D in tempVertices){ vertex3D.calculateNormal(); } } public function set ready(b:Boolean):void { if(b){ createVertexNormals(); this.dirty = false; } _ready = b; } public function get ready():Boolean { return _ready; } /** * Radius square of the mesh bounding sphere */ public function get boundingSphere():BoundingSphere { if( _boundingSphereDirty ){ _boundingSphere = BoundingSphere.getFromVertices(vertices); _boundingSphereDirty = false; } return _boundingSphere; } /** * Returns an axis aligned bounding box, not world oriented. * * @Author Ralph Hauwert - Added as an initial test. */ public function get aabb():AxisAlignedBoundingBox { if(_aabbDirty){ _aabb = AxisAlignedBoundingBox.createFromVertices(vertices); _aabbDirty = false; } return _aabb; } /** * Clones this object. * * @param parent * * @return The cloned GeometryObject3D. */ public function clone(parent:DisplayObject3D = null):GeometryObject3D { var materials:Dictionary = new Dictionary(true); var verts:Dictionary = new Dictionary(true); var geom:GeometryObject3D = new GeometryObject3D(); var i:int; geom.vertices = new Array(); geom.faces = new Array(); // clone vertices for(i = 0; i < this.vertices.length; i++) { var v:Vertex3D = this.vertices[i]; verts[ v ] = v.clone(); geom.vertices.push(verts[v]); } // clone triangles for(i = 0; i < this.faces.length; i++) { var f:Triangle3D = this.faces[i]; var v0:Vertex3D = verts[ f.v0 ]; var v1:Vertex3D = verts[ f.v1 ]; var v2:Vertex3D = verts[ f.v2 ]; geom.faces.push(new Triangle3D(parent, [v0, v1, v2], f.material, f.uv)); materials[ f.material ] = f.material; } for each(var material:MaterialObject3D in materials) material.registerObject(parent); return geom; } /** * Flips the winding of faces. */ public function flipFaces():void { for each(var f:Triangle3D in this.faces) { var tmp:Vertex3D = f.v0; f.v0 = f.v2; f.v2 = tmp; f.uv = [f.uv2, f.uv1, f.uv0]; f.createNormal(); } this.ready = true; } } }