PageRenderTime 527ms CodeModel.GetById 230ms app.highlight 111ms RepoModel.GetById 182ms app.codeStats 0ms

/src/away3d/entities/Sprite3D.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 291 lines | 234 code | 46 blank | 11 comment | 12 complexity | 7180cae526db1aeedf413235a5fb43d1 MD5 | raw file
  1package away3d.entities
  2{
  3	import away3d.animators.IAnimator;
  4	import away3d.arcane;
  5	import away3d.bounds.AxisAlignedBoundingBox;
  6	import away3d.bounds.BoundingVolumeBase;
  7	import away3d.cameras.Camera3D;
  8	import away3d.core.base.IRenderable;
  9	import away3d.core.base.SubGeometry;
 10	import away3d.core.base.SubMesh;
 11	import away3d.core.managers.Stage3DProxy;
 12	import away3d.core.math.Matrix3DUtils;
 13	import away3d.core.partition.EntityNode;
 14	import away3d.core.partition.RenderableNode;
 15	import away3d.core.pick.IPickingCollider;
 16	import away3d.materials.MaterialBase;
 17	
 18	import flash.display3D.IndexBuffer3D;
 19	import flash.geom.Matrix;
 20	import flash.geom.Matrix3D;
 21	import flash.geom.Vector3D;
 22	
 23	use namespace arcane;
 24	
 25	/**
 26	 * Sprite3D is a 3D billboard, a renderable rectangular area that is always aligned with the projection plane.
 27	 * As a result, no perspective transformation occurs on a Sprite3D object.
 28	 *
 29	 * todo: mvp generation or vertex shader code can be optimized
 30	 */
 31	public class Sprite3D extends Entity implements IRenderable
 32	{
 33		// TODO: Replace with CompactSubGeometry
 34		private static var _geometry:SubGeometry;
 35		//private static var _pickingSubMesh:SubGeometry;
 36		
 37		private var _material:MaterialBase;
 38		private var _spriteMatrix:Matrix3D;
 39		private var _animator:IAnimator;
 40		
 41		private var _pickingSubMesh:SubMesh;
 42		private var _pickingTransform:Matrix3D;
 43		private var _camera:Camera3D;
 44		
 45		private var _width:Number;
 46		private var _height:Number;
 47		private var _shadowCaster:Boolean = false;
 48		
 49		public function Sprite3D(material:MaterialBase, width:Number, height:Number)
 50		{
 51			super();
 52			this.material = material;
 53			_width = width;
 54			_height = height;
 55			_spriteMatrix = new Matrix3D();
 56			if (!_geometry) {
 57				_geometry = new SubGeometry();
 58				_geometry.updateVertexData(Vector.<Number>([-.5, .5, .0, .5, .5, .0, .5, -.5, .0, -.5, -.5, .0]));
 59				_geometry.updateUVData(Vector.<Number>([.0, .0, 1.0, .0, 1.0, 1.0, .0, 1.0]));
 60				_geometry.updateIndexData(Vector.<uint>([0, 1, 2, 0, 2, 3]));
 61				_geometry.updateVertexTangentData(Vector.<Number>([1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]));
 62				_geometry.updateVertexNormalData(Vector.<Number>([.0, .0, -1.0, .0, .0, -1.0, .0, .0, -1.0, .0, .0, -1.0]));
 63			}
 64		}
 65		
 66		override public function set pickingCollider(value:IPickingCollider):void
 67		{
 68			super.pickingCollider = value;
 69			if (value) { // bounds collider is the only null value
 70				_pickingSubMesh = new SubMesh(_geometry, null);
 71				_pickingTransform = new Matrix3D();
 72			}
 73		}
 74		
 75		public function get width():Number
 76		{
 77			return _width;
 78		}
 79		
 80		public function set width(value:Number):void
 81		{
 82			if (_width == value)
 83				return;
 84			_width = value;
 85			invalidateTransform();
 86		}
 87		
 88		public function get height():Number
 89		{
 90			return _height;
 91		}
 92		
 93		public function set height(value:Number):void
 94		{
 95			if (_height == value)
 96				return;
 97			_height = value;
 98			invalidateTransform();
 99		}
100		
101		public function activateVertexBuffer(index:int, stage3DProxy:Stage3DProxy):void
102		{
103			_geometry.activateVertexBuffer(index, stage3DProxy);
104		}
105		
106		public function activateUVBuffer(index:int, stage3DProxy:Stage3DProxy):void
107		{
108			_geometry.activateUVBuffer(index, stage3DProxy);
109		}
110		
111		public function activateSecondaryUVBuffer(index:int, stage3DProxy:Stage3DProxy):void
112		{
113			_geometry.activateSecondaryUVBuffer(index, stage3DProxy);
114		}
115		
116		public function activateVertexNormalBuffer(index:int, stage3DProxy:Stage3DProxy):void
117		{
118			_geometry.activateVertexNormalBuffer(index, stage3DProxy);
119		}
120		
121		public function activateVertexTangentBuffer(index:int, stage3DProxy:Stage3DProxy):void
122		{
123			_geometry.activateVertexTangentBuffer(index, stage3DProxy);
124		}
125		
126		public function getIndexBuffer(stage3DProxy:Stage3DProxy):IndexBuffer3D
127		{
128			return _geometry.getIndexBuffer(stage3DProxy);
129		}
130		
131		public function get numTriangles():uint
132		{
133			return 2;
134		}
135		
136		public function get sourceEntity():Entity
137		{
138			return this;
139		}
140		
141		public function get material():MaterialBase
142		{
143			return _material;
144		}
145		
146		public function set material(value:MaterialBase):void
147		{
148			if (value == _material)
149				return;
150			if (_material)
151				_material.removeOwner(this);
152			_material = value;
153			if (_material)
154				_material.addOwner(this);
155		}
156		
157		/**
158		 * Defines the animator of the mesh. Act on the mesh's geometry. Defaults to null
159		 */
160		public function get animator():IAnimator
161		{
162			return _animator;
163		}
164		
165		public function get castsShadows():Boolean
166		{
167			return _shadowCaster;
168		}
169		
170		override protected function getDefaultBoundingVolume():BoundingVolumeBase
171		{
172			return new AxisAlignedBoundingBox();
173		}
174		
175		override protected function updateBounds():void
176		{
177			_bounds.fromExtremes(-.5*_scaleX, -.5*_scaleY, -.5*_scaleZ, .5*_scaleX, .5*_scaleY, .5*_scaleZ);
178			_boundsInvalid = false;
179		}
180		
181		override protected function createEntityPartitionNode():EntityNode
182		{
183			return new RenderableNode(this);
184		}
185		
186		override protected function updateTransform():void
187		{
188			super.updateTransform();
189			_transform.prependScale(_width, _height, Math.max(_width, _height));
190		}
191		
192		public function get uvTransform():Matrix
193		{
194			return null;
195		}
196		
197		public function get vertexData():Vector.<Number>
198		{
199			return _geometry.vertexData;
200		}
201		
202		public function get indexData():Vector.<uint>
203		{
204			return _geometry.indexData;
205		}
206		
207		public function get UVData():Vector.<Number>
208		{
209			return _geometry.UVData;
210		}
211		
212		public function get numVertices():uint
213		{
214			return _geometry.numVertices;
215		}
216		
217		public function get vertexStride():uint
218		{
219			return _geometry.vertexStride;
220		}
221		
222		public function get vertexNormalData():Vector.<Number>
223		{
224			return _geometry.vertexNormalData;
225		}
226		
227		public function get vertexTangentData():Vector.<Number>
228		{
229			return _geometry.vertexTangentData;
230		}
231		
232		public function get vertexOffset():int
233		{
234			return _geometry.vertexOffset;
235		}
236		
237		public function get vertexNormalOffset():int
238		{
239			return _geometry.vertexNormalOffset;
240		}
241		
242		public function get vertexTangentOffset():int
243		{
244			return _geometry.vertexTangentOffset;
245		}
246		
247		override arcane function collidesBefore(shortestCollisionDistance:Number, findClosest:Boolean):Boolean
248		{
249			findClosest = findClosest;
250			var viewTransform:Matrix3D = _camera.inverseSceneTransform.clone();
251			viewTransform.transpose();
252			var rawViewTransform:Vector.<Number> = Matrix3DUtils.RAW_DATA_CONTAINER;
253			viewTransform.copyRawDataTo(rawViewTransform);
254			rawViewTransform[ 3  ] = 0;
255			rawViewTransform[ 7  ] = 0;
256			rawViewTransform[ 11 ] = 0;
257			rawViewTransform[ 12 ] = 0;
258			rawViewTransform[ 13 ] = 0;
259			rawViewTransform[ 14 ] = 0;
260			
261			_pickingTransform.copyRawDataFrom(rawViewTransform);
262			_pickingTransform.prependScale(_width, _height, Math.max(_width, _height));
263			_pickingTransform.appendTranslation(scenePosition.x, scenePosition.y, scenePosition.z);
264			_pickingTransform.invert();
265			
266			var localRayPosition:Vector3D = _pickingTransform.transformVector(_pickingCollisionVO.rayPosition);
267			var localRayDirection:Vector3D = _pickingTransform.deltaTransformVector(_pickingCollisionVO.rayDirection);
268			
269			_pickingCollider.setLocalRay(localRayPosition, localRayDirection);
270			
271			_pickingCollisionVO.renderable = null;
272			if (_pickingCollider.testSubMeshCollision(_pickingSubMesh, _pickingCollisionVO, shortestCollisionDistance))
273				_pickingCollisionVO.renderable = _pickingSubMesh;
274			
275			return _pickingCollisionVO.renderable != null;
276		}
277
278		public function getRenderSceneTransform(camera:Camera3D):Matrix3D
279		{
280			var comps:Vector.<Vector3D> = Matrix3DUtils.decompose(camera.sceneTransform);
281			var scale:Vector3D = comps[2];
282			comps[0].x = scenePosition.x;
283			comps[0].y = scenePosition.y;
284			comps[0].z = scenePosition.z;
285			scale.x = _width*_scaleX;
286			scale.y = _height*_scaleY;
287			_spriteMatrix.recompose(comps);
288			return _spriteMatrix;
289		}
290	}
291}