babylon.boundingBox.ts 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. module BABYLON {
  2. export class BoundingBox implements ICullable {
  3. public vectors: Vector3[] = new Array<Vector3>();
  4. public center: Vector3;
  5. public centerWorld: Vector3;
  6. public extendSize: Vector3;
  7. public extendSizeWorld: Vector3;
  8. public directions: Vector3[];
  9. public vectorsWorld: Vector3[] = new Array<Vector3>();
  10. public minimumWorld: Vector3;
  11. public maximumWorld: Vector3;
  12. private _worldMatrix: Matrix;
  13. constructor(public minimum: Vector3, public maximum: Vector3) {
  14. // Bounding vectors
  15. this.vectors.push(this.minimum.clone());
  16. this.vectors.push(this.maximum.clone());
  17. this.vectors.push(this.minimum.clone());
  18. this.vectors[2].x = this.maximum.x;
  19. this.vectors.push(this.minimum.clone());
  20. this.vectors[3].y = this.maximum.y;
  21. this.vectors.push(this.minimum.clone());
  22. this.vectors[4].z = this.maximum.z;
  23. this.vectors.push(this.maximum.clone());
  24. this.vectors[5].z = this.minimum.z;
  25. this.vectors.push(this.maximum.clone());
  26. this.vectors[6].x = this.minimum.x;
  27. this.vectors.push(this.maximum.clone());
  28. this.vectors[7].y = this.minimum.y;
  29. // OBB
  30. this.center = this.maximum.add(this.minimum).scale(0.5);
  31. this.extendSize = this.maximum.subtract(this.minimum).scale(0.5);
  32. this.directions = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
  33. // World
  34. for (var index = 0; index < this.vectors.length; index++) {
  35. this.vectorsWorld[index] = Vector3.Zero();
  36. }
  37. this.minimumWorld = Vector3.Zero();
  38. this.maximumWorld = Vector3.Zero();
  39. this.centerWorld = Vector3.Zero();
  40. this.extendSizeWorld = Vector3.Zero();
  41. this._update(Matrix.Identity());
  42. }
  43. // Methods
  44. public getWorldMatrix(): Matrix {
  45. return this._worldMatrix;
  46. }
  47. public setWorldMatrix(matrix: Matrix): BoundingBox {
  48. this._worldMatrix.copyFrom(matrix);
  49. return this;
  50. }
  51. public _update(world: Matrix): void {
  52. Vector3.FromFloatsToRef(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, this.minimumWorld);
  53. Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, this.maximumWorld);
  54. for (var index = 0; index < this.vectors.length; index++) {
  55. var v = this.vectorsWorld[index];
  56. Vector3.TransformCoordinatesToRef(this.vectors[index], world, v);
  57. if (v.x < this.minimumWorld.x)
  58. this.minimumWorld.x = v.x;
  59. if (v.y < this.minimumWorld.y)
  60. this.minimumWorld.y = v.y;
  61. if (v.z < this.minimumWorld.z)
  62. this.minimumWorld.z = v.z;
  63. if (v.x > this.maximumWorld.x)
  64. this.maximumWorld.x = v.x;
  65. if (v.y > this.maximumWorld.y)
  66. this.maximumWorld.y = v.y;
  67. if (v.z > this.maximumWorld.z)
  68. this.maximumWorld.z = v.z;
  69. }
  70. // Extend
  71. this.maximumWorld.subtractToRef(this.minimumWorld, this.extendSizeWorld);
  72. this.extendSizeWorld.scaleInPlace(0.5);
  73. // OBB
  74. this.maximumWorld.addToRef(this.minimumWorld, this.centerWorld);
  75. this.centerWorld.scaleInPlace(0.5);
  76. Vector3.FromFloatArrayToRef(world.m, 0, this.directions[0]);
  77. Vector3.FromFloatArrayToRef(world.m, 4, this.directions[1]);
  78. Vector3.FromFloatArrayToRef(world.m, 8, this.directions[2]);
  79. this._worldMatrix = world;
  80. }
  81. public isInFrustum(frustumPlanes: Plane[]): boolean {
  82. return BoundingBox.IsInFrustum(this.vectorsWorld, frustumPlanes);
  83. }
  84. public isCompletelyInFrustum(frustumPlanes: Plane[]): boolean {
  85. return BoundingBox.IsCompletelyInFrustum(this.vectorsWorld, frustumPlanes);
  86. }
  87. public intersectsPoint(point: Vector3): boolean {
  88. var delta = -Epsilon;
  89. if (this.maximumWorld.x - point.x < delta || delta > point.x - this.minimumWorld.x)
  90. return false;
  91. if (this.maximumWorld.y - point.y < delta || delta > point.y - this.minimumWorld.y)
  92. return false;
  93. if (this.maximumWorld.z - point.z < delta || delta > point.z - this.minimumWorld.z)
  94. return false;
  95. return true;
  96. }
  97. public intersectsSphere(sphere: BoundingSphere): boolean {
  98. return BoundingBox.IntersectsSphere(this.minimumWorld, this.maximumWorld, sphere.centerWorld, sphere.radiusWorld);
  99. }
  100. public intersectsMinMax(min: Vector3, max: Vector3): boolean {
  101. if (this.maximumWorld.x < min.x || this.minimumWorld.x > max.x)
  102. return false;
  103. if (this.maximumWorld.y < min.y || this.minimumWorld.y > max.y)
  104. return false;
  105. if (this.maximumWorld.z < min.z || this.minimumWorld.z > max.z)
  106. return false;
  107. return true;
  108. }
  109. // Statics
  110. public static Intersects(box0: BoundingBox, box1: BoundingBox): boolean {
  111. if (box0.maximumWorld.x < box1.minimumWorld.x || box0.minimumWorld.x > box1.maximumWorld.x)
  112. return false;
  113. if (box0.maximumWorld.y < box1.minimumWorld.y || box0.minimumWorld.y > box1.maximumWorld.y)
  114. return false;
  115. if (box0.maximumWorld.z < box1.minimumWorld.z || box0.minimumWorld.z > box1.maximumWorld.z)
  116. return false;
  117. return true;
  118. }
  119. public static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean {
  120. var vector = Vector3.Clamp(sphereCenter, minPoint, maxPoint);
  121. var num = Vector3.DistanceSquared(sphereCenter, vector);
  122. return (num <= (sphereRadius * sphereRadius));
  123. }
  124. public static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean {
  125. for (var p = 0; p < 6; p++) {
  126. for (var i = 0; i < 8; i++) {
  127. if (frustumPlanes[p].dotCoordinate(boundingVectors[i]) < 0) {
  128. return false;
  129. }
  130. }
  131. }
  132. return true;
  133. }
  134. public static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean {
  135. for (var p = 0; p < 6; p++) {
  136. var inCount = 8;
  137. for (var i = 0; i < 8; i++) {
  138. if (frustumPlanes[p].dotCoordinate(boundingVectors[i]) < 0) {
  139. --inCount;
  140. } else {
  141. break;
  142. }
  143. }
  144. if (inCount === 0)
  145. return false;
  146. }
  147. return true;
  148. }
  149. }
  150. }