@woosh/meep-engine 2.47.3 → 2.47.10
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 -0
- package/build/bundle-worker-terrain.js +1 -0
- package/build/meep.cjs +1044 -933
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +1044 -933
- package/package.json +2 -2
- package/src/core/binary/BitSet.spec.js +3 -3
- package/src/core/bvh2/BinaryNode.js +12 -10
- package/src/core/bvh2/aabb3/AABB3.js +30 -31
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +1 -1
- package/src/core/bvh2/binary/BinaryBVH.js +1 -1
- package/src/core/bvh2/binary/RayLeafIntersectionVisitor.js +1 -1
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +2 -2
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +1 -1
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +1 -1
- package/src/core/bvh2/bvh3/query/bvh_collect_user_data.js +10 -8
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_generic.js +14 -22
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +13 -15
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +14 -21
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.js +16 -24
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_frustum.js +23 -26
- package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +10 -11
- package/src/core/bvh2/transform/BottomUpOptimizingRebuilder.js +2 -2
- package/src/core/bvh2/transform/tryRotateSingleNode.js +2 -2
- package/src/core/bvh2/traversal/aabb3_detailed_volume_intersection_callback_based.js +1 -1
- package/src/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +1 -1
- package/src/core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js +13 -0
- package/src/core/color/Color.d.ts +2 -1
- package/src/core/color/Color.js +30 -5
- package/src/core/color/ColorUtils.js +7 -5
- package/src/core/color/parseHex.js +11 -3
- package/src/core/color/rgb2hex.js +1 -1
- package/src/core/geom/3d/SurfacePoint3.d.ts +7 -0
- package/src/core/geom/3d/SurfacePoint3.js +56 -1
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_combine.js +2 -2
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_contains_point.js +1 -1
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_frustum_degree.js +2 -2
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_combined_surface_area.js +2 -2
- package/src/core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js +1 -1
- package/src/core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.spec.js +8 -0
- package/src/core/geom/3d/aabb/{computeAABB3PlaneSide.js → aabb3_compute_plane_side.js} +1 -1
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_detailed_volume_intersection.js +7 -7
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_from_v3_array.js +4 -4
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_from_v3_array_transformed.js +2 -2
- package/src/core/{bvh2/aabb3/aabb3_intersect_aabb3.js → geom/3d/aabb/aabb3_intersects_aabb3.js} +2 -2
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_frustum_array.js +2 -2
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_frustum_degree.js +4 -4
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_line_segment.js +1 -1
- package/src/core/geom/3d/aabb/aabb3_intersects_ray.js +87 -0
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray.spec.js +1 -1
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray_branchless.js +2 -2
- package/src/core/{bvh2/aabb3/aabb3_intersect_ray_slab.js → geom/3d/aabb/aabb3_intersects_ray_slab.js} +35 -17
- package/src/core/geom/3d/aabb/aabb3_matrix4_project_by_corners.js +5 -1
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_nearest_point_on_surface.js +2 -2
- package/src/core/geom/3d/aabb/aabb3_raycast.js +103 -0
- package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_signed_distance_sqr_to_point.js +1 -1
- package/src/core/geom/3d/aabb/computeBoundingBoxFromVertexData.js +4 -12
- package/src/core/geom/3d/aabb/compute_aabb_from_points.js +8 -1
- package/src/core/geom/3d/shape/UnitCubeShape3D.js +1 -1
- package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +4 -7
- package/src/core/model/node-graph/DataType.d.ts +4 -0
- package/src/core/model/node-graph/node/NodeDescription.d.ts +11 -1
- package/src/core/model/node-graph/node/NodeRegistry.spec.js +47 -1
- package/src/core/model/node-graph/node/Port.d.ts +3 -0
- package/src/core/model/node-graph/node/Port.js +7 -3
- package/src/core/model/node-graph/node/Port.spec.js +44 -0
- package/src/core/model/node-graph/node/PortDirection.d.ts +5 -0
- package/src/engine/asset/Asset.js +1 -1
- package/src/engine/asset/AssetLoadState.js +10 -0
- package/src/engine/asset/AssetManager.js +164 -228
- package/src/engine/asset/PendingAsset.js +61 -0
- package/src/engine/asset/loaders/GLTFAssetLoader.js +1 -1
- package/src/engine/ecs/foliage/InstancedFoliage.js +1 -1
- package/src/engine/ecs/storage/BinaryBufferSerializer.js +13 -1
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +11 -4
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +54 -0
- package/src/engine/ecs/systems/RenderSystem.js +1 -33
- package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +2 -4
- package/src/engine/ecs/terrain/tiles/TileBuildWorker.js +6 -1
- package/src/engine/graphics/GraphicsEngine.js +5 -1
- package/src/engine/graphics/ecs/decal/v2/Decal.js +44 -2
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +31 -0
- package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +16 -5
- package/src/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +88 -56
- package/src/engine/graphics/geometry/buffered/compute_buffer_geometry_byte_size.js +5 -1
- package/src/engine/graphics/geometry/buffered/query/ClippingPlaneContainmentComputingVisitor.js +2 -2
- package/src/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +1 -1
- package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +3 -2
- package/src/engine/graphics/geometry/skining/computeSkinnedMeshBoundingVolumes.js +3 -2
- package/src/engine/graphics/micron/format/MicronGeometry.js +1 -1
- package/src/engine/graphics/micron/format/validate_patch_bounds.js +1 -1
- package/src/engine/graphics/micron/render/refinement/ActivePatchList.js +1 -1
- package/src/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +16 -16
- package/src/engine/graphics/render/forward_plus/LightManager.js +3 -0
- package/src/engine/graphics/render/forward_plus/LightManager.spec.js +5 -5
- package/src/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_APPLY_DECALS.js +4 -0
- package/src/engine/graphics/render/forward_plus/model/Decal.js +10 -2
- package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_objects.js +2 -2
- package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +18 -16
- package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +2 -0
- package/src/engine/graphics/render/visibility/IncrementalDeltaSet.js +26 -13
- package/src/engine/graphics/sh3/path_tracer/GeometryBVHBatched.js +8 -2
- package/src/engine/graphics/sh3/path_tracer/PathTracer.js +3 -3
- package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +18 -15
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_max.js +1 -1
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min.js +1 -1
- package/src/engine/graphics/three/three_computeObjectBoundingBox.js +56 -0
- package/src/engine/input/devices/{InputDeviceButton.d.ts → InputDeviceSwitch.d.ts} +1 -1
- package/src/engine/input/devices/{InputDeviceButton.js → InputDeviceSwitch.js} +1 -1
- package/src/engine/input/devices/KeyboardDevice.d.ts +2 -2
- package/src/engine/input/devices/KeyboardDevice.js +58 -40
- package/src/engine/input/devices/PointerDevice.js +224 -179
- package/src/core/bvh2/aabb3/aabb3_intersects_ray.js +0 -97
- package/src/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane_max.spec.js +0 -8
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_frustum_array.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_ray.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_ray_array.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_box_surface_area_2.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_compute_half_surface_area.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_compute_surface_area.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_corner_edge_mapping.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_corner_edge_mapping.spec.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_corner_mapping.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_corner_mapping.spec.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_plane_mapping.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_expand_array.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray_fast.js +0 -0
- /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_score_boxes_SAH.js +0 -0
- /package/src/core/{bvh2/aabb3/aabb_score_boxes_SAH_delta.js → geom/3d/aabb/aabb3_score_boxes_SAH_delta.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { aabb3_compute_plane_side } from "./aabb3_compute_plane_side.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
@@ -20,16 +20,15 @@ export function aabb3_intersects_frustum_degree(
|
|
|
20
20
|
) {
|
|
21
21
|
|
|
22
22
|
let result = 2;
|
|
23
|
-
let i = 0;
|
|
24
23
|
|
|
25
|
-
for (; i < 24; i += 4) {
|
|
24
|
+
for (let i = 0; i < 24; i += 4) {
|
|
26
25
|
|
|
27
26
|
const p_x = frustum[i];
|
|
28
27
|
const p_y = frustum[i + 1];
|
|
29
28
|
const p_z = frustum[i + 2];
|
|
30
29
|
const p_w = frustum[i + 3];
|
|
31
30
|
|
|
32
|
-
const plane_side =
|
|
31
|
+
const plane_side = aabb3_compute_plane_side(
|
|
33
32
|
p_x, p_y, p_z, p_w,
|
|
34
33
|
x0, y0, z0, x1, y1, z1
|
|
35
34
|
);
|
|
@@ -38,6 +37,7 @@ export function aabb3_intersects_frustum_degree(
|
|
|
38
37
|
// completely outside
|
|
39
38
|
return 0;
|
|
40
39
|
} else if (plane_side === 0) {
|
|
40
|
+
// partially inside - plane intersects AABB
|
|
41
41
|
result = 1;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const fabsf = Math.abs;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* NOTES:
|
|
5
|
+
* https://web.archive.org/web/20090803054252/http://tog.acm.org/resources/GraphicsGems/gems/RayBox.c
|
|
6
|
+
* https://tavianator.com/fast-branchless-raybounding-box-intersections/
|
|
7
|
+
* https://gamedev.stackexchange.com/questions/18436/most-efficient-aabb-vs-ray-collision-algorithms
|
|
8
|
+
*
|
|
9
|
+
* @param {number} x0
|
|
10
|
+
* @param {number} y0
|
|
11
|
+
* @param {number} z0
|
|
12
|
+
* @param {number} x1
|
|
13
|
+
* @param {number} y1
|
|
14
|
+
* @param {number} z1
|
|
15
|
+
* @param {number} origin_x
|
|
16
|
+
* @param {number} origin_y
|
|
17
|
+
* @param {number} origin_z
|
|
18
|
+
* @param {number} direction_x
|
|
19
|
+
* @param {number} direction_y
|
|
20
|
+
* @param {number} direction_z
|
|
21
|
+
* @returns {boolean}
|
|
22
|
+
*/
|
|
23
|
+
export function aabb3_intersects_ray(
|
|
24
|
+
x0, y0, z0,
|
|
25
|
+
x1, y1, z1,
|
|
26
|
+
origin_x, origin_y, origin_z,
|
|
27
|
+
direction_x, direction_y, direction_z
|
|
28
|
+
) {
|
|
29
|
+
|
|
30
|
+
// Z Projection
|
|
31
|
+
const extents_x = (x1 - x0) * 0.5;
|
|
32
|
+
|
|
33
|
+
const center_x = x0 + extents_x;
|
|
34
|
+
|
|
35
|
+
const diff_x = origin_x - center_x;
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if (diff_x * direction_x >= 0.0 && fabsf(diff_x) > extents_x) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Y projection
|
|
43
|
+
const extents_y = (y1 - y0) * 0.5;
|
|
44
|
+
|
|
45
|
+
const center_y = y0 + extents_y;
|
|
46
|
+
|
|
47
|
+
const diff_y = origin_y - center_y;
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if (diff_y * direction_y >= 0.0 && fabsf(diff_y) > extents_y) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Z projection
|
|
55
|
+
const extents_z = (z1 - z0) * 0.5;
|
|
56
|
+
|
|
57
|
+
const center_z = z0 + extents_z;
|
|
58
|
+
|
|
59
|
+
const diff_z = origin_z - center_z;
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if (diff_z * direction_z >= 0.0 && fabsf(diff_z) > extents_z) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const abs_direction_y = fabsf(direction_y);
|
|
67
|
+
const abs_direction_z = fabsf(direction_z);
|
|
68
|
+
|
|
69
|
+
const f0 = fabsf(direction_y * diff_z - direction_z * diff_y);
|
|
70
|
+
|
|
71
|
+
if (f0 > extents_y * abs_direction_z + extents_z * abs_direction_y) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const abs_direction_x = fabsf(direction_x);
|
|
76
|
+
|
|
77
|
+
const f1 = fabsf(direction_z * diff_x - direction_x * diff_z);
|
|
78
|
+
|
|
79
|
+
if (f1 > extents_x * abs_direction_z + extents_z * abs_direction_x) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const f2 = fabsf(direction_x * diff_y - direction_y * diff_x);
|
|
84
|
+
|
|
85
|
+
return f2 <= extents_x * abs_direction_y + extents_y * abs_direction_x;
|
|
86
|
+
}
|
|
87
|
+
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { max3 } from "../../../math/max3.js";
|
|
2
|
+
import { min3 } from "../../../math/min3.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* see
|
|
5
|
+
* @see https://tavianator.com/fast-branchless-raybounding-box-intersections-part-2-nans/
|
|
6
6
|
* NOTE: this solution forgoes consistent handling of NaNs in favor of execution speed
|
|
7
|
-
* FIXME some manual tests have shown deviation in results between this implementation and others. Possible bugs?
|
|
8
7
|
* @param {number} x0
|
|
9
8
|
* @param {number} y0
|
|
10
9
|
* @param {number} z0
|
|
@@ -19,7 +18,7 @@ import { max2 } from "../../math/max2.js";
|
|
|
19
18
|
* @param {number} dirZ
|
|
20
19
|
* @returns {boolean}
|
|
21
20
|
*/
|
|
22
|
-
export function
|
|
21
|
+
export function aabb3_intersects_ray_slab(
|
|
23
22
|
x0, y0, z0,
|
|
24
23
|
x1, y1, z1,
|
|
25
24
|
oX, oY, oZ,
|
|
@@ -46,28 +45,47 @@ export function aabb3_intersect_ray_slab(
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
48
|
+
|
|
49
|
+
let tmin_x, tmax_x, tmin_y, tmax_y, tmin_z, tmax_z;
|
|
50
|
+
const dir_inv_x = 1 / dirX;
|
|
51
|
+
const dir_inv_y = 1 / dirY;
|
|
52
|
+
const dir_inv_z = 1 / dirZ;
|
|
52
53
|
|
|
53
54
|
const t1_x = (x0 - oX) * dir_inv_x;
|
|
54
55
|
const t2_x = (x1 - oX) * dir_inv_x;
|
|
55
56
|
|
|
56
|
-
const tMin_x = min2(t1_x, t2_x);
|
|
57
|
-
const tMax_x = max2(t1_x, t2_x);
|
|
58
|
-
|
|
59
57
|
const t1_y = (y0 - oY) * dir_inv_y;
|
|
60
58
|
const t2_y = (y1 - oY) * dir_inv_y;
|
|
61
59
|
|
|
62
|
-
const tMin_y = max2(tMin_x, min2(t1_y, t2_y));
|
|
63
|
-
const tMax_y = min2(tMax_x, max2(t1_y, t2_y));
|
|
64
|
-
|
|
65
60
|
const t1_z = (z0 - oZ) * dir_inv_z;
|
|
66
61
|
const t2_z = (z1 - oZ) * dir_inv_z;
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
|
|
64
|
+
if (t1_x > t2_x) {
|
|
65
|
+
tmin_x = t2_x;
|
|
66
|
+
tmax_x = t1_x;
|
|
67
|
+
} else {
|
|
68
|
+
tmin_x = t1_x;
|
|
69
|
+
tmax_x = t2_x;
|
|
70
|
+
}
|
|
71
|
+
if (t1_y > t2_y) {
|
|
72
|
+
tmin_y = t2_y;
|
|
73
|
+
tmax_y = t1_y;
|
|
74
|
+
} else {
|
|
75
|
+
tmin_y = t1_y;
|
|
76
|
+
tmax_y = t2_y;
|
|
77
|
+
}
|
|
78
|
+
if (t1_z > t2_z) {
|
|
79
|
+
tmin_z = t2_z;
|
|
80
|
+
tmax_z = t1_z;
|
|
81
|
+
} else {
|
|
82
|
+
tmin_z = t1_z;
|
|
83
|
+
tmax_z = t2_z;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const tmin = max3(tmin_x, tmin_y, tmin_z);
|
|
87
|
+
const tmax = min3(tmax_x, tmax_y, tmax_z);
|
|
70
88
|
|
|
71
89
|
|
|
72
|
-
return
|
|
90
|
+
return tmax >= tmin;
|
|
73
91
|
}
|
|
@@ -6,7 +6,11 @@ import { assert } from "../../../assert.js";
|
|
|
6
6
|
* @param {number[]|Float32Array|Float64Array} aabb_corners
|
|
7
7
|
* @param {number[]|Float32Array|mat4} projection_matrix
|
|
8
8
|
*/
|
|
9
|
-
export function aabb3_matrix4_project_by_corners(
|
|
9
|
+
export function aabb3_matrix4_project_by_corners(
|
|
10
|
+
result,
|
|
11
|
+
aabb_corners,
|
|
12
|
+
projection_matrix
|
|
13
|
+
) {
|
|
10
14
|
assert.greaterThanOrEqual(result.length, 6, 'result.length must >= 6');
|
|
11
15
|
assert.greaterThanOrEqual(aabb_corners.length, 24, 'aabb_corners.length must >= 24');
|
|
12
16
|
assert.greaterThanOrEqual(projection_matrix.length, 16, 'projection_matrix.length must >= 16');
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import { min2 } from "../../../math/min2.js";
|
|
5
|
+
import { max2 } from "../../../math/max2.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {number[]|ArrayLike<number>|Float32Array} result hit 6-tuple is written here as follows: [hit_position_x, hit_position_y, hit_position_z, hit_normal_x, hit_normal_y, hit_normal_z]
|
|
10
|
+
* @param {number} result_offset offset into result array where to write the hit data
|
|
11
|
+
* @param {number} x0
|
|
12
|
+
* @param {number} y0
|
|
13
|
+
* @param {number} z0
|
|
14
|
+
* @param {number} x1
|
|
15
|
+
* @param {number} y1
|
|
16
|
+
* @param {number} z1
|
|
17
|
+
* @param {number} origin_x ray origin
|
|
18
|
+
* @param {number} origin_y ray origin
|
|
19
|
+
* @param {number} origin_z ray origin
|
|
20
|
+
* @param {number} direction_x ray direction
|
|
21
|
+
* @param {number} direction_y ray direction
|
|
22
|
+
* @param {number} direction_z ray direction
|
|
23
|
+
* @returns {boolean} true if ray hit the box, false otherwise
|
|
24
|
+
*
|
|
25
|
+
*
|
|
26
|
+
* @see https://tavianator.com/fast-branchless-raybounding-box-intersections-part-2-nans/
|
|
27
|
+
* @see https://gdbooks.gitbooks.io/3dcollisions/content/Chapter3/raycast_aabb.html
|
|
28
|
+
* @see https://blog.johnnovak.net/2016/10/22/the-nim-ray-tracer-project-part-4-calculating-box-normals/
|
|
29
|
+
*/
|
|
30
|
+
export function aabb3_raycast(result, result_offset, x0, y0, z0, x1, y1, z1, origin_x, origin_y, origin_z, direction_x, direction_y, direction_z) {
|
|
31
|
+
|
|
32
|
+
// first find intersection
|
|
33
|
+
const dir_inv_x = 1 / direction_x;
|
|
34
|
+
const dir_inv_y = 1 / direction_y;
|
|
35
|
+
const dir_inv_z = 1 / direction_z;
|
|
36
|
+
|
|
37
|
+
const t1_x = (x0 - origin_x) * dir_inv_x;
|
|
38
|
+
const t2_x = (x1 - origin_x) * dir_inv_x;
|
|
39
|
+
|
|
40
|
+
const t1_y = (y0 - origin_y) * dir_inv_y;
|
|
41
|
+
const t2_y = (y1 - origin_y) * dir_inv_y;
|
|
42
|
+
|
|
43
|
+
const t1_z = (z0 - origin_z) * dir_inv_z;
|
|
44
|
+
const t2_z = (z1 - origin_z) * dir_inv_z;
|
|
45
|
+
|
|
46
|
+
let tMax = max2(t1_x, t2_x);
|
|
47
|
+
tMax = min2(tMax, max2(t1_y, t2_y));
|
|
48
|
+
tMax = min2(tMax, max2(t1_z, t2_z));
|
|
49
|
+
|
|
50
|
+
if (tMax < 0) {
|
|
51
|
+
// if tMax < 0, AABB is behind the ray origin in the opposite direction to the ray's
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let tMin = min2(t1_x, t2_x);
|
|
56
|
+
tMin = max2(tMin, min2(t1_y, t2_y));
|
|
57
|
+
tMin = max2(tMin, min2(t1_z, t2_z));
|
|
58
|
+
|
|
59
|
+
if (tMin > tMax) {
|
|
60
|
+
// if tMin > tMax, ray does not intersect the AABB
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ray hit detected, figure out offset along the ray from origin to hit
|
|
65
|
+
const ray_offset = tMin < 0 ? tMax : tMin;
|
|
66
|
+
|
|
67
|
+
const hit_x = origin_x + direction_x * ray_offset;
|
|
68
|
+
const hit_y = origin_y + direction_y * ray_offset;
|
|
69
|
+
const hit_z = origin_z + direction_z * ray_offset;
|
|
70
|
+
|
|
71
|
+
// figure out normal
|
|
72
|
+
const center_x = (x0 + x1) * 0.5;
|
|
73
|
+
const center_y = (y0 + y1) * 0.5;
|
|
74
|
+
const center_z = (z0 + z1) * 0.5;
|
|
75
|
+
|
|
76
|
+
const p_x = hit_x - center_x;
|
|
77
|
+
const p_y = hit_y - center_y;
|
|
78
|
+
const p_z = hit_z - center_z;
|
|
79
|
+
|
|
80
|
+
const d_x = (x0 - x1) * 0.5;
|
|
81
|
+
const d_y = (y0 - y1) * 0.5;
|
|
82
|
+
const d_z = (z0 - z1) * 0.5;
|
|
83
|
+
|
|
84
|
+
// bias is necessary to deal with rounding errors
|
|
85
|
+
const bias = 1.000001;
|
|
86
|
+
|
|
87
|
+
const normal_x = (p_x / Math.abs(d_x) * bias) | 0;
|
|
88
|
+
const normal_y = (p_y / Math.abs(d_y) * bias) | 0;
|
|
89
|
+
const normal_z = (p_z / Math.abs(d_z) * bias) | 0;
|
|
90
|
+
|
|
91
|
+
// normalize surface normal vector
|
|
92
|
+
const normal_inv_length = 1 / Math.hypot(normal_x, normal_y, normal_z);
|
|
93
|
+
|
|
94
|
+
result[result_offset] = hit_x;
|
|
95
|
+
result[result_offset + 1] = hit_y;
|
|
96
|
+
result[result_offset + 2] = hit_z;
|
|
97
|
+
|
|
98
|
+
result[result_offset + 3] = normal_x * normal_inv_length;
|
|
99
|
+
result[result_offset + 4] = normal_y * normal_inv_length;
|
|
100
|
+
result[result_offset + 5] = normal_z * normal_inv_length;
|
|
101
|
+
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
@@ -1,20 +1,12 @@
|
|
|
1
|
+
import { aabb3_from_v3_array } from "./aabb3_from_v3_array.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
4
|
+
* @deprecated use {@link aabb3_from_v3_array} instead
|
|
3
5
|
* @param {Float32Array} data must be x,y,z sequence
|
|
4
6
|
* @param {AABB3} aabb
|
|
5
7
|
*/
|
|
6
8
|
export function computeBoundingBoxFromVertexData(data, aabb) {
|
|
7
|
-
aabb.setNegativelyInfiniteBounds();
|
|
8
|
-
|
|
9
|
-
let i = 0;
|
|
10
|
-
const data_size = data.length;
|
|
11
|
-
|
|
12
|
-
while (i < data_size) {
|
|
13
|
-
const x = data[i++];
|
|
14
|
-
const y = data[i++];
|
|
15
|
-
const z = data[i++];
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
}
|
|
10
|
+
aabb3_from_v3_array(aabb, data, data.length);
|
|
19
11
|
|
|
20
12
|
}
|
|
@@ -9,7 +9,14 @@ import { max2 } from "../../../math/max2.js";
|
|
|
9
9
|
* @param {number} input_count
|
|
10
10
|
* @param {number} d number of dimensions
|
|
11
11
|
*/
|
|
12
|
-
export function compute_aabb_from_points(
|
|
12
|
+
export function compute_aabb_from_points(
|
|
13
|
+
result,
|
|
14
|
+
input,
|
|
15
|
+
input_offset,
|
|
16
|
+
input_count,
|
|
17
|
+
d
|
|
18
|
+
) {
|
|
19
|
+
|
|
13
20
|
let i = 0;
|
|
14
21
|
let j = 0;
|
|
15
22
|
|
|
@@ -5,7 +5,7 @@ import { max2 } from "../../../math/max2.js";
|
|
|
5
5
|
import { max3 } from "../../../math/max3.js";
|
|
6
6
|
import { min2 } from "../../../math/min2.js";
|
|
7
7
|
import { compute_signed_distance_gradient_by_sampling } from "./util/compute_signed_distance_gradient_by_sampling.js";
|
|
8
|
-
import { aabb3_nearest_point_on_surface } from "
|
|
8
|
+
import { aabb3_nearest_point_on_surface } from "../aabb/aabb3_nearest_point_on_surface.js";
|
|
9
9
|
|
|
10
10
|
export class UnitCubeShape3D extends AbstractShape3D {
|
|
11
11
|
|
|
@@ -204,7 +204,7 @@ export function computeTriangleRayIntersectionBarycentricEdge(result, origin_x,
|
|
|
204
204
|
const tvec_z = origin_z - az;
|
|
205
205
|
|
|
206
206
|
// calculate u
|
|
207
|
-
|
|
207
|
+
const u = v3_dot(tvec_x, tvec_y, tvec_z, pvec_x, pvec_y, pvec_z);
|
|
208
208
|
|
|
209
209
|
if (u < 0 || u > det) {
|
|
210
210
|
// outside of bounds of the triangle
|
|
@@ -218,7 +218,7 @@ export function computeTriangleRayIntersectionBarycentricEdge(result, origin_x,
|
|
|
218
218
|
const qvec_z = tvec_x * edge1_y - tvec_y * edge1_x;
|
|
219
219
|
|
|
220
220
|
// calculate V parameter
|
|
221
|
-
|
|
221
|
+
const v = v3_dot(direction_x, direction_y, direction_z, qvec_x, qvec_y, qvec_z);
|
|
222
222
|
|
|
223
223
|
if (v < 0 || u + v > det) {
|
|
224
224
|
// out of bounds
|
|
@@ -231,12 +231,9 @@ export function computeTriangleRayIntersectionBarycentricEdge(result, origin_x,
|
|
|
231
231
|
// calculate t, scale parameter, ray intersects triangle
|
|
232
232
|
const t = v3_dot(edge2_x, edge2_y, edge2_z, qvec_x, qvec_y, qvec_z) * inv_det;
|
|
233
233
|
|
|
234
|
-
u *= inv_det;
|
|
235
|
-
v *= inv_det;
|
|
236
|
-
|
|
237
234
|
result[0] = t;
|
|
238
|
-
result[1] = u;
|
|
239
|
-
result[2] = v;
|
|
235
|
+
result[1] = u*inv_det;
|
|
236
|
+
result[2] = v*inv_det;
|
|
240
237
|
|
|
241
238
|
return true;
|
|
242
239
|
}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import {Port} from "./Port";
|
|
2
|
+
import {DataType} from "../DataType";
|
|
3
|
+
import {PortDirection} from "./PortDirection";
|
|
2
4
|
|
|
5
|
+
export class NodeDescription {
|
|
6
|
+
|
|
7
|
+
readonly inPorts:Port[]
|
|
8
|
+
readonly outPorts:Port[]
|
|
9
|
+
|
|
10
|
+
getPorts(): Port[]
|
|
11
|
+
|
|
12
|
+
createPort(type: DataType, name:string,direction:PortDirection): number
|
|
3
13
|
}
|
|
@@ -19,7 +19,7 @@ test("serialize/deserialize 1 node with 1 port", () => {
|
|
|
19
19
|
p0.dataType = t0;
|
|
20
20
|
p0.direction = PortDirection.In;
|
|
21
21
|
|
|
22
|
-
n0.
|
|
22
|
+
n0.getPorts().push(p0);
|
|
23
23
|
|
|
24
24
|
const lA = new NodeRegistry();
|
|
25
25
|
|
|
@@ -75,3 +75,49 @@ test("hasType", () => {
|
|
|
75
75
|
|
|
76
76
|
expect(registry.hasType(type)).toBe(true);
|
|
77
77
|
});
|
|
78
|
+
|
|
79
|
+
test("inPorts works as intended", () => {
|
|
80
|
+
const node = new NodeDescription();
|
|
81
|
+
|
|
82
|
+
const type = DataType.from(0, 'a');
|
|
83
|
+
|
|
84
|
+
expect(node.inPorts.length).toBe(0);
|
|
85
|
+
|
|
86
|
+
node.createPort(type, 'a', PortDirection.Out);
|
|
87
|
+
|
|
88
|
+
expect(node.inPorts.length).toBe(0);
|
|
89
|
+
|
|
90
|
+
node.createPort(type, 'a', PortDirection.In);
|
|
91
|
+
|
|
92
|
+
expect(node.inPorts.length).toBe(1);
|
|
93
|
+
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("outPorts works as intended", () => {
|
|
97
|
+
const node = new NodeDescription();
|
|
98
|
+
|
|
99
|
+
const type = DataType.from(0, 'a');
|
|
100
|
+
|
|
101
|
+
expect(node.outPorts.length).toBe(0);
|
|
102
|
+
|
|
103
|
+
node.createPort(type, 'a', PortDirection.In);
|
|
104
|
+
|
|
105
|
+
expect(node.outPorts.length).toBe(0);
|
|
106
|
+
|
|
107
|
+
node.createPort(type, 'a', PortDirection.Out);
|
|
108
|
+
|
|
109
|
+
expect(node.outPorts.length).toBe(1);
|
|
110
|
+
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test("createPort assigns unique IDs for ports", () => {
|
|
114
|
+
|
|
115
|
+
const node = new NodeDescription();
|
|
116
|
+
|
|
117
|
+
const type = DataType.from(0, 'a');
|
|
118
|
+
|
|
119
|
+
const a = node.createPort(type, 'a', PortDirection.In);
|
|
120
|
+
const b = node.createPort(type, 'a', PortDirection.In);
|
|
121
|
+
|
|
122
|
+
expect(a).not.toEqual(b);
|
|
123
|
+
});
|
|
@@ -35,11 +35,15 @@ export class Port {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
hash() {
|
|
38
|
+
const dataType = this.dataType;
|
|
39
|
+
|
|
40
|
+
const type_hash = dataType !== null ? dataType.id : 0;
|
|
41
|
+
|
|
38
42
|
return computeHashIntegerArray(
|
|
39
43
|
computeStringHash(this.name),
|
|
40
44
|
this.id,
|
|
41
45
|
this.direction,
|
|
42
|
-
|
|
46
|
+
type_hash
|
|
43
47
|
);
|
|
44
48
|
}
|
|
45
49
|
|
|
@@ -50,8 +54,8 @@ export class Port {
|
|
|
50
54
|
*/
|
|
51
55
|
equals(other) {
|
|
52
56
|
|
|
53
|
-
return this.
|
|
54
|
-
&& this.
|
|
57
|
+
return this.id === other.id
|
|
58
|
+
&& this.name === other.name
|
|
55
59
|
&& this.direction === other.direction
|
|
56
60
|
&& this.dataType === other.dataType
|
|
57
61
|
;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Port } from "./Port.js";
|
|
2
|
+
|
|
3
|
+
test("constructor does not throw", () => {
|
|
4
|
+
expect(() => new Port()).not.toThrow();
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
test("hash is consistent", () => {
|
|
8
|
+
const port = new Port();
|
|
9
|
+
|
|
10
|
+
expect(port.hash()).toEqual(port.hash());
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test("hash is an unsigned integer", () => {
|
|
14
|
+
const port = new Port();
|
|
15
|
+
|
|
16
|
+
const hash = port.hash();
|
|
17
|
+
|
|
18
|
+
expect(typeof hash).toEqual("number");
|
|
19
|
+
expect(Number.isInteger(hash)).toEqual(true);
|
|
20
|
+
expect(hash).toBeGreaterThanOrEqual(0);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("hash is different for different ports", () => {
|
|
24
|
+
|
|
25
|
+
const a = new Port();
|
|
26
|
+
const b = new Port();
|
|
27
|
+
|
|
28
|
+
expect(a.hash()).not.toEqual(b.hash());
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("equality works as intended", () => {
|
|
32
|
+
const a = new Port();
|
|
33
|
+
|
|
34
|
+
expect(a.equals(a)).toEqual(true);
|
|
35
|
+
|
|
36
|
+
const b = new Port();
|
|
37
|
+
|
|
38
|
+
expect(b.equals(a)).toEqual(false);
|
|
39
|
+
|
|
40
|
+
b.id = a.id;
|
|
41
|
+
|
|
42
|
+
expect(b.equals(a)).toEqual(true);
|
|
43
|
+
|
|
44
|
+
});
|