@woosh/meep-engine 2.43.17 → 2.43.19
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/core/assert.js +3 -1
- package/core/bvh2/aabb3/aabb3_intersects_ray.js +14 -9
- package/core/bvh2/aabb3/aabb3_intersects_ray_branchless.js +52 -0
- package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.d.ts +2 -0
- package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +162 -10
- package/core/bvh2/bvh3/ebvh_build_for_geometry_incremental.js +34 -0
- package/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +175 -0
- package/core/bvh2/bvh3/ebvh_sort_for_traversal_depth_first.js +122 -0
- package/core/bvh2/bvh3/{bvh_collect_user_data.js → query/bvh_collect_user_data.js} +1 -1
- package/core/bvh2/bvh3/{bvh_query_leaves_generic.js → query/bvh_query_leaves_generic.js} +1 -1
- package/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +97 -0
- package/core/bvh2/bvh3/{bvh_query_user_data_generic.js → query/bvh_query_user_data_generic.js} +1 -1
- package/core/bvh2/bvh3/{bvh_query_user_data_nearest_to_point.js → query/bvh_query_user_data_nearest_to_point.js} +3 -3
- package/core/bvh2/bvh3/{bvh_query_user_data_nearest_to_point.spec.js → query/bvh_query_user_data_nearest_to_point.spec.js} +1 -1
- package/core/bvh2/bvh3/{bvh_query_user_data_overlaps_frustum.js → query/bvh_query_user_data_overlaps_frustum.js} +2 -2
- package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +1 -1
- package/core/collection/array/arrayQuickSort.js +1 -1
- package/core/collection/array/typed/typed_array_copy.js +2 -2
- package/core/geom/3d/aabb/compute_aabb_from_points.js +4 -3
- package/core/geom/3d/compute_triangle_normal.js +76 -0
- package/core/geom/3d/topology/samples/sampleFloodFill.js +1 -1
- package/core/geom/3d/topology/simplify/compute_face_normal_change_dot_product.js +1 -1
- package/core/geom/3d/topology/simplify/quadratic/Quadratic3.js +1 -1
- package/core/geom/3d/topology/struct/TopoTriangle.js +1 -57
- package/core/geom/3d/topology/tm_face_normal.js +1 -1
- package/core/geom/3d/topology/tm_vertex_compute_normal.js +1 -1
- package/core/geom/3d/triangle/computeTriangleRayIntersection.js +195 -27
- package/core/geom/Vector3.js +12 -12
- package/core/math/physics/brdf/D_GGX.js +13 -0
- package/editor/tools/v2/prototypeTransformControls.js +14 -2
- package/engine/ecs/parent/EntityNode.js +80 -7
- package/engine/ecs/parent/EntityNodeFlags.js +8 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +2 -2
- package/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +9 -1
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +1 -1
- package/engine/graphics/geometry/AttributeSpec.js +18 -3
- package/engine/graphics/geometry/VertexDataSpec.js +53 -3
- package/engine/graphics/micron/format/VirtualGeometry.js +7 -0
- package/engine/graphics/micron/render/VirtualGeometryBuilder.js +1 -1
- package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +5 -2
- package/engine/graphics/particles/particular/engine/parameter/sample/RGBA_LUT_HEATMAP_IR.js +11 -0
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +2 -9
- package/engine/graphics/render/forward_plus/model/DirectionalLight.js +40 -0
- package/engine/graphics/sh3/README.md +1 -0
- package/engine/graphics/sh3/path_tracer/GeometryBVHBatched.js +265 -0
- package/engine/graphics/sh3/path_tracer/PathTracedMesh.js +85 -0
- package/engine/graphics/sh3/path_tracer/PathTracer.js +534 -0
- package/engine/graphics/sh3/path_tracer/apply_texture_clamping_to_coordinate.js +22 -0
- package/engine/graphics/sh3/path_tracer/compute_triangle_group_aabb3.js +36 -0
- package/engine/graphics/sh3/path_tracer/getBiasedNormalSample.js +55 -0
- package/engine/graphics/sh3/path_tracer/make_one_vector3.js +7 -0
- package/engine/graphics/sh3/path_tracer/make_sky_hosek.js +44 -0
- package/engine/graphics/sh3/path_tracer/make_sky_rtiw.js +17 -0
- package/engine/graphics/sh3/path_tracer/make_zero_vector3.js +7 -0
- package/engine/graphics/sh3/path_tracer/prototypePathTracer.js +631 -0
- package/engine/graphics/sh3/path_tracer/random_in_hemisphere.js +39 -0
- package/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.js +42 -0
- package/engine/graphics/sh3/path_tracer/ray_reflect.js +27 -0
- package/engine/graphics/sh3/path_tracer/sample_triangle_attribute.js +35 -0
- package/engine/graphics/sh3/path_tracer/vec3_uint8_to_float.js +12 -0
- package/engine/graphics/sh3/sky/hosek/README.md +4 -0
- package/engine/graphics/sh3/sky/hosek/prototype_hosek.js +71 -0
- package/engine/graphics/sh3/sky/hosek/sky_hosek_compute_irradiance_by_direction.js +4171 -0
- package/engine/graphics/texture/sampler/convertTexture2Sampler2D.js +2 -0
- package/package.json +1 -1
- package/view/elements/progress/SmoothProgressBar.js +1 -1
- package/view/task/TaskProgressView.js +6 -8
- package/core/bvh2/bvh3/bvh_query_leaves_ray.js +0 -95
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExplicitBinaryBoundingVolumeHierarchy
|
|
3
|
+
} from "../../../../core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
4
|
+
import { bvh_query_leaves_ray } from "../../../../core/bvh2/bvh3/query/bvh_query_leaves_ray.js";
|
|
5
|
+
import { aabb3_signed_distance_sqr_to_point } from "../../../../core/bvh2/aabb3/aabb3_signed_distance_sqr_to_point.js";
|
|
6
|
+
import {
|
|
7
|
+
computeTriangleRayIntersectionBarycentric
|
|
8
|
+
} from "../../../../core/geom/3d/triangle/computeTriangleRayIntersection.js";
|
|
9
|
+
import { ebvh_build_for_geometry_morton } from "../../../../core/bvh2/bvh3/ebvh_build_for_geometry_morton.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @type {number[]}
|
|
14
|
+
*/
|
|
15
|
+
const leaf_buffer = [];
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @type {number[]}
|
|
19
|
+
*/
|
|
20
|
+
const v3_scratch_0 = [];
|
|
21
|
+
|
|
22
|
+
const temp_aabb3 = new Float32Array(6);
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export class GeometryBVHBatched {
|
|
26
|
+
constructor() {
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @type {ExplicitBinaryBoundingVolumeHierarchy}
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
this.__bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @type {THREE.BufferGeometry|null}
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
this.__geometry = null;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @type {number[]|null}
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
this.__geometry_index = null;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @type {number[]|null}
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
this.__geometry_positions = null;
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @type {number}
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
this.__triangle_count = 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param {THREE.BufferGeometry} geometry
|
|
67
|
+
*/
|
|
68
|
+
build(geometry) {
|
|
69
|
+
this.__geometry = geometry;
|
|
70
|
+
|
|
71
|
+
const index = geometry.getIndex();
|
|
72
|
+
const index_array = index.array;
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
const attribute_position = geometry.getAttribute('position');
|
|
76
|
+
const array_positions = attribute_position.array;
|
|
77
|
+
|
|
78
|
+
this.__geometry_positions = array_positions;
|
|
79
|
+
this.__geometry_index = index_array;
|
|
80
|
+
|
|
81
|
+
this.__triangle_count = index_array.length / 3;
|
|
82
|
+
|
|
83
|
+
const bvh = this.__bvh;
|
|
84
|
+
|
|
85
|
+
ebvh_build_for_geometry_morton(bvh, index_array, array_positions);
|
|
86
|
+
//
|
|
87
|
+
// ebvh_build_for_geometry_incremental(bvh, index_array, array_positions, 1);
|
|
88
|
+
|
|
89
|
+
bvh.trim();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
* @param {number[]} output
|
|
95
|
+
* @param {number} face_index
|
|
96
|
+
* @param {number} t
|
|
97
|
+
* @param {number} u
|
|
98
|
+
* @param {number} v
|
|
99
|
+
*/
|
|
100
|
+
construct_ray_hit(output, face_index, t, u, v) {
|
|
101
|
+
const indices = this.__geometry_index;
|
|
102
|
+
const positions = this.__geometry_positions;
|
|
103
|
+
|
|
104
|
+
const index_offset = face_index * 3;
|
|
105
|
+
|
|
106
|
+
const a = indices[index_offset];
|
|
107
|
+
const b = indices[index_offset + 1];
|
|
108
|
+
const c = indices[index_offset + 2];
|
|
109
|
+
|
|
110
|
+
const a_address = a * 3;
|
|
111
|
+
const b_address = b * 3;
|
|
112
|
+
const c_address = c * 3;
|
|
113
|
+
|
|
114
|
+
const ax = positions[a_address];
|
|
115
|
+
const ay = positions[a_address + 1];
|
|
116
|
+
const az = positions[a_address + 2];
|
|
117
|
+
|
|
118
|
+
const bx = positions[b_address];
|
|
119
|
+
const by = positions[b_address + 1];
|
|
120
|
+
const bz = positions[b_address + 2];
|
|
121
|
+
|
|
122
|
+
const cx = positions[c_address];
|
|
123
|
+
const cy = positions[c_address + 1];
|
|
124
|
+
const cz = positions[c_address + 2];
|
|
125
|
+
|
|
126
|
+
// normal
|
|
127
|
+
|
|
128
|
+
// edge1 = a - b
|
|
129
|
+
const edge1_x = bx - ax;
|
|
130
|
+
const edge1_y = by - ay;
|
|
131
|
+
const edge1_z = bz - az;
|
|
132
|
+
|
|
133
|
+
// edge2 = c - a
|
|
134
|
+
const edge2_x = cx - ax;
|
|
135
|
+
const edge2_y = cy - ay;
|
|
136
|
+
const edge2_z = cz - az;
|
|
137
|
+
|
|
138
|
+
// Compute triangle normal
|
|
139
|
+
|
|
140
|
+
// normal = edge1 x edge2
|
|
141
|
+
const normal_x = edge1_y * edge2_z - edge1_z * edge2_y;
|
|
142
|
+
const normal_y = edge1_z * edge2_x - edge1_x * edge2_z;
|
|
143
|
+
const normal_z = edge1_x * edge2_y - edge1_y * edge2_x
|
|
144
|
+
|
|
145
|
+
output[3] = normal_x;
|
|
146
|
+
output[4] = normal_y;
|
|
147
|
+
output[5] = normal_z;
|
|
148
|
+
|
|
149
|
+
output[6] = t;
|
|
150
|
+
output[7] = u;
|
|
151
|
+
output[8] = v;
|
|
152
|
+
output[9] = face_index;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
*
|
|
157
|
+
* @param {number[]} output
|
|
158
|
+
* @param {number[]} ray
|
|
159
|
+
* @param {number} min_distance
|
|
160
|
+
* @param {number} max_distance
|
|
161
|
+
* @returns {number} distance along the ray, negative if no hit
|
|
162
|
+
*/
|
|
163
|
+
raycast(output, ray, min_distance, max_distance) {
|
|
164
|
+
|
|
165
|
+
const indices = this.__geometry_index;
|
|
166
|
+
const positions = this.__geometry_positions;
|
|
167
|
+
|
|
168
|
+
const origin_x = ray[0];
|
|
169
|
+
const origin_y = ray[1];
|
|
170
|
+
const origin_z = ray[2];
|
|
171
|
+
|
|
172
|
+
const direction_x = ray[3];
|
|
173
|
+
const direction_y = ray[4];
|
|
174
|
+
const direction_z = ray[5];
|
|
175
|
+
|
|
176
|
+
const bvh = this.__bvh;
|
|
177
|
+
|
|
178
|
+
// TODO we can unify BVH traversal with ray checks to reduce number of checks
|
|
179
|
+
const count = bvh_query_leaves_ray(
|
|
180
|
+
bvh, leaf_buffer, 0,
|
|
181
|
+
origin_x, origin_y, origin_z,
|
|
182
|
+
direction_x, direction_y, direction_z
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
let best_t = max_distance;
|
|
186
|
+
|
|
187
|
+
let best_index = -1;
|
|
188
|
+
let best_u = 0;
|
|
189
|
+
let best_v = 0;
|
|
190
|
+
|
|
191
|
+
for (let i = 0; i < count; i++) {
|
|
192
|
+
const node_id = leaf_buffer[i];
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
if (best_t < max_distance) {
|
|
196
|
+
// early bail-out
|
|
197
|
+
|
|
198
|
+
bvh.node_get_aabb(node_id, temp_aabb3);
|
|
199
|
+
|
|
200
|
+
const distance = aabb3_signed_distance_sqr_to_point(temp_aabb3[0], temp_aabb3[1], temp_aabb3[2], temp_aabb3[3], temp_aabb3[4], temp_aabb3[5], ray[0], ray[1], ray[2]);
|
|
201
|
+
|
|
202
|
+
if (distance > best_t * best_t) {
|
|
203
|
+
// whole AABB is too far
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const triangle_index = bvh.node_get_user_data(node_id);
|
|
209
|
+
|
|
210
|
+
const index_offset = triangle_index * 3;
|
|
211
|
+
|
|
212
|
+
const a = indices[index_offset];
|
|
213
|
+
const b = indices[index_offset + 1];
|
|
214
|
+
const c = indices[index_offset + 2];
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
const a_address = a * 3;
|
|
218
|
+
const b_address = b * 3;
|
|
219
|
+
const c_address = c * 3;
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
const ax = positions[a_address];
|
|
223
|
+
const ay = positions[a_address + 1];
|
|
224
|
+
const az = positions[a_address + 2];
|
|
225
|
+
|
|
226
|
+
const bx = positions[b_address];
|
|
227
|
+
const by = positions[b_address + 1];
|
|
228
|
+
const bz = positions[b_address + 2];
|
|
229
|
+
|
|
230
|
+
const cx = positions[c_address];
|
|
231
|
+
const cy = positions[c_address + 1];
|
|
232
|
+
const cz = positions[c_address + 2];
|
|
233
|
+
|
|
234
|
+
const intersection_found = computeTriangleRayIntersectionBarycentric(
|
|
235
|
+
v3_scratch_0,
|
|
236
|
+
origin_x, origin_y, origin_z,
|
|
237
|
+
direction_x, direction_y, direction_z,
|
|
238
|
+
ax, ay, az,
|
|
239
|
+
bx, by, bz,
|
|
240
|
+
cx, cy, cz
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
if (intersection_found && v3_scratch_0[0] < best_t && v3_scratch_0[0] > min_distance) {
|
|
244
|
+
best_t = v3_scratch_0[0];
|
|
245
|
+
|
|
246
|
+
best_index = triangle_index;
|
|
247
|
+
best_u = v3_scratch_0[1];
|
|
248
|
+
best_v = v3_scratch_0[2];
|
|
249
|
+
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (best_t === max_distance) {
|
|
254
|
+
return -1;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
output[0] = origin_x + direction_x * best_t;
|
|
258
|
+
output[1] = origin_y + direction_y * best_t;
|
|
259
|
+
output[2] = origin_z + direction_z * best_t;
|
|
260
|
+
|
|
261
|
+
this.construct_ray_hit(output, best_index, best_t, best_u, best_v);
|
|
262
|
+
|
|
263
|
+
return best_t;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { array_copy } from "../../../../core/collection/array/copyArray.js";
|
|
2
|
+
import { mat4 } from "gl-matrix";
|
|
3
|
+
import { ray3_array_apply_matrix4 } from "../../../../core/geom/3d/ray/ray3_array_apply_matrix4.js";
|
|
4
|
+
import { ray_hit_apply_transform } from "./ray_hit_apply_transform.js";
|
|
5
|
+
|
|
6
|
+
const local_ray = new Float32Array(6);
|
|
7
|
+
let mesh_id_counter = 0;
|
|
8
|
+
|
|
9
|
+
export class PathTracedMesh {
|
|
10
|
+
constructor() {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @type {GeometryBVHBatched|null}
|
|
15
|
+
*/
|
|
16
|
+
this.geo_bvh = null;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @type {THREE.BufferGeometry|null}
|
|
21
|
+
*/
|
|
22
|
+
this.geometry = null;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @type {THREE.Material|null}
|
|
27
|
+
*/
|
|
28
|
+
this.material = null;
|
|
29
|
+
|
|
30
|
+
const buffer = new ArrayBuffer(16 * 2 * 4);
|
|
31
|
+
|
|
32
|
+
this.__transform_inverse = new Float32Array(buffer, 0, 16);
|
|
33
|
+
this.__transform = new Float32Array(buffer, 16 * 4, 16);
|
|
34
|
+
this.__local_scale_inverse = 1;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @type {number}
|
|
39
|
+
*/
|
|
40
|
+
this.id = mesh_id_counter++;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
set transform(m) {
|
|
44
|
+
array_copy(m, 0, this.__transform, 0, 16);
|
|
45
|
+
mat4.invert(this.__transform_inverse, m);
|
|
46
|
+
|
|
47
|
+
// precompute scaling factor for rays
|
|
48
|
+
const m4 = this.__transform_inverse;
|
|
49
|
+
|
|
50
|
+
const scale_x = Math.hypot(m4[0], m4[1], m4[2]);
|
|
51
|
+
const scale_y = Math.hypot(m4[4], m4[5], m4[6]);
|
|
52
|
+
const scale_z = Math.hypot(m4[8], m4[9], m4[10]);
|
|
53
|
+
|
|
54
|
+
this.__local_scale_inverse = Math.hypot(scale_x, scale_y, scale_z);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
* @param {number[]} out
|
|
60
|
+
* @param {number[]} ray
|
|
61
|
+
* @param {number} min_distance
|
|
62
|
+
* @param {number} max_distance
|
|
63
|
+
* @returns {number} distance along the ray to contact
|
|
64
|
+
*/
|
|
65
|
+
hit(out, ray, min_distance, max_distance) {
|
|
66
|
+
//transform ray
|
|
67
|
+
const m4 = this.__transform_inverse;
|
|
68
|
+
ray3_array_apply_matrix4(local_ray, ray, m4);
|
|
69
|
+
|
|
70
|
+
const scale_d = this.__local_scale_inverse;
|
|
71
|
+
|
|
72
|
+
let distance_to_hit = this.geo_bvh.raycast(out, local_ray, min_distance * scale_d, max_distance * scale_d);
|
|
73
|
+
|
|
74
|
+
if (distance_to_hit >= 0) {
|
|
75
|
+
// transform output
|
|
76
|
+
ray_hit_apply_transform(out, out, this.__transform);
|
|
77
|
+
|
|
78
|
+
out[10] = this.id;
|
|
79
|
+
|
|
80
|
+
distance_to_hit /= scale_d;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return distance_to_hit;
|
|
84
|
+
}
|
|
85
|
+
}
|