@woosh/meep-engine 2.163.9 → 2.163.11
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/package.json +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_capsule.d.ts +22 -0
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_capsule.d.ts.map +1 -0
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_capsule.js +101 -0
- package/src/core/collection/heap/IndexedFloatMaxHeap.d.ts.map +1 -0
- package/src/core/{graph/metis/native/refine → collection/heap}/IndexedFloatMaxHeap.js +1 -1
- package/src/core/geom/3d/capsule/capsule_intersects_aabb3_closed.d.ts +40 -0
- package/src/core/geom/3d/capsule/capsule_intersects_aabb3_closed.d.ts.map +1 -0
- package/src/core/geom/3d/capsule/capsule_intersects_aabb3_closed.js +67 -0
- package/src/core/geom/3d/capsule/capsule_intersects_aabb3_iterative.d.ts +45 -0
- package/src/core/geom/3d/capsule/capsule_intersects_aabb3_iterative.d.ts.map +1 -0
- package/src/core/geom/3d/capsule/capsule_intersects_aabb3_iterative.js +137 -0
- package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +146 -0
- package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_aabb3_t.d.ts +44 -0
- package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_aabb3_t.d.ts.map +1 -0
- package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_aabb3_t.js +153 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +18 -7
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.d.ts +6 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.js +139 -95
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +2 -26
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify_by_error.d.ts +19 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify_by_error.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify_by_error.js +555 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_swap_vertex_slots.d.ts +13 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_swap_vertex_slots.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_swap_vertex_slots.js +28 -0
- package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts +1 -1
- package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts.map +1 -1
- package/src/core/graph/metis/native/bisection/BisectionScratch.js +1 -1
- package/src/core/graph/metis/native/refine/RefinementScratch.d.ts +1 -1
- package/src/core/graph/metis/native/refine/RefinementScratch.d.ts.map +1 -1
- package/src/core/graph/metis/native/refine/RefinementScratch.js +1 -1
- package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts.map +1 -1
- package/src/engine/navigation/mesh/build/navmesh_build_topology.js +25 -0
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/capsule_contacts.js +14 -21
- package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts.map +0 -1
- /package/src/core/{graph/metis/native/refine → collection/heap}/IndexedFloatMaxHeap.d.ts +0 -0
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"description": "Pure JavaScript game engine. Fully featured and production ready.",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"author": "Alexander Goldring",
|
|
9
|
-
"version": "2.163.
|
|
9
|
+
"version": "2.163.11",
|
|
10
10
|
"main": "build/meep.module.js",
|
|
11
11
|
"module": "build/meep.module.js",
|
|
12
12
|
"exports": {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collect the user-data of every BVH leaf whose AABB overlaps a capsule.
|
|
3
|
+
*
|
|
4
|
+
* The capsule is packed into a single array as
|
|
5
|
+
* `[p0_x, p0_y, p0_z, p1_x, p1_y, p1_z, r]` — the two segment endpoints
|
|
6
|
+
* followed by the radius (the same component order as
|
|
7
|
+
* {@link capsule_intersects_aabb3_closed}).
|
|
8
|
+
*
|
|
9
|
+
* Modelled on {@link bvh_query_user_data_overlaps_aabb} /
|
|
10
|
+
* {@link bvh_query_user_data_overlaps_sphere}: the same stack traversal, with
|
|
11
|
+
* the per-node predicate swapped for the exact capsule-vs-AABB overlap. Every
|
|
12
|
+
* child AABB is contained in its parent's, so a node the capsule misses prunes
|
|
13
|
+
* its whole subtree.
|
|
14
|
+
*
|
|
15
|
+
* @param {number[]|Uint32Array} result destination for matched leaf user-data
|
|
16
|
+
* @param {number} result_offset first index in `result` to write to
|
|
17
|
+
* @param {BVH} bvh
|
|
18
|
+
* @param {Float32Array|number[]} capsule `[p0x, p0y, p0z, p1x, p1y, p1z, r]`
|
|
19
|
+
* @returns {number} number of leaves written
|
|
20
|
+
*/
|
|
21
|
+
export function bvh_query_user_data_overlaps_capsule(result: number[] | Uint32Array, result_offset: number, bvh: BVH, capsule: Float32Array | number[]): number;
|
|
22
|
+
//# sourceMappingURL=bvh_query_user_data_overlaps_capsule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bvh_query_user_data_overlaps_capsule.d.ts","sourceRoot":"","sources":["../../../../../../src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_capsule.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,6DANW,MAAM,EAAE,GAAC,WAAW,iBACpB,MAAM,qBAEN,YAAY,GAAC,MAAM,EAAE,GACnB,MAAM,CAyElB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
//
|
|
2
|
+
import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
|
|
3
|
+
import { capsule_intersects_aabb3_closed } from "../../../geom/3d/capsule/capsule_intersects_aabb3_closed.js";
|
|
4
|
+
import { NULL_NODE } from "../BVH.js";
|
|
5
|
+
|
|
6
|
+
const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
7
|
+
|
|
8
|
+
const scratch_aabb = new Float32Array(6);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Collect the user-data of every BVH leaf whose AABB overlaps a capsule.
|
|
12
|
+
*
|
|
13
|
+
* The capsule is packed into a single array as
|
|
14
|
+
* `[p0_x, p0_y, p0_z, p1_x, p1_y, p1_z, r]` — the two segment endpoints
|
|
15
|
+
* followed by the radius (the same component order as
|
|
16
|
+
* {@link capsule_intersects_aabb3_closed}).
|
|
17
|
+
*
|
|
18
|
+
* Modelled on {@link bvh_query_user_data_overlaps_aabb} /
|
|
19
|
+
* {@link bvh_query_user_data_overlaps_sphere}: the same stack traversal, with
|
|
20
|
+
* the per-node predicate swapped for the exact capsule-vs-AABB overlap. Every
|
|
21
|
+
* child AABB is contained in its parent's, so a node the capsule misses prunes
|
|
22
|
+
* its whole subtree.
|
|
23
|
+
*
|
|
24
|
+
* @param {number[]|Uint32Array} result destination for matched leaf user-data
|
|
25
|
+
* @param {number} result_offset first index in `result` to write to
|
|
26
|
+
* @param {BVH} bvh
|
|
27
|
+
* @param {Float32Array|number[]} capsule `[p0x, p0y, p0z, p1x, p1y, p1z, r]`
|
|
28
|
+
* @returns {number} number of leaves written
|
|
29
|
+
*/
|
|
30
|
+
export function bvh_query_user_data_overlaps_capsule(
|
|
31
|
+
result,
|
|
32
|
+
result_offset,
|
|
33
|
+
bvh,
|
|
34
|
+
capsule
|
|
35
|
+
) {
|
|
36
|
+
const root = bvh.root;
|
|
37
|
+
|
|
38
|
+
if (root === NULL_NODE) {
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const p0_x = capsule[0], p0_y = capsule[1], p0_z = capsule[2];
|
|
43
|
+
const p1_x = capsule[3], p1_y = capsule[4], p1_z = capsule[5];
|
|
44
|
+
const r = capsule[6];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @type {number}
|
|
49
|
+
*/
|
|
50
|
+
const stack_top = stack.pointer++;
|
|
51
|
+
|
|
52
|
+
stack[stack_top] = root;
|
|
53
|
+
|
|
54
|
+
let result_cursor = result_offset;
|
|
55
|
+
|
|
56
|
+
while (stack.pointer > stack_top) {
|
|
57
|
+
stack.pointer--;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
*
|
|
61
|
+
* @type {number}
|
|
62
|
+
*/
|
|
63
|
+
const node = stack[stack.pointer];
|
|
64
|
+
|
|
65
|
+
// test node against the capsule
|
|
66
|
+
bvh.node_get_aabb(node, scratch_aabb);
|
|
67
|
+
|
|
68
|
+
const intersection_exists = capsule_intersects_aabb3_closed(
|
|
69
|
+
p0_x, p0_y, p0_z,
|
|
70
|
+
p1_x, p1_y, p1_z,
|
|
71
|
+
r,
|
|
72
|
+
scratch_aabb[0], scratch_aabb[1], scratch_aabb[2],
|
|
73
|
+
scratch_aabb[3], scratch_aabb[4], scratch_aabb[5]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (!intersection_exists) {
|
|
77
|
+
// fully outside
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const node_is_leaf = bvh.node_is_leaf(node);
|
|
82
|
+
|
|
83
|
+
if (node_is_leaf) {
|
|
84
|
+
// leaf node
|
|
85
|
+
result[result_cursor++] = bvh.node_get_user_data(node);
|
|
86
|
+
|
|
87
|
+
} else {
|
|
88
|
+
// read in-order
|
|
89
|
+
const child1 = bvh.node_get_child1(node);
|
|
90
|
+
const child2 = bvh.node_get_child2(node);
|
|
91
|
+
|
|
92
|
+
// write to stack in reverse order, so that fist child ends up being visited first
|
|
93
|
+
stack[stack.pointer++] = child1;
|
|
94
|
+
stack[stack.pointer++] = child2;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// drop stack frame
|
|
99
|
+
|
|
100
|
+
return result_cursor - result_offset;
|
|
101
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IndexedFloatMaxHeap.d.ts","sourceRoot":"","sources":["../../../../../src/core/collection/heap/IndexedFloatMaxHeap.js"],"names":[],"mappings":"AA6BA;IACI;;;OAGG;IACH,yBAHW,MAAM,0BACN,MAAM,EAsBhB;IAbG,wBAA4C;IAC5C,eAAe;IAEf,2BAA4E;IAC5E,2BAAwD;IACxD,6BAA0D;IAE1D;;;OAGG;IACH,cAFU,WAAW,CAE2B;IAIpD,mBAEC;IAED;;;OAGG;IACH,cAQC;IAED,2BAEC;IAED;;;OAGG;IACH,qBAkBC;IAED;;;;OAIG;IACH,oBAsBC;IAED;;;;OAIG;IACH,kBAYC;IAED,wBAUC;IAED;;;OAGG;IACH,WAHW,MAAM,SACN,MAAM,QAehB;IAED;;OAEG;IACH,WAFa,MAAM,CAuBlB;IAED;;;OAGG;IACH,WAHW,MAAM,aACN,MAAM,QAehB;IAED;;;OAGG;IACH,WAHW,MAAM,GACJ,OAAO,CA+BnB;CACJ"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test whether an oriented capsule overlaps an axis-aligned box — exact,
|
|
3
|
+
* closed-form (no iteration count, no convergence tolerance).
|
|
4
|
+
*
|
|
5
|
+
* A capsule is the set of points within `r` of its central segment `p0 → p1`
|
|
6
|
+
* (the Minkowski sum of that segment with a sphere of radius `r`), so it
|
|
7
|
+
* overlaps the box exactly when the segment passes within `r` of the box:
|
|
8
|
+
*
|
|
9
|
+
* overlap ⟺ distanceSqr(segment, AABB) ≤ r²
|
|
10
|
+
*
|
|
11
|
+
* The closest point on the segment to the box is located in O(1) by
|
|
12
|
+
* {@link line3_compute_segment_nearest_point_to_aabb3_t} (convex
|
|
13
|
+
* piecewise-quadratic minimiser); this then compares that closest distance to
|
|
14
|
+
* `r²`. {@link capsule_intersects_aabb3_iterative} is the convex-bisection
|
|
15
|
+
* sibling (simpler, but ~50 refinement steps). A degenerate capsule
|
|
16
|
+
* (`p0 === p1`) collapses to the sphere-vs-box test with no special-casing.
|
|
17
|
+
*
|
|
18
|
+
* Box bounds are assumed ordered per axis (`box_*0 ≤ box_*1`), matching the
|
|
19
|
+
* `AABB3` storage convention.
|
|
20
|
+
*
|
|
21
|
+
* @param {number} p0_x capsule segment start x
|
|
22
|
+
* @param {number} p0_y capsule segment start y
|
|
23
|
+
* @param {number} p0_z capsule segment start z
|
|
24
|
+
* @param {number} p1_x capsule segment end x
|
|
25
|
+
* @param {number} p1_y capsule segment end y
|
|
26
|
+
* @param {number} p1_z capsule segment end z
|
|
27
|
+
* @param {number} r capsule radius
|
|
28
|
+
* @param {number} box_x0 box min x
|
|
29
|
+
* @param {number} box_y0 box min y
|
|
30
|
+
* @param {number} box_z0 box min z
|
|
31
|
+
* @param {number} box_x1 box max x
|
|
32
|
+
* @param {number} box_y1 box max y
|
|
33
|
+
* @param {number} box_z1 box max z
|
|
34
|
+
* @returns {boolean} true when the capsule overlaps the box
|
|
35
|
+
*
|
|
36
|
+
* @author Alex Goldring
|
|
37
|
+
* @copyright Company Named Limited (c) 2026
|
|
38
|
+
*/
|
|
39
|
+
export function capsule_intersects_aabb3_closed(p0_x: number, p0_y: number, p0_z: number, p1_x: number, p1_y: number, p1_z: number, r: number, box_x0: number, box_y0: number, box_z0: number, box_x1: number, box_y1: number, box_z1: number): boolean;
|
|
40
|
+
//# sourceMappingURL=capsule_intersects_aabb3_closed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capsule_intersects_aabb3_closed.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/capsule/capsule_intersects_aabb3_closed.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,sDAlBW,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,KACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,OAAO,CA6BnB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { clamp } from "../../../math/clamp.js";
|
|
2
|
+
import { v3_distance_sqr } from "../../vec3/v3_distance_sqr.js";
|
|
3
|
+
import { line3_compute_segment_nearest_point_to_aabb3_t } from "../line/line3_compute_segment_nearest_point_to_aabb3_t.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Test whether an oriented capsule overlaps an axis-aligned box — exact,
|
|
7
|
+
* closed-form (no iteration count, no convergence tolerance).
|
|
8
|
+
*
|
|
9
|
+
* A capsule is the set of points within `r` of its central segment `p0 → p1`
|
|
10
|
+
* (the Minkowski sum of that segment with a sphere of radius `r`), so it
|
|
11
|
+
* overlaps the box exactly when the segment passes within `r` of the box:
|
|
12
|
+
*
|
|
13
|
+
* overlap ⟺ distanceSqr(segment, AABB) ≤ r²
|
|
14
|
+
*
|
|
15
|
+
* The closest point on the segment to the box is located in O(1) by
|
|
16
|
+
* {@link line3_compute_segment_nearest_point_to_aabb3_t} (convex
|
|
17
|
+
* piecewise-quadratic minimiser); this then compares that closest distance to
|
|
18
|
+
* `r²`. {@link capsule_intersects_aabb3_iterative} is the convex-bisection
|
|
19
|
+
* sibling (simpler, but ~50 refinement steps). A degenerate capsule
|
|
20
|
+
* (`p0 === p1`) collapses to the sphere-vs-box test with no special-casing.
|
|
21
|
+
*
|
|
22
|
+
* Box bounds are assumed ordered per axis (`box_*0 ≤ box_*1`), matching the
|
|
23
|
+
* `AABB3` storage convention.
|
|
24
|
+
*
|
|
25
|
+
* @param {number} p0_x capsule segment start x
|
|
26
|
+
* @param {number} p0_y capsule segment start y
|
|
27
|
+
* @param {number} p0_z capsule segment start z
|
|
28
|
+
* @param {number} p1_x capsule segment end x
|
|
29
|
+
* @param {number} p1_y capsule segment end y
|
|
30
|
+
* @param {number} p1_z capsule segment end z
|
|
31
|
+
* @param {number} r capsule radius
|
|
32
|
+
* @param {number} box_x0 box min x
|
|
33
|
+
* @param {number} box_y0 box min y
|
|
34
|
+
* @param {number} box_z0 box min z
|
|
35
|
+
* @param {number} box_x1 box max x
|
|
36
|
+
* @param {number} box_y1 box max y
|
|
37
|
+
* @param {number} box_z1 box max z
|
|
38
|
+
* @returns {boolean} true when the capsule overlaps the box
|
|
39
|
+
*
|
|
40
|
+
* @author Alex Goldring
|
|
41
|
+
* @copyright Company Named Limited (c) 2026
|
|
42
|
+
*/
|
|
43
|
+
export function capsule_intersects_aabb3_closed(
|
|
44
|
+
p0_x, p0_y, p0_z,
|
|
45
|
+
p1_x, p1_y, p1_z,
|
|
46
|
+
r,
|
|
47
|
+
box_x0, box_y0, box_z0,
|
|
48
|
+
box_x1, box_y1, box_z1
|
|
49
|
+
) {
|
|
50
|
+
const t = line3_compute_segment_nearest_point_to_aabb3_t(
|
|
51
|
+
p0_x, p0_y, p0_z,
|
|
52
|
+
p1_x, p1_y, p1_z,
|
|
53
|
+
box_x0, box_y0, box_z0,
|
|
54
|
+
box_x1, box_y1, box_z1
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const p_x = p0_x + (p1_x - p0_x) * t;
|
|
58
|
+
const p_y = p0_y + (p1_y - p0_y) * t;
|
|
59
|
+
const p_z = p0_z + (p1_z - p0_z) * t;
|
|
60
|
+
|
|
61
|
+
return v3_distance_sqr(
|
|
62
|
+
p_x, p_y, p_z,
|
|
63
|
+
clamp(p_x, box_x0, box_x1),
|
|
64
|
+
clamp(p_y, box_y0, box_y1),
|
|
65
|
+
clamp(p_z, box_z0, box_z1)
|
|
66
|
+
) <= r * r;
|
|
67
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test whether an oriented capsule overlaps an axis-aligned box.
|
|
3
|
+
*
|
|
4
|
+
* A capsule is the set of points within `r` of its central segment `p0 → p1`
|
|
5
|
+
* (the Minkowski sum of that segment with a sphere of radius `r`). It therefore
|
|
6
|
+
* overlaps the box exactly when the segment passes within `r` of the box:
|
|
7
|
+
*
|
|
8
|
+
* overlap ⟺ distanceSqr(segment, AABB) ≤ r²
|
|
9
|
+
*
|
|
10
|
+
* so the whole test reduces to a segment-vs-box squared-distance compared
|
|
11
|
+
* against `r²` — no square root, no curved-surface math.
|
|
12
|
+
*
|
|
13
|
+
* The segment→box distance is `min_{t∈[0,1]} g(t)` with
|
|
14
|
+
* `g(t) = distanceSqr(P(t), box)`, `P(t) = p0 + t·d`. `g` is convex (a sum of
|
|
15
|
+
* per-axis convex "outside" terms composed with an affine `P`), so its
|
|
16
|
+
* minimiser is found from the monotone sign of
|
|
17
|
+
* `g'(t) ∝ (P(t) − clamp(P(t), box)) · d`: if `g'(0) ≥ 0` the minimum is the
|
|
18
|
+
* `p0` end, if `g'(1) ≤ 0` it is the `p1` end, otherwise it is the interior
|
|
19
|
+
* root, found by {@link BISECTION_ITERATIONS} bisection. A degenerate capsule
|
|
20
|
+
* (`p0 === p1`) has `d = 0 → g'(0) = 0 → t = 0`, i.e. the sphere-vs-box test,
|
|
21
|
+
* with no special-casing.
|
|
22
|
+
*
|
|
23
|
+
* Box bounds are assumed ordered per axis (`box_*0 ≤ box_*1`), matching the
|
|
24
|
+
* `AABB3` storage convention.
|
|
25
|
+
*
|
|
26
|
+
* @param {number} p0_x capsule segment start x
|
|
27
|
+
* @param {number} p0_y capsule segment start y
|
|
28
|
+
* @param {number} p0_z capsule segment start z
|
|
29
|
+
* @param {number} p1_x capsule segment end x
|
|
30
|
+
* @param {number} p1_y capsule segment end y
|
|
31
|
+
* @param {number} p1_z capsule segment end z
|
|
32
|
+
* @param {number} r capsule radius
|
|
33
|
+
* @param {number} box_x0 box min x
|
|
34
|
+
* @param {number} box_y0 box min y
|
|
35
|
+
* @param {number} box_z0 box min z
|
|
36
|
+
* @param {number} box_x1 box max x
|
|
37
|
+
* @param {number} box_y1 box max y
|
|
38
|
+
* @param {number} box_z1 box max z
|
|
39
|
+
* @returns {boolean} true when the capsule overlaps the box
|
|
40
|
+
*
|
|
41
|
+
* @author Alex Goldring
|
|
42
|
+
* @copyright Company Named Limited (c) 2026
|
|
43
|
+
*/
|
|
44
|
+
export function capsule_intersects_aabb3_iterative(p0_x: number, p0_y: number, p0_z: number, p1_x: number, p1_y: number, p1_z: number, r: number, box_x0: number, box_y0: number, box_z0: number, box_x1: number, box_y1: number, box_z1: number): boolean;
|
|
45
|
+
//# sourceMappingURL=capsule_intersects_aabb3_iterative.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capsule_intersects_aabb3_iterative.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/capsule/capsule_intersects_aabb3_iterative.js"],"names":[],"mappings":"AAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,yDAlBW,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,KACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,OAAO,CA6EnB"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { clamp } from "../../../math/clamp.js";
|
|
2
|
+
import { v3_dot } from "../../vec3/v3_dot.js";
|
|
3
|
+
import { v3_distance_sqr } from "../../vec3/v3_distance_sqr.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bisection steps used to locate the closest point on the capsule's central
|
|
7
|
+
* segment to the box. `g(t) = distanceSqr(P(t), box)` is convex on `t ∈ [0,1]`,
|
|
8
|
+
* so bisecting the sign of `g'(t)` halves the bracket every step at a rate that
|
|
9
|
+
* does NOT depend on the segment's orientation. 50 steps drives `t` to the f64
|
|
10
|
+
* floor on `[0,1]` (`2⁻⁵⁰ ≈ 9e-16`), so the reported distance is exact to
|
|
11
|
+
* floating-point — there are no false negatives even for a hair-thin radius.
|
|
12
|
+
*
|
|
13
|
+
* (Alternating projection — project onto the segment, clamp into the box,
|
|
14
|
+
* repeat — was tried first and is what the narrowphase `capsule_box_contact`
|
|
15
|
+
* uses, but it crawls when the segment is near-parallel to a box face/edge and
|
|
16
|
+
* a short in-box chord can be missed entirely; a fuzz at `r = 1e-7` found such
|
|
17
|
+
* misses, hence the switch.)
|
|
18
|
+
* @type {number}
|
|
19
|
+
*/
|
|
20
|
+
const BISECTION_ITERATIONS = 50;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Test whether an oriented capsule overlaps an axis-aligned box.
|
|
24
|
+
*
|
|
25
|
+
* A capsule is the set of points within `r` of its central segment `p0 → p1`
|
|
26
|
+
* (the Minkowski sum of that segment with a sphere of radius `r`). It therefore
|
|
27
|
+
* overlaps the box exactly when the segment passes within `r` of the box:
|
|
28
|
+
*
|
|
29
|
+
* overlap ⟺ distanceSqr(segment, AABB) ≤ r²
|
|
30
|
+
*
|
|
31
|
+
* so the whole test reduces to a segment-vs-box squared-distance compared
|
|
32
|
+
* against `r²` — no square root, no curved-surface math.
|
|
33
|
+
*
|
|
34
|
+
* The segment→box distance is `min_{t∈[0,1]} g(t)` with
|
|
35
|
+
* `g(t) = distanceSqr(P(t), box)`, `P(t) = p0 + t·d`. `g` is convex (a sum of
|
|
36
|
+
* per-axis convex "outside" terms composed with an affine `P`), so its
|
|
37
|
+
* minimiser is found from the monotone sign of
|
|
38
|
+
* `g'(t) ∝ (P(t) − clamp(P(t), box)) · d`: if `g'(0) ≥ 0` the minimum is the
|
|
39
|
+
* `p0` end, if `g'(1) ≤ 0` it is the `p1` end, otherwise it is the interior
|
|
40
|
+
* root, found by {@link BISECTION_ITERATIONS} bisection. A degenerate capsule
|
|
41
|
+
* (`p0 === p1`) has `d = 0 → g'(0) = 0 → t = 0`, i.e. the sphere-vs-box test,
|
|
42
|
+
* with no special-casing.
|
|
43
|
+
*
|
|
44
|
+
* Box bounds are assumed ordered per axis (`box_*0 ≤ box_*1`), matching the
|
|
45
|
+
* `AABB3` storage convention.
|
|
46
|
+
*
|
|
47
|
+
* @param {number} p0_x capsule segment start x
|
|
48
|
+
* @param {number} p0_y capsule segment start y
|
|
49
|
+
* @param {number} p0_z capsule segment start z
|
|
50
|
+
* @param {number} p1_x capsule segment end x
|
|
51
|
+
* @param {number} p1_y capsule segment end y
|
|
52
|
+
* @param {number} p1_z capsule segment end z
|
|
53
|
+
* @param {number} r capsule radius
|
|
54
|
+
* @param {number} box_x0 box min x
|
|
55
|
+
* @param {number} box_y0 box min y
|
|
56
|
+
* @param {number} box_z0 box min z
|
|
57
|
+
* @param {number} box_x1 box max x
|
|
58
|
+
* @param {number} box_y1 box max y
|
|
59
|
+
* @param {number} box_z1 box max z
|
|
60
|
+
* @returns {boolean} true when the capsule overlaps the box
|
|
61
|
+
*
|
|
62
|
+
* @author Alex Goldring
|
|
63
|
+
* @copyright Company Named Limited (c) 2026
|
|
64
|
+
*/
|
|
65
|
+
export function capsule_intersects_aabb3_iterative(
|
|
66
|
+
p0_x, p0_y, p0_z,
|
|
67
|
+
p1_x, p1_y, p1_z,
|
|
68
|
+
r,
|
|
69
|
+
box_x0, box_y0, box_z0,
|
|
70
|
+
box_x1, box_y1, box_z1
|
|
71
|
+
) {
|
|
72
|
+
const d_x = p1_x - p0_x;
|
|
73
|
+
const d_y = p1_y - p0_y;
|
|
74
|
+
const d_z = p1_z - p0_z;
|
|
75
|
+
|
|
76
|
+
// Parameter of the closest point on the segment to the box.
|
|
77
|
+
let t;
|
|
78
|
+
|
|
79
|
+
// g'(0) ≥ 0 ⇒ g is non-decreasing on [0,1] ⇒ minimum at the p0 end.
|
|
80
|
+
// (Also the degenerate-segment path: d = 0 makes this dot 0 ⇒ t = 0.)
|
|
81
|
+
if (v3_dot(
|
|
82
|
+
p0_x - clamp(p0_x, box_x0, box_x1),
|
|
83
|
+
p0_y - clamp(p0_y, box_y0, box_y1),
|
|
84
|
+
p0_z - clamp(p0_z, box_z0, box_z1),
|
|
85
|
+
d_x, d_y, d_z
|
|
86
|
+
) >= 0) {
|
|
87
|
+
t = 0;
|
|
88
|
+
} else if (v3_dot(
|
|
89
|
+
// g'(1) ≤ 0 ⇒ g is non-increasing on [0,1] ⇒ minimum at the p1 end.
|
|
90
|
+
p1_x - clamp(p1_x, box_x0, box_x1),
|
|
91
|
+
p1_y - clamp(p1_y, box_y0, box_y1),
|
|
92
|
+
p1_z - clamp(p1_z, box_z0, box_z1),
|
|
93
|
+
d_x, d_y, d_z
|
|
94
|
+
) <= 0) {
|
|
95
|
+
t = 1;
|
|
96
|
+
} else {
|
|
97
|
+
// Interior minimum: g'(0) < 0 < g'(1), so a sign change is bracketed —
|
|
98
|
+
// bisect for g'(t) = 0.
|
|
99
|
+
let lo = 0;
|
|
100
|
+
let hi = 1;
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < BISECTION_ITERATIONS; i++) {
|
|
103
|
+
const mid = (lo + hi) * 0.5;
|
|
104
|
+
|
|
105
|
+
const p_x = p0_x + d_x * mid;
|
|
106
|
+
const p_y = p0_y + d_y * mid;
|
|
107
|
+
const p_z = p0_z + d_z * mid;
|
|
108
|
+
|
|
109
|
+
const g_prime = v3_dot(
|
|
110
|
+
p_x - clamp(p_x, box_x0, box_x1),
|
|
111
|
+
p_y - clamp(p_y, box_y0, box_y1),
|
|
112
|
+
p_z - clamp(p_z, box_z0, box_z1),
|
|
113
|
+
d_x, d_y, d_z
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (g_prime > 0) {
|
|
117
|
+
hi = mid;
|
|
118
|
+
} else {
|
|
119
|
+
lo = mid;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
t = (lo + hi) * 0.5;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Closest segment point and the box point nearest it; overlap ⟺ within radius.
|
|
127
|
+
const p_x = p0_x + d_x * t;
|
|
128
|
+
const p_y = p0_y + d_y * t;
|
|
129
|
+
const p_z = p0_z + d_z * t;
|
|
130
|
+
|
|
131
|
+
return v3_distance_sqr(
|
|
132
|
+
p_x, p_y, p_z,
|
|
133
|
+
clamp(p_x, box_x0, box_x1),
|
|
134
|
+
clamp(p_y, box_y0, box_y1),
|
|
135
|
+
clamp(p_z, box_z0, box_z1)
|
|
136
|
+
) <= r * r;
|
|
137
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# GJK review notes — Johnson distance subalgorithm & robustness
|
|
2
|
+
|
|
3
|
+
Notes from a 2026-06-18 research pass (capsule-vs-AABB / segment-vs-box work) on
|
|
4
|
+
how this engine's GJK family relates to the known GJK robustness literature —
|
|
5
|
+
chiefly the **Johnson distance subalgorithm** and its 2017 **signed-volumes**
|
|
6
|
+
replacement. See `NOTES.md` (same dir) for the raw reference links.
|
|
7
|
+
|
|
8
|
+
**TL;DR:** the specific Johnson failure mode does **not** apply here, because this
|
|
9
|
+
engine has **no distance-returning GJK** — nothing computes the Johnson
|
|
10
|
+
sub-distance, so there is nothing to replace. The finding is *forward-looking*:
|
|
11
|
+
it becomes relevant the day a closest-distance-between-separated-convexes query
|
|
12
|
+
is added (speculative contacts, conservative-advancement CCD, proximity
|
|
13
|
+
queries). The analogous simplex-degeneracy risk in our boolean/penetration GJK is
|
|
14
|
+
real but already mitigated by explicit floating-point-dust guards.
|
|
15
|
+
|
|
16
|
+
## What this engine actually has
|
|
17
|
+
|
|
18
|
+
There are three Minkowski-difference routines here, and **none is a distance
|
|
19
|
+
subalgorithm**:
|
|
20
|
+
|
|
21
|
+
| File | Role | Simplex / sub-distance method |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `gjk.js` | **Boolean** overlap test (used by `physics/queries/shape_cast.js`) | Voronoi-region simplex update via triple cross products (Kevin Moran adaptation). Returns a bool; never computes a closest point. |
|
|
24
|
+
| `gjk_epa_penetration.js` | **Penetration** axis+depth (narrowphase convex / mesh / concave-per-triangle) | GJK builds a rank-4 origin-enclosing simplex (Voronoi-region updates), then EPA expands faces toward the closest one (Bullet `btGjkEpa2` structure). |
|
|
25
|
+
| `mpr.js` | Penetration normal on **smooth** supports (sphere/capsule), where EPA stalls | Minkowski Portal Refinement — portal, not simplex sub-distance. |
|
|
26
|
+
|
|
27
|
+
The thing the literature calls the *Johnson distance subalgorithm* — given a
|
|
28
|
+
simplex of ≤4 points, find the closest point on it to the origin and the minimal
|
|
29
|
+
sub-simplex (which Voronoi region the origin projects into), via recursively
|
|
30
|
+
computed barycentric cofactors — is **absent**. Our GJK only ever asks "does the
|
|
31
|
+
simplex enclose / has the support passed the origin?", never "what is the
|
|
32
|
+
closest point on the simplex?". So there is no Johnson cofactor recursion and no
|
|
33
|
+
Backup procedure in this codebase.
|
|
34
|
+
|
|
35
|
+
## The Johnson subalgorithm and why it fails
|
|
36
|
+
|
|
37
|
+
In a *distance* GJK (Gilbert–Johnson–Keerthi 1988), each iteration must solve the
|
|
38
|
+
sub-distance problem: project the origin onto the current simplex and discard the
|
|
39
|
+
vertices not contributing to the closest feature. Johnson's method expresses the
|
|
40
|
+
barycentric weights as ratios of determinants (Δ cofactors) built from dot
|
|
41
|
+
products of support-point *differences*.
|
|
42
|
+
|
|
43
|
+
Failure mode (the part relevant to robustness reviews): for a **near-degenerate
|
|
44
|
+
simplex** — points nearly coincident or nearly coplanar/collinear, which GJK
|
|
45
|
+
*naturally drives toward* as it converges on a near-contact configuration — those
|
|
46
|
+
determinants are differences of nearly-equal products and lose most of their
|
|
47
|
+
significant digits to **subtractive cancellation**. The algorithm then either
|
|
48
|
+
fails to find any valid sub-simplex (the historical "Backup procedure" brute-forces
|
|
49
|
+
all subsets as a fallback) or, worse, selects the wrong Voronoi region and returns
|
|
50
|
+
a **wrong closest point / distance**. Net effect in practice: the distance is
|
|
51
|
+
*under-estimated just before contact* — i.e. under-detection, the same direction
|
|
52
|
+
of error we found in the capsule-box alternating projection.
|
|
53
|
+
|
|
54
|
+
## The 2017 fix — signed volumes (Montanari, Petrinic & Barbieri)
|
|
55
|
+
|
|
56
|
+
*"Improving the GJK Algorithm for Faster and More Reliable Distance Queries
|
|
57
|
+
Between Convex Objects"*, ACM TOG 36(3), 2017; reference impl **openGJK**
|
|
58
|
+
(SoftwareX 2018). Both already cited in `NOTES.md`.
|
|
59
|
+
|
|
60
|
+
It replaces Johnson's distance subalgorithm **and** the Backup procedure with a
|
|
61
|
+
**signed-volumes** subalgorithm:
|
|
62
|
+
|
|
63
|
+
- determines the Voronoi region by comparing **signed volumes** (determinants) of
|
|
64
|
+
the simplex and its sub-faces, projecting onto the lowest-dimensional one that
|
|
65
|
+
contains the origin's projection;
|
|
66
|
+
- crucially **does not multiply together potentially small quantities**, so it is
|
|
67
|
+
*accurate to machine precision* and, per the paper, "cannot possibly generate
|
|
68
|
+
systems of linearly dependent equations" — **degenerate simplices are handled
|
|
69
|
+
naturally** (they collapse to a lower-dimensional projection instead of
|
|
70
|
+
triggering a fallback);
|
|
71
|
+
- side benefit: ~10% faster on average, 15–30% in the contact-heavy regime.
|
|
72
|
+
|
|
73
|
+
This is the single most relevant robustness upgrade for any GJK that returns a
|
|
74
|
+
**distance**. It is *not* a drop-in change to a boolean or penetration GJK, which
|
|
75
|
+
do not run a sub-distance step.
|
|
76
|
+
|
|
77
|
+
## Applicability to this codebase
|
|
78
|
+
|
|
79
|
+
1. **No live bug.** Nothing here runs the Johnson subalgorithm, so there is
|
|
80
|
+
nothing to "fix". Do not retrofit signed-volumes onto `gjk.js` /
|
|
81
|
+
`gjk_epa_penetration.js` — they have no sub-distance step to replace.
|
|
82
|
+
|
|
83
|
+
2. **The analogous risk is the Voronoi-region update**, not Johnson cofactors.
|
|
84
|
+
`gjk.js` and the GJK phase of `gjk_epa_penetration.js` decide regions with
|
|
85
|
+
triple-cross-products and dot products, which suffer the *same class* of
|
|
86
|
+
cancellation on degenerate simplices. This is already mitigated deliberately:
|
|
87
|
+
- `gjk.js` `perpendicular_to_edge()` + the exact-zero direction checks are FP-dust
|
|
88
|
+
guards for exactly the collapsed-simplex case (see the comment block there —
|
|
89
|
+
a wedge dot rounding a hair above zero while the triple product rounds to
|
|
90
|
+
zero). Documented as off the hot path.
|
|
91
|
+
- `gjk_epa_penetration.js` carries `DIR_EPS`/`EPA_EPS` floors and pool-overflow
|
|
92
|
+
"use current best face" degradations.
|
|
93
|
+
These are spot mitigations, not a machine-precision guarantee — but they cover
|
|
94
|
+
the inputs the narrowphase actually feeds (the convex hulls / triangles), and
|
|
95
|
+
the penetration path is cross-checked by MPR on smooth shapes.
|
|
96
|
+
|
|
97
|
+
3. **Signed-volumes becomes relevant when a distance query is added.** If/when the
|
|
98
|
+
engine grows speculative/“soft” contacts that need a *separation distance*, a
|
|
99
|
+
conservative-advancement CCD that needs closest-distance per step, or general
|
|
100
|
+
proximity queries, implement that as a **new** signed-volumes distance GJK
|
|
101
|
+
(port openGJK) rather than coaxing distance out of the boolean/penetration
|
|
102
|
+
routines. Capsule primitives should keep using the closed-form contacts
|
|
103
|
+
(`capsule_contacts.js`, now exact — see below), not GJK-with-margin.
|
|
104
|
+
|
|
105
|
+
## Related robustness notes (same review)
|
|
106
|
+
|
|
107
|
+
- **EPA precision wall on flat supports.** `Triangle3D`'s support is degenerate
|
|
108
|
+
along the face normal (all 3 vertices project equally), which stalls EPA and
|
|
109
|
+
yields noisy depths. The narrowphase already routes sphere/box/capsule-vs-
|
|
110
|
+
triangle through **closed-form** fast-paths in `narrowphase_step.js` for exactly
|
|
111
|
+
this reason, and `shape_cast.js` recovers the TOI normal with **MPR** rather
|
|
112
|
+
than EPA on smooth-vs-smooth. Good — keep new primitive pairs on closed forms.
|
|
113
|
+
- **Capsule-as-segment-support-with-margin is intentionally NOT used here.** Jolt
|
|
114
|
+
and PhysX-PCM collide capsules as a segment support inflated by the radius
|
|
115
|
+
inside GJK/EPA (with bounded corner error from the shrink-margin model). This
|
|
116
|
+
engine instead uses exact closed-form capsule contacts. That is the more
|
|
117
|
+
accurate choice for these primitive pairs and should stay.
|
|
118
|
+
- **Non-convergence policy.** Both `gjk.js` and `gjk_epa_penetration.js` cap at
|
|
119
|
+
`*_MAX_ITER = 64` and treat exhaustion as *no intersection*. For well-conditioned
|
|
120
|
+
convex inputs this is unreachable; it is a backstop against pathological input,
|
|
121
|
+
not a correctness lever.
|
|
122
|
+
|
|
123
|
+
## Action items (low urgency — none is a known live defect)
|
|
124
|
+
|
|
125
|
+
- [ ] If a separation-distance / proximity / conservative-advancement query is
|
|
126
|
+
ever needed, port **openGJK signed-volumes** as a dedicated distance GJK.
|
|
127
|
+
Do not extend the boolean/penetration routines for it.
|
|
128
|
+
- [ ] (Optional, deeper) A focused robustness pass on
|
|
129
|
+
`gjk_epa_penetration.js`'s simplex phase — confirm the degenerate-simplex
|
|
130
|
+
guards hold under near-coplanar convex-hull inputs at scale. Out of scope
|
|
131
|
+
for this note; flagged only because it is the nearest analog to the Johnson
|
|
132
|
+
concern.
|
|
133
|
+
|
|
134
|
+
## References
|
|
135
|
+
|
|
136
|
+
- Gilbert, Johnson, Keerthi (1988), *A Fast Procedure for Computing the Distance
|
|
137
|
+
Between Complex Objects in Three-Dimensional Space*, IEEE J. Robotics &
|
|
138
|
+
Automation — the original GJK + Johnson distance subalgorithm.
|
|
139
|
+
- Montanari, Petrinic, Barbieri (2017), *Improving the GJK Algorithm…*, ACM TOG
|
|
140
|
+
36(3), DOI 10.1145/3072959.3083724; openGJK reference impl
|
|
141
|
+
(github.com/MattiaMontanari/openGJK). Already in `NOTES.md`.
|
|
142
|
+
- van den Bergen (1999), *A Fast and Robust GJK Implementation for Collision
|
|
143
|
+
Detection of Convex Objects* — the classic robustness treatment (error bounds,
|
|
144
|
+
the Backup procedure) that motivates the 2017 work.
|
|
145
|
+
- Ericson, *Real-Time Collision Detection* (2005), §9.5 (GJK), Ch. 9 (EPA context).
|
|
146
|
+
- `gjk.js` header — adapted from github.com/kevinmoran/GJK (boolean Voronoi GJK).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter `t ∈ [0,1]` of the point on the segment `p0 → p1` nearest to an
|
|
3
|
+
* axis-aligned box. The closest segment point is `p0 + t·(p1 − p0)`; the closest
|
|
4
|
+
* box point is that point clamped per-axis into the box. Sibling of
|
|
5
|
+
* {@link line3_compute_segment_nearest_point_to_point_t} (segment-vs-point).
|
|
6
|
+
*
|
|
7
|
+
* Exact and O(1). `g(t) = distanceSqr(P(t), box)` is convex and — for an AABB —
|
|
8
|
+
* piecewise-quadratic, with pieces meeting only where `P(t)` crosses one of the
|
|
9
|
+
* six box face planes (≤6 crossings). `g'(t) ∝ (P(t) − clamp(P(t), box)) · d` is
|
|
10
|
+
* therefore piecewise-linear and monotonically non-decreasing, so the minimiser
|
|
11
|
+
* is found in closed form by evaluating `g'` at the ≤8 candidates
|
|
12
|
+
* `{0, 1, face-plane crossings}`: the minimum is achieved on the interval where
|
|
13
|
+
* `g' = 0` (a single point when strictly convex), and this returns that
|
|
14
|
+
* interval's midpoint. No iteration, no tolerance, no Cramer's-Rule solve.
|
|
15
|
+
*
|
|
16
|
+
* When the minimum is non-unique (segment parallel to / inside the box) the
|
|
17
|
+
* midpoint is the *central* closest point — what the narrowphase
|
|
18
|
+
* `capsule_box_contact` needs for a stable resting manifold; a degenerate
|
|
19
|
+
* (`p0 === p1`) segment returns `0` (its parameter is arbitrary).
|
|
20
|
+
*
|
|
21
|
+
* The AABB specialisation of the Eberly/Ericson closest-point-segment-vs-box
|
|
22
|
+
* reduction. Backs {@link capsule_intersects_aabb3_closed} and the narrowphase
|
|
23
|
+
* `capsule_box_contact`; it replaced a 2-iteration alternating projection that
|
|
24
|
+
* under-detected and mis-placed contacts for segments near-parallel to a box
|
|
25
|
+
* face/edge (see `core/geom/3d/gjk/GJK_REVIEW_NOTES.md`).
|
|
26
|
+
*
|
|
27
|
+
* Box bounds are assumed ordered per axis (`box_*0 ≤ box_*1`).
|
|
28
|
+
*
|
|
29
|
+
* @param {number} p0_x segment start x
|
|
30
|
+
* @param {number} p0_y
|
|
31
|
+
* @param {number} p0_z
|
|
32
|
+
* @param {number} p1_x segment end x
|
|
33
|
+
* @param {number} p1_y
|
|
34
|
+
* @param {number} p1_z
|
|
35
|
+
* @param {number} box_x0 box min x
|
|
36
|
+
* @param {number} box_y0
|
|
37
|
+
* @param {number} box_z0
|
|
38
|
+
* @param {number} box_x1 box max x
|
|
39
|
+
* @param {number} box_y1
|
|
40
|
+
* @param {number} box_z1
|
|
41
|
+
* @returns {number} t in [0, 1]
|
|
42
|
+
*/
|
|
43
|
+
export function line3_compute_segment_nearest_point_to_aabb3_t(p0_x: number, p0_y: number, p0_z: number, p1_x: number, p1_y: number, p1_z: number, box_x0: number, box_y0: number, box_z0: number, box_x1: number, box_y1: number, box_z1: number): number;
|
|
44
|
+
//# sourceMappingURL=line3_compute_segment_nearest_point_to_aabb3_t.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line3_compute_segment_nearest_point_to_aabb3_t.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/line/line3_compute_segment_nearest_point_to_aabb3_t.js"],"names":[],"mappings":"AA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,qEAdW,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,MAAM,CAqFlB"}
|