@woosh/meep-engine 2.65.0 → 2.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/build/meep.cjs +51290 -54244
  3. package/build/meep.min.js +1 -1
  4. package/build/meep.module.js +51290 -54244
  5. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +4 -10
  6. package/editor/process/symbolic/makeGridPositionSymbolDisplay.js +7 -7
  7. package/editor/tools/SelectionTool.js +6 -95
  8. package/package.json +1 -1
  9. package/src/core/bvh2/binary/2/BinaryUint32BVH.js +118 -113
  10. package/src/core/bvh2/binary/2/BinaryUint32BVH.spec.js +54 -0
  11. package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +98 -0
  12. package/src/core/bvh2/bvh3/BVH.d.ts +1 -1
  13. package/src/core/bvh2/bvh3/BvhClient.d.ts +11 -0
  14. package/src/core/bvh2/bvh3/BvhClient.js +19 -0
  15. package/src/core/collection/array/array_copy.js +6 -0
  16. package/src/core/geom/3d/aabb/aabb3_array_combine.js +17 -8
  17. package/src/core/geom/3d/aabb/aabb3_array_intersects_ray.js +5 -2
  18. package/src/core/geom/3d/aabb/aabb3_array_set.js +25 -0
  19. package/src/core/geom/3d/aabb/aabb3_compute_half_surface_area.js +3 -0
  20. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +8 -1
  21. package/src/engine/EngineHarness.js +23 -25
  22. package/src/engine/ecs/renderable/RenderSystem.js +44 -32
  23. package/src/engine/ecs/renderable/Renderable.d.ts +2 -2
  24. package/src/engine/ecs/renderable/Renderable.js +12 -11
  25. package/src/engine/ecs/terrain/ecs/Terrain.js +83 -87
  26. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +106 -57
  27. package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +5 -2
  28. package/src/engine/ecs/terrain/tiles/TerrainTile.js +122 -67
  29. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +162 -146
  30. package/src/engine/ecs/terrain/tiles/TileBuildWorker.js +16 -5
  31. package/src/engine/graphics/GraphicsEngine.js +16 -25
  32. package/src/engine/graphics/camera/testClippingPlaneComputation.js +8 -11
  33. package/src/engine/graphics/debug/VisualSymbolLine.js +1 -0
  34. package/src/engine/graphics/ecs/camera/CameraSystem.js +9 -9
  35. package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.js +3 -23
  36. package/src/engine/graphics/ecs/compileAllMaterials.js +5 -12
  37. package/src/engine/graphics/ecs/light/LightSystem.js +12 -48
  38. package/src/engine/graphics/ecs/mesh/MeshSystem.js +9 -31
  39. package/src/engine/graphics/ecs/mesh/updateNodeByTransformAndBBB.js +3 -43
  40. package/src/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +22 -24
  41. package/src/engine/graphics/ecs/mesh-v2/sample/prototype_sg_raycast.js +21 -23
  42. package/src/engine/graphics/ecs/trail2d/Trail2D.js +105 -106
  43. package/src/engine/graphics/ecs/trail2d/Trail2DSystem.js +60 -61
  44. package/src/engine/graphics/ecs/trail2d/makeGradientTrail.js +3 -3
  45. package/src/engine/graphics/ecs/water/WATER_SIZE.js +1 -0
  46. package/src/engine/graphics/ecs/water/Water.js +84 -42
  47. package/src/engine/graphics/ecs/water/WaterSystem.js +53 -105
  48. package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +13 -7
  49. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +58 -0
  50. package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +32 -62
  51. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1 -1
  52. package/src/engine/graphics/particles/particular/engine/renderers/billboard/prototypeBillboardRenderer.js +8 -11
  53. package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +21 -19
  54. package/src/engine/graphics/render/layers/RenderLayer.d.ts +4 -3
  55. package/src/engine/graphics/render/layers/RenderLayer.js +34 -108
  56. package/src/engine/graphics/render/make_bvh_visibility_builder.js +64 -0
  57. package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.js +4 -4
  58. package/src/engine/graphics/trail/x/RibbonX.js +26 -5
  59. package/src/core/bvh2/binary/tiny/TinyBVH.js +0 -221
  60. package/src/engine/graphics/ecs/camera/CameraClippingPlaneComputer.js +0 -138
@@ -1,10 +1,9 @@
1
- import { ObjectEditor } from "../../primitive/ObjectEditor.js";
2
- import { BitFlagsEditor } from "../../common/BitFlagsEditor.js";
1
+ import { Texture } from "three";
2
+ import { GridTransformKind } from "../../../../../../src/engine/ecs/terrain/ecs/GridTransformKind.js";
3
3
  import { TerrainFlags } from "../../../../../../src/engine/ecs/terrain/ecs/TerrainFlags.js";
4
- import { ImagePathEditor } from "../../ImagePathEditor.js";
4
+ import { BitFlagsEditor } from "../../common/BitFlagsEditor.js";
5
5
  import { EnumEditor } from "../../common/EnumEditor.js";
6
- import { GridTransformKind } from "../../../../../../src/engine/ecs/terrain/ecs/GridTransformKind.js";
7
- import { Texture } from "three";
6
+ import { ObjectEditor } from "../../primitive/ObjectEditor.js";
8
7
 
9
8
  export class TerrainEditor extends ObjectEditor {
10
9
  build(parent, field, registry) {
@@ -69,11 +68,6 @@ export class TerrainEditor extends ObjectEditor {
69
68
  material: {
70
69
  transient: true
71
70
  },
72
- heightMapURL: {
73
- editor: new ImagePathEditor(),
74
- deprecated: true,
75
- type: String
76
- },
77
71
  heightRange: {
78
72
  deprecated: true
79
73
  },
@@ -1,19 +1,19 @@
1
+ import { BufferGeometry, Float32BufferAttribute, Line, LineBasicMaterial } from "three";
2
+ import { SurfacePoint3 } from "../../../src/core/geom/3d/SurfacePoint3.js";
3
+ import Vector3 from "../../../src/core/geom/Vector3.js";
1
4
  import { max2 } from "../../../src/core/math/max2.js";
2
5
  import { min2 } from "../../../src/core/math/min2.js";
6
+ import { ProcessState } from "../../../src/core/process/ProcessState.js";
3
7
  import Task from "../../../src/core/process/task/Task.js";
4
8
  import { TaskSignal } from "../../../src/core/process/task/TaskSignal.js";
5
9
  import Entity from "../../../src/engine/ecs/Entity.js";
6
- import { BufferGeometry, Float32BufferAttribute, Line, LineBasicMaterial } from "three";
10
+ import { EventType } from "../../../src/engine/ecs/EntityManager.js";
7
11
  import Renderable from "../../../src/engine/ecs/renderable/Renderable.js";
8
- import { SurfacePoint3 } from "../../../src/core/geom/3d/SurfacePoint3.js";
9
- import Vector3 from "../../../src/core/geom/Vector3.js";
12
+ import { obtainTerrain } from "../../../src/engine/ecs/terrain/util/obtainTerrain.js";
10
13
  import { Transform } from "../../../src/engine/ecs/transform/Transform.js";
14
+ import GridPosition from "../../../src/engine/grid/position/GridPosition.js";
11
15
  import EditorEntity from "../../ecs/EditorEntity.js";
12
- import { EventType } from "../../../src/engine/ecs/EntityManager.js";
13
16
  import { make3DSymbolicDisplay } from "./make3DSymbolicDisplay.js";
14
- import GridPosition from "../../../src/engine/grid/position/GridPosition.js";
15
- import { ProcessState } from "../../../src/core/process/ProcessState.js";
16
- import { obtainTerrain } from "../../../src/engine/ecs/terrain/util/obtainTerrain.js";
17
17
 
18
18
  /**
19
19
  *
@@ -3,23 +3,19 @@
3
3
  */
4
4
 
5
5
 
6
- import Tool from './engine/Tool.js';
7
- import Vector2 from '../../src/core/geom/Vector2.js';
6
+ import { Frustum as ThreeFrustum } from 'three';
8
7
  import AABB2 from '../../src/core/geom/2d/aabb/AABB2.js';
8
+ import Vector2 from '../../src/core/geom/Vector2.js';
9
+ import { makeScreenScissorFrustum } from "../../src/engine/graphics/camera/makeScreenScissorFrustum.js";
9
10
  import { Camera } from '../../src/engine/graphics/ecs/camera/Camera.js';
11
+ import { ShadedGeometrySystem } from "../../src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js";
12
+ import { make_ray_from_viewport_position } from "../../src/engine/graphics/make_ray_from_viewport_position.js";
10
13
  import View from '../../src/view/View.js';
11
14
 
12
15
  import SelectionAddAction from '../actions/concrete/SelectionAddAction.js';
13
16
  import SelectionClearAction from '../actions/concrete/SelectionClearAction.js';
14
-
15
- import { Frustum as ThreeFrustum, Raycaster } from 'three';
16
- import Vector3 from "../../src/core/geom/Vector3.js";
17
17
  import EditorEntity from "../ecs/EditorEntity.js";
18
- import Terrain from "../../src/engine/ecs/terrain/ecs/Terrain.js";
19
- import { SurfacePoint3 } from "../../src/core/geom/3d/SurfacePoint3.js";
20
- import { makeScreenScissorFrustum } from "../../src/engine/graphics/camera/makeScreenScissorFrustum.js";
21
- import { ShadedGeometrySystem } from "../../src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js";
22
- import { make_ray_from_viewport_position } from "../../src/engine/graphics/make_ray_from_viewport_position.js";
18
+ import Tool from './engine/Tool.js';
23
19
 
24
20
  class SelectionView extends View {
25
21
  constructor() {
@@ -283,72 +279,6 @@ export function pickingEntitySelection(point, engine, camera) {
283
279
  }
284
280
  }
285
281
 
286
- //query render layers
287
- engine.graphics.layers.traverse(function (layer) {
288
- /**
289
- *
290
- * @type {BinaryNode}
291
- */
292
- const bvh = layer.bvh;
293
-
294
- bvh.traverseRayLeafIntersections(ray_origin.x, ray_origin.y, ray_origin.z, ray_direction.x, ray_direction.y, ray_direction.z, function (leaf) {
295
- const entity = findEntityOfNode(leaf);
296
-
297
- if (typeof entity !== "number") {
298
- //no entity
299
- return;
300
- }
301
-
302
- const object = leaf.object;
303
- if (
304
- leaf.hasOwnProperty("object")
305
- && typeof object === "object"
306
- && object !== null
307
- && object.isObject3D
308
- && typeof object.raycast === "function"
309
- ) {
310
- //found a "raycast" function on the value object held by the leaf, assuming this is THREE.js raycast function
311
- const raycaster = new Raycaster(ray_origin, ray_direction, 0, Infinity);
312
-
313
- // WORKAROUND FOR https://github.com/mrdoob/three.js/issues/17078
314
- raycaster.camera = camera;
315
-
316
-
317
- object.traverse(node => {
318
- const intersection = [];
319
- node.raycast(raycaster, intersection);
320
-
321
- intersection.forEach(function (contact) {
322
- tryAddEntity(entity, contact.point);
323
- });
324
- });
325
-
326
- } else {
327
- /**
328
- *
329
- * @type {Terrain}
330
- */
331
- const terrain = dataset.getComponent(entity, Terrain);
332
-
333
- if (terrain !== undefined) {
334
- const sp = new SurfacePoint3();
335
-
336
- terrain.raycastFirstSync(sp, ray_origin.x, ray_origin.y, ray_origin.z, ray_direction.x, ray_direction.y, ray_direction.z);
337
-
338
- tryAddEntity(entity, sp.position);
339
- return;
340
- }
341
-
342
- const center = new Vector3(0, 0, 0);
343
-
344
- leaf.getCenter(center);
345
-
346
- tryAddEntity(entity, center);
347
- }
348
- });
349
-
350
- });
351
-
352
282
  return bestCandidate !== null ? [bestCandidate] : [];
353
283
  }
354
284
 
@@ -381,25 +311,6 @@ function marqueeSelection(box, editor, camera) {
381
311
  makeScreenScissorFrustum(frustum, normalizedBox, camera);
382
312
 
383
313
  const selection = [];
384
- //query render layers
385
- engine.graphics.layers.traverse(function (layer) {
386
- layer.bvh.threeTraverseFrustumsIntersections([frustum], function (leaf, fullyInside) {
387
-
388
- if (leaf.hasOwnProperty("entity") && selection.indexOf(leaf.entity) === -1) {
389
- let entity = findEntityOfNode(leaf);
390
-
391
- entity = dereferenceEntity(entity, dataset);
392
-
393
- if (entity === -1) {
394
- return;
395
- }
396
-
397
- if (selection.indexOf(entity) === -1) {
398
- selection.push(entity);
399
- }
400
- }
401
- });
402
- });
403
314
 
404
315
  return selection;
405
316
  }
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.65.0",
8
+ "version": "2.67.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -1,114 +1,70 @@
1
- import { array_copy } from "../../../collection/array/array_copy.js";
2
- import { min2 } from "../../../math/min2.js";
3
- import { max2 } from "../../../math/max2.js";
1
+ import { assert } from "../../../assert.js";
4
2
  import { ceilPowerOfTwo } from "../../../binary/operations/ceilPowerOfTwo.js";
3
+ import { array_copy } from "../../../collection/array/array_copy.js";
5
4
  import { array_swap } from "../../../collection/array/array_swap.js";
5
+ import { aabb3_array_combine } from "../../../geom/3d/aabb/aabb3_array_combine.js";
6
+ import { aabb3_array_set } from "../../../geom/3d/aabb/aabb3_array_set.js";
7
+ import { aabb3_compute_half_surface_area } from "../../../geom/3d/aabb/aabb3_compute_half_surface_area.js";
6
8
  import { mortonEncode_magicbits } from "../../../geom/3d/morton/mortonEncode_magicbits.js";
7
- import { min3 } from "../../../math/min3.js";
9
+ import { max2 } from "../../../math/max2.js";
8
10
  import { max3 } from "../../../math/max3.js";
9
- import { aabb3_compute_half_surface_area } from "../../../geom/3d/aabb/aabb3_compute_half_surface_area.js";
11
+ import { min2 } from "../../../math/min2.js";
12
+ import { min3 } from "../../../math/min3.js";
10
13
 
11
14
  /**
12
15
  * @readonly
13
16
  * @type {number}
14
17
  */
15
- export const BVH_BOX_BYTE_SIZE = 24;
18
+ export const BVH_BOX_BYTE_SIZE = 6;
16
19
 
17
20
  /**
18
- * In bytes
21
+ * In words (4 byte)
19
22
  * @readonly
20
23
  * @type {number}
21
24
  */
22
- export const BVH_BINARY_NODE_SIZE = 24;
25
+ export const BVH_BINARY_NODE_SIZE = 6;
23
26
  /**
24
27
  * @readonly
25
28
  * @type {number}
26
29
  */
27
- export const BVH_LEAF_NODE_SIZE = 28;
28
-
29
- /**
30
- *
31
- * @param {DataView} data
32
- * @param {number} destination
33
- * @param {number} source_a
34
- * @param {number} source_b
35
- */
36
- function refit_binary(data, destination, source_a, source_b) {
37
- const ax0 = data.getFloat32(source_a);
38
- const ay0 = data.getFloat32(source_a + 4);
39
- const az0 = data.getFloat32(source_a + 8);
40
- const ax1 = data.getFloat32(source_a + 12);
41
- const ay1 = data.getFloat32(source_a + 16);
42
- const az1 = data.getFloat32(source_a + 20);
43
-
44
- const bx0 = data.getFloat32(source_b);
45
- const by0 = data.getFloat32(source_b + 4);
46
- const bz0 = data.getFloat32(source_b + 8);
47
- const bx1 = data.getFloat32(source_b + 12);
48
- const by1 = data.getFloat32(source_b + 16);
49
- const bz1 = data.getFloat32(source_b + 20);
50
-
51
- const x0 = min2(ax0, bx0);
52
- const y0 = min2(ay0, by0);
53
- const z0 = min2(az0, bz0);
54
-
55
- const x1 = max2(ax1, bx1);
56
- const y1 = max2(ay1, by1);
57
- const z1 = max2(az1, bz1);
58
-
59
- data.setFloat32(destination, x0);
60
- data.setFloat32(destination + 4, y0);
61
- data.setFloat32(destination + 8, z0);
62
- data.setFloat32(destination + 12, x1);
63
- data.setFloat32(destination + 16, y1);
64
- data.setFloat32(destination + 20, z1);
65
- }
66
-
67
- /**
68
- *
69
- * @param {Uint8Array} data
70
- * @param {number} destination
71
- * @param {number} source
72
- */
73
- function copy_box(data, destination, source) {
74
- array_copy(data, source, data, destination, 24);
75
- }
30
+ export const BVH_LEAF_NODE_SIZE = 7;
76
31
 
77
32
  /**
78
33
  *
79
- * @param {DataView} data
34
+ * @param {Float32Array} data
80
35
  * @param {number} destination
81
36
  * @param {number} source
82
37
  */
83
38
  function copy_box_zero_size(data, destination, source) {
84
- const x = data.getFloat32(source);
85
- const y = data.getFloat32(source + 4);
86
- const z = data.getFloat32(source + 8);
39
+ assert.isNonNegativeInteger(destination, 'destination');
40
+ assert.isNonNegativeInteger(source, 'source');
87
41
 
88
- data.setFloat32(destination, x);
89
- data.setFloat32(destination + 4, y);
90
- data.setFloat32(destination + 8, z);
42
+ const x = data[source];
43
+ const y = data[source + 1];
44
+ const z = data[source + 2];
91
45
 
92
- data.setFloat32(destination + 12, x);
93
- data.setFloat32(destination + 16, y);
94
- data.setFloat32(destination + 20, z);
46
+ assert.notNaN(x, 'x');
47
+ assert.notNaN(y, 'y');
48
+ assert.notNaN(z, 'z');
49
+
50
+ aabb3_array_set(data, destination, x, y, z, x, y, z);
95
51
  }
96
52
 
97
53
  /**
98
54
  * Assumes data will be normalized to 0...1 value range
99
- * @param {DataView} data
55
+ * @param {Float32Array} data
100
56
  * @param {number} address
101
57
  * @param {number[]} matrix
102
58
  * @returns {number}
103
59
  */
104
60
  function build_morton(data, address, matrix) {
105
61
 
106
- const x0 = data.getFloat32(address);
107
- const y0 = data.getFloat32(address + 4);
108
- const z0 = data.getFloat32(address + 8);
109
- const x1 = data.getFloat32(address + 12);
110
- const y1 = data.getFloat32(address + 16);
111
- const z1 = data.getFloat32(address + 20);
62
+ const x0 = data[address];
63
+ const y0 = data[address + 1];
64
+ const z0 = data[address + 2];
65
+ const x1 = data[address + 3];
66
+ const y1 = data[address + 4];
67
+ const z1 = data[address + 5];
112
68
 
113
69
  const cx = (x0 + x1) / 2;
114
70
  const cy = (y0 + y1) / 2;
@@ -123,16 +79,28 @@ const scratch_box_0 = new Float32Array(18);
123
79
  const stack = [];
124
80
 
125
81
  export class BinaryUint32BVH {
126
- constructor() {
127
- this.__data_buffer = new ArrayBuffer(320);
128
- this.__data_uint8 = new Uint8Array(this.__data_buffer);
82
+ /**
83
+ *
84
+ * @private
85
+ * @type {ArrayBuffer}
86
+ */
87
+ __data_buffer;
129
88
 
130
- /**
131
- * @readonly
132
- * @type {DataView}
133
- * @private
134
- */
135
- this.__data_view = new DataView(this.__data_buffer);
89
+ /**
90
+ * @readonly
91
+ * @type {Float32Array}
92
+ * @private
93
+ */
94
+ __data_float32;
95
+
96
+ /**
97
+ * @readonly
98
+ * @private
99
+ * @type {Uint32Array}
100
+ */
101
+ __data_uint32;
102
+
103
+ constructor() {
136
104
 
137
105
  /**
138
106
  *
@@ -147,6 +115,8 @@ export class BinaryUint32BVH {
147
115
  * @private
148
116
  */
149
117
  this.__node_count_leaf = 0;
118
+
119
+ this.data = new ArrayBuffer(320);
150
120
  }
151
121
 
152
122
  getTotalBoxCount() {
@@ -169,23 +139,37 @@ export class BinaryUint32BVH {
169
139
  return this.__node_count_binary * BVH_BINARY_NODE_SIZE;
170
140
  }
171
141
 
142
+ get float32() {
143
+ return this.__data_float32;
144
+ }
145
+
146
+ get uint32() {
147
+ return this.__data_uint32;
148
+ }
149
+
172
150
  /**
173
151
  *
174
- * @returns {DataView}
152
+ * @param {ArrayBuffer} v
175
153
  */
176
- getDataView() {
177
- return this.__data_view;
154
+ set data(v) {
155
+ this.__data_buffer = v;
156
+
157
+ this.__data_float32 = new Float32Array(this.__data_buffer);
158
+ this.__data_uint32 = new Uint32Array(this.__data_buffer);
159
+ }
160
+
161
+ get data() {
162
+ return this.__data_buffer;
178
163
  }
179
164
 
180
165
  initialize_structure() {
181
166
  // compute memory requirements
182
- const storage_size = this.__node_count_binary * BVH_BINARY_NODE_SIZE + this.__node_count_leaf * BVH_LEAF_NODE_SIZE;
167
+ const word_count = this.__node_count_binary * BVH_BINARY_NODE_SIZE + this.__node_count_leaf * BVH_LEAF_NODE_SIZE;
168
+ const storage_size = word_count * 4;
183
169
 
184
170
  // possibly resize the storage
185
171
  if (this.__data_buffer.byteLength < storage_size) {
186
- this.__data_buffer = new ArrayBuffer(storage_size);
187
- this.__data_uint8 = new Uint8Array(this.__data_buffer);
188
- this.__data_view = new DataView(this.__data_buffer);
172
+ this.data = new ArrayBuffer(storage_size);
189
173
  }
190
174
  }
191
175
 
@@ -218,19 +202,28 @@ export class BinaryUint32BVH {
218
202
  * @param {number} y1
219
203
  * @param {number} z1
220
204
  */
221
- setLeafData(index, payload, x0, y0, z0, x1, y1, z1) {
222
- const address = index * BVH_LEAF_NODE_SIZE + this.__node_count_binary * BVH_BINARY_NODE_SIZE;
205
+ setLeafData(
206
+ index, payload,
207
+ x0, y0, z0,
208
+ x1, y1, z1
209
+ ) {
210
+ assert.notNaN(x0, 'x0');
211
+ assert.notNaN(y0, 'y0');
212
+ assert.notNaN(z0, 'z0');
213
+ assert.notNaN(x1, 'x1');
214
+ assert.notNaN(y1, 'y1');
215
+ assert.notNaN(z1, 'z1');
223
216
 
224
- const view = this.__data_view;
217
+ const address = index * BVH_LEAF_NODE_SIZE + this.__node_count_binary * BVH_BINARY_NODE_SIZE;
225
218
 
226
- view.setFloat32(address, x0);
227
- view.setFloat32(address + 4, y0);
228
- view.setFloat32(address + 8, z0);
229
- view.setFloat32(address + 12, x1);
230
- view.setFloat32(address + 16, y1);
231
- view.setFloat32(address + 20, z1);
219
+ aabb3_array_set(
220
+ this.__data_float32,
221
+ address,
222
+ x0, y0, z0,
223
+ x1, y1, z1
224
+ );
232
225
 
233
- view.setUint32(address + 24, payload);
226
+ this.__data_uint32[address + 6] = payload;
234
227
  }
235
228
 
236
229
  /**
@@ -240,10 +233,7 @@ export class BinaryUint32BVH {
240
233
  * @param {number} destination_offset offset within the destination array where to start writing results
241
234
  */
242
235
  readBounds(address, destination, destination_offset) {
243
- const v = this.__data_view;
244
- for (let i = 0; i < 6; i++) {
245
- destination[destination_offset + i] = v.getFloat32(address + i * 4);
246
- }
236
+ array_copy(this.__data_float32, address, destination, destination_offset, 6);
247
237
  }
248
238
 
249
239
  /**
@@ -256,7 +246,7 @@ export class BinaryUint32BVH {
256
246
 
257
247
  const address = block_address + leaf_index * BVH_LEAF_NODE_SIZE + BVH_BOX_BYTE_SIZE;
258
248
 
259
- return this.__data_view.getUint32(address);
249
+ return this.__data_uint32[address];
260
250
  }
261
251
 
262
252
  compute_total_surface_area() {
@@ -369,7 +359,7 @@ export class BinaryUint32BVH {
369
359
  stack[0] = 0; // first node
370
360
  stack[1] = this.__node_count_leaf - 1; // last node
371
361
 
372
- const data = this.__data_view;
362
+ const data = this.__data_float32;
373
363
 
374
364
  while (stackPointer > 0) {
375
365
  stackPointer -= 2;
@@ -382,7 +372,9 @@ export class BinaryUint32BVH {
382
372
 
383
373
  const pivotIndex = (left + right) >> 1;
384
374
 
385
- const pivot = build_morton(data, pivotIndex * BVH_LEAF_NODE_SIZE + leaf_block_address, projection);
375
+ const pivot_address = pivotIndex * BVH_LEAF_NODE_SIZE + leaf_block_address;
376
+
377
+ const pivot = build_morton(data, pivot_address, projection);
386
378
 
387
379
  /* partition */
388
380
  while (i <= j) {
@@ -426,9 +418,12 @@ export class BinaryUint32BVH {
426
418
  */
427
419
  __swap_leaves(i, j) {
428
420
  const leaf_block_address = this.getLeafBlockAddress();
421
+ const a = i * BVH_LEAF_NODE_SIZE + leaf_block_address;
422
+ const b = j * BVH_LEAF_NODE_SIZE + leaf_block_address;
423
+
429
424
  array_swap(
430
- this.__data_uint8, i * BVH_LEAF_NODE_SIZE + leaf_block_address,
431
- this.__data_uint8, j * BVH_LEAF_NODE_SIZE + leaf_block_address,
425
+ this.__data_float32, a,
426
+ this.__data_float32, b,
432
427
  BVH_LEAF_NODE_SIZE
433
428
  );
434
429
  }
@@ -453,6 +448,8 @@ export class BinaryUint32BVH {
453
448
 
454
449
  const node_count_leaf = this.__node_count_leaf;
455
450
 
451
+ const float32 = this.__data_float32;
452
+
456
453
  // build bottom-most level, just above the leaves
457
454
  for (i = 0; i < level_node_count; i++) {
458
455
  const leafIndex0 = i * 2;
@@ -463,13 +460,17 @@ export class BinaryUint32BVH {
463
460
 
464
461
  if (leafIndex1 < node_count_leaf) {
465
462
  // both children nodes are valid
466
- refit_binary(this.__data_view, offset, leafOffset0, leafOffset1);
463
+ aabb3_array_combine(
464
+ float32, offset,
465
+ float32, leafOffset0,
466
+ float32, leafOffset1
467
+ );
467
468
  } else if (leafIndex0 < node_count_leaf) {
468
469
  // only left child node is valid
469
- copy_box(this.__data_uint8, offset, leafOffset0);
470
+ array_copy(float32, leafOffset0, float32, offset, 6);
470
471
  } else {
471
472
  //initialize to 0-size box same position as previous node
472
- copy_box_zero_size(this.__data_view, offset, offset - BVH_BINARY_NODE_SIZE);
473
+ copy_box_zero_size(this.__data_float32, offset, (offset - BVH_BINARY_NODE_SIZE));
473
474
  }
474
475
 
475
476
  offset += BVH_BINARY_NODE_SIZE;
@@ -492,7 +493,11 @@ export class BinaryUint32BVH {
492
493
  const address_child_0 = childIndex0 * BVH_BINARY_NODE_SIZE;
493
494
  const address_child_1 = childIndex1 * BVH_BINARY_NODE_SIZE;
494
495
 
495
- refit_binary(this.__data_view, address_parent, address_child_0, address_child_1);
496
+ aabb3_array_combine(
497
+ float32, address_parent,
498
+ float32, address_child_0,
499
+ float32, address_child_1
500
+ );
496
501
 
497
502
  parentIndex++;
498
503
  }
@@ -63,6 +63,60 @@ test('read/write 1 leaf', () => {
63
63
  expect(bounds[5]).toBeCloseTo(23);
64
64
  });
65
65
 
66
+ test("2 leaf node build", () => {
67
+ const bvh = new BinaryUint32BVH();
68
+
69
+ bvh.setLeafCount(2);
70
+ bvh.initialize_structure();
71
+
72
+ bvh.setLeafData(0, 3, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6);
73
+ bvh.setLeafData(1, 7, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6);
74
+
75
+ bvh.build();
76
+
77
+ const bounds = [];
78
+
79
+ bvh.readBounds(0, bounds, 0);
80
+
81
+ expect(bounds).toEqual(Array.from(new Float32Array([0.1, 0.2, 0.3, 1.4, 1.5, 1.6])));
82
+ });
83
+
84
+ test("1 leaf node build", () => {
85
+ const bvh = new BinaryUint32BVH();
86
+
87
+ bvh.setLeafCount(1);
88
+ bvh.initialize_structure();
89
+
90
+ bvh.setLeafData(0, 3, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6);
91
+
92
+ bvh.build();
93
+
94
+ const bounds = [];
95
+
96
+ bvh.readBounds(0, bounds, 0);
97
+
98
+ expect(bounds).toEqual(Array.from(new Float32Array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])));
99
+ });
100
+
101
+ test("3 leaf node build", () => {
102
+ const bvh = new BinaryUint32BVH();
103
+
104
+ bvh.setLeafCount(3);
105
+ bvh.initialize_structure();
106
+
107
+ bvh.setLeafData(0, 3, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6);
108
+ bvh.setLeafData(1, 7, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6);
109
+ bvh.setLeafData(2, 11, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6);
110
+
111
+ bvh.build();
112
+
113
+ const bounds = [];
114
+
115
+ bvh.readBounds(0, bounds, 0);
116
+
117
+ expect(bounds).toEqual(Array.from(new Float32Array([0.1, 0.2, 0.3, 2.4, 2.5, 2.6])));
118
+ });
119
+
66
120
  test('4 node sorted build', () => {
67
121
  const bvh = new BinaryUint32BVH();
68
122