@woosh/meep-engine 2.109.20 → 2.109.21
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-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/build/meep.cjs +9 -5
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +9 -5
- package/package.json +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray_segment.js +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray_segment.js +1 -1
- package/src/core/collection/array/isArrayEqualStrict.d.ts.map +1 -1
- package/src/core/collection/array/isArrayEqualStrict.js +1 -3
- package/src/core/collection/array/typed/is_typed_array_equals.d.ts +1 -1
- package/src/core/collection/array/typed/is_typed_array_equals.d.ts.map +1 -1
- package/src/core/collection/array/typed/is_typed_array_equals.js +8 -2
- package/src/core/geom/3d/aabb/aabb3_array_near_distance_to_intersection_ray_segment.d.ts +16 -0
- package/src/core/geom/3d/aabb/aabb3_array_near_distance_to_intersection_ray_segment.d.ts.map +1 -0
- package/src/core/geom/3d/aabb/aabb3_array_near_distance_to_intersection_ray_segment.js +30 -0
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_segment.d.ts +4 -5
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_segment.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_segment.js +6 -9
- package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.d.ts +20 -0
- package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.d.ts.map +1 -0
- package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.js +67 -0
- package/src/core/geom/3d/line/line3_compute_nearest_point_to_point.d.ts.map +1 -1
- package/src/core/geom/3d/line/line3_compute_nearest_point_to_point.js +15 -1
- package/src/core/geom/3d/normal/octahedron/decode_octahedron_to_unit.d.ts +2 -1
- package/src/core/geom/3d/normal/octahedron/decode_octahedron_to_unit.d.ts.map +1 -1
- package/src/core/geom/3d/normal/octahedron/decode_octahedron_to_unit.js +6 -1
- package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.d.ts +20 -0
- package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.d.ts.map +1 -0
- package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.js +147 -0
- package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.spec.d.ts +2 -0
- package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.spec.d.ts.map +1 -0
- package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.spec.js +100 -0
- package/src/core/geom/octahedral_uv_crease_distance.d.ts +8 -0
- package/src/core/geom/octahedral_uv_crease_distance.d.ts.map +1 -0
- package/src/core/geom/octahedral_uv_crease_distance.js +26 -0
- package/src/core/math/random/generate_halton_jitter.js +2 -2
- package/src/core/math/statistics/generate_hammersley_jitter.d.ts +7 -0
- package/src/core/math/statistics/generate_hammersley_jitter.d.ts.map +1 -0
- package/src/core/math/statistics/generate_hammersley_jitter.js +16 -0
- package/src/core/math/statistics/hammersley_sequence_2d.js +2 -1
- package/src/engine/graphics/geometry/buffered/computeGeometryEquality.d.ts.map +1 -1
- package/src/engine/graphics/geometry/buffered/computeGeometryEquality.js +4 -0
- package/src/engine/graphics/sh3/gi/material/common.glsl +1 -1
- package/src/engine/graphics/sh3/lpv/LightProbeVolume.d.ts +0 -7
- package/src/engine/graphics/sh3/lpv/LightProbeVolume.d.ts.map +1 -1
- package/src/engine/graphics/sh3/lpv/LightProbeVolume.js +0 -11
- package/src/engine/graphics/sh3/lpv/LightProbeVolumeBaker.d.ts +7 -0
- package/src/engine/graphics/sh3/lpv/LightProbeVolumeBaker.d.ts.map +1 -1
- package/src/engine/graphics/sh3/lpv/LightProbeVolumeBaker.js +39 -25
- package/src/engine/graphics/sh3/lpv/PathTracerProbeRenderer.js +1 -1
- package/src/engine/graphics/sh3/lpv/depth/octahedral/bake_octahedral_depth_map.d.ts.map +1 -1
- package/src/engine/graphics/sh3/lpv/depth/octahedral/bake_octahedral_depth_map.js +34 -35
- package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.d.ts +18 -0
- package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.js +421 -21
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +4 -4
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +4 -2
- package/src/engine/graphics/texture/virtual/prototype.js +3 -1
|
@@ -1,12 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BVH,
|
|
3
|
+
COLUMN_CHILD_1,
|
|
4
|
+
COLUMN_CHILD_2,
|
|
5
|
+
COLUMN_USER_DATA,
|
|
6
|
+
ELEMENT_WORD_COUNT,
|
|
7
|
+
NULL_NODE
|
|
8
|
+
} from "../../../../core/bvh2/bvh3/BVH.js";
|
|
2
9
|
import { ebvh_build_for_geometry_morton } from "../../../../core/bvh2/bvh3/ebvh_build_for_geometry_morton.js";
|
|
3
10
|
import { bvh_query_user_data_ray_segment } from "../../../../core/bvh2/bvh3/query/bvh_query_user_data_ray_segment.js";
|
|
4
11
|
import { array_copy } from "../../../../core/collection/array/array_copy.js";
|
|
12
|
+
import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../../core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
|
|
5
13
|
import { AABB3 } from "../../../../core/geom/3d/aabb/AABB3.js";
|
|
14
|
+
import { aabb3_intersects_ray_segment } from "../../../../core/geom/3d/aabb/aabb3_intersects_ray_segment.js";
|
|
15
|
+
import {
|
|
16
|
+
aabb3_unsigned_distance_sqr_to_point
|
|
17
|
+
} from "../../../../core/geom/3d/aabb/aabb3_unsigned_distance_sqr_to_point.js";
|
|
18
|
+
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
19
|
+
import {
|
|
20
|
+
computeTriangleClosestPointToPointBarycentric
|
|
21
|
+
} from "../../../../core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.js";
|
|
6
22
|
|
|
7
23
|
import {
|
|
8
24
|
computeTriangleRayIntersectionBarycentricGeometry
|
|
9
25
|
} from "../../../../core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricGeometry.js";
|
|
26
|
+
import { v3_compute_triangle_normal } from "../../../../core/geom/3d/v3_compute_triangle_normal.js";
|
|
27
|
+
import { v3_distance_sqr } from "../../../../core/geom/vec3/v3_distance_sqr.js";
|
|
10
28
|
import Vector4 from "../../../../core/geom/Vector4.js";
|
|
11
29
|
import { makeGeometryIndexed } from "../../geometry/buffered/makeGeometryIndexed.js";
|
|
12
30
|
import { computeBoundingSphereFromVertexData } from "../../geometry/computeBoundingSphereFromVertexData.js";
|
|
@@ -23,6 +41,10 @@ const scratch_uint32_array = new Uint32Array(4096);
|
|
|
23
41
|
*/
|
|
24
42
|
const v3_scratch_0 = [];
|
|
25
43
|
|
|
44
|
+
const scratch_contact = new SurfacePoint3();
|
|
45
|
+
|
|
46
|
+
const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
47
|
+
|
|
26
48
|
export class BufferedGeometryBVH {
|
|
27
49
|
/**
|
|
28
50
|
* @type {Uint32Array}
|
|
@@ -147,40 +169,418 @@ export class BufferedGeometryBVH {
|
|
|
147
169
|
|
|
148
170
|
const bvh = this.#bvh;
|
|
149
171
|
|
|
150
|
-
const
|
|
151
|
-
bvh, bvh.root,
|
|
152
|
-
scratch_uint32_array, 0,
|
|
153
|
-
origin_x, origin_y, origin_z,
|
|
154
|
-
direction_x, direction_y, direction_z,
|
|
155
|
-
0, max_distance
|
|
156
|
-
);
|
|
172
|
+
const root = bvh.root;
|
|
157
173
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
174
|
+
if (root === NULL_NODE) {
|
|
175
|
+
return -1;
|
|
176
|
+
}
|
|
161
177
|
|
|
162
|
-
|
|
163
|
-
|
|
178
|
+
/**
|
|
179
|
+
* Move stack pointer to local variable scope to avoid de-referencing inside the loop
|
|
180
|
+
* @type {number}
|
|
181
|
+
*/
|
|
182
|
+
let pointer = stack.pointer;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
*
|
|
186
|
+
* @type {number}
|
|
187
|
+
*/
|
|
188
|
+
const stack_top = pointer;
|
|
189
|
+
|
|
190
|
+
stack[pointer++] = root;
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
/*
|
|
194
|
+
For performance, we bind data directly to avoid extra copies required to read out AABB
|
|
195
|
+
*/
|
|
196
|
+
const float32 = bvh.__data_float32;
|
|
197
|
+
const uint32 = bvh.__data_uint32;
|
|
198
|
+
|
|
199
|
+
const inv_direction_x = 1 / direction_x;
|
|
200
|
+
const inv_direction_y = 1 / direction_y;
|
|
201
|
+
const inv_direction_z = 1 / direction_z;
|
|
202
|
+
|
|
203
|
+
do {
|
|
204
|
+
|
|
205
|
+
--pointer;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
*
|
|
209
|
+
* @type {number}
|
|
210
|
+
*/
|
|
211
|
+
const node = stack[pointer];
|
|
212
|
+
|
|
213
|
+
const address = node * ELEMENT_WORD_COUNT;
|
|
214
|
+
|
|
215
|
+
// test node against the ray
|
|
216
|
+
const intersects = aabb3_intersects_ray_segment(
|
|
217
|
+
float32[address], float32[address + 1], float32[address + 2],
|
|
218
|
+
float32[address + 3], float32[address + 4], float32[address + 5],
|
|
164
219
|
origin_x, origin_y, origin_z,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
positions
|
|
220
|
+
inv_direction_x, inv_direction_y, inv_direction_z,
|
|
221
|
+
0, max_distance
|
|
168
222
|
);
|
|
169
223
|
|
|
170
|
-
if (!
|
|
224
|
+
if (!intersects) {
|
|
171
225
|
continue;
|
|
172
226
|
}
|
|
173
227
|
|
|
174
|
-
|
|
228
|
+
// get fist child to check if this is a leaf node or not
|
|
229
|
+
const child_1 = uint32[address + COLUMN_CHILD_1];
|
|
230
|
+
|
|
231
|
+
if (child_1 !== NULL_NODE) {
|
|
232
|
+
|
|
233
|
+
// this is not a leaf node, push children onto traversal stack
|
|
234
|
+
const child_2 = uint32[address + COLUMN_CHILD_2];
|
|
235
|
+
|
|
236
|
+
stack[pointer++] = child_2;
|
|
237
|
+
stack[pointer++] = child_1;
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
} else {
|
|
241
|
+
// leaf node
|
|
242
|
+
|
|
243
|
+
const triangle_index = uint32[address + COLUMN_USER_DATA];
|
|
244
|
+
|
|
245
|
+
const intersection_found = computeTriangleRayIntersectionBarycentricGeometry(
|
|
246
|
+
v3_scratch_0,
|
|
247
|
+
origin_x, origin_y, origin_z,
|
|
248
|
+
direction_x, direction_y, direction_z,
|
|
249
|
+
indices, triangle_index,
|
|
250
|
+
positions
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
if (!intersection_found) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const t = v3_scratch_0[0];
|
|
258
|
+
|
|
259
|
+
if (t < max_distance && t > 0) {
|
|
260
|
+
return true;
|
|
261
|
+
|
|
262
|
+
}
|
|
175
263
|
|
|
176
|
-
if (t < max_distance && t > 0) {
|
|
177
|
-
return true;
|
|
178
264
|
}
|
|
179
|
-
}
|
|
265
|
+
} while (pointer > stack_top);
|
|
266
|
+
|
|
180
267
|
|
|
181
268
|
return false;
|
|
182
269
|
}
|
|
183
270
|
|
|
271
|
+
/**
|
|
272
|
+
*
|
|
273
|
+
* @param {SurfacePoint3} result
|
|
274
|
+
* @param {number} x
|
|
275
|
+
* @param {number} y
|
|
276
|
+
* @param {number} z
|
|
277
|
+
* @returns {boolean} true if result is found, only false when geometry is empty
|
|
278
|
+
*/
|
|
279
|
+
nearestSurfacePoint(result, x, y, z) {
|
|
280
|
+
|
|
281
|
+
const indices = this.__geometry_index;
|
|
282
|
+
const positions = this.__geometry_positions;
|
|
283
|
+
|
|
284
|
+
const bvh = this.#bvh;
|
|
285
|
+
|
|
286
|
+
const root = bvh.root;
|
|
287
|
+
|
|
288
|
+
if (root === NULL_NODE) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Move stack pointer to local variable scope to avoid de-referencing inside the loop
|
|
294
|
+
* @type {number}
|
|
295
|
+
*/
|
|
296
|
+
let pointer = stack.pointer;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
*
|
|
300
|
+
* @type {number}
|
|
301
|
+
*/
|
|
302
|
+
const stack_top = pointer;
|
|
303
|
+
|
|
304
|
+
stack[pointer++] = root;
|
|
305
|
+
|
|
306
|
+
/*
|
|
307
|
+
For performance, we bind data directly to avoid extra copies required to read out AABB
|
|
308
|
+
*/
|
|
309
|
+
const float32 = bvh.__data_float32;
|
|
310
|
+
const uint32 = bvh.__data_uint32;
|
|
311
|
+
|
|
312
|
+
let nearest_distance_sqr = Infinity;
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
do {
|
|
316
|
+
--pointer;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
*
|
|
320
|
+
* @type {number}
|
|
321
|
+
*/
|
|
322
|
+
const node = stack[pointer];
|
|
323
|
+
|
|
324
|
+
const address = node * ELEMENT_WORD_COUNT;
|
|
325
|
+
|
|
326
|
+
// test node against the ray
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
// get fist child to check if this is a leaf node or not
|
|
330
|
+
const child_1 = uint32[address + COLUMN_CHILD_1];
|
|
331
|
+
|
|
332
|
+
if (child_1 !== NULL_NODE) {
|
|
333
|
+
|
|
334
|
+
// this is not a leaf node, push children onto traversal stack
|
|
335
|
+
const child_2 = uint32[address + COLUMN_CHILD_2];
|
|
336
|
+
|
|
337
|
+
// to achieve faster convergence, we sort children before adding them to the stack by their proximity to the reference point
|
|
338
|
+
const child_1_address = child_1 * ELEMENT_WORD_COUNT;
|
|
339
|
+
|
|
340
|
+
const distance_sqr_to_child1 = aabb3_unsigned_distance_sqr_to_point(
|
|
341
|
+
float32[child_1_address], float32[child_1_address + 1], float32[child_1_address + 2],
|
|
342
|
+
float32[child_1_address + 3], float32[child_1_address + 4], float32[child_1_address + 5],
|
|
343
|
+
x, y, z
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
const child_2_address = child_2 * ELEMENT_WORD_COUNT;
|
|
347
|
+
|
|
348
|
+
const distance_sqr_to_child2 = aabb3_unsigned_distance_sqr_to_point(
|
|
349
|
+
float32[child_2_address], float32[child_2_address + 1], float32[child_2_address + 2],
|
|
350
|
+
float32[child_2_address + 3], float32[child_2_address + 4], float32[child_2_address + 5],
|
|
351
|
+
x, y, z
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
if (distance_sqr_to_child1 < distance_sqr_to_child2) {
|
|
355
|
+
|
|
356
|
+
if (distance_sqr_to_child2 < nearest_distance_sqr) {
|
|
357
|
+
stack[pointer++] = child_2;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (distance_sqr_to_child1 < nearest_distance_sqr) {
|
|
361
|
+
stack[pointer++] = child_1;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
} else {
|
|
365
|
+
|
|
366
|
+
if (distance_sqr_to_child1 < nearest_distance_sqr) {
|
|
367
|
+
stack[pointer++] = child_1;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (distance_sqr_to_child2 < nearest_distance_sqr) {
|
|
371
|
+
stack[pointer++] = child_2;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
} else {
|
|
378
|
+
// leaf node
|
|
379
|
+
// read triangle data
|
|
380
|
+
const triangle_index = uint32[address + COLUMN_USER_DATA];
|
|
381
|
+
|
|
382
|
+
const a = indices[triangle_index];
|
|
383
|
+
const b = indices[triangle_index + 1];
|
|
384
|
+
const c = indices[triangle_index + 2];
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
const a_address = a * 3;
|
|
388
|
+
const b_address = b * 3;
|
|
389
|
+
const c_address = c * 3;
|
|
390
|
+
|
|
391
|
+
const ax = positions[a_address];
|
|
392
|
+
const ay = positions[a_address + 1];
|
|
393
|
+
const az = positions[a_address + 2];
|
|
394
|
+
|
|
395
|
+
const bx = positions[b_address];
|
|
396
|
+
const by = positions[b_address + 1];
|
|
397
|
+
const bz = positions[b_address + 2];
|
|
398
|
+
|
|
399
|
+
const cx = positions[c_address];
|
|
400
|
+
const cy = positions[c_address + 1];
|
|
401
|
+
const cz = positions[c_address + 2];
|
|
402
|
+
|
|
403
|
+
computeTriangleClosestPointToPointBarycentric(
|
|
404
|
+
v3_scratch_0, 0,
|
|
405
|
+
x, y, z,
|
|
406
|
+
ax, ay, az,
|
|
407
|
+
bx, by, bz,
|
|
408
|
+
cx, cy, cz
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
const u = v3_scratch_0[0];
|
|
412
|
+
const v = v3_scratch_0[1];
|
|
413
|
+
|
|
414
|
+
// construct edge
|
|
415
|
+
|
|
416
|
+
const contact_x = (bx - ax) * u + (cx - ax) * v + ax;
|
|
417
|
+
const contact_y = (by - ay) * u + (cy - ay) * v + ay;
|
|
418
|
+
const contact_z = (bz - az) * u + (cz - az) * v + az;
|
|
419
|
+
|
|
420
|
+
const distance_to_triangle_sqr = v3_distance_sqr(contact_x, contact_y, contact_z, x, y, z);
|
|
421
|
+
|
|
422
|
+
if (distance_to_triangle_sqr >= nearest_distance_sqr) {
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
nearest_distance_sqr = distance_to_triangle_sqr;
|
|
427
|
+
|
|
428
|
+
result.position.set(contact_x, contact_y, contact_z);
|
|
429
|
+
|
|
430
|
+
v3_compute_triangle_normal(result.normal, 0,
|
|
431
|
+
ax, ay, az,
|
|
432
|
+
bx, by, bz,
|
|
433
|
+
cx, cy, cz
|
|
434
|
+
);
|
|
435
|
+
|
|
436
|
+
result.index = triangle_index;
|
|
437
|
+
}
|
|
438
|
+
} while (pointer > stack_top);
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Code is largely inlined, to avoid extra checks
|
|
447
|
+
* NOTE: raycast is performed in local coordinate space
|
|
448
|
+
* @param {number[]} output
|
|
449
|
+
* @param {number[]|Ray3} ray
|
|
450
|
+
* @returns {number} distance along the ray, negative if no hit
|
|
451
|
+
*/
|
|
452
|
+
raycast2(output, ray) {
|
|
453
|
+
|
|
454
|
+
const indices = this.__geometry_index;
|
|
455
|
+
const positions = this.__geometry_positions;
|
|
456
|
+
|
|
457
|
+
const origin_x = ray[0];
|
|
458
|
+
const origin_y = ray[1];
|
|
459
|
+
const origin_z = ray[2];
|
|
460
|
+
|
|
461
|
+
const direction_x = ray[3];
|
|
462
|
+
const direction_y = ray[4];
|
|
463
|
+
const direction_z = ray[5];
|
|
464
|
+
|
|
465
|
+
const max_distance = ray[6];
|
|
466
|
+
|
|
467
|
+
const bvh = this.#bvh;
|
|
468
|
+
|
|
469
|
+
const root = bvh.root;
|
|
470
|
+
|
|
471
|
+
if (root === NULL_NODE) {
|
|
472
|
+
return -1;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Move stack pointer to local variable scope to avoid de-referencing inside the loop
|
|
477
|
+
* @type {number}
|
|
478
|
+
*/
|
|
479
|
+
let pointer = stack.pointer;
|
|
480
|
+
|
|
481
|
+
let nearest_hit_distance = max_distance;
|
|
482
|
+
|
|
483
|
+
let best_index = -1;
|
|
484
|
+
let best_u = 0;
|
|
485
|
+
let best_v = 0;
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
*
|
|
489
|
+
* @type {number}
|
|
490
|
+
*/
|
|
491
|
+
const stack_top = pointer;
|
|
492
|
+
|
|
493
|
+
stack[pointer++] = root;
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
/*
|
|
497
|
+
For performance, we bind data directly to avoid extra copies required to read out AABB
|
|
498
|
+
*/
|
|
499
|
+
const float32 = bvh.__data_float32;
|
|
500
|
+
const uint32 = bvh.__data_uint32;
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
const inv_direction_x = 1 / direction_x;
|
|
504
|
+
const inv_direction_y = 1 / direction_y;
|
|
505
|
+
const inv_direction_z = 1 / direction_z;
|
|
506
|
+
|
|
507
|
+
do {
|
|
508
|
+
|
|
509
|
+
--pointer;
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
*
|
|
513
|
+
* @type {number}
|
|
514
|
+
*/
|
|
515
|
+
const node = stack[pointer];
|
|
516
|
+
|
|
517
|
+
const address = node * ELEMENT_WORD_COUNT;
|
|
518
|
+
|
|
519
|
+
// test node against the ray
|
|
520
|
+
const intersects = aabb3_intersects_ray_segment(
|
|
521
|
+
float32[address], float32[address + 1], float32[address + 2],
|
|
522
|
+
float32[address + 3], float32[address + 4], float32[address + 5],
|
|
523
|
+
origin_x, origin_y, origin_z,
|
|
524
|
+
inv_direction_x, inv_direction_y, inv_direction_z,
|
|
525
|
+
0, nearest_hit_distance
|
|
526
|
+
);
|
|
527
|
+
|
|
528
|
+
if (!intersects) {
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// get fist child to check if this is a leaf node or not
|
|
533
|
+
const child_1 = uint32[address + COLUMN_CHILD_1];
|
|
534
|
+
|
|
535
|
+
if (child_1 !== NULL_NODE) {
|
|
536
|
+
|
|
537
|
+
// this is not a leaf node, push children onto traversal stack
|
|
538
|
+
const child_2 = uint32[address + COLUMN_CHILD_2];
|
|
539
|
+
|
|
540
|
+
stack[pointer++] = child_2;
|
|
541
|
+
stack[pointer++] = child_1;
|
|
542
|
+
|
|
543
|
+
} else {
|
|
544
|
+
// leaf node
|
|
545
|
+
|
|
546
|
+
const triangle_index = uint32[address + COLUMN_USER_DATA];
|
|
547
|
+
|
|
548
|
+
const intersection_found = computeTriangleRayIntersectionBarycentricGeometry(
|
|
549
|
+
v3_scratch_0,
|
|
550
|
+
origin_x, origin_y, origin_z,
|
|
551
|
+
direction_x, direction_y, direction_z,
|
|
552
|
+
indices, triangle_index,
|
|
553
|
+
positions
|
|
554
|
+
);
|
|
555
|
+
|
|
556
|
+
if (!intersection_found) {
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
const t = v3_scratch_0[0];
|
|
561
|
+
|
|
562
|
+
if (t < nearest_hit_distance && t > 0) {
|
|
563
|
+
nearest_hit_distance = t;
|
|
564
|
+
|
|
565
|
+
best_index = triangle_index;
|
|
566
|
+
best_u = v3_scratch_0[1];
|
|
567
|
+
best_v = v3_scratch_0[2];
|
|
568
|
+
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
}
|
|
572
|
+
} while (pointer > stack_top);
|
|
573
|
+
|
|
574
|
+
if (nearest_hit_distance === max_distance) {
|
|
575
|
+
// no hit
|
|
576
|
+
return -1;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
construct_ray_hit_from_geometry(output, indices, positions, best_index, nearest_hit_distance, best_u, best_v);
|
|
580
|
+
|
|
581
|
+
return nearest_hit_distance;
|
|
582
|
+
}
|
|
583
|
+
|
|
184
584
|
/**
|
|
185
585
|
* NOTE: raycast is performed in local coordinate space
|
|
186
586
|
* @param {number[]} output
|
|
@@ -67,8 +67,8 @@ vCanvas.css({
|
|
|
67
67
|
* How many rays to use per-pixel
|
|
68
68
|
* @type {number}
|
|
69
69
|
*/
|
|
70
|
-
const PIXEL_SAMPLE_COUNT =
|
|
71
|
-
const PIXEL_RENDER_RATIO =
|
|
70
|
+
const PIXEL_SAMPLE_COUNT = 16;
|
|
71
|
+
const PIXEL_RENDER_RATIO = 1;
|
|
72
72
|
|
|
73
73
|
const scene = new PathTracedScene();
|
|
74
74
|
const pt = new PathTracer();
|
|
@@ -534,8 +534,8 @@ async function start_renderer(camera) {
|
|
|
534
534
|
// await prepare_scene_lucy(scene, camera);
|
|
535
535
|
// await prepare_scene_rtiow(pt, camera);
|
|
536
536
|
// await prepare_scene_sphere_01(pt, camera);
|
|
537
|
-
|
|
538
|
-
await prepare_sponza(scene, camera);
|
|
537
|
+
await prepare_gi_box_scene(scene, camera);
|
|
538
|
+
// await prepare_sponza(scene, camera);
|
|
539
539
|
// await prepare_attic_scene(scene, camera);
|
|
540
540
|
// await prepare_scene_gltf({scene, camera, path, url: path});
|
|
541
541
|
|
|
@@ -246,7 +246,7 @@ async function getVolume({
|
|
|
246
246
|
engine,
|
|
247
247
|
ecd,
|
|
248
248
|
bounds: mesh_bounds,
|
|
249
|
-
density:
|
|
249
|
+
density: 500
|
|
250
250
|
});
|
|
251
251
|
|
|
252
252
|
const buffer = new BinaryBuffer();
|
|
@@ -378,7 +378,6 @@ async function main(engine) {
|
|
|
378
378
|
// const path = 'data/models/samples/ancient_bath_house_-_modular_set/scene.gltf';
|
|
379
379
|
// const path = 'data/models/samples/environment_-_library/scene.gltf';
|
|
380
380
|
// const path = 'data/models/Scans/green_car_wreck/scene.gltf';
|
|
381
|
-
// const path = 'data/models/samples/low_poly_classroom/no-glass/model.gltf';
|
|
382
381
|
// const path = 'data/models/samples/the_attic_environment/scene1.gltf';
|
|
383
382
|
// const path = 'data/models/LowPolyTownshipSet/Small_house/Small_house.gltf';
|
|
384
383
|
// const path = 'data/models/samples/cyberpunk_bike/scene.gltf';
|
|
@@ -391,6 +390,7 @@ async function main(engine) {
|
|
|
391
390
|
// const path = 'data/models/samples/conference/model-no-curtains.glb';
|
|
392
391
|
// const path = 'data/models/pica_pica/pica_pica.gltf';
|
|
393
392
|
// const path = 'data/models/samples/gi_box_01/model.glb';
|
|
393
|
+
// const path = 'data/models/samples/low_poly_classroom/no-glass/model.gltf';
|
|
394
394
|
|
|
395
395
|
const mesh_asset = await engine.assetManager.promise(path, 'model/gltf+json');
|
|
396
396
|
const gltf = mesh_asset.gltf;
|
|
@@ -410,6 +410,8 @@ async function main(engine) {
|
|
|
410
410
|
|
|
411
411
|
const composition = three_object_to_entity_composition(gltf.scene);
|
|
412
412
|
|
|
413
|
+
// composition.transform.rotation.multiply(Quaternion.fromEulerAngles(DEG_TO_RAD * 30, DEG_TO_RAD * 30, 0));
|
|
414
|
+
|
|
413
415
|
composition.traverse(n => {
|
|
414
416
|
|
|
415
417
|
/**
|
|
@@ -451,7 +451,9 @@ function render() {
|
|
|
451
451
|
// mesh.rotation.x += 0.05 * delta;
|
|
452
452
|
// }
|
|
453
453
|
|
|
454
|
-
virtual_texture_managers.forEach(vts =>
|
|
454
|
+
virtual_texture_managers.forEach(vts => {
|
|
455
|
+
vts.update(renderer, scene, camera);
|
|
456
|
+
});
|
|
455
457
|
|
|
456
458
|
// renderer.setViewport(0, 0, view_port_size.x, view_port_size.y);
|
|
457
459
|
renderer.clear();
|