/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

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