babylon.BoundingBox.ts 5.7 KB

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