@woosh/meep-engine 2.138.3 → 2.138.5
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/package.json +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts +13 -5
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js +253 -280
- package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.js +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.d.ts +31 -0
- package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.d.ts.map +1 -0
- package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js +101 -0
- package/src/core/cache/CacheV2.d.ts +6 -2
- package/src/core/cache/CacheV2.d.ts.map +1 -1
- package/src/core/cache/CacheV2.js +6 -2
- package/src/engine/EngineHarness.js +2 -2
- package/src/engine/ecs/renderable/RenderSystem.d.ts.map +1 -1
- package/src/engine/ecs/renderable/RenderSystem.js +6 -0
- package/src/engine/ecs/terrain/ecs/TerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/TerrainSystem.js +19 -0
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.d.ts +4 -1
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.js +121 -12
- package/src/engine/graphics/ecs/light/LightSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/light/LightSystem.js +80 -18
- package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.d.ts +14 -0
- package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.d.ts.map +1 -0
- package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.js +62 -0
- package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.d.ts +30 -0
- package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.d.ts.map +1 -0
- package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.js +97 -0
- package/src/engine/graphics/ecs/mesh/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh/MeshSystem.js +6 -0
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +6 -0
- package/src/engine/graphics/ecs/trail2d/Trail2DSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail2d/Trail2DSystem.js +6 -0
- package/src/engine/graphics/ecs/water/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterSystem.js +6 -0
- package/src/engine/graphics/impostors/octahedral/prototypeBaker.js +7 -10
- package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +139 -57
- package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderWireframeV0.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderWireframeV0.js +123 -38
- package/src/engine/graphics/impostors/octahedral/util/makeImpostorAtlasPreview.d.ts +1 -1
- package/src/engine/graphics/impostors/octahedral/util/makeImpostorAtlasPreview.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/util/makeImpostorAtlasPreview.js +7 -3
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +6 -0
- package/src/engine/graphics/render/layers/RenderLayer.d.ts +2 -0
- package/src/engine/graphics/render/layers/RenderLayer.d.ts.map +1 -1
- package/src/engine/graphics/render/layers/RenderLayer.js +14 -0
- package/src/engine/intelligence/mcts/MonteCarlo.js +1 -1
- package/src/engine/graphics/ecs/camera/FrustumProjector.d.ts +0 -14
- package/src/engine/graphics/ecs/camera/FrustumProjector.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/FrustumProjector.js +0 -86
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"description": "Pure JavaScript game engine. Fully featured and production ready.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.138.
|
|
8
|
+
"version": "2.138.5",
|
|
9
9
|
"main": "build/meep.module.js",
|
|
10
10
|
"module": "build/meep.module.js",
|
|
11
11
|
"exports": {
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Build a binary radix tree over the given leaves and Morton codes.
|
|
3
|
+
*
|
|
3
4
|
* @param {BVH} bvh
|
|
4
5
|
* @param {number[]|Uint32Array} leaf_nodes
|
|
5
|
-
*
|
|
6
|
+
* Pre-allocated leaf node IDs, ordered to match `sorted_morton_codes`
|
|
7
|
+
* (i.e. leaf_nodes[i]'s code is sorted_morton_codes[i]).
|
|
8
|
+
* @param {number[]|Uint32Array} sorted_morton_codes
|
|
9
|
+
* Morton codes in non-decreasing order. May contain duplicates.
|
|
6
10
|
* @param {number} leaf_count
|
|
7
|
-
*
|
|
8
|
-
*
|
|
11
|
+
* Number of leaves (must equal the length of `leaf_nodes` and
|
|
12
|
+
* `sorted_morton_codes` that the function will actually look at).
|
|
13
|
+
* @param {number[]|Uint32Array} internal_nodes
|
|
14
|
+
* Pre-allocated internal node IDs, of length at least `leaf_count - 1`.
|
|
15
|
+
* Ignored when leaf_count < 2.
|
|
16
|
+
* @returns {number} The root node id, or NULL_NODE if leaf_count is 0.
|
|
9
17
|
*/
|
|
10
|
-
export function ebvh_build_hierarchy_radix(bvh: BVH, leaf_nodes: number[] | Uint32Array, sorted_morton_codes: number[], leaf_count: number, internal_nodes: number[]): number;
|
|
18
|
+
export function ebvh_build_hierarchy_radix(bvh: BVH, leaf_nodes: number[] | Uint32Array, sorted_morton_codes: number[] | Uint32Array, leaf_count: number, internal_nodes: number[] | Uint32Array): number;
|
|
11
19
|
//# sourceMappingURL=ebvh_build_hierarchy_radix.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ebvh_build_hierarchy_radix.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ebvh_build_hierarchy_radix.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js"],"names":[],"mappings":"AA4KA;;;;;;;;;;;;;;;;GAgBG;AACH,iEAbW,MAAM,EAAE,GAAC,WAAW,uBAGpB,MAAM,EAAE,GAAC,WAAW,cAEpB,MAAM,kBAGN,MAAM,EAAE,GAAC,WAAW,GAGlB,MAAM,CAiElB"}
|
|
@@ -1,280 +1,253 @@
|
|
|
1
|
-
import { assert } from "../../assert.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
let length = 0;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
*
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Select childB.
|
|
257
|
-
|
|
258
|
-
let childB;
|
|
259
|
-
if (split + 1 === last) {
|
|
260
|
-
childB = leaf_nodes[split + 1];
|
|
261
|
-
} else {
|
|
262
|
-
childB = internal_nodes[split + 1];
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Record parent-child relationships.
|
|
266
|
-
const parent = internal_nodes[idx];
|
|
267
|
-
|
|
268
|
-
bvh.node_assign_children_only(parent, childA, childB);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Node 0 is the root.
|
|
272
|
-
const root = internal_nodes[0];
|
|
273
|
-
|
|
274
|
-
bvh.node_set_parent(root, NULL_NODE);
|
|
275
|
-
|
|
276
|
-
// update bounds
|
|
277
|
-
ebvh_update_hierarchy_bounds(bvh, root);
|
|
278
|
-
|
|
279
|
-
return root;
|
|
280
|
-
}
|
|
1
|
+
import { assert } from "../../assert.js";
|
|
2
|
+
import { NULL_NODE } from "./BVH.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Karras 2012 — "Maximizing Parallelism in the Construction of BVHs, Octrees, and k-d Trees".
|
|
6
|
+
*
|
|
7
|
+
* For a sorted array of N Morton codes, build a binary radix tree of N-1 internal
|
|
8
|
+
* nodes and N leaves. Each internal node corresponds to the longest common prefix
|
|
9
|
+
* of a contiguous range of Morton codes; its split point is where the first bit
|
|
10
|
+
* after that prefix flips from 0 to 1.
|
|
11
|
+
*
|
|
12
|
+
* The caller must pre-allocate:
|
|
13
|
+
* - `leaf_count` leaf nodes in `bvh`, each with its AABB and user-data set;
|
|
14
|
+
* their IDs are passed in `leaf_nodes`, sorted by `sorted_morton_codes`.
|
|
15
|
+
* - `leaf_count - 1` internal nodes (when `leaf_count >= 2`); their IDs are
|
|
16
|
+
* passed in `internal_nodes`, in arbitrary order.
|
|
17
|
+
*
|
|
18
|
+
* The returned root index is wired into the tree; internal-node bounds and
|
|
19
|
+
* heights are filled in by a bottom-up refit after structural construction.
|
|
20
|
+
*
|
|
21
|
+
* @see "Thinking Parallel, Part III: Tree Construction on the GPU", 2012 by Tero Karras
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Compute the position of the first bit where the codes at `first` and `last`
|
|
26
|
+
* differ in their longest-common-prefix sense — i.e. the split point for the
|
|
27
|
+
* range [first, last]. Returns an index `s` such that all codes in [first, s]
|
|
28
|
+
* share more leading bits with the firstCode than codes in [s+1, last] do.
|
|
29
|
+
*
|
|
30
|
+
* @param {number[]|Uint32Array} sortedMortonCodes
|
|
31
|
+
* @param {number} first
|
|
32
|
+
* @param {number} last
|
|
33
|
+
* @return {number}
|
|
34
|
+
*/
|
|
35
|
+
function find_split(sortedMortonCodes, first, last) {
|
|
36
|
+
const firstCode = sortedMortonCodes[first];
|
|
37
|
+
const lastCode = sortedMortonCodes[last];
|
|
38
|
+
|
|
39
|
+
// Identical Morton codes (multiple leaves at the same point): split the
|
|
40
|
+
// range in the middle so we still build a balanced subtree.
|
|
41
|
+
if (firstCode === lastCode) {
|
|
42
|
+
return (first + last) >>> 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Number of highest bits that match between first and last.
|
|
46
|
+
const commonPrefix = Math.clz32(firstCode ^ lastCode);
|
|
47
|
+
|
|
48
|
+
// Binary search for the highest index that still shares more than
|
|
49
|
+
// `commonPrefix` bits with the firstCode.
|
|
50
|
+
let split = first;
|
|
51
|
+
let step = last - first;
|
|
52
|
+
|
|
53
|
+
do {
|
|
54
|
+
step = (step + 1) >>> 1;
|
|
55
|
+
const newSplit = split + step;
|
|
56
|
+
|
|
57
|
+
if (newSplit < last) {
|
|
58
|
+
const splitCode = sortedMortonCodes[newSplit];
|
|
59
|
+
const splitPrefix = Math.clz32(firstCode ^ splitCode);
|
|
60
|
+
if (splitPrefix > commonPrefix) {
|
|
61
|
+
split = newSplit;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} while (step > 1);
|
|
65
|
+
|
|
66
|
+
return split;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Determine the [first, last] code range covered by internal node `idx`.
|
|
71
|
+
*
|
|
72
|
+
* @see https://github.com/mbartling/cuda-bvh/blob/7f2f98d9d29956c3559632e59104ba66f31f80b8/kernels/bvh.cu#L276
|
|
73
|
+
* @param {number[]|Uint32Array} output 2-element output [first, last]
|
|
74
|
+
* @param {number[]|Uint32Array} sortedMortonCodes
|
|
75
|
+
* @param {number} leaf_count
|
|
76
|
+
* @param {number} idx
|
|
77
|
+
*/
|
|
78
|
+
function determineRange(output, sortedMortonCodes, leaf_count, idx) {
|
|
79
|
+
// For the root (idx === 0) the range is unambiguously [0, leaf_count - 1].
|
|
80
|
+
// We short-circuit so callers don't have to special-case it.
|
|
81
|
+
if (idx === 0) {
|
|
82
|
+
output[0] = 0;
|
|
83
|
+
output[1] = leaf_count - 1;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const codeIdx = sortedMortonCodes[idx];
|
|
88
|
+
const prefixRight = Math.clz32(codeIdx ^ sortedMortonCodes[idx + 1]);
|
|
89
|
+
const prefixLeft = Math.clz32(codeIdx ^ sortedMortonCodes[idx - 1]);
|
|
90
|
+
|
|
91
|
+
const direction = (prefixRight - prefixLeft) > 0 ? 1 : -1;
|
|
92
|
+
|
|
93
|
+
// Minimum prefix length we require to stay in this range — anything that
|
|
94
|
+
// shares fewer bits than this is "outside" the node's subtree.
|
|
95
|
+
const min_prefix_range = Math.clz32(codeIdx ^ sortedMortonCodes[idx - direction]);
|
|
96
|
+
|
|
97
|
+
// Expand maximum range with exponential growth, bounded by array.
|
|
98
|
+
let lmax = 2;
|
|
99
|
+
let next_key = idx + lmax * direction;
|
|
100
|
+
|
|
101
|
+
while (
|
|
102
|
+
next_key >= 0 &&
|
|
103
|
+
next_key < leaf_count &&
|
|
104
|
+
Math.clz32(codeIdx ^ sortedMortonCodes[next_key]) > min_prefix_range
|
|
105
|
+
) {
|
|
106
|
+
lmax *= 2;
|
|
107
|
+
next_key = idx + lmax * direction;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Binary-search for the actual length within [0, lmax].
|
|
111
|
+
let length = 0;
|
|
112
|
+
do {
|
|
113
|
+
lmax = (lmax + 1) >> 1;
|
|
114
|
+
const new_val = idx + (length + lmax) * direction;
|
|
115
|
+
|
|
116
|
+
if (new_val >= 0 && new_val < leaf_count) {
|
|
117
|
+
const prefix = Math.clz32(codeIdx ^ sortedMortonCodes[new_val]);
|
|
118
|
+
if (prefix > min_prefix_range) {
|
|
119
|
+
length += lmax;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} while (lmax > 1);
|
|
123
|
+
|
|
124
|
+
const j = idx + length * direction;
|
|
125
|
+
|
|
126
|
+
output[0] = Math.min(idx, j);
|
|
127
|
+
output[1] = Math.max(idx, j);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Bottom-up bounds and height refit for a radix-built tree.
|
|
132
|
+
*
|
|
133
|
+
* Walks the tree once in pre-order to collect every reachable node, then
|
|
134
|
+
* processes them in reverse — which is post-order for trees — combining
|
|
135
|
+
* each internal node's AABB from its children and updating its height.
|
|
136
|
+
*
|
|
137
|
+
* @param {BVH} bvh
|
|
138
|
+
* @param {number} root
|
|
139
|
+
*/
|
|
140
|
+
function refit_radix_tree(bvh, root) {
|
|
141
|
+
if (root === NULL_NODE) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const order = [];
|
|
146
|
+
const stack = [root];
|
|
147
|
+
|
|
148
|
+
while (stack.length > 0) {
|
|
149
|
+
const node = stack.pop();
|
|
150
|
+
order.push(node);
|
|
151
|
+
|
|
152
|
+
if (!bvh.node_is_leaf(node)) {
|
|
153
|
+
stack.push(bvh.node_get_child1(node));
|
|
154
|
+
stack.push(bvh.node_get_child2(node));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
159
|
+
const node = order[i];
|
|
160
|
+
if (bvh.node_is_leaf(node)) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const c1 = bvh.node_get_child1(node);
|
|
164
|
+
const c2 = bvh.node_get_child2(node);
|
|
165
|
+
bvh.node_set_combined_aabb(node, c1, c2);
|
|
166
|
+
bvh.node_set_height(
|
|
167
|
+
node,
|
|
168
|
+
1 + Math.max(bvh.node_get_height(c1), bvh.node_get_height(c2))
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Build a binary radix tree over the given leaves and Morton codes.
|
|
175
|
+
*
|
|
176
|
+
* @param {BVH} bvh
|
|
177
|
+
* @param {number[]|Uint32Array} leaf_nodes
|
|
178
|
+
* Pre-allocated leaf node IDs, ordered to match `sorted_morton_codes`
|
|
179
|
+
* (i.e. leaf_nodes[i]'s code is sorted_morton_codes[i]).
|
|
180
|
+
* @param {number[]|Uint32Array} sorted_morton_codes
|
|
181
|
+
* Morton codes in non-decreasing order. May contain duplicates.
|
|
182
|
+
* @param {number} leaf_count
|
|
183
|
+
* Number of leaves (must equal the length of `leaf_nodes` and
|
|
184
|
+
* `sorted_morton_codes` that the function will actually look at).
|
|
185
|
+
* @param {number[]|Uint32Array} internal_nodes
|
|
186
|
+
* Pre-allocated internal node IDs, of length at least `leaf_count - 1`.
|
|
187
|
+
* Ignored when leaf_count < 2.
|
|
188
|
+
* @returns {number} The root node id, or NULL_NODE if leaf_count is 0.
|
|
189
|
+
*/
|
|
190
|
+
export function ebvh_build_hierarchy_radix(
|
|
191
|
+
bvh,
|
|
192
|
+
leaf_nodes,
|
|
193
|
+
sorted_morton_codes,
|
|
194
|
+
leaf_count,
|
|
195
|
+
internal_nodes
|
|
196
|
+
) {
|
|
197
|
+
assert.isNonNegativeInteger(leaf_count, 'leaf_count');
|
|
198
|
+
|
|
199
|
+
// Empty input: nothing to build.
|
|
200
|
+
if (leaf_count === 0) {
|
|
201
|
+
return NULL_NODE;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Single leaf is its own root; no internal node needed.
|
|
205
|
+
if (leaf_count === 1) {
|
|
206
|
+
const root = leaf_nodes[0];
|
|
207
|
+
bvh.node_set_parent(root, NULL_NODE);
|
|
208
|
+
return root;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// General case: build leaf_count - 1 internal nodes per Karras 2012.
|
|
212
|
+
const range = new Uint32Array(2);
|
|
213
|
+
const internal_node_count = leaf_count - 1;
|
|
214
|
+
|
|
215
|
+
for (let idx = 0; idx < internal_node_count; idx++) {
|
|
216
|
+
determineRange(range, sorted_morton_codes, leaf_count, idx);
|
|
217
|
+
|
|
218
|
+
const first = range[0];
|
|
219
|
+
const last = range[1];
|
|
220
|
+
|
|
221
|
+
const split = find_split(sorted_morton_codes, first, last);
|
|
222
|
+
assert.isNonNegativeInteger(split, 'split');
|
|
223
|
+
|
|
224
|
+
// child A: the [first, split] subrange's owner. If that subrange is a
|
|
225
|
+
// single element it's a leaf; otherwise it's the internal node at
|
|
226
|
+
// index `split` (Karras's convention: internal node k owns the range
|
|
227
|
+
// whose left boundary is at code-index k).
|
|
228
|
+
const childA = (split === first)
|
|
229
|
+
? leaf_nodes[split]
|
|
230
|
+
: internal_nodes[split];
|
|
231
|
+
|
|
232
|
+
// child B: the [split+1, last] subrange's owner.
|
|
233
|
+
const childB = (split + 1 === last)
|
|
234
|
+
? leaf_nodes[split + 1]
|
|
235
|
+
: internal_nodes[split + 1];
|
|
236
|
+
|
|
237
|
+
const parent = internal_nodes[idx];
|
|
238
|
+
bvh.node_assign_children_only(parent, childA, childB);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Internal node 0 covers [0, leaf_count - 1] — the whole tree — and is
|
|
242
|
+
// therefore the root.
|
|
243
|
+
const root = internal_nodes[0];
|
|
244
|
+
bvh.node_set_parent(root, NULL_NODE);
|
|
245
|
+
|
|
246
|
+
// Walk back up to fill in correct AABBs and heights for every internal
|
|
247
|
+
// node. Heights set during construction by node_assign_children_only are
|
|
248
|
+
// stale because children may not have been built yet at parent-creation
|
|
249
|
+
// time.
|
|
250
|
+
refit_radix_tree(bvh, root);
|
|
251
|
+
|
|
252
|
+
return root;
|
|
253
|
+
}
|
|
@@ -107,7 +107,7 @@ export function ebvh_update_hierarchy_bounds(bvh, root = bvh.root) {
|
|
|
107
107
|
|
|
108
108
|
} else if (came_from_type === CAME_FROM_TYPE_PARENT) {
|
|
109
109
|
const child1 = bvh.node_get_child1(node);
|
|
110
|
-
const child2 = bvh.
|
|
110
|
+
const child2 = bvh.node_get_child2(node);
|
|
111
111
|
|
|
112
112
|
if (child1 !== NULL_NODE) {
|
|
113
113
|
came_from_type = CAME_FROM_TYPE_PARENT;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk a BVH and, for each node-AABB overlapping the frustum, update the
|
|
3
|
+
* running (min, max) distance from those AABBs to a plane. Used to compute the
|
|
4
|
+
* tight near/far range a camera needs to contain all visible content along its
|
|
5
|
+
* view direction.
|
|
6
|
+
*
|
|
7
|
+
* Distances are measured along the plane normal: positive when the AABB sits
|
|
8
|
+
* on the side the normal points to. Range starts wide and shrinks per AABB —
|
|
9
|
+
* caller may pre-seed `result` (e.g. to chain BVHs) and read back the
|
|
10
|
+
* accumulated range.
|
|
11
|
+
*
|
|
12
|
+
* Resolves at AABB granularity. Nodes fully inside the frustum take a fast
|
|
13
|
+
* path (no further recursion) and contribute their full AABB extent, which
|
|
14
|
+
* may overstate the range slightly when the AABB extends past the frustum
|
|
15
|
+
* walls; for clipping plane fitting that's the right (conservative) tradeoff.
|
|
16
|
+
*
|
|
17
|
+
* @param {{near:number, far:number}} result accumulator — mutated in place.
|
|
18
|
+
* Initialize {near: +Infinity, far: -Infinity} on first call.
|
|
19
|
+
* @param {BVH} bvh
|
|
20
|
+
* @param {ArrayLike<number>} frustum 6 inward-facing planes, layout matching
|
|
21
|
+
* {@link frustum_from_projection_matrix_array}
|
|
22
|
+
* @param {number} plane_normal_x
|
|
23
|
+
* @param {number} plane_normal_y
|
|
24
|
+
* @param {number} plane_normal_z
|
|
25
|
+
* @param {number} plane_constant
|
|
26
|
+
*/
|
|
27
|
+
export function bvh_query_depth_range_in_frustum(result: {
|
|
28
|
+
near: number;
|
|
29
|
+
far: number;
|
|
30
|
+
}, bvh: BVH, frustum: ArrayLike<number>, plane_normal_x: number, plane_normal_y: number, plane_normal_z: number, plane_constant: number): void;
|
|
31
|
+
//# sourceMappingURL=bvh_query_depth_range_in_frustum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bvh_query_depth_range_in_frustum.d.ts","sourceRoot":"","sources":["../../../../../../src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,yDAVW;IAAC,IAAI,EAAC,MAAM,CAAC;IAAC,GAAG,EAAC,MAAM,CAAA;CAAC,qBAGzB,UAAU,MAAM,CAAC,kBAEjB,MAAM,kBACN,MAAM,kBACN,MAAM,kBACN,MAAM,QAkEhB"}
|