@ifc-lite/clash 2.3.1 → 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.
Files changed (57) hide show
  1. package/dist/adapters/step.js +1 -0
  2. package/dist/adapters/step.js.map +1 -1
  3. package/dist/analysis.d.ts +6 -6
  4. package/dist/analysis.d.ts.map +1 -1
  5. package/dist/analysis.js +30 -29
  6. package/dist/analysis.js.map +1 -1
  7. package/dist/contact/narrow-phase.js +1 -1
  8. package/dist/engine-ts/broad.d.ts.map +1 -1
  9. package/dist/engine-ts/broad.js +11 -10
  10. package/dist/engine-ts/broad.js.map +1 -1
  11. package/dist/engine-ts/depth.d.ts +59 -10
  12. package/dist/engine-ts/depth.d.ts.map +1 -1
  13. package/dist/engine-ts/depth.js +101 -58
  14. package/dist/engine-ts/depth.js.map +1 -1
  15. package/dist/engine-ts/kernel.d.ts +2 -0
  16. package/dist/engine-ts/kernel.d.ts.map +1 -1
  17. package/dist/engine-ts/narrow.d.ts +8 -0
  18. package/dist/engine-ts/narrow.d.ts.map +1 -1
  19. package/dist/engine-ts/narrow.js +17 -13
  20. package/dist/engine-ts/narrow.js.map +1 -1
  21. package/dist/engine-ts/obb-detect.d.ts +19 -0
  22. package/dist/engine-ts/obb-detect.d.ts.map +1 -0
  23. package/dist/engine-ts/obb-detect.js +191 -0
  24. package/dist/engine-ts/obb-detect.js.map +1 -0
  25. package/dist/engine-ts/obb.d.ts +14 -23
  26. package/dist/engine-ts/obb.d.ts.map +1 -1
  27. package/dist/engine-ts/obb.js +35 -140
  28. package/dist/engine-ts/obb.js.map +1 -1
  29. package/dist/engine-ts/orchestrator.d.ts.map +1 -1
  30. package/dist/engine-ts/orchestrator.js +59 -15
  31. package/dist/engine-ts/orchestrator.js.map +1 -1
  32. package/dist/engine-ts/tri-mesh.d.ts +10 -5
  33. package/dist/engine-ts/tri-mesh.d.ts.map +1 -1
  34. package/dist/engine-ts/tri-mesh.js +35 -25
  35. package/dist/engine-ts/tri-mesh.js.map +1 -1
  36. package/dist/engine-ts/ts-kernel.d.ts.map +1 -1
  37. package/dist/engine-ts/ts-kernel.js +1 -0
  38. package/dist/engine-ts/ts-kernel.js.map +1 -1
  39. package/dist/engine-wasm/wasm-kernel.d.ts.map +1 -1
  40. package/dist/engine-wasm/wasm-kernel.js +10 -1
  41. package/dist/engine-wasm/wasm-kernel.js.map +1 -1
  42. package/dist/math/aabb.d.ts +9 -0
  43. package/dist/math/aabb.d.ts.map +1 -1
  44. package/dist/math/aabb.js +13 -0
  45. package/dist/math/aabb.js.map +1 -1
  46. package/dist/math/generated/plato.g.d.ts +11 -2
  47. package/dist/math/generated/plato.g.d.ts.map +1 -1
  48. package/dist/math/generated/plato.g.js +347 -190
  49. package/dist/math/generated/plato.g.js.map +1 -1
  50. package/dist/math/triangle-intersect.d.ts +12 -6
  51. package/dist/math/triangle-intersect.d.ts.map +1 -1
  52. package/dist/math/triangle-intersect.js +12 -6
  53. package/dist/math/triangle-intersect.js.map +1 -1
  54. package/dist/types.d.ts +15 -0
  55. package/dist/types.d.ts.map +1 -1
  56. package/dist/types.js.map +1 -1
  57. package/package.json +9 -9
@@ -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":"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"}
1
+ {"version":3,"file":"step.js","sourceRoot":"","sources":["../../src/adapters/step.ts"],"names":[],"mappings":"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"}
@@ -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 scale-relative default: near the
35
- * origin this constant IS the default (bit-for-bit), it only grows once the
36
- * pair's own coordinate magnitude pushes the f32 noise floor past it. */
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}, scaled to this clash's own
46
- * coordinate magnitude (see that function) so the touching band stays valid
47
- * far from the origin. An explicit `eps` overrides the default entirely.
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
  /**
@@ -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;;;;0EAI0E;AAC1E,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"}
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 scale-relative default: near the
45
- * origin this constant IS the default (bit-for-bit), it only grows once the
46
- * pair's own coordinate magnitude pushes the f32 noise floor past it. */
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 a "worst-case" single-precision coordinate: for a
50
- * value with magnitude in `[2, 4)` the true float32 ULP is `2^-22`, and for
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, scaled to that clash's own
60
- * coordinate magnitude rather than a fixed constant.
54
+ * The touching band for one specific clash.
61
55
  *
62
- * Geometry is ingested from f32 buffers, so a fixed `TOUCHING_EPSILON` is
63
- * only valid near the origin: the f32 ULP exceeds `1e-4` above roughly 1 km
64
- * from the origin (a `Clash`'s own coordinate magnitude — see below — decides
65
- * exactly where). Past that distance, a genuinely flush pair (a wall meeting
66
- * a slab) can pick up more than `1e-4` of pure rounding noise in its measured
67
- * penetration depth, and the fixed band then misses it, letting it reappear
68
- * as a hard clash in a list the user asked to de-noise.
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
- * `Clash` carries no element bounds (that lives on `ClashElement`, not on the
71
- * detection result), but it does carry `bounds` — the contact/overlap region
72
- * itself, in the same world coordinates as the elements — so that is the
73
- * scale source: the max absolute coordinate over the clash's own contact
74
- * box. Floored at {@link TOUCHING_EPSILON} (not the raw single-unit f32
75
- * floor `precisionFloor` uses) so a clash near the origin gets exactly the
76
- * old fixed band, unchanged.
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}, scaled to this clash's own
97
- * coordinate magnitude (see that function) so the touching band stays valid
98
- * far from the origin. An explicit `eps` overrides the default entirely.
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);
@@ -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;;;;0EAI0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,aAAa,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,kBAAkB,CAAC,CAAQ;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,GAAG,MAAM;gBAAE,MAAM,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,CAAQ,EAAE,MAAc,kBAAkB,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,gBAAgB,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;AACrF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAA2B;IACxD,OAAO,QAAQ,CAAC,QAAQ,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC,CAAC;AAC5D,CAAC;AAuBD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAA4C,EAC5C,QAA2B;IAE3B,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC;IAChC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,qBAAqB,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAyC;IAC5E,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC;IACrC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC;IAC1D,IAAI,UAAU,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACrC,IAAI,UAAU,KAAK,QAAQ,CAAC,MAAM;QAAE,OAAO,UAAU,CAAC;IACtD,OAAO,SAAS,CAAC;AACnB,CAAC;AAID,SAAS,KAAK,CAAC,CAAQ,EAAE,CAAQ;IAC/B,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAyB,EAAE,EAAe;IACpE,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAC5B,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,UAAU;YACb,GAAG,CAAC,IAAI,CACN,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACrD,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC;gBACzC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CACd,CAAC;YACF,MAAM;QACR,KAAK,OAAO;YACV,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7E,MAAM;QACR,KAAK,UAAU;YACb,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3D,MAAM;IACV,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
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
- * `precisionFloor` in `engine-ts/narrow.ts` — kept local rather than shared
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,CAsCzB"}
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"}
@@ -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
- const seen = new Set();
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":"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"}
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 maximum distance-to-surface of `other` over the vertices of the
40
- * triangles flagged in `crossFlags` (the pairs the narrow phase saw
41
- * genuinely crossing `other`) that lie inside `other`. Each vertex is
42
- * visited once (deduped by vertex index, in index order — bit-identical to
43
- * the Rust `crossing_vertex_penetration`). Returns 0 when no flagged vertex
44
- * is inside.
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): number;
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
- * The pair is `hard` only when the SMALLEST available candidate clears the
83
- * floor. That is what makes the floor unreachable by depth-source selection:
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: number | null, elA: ClashElement, elB: ClashElement, rule: ClashRule, point: Vec3, bounds: AABB): NarrowResult | null;
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;AAGhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ;6DACyD;IACzD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAOpF;AAsDD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,CAevG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,cAAc,GAAG,IAAI,EAC1B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,GAAG,EAAE,YAAY,EACjB,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,GACX,YAAY,GAAG,IAAI,CAsBrB"}
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"}
@@ -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, obbPenetrationDepth } from './obb.js';
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 mtd = obbPenetrationDepth(oa, ob);
11
- if (mtd == null)
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
- * Penetration-depth floor below which a computed overlap cannot be
26
- * distinguished from float32 rounding noise, scaled to the pair's own
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
- * `rust/clash/src/tri_mesh.rs` ingests geometry from f32 buffers and stores/
32
- * queries it in f64, so f64 arithmetic cannot recover precision the source
33
- * data never had: two surfaces authored to be flush round to adjacent f32
34
- * values, and the resulting "penetration" is bit-noise at the ULP of
35
- * whichever operand coordinate is largest, not a measured overlap. Extent is
36
- * the max abs coordinate over both elements' AABBs (world space, matching
37
- * `near_band_from_extent`'s use of the actual compared coordinates) with a
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
- * The floor grows linearly with the pair's distance from the origin — that
42
- * is the point, since f32 precision itself degrades the same way. The
43
- * consequence: on a georeferenced model whose elements sit at real map
44
- * coordinates (hundreds of kilometres out, which real IFC files do), the
45
- * floor reaches decimetre scale, and a genuine clash below that threshold
46
- * reclassifies as `touch`. That is not a bug in this function — at those
47
- * magnitudes f32 genuinely cannot represent a finer distinction, so the
48
- * "penetration" is not reliably measurable either way — but it means the
49
- * floor tracks a limitation of the source data, not of clash detection.
50
- * The fix for a model in that position is ingesting geometry closer to the
51
- * origin (or in f64), not lowering this floor.
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 precisionFloor(elA, elB) {
54
- let extent = 1.0;
55
- for (const b of [elA.bounds, elB.bounds]) {
56
- for (const v of [b.min, b.max]) {
57
- for (const c of v) {
58
- const a = Math.abs(c);
59
- if (a > extent)
60
- extent = a;
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 extent * F32_ULP_SCALE;
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 maximum distance-to-surface of `other` over the vertices of the
69
- * triangles flagged in `crossFlags` (the pairs the narrow phase saw
70
- * genuinely crossing `other`) that lie inside `other`. Each vertex is
71
- * visited once (deduped by vertex index, in index order — bit-identical to
72
- * the Rust `crossing_vertex_penetration`). Returns 0 when no flagged vertex
73
- * is inside.
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 depth = 0;
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.distanceToSurface(v);
102
- if (d > depth)
103
- depth = d;
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 depth;
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
- * The pair is `hard` only when the SMALLEST available candidate clears the
131
- * floor. That is what makes the floor unreachable by depth-source selection:
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
- let floorDepth = estimate;
148
- if (box != null && box.mtd < floorDepth)
149
- floorDepth = box.mtd;
150
- if (meshEvidence != null && meshEvidence < floorDepth)
151
- floorDepth = meshEvidence;
152
- if (floorDepth <= precisionFloor(elA, elB)) {
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