@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,97 @@
|
|
|
1
|
+
import { aabb3_intersects_ray } from "../../aabb3/aabb3_intersects_ray.js";
|
|
2
|
+
import {
|
|
3
|
+
COLUMN_CHILD_1,
|
|
4
|
+
COLUMN_CHILD_2,
|
|
5
|
+
ELEMENT_WORD_COUNT,
|
|
6
|
+
NULL_NODE
|
|
7
|
+
} from "../ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @type {number[]}
|
|
12
|
+
*/
|
|
13
|
+
const traversal_stack = new Uint32Array(2048);
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @param {ExplicitBinaryBoundingVolumeHierarchy} bvh
|
|
19
|
+
* @param {number[]} result
|
|
20
|
+
* @param {number} result_offset
|
|
21
|
+
* @param {number} origin_x
|
|
22
|
+
* @param {number} origin_y
|
|
23
|
+
* @param {number} origin_z
|
|
24
|
+
* @param {number} direction_x
|
|
25
|
+
* @param {number} direction_y
|
|
26
|
+
* @param {number} direction_z
|
|
27
|
+
* @returns {number}
|
|
28
|
+
*/
|
|
29
|
+
export function bvh_query_leaves_ray(
|
|
30
|
+
bvh,
|
|
31
|
+
result, result_offset,
|
|
32
|
+
origin_x, origin_y, origin_z,
|
|
33
|
+
direction_x, direction_y, direction_z
|
|
34
|
+
) {
|
|
35
|
+
const root = bvh.root;
|
|
36
|
+
|
|
37
|
+
if (root === NULL_NODE) {
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
traversal_stack[0] = root;
|
|
43
|
+
|
|
44
|
+
let result_cursor = result_offset;
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @type {number}
|
|
48
|
+
*/
|
|
49
|
+
let traversal_cursor = 1;
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
For performance, we bind data directly to avoid extra copies required to read out AABB
|
|
53
|
+
*/
|
|
54
|
+
const float32 = bvh.__data_float32;
|
|
55
|
+
const uint32 = bvh.__data_uint32;
|
|
56
|
+
|
|
57
|
+
do {
|
|
58
|
+
traversal_cursor--;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
* @type {number}
|
|
63
|
+
*/
|
|
64
|
+
const node = traversal_stack[traversal_cursor];
|
|
65
|
+
|
|
66
|
+
const address = node * ELEMENT_WORD_COUNT;
|
|
67
|
+
|
|
68
|
+
// test node against the ray
|
|
69
|
+
const intersects = aabb3_intersects_ray(
|
|
70
|
+
float32[address], float32[address + 1], float32[address + 2],
|
|
71
|
+
float32[address + 3], float32[address + 4], float32[address + 5],
|
|
72
|
+
origin_x, origin_y, origin_z,
|
|
73
|
+
direction_x, direction_y, direction_z
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (!intersects) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// get fist child to check if this is a leaf node or not
|
|
81
|
+
const child_1 = uint32[address + COLUMN_CHILD_1];
|
|
82
|
+
|
|
83
|
+
if (child_1 !== NULL_NODE) {
|
|
84
|
+
|
|
85
|
+
// this is not a leaf node, push children onto traversal stack
|
|
86
|
+
traversal_stack[traversal_cursor++] = child_1;
|
|
87
|
+
traversal_stack[traversal_cursor++] = uint32[address + COLUMN_CHILD_2];
|
|
88
|
+
|
|
89
|
+
} else {
|
|
90
|
+
// leaf node
|
|
91
|
+
|
|
92
|
+
result[result_cursor++] = node;
|
|
93
|
+
}
|
|
94
|
+
} while (traversal_cursor > 0);
|
|
95
|
+
|
|
96
|
+
return result_cursor - result_offset;
|
|
97
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { NULL_NODE } from "
|
|
2
|
-
import { aabb3_signed_distance_sqr_to_point } from "
|
|
3
|
-
import { max2 } from "
|
|
1
|
+
import { NULL_NODE } from "../ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
2
|
+
import { aabb3_signed_distance_sqr_to_point } from "../../aabb3/aabb3_signed_distance_sqr_to_point.js";
|
|
3
|
+
import { max2 } from "../../../math/max2.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExplicitBinaryBoundingVolumeHierarchy } from "
|
|
1
|
+
import { ExplicitBinaryBoundingVolumeHierarchy } from "../ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
2
2
|
import { bvh_query_user_data_nearest_to_point } from "./bvh_query_user_data_nearest_to_point.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//
|
|
2
|
-
import { NULL_NODE } from "
|
|
3
|
-
import { aabb3_array_intersects_frustum_degree } from "
|
|
2
|
+
import { NULL_NODE } from "../ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
3
|
+
import { aabb3_array_intersects_frustum_degree } from "../../aabb3/aabb3_array_intersects_frustum_degree.js";
|
|
4
4
|
import { bvh_collect_user_data } from "./bvh_collect_user_data.js";
|
|
5
5
|
|
|
6
6
|
const traversal_stack = [];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { array_copy } from "../../../collection/array/copyArray.js";
|
|
5
5
|
import { NULL_NODE } from "../ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
6
6
|
import { aabb3_array_intersects_frustum_degree } from "../../aabb3/aabb3_array_intersects_frustum_degree.js";
|
|
7
|
-
import { bvh_collect_user_data } from "
|
|
7
|
+
import { bvh_collect_user_data } from "./bvh_collect_user_data.js";
|
|
8
8
|
import { v3_distance_above_plane } from "../../../geom/v3_distance_above_plane.js";
|
|
9
9
|
|
|
10
10
|
const traversal_stack = [];
|
|
@@ -3,8 +3,8 @@ import { array_copy } from "../copyArray.js";
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Assumes arrays have the same type
|
|
6
|
-
* @param {TypedArray|Float32Array|Uint8Array} source
|
|
7
|
-
* @param {TypedArray|Float32Array|Uint8Array} destination
|
|
6
|
+
* @param {TypedArray|Float32Array|Uint8Array|Uint32Array} source
|
|
7
|
+
* @param {TypedArray|Float32Array|Uint8Array|Uint32Array} destination
|
|
8
8
|
*/
|
|
9
9
|
export function typed_array_copy(source, destination) {
|
|
10
10
|
const destination_size = destination.length;
|
|
@@ -4,11 +4,12 @@ import { max2 } from "../../../math/max2.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* Multidimensional axis-aligned bounding box calculation
|
|
6
6
|
* @param {number[]} result
|
|
7
|
-
* @param {number[]} input
|
|
7
|
+
* @param {number[]|ArrayLike<number>} input
|
|
8
|
+
* @param {number} input_offset
|
|
8
9
|
* @param {number} input_count
|
|
9
10
|
* @param {number} d number of dimensions
|
|
10
11
|
*/
|
|
11
|
-
export function compute_aabb_from_points(result, input, input_count, d) {
|
|
12
|
+
export function compute_aabb_from_points(result, input, input_offset, input_count, d) {
|
|
12
13
|
let i = 0;
|
|
13
14
|
let j = 0;
|
|
14
15
|
|
|
@@ -19,7 +20,7 @@ export function compute_aabb_from_points(result, input, input_count, d) {
|
|
|
19
20
|
|
|
20
21
|
for (i = 0; i < input_count; i++) {
|
|
21
22
|
for (j = 0; j < d; j++) {
|
|
22
|
-
const v = input[i*d + j];
|
|
23
|
+
const v = input[input_count + i * d + j];
|
|
23
24
|
|
|
24
25
|
result[j] = min2(result[j], v);
|
|
25
26
|
result[j + d] = max2(result[j + d], v);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { v3_length_sqr } from "../v3_length_sqr.js";
|
|
2
|
+
import { vec3 } from "gl-matrix";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {number[]} result
|
|
7
|
+
* @param {number} result_offset
|
|
8
|
+
* @param {number} vAx
|
|
9
|
+
* @param {number} vAy
|
|
10
|
+
* @param {number} vAz
|
|
11
|
+
* @param {number} vBx
|
|
12
|
+
* @param {number} vBy
|
|
13
|
+
* @param {number} vBz
|
|
14
|
+
* @param {number} vCx
|
|
15
|
+
* @param {number} vCy
|
|
16
|
+
* @param {number} vCz
|
|
17
|
+
*/
|
|
18
|
+
export function v3_compute_triangle_normal(result, result_offset, vAx, vAy, vAz, vBx, vBy, vBz, vCx, vCy, vCz) {
|
|
19
|
+
//compute CB and AB vectors
|
|
20
|
+
const vCBx = vCx - vBx;
|
|
21
|
+
const vCBy = vCy - vBy;
|
|
22
|
+
const vCBz = vCz - vBz;
|
|
23
|
+
|
|
24
|
+
const vABx = vAx - vBx;
|
|
25
|
+
const vABy = vAy - vBy;
|
|
26
|
+
const vABz = vAz - vBz;
|
|
27
|
+
|
|
28
|
+
//compute triangle normal
|
|
29
|
+
const crossX = vCBy * vABz - vCBz * vABy;
|
|
30
|
+
const crossY = vCBz * vABx - vCBx * vABz;
|
|
31
|
+
const crossZ = vCBx * vABy - vCBy * vABx;
|
|
32
|
+
|
|
33
|
+
const l_sqr = v3_length_sqr(crossX, crossY, crossZ);
|
|
34
|
+
|
|
35
|
+
if (l_sqr === 0) {
|
|
36
|
+
// degenerate triangle, provide arbitrary invalid result
|
|
37
|
+
result[result_offset] = 0;
|
|
38
|
+
result[result_offset + 1] = 1;
|
|
39
|
+
result[result_offset + 2] = 0;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const l_inv = 1 / Math.sqrt(l_sqr);
|
|
44
|
+
|
|
45
|
+
const x = crossX * l_inv;
|
|
46
|
+
const y = crossY * l_inv;
|
|
47
|
+
const z = crossZ * l_inv;
|
|
48
|
+
|
|
49
|
+
result[result_offset] = x;
|
|
50
|
+
result[result_offset + 1] = y;
|
|
51
|
+
result[result_offset + 2] = z;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param {number[]|vec3} result
|
|
57
|
+
* @param {number[]} vA
|
|
58
|
+
* @param {number[]} vB
|
|
59
|
+
* @param {number[]} vC
|
|
60
|
+
*/
|
|
61
|
+
export function compute_triangle_normal(result, vA, vB, vC) {
|
|
62
|
+
|
|
63
|
+
const vAx = vA[0];
|
|
64
|
+
const vAy = vA[1];
|
|
65
|
+
const vAz = vA[2];
|
|
66
|
+
|
|
67
|
+
const vBx = vB[0];
|
|
68
|
+
const vBy = vB[1];
|
|
69
|
+
const vBz = vB[2];
|
|
70
|
+
|
|
71
|
+
const vCx = vC[0];
|
|
72
|
+
const vCy = vC[1];
|
|
73
|
+
const vCz = vC[2];
|
|
74
|
+
|
|
75
|
+
v3_compute_triangle_normal(result, 0, vAx, vAy, vAz, vBx, vBy, vBz, vCx, vCy, vCz);
|
|
76
|
+
}
|
|
@@ -211,7 +211,7 @@ async function main(engine) {
|
|
|
211
211
|
|
|
212
212
|
const aabb_array = [];
|
|
213
213
|
const position_attribute = geometry.getAttribute('position');
|
|
214
|
-
compute_aabb_from_points(aabb_array, position_attribute.array, position_attribute.count, 3);
|
|
214
|
+
compute_aabb_from_points(aabb_array, position_attribute.array, 0, position_attribute.count, 3);
|
|
215
215
|
const aabb3 = new AABB3(...aabb_array);
|
|
216
216
|
//
|
|
217
217
|
// weld_duplicate_vertices(topo, aabb3);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { v3_dot } from "../../../../v3_dot.js";
|
|
2
2
|
import { fabsf } from "../../../../../math/fabsf.js";
|
|
3
3
|
import { vec3 } from "gl-matrix";
|
|
4
|
-
import { compute_triangle_normal } from "../../struct/TopoTriangle.js";
|
|
5
4
|
import { EPSILON } from "../../../../../math/EPSILON.js";
|
|
5
|
+
import { compute_triangle_normal } from "../../../compute_triangle_normal.js";
|
|
6
6
|
|
|
7
7
|
const scratch_v3 = new Float32Array(3);
|
|
8
8
|
|
|
@@ -3,63 +3,7 @@ import { array_push_if_unique } from "../../../../collection/array/array_push_if
|
|
|
3
3
|
import { assert } from "../../../../assert.js";
|
|
4
4
|
import { array_remove_first } from "../../../../collection/array/array_remove_first.js";
|
|
5
5
|
import { vec3 } from "gl-matrix";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* @param {number[]|vec3} result
|
|
11
|
-
* @param {Vector3|Vector3Like|TopoVertex|{x:number,y:number,z:number}} vA
|
|
12
|
-
* @param {Vector3|Vector3Like|TopoVertex|{x:number,y:number,z:number}} vB
|
|
13
|
-
* @param {Vector3|Vector3Like|TopoVertex|{x:number,y:number,z:number}} vC
|
|
14
|
-
*/
|
|
15
|
-
export function compute_triangle_normal(result, vA, vB, vC) {
|
|
16
|
-
|
|
17
|
-
const vAx = vA.x
|
|
18
|
-
const vAy = vA.y
|
|
19
|
-
const vAz = vA.z
|
|
20
|
-
|
|
21
|
-
const vBx = vB.x
|
|
22
|
-
const vBy = vB.y
|
|
23
|
-
const vBz = vB.z
|
|
24
|
-
|
|
25
|
-
const vCx = vC.x
|
|
26
|
-
const vCy = vC.y
|
|
27
|
-
const vCz = vC.z
|
|
28
|
-
|
|
29
|
-
//compute CB and AB vectors
|
|
30
|
-
const vCBx = vCx - vBx;
|
|
31
|
-
const vCBy = vCy - vBy;
|
|
32
|
-
const vCBz = vCz - vBz;
|
|
33
|
-
|
|
34
|
-
const vABx = vAx - vBx;
|
|
35
|
-
const vABy = vAy - vBy;
|
|
36
|
-
const vABz = vAz - vBz;
|
|
37
|
-
|
|
38
|
-
//compute triangle normal
|
|
39
|
-
const crossX = vCBy * vABz - vCBz * vABy;
|
|
40
|
-
const crossY = vCBz * vABx - vCBx * vABz;
|
|
41
|
-
const crossZ = vCBx * vABy - vCBy * vABx;
|
|
42
|
-
|
|
43
|
-
const l_sqr = v3_length_sqr(crossX, crossY, crossZ);
|
|
44
|
-
|
|
45
|
-
if (l_sqr === 0) {
|
|
46
|
-
// degenerate triangle, provide arbitrary invalid result
|
|
47
|
-
vec3.set(result, 0, 0, 0);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const l_inv = 1 / Math.sqrt(l_sqr);
|
|
52
|
-
|
|
53
|
-
const x = crossX * l_inv;
|
|
54
|
-
const y = crossY * l_inv;
|
|
55
|
-
const z = crossZ * l_inv;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
vec3.set(
|
|
59
|
-
result,
|
|
60
|
-
x, y, z
|
|
61
|
-
);
|
|
62
|
-
}
|
|
6
|
+
import { compute_triangle_normal } from "../../compute_triangle_normal.js";
|
|
63
7
|
|
|
64
8
|
let index_counter = 0;
|
|
65
9
|
|
|
@@ -30,43 +30,43 @@ export function computeTriangleRayIntersection(
|
|
|
30
30
|
bx, by, bz,
|
|
31
31
|
cx, cy, cz
|
|
32
32
|
) {
|
|
33
|
-
assert.isNumber(ax,'ax');
|
|
34
|
-
assert.isNumber(ay,'ay');
|
|
35
|
-
assert.isNumber(az,'az');
|
|
33
|
+
assert.isNumber(ax, 'ax');
|
|
34
|
+
assert.isNumber(ay, 'ay');
|
|
35
|
+
assert.isNumber(az, 'az');
|
|
36
36
|
|
|
37
|
-
assert.isNumber(bx,'bx');
|
|
38
|
-
assert.isNumber(by,'by');
|
|
39
|
-
assert.isNumber(bz,'bz');
|
|
37
|
+
assert.isNumber(bx, 'bx');
|
|
38
|
+
assert.isNumber(by, 'by');
|
|
39
|
+
assert.isNumber(bz, 'bz');
|
|
40
40
|
|
|
41
|
-
assert.isNumber(cx,'cx');
|
|
42
|
-
assert.isNumber(cy,'cy');
|
|
43
|
-
assert.isNumber(cz,'cz');
|
|
41
|
+
assert.isNumber(cx, 'cx');
|
|
42
|
+
assert.isNumber(cy, 'cy');
|
|
43
|
+
assert.isNumber(cz, 'cz');
|
|
44
44
|
|
|
45
45
|
// nan checks
|
|
46
|
-
assert.notNaN(ax,'ax');
|
|
47
|
-
assert.notNaN(ay,'ay');
|
|
48
|
-
assert.notNaN(az,'az');
|
|
46
|
+
assert.notNaN(ax, 'ax');
|
|
47
|
+
assert.notNaN(ay, 'ay');
|
|
48
|
+
assert.notNaN(az, 'az');
|
|
49
49
|
|
|
50
|
-
assert.notNaN(bx,'bx');
|
|
51
|
-
assert.notNaN(by,'by');
|
|
52
|
-
assert.notNaN(bz,'bz');
|
|
50
|
+
assert.notNaN(bx, 'bx');
|
|
51
|
+
assert.notNaN(by, 'by');
|
|
52
|
+
assert.notNaN(bz, 'bz');
|
|
53
53
|
|
|
54
|
-
assert.notNaN(cx,'cx');
|
|
55
|
-
assert.notNaN(cy,'cy');
|
|
56
|
-
assert.notNaN(cz,'cz');
|
|
54
|
+
assert.notNaN(cx, 'cx');
|
|
55
|
+
assert.notNaN(cy, 'cy');
|
|
56
|
+
assert.notNaN(cz, 'cz');
|
|
57
57
|
|
|
58
58
|
// finate number check
|
|
59
|
-
assert.isFiniteNumber(ax,'ax');
|
|
60
|
-
assert.isFiniteNumber(ay,'ay');
|
|
61
|
-
assert.isFiniteNumber(az,'az');
|
|
59
|
+
assert.isFiniteNumber(ax, 'ax');
|
|
60
|
+
assert.isFiniteNumber(ay, 'ay');
|
|
61
|
+
assert.isFiniteNumber(az, 'az');
|
|
62
62
|
|
|
63
|
-
assert.isFiniteNumber(bx,'bx');
|
|
64
|
-
assert.isFiniteNumber(by,'by');
|
|
65
|
-
assert.isFiniteNumber(bz,'bz');
|
|
63
|
+
assert.isFiniteNumber(bx, 'bx');
|
|
64
|
+
assert.isFiniteNumber(by, 'by');
|
|
65
|
+
assert.isFiniteNumber(bz, 'bz');
|
|
66
66
|
|
|
67
|
-
assert.isFiniteNumber(cx,'cx');
|
|
68
|
-
assert.isFiniteNumber(cy,'cy');
|
|
69
|
-
assert.isFiniteNumber(cz,'cz');
|
|
67
|
+
assert.isFiniteNumber(cx, 'cx');
|
|
68
|
+
assert.isFiniteNumber(cy, 'cy');
|
|
69
|
+
assert.isFiniteNumber(cz, 'cz');
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
// edge1 = a - b
|
|
@@ -157,3 +157,171 @@ export function computeTriangleRayIntersection(
|
|
|
157
157
|
|
|
158
158
|
return true;
|
|
159
159
|
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Compute barycentric coordinates for triangle intersection
|
|
163
|
+
* Operates on edges, this is optimized for raytracing, as same edges are required to reconstruct various attributes later on
|
|
164
|
+
* NOTE: most of the code is inlined for speed to avoid allocation and function calls
|
|
165
|
+
* @see https://github.com/erich666/jgt-code/blob/master/Volume_02/Number_1/Moller1997a/raytri.c
|
|
166
|
+
* @source https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm (Möller and Trumbore, « Fast, Minimum Storage Ray-Triangle Intersection », Journal of Graphics Tools, vol. 2, 1997, p. 21–28)
|
|
167
|
+
* @param {number[]} result
|
|
168
|
+
* @param {number} origin_x
|
|
169
|
+
* @param {number} origin_y
|
|
170
|
+
* @param {number} origin_z
|
|
171
|
+
* @param {number} direction_x
|
|
172
|
+
* @param {number} direction_y
|
|
173
|
+
* @param {number} direction_z
|
|
174
|
+
* @param {number} ax
|
|
175
|
+
* @param {number} ay
|
|
176
|
+
* @param {number} az
|
|
177
|
+
* @param {number} edge1_x
|
|
178
|
+
* @param {number} edge1_y
|
|
179
|
+
* @param {number} edge1_z
|
|
180
|
+
* @param {number} edge2_x
|
|
181
|
+
* @param {number} edge2_y
|
|
182
|
+
* @param {number} edge2_z
|
|
183
|
+
* @return {boolean}
|
|
184
|
+
*/
|
|
185
|
+
export function computeTriangleRayIntersectionBarycentricEdge(result, origin_x, origin_y, origin_z, direction_x, direction_y, direction_z, ax, ay, az, edge1_x, edge1_y, edge1_z, edge2_x, edge2_y, edge2_z) {
|
|
186
|
+
// begin calculating determinant - also used to calculate U parameter
|
|
187
|
+
|
|
188
|
+
// CROSS(pvec, dir, edge2)
|
|
189
|
+
const pvec_x = direction_y * edge2_z - direction_z * edge2_y;
|
|
190
|
+
const pvec_y = direction_z * edge2_x - direction_x * edge2_z;
|
|
191
|
+
const pvec_z = direction_x * edge2_y - direction_y * edge2_x;
|
|
192
|
+
|
|
193
|
+
//if determinant is near zero, ray lies in plane of triangle
|
|
194
|
+
const det = v3_dot(edge1_x, edge1_y, edge1_z, pvec_x, pvec_y, pvec_z);
|
|
195
|
+
|
|
196
|
+
if (det <= 0) {
|
|
197
|
+
// back-face culling
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// calculate distance from vert0 to ray origin (not really, but okay)
|
|
202
|
+
const tvec_x = origin_x - ax;
|
|
203
|
+
const tvec_y = origin_y - ay;
|
|
204
|
+
const tvec_z = origin_z - az;
|
|
205
|
+
|
|
206
|
+
// calculate u
|
|
207
|
+
let u = v3_dot(tvec_x, tvec_y, tvec_z, pvec_x, pvec_y, pvec_z);
|
|
208
|
+
|
|
209
|
+
if (u < 0 || u > det) {
|
|
210
|
+
// outside of bounds of the triangle
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// prepare to test V parameter
|
|
215
|
+
// CROSS(qvec, tvec, edge1)
|
|
216
|
+
const qvec_x = tvec_y * edge1_z - tvec_z * edge1_y;
|
|
217
|
+
const qvec_y = tvec_z * edge1_x - tvec_x * edge1_z;
|
|
218
|
+
const qvec_z = tvec_x * edge1_y - tvec_y * edge1_x;
|
|
219
|
+
|
|
220
|
+
// calculate V parameter
|
|
221
|
+
let v = v3_dot(direction_x, direction_y, direction_z, qvec_x, qvec_y, qvec_z);
|
|
222
|
+
|
|
223
|
+
if (v < 0 || u + v > det) {
|
|
224
|
+
// out of bounds
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
const inv_det = 1 / det;
|
|
230
|
+
|
|
231
|
+
// calculate t, scale parameter, ray intersects triangle
|
|
232
|
+
const t = v3_dot(edge2_x, edge2_y, edge2_z, qvec_x, qvec_y, qvec_z) * inv_det;
|
|
233
|
+
|
|
234
|
+
u *= inv_det;
|
|
235
|
+
v *= inv_det;
|
|
236
|
+
|
|
237
|
+
result[0] = t;
|
|
238
|
+
result[1] = u;
|
|
239
|
+
result[2] = v;
|
|
240
|
+
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Compute barycentric coordinates for triangle intersection
|
|
246
|
+
* NOTE: most of the code is inlined for speed to avoid allocation and function calls
|
|
247
|
+
* @see https://github.com/erich666/jgt-code/blob/master/Volume_02/Number_1/Moller1997a/raytri.c
|
|
248
|
+
* @source https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm (Möller and Trumbore, « Fast, Minimum Storage Ray-Triangle Intersection », Journal of Graphics Tools, vol. 2, 1997, p. 21–28)
|
|
249
|
+
* @param {number[]} result [t,u,v, normal_x, normal_y, normal_z] will be written here
|
|
250
|
+
* @param {number} origin_x
|
|
251
|
+
* @param {number} origin_y
|
|
252
|
+
* @param {number} origin_z
|
|
253
|
+
* @param {number} direction_x
|
|
254
|
+
* @param {number} direction_y
|
|
255
|
+
* @param {number} direction_z
|
|
256
|
+
* @param {number} ax
|
|
257
|
+
* @param {number} ay
|
|
258
|
+
* @param {number} az
|
|
259
|
+
* @param {number} bx
|
|
260
|
+
* @param {number} by
|
|
261
|
+
* @param {number} bz
|
|
262
|
+
* @param {number} cx
|
|
263
|
+
* @param {number} cy
|
|
264
|
+
* @param {number} cz
|
|
265
|
+
* @returns {boolean}
|
|
266
|
+
*/
|
|
267
|
+
export function computeTriangleRayIntersectionBarycentric(
|
|
268
|
+
result,
|
|
269
|
+
origin_x, origin_y, origin_z,
|
|
270
|
+
direction_x, direction_y, direction_z,
|
|
271
|
+
ax, ay, az,
|
|
272
|
+
bx, by, bz,
|
|
273
|
+
cx, cy, cz
|
|
274
|
+
) {
|
|
275
|
+
assert.isNumber(ax, 'ax');
|
|
276
|
+
assert.isNumber(ay, 'ay');
|
|
277
|
+
assert.isNumber(az, 'az');
|
|
278
|
+
|
|
279
|
+
assert.isNumber(bx, 'bx');
|
|
280
|
+
assert.isNumber(by, 'by');
|
|
281
|
+
assert.isNumber(bz, 'bz');
|
|
282
|
+
|
|
283
|
+
assert.isNumber(cx, 'cx');
|
|
284
|
+
assert.isNumber(cy, 'cy');
|
|
285
|
+
assert.isNumber(cz, 'cz');
|
|
286
|
+
|
|
287
|
+
// nan checks
|
|
288
|
+
assert.notNaN(ax, 'ax');
|
|
289
|
+
assert.notNaN(ay, 'ay');
|
|
290
|
+
assert.notNaN(az, 'az');
|
|
291
|
+
|
|
292
|
+
assert.notNaN(bx, 'bx');
|
|
293
|
+
assert.notNaN(by, 'by');
|
|
294
|
+
assert.notNaN(bz, 'bz');
|
|
295
|
+
|
|
296
|
+
assert.notNaN(cx, 'cx');
|
|
297
|
+
assert.notNaN(cy, 'cy');
|
|
298
|
+
assert.notNaN(cz, 'cz');
|
|
299
|
+
|
|
300
|
+
// finate number check
|
|
301
|
+
assert.isFiniteNumber(ax, 'ax');
|
|
302
|
+
assert.isFiniteNumber(ay, 'ay');
|
|
303
|
+
assert.isFiniteNumber(az, 'az');
|
|
304
|
+
|
|
305
|
+
assert.isFiniteNumber(bx, 'bx');
|
|
306
|
+
assert.isFiniteNumber(by, 'by');
|
|
307
|
+
assert.isFiniteNumber(bz, 'bz');
|
|
308
|
+
|
|
309
|
+
assert.isFiniteNumber(cx, 'cx');
|
|
310
|
+
assert.isFiniteNumber(cy, 'cy');
|
|
311
|
+
assert.isFiniteNumber(cz, 'cz');
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
// find vectors for two edges sharing vert
|
|
315
|
+
|
|
316
|
+
// edge1 = a - b
|
|
317
|
+
const edge1_x = bx - ax;
|
|
318
|
+
const edge1_y = by - ay;
|
|
319
|
+
const edge1_z = bz - az;
|
|
320
|
+
|
|
321
|
+
// edge2 = c - a
|
|
322
|
+
const edge2_x = cx - ax;
|
|
323
|
+
const edge2_y = cy - ay;
|
|
324
|
+
const edge2_z = cz - az;
|
|
325
|
+
|
|
326
|
+
return computeTriangleRayIntersectionBarycentricEdge(result, origin_x, origin_y, origin_z, direction_x, direction_y, direction_z, ax, ay, az, edge1_x, edge1_y, edge1_z, edge2_x, edge2_y, edge2_z);
|
|
327
|
+
}
|
package/core/geom/Vector3.js
CHANGED
|
@@ -305,6 +305,18 @@ class Vector3 {
|
|
|
305
305
|
return this;
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
+
/**
|
|
309
|
+
*
|
|
310
|
+
* @param {Vector3} first
|
|
311
|
+
* @param {Vector3} second
|
|
312
|
+
*/
|
|
313
|
+
crossVectors(first, second) {
|
|
314
|
+
const ax = first.x, ay = first.y, az = first.z;
|
|
315
|
+
const bx = second.x, by = second.y, bz = second.z;
|
|
316
|
+
|
|
317
|
+
this._crossVectors(ax, ay, az, bx, by, bz);
|
|
318
|
+
}
|
|
319
|
+
|
|
308
320
|
/**
|
|
309
321
|
*
|
|
310
322
|
* @param {number} ax
|
|
@@ -322,18 +334,6 @@ class Vector3 {
|
|
|
322
334
|
this.set(x, y, z);
|
|
323
335
|
}
|
|
324
336
|
|
|
325
|
-
/**
|
|
326
|
-
*
|
|
327
|
-
* @param {Vector3} first
|
|
328
|
-
* @param {Vector3} second
|
|
329
|
-
*/
|
|
330
|
-
crossVectors(first, second) {
|
|
331
|
-
const ax = first.x, ay = first.y, az = first.z;
|
|
332
|
-
const bx = second.x, by = second.y, bz = second.z;
|
|
333
|
-
|
|
334
|
-
this._crossVectors(ax, ay, az, bx, by, bz);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
337
|
/**
|
|
338
338
|
* Sets all components of the vector to absolute value (positive)
|
|
339
339
|
* @returns {Vector3}
|