babylon.boundingInfo.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. module BABYLON {
  2. var computeBoxExtents = (axis: Vector3, box: BoundingBox) => {
  3. var p = Vector3.Dot(box.centerWorld, axis);
  4. var r0 = Math.abs(Vector3.Dot(box.directions[0], axis)) * box.extendSize.x;
  5. var r1 = Math.abs(Vector3.Dot(box.directions[1], axis)) * box.extendSize.y;
  6. var r2 = Math.abs(Vector3.Dot(box.directions[2], axis)) * box.extendSize.z;
  7. var r = r0 + r1 + r2;
  8. return {
  9. min: p - r,
  10. max: p + r
  11. };
  12. }
  13. var extentsOverlap = (min0: number, max0: number, min1: number, max1: number): boolean => !(min0 > max1 || min1 > max0);
  14. var axisOverlap = (axis: Vector3, box0: BoundingBox, box1: BoundingBox): boolean => {
  15. var result0 = computeBoxExtents(axis, box0);
  16. var result1 = computeBoxExtents(axis, box1);
  17. return extentsOverlap(result0.min, result0.max, result1.min, result1.max);
  18. }
  19. export interface ICullable {
  20. isInFrustum(frustumPlanes: Plane[]): boolean;
  21. isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
  22. }
  23. export class BoundingInfo implements ICullable {
  24. public boundingBox: BoundingBox;
  25. public boundingSphere: BoundingSphere;
  26. private _isLocked = false;
  27. constructor(public minimum: Vector3, public maximum: Vector3) {
  28. this.boundingBox = new BoundingBox(minimum, maximum);
  29. this.boundingSphere = new BoundingSphere(minimum, maximum);
  30. }
  31. public get isLocked(): boolean {
  32. return this._isLocked;
  33. }
  34. public set isLocked(value: boolean) {
  35. this._isLocked = value;
  36. }
  37. // Methods
  38. public update(world: Matrix) {
  39. if (this._isLocked) {
  40. return;
  41. }
  42. this.boundingBox._update(world);
  43. this.boundingSphere._update(world);
  44. }
  45. public isInFrustum(frustumPlanes: Plane[]): boolean {
  46. if (!this.boundingSphere.isInFrustum(frustumPlanes))
  47. return false;
  48. return this.boundingBox.isInFrustum(frustumPlanes);
  49. }
  50. /**
  51. * Gets the world distance between the min and max points of the bounding box
  52. */
  53. public get diagonalLength(): number {
  54. let boundingBox = this.boundingBox;
  55. let size = boundingBox.maximumWorld.subtract(boundingBox.minimumWorld);
  56. return size.length();
  57. }
  58. public isCompletelyInFrustum(frustumPlanes: Plane[]): boolean {
  59. return this.boundingBox.isCompletelyInFrustum(frustumPlanes);
  60. }
  61. public _checkCollision(collider: Collider): boolean {
  62. return collider._canDoCollision(this.boundingSphere.centerWorld, this.boundingSphere.radiusWorld, this.boundingBox.minimumWorld, this.boundingBox.maximumWorld);
  63. }
  64. public intersectsPoint(point: Vector3): boolean {
  65. if (!this.boundingSphere.centerWorld) {
  66. return false;
  67. }
  68. if (!this.boundingSphere.intersectsPoint(point)) {
  69. return false;
  70. }
  71. if (!this.boundingBox.intersectsPoint(point)) {
  72. return false;
  73. }
  74. return true;
  75. }
  76. public intersects(boundingInfo: BoundingInfo, precise: boolean): boolean {
  77. if (!this.boundingSphere.centerWorld || !boundingInfo.boundingSphere.centerWorld) {
  78. return false;
  79. }
  80. if (!BoundingSphere.Intersects(this.boundingSphere, boundingInfo.boundingSphere)) {
  81. return false;
  82. }
  83. if (!BoundingBox.Intersects(this.boundingBox, boundingInfo.boundingBox)) {
  84. return false;
  85. }
  86. if (!precise) {
  87. return true;
  88. }
  89. var box0 = this.boundingBox;
  90. var box1 = boundingInfo.boundingBox;
  91. if (!axisOverlap(box0.directions[0], box0, box1)) return false;
  92. if (!axisOverlap(box0.directions[1], box0, box1)) return false;
  93. if (!axisOverlap(box0.directions[2], box0, box1)) return false;
  94. if (!axisOverlap(box1.directions[0], box0, box1)) return false;
  95. if (!axisOverlap(box1.directions[1], box0, box1)) return false;
  96. if (!axisOverlap(box1.directions[2], box0, box1)) return false;
  97. if (!axisOverlap(Vector3.Cross(box0.directions[0], box1.directions[0]), box0, box1)) return false;
  98. if (!axisOverlap(Vector3.Cross(box0.directions[0], box1.directions[1]), box0, box1)) return false;
  99. if (!axisOverlap(Vector3.Cross(box0.directions[0], box1.directions[2]), box0, box1)) return false;
  100. if (!axisOverlap(Vector3.Cross(box0.directions[1], box1.directions[0]), box0, box1)) return false;
  101. if (!axisOverlap(Vector3.Cross(box0.directions[1], box1.directions[1]), box0, box1)) return false;
  102. if (!axisOverlap(Vector3.Cross(box0.directions[1], box1.directions[2]), box0, box1)) return false;
  103. if (!axisOverlap(Vector3.Cross(box0.directions[2], box1.directions[0]), box0, box1)) return false;
  104. if (!axisOverlap(Vector3.Cross(box0.directions[2], box1.directions[1]), box0, box1)) return false;
  105. if (!axisOverlap(Vector3.Cross(box0.directions[2], box1.directions[2]), box0, box1)) return false;
  106. return true;
  107. }
  108. }
  109. }