@woosh/meep-engine 2.47.2 → 2.47.8

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.
Files changed (126) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -0
  2. package/build/bundle-worker-terrain.js +1 -0
  3. package/build/meep.cjs +659 -553
  4. package/build/meep.min.js +1 -1
  5. package/build/meep.module.js +659 -553
  6. package/package.json +2 -2
  7. package/src/core/binary/BitSet.spec.js +3 -3
  8. package/src/core/bvh2/BinaryNode.js +12 -10
  9. package/src/core/bvh2/aabb3/AABB3.js +30 -31
  10. package/src/core/bvh2/binary/2/BinaryUint32BVH.js +1 -1
  11. package/src/core/bvh2/binary/BinaryBVH.js +1 -1
  12. package/src/core/bvh2/binary/RayLeafIntersectionVisitor.js +1 -1
  13. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +1 -1
  14. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +2 -2
  15. package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +1 -1
  16. package/src/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +1 -1
  17. package/src/core/bvh2/bvh3/query/bvh_collect_user_data.js +10 -8
  18. package/src/core/bvh2/bvh3/query/bvh_query_leaves_generic.js +14 -22
  19. package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +13 -15
  20. package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +14 -21
  21. package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.js +16 -24
  22. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_frustum.js +23 -26
  23. package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +10 -11
  24. package/src/core/bvh2/transform/BottomUpOptimizingRebuilder.js +2 -2
  25. package/src/core/bvh2/transform/tryRotateSingleNode.js +2 -2
  26. package/src/core/bvh2/traversal/aabb3_detailed_volume_intersection_callback_based.js +1 -1
  27. package/src/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +1 -1
  28. package/src/core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js +13 -0
  29. package/src/core/color/Color.d.ts +2 -1
  30. package/src/core/color/Color.js +30 -5
  31. package/src/core/color/ColorUtils.js +7 -5
  32. package/src/core/color/parseHex.js +11 -3
  33. package/src/core/color/rgb2hex.js +1 -1
  34. package/src/core/geom/3d/SurfacePoint3.d.ts +7 -0
  35. package/src/core/geom/3d/SurfacePoint3.js +56 -1
  36. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_combine.js +2 -2
  37. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_contains_point.js +1 -1
  38. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_frustum_degree.js +2 -2
  39. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_combined_surface_area.js +2 -2
  40. package/src/core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js +1 -1
  41. package/src/core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.spec.js +8 -0
  42. package/src/core/geom/3d/aabb/{computeAABB3PlaneSide.js → aabb3_compute_plane_side.js} +1 -1
  43. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_detailed_volume_intersection.js +7 -7
  44. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_from_v3_array.js +4 -4
  45. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_from_v3_array_transformed.js +2 -2
  46. package/src/core/{bvh2/aabb3/aabb3_intersect_aabb3.js → geom/3d/aabb/aabb3_intersects_aabb3.js} +2 -2
  47. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_frustum_array.js +2 -2
  48. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_frustum_degree.js +4 -4
  49. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_line_segment.js +1 -1
  50. package/src/core/geom/3d/aabb/aabb3_intersects_ray.js +87 -0
  51. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray.spec.js +1 -1
  52. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray_branchless.js +2 -2
  53. package/src/core/{bvh2/aabb3/aabb3_intersect_ray_slab.js → geom/3d/aabb/aabb3_intersects_ray_slab.js} +35 -17
  54. package/src/core/geom/3d/aabb/aabb3_matrix4_project_by_corners.js +5 -1
  55. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_nearest_point_on_surface.js +2 -2
  56. package/src/core/geom/3d/aabb/aabb3_raycast.js +103 -0
  57. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_signed_distance_sqr_to_point.js +1 -1
  58. package/src/core/geom/3d/aabb/computeBoundingBoxFromVertexData.js +4 -12
  59. package/src/core/geom/3d/aabb/compute_aabb_from_points.js +8 -1
  60. package/src/core/geom/3d/shape/UnitCubeShape3D.js +1 -1
  61. package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +4 -7
  62. package/src/core/model/node-graph/DataType.d.ts +4 -0
  63. package/src/core/model/node-graph/node/NodeDescription.d.ts +11 -1
  64. package/src/core/model/node-graph/node/NodeInstance.js +8 -1
  65. package/src/core/model/node-graph/node/NodeRegistry.spec.js +47 -1
  66. package/src/core/model/node-graph/node/Port.d.ts +3 -0
  67. package/src/core/model/node-graph/node/Port.js +7 -3
  68. package/src/core/model/node-graph/node/Port.spec.js +44 -0
  69. package/src/core/model/node-graph/node/PortDirection.d.ts +5 -0
  70. package/src/engine/asset/loaders/GLTFAssetLoader.js +1 -1
  71. package/src/engine/ecs/foliage/InstancedFoliage.js +1 -1
  72. package/src/engine/ecs/storage/BinaryBufferSerializer.js +13 -1
  73. package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +11 -4
  74. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +54 -0
  75. package/src/engine/ecs/systems/RenderSystem.js +1 -33
  76. package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +2 -4
  77. package/src/engine/ecs/terrain/tiles/TileBuildWorker.js +6 -1
  78. package/src/engine/graphics/GraphicsEngine.js +5 -1
  79. package/src/engine/graphics/ecs/decal/v2/Decal.js +44 -2
  80. package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +31 -0
  81. package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +16 -5
  82. package/src/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +88 -56
  83. package/src/engine/graphics/geometry/buffered/query/ClippingPlaneContainmentComputingVisitor.js +2 -2
  84. package/src/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +1 -1
  85. package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +3 -2
  86. package/src/engine/graphics/geometry/skining/computeSkinnedMeshBoundingVolumes.js +3 -2
  87. package/src/engine/graphics/micron/format/MicronGeometry.js +1 -1
  88. package/src/engine/graphics/micron/format/validate_patch_bounds.js +1 -1
  89. package/src/engine/graphics/micron/render/refinement/ActivePatchList.js +1 -1
  90. package/src/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +16 -16
  91. package/src/engine/graphics/render/forward_plus/LightManager.js +3 -0
  92. package/src/engine/graphics/render/forward_plus/LightManager.spec.js +5 -5
  93. package/src/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_APPLY_DECALS.js +4 -0
  94. package/src/engine/graphics/render/forward_plus/model/Decal.js +10 -2
  95. package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_objects.js +2 -2
  96. package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +18 -16
  97. package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +2 -0
  98. package/src/engine/graphics/render/visibility/IncrementalDeltaSet.js +26 -13
  99. package/src/engine/graphics/sh3/path_tracer/GeometryBVHBatched.js +8 -2
  100. package/src/engine/graphics/sh3/path_tracer/PathTracer.js +3 -3
  101. package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +18 -15
  102. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_max.js +1 -1
  103. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min.js +1 -1
  104. package/src/engine/graphics/three/three_computeObjectBoundingBox.js +56 -0
  105. package/src/engine/input/devices/{InputDeviceButton.d.ts → InputDeviceSwitch.d.ts} +1 -1
  106. package/src/engine/input/devices/{InputDeviceButton.js → InputDeviceSwitch.js} +1 -1
  107. package/src/engine/input/devices/KeyboardDevice.d.ts +2 -2
  108. package/src/engine/input/devices/KeyboardDevice.js +58 -40
  109. package/src/engine/input/devices/PointerDevice.js +224 -179
  110. package/src/core/bvh2/aabb3/aabb3_intersects_ray.js +0 -97
  111. package/src/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane_max.spec.js +0 -8
  112. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_frustum_array.js +0 -0
  113. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_ray.js +0 -0
  114. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_ray_array.js +0 -0
  115. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_box_surface_area_2.js +0 -0
  116. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_compute_half_surface_area.js +0 -0
  117. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_compute_surface_area.js +0 -0
  118. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_corner_edge_mapping.js +0 -0
  119. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_corner_edge_mapping.spec.js +0 -0
  120. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_corner_mapping.js +0 -0
  121. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_corner_mapping.spec.js +0 -0
  122. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_plane_mapping.js +0 -0
  123. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_expand_array.js +0 -0
  124. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray_fast.js +0 -0
  125. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_score_boxes_SAH.js +0 -0
  126. /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 { computeAABB3PlaneSide } from "../../geom/3d/aabb/computeAABB3PlaneSide.js";
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 = computeAABB3PlaneSide(
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
  }
@@ -1,4 +1,4 @@
1
- import { fabsf } from "../../math/fabsf.js";
1
+ import { fabsf } from "../../../math/fabsf.js";
2
2
 
3
3
  /**
4
4
  * http://stackoverflow.com/questions/3106666/intersection-of-line-segment-with-axis-aligned-box-in-c-sharp
@@ -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,4 +1,4 @@
1
- import { seededRandom } from "../../math/random/seededRandom.js";
1
+ import { seededRandom } from "../../../math/random/seededRandom.js";
2
2
  import { aabb3_intersects_ray } from "./aabb3_intersects_ray.js";
3
3
 
4
4
  test.skip("performance raycast", () => {
@@ -1,5 +1,5 @@
1
- import { min2 } from "../../math/min2.js";
2
- import { max2 } from "../../math/max2.js";
1
+ import { min2 } from "../../../math/min2.js";
2
+ import { max2 } from "../../../math/max2.js";
3
3
 
4
4
  /**
5
5
  * SLOW, don't use in production
@@ -1,10 +1,9 @@
1
- import { min2 } from "../../math/min2.js";
2
- import { max2 } from "../../math/max2.js";
1
+ import { max3 } from "../../../math/max3.js";
2
+ import { min3 } from "../../../math/min3.js";
3
3
 
4
4
  /**
5
- * see: https://tavianator.com/fast-branchless-raybounding-box-intersections-part-2-nans/
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 aabb3_intersect_ray_slab(
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
- const dir_inv_x = -dirX;
50
- const dir_inv_y = -dirY;
51
- const dir_inv_z = -dirZ;
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
- const tMin_z = max2(tMin_y, min2(t1_z, t2_z));
69
- const tMax_z = min2(tMax_y, max2(t1_z, t2_z));
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 tMax_z > max2(tMin_z, 0.0);
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(result, aabb_corners, projection_matrix) {
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');
@@ -1,5 +1,5 @@
1
- import { clamp } from "../../math/clamp.js";
2
- import { min2 } from "../../math/min2.js";
1
+ import { clamp } from "../../../math/clamp.js";
2
+ import { min2 } from "../../../math/min2.js";
3
3
 
4
4
  //
5
5
 
@@ -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,4 +1,4 @@
1
- import { max2 } from "../../math/max2.js";
1
+ import { max2 } from "../../../math/max2.js";
2
2
 
3
3
  /**
4
4
  * Compute squared distance to point, value is negative if the point is inside the box
@@ -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
- aabb._expandToFitPoint(x, y, z);
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(result, input, input_offset, input_count, d) {
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 "../../../bvh2/aabb3/aabb3_nearest_point_on_surface.js";
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
- let u = v3_dot(tvec_x, tvec_y, tvec_z, pvec_x, pvec_y, pvec_z);
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
- let v = v3_dot(direction_x, direction_y, direction_z, qvec_x, qvec_y, qvec_z);
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
  }
@@ -0,0 +1,4 @@
1
+ export class DataType{
2
+ id:number
3
+ name:string
4
+ }
@@ -1,3 +1,13 @@
1
- export class NodeDescription{
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
  }
@@ -228,6 +228,12 @@ export class NodeInstance {
228
228
  }
229
229
  }
230
230
 
231
+ clearParameters(){
232
+ for (const key in this.parameters) {
233
+ this.deleteParameter(key);
234
+ }
235
+ }
236
+
231
237
  /**
232
238
  *
233
239
  * @param {NodeDescription} node
@@ -247,8 +253,9 @@ export class NodeInstance {
247
253
  });
248
254
 
249
255
  //clear parameters
250
- this.parameters.splice(0, this.parameters.length);
256
+ this.clearParameters();
251
257
 
258
+ // TODO address parameters in NodeDescription as well
252
259
  //populate parameter defaults
253
260
  node.parameters.forEach(pd => {
254
261
  this.parameters[pd.id] = pd.defaultValue;
@@ -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.ports.push(p0);
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
+ });
@@ -0,0 +1,3 @@
1
+ export class Port{
2
+
3
+ }
@@ -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
- this.dataType.id
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.name === other.name
54
- && this.id === other.id
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
+ });
@@ -0,0 +1,5 @@
1
+ export enum PortDirection{
2
+ In= 0,
3
+ Out= 1,
4
+ Unspecified= 2
5
+ }
@@ -2,7 +2,6 @@ import { Transform } from "../../ecs/transform/Transform.js";
2
2
  import { Asset } from "../Asset.js";
3
3
  import { prepareMaterial, prepareObject } from "../../graphics/three/ThreeFactory.js";
4
4
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
5
- import { three_computeObjectBoundingBox } from "../../ecs/systems/RenderSystem.js";
6
5
  import { AABB3 } from "../../../core/bvh2/aabb3/AABB3.js";
7
6
  import { StaticMaterialCache } from "./material/StaticMaterialCache.js";
8
7
  import { DDSLoader } from "three/examples/jsm/loaders/DDSLoader.js";
@@ -28,6 +27,7 @@ import { traverseThreeObject } from "../../graphics/ecs/highlight/renderer/trave
28
27
  import { computeTextureHash } from "./material/computeTextureHash.js";
29
28
  import { computeTextureEquality } from "./material/computeTextureEquality.js";
30
29
  import { async_traverse_three_object } from "./async_traverse_three_object.js";
30
+ import { three_computeObjectBoundingBox } from "../../graphics/three/three_computeObjectBoundingBox.js";
31
31
 
32
32
  const animationOptimizer = new AnimationOptimizer();
33
33
  const materialCache = StaticMaterialCache.Global;
@@ -17,7 +17,7 @@ import {
17
17
  } from "../../graphics/geometry/buffered/computeGeometryBoundingSphereMiniball.js";
18
18
  import { serializeRowFirstTable } from "../../../core/collection/table/serializeRowFirstTable.js";
19
19
  import { deserializeRowFirstTable } from "../../../core/collection/table/deserializeRowFirstTable.js";
20
- import { aabb3_from_v3_array_transformed } from "../../../core/bvh2/aabb3/aabb3_from_v3_array_transformed.js";
20
+ import { aabb3_from_v3_array_transformed } from "../../../core/geom/3d/aabb/aabb3_from_v3_array_transformed.js";
21
21
  import { ViewState } from "./ViewState.js";
22
22
  import { compose_matrix4_array } from "../../../core/geom/3d/compose_matrix4_array.js";
23
23