@woosh/meep-engine 2.68.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.
- package/build/bundle-worker-terrain.js +1 -1
- package/build/meep.cjs +698 -1269
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +698 -1269
- package/package.json +1 -1
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +55 -28
- package/src/core/bvh2/binary/2/BinaryUint32BVH.spec.js +3 -3
- package/src/core/bvh2/binary/2/bvh32_query_user_data_overlaps_clipping_volume.js +94 -0
- package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +17 -18
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +4 -2
- package/src/core/geom/3d/aabb/AABB3.js +14 -14
- package/src/core/geom/3d/aabb/aabb3_array_intersects_clipping_volume_array.js +30 -0
- package/src/core/geom/3d/aabb/aabb3_intersects_clipping_volume_array.js +51 -0
- package/src/core/geom/3d/frustum/{read_frustum_planes_to_array.js → read_three_planes_to_array.js} +5 -3
- package/src/core/geom/3d/triangle/triangle_intersects_clipping_volume.js +51 -0
- package/src/engine/ecs/terrain/ecs/TerrainSystem.js +2 -2
- package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +9 -46
- package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.d.ts +2 -2
- package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +79 -36
- package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_overlap_clipping_volume.js +88 -0
- package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.js +108 -0
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +4 -30
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_unindexed_geometry.js +30 -0
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_set_leaf_from_triangle.js +41 -0
- package/src/engine/graphics/render/forward_plus/LightManager.js +2 -2
- package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +2 -2
- package/src/engine/graphics/render/view/CameraView.js +8 -8
- package/src/core/bvh2/binary/BinaryBVH.js +0 -281
- package/src/core/bvh2/binary/IndexedBinaryBVH.js +0 -407
- package/src/core/bvh2/binary/IndexedBinaryBVH.spec.js +0 -27
- package/src/core/bvh2/binary/IndexedBinaryBVHVisitor.js +0 -11
- package/src/core/bvh2/binary/NodeType.js +0 -8
- package/src/core/bvh2/binary/RayLeafIntersectionVisitor.js +0 -59
- package/src/core/geom/3d/aabb/aabb3_array_intersects_frustum_array.js +0 -20
- package/src/core/geom/3d/aabb/aabb3_intersects_frustum_array.js +0 -35
- package/src/engine/graphics/geometry/buffered/query/ClippingPlaneContainmentComputingVisitor.js +0 -195
- package/src/engine/graphics/geometry/buffered/query/GeometryVisitor.js +0 -87
- package/src/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +0 -206
- package/src/engine/graphics/geometry/bvh/buffered/BinaryBVHFromBufferGeometry.js +0 -123
package/package.json
CHANGED
|
@@ -100,34 +100,41 @@ export class BinaryUint32BVH {
|
|
|
100
100
|
*/
|
|
101
101
|
__data_uint32;
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
133
|
+
get binary_node_count() {
|
|
127
134
|
return this.__node_count_binary;
|
|
128
135
|
}
|
|
129
136
|
|
|
130
|
-
|
|
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}
|
|
159
|
+
* @param {ArrayBuffer} buffer
|
|
153
160
|
*/
|
|
154
|
-
set data(
|
|
155
|
-
|
|
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
|
|
456
|
-
const
|
|
482
|
+
const leaf_index_0 = i * 2;
|
|
483
|
+
const leaf_index_1 = leaf_index_0 + 1;
|
|
457
484
|
|
|
458
|
-
const
|
|
459
|
-
const
|
|
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 (
|
|
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,
|
|
466
|
-
float32,
|
|
492
|
+
float32, leaf_offset_0,
|
|
493
|
+
float32, leaf_offset_1
|
|
467
494
|
);
|
|
468
|
-
} else if (
|
|
495
|
+
} else if (leaf_index_0 < node_count_leaf) {
|
|
469
496
|
// only left child node is valid
|
|
470
|
-
array_copy(float32,
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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 {
|
|
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
|
|
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
|
+
}
|
package/src/core/geom/3d/frustum/{read_frustum_planes_to_array.js → read_three_planes_to_array.js}
RENAMED
|
@@ -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
|
|
9
|
-
|
|
8
|
+
export function read_three_planes_to_array(planes, array) {
|
|
9
|
+
const plane_count = planes.length;
|
|
10
10
|
|
|
11
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
}
|
|
@@ -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
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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);
|