@ifc-lite/clash 2.3.0 → 2.4.0
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/dist/adapters/step.js +1 -0
- package/dist/adapters/step.js.map +1 -1
- package/dist/analysis.d.ts +6 -6
- package/dist/analysis.d.ts.map +1 -1
- package/dist/analysis.js +30 -29
- package/dist/analysis.js.map +1 -1
- package/dist/contact/narrow-phase.js +1 -1
- package/dist/engine-ts/broad.d.ts.map +1 -1
- package/dist/engine-ts/broad.js +11 -10
- package/dist/engine-ts/broad.js.map +1 -1
- package/dist/engine-ts/depth.d.ts +59 -10
- package/dist/engine-ts/depth.d.ts.map +1 -1
- package/dist/engine-ts/depth.js +101 -58
- package/dist/engine-ts/depth.js.map +1 -1
- package/dist/engine-ts/kernel.d.ts +2 -0
- package/dist/engine-ts/kernel.d.ts.map +1 -1
- package/dist/engine-ts/narrow.d.ts +8 -0
- package/dist/engine-ts/narrow.d.ts.map +1 -1
- package/dist/engine-ts/narrow.js +17 -13
- package/dist/engine-ts/narrow.js.map +1 -1
- package/dist/engine-ts/obb-detect.d.ts +19 -0
- package/dist/engine-ts/obb-detect.d.ts.map +1 -0
- package/dist/engine-ts/obb-detect.js +191 -0
- package/dist/engine-ts/obb-detect.js.map +1 -0
- package/dist/engine-ts/obb.d.ts +14 -23
- package/dist/engine-ts/obb.d.ts.map +1 -1
- package/dist/engine-ts/obb.js +35 -140
- package/dist/engine-ts/obb.js.map +1 -1
- package/dist/engine-ts/orchestrator.d.ts.map +1 -1
- package/dist/engine-ts/orchestrator.js +59 -15
- package/dist/engine-ts/orchestrator.js.map +1 -1
- package/dist/engine-ts/tri-mesh.d.ts +10 -5
- package/dist/engine-ts/tri-mesh.d.ts.map +1 -1
- package/dist/engine-ts/tri-mesh.js +35 -25
- package/dist/engine-ts/tri-mesh.js.map +1 -1
- package/dist/engine-ts/ts-kernel.d.ts.map +1 -1
- package/dist/engine-ts/ts-kernel.js +1 -0
- package/dist/engine-ts/ts-kernel.js.map +1 -1
- package/dist/engine-wasm/wasm-kernel.d.ts.map +1 -1
- package/dist/engine-wasm/wasm-kernel.js +10 -1
- package/dist/engine-wasm/wasm-kernel.js.map +1 -1
- package/dist/math/aabb.d.ts +9 -0
- package/dist/math/aabb.d.ts.map +1 -1
- package/dist/math/aabb.js +13 -0
- package/dist/math/aabb.js.map +1 -1
- package/dist/math/generated/plato.g.d.ts +11 -2
- package/dist/math/generated/plato.g.d.ts.map +1 -1
- package/dist/math/generated/plato.g.js +347 -190
- package/dist/math/generated/plato.g.js.map +1 -1
- package/dist/math/triangle-intersect.d.ts +12 -6
- package/dist/math/triangle-intersect.d.ts.map +1 -1
- package/dist/math/triangle-intersect.js +12 -6
- package/dist/math/triangle-intersect.js.map +1 -1
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +10 -10
package/dist/adapters/step.js
CHANGED
|
@@ -61,6 +61,7 @@ function syntheticKey(modelId, expressId) {
|
|
|
61
61
|
*/
|
|
62
62
|
function storeHasAnyGlobalId(store) {
|
|
63
63
|
const { entities } = store;
|
|
64
|
+
// @raw-entity-enumeration-ok fallback source-metadata probe asks whether the parsed file carries any GlobalId, not for live clash membership
|
|
64
65
|
for (let i = 0; i < entities.count; i += 1) {
|
|
65
66
|
if (entities.getGlobalId(entities.expressId[i]))
|
|
66
67
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step.js","sourceRoot":"","sources":["../../src/adapters/step.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAe/D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAsF3D;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAmB,EAAE,CAA2B;IAC3E,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACzB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAS,YAAY,CAAC,OAAe,EAAE,SAAiB;IACtD,OAAO,aAAa,kBAAkB,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC;AACjE,CAAC;
|
|
1
|
+
{"version":3,"file":"step.js","sourceRoot":"","sources":["../../src/adapters/step.ts"],"names":[],"mappings":"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"}
|
package/dist/analysis.d.ts
CHANGED
|
@@ -31,9 +31,9 @@ export declare const SEVERITY_RANK: Record<ClashSeverity, number>;
|
|
|
31
31
|
export declare function penetrationDepth(c: Clash): number;
|
|
32
32
|
/** Default band (m) under which a `hard` clash is really a face/edge *contact*
|
|
33
33
|
* rather than a genuine interpenetration — see {@link isTouching}. Also the
|
|
34
|
-
* floor for {@link touchingEpsilonFor}'s
|
|
35
|
-
*
|
|
36
|
-
*
|
|
34
|
+
* floor for {@link touchingEpsilonFor}'s default: the band only grows past
|
|
35
|
+
* it when the clash's own depth floor (or, for a clash without one, its
|
|
36
|
+
* coordinate magnitude) exceeds it. */
|
|
37
37
|
export declare const TOUCHING_EPSILON = 0.0001;
|
|
38
38
|
/**
|
|
39
39
|
* Whether a clash is effectively a zero-distance *contact* rather than a real
|
|
@@ -42,9 +42,9 @@ export declare const TOUCHING_EPSILON = 0.0001;
|
|
|
42
42
|
* slab, a column sitting on a footing) reported with a ~0 m depth, which users
|
|
43
43
|
* reasonably distrust when they appear in the clash list.
|
|
44
44
|
*
|
|
45
|
-
* `eps` defaults to {@link touchingEpsilonFor}
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* `eps` defaults to {@link touchingEpsilonFor}: the clash's own depth floor
|
|
46
|
+
* when the engine recorded one, else the older coordinate-magnitude band (see
|
|
47
|
+
* that function). An explicit `eps` overrides the default entirely.
|
|
48
48
|
*/
|
|
49
49
|
export declare function isTouching(c: Clash, eps?: number): boolean;
|
|
50
50
|
/**
|
package/dist/analysis.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,GAAG,YAAY,CAWxE;AAED,uEAAuE;AACvE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKvD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAEjD;AAED;;;;
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,GAAG,YAAY,CAWxE;AAED,uEAAuE;AACvE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKvD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAEjD;AAED;;;;wCAIwC;AACxC,eAAO,MAAM,gBAAgB,SAAO,CAAC;AA4CrC;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,GAAE,MAA8B,GAAG,OAAO,CAEjF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAEnE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/E;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,GAAG,GAAG,CAAC,GAAG,SAAS,EAC5C,QAAQ,EAAE,iBAAiB,GAC1B,MAAM,CAUR;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,mBAAmB,CAOnG;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAM5D;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,GAAG,KAAK,EAAE,CAmB/E"}
|
package/dist/analysis.js
CHANGED
|
@@ -41,41 +41,42 @@ export function penetrationDepth(c) {
|
|
|
41
41
|
}
|
|
42
42
|
/** Default band (m) under which a `hard` clash is really a face/edge *contact*
|
|
43
43
|
* rather than a genuine interpenetration — see {@link isTouching}. Also the
|
|
44
|
-
* floor for {@link touchingEpsilonFor}'s
|
|
45
|
-
*
|
|
46
|
-
*
|
|
44
|
+
* floor for {@link touchingEpsilonFor}'s default: the band only grows past
|
|
45
|
+
* it when the clash's own depth floor (or, for a clash without one, its
|
|
46
|
+
* coordinate magnitude) exceeds it. */
|
|
47
47
|
export const TOUCHING_EPSILON = 1e-4;
|
|
48
48
|
/**
|
|
49
|
-
* f32-ULP scale factor for
|
|
50
|
-
*
|
|
51
|
-
* larger magnitudes the ULP only grows. Same term (and reasoning) as
|
|
52
|
-
* `precisionFloor` in `engine-ts/narrow.ts` and `narrowPhase`'s `planeEps` in
|
|
53
|
-
* `contact/narrow-phase.ts` — kept local because this is a different job
|
|
54
|
-
* (the *reported* touching band, not the narrow-phase's own depth floor) on
|
|
55
|
-
* a `Clash`, which doesn't carry the element bounds those two derive from.
|
|
49
|
+
* f32-ULP scale factor (2^-22), for the legacy band only: see
|
|
50
|
+
* {@link touchingEpsilonFor}'s fallback.
|
|
56
51
|
*/
|
|
57
52
|
const F32_ULP_SCALE = 1 / 4_194_304; // 2^-22
|
|
58
53
|
/**
|
|
59
|
-
* The touching band for one specific clash
|
|
60
|
-
* coordinate magnitude rather than a fixed constant.
|
|
54
|
+
* The touching band for one specific clash.
|
|
61
55
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
56
|
+
* A clash from the engine carries {@link Clash.depthFloor}: the f32 noise
|
|
57
|
+
* floor of its own depth along the direction that depth was measured, the
|
|
58
|
+
* very floor the engine classified it against (`depthFloor` /
|
|
59
|
+
* `estimateFloor`, one definition in the clash-math source). The band is
|
|
60
|
+
* that floor, floored at {@link TOUCHING_EPSILON}, so whether a reported
|
|
61
|
+
* clash counts as touching is decided by the same rule as its `hard` verdict
|
|
62
|
+
* and does not move when the model is translated orthogonally to the depth
|
|
63
|
+
* (#5639). A `hard` clash's depth always exceeds its own floor, so for engine
|
|
64
|
+
* results this is the fixed {@link TOUCHING_EPSILON} band in practice; the
|
|
65
|
+
* floor is kept in the comparison so the band can never be narrower than
|
|
66
|
+
* what the engine itself cannot resolve.
|
|
69
67
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
68
|
+
* FALLBACK, deliberately unchanged: a clash without `depthFloor` (recorded
|
|
69
|
+
* before the field existed, rehydrated from BCF/JSON without it, or built by
|
|
70
|
+
* hand) keeps the old band — the max absolute coordinate of its `bounds`
|
|
71
|
+
* over all three axes times 2^-22, floored at {@link TOUCHING_EPSILON}. That
|
|
72
|
+
* band is origin-dependent (a model 10 km out in X gives a Z-direction
|
|
73
|
+
* contact ~2.4 mm of slack), which is exactly why engine results no longer
|
|
74
|
+
* use it; it stays for those results only because nothing better can be
|
|
75
|
+
* derived from a bare `Clash`.
|
|
77
76
|
*/
|
|
78
77
|
function touchingEpsilonFor(c) {
|
|
78
|
+
if (c.depthFloor !== undefined)
|
|
79
|
+
return Math.max(TOUCHING_EPSILON, c.depthFloor);
|
|
79
80
|
let extent = 0;
|
|
80
81
|
for (const v of [c.bounds.min, c.bounds.max]) {
|
|
81
82
|
for (const coord of v) {
|
|
@@ -93,9 +94,9 @@ function touchingEpsilonFor(c) {
|
|
|
93
94
|
* slab, a column sitting on a footing) reported with a ~0 m depth, which users
|
|
94
95
|
* reasonably distrust when they appear in the clash list.
|
|
95
96
|
*
|
|
96
|
-
* `eps` defaults to {@link touchingEpsilonFor}
|
|
97
|
-
*
|
|
98
|
-
*
|
|
97
|
+
* `eps` defaults to {@link touchingEpsilonFor}: the clash's own depth floor
|
|
98
|
+
* when the engine recorded one, else the older coordinate-magnitude band (see
|
|
99
|
+
* that function). An explicit `eps` overrides the default entirely.
|
|
99
100
|
*/
|
|
100
101
|
export function isTouching(c, eps = touchingEpsilonFor(c)) {
|
|
101
102
|
return c.status === 'touch' || (c.status === 'hard' && penetrationDepth(c) <= eps);
|
package/dist/analysis.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAe/D;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAyB;IACxD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAkC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/F,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;AACnE,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,MAAM,aAAa,GAAkC;IAC1D,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;CACR,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAQ;IACvC,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;;
|
|
1
|
+
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ import { triangleAt, triangleCount } from "./triangle.js";
|
|
|
9
9
|
* value with magnitude in `[2, 4)` the true float32 ULP is `2^-22`, and for
|
|
10
10
|
* larger magnitudes the ULP only grows. Same `2^-22` term (and reasoning) as
|
|
11
11
|
* `near_band_from_extent` in `rust/geometry/src/kernel/near_band.rs` and
|
|
12
|
-
* `
|
|
12
|
+
* the clash-math `depthFloor` (`math/aabb.ts`) — kept local rather than shared
|
|
13
13
|
* because plane-distance tolerance and penetration-depth tolerance are
|
|
14
14
|
* different jobs, even though both derive from the same f32 ingestion floor.
|
|
15
15
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broad.d.ts","sourceRoot":"","sources":["../../src/engine-ts/broad.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,YAAY,EAAE,EACtB,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,EAC7B,MAAM,EAAE,MAAM,GACb,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"broad.d.ts","sourceRoot":"","sources":["../../src/engine-ts/broad.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,YAAY,EAAE,EACtB,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,EAC7B,MAAM,EAAE,MAAM,GACb,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA6CzB"}
|
package/dist/engine-ts/broad.js
CHANGED
|
@@ -18,7 +18,17 @@ export function candidatePairs(groupA, groupB, margin) {
|
|
|
18
18
|
const bvh = BVH.build(items);
|
|
19
19
|
const pairs = [];
|
|
20
20
|
if (groupB) {
|
|
21
|
-
|
|
21
|
+
// No entity-identity dedup here. Deduping candidate PAIRS by
|
|
22
|
+
// (a.model, a.key, b.model, b.key) before the narrow phase ran used to
|
|
23
|
+
// collapse every sub-prim of a split entity onto whichever one the BVH
|
|
24
|
+
// reached first — so a broad-phase false positive submesh could claim
|
|
25
|
+
// the (A, B) slot and hide a sibling submesh that genuinely clashes
|
|
26
|
+
// (#5194). Every candidate the broad phase finds is now tested; entity
|
|
27
|
+
// identity is deduped once, downstream, AFTER the narrow phase has
|
|
28
|
+
// decided each submesh's verdict, keeping the more severe one — see
|
|
29
|
+
// `mostSevere` in `orchestrator.ts`, which already deduped by the same
|
|
30
|
+
// (model, key) identity via `clashId` for an unrelated reason and is the
|
|
31
|
+
// single place both kernels' records converge.
|
|
22
32
|
for (let j = 0; j < groupB.length; j += 1) {
|
|
23
33
|
const b = groupB[j];
|
|
24
34
|
const hits = bvh.queryAABB(inflate(b.bounds, margin));
|
|
@@ -26,10 +36,6 @@ export function candidatePairs(groupA, groupB, margin) {
|
|
|
26
36
|
const a = groupA[i];
|
|
27
37
|
if (isSameEntity(a, b))
|
|
28
38
|
continue;
|
|
29
|
-
const dedup = orderKey(a.model, a.key, b.model, b.key);
|
|
30
|
-
if (seen.has(dedup))
|
|
31
|
-
continue;
|
|
32
|
-
seen.add(dedup);
|
|
33
39
|
pairs.push([i, j]);
|
|
34
40
|
}
|
|
35
41
|
}
|
|
@@ -71,9 +77,4 @@ function isSameEntity(a, b) {
|
|
|
71
77
|
return false;
|
|
72
78
|
return a.key === b.key || a.ref === b.ref;
|
|
73
79
|
}
|
|
74
|
-
function orderKey(modelA, keyA, modelB, keyB) {
|
|
75
|
-
const a = `${modelA} ${keyA}`;
|
|
76
|
-
const b = `${modelB} ${keyB}`;
|
|
77
|
-
return a < b ? `${a} ${b}` : `${b} ${a}`;
|
|
78
|
-
}
|
|
79
80
|
//# sourceMappingURL=broad.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broad.js","sourceRoot":"","sources":["../../src/engine-ts/broad.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,GAAG,EAAuB,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAsB,EACtB,MAA6B,EAC7B,MAAc;IAEd,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAqB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3F,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,KAAK,GAA4B,EAAE,CAAC;IAE1C,IAAI,MAAM,EAAE,CAAC;QACX,
|
|
1
|
+
{"version":3,"file":"broad.js","sourceRoot":"","sources":["../../src/engine-ts/broad.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,GAAG,EAAuB,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAsB,EACtB,MAA6B,EAC7B,MAAc;IAEd,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,KAAK,GAAqB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3F,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,KAAK,GAA4B,EAAE,CAAC;IAE1C,IAAI,MAAM,EAAE,CAAC;QACX,6DAA6D;QAC7D,uEAAuE;QACvE,uEAAuE;QACvE,sEAAsE;QACtE,oEAAoE;QACpE,uEAAuE;QACvE,mEAAmE;QACnE,oEAAoE;QACpE,uEAAuE;QACvE,yEAAyE;QACzE,+CAA+C;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACpB,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YACtD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACpB,IAAI,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;oBAAE,SAAS;gBACjC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACpB,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YACtD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,IAAI,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACrB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACxB,mEAAmE;gBACnE,qEAAqE;gBACrE,2DAA2D;gBAC3D,IAAI,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC;oBAAE,SAAS;gBACrC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,YAAY,CAAC,CAA8C,EAAE,CAA8C;IAClH,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC;AAC5C,CAAC"}
|
|
@@ -29,19 +29,60 @@ import type { NarrowResult } from './narrow.js';
|
|
|
29
29
|
export interface BoxPenetration {
|
|
30
30
|
/** Exact box-box minimum-translation depth (Gottschalk 15-axis SAT). */
|
|
31
31
|
mtd: number;
|
|
32
|
+
/** The unit axis `mtd` was measured along (its precision floor's
|
|
33
|
+
* direction, #5405). */
|
|
34
|
+
axis: Vec3;
|
|
32
35
|
/** The MTD is inflated by the piercing member's own extent; report the
|
|
33
36
|
* AABB estimate instead (see `isThroughPenetration`). */
|
|
34
37
|
through: boolean;
|
|
35
38
|
}
|
|
36
39
|
export declare function boxPenetration(small: TriMesh, large: TriMesh): BoxPenetration | null;
|
|
40
|
+
/**
|
|
41
|
+
* Whether `inner` — AABB-contained in `outer`, with no triangle pair crossing
|
|
42
|
+
* beyond f32 noise — is buried in `outer`'s solid (#5473).
|
|
43
|
+
*
|
|
44
|
+
* With no crossing, each connected shell of `inner` lies entirely on one side
|
|
45
|
+
* of `outer`'s surface up to touching it, so one probe point per shell decides
|
|
46
|
+
* by ray parity — provided the probe is not itself on `outer`'s surface, where
|
|
47
|
+
* parity is a coin flip decided by f32 rounding. The old probe, `inner`'s
|
|
48
|
+
* first vertex, is exactly that point for a flush pair (an element resting
|
|
49
|
+
* against the inside of another's AABB touches it AT its vertices), so a rigid
|
|
50
|
+
* translation re-rolled the verdict.
|
|
51
|
+
*
|
|
52
|
+
* Candidates are `inner`'s vertex centroid (when that lies inside `inner`) and
|
|
53
|
+
* every vertex; a candidate is CLEAR when it is more than
|
|
54
|
+
* {@link PROBE_CLEAR_ULPS} f32 ULPs of its largest coordinate off `outer`'s
|
|
55
|
+
* surface, where its parity is trustworthy.
|
|
56
|
+
* 1. Any clear candidate inside `outer` means its shell is buried: `true`.
|
|
57
|
+
* Every candidate is checked, because `inner` may be several disconnected
|
|
58
|
+
* shells and only one of them need be buried (review of #5564); an outside
|
|
59
|
+
* shell must not end the search.
|
|
60
|
+
* 2. Otherwise any clear candidate is outside, and no shell is clearly
|
|
61
|
+
* buried: `false`.
|
|
62
|
+
* 3. With no clear candidate at all — every vertex on `outer`'s surface — the
|
|
63
|
+
* one farthest from it decides. That is what separates an element exactly
|
|
64
|
+
* filling a notch (its centroid is outside) from a duplicate of part of
|
|
65
|
+
* `outer` (its centroid is inside).
|
|
66
|
+
*
|
|
67
|
+
* Visit order and strict comparisons keep the pick bit-identical to the Rust
|
|
68
|
+
* `contained_solid_is_buried`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function containedSolidIsBuried(inner: TriMesh, outer: TriMesh): boolean;
|
|
71
|
+
/** A crossing vertex's penetration into the other solid, with the unit
|
|
72
|
+
* direction it was measured along (from the other's surface to the vertex),
|
|
73
|
+
* which is what its precision floor is projected onto (#5405). */
|
|
74
|
+
export interface VertexPenetration {
|
|
75
|
+
depth: number;
|
|
76
|
+
axis: Vec3;
|
|
77
|
+
}
|
|
37
78
|
/**
|
|
38
79
|
* Deepest penetration of `mesh`'s crossing-triangle VERTICES into `other`:
|
|
39
|
-
* the
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
80
|
+
* the vertex of the triangles flagged in `crossFlags` (the pairs the narrow
|
|
81
|
+
* phase saw genuinely crossing `other`) that lies inside `other` farthest
|
|
82
|
+
* from its surface. Each vertex is visited once (deduped by vertex index, in
|
|
83
|
+
* index order, strict `>` — bit-identical to the Rust
|
|
84
|
+
* `crossing_vertex_penetration`). `null` when no flagged vertex is strictly
|
|
85
|
+
* inside.
|
|
45
86
|
*
|
|
46
87
|
* This is NOT a depth metric and must never be reported as one — it is the
|
|
47
88
|
* sampling probe PR #2536 was held over (`maxPenetrationInto`): its value is
|
|
@@ -56,7 +97,7 @@ export declare function boxPenetration(small: TriMesh, large: TriMesh): BoxPenet
|
|
|
56
97
|
* underestimating can only keep a pair BELOW the floor, and the floor is
|
|
57
98
|
* the very thing being tested.
|
|
58
99
|
*/
|
|
59
|
-
export declare function crossingVertexPenetration(mesh: TriMesh, other: TriMesh, crossFlags: Uint8Array):
|
|
100
|
+
export declare function crossingVertexPenetration(mesh: TriMesh, other: TriMesh, crossFlags: Uint8Array): VertexPenetration | null;
|
|
60
101
|
/**
|
|
61
102
|
* Turns the candidate penetration depths into the final `(status,
|
|
62
103
|
* distanceKind, distance)` triple. This is the ONLY place in the narrow
|
|
@@ -79,8 +120,16 @@ export declare function crossingVertexPenetration(mesh: TriMesh, other: TriMesh,
|
|
|
79
120
|
* vertex inside the other solid (`meshEvidence`) — evidence for this gate
|
|
80
121
|
* only, never a reported depth (see `crossingVertexPenetration`).
|
|
81
122
|
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
123
|
+
* Each candidate is tested against the floor OF ITS OWN DIRECTION — the
|
|
124
|
+
* pair's per-axis f32 noise projected onto the direction that candidate was
|
|
125
|
+
* measured along (`depthFloor`, `estimateFloor`; #5405). A single floor from
|
|
126
|
+
* the max coordinate over all axes handed a Z-direction depth the noise of
|
|
127
|
+
* an X coordinate 10 km out: a genuine 2 mm overlap read as `touch` there and
|
|
128
|
+
* `hard` at the origin, and near the origin the X extent pinned the threshold
|
|
129
|
+
* for contacts that have no X component at all.
|
|
130
|
+
*
|
|
131
|
+
* The pair is `hard` only when EVERY available candidate clears its floor.
|
|
132
|
+
* That is what makes the floor unreachable by depth-source selection:
|
|
84
133
|
* a sub-floor box MTD cannot be promoted by the through-penetration guard
|
|
85
134
|
* swapping in a larger AABB estimate; a sub-floor crossing-vertex
|
|
86
135
|
* penetration on a contained pair (surfaces authored flush — the eight
|
|
@@ -95,5 +144,5 @@ export declare function crossingVertexPenetration(mesh: TriMesh, other: TriMesh,
|
|
|
95
144
|
* distance clears the floor by construction, whichever quantity it came
|
|
96
145
|
* from.
|
|
97
146
|
*/
|
|
98
|
-
export declare function depthClashResult(box: BoxPenetration | null, estimate: number, meshEvidence:
|
|
147
|
+
export declare function depthClashResult(box: BoxPenetration | null, estimate: number, meshEvidence: VertexPenetration | null, elA: ClashElement, elB: ClashElement, rule: ClashRule, point: Vec3, bounds: AABB): NarrowResult | null;
|
|
99
148
|
//# sourceMappingURL=depth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"depth.d.ts","sourceRoot":"","sources":["../../src/engine-ts/depth.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"depth.d.ts","sourceRoot":"","sources":["../../src/engine-ts/depth.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ;4BACwB;IACxB,IAAI,EAAE,IAAI,CAAC;IACX;6DACyD;IACzD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAOpF;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CA0B9E;AAWD;;mEAEmE;AACnE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG,iBAAiB,GAAG,IAAI,CAiBzH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,cAAc,GAAG,IAAI,EAC1B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,iBAAiB,GAAG,IAAI,EACtC,GAAG,EAAE,YAAY,EACjB,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,GACX,YAAY,GAAG,IAAI,CA8BrB"}
|
package/dist/engine-ts/depth.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
-
import { isThroughPenetration,
|
|
4
|
+
import { isThroughPenetration, obbPenetration } from './obb.js';
|
|
5
|
+
import { depthFloor, estimateFloor } from '../math/aabb.js';
|
|
5
6
|
export function boxPenetration(small, large) {
|
|
6
7
|
const oa = small.getObb();
|
|
7
8
|
const ob = large.getObb();
|
|
8
9
|
if (!oa || !ob)
|
|
9
10
|
return null;
|
|
10
|
-
const
|
|
11
|
-
if (
|
|
11
|
+
const pen = obbPenetration(oa, ob);
|
|
12
|
+
if (pen == null)
|
|
12
13
|
return null;
|
|
13
|
-
return { mtd, through: isThroughPenetration(oa, ob) };
|
|
14
|
+
return { mtd: pen.depth, axis: pen.axis, through: isThroughPenetration(oa, ob) };
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
17
|
* f32-ULP scale factor for a "worst-case" single-precision coordinate: for a
|
|
@@ -22,55 +23,83 @@ export function boxPenetration(small, large) {
|
|
|
22
23
|
*/
|
|
23
24
|
const F32_ULP_SCALE = 1 / 4_194_304; // 2^-22
|
|
24
25
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* coordinate magnitude (not a fixed constant — infra models sit far from the
|
|
28
|
-
* origin, where a fixed epsilon would be far too tight, and small models sit
|
|
29
|
-
* near it, where a fixed epsilon would be far too loose).
|
|
26
|
+
* Whether `inner` — AABB-contained in `outer`, with no triangle pair crossing
|
|
27
|
+
* beyond f32 noise — is buried in `outer`'s solid (#5473).
|
|
30
28
|
*
|
|
31
|
-
* `
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* the
|
|
37
|
-
*
|
|
38
|
-
* floor of 1.0 so a model near the origin still gets the single-unit ULP,
|
|
39
|
-
* not zero.
|
|
29
|
+
* With no crossing, each connected shell of `inner` lies entirely on one side
|
|
30
|
+
* of `outer`'s surface up to touching it, so one probe point per shell decides
|
|
31
|
+
* by ray parity — provided the probe is not itself on `outer`'s surface, where
|
|
32
|
+
* parity is a coin flip decided by f32 rounding. The old probe, `inner`'s
|
|
33
|
+
* first vertex, is exactly that point for a flush pair (an element resting
|
|
34
|
+
* against the inside of another's AABB touches it AT its vertices), so a rigid
|
|
35
|
+
* translation re-rolled the verdict.
|
|
40
36
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
37
|
+
* Candidates are `inner`'s vertex centroid (when that lies inside `inner`) and
|
|
38
|
+
* every vertex; a candidate is CLEAR when it is more than
|
|
39
|
+
* {@link PROBE_CLEAR_ULPS} f32 ULPs of its largest coordinate off `outer`'s
|
|
40
|
+
* surface, where its parity is trustworthy.
|
|
41
|
+
* 1. Any clear candidate inside `outer` means its shell is buried: `true`.
|
|
42
|
+
* Every candidate is checked, because `inner` may be several disconnected
|
|
43
|
+
* shells and only one of them need be buried (review of #5564); an outside
|
|
44
|
+
* shell must not end the search.
|
|
45
|
+
* 2. Otherwise any clear candidate is outside, and no shell is clearly
|
|
46
|
+
* buried: `false`.
|
|
47
|
+
* 3. With no clear candidate at all — every vertex on `outer`'s surface — the
|
|
48
|
+
* one farthest from it decides. That is what separates an element exactly
|
|
49
|
+
* filling a notch (its centroid is outside) from a duplicate of part of
|
|
50
|
+
* `outer` (its centroid is inside).
|
|
51
|
+
*
|
|
52
|
+
* Visit order and strict comparisons keep the pick bit-identical to the Rust
|
|
53
|
+
* `contained_solid_is_buried`.
|
|
52
54
|
*/
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
export function containedSolidIsBuried(inner, outer) {
|
|
56
|
+
if (inner.count === 0)
|
|
57
|
+
return false;
|
|
58
|
+
const clear = (p, d) => {
|
|
59
|
+
const m = Math.max(Math.max(Math.max(Math.abs(p[0]), Math.abs(p[1])), Math.abs(p[2])), 1);
|
|
60
|
+
return d > PROBE_CLEAR_ULPS * F32_ULP_SCALE * m;
|
|
61
|
+
};
|
|
62
|
+
const candidates = [];
|
|
63
|
+
const c = inner.vertexCentroid();
|
|
64
|
+
if (inner.containsPoint(c))
|
|
65
|
+
candidates.push(c);
|
|
66
|
+
const n = inner.vertexCount();
|
|
67
|
+
for (let i = 0; i < n; i += 1)
|
|
68
|
+
candidates.push(inner.vertex(i));
|
|
69
|
+
// 1. A clearly buried shell. Parity first: it is the cheaper query, and
|
|
70
|
+
// only candidates it places inside need their distance.
|
|
71
|
+
if (candidates.some((p) => outer.containsPoint(p) && clear(p, outer.distanceToSurface(p))))
|
|
72
|
+
return true;
|
|
73
|
+
// 2./3. No shell is clearly buried.
|
|
74
|
+
let probe = null;
|
|
75
|
+
let farthest = -Infinity;
|
|
76
|
+
for (const p of candidates) {
|
|
77
|
+
const d = outer.distanceToSurface(p);
|
|
78
|
+
if (clear(p, d))
|
|
79
|
+
return false;
|
|
80
|
+
if (d > farthest) {
|
|
81
|
+
farthest = d;
|
|
82
|
+
probe = p;
|
|
62
83
|
}
|
|
63
84
|
}
|
|
64
|
-
return
|
|
85
|
+
return probe !== null && outer.containsPoint(probe);
|
|
65
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* How far off `outer`'s surface a candidate must be for
|
|
89
|
+
* `containedSolidIsBuried` to trust its ray parity, in f32 ULPs of its largest
|
|
90
|
+
* coordinate. Generous on purpose: rounding moves a point on the surface by a
|
|
91
|
+
* few ULPs, and a vertex any closer is treated as touching, which only defers
|
|
92
|
+
* the verdict to a farther candidate.
|
|
93
|
+
*/
|
|
94
|
+
const PROBE_CLEAR_ULPS = 64;
|
|
66
95
|
/**
|
|
67
96
|
* Deepest penetration of `mesh`'s crossing-triangle VERTICES into `other`:
|
|
68
|
-
* the
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
97
|
+
* the vertex of the triangles flagged in `crossFlags` (the pairs the narrow
|
|
98
|
+
* phase saw genuinely crossing `other`) that lies inside `other` farthest
|
|
99
|
+
* from its surface. Each vertex is visited once (deduped by vertex index, in
|
|
100
|
+
* index order, strict `>` — bit-identical to the Rust
|
|
101
|
+
* `crossing_vertex_penetration`). `null` when no flagged vertex is strictly
|
|
102
|
+
* inside.
|
|
74
103
|
*
|
|
75
104
|
* This is NOT a depth metric and must never be reported as one — it is the
|
|
76
105
|
* sampling probe PR #2536 was held over (`maxPenetrationInto`): its value is
|
|
@@ -87,7 +116,7 @@ function precisionFloor(elA, elB) {
|
|
|
87
116
|
*/
|
|
88
117
|
export function crossingVertexPenetration(mesh, other, crossFlags) {
|
|
89
118
|
const seen = new Uint8Array(mesh.vertexCount());
|
|
90
|
-
let
|
|
119
|
+
let deepest = null;
|
|
91
120
|
for (let t = 0; t < mesh.count; t += 1) {
|
|
92
121
|
if (crossFlags[t] === 0)
|
|
93
122
|
continue;
|
|
@@ -98,12 +127,13 @@ export function crossingVertexPenetration(mesh, other, crossFlags) {
|
|
|
98
127
|
const v = mesh.vertex(vi);
|
|
99
128
|
if (!other.containsPoint(v))
|
|
100
129
|
continue;
|
|
101
|
-
const d = other.
|
|
102
|
-
if (d > depth)
|
|
103
|
-
|
|
130
|
+
const [d, q] = other.closestOnSurface(v);
|
|
131
|
+
if (d > (deepest?.depth ?? 0)) {
|
|
132
|
+
deepest = { depth: d, axis: [(v[0] - q[0]) / d, (v[1] - q[1]) / d, (v[2] - q[2]) / d] };
|
|
133
|
+
}
|
|
104
134
|
}
|
|
105
135
|
}
|
|
106
|
-
return
|
|
136
|
+
return deepest;
|
|
107
137
|
}
|
|
108
138
|
/**
|
|
109
139
|
* Turns the candidate penetration depths into the final `(status,
|
|
@@ -127,8 +157,16 @@ export function crossingVertexPenetration(mesh, other, crossFlags) {
|
|
|
127
157
|
* vertex inside the other solid (`meshEvidence`) — evidence for this gate
|
|
128
158
|
* only, never a reported depth (see `crossingVertexPenetration`).
|
|
129
159
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
160
|
+
* Each candidate is tested against the floor OF ITS OWN DIRECTION — the
|
|
161
|
+
* pair's per-axis f32 noise projected onto the direction that candidate was
|
|
162
|
+
* measured along (`depthFloor`, `estimateFloor`; #5405). A single floor from
|
|
163
|
+
* the max coordinate over all axes handed a Z-direction depth the noise of
|
|
164
|
+
* an X coordinate 10 km out: a genuine 2 mm overlap read as `touch` there and
|
|
165
|
+
* `hard` at the origin, and near the origin the X extent pinned the threshold
|
|
166
|
+
* for contacts that have no X component at all.
|
|
167
|
+
*
|
|
168
|
+
* The pair is `hard` only when EVERY available candidate clears its floor.
|
|
169
|
+
* That is what makes the floor unreachable by depth-source selection:
|
|
132
170
|
* a sub-floor box MTD cannot be promoted by the through-penetration guard
|
|
133
171
|
* swapping in a larger AABB estimate; a sub-floor crossing-vertex
|
|
134
172
|
* penetration on a contained pair (surfaces authored flush — the eight
|
|
@@ -144,12 +182,14 @@ export function crossingVertexPenetration(mesh, other, crossFlags) {
|
|
|
144
182
|
* from.
|
|
145
183
|
*/
|
|
146
184
|
export function depthClashResult(box, estimate, meshEvidence, elA, elB, rule, point, bounds) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
185
|
+
// `||` in the same order as the Rust kernel, each comparison `<=` so a NaN
|
|
186
|
+
// candidate never counts as below its floor, on either side.
|
|
187
|
+
const estFloor = estimateFloor(elA.bounds, elB.bounds);
|
|
188
|
+
const boxFloor = box != null ? depthFloor(box.axis, elA.bounds, elB.bounds) : null;
|
|
189
|
+
const belowFloor = estimate <= estFloor ||
|
|
190
|
+
(box != null && boxFloor != null && box.mtd <= boxFloor) ||
|
|
191
|
+
(meshEvidence != null && meshEvidence.depth <= depthFloor(meshEvidence.axis, elA.bounds, elB.bounds));
|
|
192
|
+
if (belowFloor) {
|
|
153
193
|
if (!rule.reportTouch)
|
|
154
194
|
return null;
|
|
155
195
|
// distance is exactly 0 here (the classification, not a measurement, is
|
|
@@ -160,6 +200,8 @@ export function depthClashResult(box, estimate, meshEvidence, elA, elB, rule, po
|
|
|
160
200
|
// Estimate-vs-mesh selection, reachable only above the floor: the box MTD
|
|
161
201
|
// is certified (`mesh`) unless the pair is a through-penetration, where
|
|
162
202
|
// the AABB estimate is the honest number (see `boxPenetration`).
|
|
203
|
+
// The reported depth carries ITS OWN floor out with it (#5639), so the
|
|
204
|
+
// reported touching band is decided by the same rule as this verdict.
|
|
163
205
|
const measured = box != null && !box.through;
|
|
164
206
|
return {
|
|
165
207
|
status: 'hard',
|
|
@@ -167,6 +209,7 @@ export function depthClashResult(box, estimate, meshEvidence, elA, elB, rule, po
|
|
|
167
209
|
distanceKind: measured ? 'mesh' : 'estimate',
|
|
168
210
|
point,
|
|
169
211
|
bounds,
|
|
212
|
+
depthFloor: measured && boxFloor != null ? boxFloor : estFloor,
|
|
170
213
|
};
|
|
171
214
|
}
|
|
172
215
|
//# sourceMappingURL=depth.js.map
|