babylon.octree.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. module BABYLON {
  2. export interface IOctreeContainer {
  3. blocks: Array<OctreeBlock>;
  4. }
  5. export class Octree {
  6. public blocks: Array<OctreeBlock>;
  7. private _maxBlockCapacity: number;
  8. private _selection;
  9. constructor(maxBlockCapacity?: number) {
  10. this._maxBlockCapacity = maxBlockCapacity || 64;
  11. this._selection = new BABYLON.SmartArray(256);
  12. }
  13. // Methods
  14. public update(worldMin: Vector3, worldMax: Vector3, meshes): void {
  15. Octree._CreateBlocks(worldMin, worldMax, meshes, this._maxBlockCapacity, this);
  16. }
  17. public addMesh(mesh): void {
  18. for (var index = 0; index < this.blocks.length; index++) {
  19. var block = this.blocks[index];
  20. block.addMesh(mesh);
  21. }
  22. }
  23. public select(frustumPlanes: Plane[]) {
  24. this._selection.reset();
  25. for (var index = 0; index < this.blocks.length; index++) {
  26. var block = this.blocks[index];
  27. block.select(frustumPlanes, this._selection);
  28. }
  29. return this._selection;
  30. }
  31. // Statics
  32. static _CreateBlocks(worldMin: Vector3, worldMax: Vector3, meshes, maxBlockCapacity: number, target: IOctreeContainer): void {
  33. target.blocks = [];
  34. var blockSize = new BABYLON.Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);
  35. // Segmenting space
  36. for (var x = 0; x < 2; x++) {
  37. for (var y = 0; y < 2; y++) {
  38. for (var z = 0; z < 2; z++) {
  39. var localMin = worldMin.add(blockSize.multiplyByFloats(x, y, z));
  40. var localMax = worldMin.add(blockSize.multiplyByFloats(x + 1, y + 1, z + 1));
  41. var block = new BABYLON.OctreeBlock(localMin, localMax, maxBlockCapacity);
  42. block.addEntries(meshes);
  43. target.blocks.push(block);
  44. }
  45. }
  46. }
  47. }
  48. }
  49. }