@woosh/meep-engine 2.34.41 → 2.34.45

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 (58) hide show
  1. package/core/bvh2/BinaryNode.js +10 -8
  2. package/core/bvh2/LeafNode.js +2 -1
  3. package/core/bvh2/aabb3/AABB3.js +879 -1059
  4. package/core/bvh2/aabb3/AABB3.spec.js +5 -7
  5. package/core/bvh2/aabb3/aabb3_array_intersects_ray.js +2 -2
  6. package/core/bvh2/aabb3/aabb3_box_surface_area_2.js +10 -0
  7. package/core/bvh2/aabb3/aabb3_compute_half_surface_area.js +16 -0
  8. package/core/bvh2/aabb3/aabb3_compute_surface_area.js +18 -0
  9. package/core/bvh2/aabb3/aabb3_expand_array.js +15 -0
  10. package/core/bvh2/aabb3/aabb3_intersect_aabb3.js +28 -0
  11. package/core/bvh2/aabb3/aabb3_intersect_ray_slab.js +73 -0
  12. package/core/bvh2/aabb3/{aabb3_intersects_frustum.js → aabb3_intersects_frustum_array.js} +16 -1
  13. package/core/bvh2/aabb3/aabb3_intersects_line_segment.js +79 -0
  14. package/core/bvh2/aabb3/aabb3_intersects_ray.js +92 -0
  15. package/core/bvh2/aabb3/{AABB3Math.spec.js → aabb3_intersects_ray.spec.js} +3 -3
  16. package/core/bvh2/aabb3/aabb3_intersects_ray_fast.js +176 -0
  17. package/core/bvh2/aabb3/aabb3_score_boxes_SAH.js +43 -0
  18. package/core/bvh2/aabb3/aabb_score_boxes_SAH_delta.js +37 -0
  19. package/core/bvh2/aabb3/deserializeAABB3.js +17 -0
  20. package/core/bvh2/aabb3/deserializeAABB3Encoded_v0.js +73 -0
  21. package/core/bvh2/aabb3/deserializeAABB3Quantized16Uint.js +36 -0
  22. package/core/bvh2/aabb3/serializeAABB3.js +13 -0
  23. package/core/bvh2/aabb3/serializeAABB3Quantized16Uint.js +33 -0
  24. package/core/bvh2/binary/2/BinaryUint32BVH.js +3 -3
  25. package/core/bvh2/binary/BinaryBVH.js +2 -2
  26. package/core/bvh2/binary/RayLeafIntersectionVisitor.js +2 -2
  27. package/core/bvh2/serialization/deserializeBinaryNode.js +1 -1
  28. package/core/bvh2/serialization/deserializeBinaryNodeFromBinaryBuffer.js +2 -1
  29. package/core/bvh2/serialization/serializeBinaryNode.js +1 -1
  30. package/core/bvh2/serialization/serializeBinaryNodeToBinaryBuffer.js +2 -1
  31. package/core/bvh2/transform/BottomUpOptimizingRebuilder.js +6 -5
  32. package/core/bvh2/transform/tryRotateSingleNode.js +2 -1
  33. package/core/geom/3d/frustum/{array_setFromProjectionMatrix.js → frustum_from_projection_matrix_array.js} +1 -1
  34. package/core/geom/3d/topology/TopoMesh.js +0 -8
  35. package/core/geom/3d/topology/TopoVertex.js +7 -6
  36. package/core/geom/3d/topology/simplify/quadratic/Quadratic3.js +93 -5
  37. package/core/geom/3d/topology/simplify/quadratic/build_vertex_quadratics.js +7 -4
  38. package/core/geom/3d/topology/simplify/quadratic/compute_edge_collapse_cost_quadratic.js +7 -1
  39. package/core/geom/3d/topology/simplify/simplifyTopoMesh.js +1 -14
  40. package/core/math/fabsf.js +8 -0
  41. package/engine/development/performance/MetricCollection.js +6 -0
  42. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +1 -1
  43. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +2 -2
  44. package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +23 -8
  45. package/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +2 -2
  46. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +4 -0
  47. package/engine/graphics/micron/build/hierarchy/merge_patches.js +1 -1
  48. package/engine/graphics/micron/convert_three_object_to_micron.js +2 -0
  49. package/engine/graphics/micron/format/MicronGeometryPatchOccurance.js +3 -2
  50. package/engine/graphics/micron/prototypeVirtualGeometry.js +12 -7
  51. package/engine/graphics/micron/render/PatchCacheKey.js +1 -1
  52. package/engine/graphics/micron/render/VirtualGeometryBuilder.js +16 -43
  53. package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +5 -1
  54. package/engine/graphics/micron/render/refinement/ActivePatchList.js +4 -10
  55. package/engine/graphics/micron/render/refinement/RefinementSpec.js +16 -20
  56. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +2 -2
  57. package/package.json +1 -1
  58. package/core/bvh2/aabb3/AABB3Math.js +0 -579
@@ -1,11 +1,9 @@
1
1
  import { BinaryBuffer } from "../../binary/BinaryBuffer.js";
2
- import {
3
- AABB3,
4
- deserializeAABB3,
5
- deserializeAABB3Quantized16Uint,
6
- serializeAABB3,
7
- serializeAABB3Quantized16Uint
8
- } from "./AABB3.js";
2
+ import { AABB3 } from "./AABB3.js";
3
+ import { serializeAABB3Quantized16Uint } from "./serializeAABB3Quantized16Uint.js";
4
+ import { deserializeAABB3Quantized16Uint } from "./deserializeAABB3Quantized16Uint.js";
5
+ import { serializeAABB3 } from "./serializeAABB3.js";
6
+ import { deserializeAABB3 } from "./deserializeAABB3.js";
9
7
 
10
8
 
11
9
  function compareBounds(expected, actual, numDigits = 10) {
@@ -1,6 +1,6 @@
1
1
  //
2
2
 
3
- import { intersectRay } from "./AABB3Math.js";
3
+ import { aabb3_intersects_ray } from "./aabb3_intersects_ray.js";
4
4
 
5
5
  /**
6
6
  *
@@ -13,7 +13,7 @@ import { intersectRay } from "./AABB3Math.js";
13
13
  * @param {number} direction_z
14
14
  */
15
15
  export function aabb3_array_intersects_ray(aabb, origin_x, origin_y, origin_z, direction_x, direction_y, direction_z) {
16
- return intersectRay(aabb[0], aabb[1], aabb[2], aabb[3], aabb[4], aabb[5],
16
+ return aabb3_intersects_ray(aabb[0], aabb[1], aabb[2], aabb[3], aabb[4], aabb[5],
17
17
  origin_x, origin_y, origin_z,
18
18
  direction_x, direction_y, direction_z
19
19
  );
@@ -0,0 +1,10 @@
1
+ import { aabb3_compute_half_surface_area } from "./aabb3_compute_half_surface_area.js";
2
+
3
+ /**
4
+ *
5
+ * @param {AABB3} node
6
+ * @returns {number}
7
+ */
8
+ export function aabb3_box_surface_area_2(node) {
9
+ return aabb3_compute_half_surface_area(node.x0, node.y0, node.z0, node.x1, node.y1, node.z1);
10
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ *
3
+ * @param {number} x0
4
+ * @param {number} y0
5
+ * @param {number} z0
6
+ * @param {number} x1
7
+ * @param {number} y1
8
+ * @param {number} z1
9
+ * @returns {number}
10
+ */
11
+ export function aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1) {
12
+ const dx = x1 - x0;
13
+ const dy = y1 - y0;
14
+ const dz = z1 - z0;
15
+ return dy * (dx + dz) + dz * dx; //1 side, since it's a heuristic only
16
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ *
3
+ * @param {number} x0
4
+ * @param {number} y0
5
+ * @param {number} z0
6
+ * @param {number} x1
7
+ * @param {number} y1
8
+ * @param {number} z1
9
+ * @returns {number}
10
+ */
11
+ function aabb3_compute_surface_area(x0, y0, z0, x1, y1, z1) {
12
+ const dx = x1 - x0;
13
+ const dy = y1 - y0;
14
+ const dz = z1 - z0;
15
+ return (dy * (dx + dz) + dz * dx) * 2; //2 of each side
16
+ }
17
+
18
+ export { aabb3_compute_surface_area };
@@ -0,0 +1,15 @@
1
+ /**
2
+ *
3
+ * @param {ArrayLike<number>|number[]|Float64Array|Float32Array} input
4
+ * @param {ArrayLike<number>|number[]|Float64Array|Float32Array} output
5
+ * @param {number} distance
6
+ */
7
+ export function aabb3_expand_array(input, output, distance) {
8
+ output[0] = input[0] - distance;
9
+ output[1] = input[1] - distance;
10
+ output[2] = input[2] - distance;
11
+
12
+ output[3] = input[3] + distance;
13
+ output[4] = input[4] + distance;
14
+ output[5] = input[5] + distance;
15
+ }
@@ -0,0 +1,28 @@
1
+ import { intersects1D } from "../../math/intersects1D.js";
2
+
3
+ /**
4
+ *
5
+ * @param {number} ax0
6
+ * @param {number} ay0
7
+ * @param {number} az0
8
+ * @param {number} ax1
9
+ * @param {number} ay1
10
+ * @param {number} az1
11
+ * @param {number} bx0
12
+ * @param {number} by0
13
+ * @param {number} bz0
14
+ * @param {number} bx1
15
+ * @param {number} by1
16
+ * @param {number} bz1
17
+ * @returns {boolean}
18
+ */
19
+ export function aabb3_intersect_aabb3(
20
+ ax0, ay0, az0,
21
+ ax1, ay1, az1,
22
+ bx0, by0, bz0,
23
+ bx1, by1, bz1
24
+ ) {
25
+ return intersects1D(ax0, ax1, bx0, bx1)
26
+ && intersects1D(ay0, ay1, by0, by1)
27
+ && intersects1D(az0, az1, bz0, bz1);
28
+ }
@@ -0,0 +1,73 @@
1
+ import { min2 } from "../../math/min2.js";
2
+ import { max2 } from "../../math/max2.js";
3
+
4
+ /**
5
+ * see: https://tavianator.com/fast-branchless-raybounding-box-intersections-part-2-nans/
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
+ * @param {number} x0
9
+ * @param {number} y0
10
+ * @param {number} z0
11
+ * @param {number} x1
12
+ * @param {number} y1
13
+ * @param {number} z1
14
+ * @param {number} oX
15
+ * @param {number} oY
16
+ * @param {number} oZ
17
+ * @param {number} dirX
18
+ * @param {number} dirY
19
+ * @param {number} dirZ
20
+ * @returns {boolean}
21
+ */
22
+ export function aabb3_intersect_ray_slab(
23
+ x0, y0, z0,
24
+ x1, y1, z1,
25
+ oX, oY, oZ,
26
+ dirX, dirY, dirZ
27
+ ) {
28
+ /*
29
+ Java CODE:
30
+ bool intersection(box b, ray r) {
31
+ double t1 = (b.min[0] - r.origin[0])*r.dir_inv[0];
32
+ double t2 = (b.max[0] - r.origin[0])*r.dir_inv[0];
33
+
34
+ double tmin = min(t1, t2);
35
+ double tmax = max(t1, t2);
36
+
37
+ for (int i = 1; i < 3; ++i) {
38
+ t1 = (b.min[i] - r.origin[i])*r.dir_inv[i];
39
+ t2 = (b.max[i] - r.origin[i])*r.dir_inv[i];
40
+
41
+ tmin = max(tmin, min(t1, t2));
42
+ tmax = min(tmax, max(t1, t2));
43
+ }
44
+
45
+ return tmax > max(tmin, 0.0);
46
+ }
47
+
48
+ */
49
+ const dir_inv_x = -dirX;
50
+ const dir_inv_y = -dirY;
51
+ const dir_inv_z = -dirZ;
52
+
53
+ const t1_x = (x0 - oX) * dir_inv_x;
54
+ const t2_x = (x1 - oX) * dir_inv_x;
55
+
56
+ const tMin_x = min2(t1_x, t2_x);
57
+ const tMax_x = max2(t1_x, t2_x);
58
+
59
+ const t1_y = (y0 - oY) * dir_inv_y;
60
+ const t2_y = (y1 - oY) * dir_inv_y;
61
+
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
+ const t1_z = (z0 - oZ) * dir_inv_z;
66
+ const t2_z = (z1 - oZ) * dir_inv_z;
67
+
68
+ const tMin_z = max2(tMin_y, min2(t1_z, t2_z));
69
+ const tMax_z = min2(tMax_y, max2(t1_z, t2_z));
70
+
71
+
72
+ return tMax_z > max2(tMin_z, 0.0);
73
+ }
@@ -6,7 +6,7 @@ import { aabb3_computeDistanceAbovePlane } from "../../geom/3d/aabb/aabb3_comput
6
6
  * @param {Float32Array|number[]} frustum
7
7
  * @return {boolean}
8
8
  */
9
- export function aabb3_intersects_frustum(aabb, frustum) {
9
+ export function aabb3_intersects_frustum_array(aabb, frustum) {
10
10
 
11
11
  const x0 = aabb[0];
12
12
  const y0 = aabb[1];
@@ -15,6 +15,21 @@ export function aabb3_intersects_frustum(aabb, frustum) {
15
15
  const y1 = aabb[4];
16
16
  const z1 = aabb[5];
17
17
 
18
+ return aabb3_intersects_frustum(x0, y0, z0, x1, y1, z1, frustum);
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param {number} x0
24
+ * @param {number} y0
25
+ * @param {number} z0
26
+ * @param {number} x1
27
+ * @param {number} y1
28
+ * @param {number} z1
29
+ * @param {ArrayLike<number>|number[]|Float32Array|Float64Array} frustum
30
+ * @return {boolean}
31
+ */
32
+ export function aabb3_intersects_frustum(x0, y0, z0, x1, y1, z1, frustum) {
18
33
  for (let i = 0; i < 24; i += 4) {
19
34
 
20
35
  const plane_n_x = frustum[i];
@@ -0,0 +1,79 @@
1
+ import { fabsf } from "../../math/fabsf.js";
2
+
3
+ /**
4
+ *
5
+ * @param {number} x0
6
+ * @param {number} y0
7
+ * @param {number} z0
8
+ * @param {number} x1
9
+ * @param {number} y1
10
+ * @param {number} z1
11
+ * @param {number} startX
12
+ * @param {number} startY
13
+ * @param {number} startZ
14
+ * @param {number} endX
15
+ * @param {number} endY
16
+ * @param {number} endZ
17
+ * @returns {boolean}
18
+ */
19
+ function aabb3_intersects_line_segment(
20
+ x0, y0, z0,
21
+ x1, y1, z1,
22
+ startX, startY, startZ,
23
+ endX, endY, endZ
24
+ ) {
25
+
26
+ let boxExtentsX,
27
+ boxExtentsY,
28
+ boxExtentsZ,
29
+ diffX,
30
+ diffY,
31
+ diffZ,
32
+ dirX,
33
+ dirY,
34
+ dirZ,
35
+ centerX,
36
+ centerY,
37
+ centerZ;
38
+ //
39
+ let a, b, c;
40
+
41
+ dirX = 0.5 * (endX - startX);
42
+ boxExtentsX = (x1 - x0) / 2;
43
+ centerX = x0 + boxExtentsX;
44
+ diffX = (0.5 * (endX + startX)) - centerX;
45
+ a = fabsf(dirX);
46
+ if (fabsf(diffX) > boxExtentsX + a) return false;
47
+ //
48
+ dirY = 0.5 * (endY - startY);
49
+ boxExtentsY = (y1 - y0) / 2;
50
+ centerY = y0 + boxExtentsY;
51
+ diffY = (0.5 * (endY + startY)) - centerY;
52
+ b = fabsf(dirY);
53
+ if (fabsf(diffY) > boxExtentsY + b) return false;
54
+ //
55
+ dirZ = 0.5 * (endZ - startZ);
56
+ boxExtentsZ = (z1 - z0) / 2;
57
+ centerZ = z0 + boxExtentsZ;
58
+ diffZ = (0.5 * (endZ + startZ)) - centerZ;
59
+ c = fabsf(dirZ);
60
+ if (fabsf(diffZ) > boxExtentsZ + c) return false;
61
+
62
+ //Dir.y = 0.5f * (segment.mP1.y - segment.mP0.y);
63
+ //BoxExtents.y = aabb.GetExtents(1);
64
+ //Diff.y = (0.5f * (segment.mP1.y + segment.mP0.y)) - aabb.GetCenter(1);
65
+ //b = fabsf(Dir.y);
66
+ //if(fabsf(Diff.y)>BoxExtents.y + b) return false;
67
+
68
+ let f;
69
+ f = dirY * diffZ - dirZ * diffY;
70
+ if (fabsf(f) > boxExtentsY * c + boxExtentsZ * b) return false;
71
+ f = dirZ * diffX - dirX * diffZ;
72
+ if (fabsf(f) > boxExtentsX * c + boxExtentsZ * a) return false;
73
+ f = dirX * diffY - dirY * diffX;
74
+ if (fabsf(f) > boxExtentsX * b + boxExtentsY * a) return false;
75
+
76
+ return true;
77
+ }
78
+
79
+ export { aabb3_intersects_line_segment };
@@ -0,0 +1,92 @@
1
+ import { fabsf } from "../../math/fabsf.js";
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} oX
16
+ * @param {number} oY
17
+ * @param {number} oZ
18
+ * @param {number} dirX
19
+ * @param {number} dirY
20
+ * @param {number} dirZ
21
+ * @returns {boolean}
22
+ */
23
+ function aabb3_intersects_ray(x0, y0, z0, x1, y1, z1, oX, oY, oZ, dirX, dirY, dirZ) {
24
+
25
+ // Z Projection
26
+ const boxExtentsX = (x1 - x0) / 2;
27
+
28
+ const centerX = x0 + boxExtentsX;
29
+
30
+ const diffX = oX - centerX;
31
+
32
+
33
+ if (fabsf(diffX) > boxExtentsX && diffX * dirX >= 0.0) {
34
+ return false;
35
+ }
36
+
37
+ // Y projection
38
+ const boxExtentsY = (y1 - y0) / 2;
39
+
40
+ const centerY = y0 + boxExtentsY;
41
+
42
+ const diffY = oY - centerY;
43
+
44
+
45
+ if (fabsf(diffY) > boxExtentsY && diffY * dirY >= 0.0) {
46
+ return false;
47
+ }
48
+
49
+ // Z projection
50
+ const boxExtentsZ = (z1 - z0) / 2;
51
+
52
+ const centerZ = z0 + boxExtentsZ;
53
+
54
+ const diffZ = oZ - centerZ;
55
+
56
+
57
+ if (fabsf(diffZ) > boxExtentsZ && diffZ * dirZ >= 0.0) {
58
+ return false;
59
+ }
60
+
61
+ //Dir.y = 0.5f * (segment.mP1.y - segment.mP0.y);
62
+ //BoxExtents.y = aabb.GetExtents(1);
63
+ //Diff.y = (0.5f * (segment.mP1.y + segment.mP0.y)) - aabb.GetCenter(1);
64
+ //b = fabsf(Dir.y);
65
+ //if(fabsf(Diff.y)>BoxExtents.y + b) return false;
66
+
67
+ const a = fabsf(dirX);
68
+ const b = fabsf(dirY);
69
+ const c = fabsf(dirZ);
70
+
71
+ const f0 = dirY * diffZ - dirZ * diffY;
72
+
73
+ if (fabsf(f0) > boxExtentsY * c + boxExtentsZ * b) {
74
+ return false;
75
+ }
76
+
77
+ const f1 = dirZ * diffX - dirX * diffZ;
78
+
79
+ if (fabsf(f1) > boxExtentsX * c + boxExtentsZ * a) {
80
+ return false;
81
+ }
82
+
83
+ const f2 = dirX * diffY - dirY * diffX;
84
+
85
+ if (fabsf(f2) > boxExtentsX * b + boxExtentsY * a) {
86
+ return false;
87
+ }
88
+
89
+ return true;
90
+ }
91
+
92
+ export { aabb3_intersects_ray };
@@ -1,5 +1,5 @@
1
1
  import { seededRandom } from "../../math/random/seededRandom.js";
2
- import { intersectRay } from "./AABB3Math.js";
2
+ import { aabb3_intersects_ray } from "./aabb3_intersects_ray.js";
3
3
 
4
4
  test.skip("performance raycast", () => {
5
5
  const rng = seededRandom(42);
@@ -13,7 +13,7 @@ test.skip("performance raycast", () => {
13
13
  //warm up
14
14
  for (i = 0; i < 10000; i++) {
15
15
  rng();
16
- intersectRay(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
16
+ aabb3_intersects_ray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
17
17
  }
18
18
 
19
19
  //isolate timing of random function
@@ -57,7 +57,7 @@ test.skip("performance raycast", () => {
57
57
  const dirY = rng();
58
58
  const dirZ = rng();
59
59
 
60
- if (intersectRay(x0, y0, z0, x1, y1, z1, oX, oY, oZ, dirX, dirY, dirZ)) {
60
+ if (aabb3_intersects_ray(x0, y0, z0, x1, y1, z1, oX, oY, oZ, dirX, dirY, dirZ)) {
61
61
  p++;
62
62
  }
63
63
  }
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Fast Ray-Box intersection
3
+ * From "Graphics Gems", Academic Press, 1990
4
+ * ported from C
5
+ * see: https://web.archive.org/web/20090803054252/http://tog.acm.org/resources/GraphicsGems/gems/RayBox.c
6
+ * @param {number} x0
7
+ * @param {number} y0
8
+ * @param {number} z0
9
+ * @param {number} x1
10
+ * @param {number} y1
11
+ * @param {number} z1
12
+ * @param {number} oX
13
+ * @param {number} oY
14
+ * @param {number} oZ
15
+ * @param {number} dirX
16
+ * @param {number} dirY
17
+ * @param {number} dirZ
18
+ * @returns {boolean}
19
+ */
20
+ export function aabb3_intersects_ray_fast(x0, y0, z0, x1, y1, z1, oX, oY, oZ, dirX, dirY, dirZ) {
21
+ let inside = true;
22
+
23
+ let quadrantX = 0;
24
+ let quadrantY = 0;
25
+ let quadrantZ = 0;
26
+
27
+ let maxTX = 0;
28
+ let maxTY = 0;
29
+ let maxTZ = 0;
30
+
31
+ let maxT = 0;
32
+
33
+ let candidatePlaneX = 0;
34
+ let candidatePlaneY = 0;
35
+ let candidatePlaneZ = 0;
36
+
37
+ let coordX = 0;
38
+ let coordY = 0;
39
+ let coordZ = 0;
40
+
41
+ /*
42
+ find candidate planes
43
+ */
44
+ if (oX < x0) {
45
+ quadrantX = 1; //LEFT
46
+ candidatePlaneX = x0;
47
+ inside = false;
48
+ } else if (oX > x1) {
49
+ quadrantX = 0; //RIGHT
50
+ candidatePlaneX = x1;
51
+ inside = false;
52
+ } else {
53
+ quadrantX = 2; //MIDDLE
54
+ }
55
+
56
+ if (oY < y0) {
57
+ quadrantY = 1; //LEFT
58
+ candidatePlaneY = y0;
59
+ inside = false;
60
+ } else if (oY > y1) {
61
+ quadrantY = 0; //RIGHT
62
+ candidatePlaneY = y1;
63
+ inside = false;
64
+ } else {
65
+ quadrantY = 2; //MIDDLE
66
+ }
67
+
68
+ if (oZ < z0) {
69
+ quadrantZ = 1; //LEFT
70
+ candidatePlaneZ = z0;
71
+ inside = false;
72
+ } else if (oZ > z1) {
73
+ quadrantZ = 0; //RIGHT
74
+ candidatePlaneZ = z1;
75
+ inside = false;
76
+ } else {
77
+ quadrantZ = 2; //MIDDLE
78
+ }
79
+
80
+ // Ray origin inside the bounding box
81
+ if (inside) {
82
+ return true;
83
+ }
84
+
85
+ // Calculate T distances to candidate planes
86
+ if (quadrantX !== 2 && dirX !== 0) {
87
+ maxTX = (candidatePlaneX - oX) / dirX;
88
+ } else {
89
+ maxTX = -1;
90
+ }
91
+
92
+ if (quadrantY !== 2 && dirY !== 0) {
93
+ maxTY = (candidatePlaneY - oY) / dirY;
94
+ } else {
95
+ maxTY = -1;
96
+ }
97
+
98
+ if (quadrantZ !== 2 && dirZ !== 0) {
99
+ maxTZ = (candidatePlaneZ - oZ) / dirZ;
100
+ } else {
101
+ maxTZ = -1;
102
+ }
103
+
104
+ // Get largest of maxT's for final choice of intersection
105
+ if (maxTX < maxTY) {
106
+ if (maxTY < maxTZ) {
107
+ maxT = maxTZ;
108
+ // Check if final candidate actually inside the box
109
+ if (maxT < 0) {
110
+ return false;
111
+ }
112
+
113
+ coordX = oX + maxT * dirX;
114
+ if (coordX < x0 || coordX > x1) {
115
+ return false;
116
+ }
117
+
118
+ coordY = oY + maxT * dirY;
119
+ if (coordY < y0 || coordY > y1) {
120
+ return false;
121
+ }
122
+
123
+ } else {
124
+ maxT = maxTY;
125
+ // Check if final candidate actually inside the box
126
+ if (maxT < 0) {
127
+ return false;
128
+ }
129
+
130
+ coordX = oX + maxT * dirX;
131
+ if (coordX < x0 || coordX > x1) {
132
+ return false;
133
+ }
134
+
135
+ coordZ = oZ + maxT * dirZ;
136
+ if (coordZ < z0 || coordZ > z1) {
137
+ return false;
138
+ }
139
+ }
140
+ } else if (maxTX < maxTZ) {
141
+ maxT = maxTZ;
142
+ // Check if final candidate actually inside the box
143
+ if (maxT < 0) {
144
+ return false;
145
+ }
146
+
147
+ coordX = oX + maxT * dirX;
148
+ if (coordX < x0 || coordX > x1) {
149
+ return false;
150
+ }
151
+
152
+ coordY = oY + maxT * dirY;
153
+ if (coordY < y0 || coordY > y1) {
154
+ return false;
155
+ }
156
+ } else {
157
+ maxT = maxTX;
158
+ // Check if final candidate actually inside the box
159
+ if (maxT < 0) {
160
+ return false;
161
+ }
162
+
163
+ coordY = oY + maxT * dirY;
164
+ if (coordY < y0 || coordY > y1) {
165
+ return false;
166
+ }
167
+
168
+ coordZ = oZ + maxT * dirZ;
169
+ if (coordZ < z0 || coordZ > z1) {
170
+ return false;
171
+ }
172
+ }
173
+
174
+ //ray hits the box
175
+ return true;
176
+ }
@@ -0,0 +1,43 @@
1
+ import { aabb3_compute_half_surface_area } from "./aabb3_compute_half_surface_area.js";
2
+
3
+ /**
4
+ * Compute surface area for a box contain both inputs
5
+ * @param {AABB3} a
6
+ * @param {AABB3} b
7
+ * @returns {number}
8
+ */
9
+ function aabb3_score_boxes_SAH(a, b) {
10
+ let x0, y0, z0, x1, y1, z1;
11
+
12
+ //
13
+
14
+ const ax0 = a.x0;
15
+ const ay0 = a.y0;
16
+ const az0 = a.z0;
17
+ const ax1 = a.x1;
18
+ const ay1 = a.y1;
19
+ const az1 = a.z1;
20
+
21
+ const bx0 = b.x0;
22
+ const by0 = b.y0;
23
+ const bz0 = b.z0;
24
+ const bx1 = b.x1;
25
+ const by1 = b.y1;
26
+ const bz1 = b.z1;
27
+
28
+ //
29
+
30
+ x0 = ax0 < bx0 ? ax0 : bx0;
31
+ y0 = ay0 < by0 ? ay0 : by0;
32
+ z0 = az0 < bz0 ? az0 : bz0;
33
+
34
+ x1 = ax1 > bx1 ? ax1 : bx1;
35
+ y1 = ay1 > by1 ? ay1 : by1;
36
+ z1 = az1 > bz1 ? az1 : bz1;
37
+
38
+ //
39
+
40
+ return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
41
+ }
42
+
43
+ export { aabb3_score_boxes_SAH };
@@ -0,0 +1,37 @@
1
+ import { aabb3_compute_half_surface_area } from "./aabb3_compute_half_surface_area.js";
2
+
3
+ /**
4
+ *
5
+ * @param {AABB3} b0
6
+ * @param {AABB3} b1
7
+ * @return {number}
8
+ */
9
+ function aabb3_score_boxes_SAH_delta(b0, b1) {
10
+ let x0, y0, z0, x1, y1, z1;
11
+ //
12
+ const b0x0 = b0.x0;
13
+ const b0y0 = b0.y0;
14
+ const b0z0 = b0.z0;
15
+ const b0x1 = b0.x1;
16
+ const b0y1 = b0.y1;
17
+ const b0z1 = b0.z1;
18
+
19
+ const b1x0 = b1.x0;
20
+ const b1y0 = b1.y0;
21
+ const b1z0 = b1.z0;
22
+ const b1x1 = b1.x1;
23
+ const b1y1 = b1.y1;
24
+ const b1z1 = b1.z1;
25
+ //
26
+ x0 = b0x0 < b1x0 ? b0x0 : b1x0;
27
+ y0 = b0y0 < b1y0 ? b0y0 : b1y0;
28
+ z0 = b0z0 < b1z0 ? b0z0 : b1z0;
29
+ x1 = b0x1 > b1x1 ? b0x1 : b1x1;
30
+ y1 = b0y1 > b1y1 ? b0y1 : b1y1;
31
+ z1 = b0z1 > b1z1 ? b0z1 : b1z1;
32
+ //
33
+ const totalArea = aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
34
+ const area0 = b0.getSurfaceArea();
35
+ const area1 = b1.getSurfaceArea();
36
+ return totalArea - Math.max(area0, area1);
37
+ }