babylon.octreeBlock.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. module BABYLON {
  2. export class OctreeBlock<T> {
  3. public entries = new Array<T>();
  4. public blocks: Array<OctreeBlock<T>>;
  5. private _depth: number;
  6. private _maxDepth: number;
  7. private _capacity: number;
  8. private _minPoint: Vector3;
  9. private _maxPoint: Vector3;
  10. private _boundingVectors = new Array<Vector3>();
  11. private _creationFunc: (entry: T, block: OctreeBlock<T>) => void;
  12. constructor(minPoint: Vector3, maxPoint: Vector3, capacity: number, depth: number, maxDepth: number, creationFunc: (entry: T, block: OctreeBlock<T>) => void) {
  13. this._capacity = capacity;
  14. this._depth = depth;
  15. this._maxDepth = maxDepth;
  16. this._creationFunc = creationFunc;
  17. this._minPoint = minPoint;
  18. this._maxPoint = maxPoint;
  19. this._boundingVectors.push(minPoint.clone());
  20. this._boundingVectors.push(maxPoint.clone());
  21. this._boundingVectors.push(minPoint.clone());
  22. this._boundingVectors[2].x = maxPoint.x;
  23. this._boundingVectors.push(minPoint.clone());
  24. this._boundingVectors[3].y = maxPoint.y;
  25. this._boundingVectors.push(minPoint.clone());
  26. this._boundingVectors[4].z = maxPoint.z;
  27. this._boundingVectors.push(maxPoint.clone());
  28. this._boundingVectors[5].z = minPoint.z;
  29. this._boundingVectors.push(maxPoint.clone());
  30. this._boundingVectors[6].x = minPoint.x;
  31. this._boundingVectors.push(maxPoint.clone());
  32. this._boundingVectors[7].y = minPoint.y;
  33. }
  34. // Property
  35. public get capacity(): number {
  36. return this._capacity;
  37. }
  38. public get minPoint(): Vector3 {
  39. return this._minPoint;
  40. }
  41. public get maxPoint(): Vector3 {
  42. return this._maxPoint;
  43. }
  44. // Methods
  45. public addEntry(entry: T): void {
  46. if (this.blocks) {
  47. for (var index = 0; index < this.blocks.length; index++) {
  48. var block = this.blocks[index];
  49. block.addEntry(entry);
  50. }
  51. return;
  52. }
  53. this._creationFunc(entry, this);
  54. if (this.entries.length > this.capacity && this._depth < this._maxDepth) {
  55. this.createInnerBlocks();
  56. }
  57. }
  58. public addEntries(entries: T[]): void {
  59. for (var index = 0; index < entries.length; index++) {
  60. var mesh = entries[index];
  61. this.addEntry(mesh);
  62. }
  63. }
  64. public select(frustumPlanes: Plane[], selection: SmartArray<T>, allowDuplicate?: boolean): void {
  65. if (BABYLON.BoundingBox.IsInFrustum(this._boundingVectors, frustumPlanes)) {
  66. if (this.blocks) {
  67. for (var index = 0; index < this.blocks.length; index++) {
  68. var block = this.blocks[index];
  69. block.select(frustumPlanes, selection, allowDuplicate);
  70. }
  71. return;
  72. }
  73. if (allowDuplicate) {
  74. selection.concat(this.entries);
  75. } else {
  76. selection.concatWithNoDuplicate(this.entries);
  77. }
  78. }
  79. }
  80. public intersects(sphereCenter: Vector3, sphereRadius: number, selection: SmartArray<T>, allowDuplicate?: boolean): void {
  81. if (BABYLON.BoundingBox.IntersectsSphere(this._minPoint, this._maxPoint, sphereCenter, sphereRadius)) {
  82. if (this.blocks) {
  83. for (var index = 0; index < this.blocks.length; index++) {
  84. var block = this.blocks[index];
  85. block.intersects(sphereCenter, sphereRadius, selection, allowDuplicate);
  86. }
  87. return;
  88. }
  89. if (allowDuplicate) {
  90. selection.concat(this.entries);
  91. } else {
  92. selection.concatWithNoDuplicate(this.entries);
  93. }
  94. }
  95. }
  96. public intersectsRay(ray: Ray, selection: SmartArray<T>): void {
  97. if (ray.intersectsBoxMinMax(this._minPoint, this._maxPoint)) {
  98. if (this.blocks) {
  99. for (var index = 0; index < this.blocks.length; index++) {
  100. var block = this.blocks[index];
  101. block.intersectsRay(ray, selection);
  102. }
  103. return;
  104. }
  105. selection.concatWithNoDuplicate(this.entries);
  106. }
  107. }
  108. public createInnerBlocks(): void {
  109. Octree._CreateBlocks(this._minPoint, this._maxPoint, this.entries, this._capacity, this._depth, this._maxDepth, this, this._creationFunc);
  110. }
  111. }
  112. }