@woosh/meep-engine 2.67.0 → 2.69.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 (87) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/build/meep.cjs +698 -1270
  3. package/build/meep.min.js +1 -1
  4. package/build/meep.module.js +698 -1270
  5. package/package.json +1 -1
  6. package/src/core/bvh2/binary/2/BinaryUint32BVH.js +55 -28
  7. package/src/core/bvh2/binary/2/BinaryUint32BVH.spec.js +3 -3
  8. package/src/core/bvh2/binary/2/bvh32_query_user_data_overlaps_clipping_volume.js +94 -0
  9. package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +17 -18
  10. package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +4 -2
  11. package/src/core/geom/3d/aabb/AABB3.js +14 -14
  12. package/src/core/geom/3d/aabb/aabb3_array_intersects_clipping_volume_array.js +30 -0
  13. package/src/core/geom/3d/aabb/aabb3_intersects_clipping_volume_array.js +51 -0
  14. package/src/core/geom/3d/frustum/{read_frustum_planes_to_array.js → read_three_planes_to_array.js} +5 -3
  15. package/src/core/geom/3d/triangle/triangle_intersects_clipping_volume.js +51 -0
  16. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +2 -2
  17. package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +1 -1
  18. package/src/engine/ecs/terrain/tiles/TerrainTile.js +9 -46
  19. package/src/engine/graphics/ecs/mesh/Mesh.d.ts +0 -1
  20. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +0 -5
  21. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +0 -1
  22. package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.d.ts +2 -2
  23. package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +79 -36
  24. package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_overlap_clipping_volume.js +88 -0
  25. package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.js +108 -0
  26. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +4 -30
  27. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_unindexed_geometry.js +30 -0
  28. package/src/engine/graphics/geometry/bvh/buffered/bvh32_set_leaf_from_triangle.js +41 -0
  29. package/src/engine/graphics/material/optimization/prototypeMaterialOptimizer.js +16 -19
  30. package/src/engine/graphics/render/forward_plus/LightManager.js +2 -2
  31. package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +46 -47
  32. package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +2 -2
  33. package/src/engine/graphics/render/view/CameraView.js +8 -8
  34. package/src/core/bvh2/BVHTasks.js +0 -65
  35. package/src/core/bvh2/BinaryNode.d.ts +0 -13
  36. package/src/core/bvh2/BinaryNode.js +0 -1188
  37. package/src/core/bvh2/BinaryNode.spec.js +0 -309
  38. package/src/core/bvh2/LeafNode.d.ts +0 -7
  39. package/src/core/bvh2/LeafNode.js +0 -147
  40. package/src/core/bvh2/Node.d.ts +0 -9
  41. package/src/core/bvh2/Node.js +0 -196
  42. package/src/core/bvh2/NodeValidator.js +0 -197
  43. package/src/core/bvh2/StacklessTraverser.js +0 -154
  44. package/src/core/bvh2/StacklessTraverser.spec.js +0 -109
  45. package/src/core/bvh2/binary/BinaryBVH.js +0 -281
  46. package/src/core/bvh2/binary/IndexedBinaryBVH.js +0 -407
  47. package/src/core/bvh2/binary/IndexedBinaryBVH.spec.js +0 -27
  48. package/src/core/bvh2/binary/IndexedBinaryBVHVisitor.js +0 -11
  49. package/src/core/bvh2/binary/NodeType.js +0 -8
  50. package/src/core/bvh2/binary/RayLeafIntersectionVisitor.js +0 -59
  51. package/src/core/bvh2/serialization/deserializeBinaryNode.js +0 -40
  52. package/src/core/bvh2/serialization/deserializeBinaryNodeFromBinaryBuffer.js +0 -90
  53. package/src/core/bvh2/serialization/serializeBinaryNode.js +0 -31
  54. package/src/core/bvh2/serialization/serializeBinaryNodeToBinaryBuffer.js +0 -86
  55. package/src/core/bvh2/transform/BottomUpOptimizingRebuilder.js +0 -144
  56. package/src/core/bvh2/transform/RotationOptimizer.js +0 -123
  57. package/src/core/bvh2/transform/RotationOptimizer.spec.js +0 -303
  58. package/src/core/bvh2/transform/tryRotateSingleNode.js +0 -260
  59. package/src/core/bvh2/traversal/BVHVisitor.js +0 -30
  60. package/src/core/bvh2/traversal/RaycastBVHVisitor.js +0 -66
  61. package/src/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +0 -384
  62. package/src/core/bvh2/traversal/ThreeFrustumsIntersectionBVHVisitor.js +0 -52
  63. package/src/core/bvh2/traversal/bvh_traverse_pre_order_using_stack.js +0 -43
  64. package/src/core/bvh2/traversal/queryBinaryNode_ClippingPlanes.d.ts +0 -5
  65. package/src/core/bvh2/traversal/queryBinaryNode_ClippingPlanes.js +0 -66
  66. package/src/core/bvh2/traversal/queryBinaryNode_CollectData.js +0 -49
  67. package/src/core/bvh2/traversal/queryBinaryNode_CollectLeaves.js +0 -51
  68. package/src/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +0 -77
  69. package/src/core/bvh2/traversal/queryBinaryNode_SphereIntersections.js +0 -63
  70. package/src/core/bvh2/traversal/traverseBinaryNodeUsingVisitor.js +0 -50
  71. package/src/core/bvh2/traversal/traverseBinaryNodeUsingVisitor_DepthFirst_PreOrder.js +0 -34
  72. package/src/core/bvh2/util/find_least_common_ancestor.js +0 -34
  73. package/src/core/bvh2/visual/convert_bvh_to_dot_format_string.js +0 -50
  74. package/src/core/geom/2d/bvh/BinaryNode2.js +0 -152
  75. package/src/core/geom/2d/bvh/LeafNode2.js +0 -11
  76. package/src/core/geom/2d/bvh/Node2.js +0 -51
  77. package/src/core/geom/3d/aabb/aabb3_array_intersects_frustum_array.js +0 -20
  78. package/src/core/geom/3d/aabb/aabb3_intersects_frustum_array.js +0 -35
  79. package/src/engine/ecs/terrain/tiles/FirstRayIntersectionTerrainBVHVisitor.js +0 -74
  80. package/src/engine/graphics/geometry/buffered/query/ClippingPlaneContainmentComputingVisitor.js +0 -195
  81. package/src/engine/graphics/geometry/buffered/query/GeometryVisitor.js +0 -87
  82. package/src/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +0 -206
  83. package/src/engine/graphics/geometry/bvh/BVHFromGeometry.js +0 -72
  84. package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +0 -240
  85. package/src/engine/graphics/geometry/bvh/buffered/BinaryBVHFromBufferGeometry.js +0 -123
  86. package/src/engine/graphics/geometry/bvh/buffered/IndexedTraingleBoundsComputer.js +0 -43
  87. package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_objects.js +0 -133
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.67.0",
8
+ "version": "2.69.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -100,34 +100,41 @@ export class BinaryUint32BVH {
100
100
  */
101
101
  __data_uint32;
102
102
 
103
- constructor() {
104
-
105
- /**
106
- *
107
- * @type {number}
108
- * @private
109
- */
110
- this.__node_count_binary = 0;
103
+ /**
104
+ *
105
+ * @type {number}
106
+ * @private
107
+ */
108
+ __node_count_binary = 0;
111
109
 
112
- /**
113
- *
114
- * @type {number}
115
- * @private
116
- */
117
- this.__node_count_leaf = 0;
110
+ /**
111
+ *
112
+ * @type {number}
113
+ * @private
114
+ */
115
+ __node_count_leaf = 0;
118
116
 
117
+ constructor() {
119
118
  this.data = new ArrayBuffer(320);
120
119
  }
121
120
 
121
+ /**
122
+ * In bytes
123
+ * @returns {number}
124
+ */
125
+ estimateByteSize() {
126
+ return this.data.byteLength + 248;
127
+ }
128
+
122
129
  getTotalBoxCount() {
123
130
  return this.__node_count_binary + this.__node_count_leaf;
124
131
  }
125
132
 
126
- getBinaryNodeCount() {
133
+ get binary_node_count() {
127
134
  return this.__node_count_binary;
128
135
  }
129
136
 
130
- getLeafNodeCount() {
137
+ get leaf_node_count() {
131
138
  return this.__node_count_leaf;
132
139
  }
133
140
 
@@ -149,10 +156,12 @@ export class BinaryUint32BVH {
149
156
 
150
157
  /**
151
158
  *
152
- * @param {ArrayBuffer} v
159
+ * @param {ArrayBuffer} buffer
153
160
  */
154
- set data(v) {
155
- this.__data_buffer = v;
161
+ set data(buffer) {
162
+ assert.defined(buffer, 'buffer');
163
+
164
+ this.__data_buffer = buffer;
156
165
 
157
166
  this.__data_float32 = new Float32Array(this.__data_buffer);
158
167
  this.__data_uint32 = new Uint32Array(this.__data_buffer);
@@ -162,6 +171,24 @@ export class BinaryUint32BVH {
162
171
  return this.__data_buffer;
163
172
  }
164
173
 
174
+ /**
175
+ * Resolve index of the node to address where the node data starts, this is required to know where AABB is stored in memory
176
+ * @param {number} node_index
177
+ * @returns {number}
178
+ */
179
+ getNodeAddress(node_index) {
180
+ const binary_node_count = this.__node_count_binary;
181
+ const leaf_node_index = node_index - binary_node_count;
182
+
183
+ if (leaf_node_index < 0) {
184
+ // binary node
185
+ return node_index * BVH_BINARY_NODE_SIZE;
186
+ } else {
187
+ // leaf node
188
+ return binary_node_count * BVH_BINARY_NODE_SIZE + leaf_node_index * BVH_LEAF_NODE_SIZE;
189
+ }
190
+ }
191
+
165
192
  initialize_structure() {
166
193
  // compute memory requirements
167
194
  const word_count = this.__node_count_binary * BVH_BINARY_NODE_SIZE + this.__node_count_leaf * BVH_LEAF_NODE_SIZE;
@@ -452,22 +479,22 @@ export class BinaryUint32BVH {
452
479
 
453
480
  // build bottom-most level, just above the leaves
454
481
  for (i = 0; i < level_node_count; i++) {
455
- const leafIndex0 = i * 2;
456
- const leafIndex1 = leafIndex0 + 1;
482
+ const leaf_index_0 = i * 2;
483
+ const leaf_index_1 = leaf_index_0 + 1;
457
484
 
458
- const leafOffset0 = leaf_node_block_address + leafIndex0 * BVH_LEAF_NODE_SIZE;
459
- const leafOffset1 = leaf_node_block_address + leafIndex1 * BVH_LEAF_NODE_SIZE;
485
+ const leaf_offset_0 = leaf_node_block_address + leaf_index_0 * BVH_LEAF_NODE_SIZE;
486
+ const leaf_offset_1 = leaf_node_block_address + leaf_index_1 * BVH_LEAF_NODE_SIZE;
460
487
 
461
- if (leafIndex1 < node_count_leaf) {
488
+ if (leaf_index_1 < node_count_leaf) {
462
489
  // both children nodes are valid
463
490
  aabb3_array_combine(
464
491
  float32, offset,
465
- float32, leafOffset0,
466
- float32, leafOffset1
492
+ float32, leaf_offset_0,
493
+ float32, leaf_offset_1
467
494
  );
468
- } else if (leafIndex0 < node_count_leaf) {
495
+ } else if (leaf_index_0 < node_count_leaf) {
469
496
  // only left child node is valid
470
- array_copy(float32, leafOffset0, float32, offset, 6);
497
+ array_copy(float32, leaf_offset_0, float32, offset, 6);
471
498
  } else {
472
499
  //initialize to 0-size box same position as previous node
473
500
  copy_box_zero_size(this.__data_float32, offset, (offset - BVH_BINARY_NODE_SIZE));
@@ -19,7 +19,7 @@ test('0 leaf tree must have a no binary nodes', () => {
19
19
  bvh.initialize_structure();
20
20
  bvh.build();
21
21
 
22
- expect(bvh.getBinaryNodeCount()).toBe(0);
22
+ expect(bvh.binary_node_count).toBe(0);
23
23
  });
24
24
 
25
25
  test('1 leaf tree must have a single binary node', () => {
@@ -29,7 +29,7 @@ test('1 leaf tree must have a single binary node', () => {
29
29
  bvh.initialize_structure();
30
30
  bvh.build();
31
31
 
32
- expect(bvh.getBinaryNodeCount()).toBe(1);
32
+ expect(bvh.binary_node_count).toBe(1);
33
33
  });
34
34
 
35
35
  test('4 leaf tree must have a 3 binary nodes', () => {
@@ -39,7 +39,7 @@ test('4 leaf tree must have a 3 binary nodes', () => {
39
39
  bvh.initialize_structure();
40
40
  bvh.build();
41
41
 
42
- expect(bvh.getBinaryNodeCount()).toBe(3);
42
+ expect(bvh.binary_node_count).toBe(3);
43
43
  });
44
44
 
45
45
  test('read/write 1 leaf', () => {
@@ -0,0 +1,94 @@
1
+ import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
2
+ import {
3
+ aabb3_array_intersects_clipping_volume_array
4
+ } from "../../../geom/3d/aabb/aabb3_array_intersects_clipping_volume_array.js";
5
+
6
+ const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
7
+
8
+ /**
9
+ *
10
+ * @param {number[]} result
11
+ * @param {number} result_offset
12
+ * @param {BinaryUint32BVH} bvh
13
+ * @param {Float32Array|number[]} planes
14
+ * @param {number} planes_offset
15
+ * @param {number} plane_count
16
+ * @returns {number}
17
+ */
18
+ export function bvh32_query_user_data_overlaps_clipping_volume(
19
+ result, result_offset,
20
+ bvh,
21
+ planes, planes_offset, plane_count
22
+ ) {
23
+ let hit_count = 0;
24
+
25
+ const binary_node_count = bvh.binary_node_count;
26
+
27
+ if (binary_node_count <= 0) {
28
+ // this should not happen
29
+ return 0;
30
+ }
31
+
32
+ /**
33
+ *
34
+ * @type {number}
35
+ */
36
+ const stack_top = stack.pointer++;
37
+
38
+ /**
39
+ * After performing empirical tests, stack-based depth-first traversal turns out faster than using a queue
40
+ * @type {number}
41
+ */
42
+ stack[stack_top] = 0;
43
+
44
+ const last_valid_index = binary_node_count + bvh.leaf_node_count;
45
+
46
+ const float32 = bvh.float32;
47
+ const uint32 = bvh.uint32;
48
+
49
+ do {
50
+ stack.pointer--;
51
+
52
+ // query_bvh_frustum_from_objects.iteration_count++;
53
+ const node_index = stack[stack.pointer];
54
+
55
+ const node_address = bvh.getNodeAddress(node_index);
56
+
57
+ if (!aabb3_array_intersects_clipping_volume_array(
58
+ float32, node_address,
59
+ planes, planes_offset, plane_count
60
+ )) {
61
+ continue;
62
+ }
63
+
64
+ const is_intermediate_node = node_index < binary_node_count;
65
+
66
+ if (is_intermediate_node) {
67
+ // is intermediate node
68
+
69
+ const left_index = (node_index << 1) + 1;
70
+ const right_index = left_index + 1;
71
+
72
+ // left node ends up on top of the stack, which aligns with the desired access sequence
73
+ if (right_index < last_valid_index) {
74
+ stack[stack.pointer++] = right_index;
75
+ // micro-optimization, since we know that right node is valid and left appears before that, left is valid too
76
+ stack[stack.pointer++] = left_index;
77
+ } else if (left_index < last_valid_index) {
78
+ stack[stack.pointer++] = left_index;
79
+ }
80
+
81
+
82
+ } else {
83
+ // leaf node
84
+
85
+ // write to output
86
+ result[result_offset + hit_count] = uint32[node_address + 6];
87
+
88
+ hit_count++;
89
+ }
90
+
91
+ } while (stack.pointer > stack_top)
92
+
93
+ return hit_count;
94
+ }
@@ -1,14 +1,13 @@
1
1
  import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
2
2
  import { aabb3_array_intersects_ray } from "../../../geom/3d/aabb/aabb3_array_intersects_ray.js";
3
- import { BVH_BINARY_NODE_SIZE, BVH_LEAF_NODE_SIZE } from "./BinaryUint32BVH.js";
4
3
 
5
4
  const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
6
5
 
7
6
  /**
8
7
  *
9
- * @param {BinaryUint32BVH} bvh
10
8
  * @param {number[]} result
11
9
  * @param {number} result_offset
10
+ * @param {BinaryUint32BVH} bvh
12
11
  * @param {number} origin_x
13
12
  * @param {number} origin_y
14
13
  * @param {number} origin_z
@@ -18,14 +17,14 @@ const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
18
17
  * @returns {number}
19
18
  */
20
19
  export function bvh32_query_user_data_ray(
21
- bvh,
22
20
  result, result_offset,
21
+ bvh,
23
22
  origin_x, origin_y, origin_z,
24
23
  direction_x, direction_y, direction_z
25
24
  ) {
26
25
  let hit_count = 0;
27
26
 
28
- const binary_node_count = bvh.getBinaryNodeCount();
27
+ const binary_node_count = bvh.binary_node_count;
29
28
 
30
29
  if (binary_node_count <= 0) {
31
30
  // this should not happen
@@ -44,7 +43,7 @@ export function bvh32_query_user_data_ray(
44
43
  */
45
44
  stack[stack_top] = 0;
46
45
 
47
- const last_valid_index = binary_node_count + bvh.getLeafNodeCount();
46
+ const last_valid_index = binary_node_count + bvh.leaf_node_count;
48
47
 
49
48
  const float32 = bvh.float32;
50
49
  const uint32 = bvh.uint32;
@@ -55,17 +54,20 @@ export function bvh32_query_user_data_ray(
55
54
  // query_bvh_frustum_from_objects.iteration_count++;
56
55
  const node_index = stack[stack.pointer];
57
56
 
58
- if (node_index < binary_node_count) {
57
+ const node_address = bvh.getNodeAddress(node_index);
58
+
59
+ if (!aabb3_array_intersects_ray(
60
+ float32, node_address,
61
+ origin_x, origin_y, origin_z,
62
+ direction_x, direction_y, direction_z
63
+ )) {
64
+ continue;
65
+ }
66
+
67
+ const is_intermediate_node = node_index < binary_node_count;
68
+
69
+ if (is_intermediate_node) {
59
70
  // is intermediate node
60
- const node_address = node_index * BVH_BINARY_NODE_SIZE;
61
-
62
- if (!aabb3_array_intersects_ray(
63
- float32, node_address,
64
- origin_x, origin_y, origin_z,
65
- direction_x, direction_y, direction_z
66
- )) {
67
- continue;
68
- }
69
71
 
70
72
  const left_index = (node_index << 1) + 1;
71
73
  const right_index = left_index + 1;
@@ -82,9 +84,6 @@ export function bvh32_query_user_data_ray(
82
84
 
83
85
  } else {
84
86
  // leaf node
85
- const leaf_index = node_index - binary_node_count;
86
-
87
- const node_address = leaf_index * BVH_LEAF_NODE_SIZE + binary_node_count * BVH_BINARY_NODE_SIZE;
88
87
 
89
88
  // write to output
90
89
  result[result_offset + hit_count] = uint32[node_address + 6];
@@ -1,4 +1,6 @@
1
- import { aabb3_array_intersects_frustum_array } from "../../../geom/3d/aabb/aabb3_array_intersects_frustum_array.js";
1
+ import {
2
+ aabb3_array_intersects_clipping_volume_array
3
+ } from "../../../geom/3d/aabb/aabb3_array_intersects_clipping_volume_array.js";
2
4
  import { BVHQuery } from "./BVHQuery.js";
3
5
 
4
6
  const scratch_aabb = [];
@@ -29,6 +31,6 @@ export class BVHQueryIntersectsFrustum extends BVHQuery {
29
31
 
30
32
  tree.node_get_aabb(node, scratch_aabb);
31
33
 
32
- return aabb3_array_intersects_frustum_array(scratch_aabb, this.frustum);
34
+ return aabb3_array_intersects_clipping_volume_array(scratch_aabb, 0, this.frustum, 0, 6);
33
35
  }
34
36
  }
@@ -3,20 +3,20 @@
3
3
  */
4
4
 
5
5
 
6
- import {assert} from "../../../assert.js";
6
+ import { assert } from "../../../assert.js";
7
7
  import computeMortonCode from "../morton/Morton.js";
8
- import {aabb3_array_intersects_point} from "./aabb3_array_intersects_point.js";
9
- import {aabb3_build_corners} from "./aabb3_build_corners.js";
10
- import {aabb3_compute_distance_above_plane_max} from "./aabb3_compute_distance_above_plane_max.js";
11
- import {aabb3_compute_plane_side} from "./aabb3_compute_plane_side.js";
12
- import {aabb3_compute_surface_area} from "./aabb3_compute_surface_area.js";
13
- import {aabb3_intersects_frustum_array} from "./aabb3_intersects_frustum_array.js";
14
- import {aabb3_intersects_frustum_degree} from "./aabb3_intersects_frustum_degree.js";
15
- import {aabb3_intersects_line_segment} from "./aabb3_intersects_line_segment.js";
16
- import {aabb3_intersects_ray} from "./aabb3_intersects_ray.js";
17
- import {aabb3_matrix4_project} from "./aabb3_matrix4_project.js";
18
- import {aabb3_signed_distance_sqr_to_point} from "./aabb3_signed_distance_sqr_to_point.js";
19
- import {aabb3_signed_distance_to_aabb3} from "./aabb3_signed_distance_to_aabb3.js";
8
+ import { aabb3_array_intersects_point } from "./aabb3_array_intersects_point.js";
9
+ import { aabb3_build_corners } from "./aabb3_build_corners.js";
10
+ import { aabb3_compute_distance_above_plane_max } from "./aabb3_compute_distance_above_plane_max.js";
11
+ import { aabb3_compute_plane_side } from "./aabb3_compute_plane_side.js";
12
+ import { aabb3_compute_surface_area } from "./aabb3_compute_surface_area.js";
13
+ import { aabb3_intersects_clipping_volume_array } from "./aabb3_intersects_clipping_volume_array.js";
14
+ import { aabb3_intersects_frustum_degree } from "./aabb3_intersects_frustum_degree.js";
15
+ import { aabb3_intersects_line_segment } from "./aabb3_intersects_line_segment.js";
16
+ import { aabb3_intersects_ray } from "./aabb3_intersects_ray.js";
17
+ import { aabb3_matrix4_project } from "./aabb3_matrix4_project.js";
18
+ import { aabb3_signed_distance_sqr_to_point } from "./aabb3_signed_distance_sqr_to_point.js";
19
+ import { aabb3_signed_distance_to_aabb3 } from "./aabb3_signed_distance_to_aabb3.js";
20
20
 
21
21
  /**
22
22
  * Axis-Aligned bounding box in 3D
@@ -850,7 +850,7 @@ export class AABB3 {
850
850
  const y1 = this.y1;
851
851
  const z1 = this.z1;
852
852
 
853
- return aabb3_intersects_frustum_array(x0, y0, z0, x1, y1, z1, frustum);
853
+ return aabb3_intersects_clipping_volume_array(x0, y0, z0, x1, y1, z1, frustum, 0, 6);
854
854
  }
855
855
 
856
856
  /**
@@ -0,0 +1,30 @@
1
+ import { aabb3_intersects_clipping_volume_array } from "./aabb3_intersects_clipping_volume_array.js";
2
+
3
+ /**
4
+ *
5
+ * @param {Float32Array|number[]} aabb
6
+ * @param {number} aabb_offset
7
+ * @param {Float32Array|number[]} planes
8
+ * @param {number} planes_offset
9
+ * @param {number} plane_count
10
+ * @return {boolean}
11
+ */
12
+ export function aabb3_array_intersects_clipping_volume_array(
13
+ aabb, aabb_offset,
14
+ planes, planes_offset, plane_count
15
+ ) {
16
+
17
+ const x0 = aabb[aabb_offset + 0];
18
+ const y0 = aabb[aabb_offset + 1];
19
+ const z0 = aabb[aabb_offset + 2];
20
+ const x1 = aabb[aabb_offset + 3];
21
+ const y1 = aabb[aabb_offset + 4];
22
+ const z1 = aabb[aabb_offset + 5];
23
+
24
+ return aabb3_intersects_clipping_volume_array(
25
+ x0, y0, z0,
26
+ x1, y1, z1,
27
+ planes, planes_offset, plane_count
28
+ );
29
+ }
30
+
@@ -0,0 +1,51 @@
1
+ import { assert } from "../../../assert.js";
2
+ import { aabb3_compute_distance_above_plane_max } from "./aabb3_compute_distance_above_plane_max.js";
3
+
4
+ /**
5
+ * Tests whether AABB intersects a clipping volume defined by a set of planes
6
+ * Mainly useful for frustum checks
7
+ * @param {number} x0
8
+ * @param {number} y0
9
+ * @param {number} z0
10
+ * @param {number} x1
11
+ * @param {number} y1
12
+ * @param {number} z1
13
+ * @param {ArrayLike<number>|number[]|Float32Array|Float64Array} planes
14
+ * @param {number} planes_offset
15
+ * @param {number} plane_count
16
+ * @return {boolean}
17
+ */
18
+ export function aabb3_intersects_clipping_volume_array(
19
+ x0, y0, z0,
20
+ x1, y1, z1,
21
+ planes, planes_offset, plane_count
22
+ ) {
23
+
24
+ assert.isNonNegativeInteger(planes_offset, 'frustum_offset');
25
+
26
+ const limit = plane_count * 4;
27
+
28
+ for (let i = 0; i < limit; i += 4) {
29
+
30
+ const offset = planes_offset + i;
31
+
32
+ const plane_x = planes[offset];
33
+ const plane_y = planes[offset + 1];
34
+ const plane_z = planes[offset + 2];
35
+ const plane_w = planes[offset + 3];
36
+
37
+ const plane_distance = aabb3_compute_distance_above_plane_max(
38
+ plane_x, plane_y, plane_z, plane_w,
39
+ x0, y0, z0,
40
+ x1, y1, z1
41
+ );
42
+
43
+ if (plane_distance < 0) {
44
+ return false;
45
+ }
46
+
47
+ }
48
+
49
+ return true;
50
+
51
+ }
@@ -5,10 +5,12 @@ import { assert } from "../../../assert.js";
5
5
  * @param {Plane[]} planes
6
6
  * @param {ArrayLike<number>|number[]|Float32Array|Float64Array} array
7
7
  */
8
- export function read_frustum_planes_to_array(planes, array) {
9
- assert.greaterThanOrEqual(array.length, 24, 'target array is too small');
8
+ export function read_three_planes_to_array(planes, array) {
9
+ const plane_count = planes.length;
10
10
 
11
- for (let i = 0; i < 6; i++) {
11
+ assert.greaterThanOrEqual(array.length, plane_count * 4, 'target array is too small');
12
+
13
+ for (let i = 0; i < plane_count; i++) {
12
14
  const plane = planes[i];
13
15
 
14
16
  const offset = i * 4;
@@ -0,0 +1,51 @@
1
+ import { computeTrianglePlaneSide } from "./computeTrianglePlaneSide.js";
2
+
3
+ /**
4
+ * @param {number[]|Float32Array} planes
5
+ * @param {number} planes_offset
6
+ * @param {number} plane_count
7
+ * @param {number} ax
8
+ * @param {number} ay
9
+ * @param {number} az
10
+ * @param {number} bx
11
+ * @param {number} by
12
+ * @param {number} bz
13
+ * @param {number} cx
14
+ * @param {number} cy
15
+ * @param {number} cz
16
+ * @returns {boolean}
17
+ */
18
+ export function triangle_intersects_clipping_volume(
19
+ planes, planes_offset, plane_count,
20
+ ax, ay, az,
21
+ bx, by, bz,
22
+ cx, cy, cz
23
+ ) {
24
+
25
+ for (let j = 0; j < plane_count; j++) {
26
+
27
+ const plane_address = planes_offset + j * 4;
28
+
29
+ const plane_normal_x = planes[plane_address];
30
+ const plane_normal_y = planes[plane_address + 1];
31
+ const plane_normal_z = planes[plane_address + 2];
32
+ const plane_constant = planes[plane_address + 3];
33
+
34
+ const side = computeTrianglePlaneSide(
35
+ plane_normal_x,
36
+ plane_normal_y,
37
+ plane_normal_z,
38
+ plane_constant,
39
+ ax, ay, az,
40
+ bx, by, bz,
41
+ cx, cy, cz
42
+ );
43
+
44
+ if (side === -3) {
45
+ // fully outside
46
+ return false;
47
+ }
48
+ }
49
+
50
+ return true;
51
+ }
@@ -4,7 +4,7 @@ import {
4
4
  bvh_query_user_data_overlaps_frustum
5
5
  } from "../../../../core/bvh2/bvh3/query/bvh_query_user_data_overlaps_frustum.js";
6
6
  import { noop } from "../../../../core/function/Functions.js";
7
- import { read_frustum_planes_to_array } from "../../../../core/geom/3d/frustum/read_frustum_planes_to_array.js";
7
+ import { read_three_planes_to_array } from "../../../../core/geom/3d/frustum/read_three_planes_to_array.js";
8
8
  import { MATRIX_4_IDENTITY } from "../../../../core/geom/3d/matrix/MATRIX_4_IDENTITY.js";
9
9
  import { ImageRGBADataLoader } from "../../../asset/loaders/image/ImageRGBADataLoader.js";
10
10
  import { CameraSystem } from '../../../graphics/ecs/camera/CameraSystem.js';
@@ -255,7 +255,7 @@ class TerrainSystem extends System {
255
255
 
256
256
  for (let i = 0; i < frustums.length; i++) {
257
257
 
258
- read_frustum_planes_to_array(frustums[i].planes, frustum);
258
+ read_three_planes_to_array(frustums[i].planes, frustum);
259
259
 
260
260
  found_tiles += bvh_query_user_data_overlaps_frustum(tiles, tile_count, tileManager.bvh, frustum);
261
261
  }
@@ -70,7 +70,7 @@ export function makeTerrainWorkerProxy() {
70
70
  resolve({
71
71
  geometry: geometry,
72
72
  bvh: {
73
- leaf_count: bvh.getLeafNodeCount(),
73
+ leaf_count: bvh.leaf_node_count,
74
74
  data: bvh.data
75
75
  }
76
76
  });
@@ -13,7 +13,6 @@ import {
13
13
  Vector3 as ThreeVector3
14
14
  } from 'three';
15
15
  import { BinaryUint32BVH } from "../../../../core/bvh2/binary/2/BinaryUint32BVH.js";
16
- import { bvh32_query_user_data_ray } from "../../../../core/bvh2/binary/2/bvh32_query_user_data_ray.js";
17
16
  import { BvhClient } from "../../../../core/bvh2/bvh3/BvhClient.js";
18
17
  import { array_copy } from "../../../../core/collection/array/array_copy.js";
19
18
  import Signal from "../../../../core/events/signal/Signal.js";
@@ -21,11 +20,11 @@ import { AABB3 } from "../../../../core/geom/3d/aabb/AABB3.js";
21
20
  import { ray3_array_apply_matrix4 } from "../../../../core/geom/3d/ray/ray3_array_apply_matrix4.js";
22
21
  import { ray3_array_compose } from "../../../../core/geom/3d/ray/ray3_array_compose.js";
23
22
  import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
24
- import { computeTriangleRayIntersection } from "../../../../core/geom/3d/triangle/computeTriangleRayIntersection.js";
25
23
  import Vector2 from '../../../../core/geom/Vector2.js';
26
24
  import Vector3 from '../../../../core/geom/Vector3.js';
27
25
  import { NumericInterval } from "../../../../core/math/interval/NumericInterval.js";
28
26
  import ObservedInteger from "../../../../core/model/ObservedInteger.js";
27
+ import { bvh32_geometry_raycast } from "../../../graphics/geometry/buffered/query/bvh32_geometry_raycast.js";
29
28
 
30
29
  import ThreeFactory from '../../../graphics/three/ThreeFactory.js';
31
30
 
@@ -33,9 +32,6 @@ import ThreeFactory from '../../../graphics/three/ThreeFactory.js';
33
32
  const EMPTY_GEOMETRY = new ThreeBufferGeometry();
34
33
  const DEFAULT_MATERIAL = new MeshBasicMaterial();
35
34
 
36
- const scratch_array = []
37
- const scratch_hit = new SurfacePoint3()
38
-
39
35
  const ray_tmp = [];
40
36
  const m4_tmp = [];
41
37
 
@@ -191,52 +187,19 @@ class TerrainTile {
191
187
  const _directionY = ray_tmp[4];
192
188
  const _directionZ = ray_tmp[5];
193
189
 
194
- const hit_count = bvh32_query_user_data_ray(
195
- this.bvh,
196
- scratch_array, 0,
197
- _originX, _originY, _originZ,
198
- _directionX, _directionY, _directionZ
199
- );
200
-
201
- let best_distance = Infinity;
202
- let hit_found = false;
203
-
204
190
  const geometry = this.geometry;
205
191
 
206
192
  const geometryIndices = geometry.getIndex().array;
207
193
  const geometryPositions = geometry.getAttribute('position').array;
208
194
 
209
- for (let i = 0; i < hit_count; i++) {
210
- const triangle_index = scratch_array[i];
211
-
212
- const index3 = triangle_index * 3;
213
-
214
- const a = geometryIndices[index3] * 3;
215
- const b = geometryIndices[index3 + 1] * 3;
216
- const c = geometryIndices[index3 + 2] * 3;
217
-
218
- const triangle_hit_found = computeTriangleRayIntersection(
219
- scratch_hit,
220
- _originX, _originY, _originZ,
221
- _directionX, _directionY, _directionZ,
222
- geometryPositions[a], geometryPositions[a + 1], geometryPositions[a + 2],
223
- geometryPositions[b], geometryPositions[b + 1], geometryPositions[b + 2],
224
- geometryPositions[c], geometryPositions[c + 1], geometryPositions[c + 2],
225
- )
226
-
227
- if (!triangle_hit_found) {
228
- continue;
229
- }
230
-
231
- hit_found = true;
232
-
233
- const distance_sqr = scratch_hit.position._distanceSqrTo(_originX, _originY, _originZ);
234
-
235
- if (distance_sqr < best_distance) {
236
- best_distance = distance_sqr;
237
- result.copy(scratch_hit);
238
- }
239
- }
195
+ let hit_found = bvh32_geometry_raycast(
196
+ result,
197
+ this.bvh,
198
+ geometryPositions, 0, 3,
199
+ geometryIndices,
200
+ _originX, _originY, _originZ,
201
+ _directionX, _directionY, _directionZ
202
+ );
240
203
 
241
204
  if (hit_found) {
242
205
  result.applyMatrix4(m4);