@woosh/meep-engine 2.143.0 → 2.145.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 (56) hide show
  1. package/package.json +1 -1
  2. package/src/core/bvh2/bvh3/BVH.d.ts.map +1 -1
  3. package/src/core/bvh2/bvh3/BVH.js +158 -4
  4. package/src/core/geom/3d/shape/CylinderShape3D.d.ts +56 -0
  5. package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -0
  6. package/src/core/geom/3d/shape/CylinderShape3D.js +223 -0
  7. package/src/core/geom/3d/shape/PointShape3D.d.ts +1 -0
  8. package/src/core/geom/3d/shape/PointShape3D.d.ts.map +1 -1
  9. package/src/core/geom/3d/shape/PointShape3D.js +11 -0
  10. package/src/core/geom/3d/shape/SphereShape3D.d.ts +1 -0
  11. package/src/core/geom/3d/shape/SphereShape3D.d.ts.map +1 -1
  12. package/src/core/geom/3d/shape/SphereShape3D.js +4 -0
  13. package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
  14. package/src/core/geom/3d/shape/json/shape_to_type.js +3 -0
  15. package/src/core/geom/3d/shape/json/type_adapters.d.ts +15 -0
  16. package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
  17. package/src/core/geom/3d/shape/json/type_adapters.js +16 -0
  18. package/src/engine/control/first-person/DESIGN_COLLISION.md +314 -217
  19. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +104 -58
  20. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  21. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +1828 -1789
  22. package/src/engine/control/first-person/TODO.md +17 -32
  23. package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -1
  24. package/src/engine/control/first-person/abilities/WallRun.js +18 -35
  25. package/src/engine/control/first-person/collision/KinematicMover.d.ts +206 -0
  26. package/src/engine/control/first-person/collision/KinematicMover.d.ts.map +1 -0
  27. package/src/engine/control/first-person/collision/KinematicMover.js +592 -0
  28. package/src/engine/control/first-person/prototype_first_person_controller.js +65 -0
  29. package/src/engine/graphics/render/buffer/simple-fx/ao/SAOShader.js +18 -9
  30. package/src/engine/physics/PLAN.md +145 -41
  31. package/src/engine/physics/contact/ManifoldStore.d.ts +28 -2
  32. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
  33. package/src/engine/physics/contact/ManifoldStore.js +37 -3
  34. package/src/engine/physics/contact/combine_material.d.ts +30 -0
  35. package/src/engine/physics/contact/combine_material.d.ts.map +1 -0
  36. package/src/engine/physics/contact/combine_material.js +35 -0
  37. package/src/engine/physics/ecs/Collider.d.ts +15 -0
  38. package/src/engine/physics/ecs/Collider.d.ts.map +1 -1
  39. package/src/engine/physics/ecs/Collider.js +34 -0
  40. package/src/engine/physics/ecs/Joint.d.ts +18 -0
  41. package/src/engine/physics/ecs/Joint.d.ts.map +1 -1
  42. package/src/engine/physics/ecs/Joint.js +70 -0
  43. package/src/engine/physics/ecs/PhysicsSystem.d.ts +9 -4
  44. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  45. package/src/engine/physics/ecs/PhysicsSystem.js +9 -4
  46. package/src/engine/physics/ecs/RigidBody.d.ts +15 -0
  47. package/src/engine/physics/ecs/RigidBody.d.ts.map +1 -1
  48. package/src/engine/physics/ecs/RigidBody.js +46 -0
  49. package/src/engine/physics/narrowphase/compute_penetration.d.ts +41 -41
  50. package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -1
  51. package/src/engine/physics/narrowphase/compute_penetration.js +96 -169
  52. package/src/engine/physics/narrowphase/narrowphase_step.d.ts +52 -0
  53. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  54. package/src/engine/physics/narrowphase/narrowphase_step.js +130 -3
  55. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
  56. package/src/engine/physics/solver/solve_contacts.js +10 -21
@@ -1 +1 @@
1
- {"version":3,"file":"Joint.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/Joint.js"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,gCAFU,MAAM,CAEoB;AAEpC;;;;GAIG;AACH,0BAFU,MAAM,CAEc;AAE9B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAEI;;;OAGG;IACH,SAFU,MAAM,CAEH;IAEb;;;OAGG;IACH,SAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,uBAFU,OAAO,CAEmB;IAEpC;;;;;OAKG;IACH,uBAFU,OAAO,CAEmB;IAEpC;;;;;;;;;OASG;IACH,sBAFU,UAAU,CAEW;IAE/B;;;;;;;OAOG;IACH,sBAFU,UAAU,CAEW;IAE/B;;;;;OAKG;IACH,kBAFU,UAAU,CAKjB;IAEH;;;;;;;;;;OAUG;IACH,YAFU,OAAO,CAEE;IAEnB;;;;;;OAMG;IACH,wBAFU,YAAY,CAEc;IACpC,qCAAqC;IACrC,wBADqB,YAAY,CACG;IAEpC;;;;;OAKG;IACH,uBAFU,YAAY,CAEa;IACnC,qCAAqC;IACrC,qBADqB,YAAY,CACA;IAEjC;;;;;OAKG;IACH,iCAFU,YAAY,CAEuB;IAC7C,qCAAqC;IACrC,2BADqB,YAAY,CACM;IAEvC;;;;;OAKG;IACH,qBAFU,YAAY,CAEW;IAEjC;;;OAGG;IACH,UAFU,MAAM,CAEF;IACd;;;OAGG;IACH,UAFU,MAAM,CAEO;IACvB;;;OAGG;IACH,UAFU,MAAM,CAEa;IAE7B;;;;;OAKG;IACH,gBAFa,KAAK,CAUjB;IAED;;;;OAIG;IACH,UAFa,KAAK,CAKjB;IAED;;;;;;;;OAQG;IACH,0BAJW,MAAM,GAEJ,KAAK,CAWjB;IAED;;;;;;;;OAQG;IACH,6BAJW,MAAM,GAEJ,KAAK,CAWjB;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,wBANW,MAAM,cAAqB,MAAM,eACjC,MAAM,gBACN,MAAM,GAEJ,KAAK,CAiBjB;IAED;;;;;;;;;OASG;IACH,qBALW,MAAM,SACN,MAAM,SAAgB,MAAM,GAE1B,KAAK,CAOjB;IAED;;;;;;;;;;;;;;;OAeG;IACH,sBAJW,MAAM,SACN,MAAM,SAAgB,MAAM,GAC1B,KAAK,CAOjB;IAED;;;;;;;;;;;;OAYG;IACH,qBAPW,MAAM,kBACN,MAAM,YAEN,MAAM,GAEJ,KAAK,CAOjB;IAED;;;;;;;;;;;;;;OAcG;IACH,sBATW,MAAM,kBACN,MAAM,YAIN,MAAM,GAEJ,KAAK,CAOjB;IAED;;;;;;;;;;;OAWG;IACH,sBALW,MAAM,aACN,MAAM,WACN,MAAM,GACJ,KAAK,CAOjB;IAED;;;;;;;;;;;;OAYG;IACH,uBANW,MAAM,aACN,MAAM,WAEN,MAAM,GACJ,KAAK,CAOjB;IASL;;;OAGG;IACH,kBAFU,OAAO,CAEM;CAZtB;;kBAIS,MAAM;;oBAzYI,+BAA+B;uBAC5B,kCAAkC"}
1
+ {"version":3,"file":"Joint.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/Joint.js"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,gCAFU,MAAM,CAEoB;AAEpC;;;;GAIG;AACH,0BAFU,MAAM,CAEc;AAE9B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAEI;;;OAGG;IACH,SAFU,MAAM,CAEH;IAEb;;;OAGG;IACH,SAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,uBAFU,OAAO,CAEmB;IAEpC;;;;;OAKG;IACH,uBAFU,OAAO,CAEmB;IAEpC;;;;;;;;;OASG;IACH,sBAFU,UAAU,CAEW;IAE/B;;;;;;;OAOG;IACH,sBAFU,UAAU,CAEW;IAE/B;;;;;OAKG;IACH,kBAFU,UAAU,CAKjB;IAEH;;;;;;;;;;OAUG;IACH,YAFU,OAAO,CAEE;IAEnB;;;;;;OAMG;IACH,wBAFU,YAAY,CAEc;IACpC,qCAAqC;IACrC,wBADqB,YAAY,CACG;IAEpC;;;;;OAKG;IACH,uBAFU,YAAY,CAEa;IACnC,qCAAqC;IACrC,qBADqB,YAAY,CACA;IAEjC;;;;;OAKG;IACH,iCAFU,YAAY,CAEuB;IAC7C,qCAAqC;IACrC,2BADqB,YAAY,CACM;IAEvC;;;;;OAKG;IACH,qBAFU,YAAY,CAEW;IAEjC;;;OAGG;IACH,UAFU,MAAM,CAEF;IACd;;;OAGG;IACH,UAFU,MAAM,CAEO;IACvB;;;OAGG;IACH,UAFU,MAAM,CAEa;IAE7B;;;;;OAKG;IACH,gBAFa,KAAK,CAUjB;IAED;;;;OAIG;IACH,UAFa,KAAK,CAKjB;IAED;;;;;;;;OAQG;IACH,0BAJW,MAAM,GAEJ,KAAK,CAWjB;IAED;;;;;;;;OAQG;IACH,6BAJW,MAAM,GAEJ,KAAK,CAWjB;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,wBANW,MAAM,cAAqB,MAAM,eACjC,MAAM,gBACN,MAAM,GAEJ,KAAK,CAiBjB;IAED;;;;;;;;;OASG;IACH,qBALW,MAAM,SACN,MAAM,SAAgB,MAAM,GAE1B,KAAK,CAOjB;IAED;;;;;;;;;;;;;;;OAeG;IACH,sBAJW,MAAM,SACN,MAAM,SAAgB,MAAM,GAC1B,KAAK,CAOjB;IAED;;;;;;;;;;;;OAYG;IACH,qBAPW,MAAM,kBACN,MAAM,YAEN,MAAM,GAEJ,KAAK,CAOjB;IAED;;;;;;;;;;;;;;OAcG;IACH,sBATW,MAAM,kBACN,MAAM,YAIN,MAAM,GAEJ,KAAK,CAOjB;IAED;;;;;;;;;;;OAWG;IACH,sBALW,MAAM,aACN,MAAM,WACN,MAAM,GACJ,KAAK,CAOjB;IAED;;;;;;;;;;;;OAYG;IACH,uBANW,MAAM,aACN,MAAM,WAEN,MAAM,GACJ,KAAK,CAOjB;IAED;;;;;;;;;;OAUG;IACH,cAHW,KAAK,GACH,OAAO,CA+BnB;IAED;;;;OAIG;IACH,QAFa,MAAM,CAsBlB;IASL;;;OAGG;IACH,kBAFU,OAAO,CAEM;CAZtB;;kBAIS,MAAM;;oBA9cI,+BAA+B;uBAC5B,kCAAkC"}
@@ -1,3 +1,4 @@
1
+ import { computeHashFloat } from "../../../core/primitives/numbers/computeHashFloat.js";
1
2
  import Vector3 from "../../../core/geom/Vector3.js";
2
3
  import Quaternion from "../../../core/geom/Quaternion.js";
3
4
  import { DofMode } from "../constraint/DofMode.js";
@@ -387,6 +388,75 @@ export class Joint {
387
388
  this.dofDamping[3 + axis] = damping;
388
389
  return this;
389
390
  }
391
+
392
+ /**
393
+ * Value equality over the configurable / persistent state — the same field
394
+ * set that {@link JointSerializationAdapter} writes: the two anchor
395
+ * entities, the local anchor points and basis frames, the swing-twist flag,
396
+ * and the six per-DOF mode + limit / spring / motor arrays. Transient
397
+ * solver state (`dofImpulse`) and the system-resolved handles (`_bodyIdA`,
398
+ * `_bodyIdB`, `_jointId`) are excluded.
399
+ *
400
+ * @param {Joint} other
401
+ * @returns {boolean}
402
+ */
403
+ equals(other) {
404
+ if (other === this) return true;
405
+ if (other === null || other === undefined || other.isJoint !== true) return false;
406
+
407
+ if (this.entityA !== other.entityA
408
+ || this.entityB !== other.entityB
409
+ || this.swingTwist !== other.swingTwist
410
+ || !this.localAnchorA.equals(other.localAnchorA)
411
+ || !this.localAnchorB.equals(other.localAnchorB)
412
+ || !this.localBasisA.equals(other.localBasisA)
413
+ || !this.localBasisB.equals(other.localBasisB)
414
+ ) {
415
+ return false;
416
+ }
417
+
418
+ for (let i = 0; i < 6; i++) {
419
+ if (this.dofMode[i] !== other.dofMode[i]
420
+ || this.dofLowerLimit[i] !== other.dofLowerLimit[i]
421
+ || this.dofUpperLimit[i] !== other.dofUpperLimit[i]
422
+ || this.dofStiffness[i] !== other.dofStiffness[i]
423
+ || this.dofDamping[i] !== other.dofDamping[i]
424
+ || this.dofMotorTargetVelocity[i] !== other.dofMotorTargetVelocity[i]
425
+ || this.dofMotorMaxForce[i] !== other.dofMotorMaxForce[i]
426
+ ) {
427
+ return false;
428
+ }
429
+ }
430
+
431
+ return true;
432
+ }
433
+
434
+ /**
435
+ * Hash over the same persistent state as {@link equals}. Equal joints hash
436
+ * equal.
437
+ * @returns {number}
438
+ */
439
+ hash() {
440
+ let h = this.entityA | 0;
441
+ h = (h * 31 + (this.entityB | 0)) | 0;
442
+ h = (h * 31 + (this.swingTwist ? 1 : 0)) | 0;
443
+ h = (h * 31 + this.localAnchorA.hash()) | 0;
444
+ h = (h * 31 + this.localAnchorB.hash()) | 0;
445
+ h = (h * 31 + this.localBasisA.hash()) | 0;
446
+ h = (h * 31 + this.localBasisB.hash()) | 0;
447
+
448
+ for (let i = 0; i < 6; i++) {
449
+ h = (h * 31 + (this.dofMode[i] | 0)) | 0;
450
+ h = (h * 31 + computeHashFloat(this.dofLowerLimit[i])) | 0;
451
+ h = (h * 31 + computeHashFloat(this.dofUpperLimit[i])) | 0;
452
+ h = (h * 31 + computeHashFloat(this.dofStiffness[i])) | 0;
453
+ h = (h * 31 + computeHashFloat(this.dofDamping[i])) | 0;
454
+ h = (h * 31 + computeHashFloat(this.dofMotorTargetVelocity[i])) | 0;
455
+ h = (h * 31 + computeHashFloat(this.dofMotorMaxForce[i])) | 0;
456
+ }
457
+
458
+ return h;
459
+ }
390
460
  }
391
461
 
392
462
  /**
@@ -219,10 +219,15 @@ export class PhysicsSystem extends System<any, any, any, any, any> {
219
219
  */
220
220
  private __pair_filter;
221
221
  /**
222
- * First attached collider of a body, or `null` if none. Used by the
223
- * solver to read material parameters (friction / restitution) when the
224
- * per-contact source-collider identity isn't tracked yet (v1 limitation
225
- * multi-collider bodies with mixed materials lose precision here).
222
+ * First attached collider of a body, or `null` if none. Used for
223
+ * body-level checks that aren't yet per-collider: the sensor flag, the
224
+ * concave-shape dispatch flag, and the contact-filter callback's
225
+ * `colliderA` / `colliderB` arguments. Contact **materials** (friction /
226
+ * restitution) are NOT read here — the narrowphase tracks the specific
227
+ * source collider on each side of every contact and stamps the combined
228
+ * coefficients into the manifold per contact, so mixed-material compound
229
+ * bodies are accurate. (Per-contact source colliders for the filter
230
+ * callback / sensor flag remain a follow-up.)
226
231
  *
227
232
  * @private
228
233
  * @param {number} body_idx
@@ -1 +1 @@
1
- {"version":3,"file":"PhysicsSystem.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/PhysicsSystem.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PhysicsSystem.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/PhysicsSystem.js"],"names":[],"mappings":"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"}
@@ -341,10 +341,15 @@ export class PhysicsSystem extends System {
341
341
  }
342
342
 
343
343
  /**
344
- * First attached collider of a body, or `null` if none. Used by the
345
- * solver to read material parameters (friction / restitution) when the
346
- * per-contact source-collider identity isn't tracked yet (v1 limitation
347
- * multi-collider bodies with mixed materials lose precision here).
344
+ * First attached collider of a body, or `null` if none. Used for
345
+ * body-level checks that aren't yet per-collider: the sensor flag, the
346
+ * concave-shape dispatch flag, and the contact-filter callback's
347
+ * `colliderA` / `colliderB` arguments. Contact **materials** (friction /
348
+ * restitution) are NOT read here — the narrowphase tracks the specific
349
+ * source collider on each side of every contact and stamps the combined
350
+ * coefficients into the manifold per contact, so mixed-material compound
351
+ * bodies are accurate. (Per-contact source colliders for the filter
352
+ * callback / sensor flag remain a follow-up.)
348
353
  *
349
354
  * @private
350
355
  * @param {number} body_idx
@@ -181,6 +181,21 @@ export class RigidBody {
181
181
  flags: number;
182
182
  };
183
183
  fromJSON(json: any): void;
184
+ /**
185
+ * Value equality over the configurable / persistent state — the same field
186
+ * set that is serialized. Transient runtime state (`_bodyId`, `sleepState`,
187
+ * sleep timers, accumulated force/torque) is system-owned and excluded.
188
+ *
189
+ * @param {RigidBody} other
190
+ * @returns {boolean}
191
+ */
192
+ equals(other: RigidBody): boolean;
193
+ /**
194
+ * Hash over the same persistent state as {@link equals}. Equal bodies hash
195
+ * equal.
196
+ * @returns {number}
197
+ */
198
+ hash(): number;
184
199
  /**
185
200
  * @readonly
186
201
  * @type {boolean}
@@ -1 +1 @@
1
- {"version":3,"file":"RigidBody.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/RigidBody.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,qCAFU,MAAM,CAEyB;AAEzC;;;;;;;;;;;;;GAaG;AACH;IAEI;;OAEG;IACH,MAFU,QAAQ,GAAC,MAAM,CAED;IAExB;;;;OAIG;IACH,yBAFU,OAAO,CAEqB;IAEtC;;;;OAIG;IACH,0BAFU,OAAO,CAEsB;IAEvC;;;;;;OAMG;IACH,2BAFU,OAAO,CAEuB;IAExC;;;;;OAKG;IACH,4BAFU,OAAO,CAEwB;IAEzC;;;;OAIG;IACH,MAFU,MAAM,CAEP;IAET;;;;;;OAMG;IACH,8BAFU,OAAO,CAE0B;IAE3C;;OAEG;IACH,eAFU,MAAM,CAEE;IAElB;;OAEG;IACH,gBAFU,MAAM,CAEG;IAEnB;;;;OAIG;IACH,cAFU,MAAM,CAEC;IAEjB;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,MAFU,MAAM,CAEM;IAEtB;;OAEG;IACH,OAFU,cAAc,GAAC,MAAM,CAEH;IAE5B;;;OAGG;IACH,YAFU,UAAU,GAAC,MAAM,CAEG;IAE9B;;;;;;;;OAQG;IACH,aAFU,MAAM,CAEA;IAEhB;;;;;;;;;;;OAWG;IACH,kBAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,kBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,SAFU,MAAM,CAEiB;IAEjC;;;OAGG;IACH,cAFW,MAAM,GAAC,cAAc,QAI/B;IAED;;;OAGG;IACH,gBAFW,MAAM,GAAC,cAAc,QAI/B;IAED;;;;OAIG;IACH,cAHW,MAAM,GAAC,cAAc,GACnB,OAAO,CAInB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,cAAc,SACrB,OAAO,QAQjB;IAED;;;;;;;;;;;;;;;;;;;;;;;;MAcC;IAED,0BAYC;IASL;;;OAGG;IACH,sBAFU,OAAO,CAEc;CAZ9B;;kBAIS,MAAM;;yBAtOS,eAAe;oBADpB,+BAA+B;+BAEpB,qBAAqB;2BACzB,iBAAiB"}
1
+ {"version":3,"file":"RigidBody.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/RigidBody.js"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,qCAFU,MAAM,CAEyB;AAEzC;;;;;;;;;;;;;GAaG;AACH;IAEI;;OAEG;IACH,MAFU,QAAQ,GAAC,MAAM,CAED;IAExB;;;;OAIG;IACH,yBAFU,OAAO,CAEqB;IAEtC;;;;OAIG;IACH,0BAFU,OAAO,CAEsB;IAEvC;;;;;;OAMG;IACH,2BAFU,OAAO,CAEuB;IAExC;;;;;OAKG;IACH,4BAFU,OAAO,CAEwB;IAEzC;;;;OAIG;IACH,MAFU,MAAM,CAEP;IAET;;;;;;OAMG;IACH,8BAFU,OAAO,CAE0B;IAE3C;;OAEG;IACH,eAFU,MAAM,CAEE;IAElB;;OAEG;IACH,gBAFU,MAAM,CAEG;IAEnB;;;;OAIG;IACH,cAFU,MAAM,CAEC;IAEjB;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,MAFU,MAAM,CAEM;IAEtB;;OAEG;IACH,OAFU,cAAc,GAAC,MAAM,CAEH;IAE5B;;;OAGG;IACH,YAFU,UAAU,GAAC,MAAM,CAEG;IAE9B;;;;;;;;OAQG;IACH,aAFU,MAAM,CAEA;IAEhB;;;;;;;;;;;OAWG;IACH,kBAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,kBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,SAFU,MAAM,CAEiB;IAEjC;;;OAGG;IACH,cAFW,MAAM,GAAC,cAAc,QAI/B;IAED;;;OAGG;IACH,gBAFW,MAAM,GAAC,cAAc,QAI/B;IAED;;;;OAIG;IACH,cAHW,MAAM,GAAC,cAAc,GACnB,OAAO,CAInB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,cAAc,SACrB,OAAO,QAQjB;IAED;;;;;;;;;;;;;;;;;;;;;;;;MAcC;IAED,0BAYC;IAED;;;;;;;OAOG;IACH,cAHW,SAAS,GACP,OAAO,CAiBnB;IAED;;;;OAIG;IACH,QAFa,MAAM,CAelB;IASL;;;OAGG;IACH,sBAFU,OAAO,CAEc;CAZ9B;;kBAIS,MAAM;;yBAnRS,eAAe;oBADpB,+BAA+B;+BAEpB,qBAAqB;2BACzB,iBAAiB"}
@@ -1,3 +1,4 @@
1
+ import { computeHashFloat } from "../../../core/primitives/numbers/computeHashFloat.js";
1
2
  import Vector3 from "../../../core/geom/Vector3.js";
2
3
  import { BodyKind } from "./BodyKind.js";
3
4
  import { RigidBodyFlags } from "./RigidBodyFlags.js";
@@ -225,6 +226,51 @@ export class RigidBody {
225
226
  if (json.mask !== undefined) this.mask = json.mask;
226
227
  if (json.flags !== undefined) this.flags = json.flags;
227
228
  }
229
+
230
+ /**
231
+ * Value equality over the configurable / persistent state — the same field
232
+ * set that is serialized. Transient runtime state (`_bodyId`, `sleepState`,
233
+ * sleep timers, accumulated force/torque) is system-owned and excluded.
234
+ *
235
+ * @param {RigidBody} other
236
+ * @returns {boolean}
237
+ */
238
+ equals(other) {
239
+ if (other === this) return true;
240
+ if (other === null || other === undefined || other.isRigidBody !== true) return false;
241
+
242
+ return this.kind === other.kind
243
+ && this.mass === other.mass
244
+ && this.linearDamping === other.linearDamping
245
+ && this.angularDamping === other.angularDamping
246
+ && this.gravityScale === other.gravityScale
247
+ && this.layer === other.layer
248
+ && this.mask === other.mask
249
+ && this.flags === other.flags
250
+ && this.linearVelocity.equals(other.linearVelocity)
251
+ && this.angularVelocity.equals(other.angularVelocity)
252
+ && this.inverseInertiaLocal.equals(other.inverseInertiaLocal);
253
+ }
254
+
255
+ /**
256
+ * Hash over the same persistent state as {@link equals}. Equal bodies hash
257
+ * equal.
258
+ * @returns {number}
259
+ */
260
+ hash() {
261
+ let h = this.kind | 0;
262
+ h = (h * 31 + computeHashFloat(this.mass)) | 0;
263
+ h = (h * 31 + computeHashFloat(this.linearDamping)) | 0;
264
+ h = (h * 31 + computeHashFloat(this.angularDamping)) | 0;
265
+ h = (h * 31 + computeHashFloat(this.gravityScale)) | 0;
266
+ h = (h * 31 + (this.layer | 0)) | 0;
267
+ h = (h * 31 + (this.mask | 0)) | 0;
268
+ h = (h * 31 + (this.flags | 0)) | 0;
269
+ h = (h * 31 + this.linearVelocity.hash()) | 0;
270
+ h = (h * 31 + this.angularVelocity.hash()) | 0;
271
+ h = (h * 31 + this.inverseInertiaLocal.hash()) | 0;
272
+ return h;
273
+ }
228
274
  }
229
275
 
230
276
  /**
@@ -10,56 +10,56 @@
10
10
  * `-out_direction * return_value` to `position_b`) is the minimum
11
11
  * translation that produces separation.
12
12
  *
13
- * If the shapes do not overlap (or EPA degenerates on a tangent
14
- * contact), the return value is `0` and `out_direction` is left
15
- * untouched. Callers should treat 0 as "no penetration".
13
+ * If the shapes do not overlap, the return value is `0` and
14
+ * `out_direction` is left untouched. Callers should treat 0 as "no
15
+ * penetration".
16
16
  *
17
17
  * Sign convention matches the narrowphase's stored contact normal:
18
- * - `out_direction` ≡ "B → A" direction
19
- * - Negative of cast direction in shape_cast at the kiss point
20
- * - The outward normal of B's surface at the contact, pointing
21
- * toward A
18
+ * `out_direction` ≡ the "B → A" direction (B's outward surface normal at the
19
+ * contact, pointing toward A).
22
20
  *
23
- * Built on the existing GJK + EPA + PosedShape primitives — same
24
- * precision characteristics (essentially exact for sign-based supports
25
- * like cubes; asymptotic on curved supports like spheres near tangent,
26
- * where the polytope iteration cap leaves a small angular residual on
27
- * the direction).
21
+ * ## How it is computed (hardened)
28
22
  *
29
- * ## Non-convex support
23
+ * The query routes through the **same narrowphase contact dispatch the solver
24
+ * consumes** ({@link deepest_pair_penetration} → `dispatch_pair`) and reports
25
+ * the deepest contact. That makes it correct — not "correct sometimes" — for
26
+ * every shape pair the engine can build:
30
27
  *
31
- * Exactly **one** of the two shapes may be non-convex (heightmap,
32
- * mesh). The non-convex shape is decomposed into triangles overlapping
33
- * the convex shape's AABB (via the same machinery the narrowphase
34
- * uses), and per-triangle GJK + EPA is run; the deepest contact's
35
- * direction and depth are reported. Concave-vs-concave throws the
36
- * M×N triangle-pair cost is out of scope for this primitive (and is
37
- * also refused by the narrowphase for dynamic pairs).
28
+ * - **sphere / box / capsule pairs** exact closed-form solvers
29
+ * (`sphere_sphere`, `sphere_box`, `box_box` via SAT, `capsule_*`). Box-box
30
+ * in particular uses the true minimum-translation axis, so a small body
31
+ * resting on a large box reports the few-cm overlap through the near face
32
+ * rather than the metres-deep "exit through the far side" a centroid-seeded
33
+ * MPR portal used to return.
34
+ * - **general convex pairs** (anything without a closed form) → GJK + EPA,
35
+ * which is exact for polytopes and is only ever reached by polytope-like
36
+ * shapes here, since every curved primitive (sphere, capsule) has a closed
37
+ * form above.
38
+ * - **convex vs concave** (one of heightmap / mesh) → triangle decomposition
39
+ * over the convex AABB + the closed-form per-triangle solvers
40
+ * (`sphere_triangle`, `box_triangle`, `capsule_triangle`), deepest wins.
41
+ * These are bounded to each triangle's true 2-D extent, so the historical
42
+ * over-report on closed-mesh side faces (infinite-plane extrapolation) is
43
+ * gone.
38
44
  *
39
- * ## Non-convex precision limits
45
+ * ## Convex-vs-concave recovery (fully-tunnelled bodies)
40
46
  *
41
- * The concave path is a per-triangle half-space test (convex's deepest
42
- * point along −face_normal, compared to the triangle's plane). This
43
- * is exact for **heightmaps** adjacent triangles cover the
44
- * boundary cases, and the face normal IS the contact direction.
47
+ * The per-triangle closed-form solvers are intentionally one-sided: a convex
48
+ * shape that has crossed to the *inner* side of a surface produces no
49
+ * from-outside contact (the narrowphase won't shove a body deeper into the
50
+ * solid mid-step). For a standalone penetration / depenetration query that is
51
+ * the wrong answer — the shape *is* overlapping the solid and must be pushed
52
+ * back out. When the primary dispatch finds no contact for a convex-vs-concave
53
+ * pair, this function falls back to a half-space test
54
+ * ({@link concave_recovery_penetration}) that reports the outward push-out
55
+ * vector. This is exact for heightmap terrain and a valid (if not strictly
56
+ * minimal) recovery direction for closed meshes.
45
57
  *
46
- * For **closed meshes** the half-space test extrapolates each triangle
47
- * as an infinite plane, which can over-report depth on side faces
48
- * when the convex shape extends past a face's 2D extent. The
49
- * deepest-wins aggregation then picks a "false-deepest" face whose
50
- * direction may not be the geometrically optimal one. A closed-form
51
- * triangle-vs-X solver per primitive shape would fix this; until
52
- * then, the function reports *some* outward direction with positive
53
- * depth, which still resolves penetration over multiple iterations.
58
+ * Concave-vs-concave throws the M×N triangle-pair cost is out of scope (and
59
+ * is also refused by the narrowphase for dynamic pairs).
54
60
  *
55
- * Bodies fully inside the concave solid (or below a heightmap
56
- * surface) are correctly recovered: every face's deepest-inward
57
- * support point lands on the inward side, so the half-space test
58
- * fires, and the deepest face wins. The reported direction pushes
59
- * the body outward through that face.
60
- *
61
- * @param {Float64Array|number[]} out_direction length ≥ 3; receives
62
- * the unit separation direction (B → A) on penetration
61
+ * @param {Float64Array|number[]} out_direction length 3; receives the unit
62
+ * separation direction (B A) on penetration
63
63
  * @param {AbstractShape3D} shape_a in shape_a's local frame; may be concave
64
64
  * @param {{x:number,y:number,z:number}} position_a world position of A
65
65
  * @param {{x:number,y:number,z:number,w:number}} rotation_a world rotation of A
@@ -1 +1 @@
1
- {"version":3,"file":"compute_penetration.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/narrowphase/compute_penetration.js"],"names":[],"mappings":"AAkEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,mDAXW,YAAY,GAAC,MAAM,EAAE,wCAGrB;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,cAC5B;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,wCAErC;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,cAC5B;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,GACnC,MAAM,CA4BlB"}
1
+ {"version":3,"file":"compute_penetration.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/narrowphase/compute_penetration.js"],"names":[],"mappings":"AAyDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,mDAXW,YAAY,GAAC,MAAM,EAAE,wCAGrB;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,cAC5B;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,wCAErC;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,cAC5B;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,GACnC,MAAM,CAwClB"}