/src/away3d/bounds/BoundingVolumeBase.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 351 lines · 228 code · 36 blank · 87 comment · 29 complexity · f86ffc13b8d160d7dec0417071bd51ab MD5 · raw file

  1. package away3d.bounds
  2. {
  3. import away3d.arcane;
  4. import away3d.core.base.*;
  5. import away3d.core.math.Plane3D;
  6. import away3d.errors.*;
  7. import away3d.primitives.*;
  8. import flash.geom.*;
  9. use namespace arcane;
  10. /**
  11. * An abstract base class for all bounding volume classes. It should not be instantiated directly.
  12. */
  13. public class BoundingVolumeBase
  14. {
  15. protected var _min:Vector3D;
  16. protected var _max:Vector3D;
  17. protected var _aabbPoints:Vector.<Number> = new Vector.<Number>();
  18. protected var _aabbPointsDirty:Boolean = true;
  19. protected var _boundingRenderable:WireframePrimitiveBase;
  20. /**
  21. * The maximum extreme of the bounds
  22. */
  23. public function get max():Vector3D
  24. {
  25. return _max;
  26. }
  27. /**
  28. * The minimum extreme of the bounds
  29. */
  30. public function get min():Vector3D
  31. {
  32. return _min;
  33. }
  34. /**
  35. * Returns a vector of values representing the concatenated cartesian triplet of the 8 axial extremities of the bounding volume.
  36. */
  37. public function get aabbPoints():Vector.<Number>
  38. {
  39. if (_aabbPointsDirty)
  40. updateAABBPoints();
  41. return _aabbPoints;
  42. }
  43. /**
  44. * Returns the bounding renderable object for the bounding volume, in cases where the showBounds
  45. * property of the entity is set to true.
  46. *
  47. * @see away3d.entities.Entity#showBounds
  48. */
  49. public function get boundingRenderable():WireframePrimitiveBase
  50. {
  51. if (!_boundingRenderable) {
  52. _boundingRenderable = createBoundingRenderable();
  53. updateBoundingRenderable();
  54. }
  55. return _boundingRenderable;
  56. }
  57. /**
  58. * Creates a new <code>BoundingVolumeBase</code> object
  59. */
  60. public function BoundingVolumeBase()
  61. {
  62. _min = new Vector3D();
  63. _max = new Vector3D();
  64. }
  65. /**
  66. * Sets the bounds to zero size.
  67. */
  68. public function nullify():void
  69. {
  70. _min.x = _min.y = _min.z = 0;
  71. _max.x = _max.y = _max.z = 0;
  72. _aabbPointsDirty = true;
  73. if (_boundingRenderable)
  74. updateBoundingRenderable();
  75. }
  76. /**
  77. * Disposes of the bounds renderable object. Used to clear memory after a bounds rendeable is no longer required.
  78. */
  79. public function disposeRenderable():void
  80. {
  81. if (_boundingRenderable)
  82. _boundingRenderable.dispose();
  83. _boundingRenderable = null;
  84. }
  85. /**
  86. * Updates the bounds to fit a list of vertices
  87. *
  88. * @param vertices A Vector.&lt;Number&gt; of vertex data to be bounded.
  89. */
  90. public function fromVertices(vertices:Vector.<Number>):void
  91. {
  92. var i:uint;
  93. var len:uint = vertices.length;
  94. var minX:Number, minY:Number, minZ:Number;
  95. var maxX:Number, maxY:Number, maxZ:Number;
  96. if (len == 0) {
  97. nullify();
  98. return;
  99. }
  100. var v:Number;
  101. minX = maxX = vertices[uint(i++)];
  102. minY = maxY = vertices[uint(i++)];
  103. minZ = maxZ = vertices[uint(i++)];
  104. while (i < len) {
  105. v = vertices[i++];
  106. if (v < minX)
  107. minX = v;
  108. else if (v > maxX)
  109. maxX = v;
  110. v = vertices[i++];
  111. if (v < minY)
  112. minY = v;
  113. else if (v > maxY)
  114. maxY = v;
  115. v = vertices[i++];
  116. if (v < minZ)
  117. minZ = v;
  118. else if (v > maxZ)
  119. maxZ = v;
  120. }
  121. fromExtremes(minX, minY, minZ, maxX, maxY, maxZ);
  122. }
  123. /**
  124. * Updates the bounds to fit a Geometry object.
  125. *
  126. * @param geometry The Geometry object to be bounded.
  127. */
  128. public function fromGeometry(geometry:Geometry):void
  129. {
  130. var subGeoms:Vector.<ISubGeometry> = geometry.subGeometries;
  131. var numSubGeoms:uint = subGeoms.length;
  132. var minX:Number, minY:Number, minZ:Number;
  133. var maxX:Number, maxY:Number, maxZ:Number;
  134. if (numSubGeoms > 0) {
  135. var subGeom:ISubGeometry = subGeoms[0];
  136. var vertices:Vector.<Number> = subGeom.vertexData;
  137. var i:uint = subGeom.vertexOffset;
  138. minX = maxX = vertices[i];
  139. minY = maxY = vertices[i + 1];
  140. minZ = maxZ = vertices[i + 2];
  141. var j:uint = 0;
  142. while (j < numSubGeoms) {
  143. subGeom = subGeoms[j++];
  144. vertices = subGeom.vertexData;
  145. var vertexDataLen:uint = vertices.length;
  146. i = subGeom.vertexOffset;
  147. var stride:uint = subGeom.vertexStride;
  148. while (i < vertexDataLen) {
  149. var v:Number = vertices[i];
  150. if (v < minX)
  151. minX = v;
  152. else if (v > maxX)
  153. maxX = v;
  154. v = vertices[i + 1];
  155. if (v < minY)
  156. minY = v;
  157. else if (v > maxY)
  158. maxY = v;
  159. v = vertices[i + 2];
  160. if (v < minZ)
  161. minZ = v;
  162. else if (v > maxZ)
  163. maxZ = v;
  164. i += stride;
  165. }
  166. }
  167. fromExtremes(minX, minY, minZ, maxX, maxY, maxZ);
  168. } else
  169. fromExtremes(0, 0, 0, 0, 0, 0);
  170. }
  171. /**
  172. * Sets the bound to fit a given sphere.
  173. *
  174. * @param center The center of the sphere to be bounded
  175. * @param radius The radius of the sphere to be bounded
  176. */
  177. public function fromSphere(center:Vector3D, radius:Number):void
  178. {
  179. // this is BETTER overridden, because most volumes will have shortcuts for this
  180. // but then again, sphere already overrides it, and if we'd call "fromSphere", it'd probably need a sphere bound anyway
  181. fromExtremes(center.x - radius, center.y - radius, center.z - radius, center.x + radius, center.y + radius, center.z + radius);
  182. }
  183. /**
  184. * Sets the bounds to the given extrema.
  185. *
  186. * @param minX The minimum x value of the bounds
  187. * @param minY The minimum y value of the bounds
  188. * @param minZ The minimum z value of the bounds
  189. * @param maxX The maximum x value of the bounds
  190. * @param maxY The maximum y value of the bounds
  191. * @param maxZ The maximum z value of the bounds
  192. */
  193. public function fromExtremes(minX:Number, minY:Number, minZ:Number, maxX:Number, maxY:Number, maxZ:Number):void
  194. {
  195. _min.x = minX;
  196. _min.y = minY;
  197. _min.z = minZ;
  198. _max.x = maxX;
  199. _max.y = maxY;
  200. _max.z = maxZ;
  201. _aabbPointsDirty = true;
  202. if (_boundingRenderable)
  203. updateBoundingRenderable();
  204. }
  205. /**
  206. * Tests if the bounds are in the camera frustum.
  207. *
  208. * @param mvpMatrix The model view projection matrix for the object to which this bounding box belongs.
  209. * @return True if the bounding box is at least partially inside the frustum
  210. */
  211. public function isInFrustum(planes:Vector.<Plane3D>, numPlanes:int):Boolean
  212. {
  213. throw new AbstractMethodError();
  214. }
  215. /**
  216. * Tests if the bounds overlap other bounds, treating both bounds as AABBs.
  217. */
  218. public function overlaps(bounds:BoundingVolumeBase):Boolean
  219. {
  220. var min:Vector3D = bounds._min;
  221. var max:Vector3D = bounds._max;
  222. return _max.x > min.x &&
  223. _min.x < max.x &&
  224. _max.y > min.y &&
  225. _min.y < max.y &&
  226. _max.z > min.z &&
  227. _min.z < max.z;
  228. }
  229. /*public function classifyAgainstPlane(plane : Plane3D) : int
  230. {
  231. throw new AbstractMethodError();
  232. return -1;
  233. }*/
  234. /**
  235. * Clones the current BoundingVolume object
  236. * @return An exact duplicate of this object
  237. */
  238. public function clone():BoundingVolumeBase
  239. {
  240. throw new AbstractMethodError();
  241. }
  242. /**
  243. * Method for calculating whether an intersection of the given ray occurs with the bounding volume.
  244. *
  245. * @param position The starting position of the casting ray in local coordinates.
  246. * @param direction A unit vector representing the direction of the casting ray in local coordinates.
  247. * @param targetNormal The vector to store the bounds' normal at the point of collision
  248. * @return A Boolean value representing the detection of an intersection.
  249. */
  250. public function rayIntersection(position:Vector3D, direction:Vector3D, targetNormal:Vector3D):Number
  251. {
  252. position = position;
  253. direction = direction;
  254. targetNormal = targetNormal;
  255. return -1;
  256. }
  257. /**
  258. * Method for calculating whether the given position is contained within the bounding volume.
  259. *
  260. * @param position The position in local coordinates to be checked.
  261. * @return A Boolean value representing the detection of a contained position.
  262. */
  263. public function containsPoint(position:Vector3D):Boolean
  264. {
  265. position = position;
  266. return false;
  267. }
  268. protected function updateAABBPoints():void
  269. {
  270. var maxX:Number = _max.x, maxY:Number = _max.y, maxZ:Number = _max.z;
  271. var minX:Number = _min.x, minY:Number = _min.y, minZ:Number = _min.z;
  272. _aabbPoints[0] = minX;
  273. _aabbPoints[1] = minY;
  274. _aabbPoints[2] = minZ;
  275. _aabbPoints[3] = maxX;
  276. _aabbPoints[4] = minY;
  277. _aabbPoints[5] = minZ;
  278. _aabbPoints[6] = minX;
  279. _aabbPoints[7] = maxY;
  280. _aabbPoints[8] = minZ;
  281. _aabbPoints[9] = maxX;
  282. _aabbPoints[10] = maxY;
  283. _aabbPoints[11] = minZ;
  284. _aabbPoints[12] = minX;
  285. _aabbPoints[13] = minY;
  286. _aabbPoints[14] = maxZ;
  287. _aabbPoints[15] = maxX;
  288. _aabbPoints[16] = minY;
  289. _aabbPoints[17] = maxZ;
  290. _aabbPoints[18] = minX;
  291. _aabbPoints[19] = maxY;
  292. _aabbPoints[20] = maxZ;
  293. _aabbPoints[21] = maxX;
  294. _aabbPoints[22] = maxY;
  295. _aabbPoints[23] = maxZ;
  296. _aabbPointsDirty = false;
  297. }
  298. protected function updateBoundingRenderable():void
  299. {
  300. throw new AbstractMethodError();
  301. }
  302. protected function createBoundingRenderable():WireframePrimitiveBase
  303. {
  304. throw new AbstractMethodError();
  305. }
  306. public function classifyToPlane(plane:Plane3D):int
  307. {
  308. throw new AbstractMethodError();
  309. }
  310. public function transformFrom(bounds:BoundingVolumeBase, matrix:Matrix3D):void
  311. {
  312. throw new AbstractMethodError();
  313. }
  314. }
  315. }