@woosh/meep-engine 2.145.0 → 2.147.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 (99) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +33 -3
  3. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  4. package/src/core/geom/3d/shape/HeightMapShape3D.js +486 -451
  5. package/src/engine/control/first-person/DESIGN_COLLISION.md +365 -352
  6. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +1 -14
  7. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  8. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +20 -8
  9. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  10. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +552 -546
  11. package/src/engine/control/first-person/TODO.md +13 -11
  12. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +8 -3
  13. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
  14. package/src/engine/control/first-person/abilities/LedgeGrab.js +213 -199
  15. package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -1
  16. package/src/engine/control/first-person/abilities/Mantle.js +195 -188
  17. package/src/engine/control/first-person/abilities/WallJump.d.ts.map +1 -1
  18. package/src/engine/control/first-person/abilities/WallJump.js +11 -3
  19. package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -1
  20. package/src/engine/control/first-person/abilities/WallRun.js +183 -163
  21. package/src/engine/control/first-person/collision/KinematicMover.d.ts.map +1 -1
  22. package/src/engine/control/first-person/collision/KinematicMover.js +634 -592
  23. package/src/engine/control/first-person/prototype_first_person_controller.js +1003 -901
  24. package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts +9 -0
  25. package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts.map +1 -1
  26. package/src/engine/control/first-person/sensors/FirstPersonSensors.js +87 -77
  27. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +8 -0
  28. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
  29. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +229 -196
  30. package/src/engine/ecs/EntityManager.d.ts +34 -11
  31. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  32. package/src/engine/ecs/EntityManager.js +71 -42
  33. package/src/engine/interpolation/BinaryInterpolationAdapter.d.ts.map +1 -0
  34. package/src/engine/interpolation/Interpoland.d.ts +48 -0
  35. package/src/engine/interpolation/Interpoland.d.ts.map +1 -0
  36. package/src/engine/interpolation/Interpoland.js +49 -0
  37. package/src/engine/interpolation/Interpolated.d.ts +101 -0
  38. package/src/engine/interpolation/Interpolated.d.ts.map +1 -0
  39. package/src/engine/interpolation/Interpolated.js +149 -0
  40. package/src/engine/{network/sim → interpolation}/InterpolationLog.d.ts +1 -1
  41. package/src/engine/interpolation/InterpolationLog.d.ts.map +1 -0
  42. package/src/engine/{network/sim → interpolation}/InterpolationLog.js +2 -2
  43. package/src/engine/interpolation/InterpolationSystem.d.ts +116 -0
  44. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -0
  45. package/src/engine/interpolation/InterpolationSystem.js +233 -0
  46. package/src/engine/interpolation/PoseInterpolationAdapter.d.ts +17 -0
  47. package/src/engine/interpolation/PoseInterpolationAdapter.d.ts.map +1 -0
  48. package/src/engine/interpolation/PoseInterpolationAdapter.js +61 -0
  49. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +35 -0
  50. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -0
  51. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +57 -0
  52. package/src/engine/interpolation/pose_interpoland.d.ts +18 -0
  53. package/src/engine/interpolation/pose_interpoland.d.ts.map +1 -0
  54. package/src/engine/interpolation/pose_interpoland.js +27 -0
  55. package/src/engine/network/NetworkSession.d.ts +2 -2
  56. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  57. package/src/engine/network/NetworkSession.js +2 -2
  58. package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts +1 -1
  59. package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts.map +1 -1
  60. package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +1 -1
  61. package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts +1 -1
  62. package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts.map +1 -1
  63. package/src/engine/network/adapters/TransformInterpolationAdapter.js +1 -1
  64. package/src/engine/network/adapters/Vector3InterpolationAdapter.d.ts +1 -1
  65. package/src/engine/network/adapters/Vector3InterpolationAdapter.d.ts.map +1 -1
  66. package/src/engine/network/adapters/Vector3InterpolationAdapter.js +1 -1
  67. package/src/engine/physics/INTEPOLATION_SYSTEM_PLAN.md +287 -0
  68. package/src/engine/physics/PLAN.md +944 -809
  69. package/src/engine/physics/body/BodyStorage.d.ts +9 -0
  70. package/src/engine/physics/body/BodyStorage.d.ts.map +1 -1
  71. package/src/engine/physics/body/BodyStorage.js +23 -0
  72. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
  73. package/src/engine/physics/broadphase/generate_pairs.js +7 -0
  74. package/src/engine/physics/ccd/linear_sweep.d.ts +97 -0
  75. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -0
  76. package/src/engine/physics/ccd/linear_sweep.js +238 -0
  77. package/src/engine/physics/ecs/PhysicsSystem.d.ts +82 -3
  78. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  79. package/src/engine/physics/ecs/PhysicsSystem.js +227 -8
  80. package/src/engine/physics/ecs/RigidBodyFlags.d.ts +6 -0
  81. package/src/engine/physics/ecs/RigidBodyFlags.d.ts.map +1 -1
  82. package/src/engine/physics/ecs/RigidBodyFlags.js +6 -0
  83. package/src/engine/physics/narrowphase/box_triangle_contact.js +814 -811
  84. package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -1
  85. package/src/engine/physics/narrowphase/compute_penetration.js +325 -323
  86. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts +27 -8
  87. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts.map +1 -1
  88. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.js +235 -204
  89. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  90. package/src/engine/physics/narrowphase/narrowphase_step.js +97 -13
  91. package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -1
  92. package/src/engine/physics/queries/overlap_shape.js +185 -183
  93. package/src/engine/simulation/Ticker.d.ts +14 -0
  94. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  95. package/src/engine/simulation/Ticker.js +136 -1
  96. package/src/engine/network/sim/BinaryInterpolationAdapter.d.ts.map +0 -1
  97. package/src/engine/network/sim/InterpolationLog.d.ts.map +0 -1
  98. /package/src/engine/{network/sim → interpolation}/BinaryInterpolationAdapter.d.ts +0 -0
  99. /package/src/engine/{network/sim → interpolation}/BinaryInterpolationAdapter.js +0 -0
@@ -61,6 +61,7 @@ export class BodyStorage {
61
61
  __awake_count: number;
62
62
  __free_heap: Uint32Array;
63
63
  __free_count: number;
64
+ __entity_to_index: Map<any, any>;
64
65
  /**
65
66
  * Currently allocated body count (live, regardless of awake/sleeping).
66
67
  * @returns {number}
@@ -109,6 +110,14 @@ export class BodyStorage {
109
110
  * @returns {number} entity for the body, or -1 if the slot is free.
110
111
  */
111
112
  entity_at(index: number): number;
113
+ /**
114
+ * Body index for `entity`, or {@link BODY_INDEX_ABSENT} if no live body owns
115
+ * it. O(1) reverse of {@link entity_at} — the lookup callers use on the
116
+ * link / attach / joint paths instead of scanning the slot table.
117
+ * @param {number} entity
118
+ * @returns {number}
119
+ */
120
+ index_of_entity(entity: number): number;
112
121
  /**
113
122
  * @param {number} index
114
123
  * @returns {number}
@@ -1 +1 @@
1
- {"version":3,"file":"BodyStorage.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/body/BodyStorage.js"],"names":[],"mappings":"AA2BA;;;;;;GAMG;AACH,oCAJW,MAAM,cACN,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,sCAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,2CAHW,MAAM,GACJ,MAAM,CAIlB;AAlCD;;;;GAIG;AACH,gCAFU,MAAM,CAEoB;AA+BpC;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAEI;;;OAGG;IACH,+BAFW,MAAM,EA+BhB;IAxBG,mBAAqB;IAGrB,gBAAgB;IAEhB,uBAAqC;IACrC,0BAAwC;IACxC,oBAAkC;IAClC,qBAAmC;IAGnC,oBAAkC;IAGlC,0BAAwC;IACxC,wBAAsC;IACtC,sBAAsB;IAGtB,yBAAuC;IACvC,qBAAqB;IAMzB;;;OAGG;IACH,mBAEC;IAED;;;OAGG;IACH,uBAEC;IAED;;;OAGG;IACH,0BAEC;IAED;;;;OAIG;IACH,8BAEC;IAED;;;;;;;OAOG;IACH,iBAHW,MAAM,GACJ,MAAM,CAyBlB;IAED;;;;;OAKG;IACH,qBAFW,MAAM,QAoBhB;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,OAAO,CAWnB;IAED;;;OAGG;IACH,iBAHW,MAAM,GACJ,MAAM,CAOlB;IAED;;;OAGG;IACH,qBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,eAHW,MAAM,GACJ,QAAQ,GAAC,MAAM,CAI3B;IAED;;;OAGG;IACH,gBAHW,MAAM,QACN,QAAQ,GAAC,MAAM,QAIzB;IAED;;;OAGG;IACH,gBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,iBAHW,MAAM,SACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;;OAIG;IACH,YAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,kBAFW,MAAM,QAShB;IAED;;;OAGG;IACH,qBAFW,MAAM,QAShB;IAED;;;;OAIG;IACH,0BAOC;IAED;;OAEG;IACH,eAiCC;IAID;;;OAGG;IACH,oBAgBC;IAED;;;OAGG;IACH,mBAqBC;CACJ;yBAzawB,oBAAoB"}
1
+ {"version":3,"file":"BodyStorage.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/body/BodyStorage.js"],"names":[],"mappings":"AA2BA;;;;;;GAMG;AACH,oCAJW,MAAM,cACN,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,sCAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,2CAHW,MAAM,GACJ,MAAM,CAIlB;AAlCD;;;;GAIG;AACH,gCAFU,MAAM,CAEoB;AA+BpC;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAEI;;;OAGG;IACH,+BAFW,MAAM,EAqChB;IA9BG,mBAAqB;IAGrB,gBAAgB;IAEhB,uBAAqC;IACrC,0BAAwC;IACxC,oBAAkC;IAClC,qBAAmC;IAGnC,oBAAkC;IAGlC,0BAAwC;IACxC,wBAAsC;IACtC,sBAAsB;IAGtB,yBAAuC;IACvC,qBAAqB;IAMrB,iCAAkC;IAMtC;;;OAGG;IACH,mBAEC;IAED;;;OAGG;IACH,uBAEC;IAED;;;OAGG;IACH,0BAEC;IAED;;;;OAIG;IACH,8BAEC;IAED;;;;;;;OAOG;IACH,iBAHW,MAAM,GACJ,MAAM,CA0BlB;IAED;;;;;OAKG;IACH,qBAFW,MAAM,QAwBhB;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,OAAO,CAWnB;IAED;;;OAGG;IACH,iBAHW,MAAM,GACJ,MAAM,CAOlB;IAED;;;;;;OAMG;IACH,wBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;OAGG;IACH,qBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,eAHW,MAAM,GACJ,QAAQ,GAAC,MAAM,CAI3B;IAED;;;OAGG;IACH,gBAHW,MAAM,QACN,QAAQ,GAAC,MAAM,QAIzB;IAED;;;OAGG;IACH,gBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,iBAHW,MAAM,SACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GACJ,OAAO,CAInB;IAED;;;;OAIG;IACH,YAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,kBAFW,MAAM,QAShB;IAED;;;OAGG;IACH,qBAFW,MAAM,QAShB;IAED;;;;OAIG;IACH,0BAOC;IAED;;OAEG;IACH,eAiCC;IAID;;;OAGG;IACH,oBAgBC;IAED;;;OAGG;IACH,mBAqBC;CACJ;yBAhcwB,oBAAoB"}
@@ -106,6 +106,12 @@ export class BodyStorage {
106
106
  this.__free_heap = new Uint32Array(cap);
107
107
  this.__free_count = 0;
108
108
 
109
+ // Entity → body-index map (one body per entity). Keeps {@link
110
+ // index_of_entity} O(1) instead of an O(N) scan over the slot table on
111
+ // every collider attach / detach and joint link. Maintained on
112
+ // allocate / free; never grows with the typed arrays (a plain Map).
113
+ this.__entity_to_index = new Map();
114
+
109
115
  // Initialise reverse map to BODY_INDEX_ABSENT.
110
116
  this.__awake_pos.fill(BODY_INDEX_ABSENT);
111
117
  }
@@ -167,6 +173,7 @@ export class BodyStorage {
167
173
  this.__kinds[index] = BodyKind.Dynamic;
168
174
  this.__flags[index] = 0;
169
175
  this.__alive[index] = 1;
176
+ this.__entity_to_index.set(entity, index);
170
177
 
171
178
  // Insert into awake set.
172
179
  const awake_pos = this.__awake_count++;
@@ -196,6 +203,10 @@ export class BodyStorage {
196
203
 
197
204
  this.__alive[index] = 0;
198
205
 
206
+ // Drop the entity → index mapping (the slot still holds the old entity
207
+ // value until reallocation, so delete by it now while it's valid).
208
+ this.__entity_to_index.delete(this.__entities[index]);
209
+
199
210
  // Bump generation; wraps mod 256.
200
211
  this.__generations[index] = (this.__generations[index] + 1) & GENERATION_MASK;
201
212
 
@@ -229,6 +240,18 @@ export class BodyStorage {
229
240
  return this.__entities[index];
230
241
  }
231
242
 
243
+ /**
244
+ * Body index for `entity`, or {@link BODY_INDEX_ABSENT} if no live body owns
245
+ * it. O(1) reverse of {@link entity_at} — the lookup callers use on the
246
+ * link / attach / joint paths instead of scanning the slot table.
247
+ * @param {number} entity
248
+ * @returns {number}
249
+ */
250
+ index_of_entity(entity) {
251
+ const idx = this.__entity_to_index.get(entity);
252
+ return idx === undefined ? BODY_INDEX_ABSENT : idx;
253
+ }
254
+
232
255
  /**
233
256
  * @param {number} index
234
257
  * @returns {number}
@@ -1 +1 @@
1
- {"version":3,"file":"generate_pairs.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/broadphase/generate_pairs.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,uIARW,MAAM,MAAM;IAAC,QAAQ,WAAW;IAAC,SAAS,YAAY;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,+CAElF,MAAM,OAAO,MAAM,KAAK,OAAO,QAsEhD"}
1
+ {"version":3,"file":"generate_pairs.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/broadphase/generate_pairs.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,uIARW,MAAM,MAAM;IAAC,QAAQ,WAAW;IAAC,SAAS,YAAY;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,+CAElF,MAAM,OAAO,MAAM,KAAK,OAAO,QA4EhD"}
@@ -1,3 +1,4 @@
1
+ import { assert } from "../../../core/assert.js";
1
2
  import { bvh_query_user_data_overlaps_aabb } from "../../../core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.js";
2
3
 
3
4
  const scratch_aabb = new Float64Array(6);
@@ -65,6 +66,11 @@ export function generate_pairs(
65
66
  dynamic_bvh,
66
67
  scratch_aabb
67
68
  );
69
+ // The BVH query writes leaves unconditionally — at capacity it both
70
+ // drops leaves (typed-array OOB writes no-op) AND returns a count
71
+ // past the buffer end, so the loop below would read `undefined`
72
+ // candidates and build garbage pairs. Guard the buffer size.
73
+ assert.lessThan(n, candidates.length, 'generate_pairs: dynamic broadphase overflowed the candidate buffer');
68
74
  for (let c = 0; c < n; c++) {
69
75
  const other = candidates[c];
70
76
  if (other === my_packed) continue;
@@ -85,6 +91,7 @@ export function generate_pairs(
85
91
  static_bvh,
86
92
  scratch_aabb
87
93
  );
94
+ assert.lessThan(n, candidates.length, 'generate_pairs: static broadphase overflowed the candidate buffer');
88
95
  for (let c = 0; c < n; c++) {
89
96
  const other = candidates[c];
90
97
  const idA = my_packed < other ? my_packed : other;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Sweep `shape` (held at the fixed `rotation`) linearly from `(fx,fy,fz)` to
3
+ * `(tx,ty,tz)` through both broadphase trees, ignoring colliders owned by
4
+ * `exclude_entity`.
5
+ *
6
+ * Returns the traversable fraction of the segment in `[0, 1]`: `1` means the
7
+ * path is clear; a value `< 1` means a blocker was hit at that fraction and
8
+ * `result` has been filled — `result.position` is the swept-shape centre at
9
+ * first contact, `result.normal` is the blocker's outward surface normal
10
+ * (B → A), `result.entity` / `result.body_id` the blocker.
11
+ *
12
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
13
+ * @param {import("../../../core/geom/3d/shape/AbstractShape3D.js").AbstractShape3D} shape
14
+ * @param {{x:number,y:number,z:number,w:number}} rotation fixed orientation
15
+ * @param {number} fx
16
+ * @param {number} fy
17
+ * @param {number} fz
18
+ * @param {number} tx
19
+ * @param {number} ty
20
+ * @param {number} tz
21
+ * @param {number} exclude_entity entity to ignore (the swept body itself)
22
+ * @param {PhysicsSurfacePoint} result populated on hit; untouched on a clear path
23
+ * @returns {number} traversable fraction in [0, 1]
24
+ */
25
+ export function ccd_sweep_segment(system: import("../ecs/PhysicsSystem.js").PhysicsSystem, shape: import("../../../core/geom/3d/shape/AbstractShape3D.js").AbstractShape3D, rotation: {
26
+ x: number;
27
+ y: number;
28
+ z: number;
29
+ w: number;
30
+ }, fx: number, fy: number, fz: number, tx: number, ty: number, tz: number, exclude_entity: number, result: PhysicsSurfacePoint): number;
31
+ /**
32
+ * Post-solve continuous-collision pass over the awake set. For each awake
33
+ * Dynamic body flagged {@link RigidBodyFlags.CCD} that moved more than
34
+ * {@link CCD_MIN_SWEEP_DISTANCE} this step, sweep its primary collider along the
35
+ * step's net translation and stop it at the first blocker (clamp pose + remove
36
+ * inbound normal velocity).
37
+ *
38
+ * Start-of-step positions are captured into `system.__ccd_start_pos` (3 doubles
39
+ * per body index) before the substep loop; this pass reads the final pose from
40
+ * the live Transform. Iterates the awake list in storage order, so it is
41
+ * deterministic.
42
+ *
43
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
44
+ */
45
+ export function ccd_resolve(system: import("../ecs/PhysicsSystem.js").PhysicsSystem): void;
46
+ /**
47
+ * Continuous collision detection — linear shape-cast (the "speculative margin
48
+ * floor, upgraded to an opt-in per-body sweep" item from PLAN.md).
49
+ *
50
+ * The discrete pipeline detects contacts by overlap at step boundaries: a body
51
+ * that moves more than its own thickness in one step can start a step on one
52
+ * side of a thin wall and end on the other, never overlapping it on any frame
53
+ * the broadphase samples — it tunnels. The speculative fat-AABB margin
54
+ * (`compute_fat_world_aabb`) covers moderate speeds; genuinely fast movers
55
+ * (bullets, dropped debris, a body flung by an explosion) need a swept test.
56
+ *
57
+ * Approach (Box2D `b2_continuousPhysics`-style conservative advancement): after
58
+ * the substep solver has produced each body's final pose, sweep a CCD-flagged
59
+ * fast mover's primary collider along its NET step translation
60
+ * (start-of-step → final pose) using the existing {@link shape_cast} TOI engine.
61
+ * On the first blocker, clamp the body to the contact pose and remove the
62
+ * inbound normal component of its velocity (an inelastic stop) — the next
63
+ * discrete step then resolves the now-touching contact with the real
64
+ * material / restitution.
65
+ *
66
+ * Scope (v1, deliberate):
67
+ * - LINEAR sweep only: the orientation is held fixed through the sweep (the
68
+ * per-step angular motion is small at the fixed-step rate).
69
+ * - PRIMARY same-entity collider: a compound body sweeps its first collider;
70
+ * child-entity colliders (whose transform is synced outside the step) are
71
+ * not swept.
72
+ * - EXACT against static geometry (the static BVH holds tight, never-moved
73
+ * leaves); APPROXIMATE against other dynamic bodies (they have moved this
74
+ * step too, but the sweep sees their start-of-step broadphase AABBs) — the
75
+ * speculative-margin floor for the dynamic-vs-dynamic case.
76
+ * - The CCD stop itself is inelastic; the impact does not bounce. Restitution
77
+ * applies on the next discrete contact.
78
+ */
79
+ /**
80
+ * Minimum per-step displacement (metres) before a CCD sweep is worth running.
81
+ * Its ONLY job is to skip a body that didn't meaningfully move — a resting /
82
+ * sleeping-soon body whose displacement is sub-millimetre jitter — which avoids
83
+ * a degenerate zero-length sweep and saves the query cost.
84
+ *
85
+ * It must NOT be tied to the body's own size. Tunnelling risk is governed by the
86
+ * *obstacle's* thickness, not the mover's: a 2 m sphere drifting at 0.5 m/step
87
+ * still passes clean through a 1 cm floor. A small absolute slop catches that;
88
+ * gating on a fraction of the body's extent would (wrongly) wait until the body
89
+ * moved more than its own radius and miss every thin-obstacle tunnel below that
90
+ * speed. The discrete narrowphase still owns any obstacle thicker than a body's
91
+ * per-step move, so CCD reliably prevents tunnelling of obstacles thicker than
92
+ * this slop.
93
+ * @type {number}
94
+ */
95
+ export const CCD_MIN_SWEEP_DISTANCE: number;
96
+ import { PhysicsSurfacePoint } from "../queries/PhysicsSurfacePoint.js";
97
+ //# sourceMappingURL=linear_sweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear_sweep.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ccd/linear_sweep.js"],"names":[],"mappings":"AA8FA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,0CAbW,OAAO,yBAAyB,EAAE,aAAa,SAC/C,OAAO,gDAAgD,EAAE,eAAe,YACxE;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,MACrC,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,kBACN,MAAM,UACN,mBAAmB,GACjB,MAAM,CAmClB;AAED;;;;;;;;;;;;;GAaG;AACH,oCAFW,OAAO,yBAAyB,EAAE,aAAa,QAwEzD;AAvOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,qCAFU,MAAM,CAE2B;oCArDP,mCAAmC"}
@@ -0,0 +1,238 @@
1
+ import { Ray3 } from "../../../core/geom/3d/ray/Ray3.js";
2
+ import { BodyKind } from "../ecs/BodyKind.js";
3
+ import { RigidBodyFlags } from "../ecs/RigidBodyFlags.js";
4
+ import { PhysicsSurfacePoint } from "../queries/PhysicsSurfacePoint.js";
5
+ import { shape_cast } from "../queries/shape_cast.js";
6
+
7
+ /**
8
+ * Continuous collision detection — linear shape-cast (the "speculative margin
9
+ * floor, upgraded to an opt-in per-body sweep" item from PLAN.md).
10
+ *
11
+ * The discrete pipeline detects contacts by overlap at step boundaries: a body
12
+ * that moves more than its own thickness in one step can start a step on one
13
+ * side of a thin wall and end on the other, never overlapping it on any frame
14
+ * the broadphase samples — it tunnels. The speculative fat-AABB margin
15
+ * (`compute_fat_world_aabb`) covers moderate speeds; genuinely fast movers
16
+ * (bullets, dropped debris, a body flung by an explosion) need a swept test.
17
+ *
18
+ * Approach (Box2D `b2_continuousPhysics`-style conservative advancement): after
19
+ * the substep solver has produced each body's final pose, sweep a CCD-flagged
20
+ * fast mover's primary collider along its NET step translation
21
+ * (start-of-step → final pose) using the existing {@link shape_cast} TOI engine.
22
+ * On the first blocker, clamp the body to the contact pose and remove the
23
+ * inbound normal component of its velocity (an inelastic stop) — the next
24
+ * discrete step then resolves the now-touching contact with the real
25
+ * material / restitution.
26
+ *
27
+ * Scope (v1, deliberate):
28
+ * - LINEAR sweep only: the orientation is held fixed through the sweep (the
29
+ * per-step angular motion is small at the fixed-step rate).
30
+ * - PRIMARY same-entity collider: a compound body sweeps its first collider;
31
+ * child-entity colliders (whose transform is synced outside the step) are
32
+ * not swept.
33
+ * - EXACT against static geometry (the static BVH holds tight, never-moved
34
+ * leaves); APPROXIMATE against other dynamic bodies (they have moved this
35
+ * step too, but the sweep sees their start-of-step broadphase AABBs) — the
36
+ * speculative-margin floor for the dynamic-vs-dynamic case.
37
+ * - The CCD stop itself is inelastic; the impact does not bounce. Restitution
38
+ * applies on the next discrete contact.
39
+ */
40
+
41
+ /**
42
+ * Minimum per-step displacement (metres) before a CCD sweep is worth running.
43
+ * Its ONLY job is to skip a body that didn't meaningfully move — a resting /
44
+ * sleeping-soon body whose displacement is sub-millimetre jitter — which avoids
45
+ * a degenerate zero-length sweep and saves the query cost.
46
+ *
47
+ * It must NOT be tied to the body's own size. Tunnelling risk is governed by the
48
+ * *obstacle's* thickness, not the mover's: a 2 m sphere drifting at 0.5 m/step
49
+ * still passes clean through a 1 cm floor. A small absolute slop catches that;
50
+ * gating on a fraction of the body's extent would (wrongly) wait until the body
51
+ * moved more than its own radius and miss every thin-obstacle tunnel below that
52
+ * speed. The discrete narrowphase still owns any obstacle thicker than a body's
53
+ * per-step move, so CCD reliably prevents tunnelling of obstacles thicker than
54
+ * this slop.
55
+ * @type {number}
56
+ */
57
+ export const CCD_MIN_SWEEP_DISTANCE = 1e-3;
58
+
59
+ /**
60
+ * Impact distances at or below this (metres) mean the body was already
61
+ * overlapping the target at the start of the step — i.e. a resting / sliding
62
+ * contact the discrete solver owns, not a tunnel. The sweep ignores these so
63
+ * CCD never clamps a body to a surface it is merely sitting or sliding on.
64
+ * @type {number}
65
+ */
66
+ const CCD_INITIAL_OVERLAP_EPS = 1e-6;
67
+
68
+ // ── Module scratch ──────────────────────────────────────────────────────────
69
+ // CCD runs inside the step loop; reuse buffers so the pass allocates nothing.
70
+
71
+ /** Swept ray, re-seeded per sweep (origin, unit direction, tMax). */
72
+ const _ray = new Ray3();
73
+
74
+ /** Sweep result reused across bodies inside {@link ccd_resolve}. */
75
+ const _hit = new PhysicsSurfacePoint();
76
+
77
+ /**
78
+ * Entity whose colliders the current sweep must ignore (the moving body's own).
79
+ * Module-scoped so {@link _exclude_self} stays a stable, non-allocating
80
+ * reference handed to {@link shape_cast}.
81
+ * @type {number}
82
+ */
83
+ let _exclude_entity = -1;
84
+
85
+ /**
86
+ * Self-exclusion filter for the sweep: drop candidates owned by the moving
87
+ * body's own entity (otherwise the body would "hit itself" at `t = 0`).
88
+ * @param {number} entity
89
+ * @returns {boolean}
90
+ */
91
+ function _exclude_self(entity) {
92
+ return entity !== _exclude_entity;
93
+ }
94
+
95
+ /**
96
+ * Sweep `shape` (held at the fixed `rotation`) linearly from `(fx,fy,fz)` to
97
+ * `(tx,ty,tz)` through both broadphase trees, ignoring colliders owned by
98
+ * `exclude_entity`.
99
+ *
100
+ * Returns the traversable fraction of the segment in `[0, 1]`: `1` means the
101
+ * path is clear; a value `< 1` means a blocker was hit at that fraction and
102
+ * `result` has been filled — `result.position` is the swept-shape centre at
103
+ * first contact, `result.normal` is the blocker's outward surface normal
104
+ * (B → A), `result.entity` / `result.body_id` the blocker.
105
+ *
106
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
107
+ * @param {import("../../../core/geom/3d/shape/AbstractShape3D.js").AbstractShape3D} shape
108
+ * @param {{x:number,y:number,z:number,w:number}} rotation fixed orientation
109
+ * @param {number} fx
110
+ * @param {number} fy
111
+ * @param {number} fz
112
+ * @param {number} tx
113
+ * @param {number} ty
114
+ * @param {number} tz
115
+ * @param {number} exclude_entity entity to ignore (the swept body itself)
116
+ * @param {PhysicsSurfacePoint} result populated on hit; untouched on a clear path
117
+ * @returns {number} traversable fraction in [0, 1]
118
+ */
119
+ export function ccd_sweep_segment(
120
+ system, shape, rotation,
121
+ fx, fy, fz, tx, ty, tz,
122
+ exclude_entity, result,
123
+ ) {
124
+ const dx = tx - fx;
125
+ const dy = ty - fy;
126
+ const dz = tz - fz;
127
+ const len = Math.sqrt(dx * dx + dy * dy + dz * dz);
128
+ if (len === 0) return 1;
129
+
130
+ const inv = 1 / len;
131
+ _ray[0] = fx; _ray[1] = fy; _ray[2] = fz;
132
+ _ray[3] = dx * inv; _ray[4] = dy * inv; _ray[5] = dz * inv;
133
+ _ray[6] = len; // tMax in metres — direction is unit length
134
+
135
+ _exclude_entity = exclude_entity;
136
+ if (!shape_cast(system, _ray, shape, rotation, result, _exclude_self)) {
137
+ return 1;
138
+ }
139
+
140
+ // An impact at t ≈ 0 means the swept shape was already overlapping the
141
+ // target at the segment start — a resting / sliding contact, not a tunnel.
142
+ // The discrete solver owns it; clamping here would freeze a body onto a
143
+ // surface it is sitting or sliding on. Treat as a clear path.
144
+ if (result.t <= CCD_INITIAL_OVERLAP_EPS) return 1;
145
+
146
+ // result.t is the impact distance along the unit direction; normalise to a
147
+ // segment fraction. shape_cast reports the just-SEPARATING side of its
148
+ // bisection, so the swept shape at `result.t` is provably not overlapping —
149
+ // safe to place the body there.
150
+ const frac = result.t * inv;
151
+ return frac < 1 ? frac : 1;
152
+ }
153
+
154
+ /**
155
+ * Post-solve continuous-collision pass over the awake set. For each awake
156
+ * Dynamic body flagged {@link RigidBodyFlags.CCD} that moved more than
157
+ * {@link CCD_MIN_SWEEP_DISTANCE} this step, sweep its primary collider along the
158
+ * step's net translation and stop it at the first blocker (clamp pose + remove
159
+ * inbound normal velocity).
160
+ *
161
+ * Start-of-step positions are captured into `system.__ccd_start_pos` (3 doubles
162
+ * per body index) before the substep loop; this pass reads the final pose from
163
+ * the live Transform. Iterates the awake list in storage order, so it is
164
+ * deterministic.
165
+ *
166
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
167
+ */
168
+ export function ccd_resolve(system) {
169
+ const storage = system.storage;
170
+ const count = storage.awake_count;
171
+ const lists = system.__body_collider_lists;
172
+ const start = system.__ccd_start_pos;
173
+ const CCD = RigidBodyFlags.CCD;
174
+
175
+ for (let i = 0; i < count; i++) {
176
+ const idx = storage.awake_at(i);
177
+
178
+ const rb = system.__bodies[idx];
179
+ if (rb === undefined) continue;
180
+ if ((rb.flags & CCD) === 0) continue;
181
+ if (rb.kind !== BodyKind.Dynamic) continue;
182
+
183
+ const list = lists[idx];
184
+ if (list === undefined || list.length === 0) continue;
185
+ const primary = list[0];
186
+ const tr = primary.transform;
187
+ const p = tr.position;
188
+
189
+ const base = idx * 3;
190
+ const sx = start[base];
191
+ const sy = start[base + 1];
192
+ const sz = start[base + 2];
193
+ const ex = p[0];
194
+ const ey = p[1];
195
+ const ez = p[2];
196
+
197
+ const dx = ex - sx;
198
+ const dy = ey - sy;
199
+ const dz = ez - sz;
200
+ const disp2 = dx * dx + dy * dy + dz * dz;
201
+ if (disp2 === 0) continue;
202
+
203
+ // Motion gate: skip a body that barely moved (resting / negligible
204
+ // jitter) — avoids a degenerate sweep and the query cost. NOT tied to
205
+ // body size: a body tunnels a thin obstacle at speeds well below its
206
+ // own extent, so the threshold is a small absolute slop. A resting /
207
+ // sliding body that does clear it is still safe — the sweep ignores its
208
+ // initial-overlap contact (see CCD_INITIAL_OVERLAP_EPS).
209
+ if (disp2 <= CCD_MIN_SWEEP_DISTANCE * CCD_MIN_SWEEP_DISTANCE) continue;
210
+
211
+ const shape = primary.collider.shape;
212
+ const frac = ccd_sweep_segment(
213
+ system, shape, tr.rotation,
214
+ sx, sy, sz, ex, ey, ez,
215
+ primary.entity, _hit,
216
+ );
217
+ if (frac >= 1) continue; // clear path — no tunnelling this step
218
+
219
+ // Clamp the body to the first-contact pose (swept-shape centre at the
220
+ // TOI), so it cannot end the step on the far side of the blocker.
221
+ const hp = _hit.position;
222
+ p.set(hp[0], hp[1], hp[2]);
223
+
224
+ // Remove the inbound normal component of velocity (inelastic stop).
225
+ // `_hit.normal` is the blocker's outward surface normal; the body is
226
+ // moving into it (v·n < 0). Zeroing that component leaves the tangential
227
+ // slide intact and never adds energy. The next discrete step applies the
228
+ // real restitution / friction on the established contact.
229
+ const n = _hit.normal;
230
+ const lv = rb.linearVelocity;
231
+ const vn = lv[0] * n[0] + lv[1] * n[1] + lv[2] * n[2];
232
+ if (vn < 0) {
233
+ lv[0] -= vn * n[0];
234
+ lv[1] -= vn * n[1];
235
+ lv[2] -= vn * n[2];
236
+ }
237
+ }
238
+ }
@@ -196,6 +196,21 @@ export class PhysicsSystem extends System<any, any, any, any, any> {
196
196
  * @type {Float64Array}
197
197
  */
198
198
  __pseudo_velocity: Float64Array;
199
+ /**
200
+ * Master switch for the continuous-collision pass. When false the
201
+ * {@link RigidBodyFlags.CCD} flag is ignored and no swept queries run.
202
+ * @type {boolean}
203
+ */
204
+ ccdEnabled: boolean;
205
+ /**
206
+ * Start-of-step world positions for CCD-flagged bodies — 3 doubles per
207
+ * body slot index (`[x, y, z]`). Captured in Stage 1 before the substep
208
+ * loop integrates poses; the CCD pass ({@link ccd_resolve}) sweeps from
209
+ * here to the final pose. Grows to `storage.high_water_mark * 3`; only
210
+ * CCD-flagged slots are written each step.
211
+ * @type {Float64Array}
212
+ */
213
+ __ccd_start_pos: Float64Array;
199
214
  /**
200
215
  * Bound reference to {@link __pair_filter} so we hand the same
201
216
  * callable to {@link generate_pairs} each step without per-step
@@ -203,6 +218,23 @@ export class PhysicsSystem extends System<any, any, any, any, any> {
203
218
  * @private
204
219
  */
205
220
  private __pair_filter_bound;
221
+ /**
222
+ * Optional shared interpolation log to produce per-step pose snapshots
223
+ * into (the {@link InterpolationSystem}'s log). When set — and only then —
224
+ * each fixedUpdate restores every awake {@link Interpolated} body's live
225
+ * components from the previous tick (undoing render-time interpolation so
226
+ * the sim reads authoritative state), then records the post-step state
227
+ * under the current `entityManager.fixedStepTick`. Null on a headless /
228
+ * non-rendering world, where the producer work is skipped entirely.
229
+ * @type {InterpolationLog|null}
230
+ */
231
+ interpolationLog: InterpolationLog | null;
232
+ /**
233
+ * Reusable decode buffer for restoring interpolated snapshots.
234
+ * @private
235
+ * @type {BinaryBuffer}
236
+ */
237
+ private __interp_scratch;
206
238
  /**
207
239
  * Symmetric layer/mask check + optional user callback. Called per
208
240
  * candidate pair during broadphase. Returns `true` to accept the pair.
@@ -322,9 +354,9 @@ export class PhysicsSystem extends System<any, any, any, any, any> {
322
354
  */
323
355
  detach_collider(body_entity: number, collider: Collider): void;
324
356
  /**
325
- * Linear scan over body slots looking for the one whose entity matches.
326
- * O(N) where N is the live body countonly called on the link/unlink
327
- * paths, not during simulation, so the scan cost is bounded.
357
+ * Resolve an entity to its body index, or -1 if no live body owns it.
358
+ * O(1) via {@link BodyStorage#index_of_entity}'s entity index mapused
359
+ * on the collider attach / detach and joint link paths.
328
360
  *
329
361
  * @private
330
362
  * @param {number} entity
@@ -453,6 +485,32 @@ export class PhysicsSystem extends System<any, any, any, any, any> {
453
485
  y: number;
454
486
  z: number;
455
487
  }): void;
488
+ /**
489
+ * Teleport a body to a new pose, bypassing integration: writes the body's
490
+ * Transform directly and wakes it. For an interpolated body this also flags a
491
+ * render `snap` on its {@link Interpolated} component, so the producer keeps
492
+ * this pose (rather than restoring the previous tick over it) and the
493
+ * renderer shows the new pose without sliding across the jump.
494
+ *
495
+ * This is the authoritative way to reposition an interpolated body — a raw
496
+ * `Transform` write would be undone by the per-step restore. Velocity is left
497
+ * as-is; zero it via {@link setLinearVelocity} if the teleport should also
498
+ * stop the body.
499
+ *
500
+ * @param {RigidBody} rigidBody
501
+ * @param {Vector3|{x:number,y:number,z:number}} position world position
502
+ * @param {Quaternion|{x:number,y:number,z:number,w:number}} rotation world unit-quaternion rotation
503
+ */
504
+ setPose(rigidBody: RigidBody, position: Vector3 | {
505
+ x: number;
506
+ y: number;
507
+ z: number;
508
+ }, rotation: Quaternion | {
509
+ x: number;
510
+ y: number;
511
+ z: number;
512
+ w: number;
513
+ }): void;
456
514
  /**
457
515
  * Force the body awake. Static bodies are ignored.
458
516
  * @param {RigidBody} rigidBody
@@ -659,6 +717,27 @@ export class PhysicsSystem extends System<any, any, any, any, any> {
659
717
  * @private
660
718
  */
661
719
  private __dispatch_contact_events;
720
+ /**
721
+ * Producer — restore pass. At the top of a fixed step, reset every awake
722
+ * {@link Interpolated} body's live components to their authoritative state
723
+ * from the previous tick's snapshot, undoing any render-time interpolation
724
+ * the {@link InterpolationSystem} wrote between frames so the sim integrates
725
+ * from truth, not an interpolated pose. A body with no previous snapshot
726
+ * (first step ever, or just woken) is left as-is — its live state is already
727
+ * authoritative. No-op unless {@link interpolationLog} is wired.
728
+ * @private
729
+ */
730
+ private __interp_restore;
731
+ /**
732
+ * Producer — record pass. At the end of a fixed step, snapshot every awake
733
+ * {@link Interpolated} body's live components into the shared log under the
734
+ * current `entityManager.fixedStepTick`. The render-time
735
+ * {@link InterpolationSystem} blends consecutive ticks from these snapshots.
736
+ * Only awake (moving) bodies are recorded, so the log stays sparse. No-op
737
+ * unless {@link interpolationLog} is wired.
738
+ * @private
739
+ */
740
+ private __interp_record;
662
741
  fixedUpdate(dt: any): void;
663
742
  /**
664
743
  * @readonly
@@ -1 +1 @@
1
- {"version":3,"file":"PhysicsSystem.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/PhysicsSystem.js"],"names":[],"mappings":"AA+DA;;;;;;;;;;;;;;;;GAgBG;AACH;IAEI,cA6NC;IA1NG,sDAA0C;IAE1C,kKAIC;IAED;;OAEG;IACH,SAFU,WAAW,CAEW;IAEhC;;OAEG;IACH,WAFU,GAAG,CAEa;IAE1B;;OAEG;IACH,YAFU,GAAG,CAEc;IAE3B;;;OAGG;IACH,WAFU,aAAa,CAEa;IAEpC;;;;OAIG;IACH,OAFU,QAAQ,CAES;IAE3B;;;;OAIG;IACH,eAFU,kBAAkB,CAEiB;IAE7C;;;;;;;OAOG;IACH,SAFU,aAAa,CAEW;IAElC;;;;;;OAMG;IACH,2BAFU,MAAM,CAEqB;IAErC;;;;OAIG;IACH,oBAFU,MAAM,CAEa;IAE7B;;;;;;;;;;;OAWG;IACH,UAFU,MAAM,CAEC;IAEjB;;;;;OAKG;IACH,oBAFU,MAAM,CAEW;IAE3B;;;OAGG;IACH,oBAFU,MAAM,CAEW;IAE3B;;;;OAIG;IACH,0BAOC;IAED;;;;OAIG;IACH,kBAFU,OAAO,CAEsB;IAEvC;;;;OAIG;IACH,yBAFU,MAAM,CAEkB;IAElC;;;;OAIG;IACH,wBAFU,MAAM,CAEiB;IAEjC;;;;OAIG;IACH,uBAFU,MAAM,CAEgB;IAEhC;;;;;OAKG;IACH,yBAA4B;IAE5B;;;;;OAKG;IACH,UAFU,SAAS,EAAE,CAEH;IAClB,0BAA0B;IAC1B,cADW,SAAS,EAAE,CACA;IAEtB;;;;;;;;OAQG;IACH,uBAFU,MAAM,MAAM;QAAC,QAAQ,EAAE,QAAQ,CAAC;QAAC,SAAS,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC,CAEpE;IAE/B;;;;;OAKG;IACH,UAFU,OAAO,CAEC;IAElB;;;;OAIG;IACH,qBAAsB;IAEtB;;;;;;OAMG;IACH,iBAFU,MAAM,CAEQ;IAExB;;;;;;;;;;;;;;;;OAgBG;IACH,mBAFU,YAAY,CAEsB;IAE5C;;;;;OAKG;IACH,4BAAqE;IAGzE;;;;;;;;;;;;;OAaG;IACH,sBAqBC;IAED;;;;;;;;;;;;;;OAcG;IACH,2BAGC;IAED;;;;;;;;;;OAUG;IACH,gCAOC;IAED;;;OAGG;IACH,cAFW,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAI9C;IAED;;;OAGG;IACH,+BAFqB,MAAM,WAAU,MAAM,aAAY,QAAQ,aAAY,QAAQ,KAAK,OAAO,QAI9F;IAED;;OAEG;IACH,8BAFuB,MAAM,WAAU,MAAM,aAAY,QAAQ,aAAY,QAAQ,KAAK,OAAO,CAIhG;IAED;;;;;;OAMG;IACH,iCA8BC;IAED;;;;OAIG;IACH,iCAIC;IAED;;;;;;;;;;OAUG;IACH,gBAJW,SAAS,aACT,SAAS,UACT,MAAM,QAmBhB;IAED;;;;;;;OAOG;IACH,kBAJW,SAAS,aACT,SAAS,UACT,MAAM,QAkChB;IAED;;;;;;;;;;;;;OAaG;IACH,6BALW,MAAM,YACN,QAAQ,aACR,SAAS,oBACT,MAAM,QAmBhB;IAED;;;;;OAKG;IACH,6BAHW,MAAM,YACN,QAAQ,QAqBlB;IAED;;;;;;;;OAQG;IACH,oCAMC;IAED;;;;;;;;;OASG;IACH,+BAsBC;IAED;;;;OAIG;IACH,iCAMC;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;OAGG;IACH,wBAEC;IAED;;;;;;;;;OASG;IACH,wBAHW,SAAS,WACT,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAU9C;IAED;;;;;;;;;;;OAWG;IACH,0BALW,SAAS,aACT,SAAS,WACT,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,cACpC,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAgC9C;IAED;;;;;;;;OAQG;IACH,uBAHW,SAAS,UACT,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAY9C;IAED;;;;;;;;;;;OAWG;IACH,wBALW,SAAS,aACT,SAAS,SACT,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,cACpC,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAuB9C;IAED;;;;;;OAMG;IACH,sBAHW,SAAS,SACT,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAQ9C;IAED;;;;;OAKG;IACH,6BAHW,SAAS,KACT,OAAO,GAAC;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,QAO9C;IAED;;;OAGG;IACH,gBAFW,SAAS,QAInB;IAED;;;;OAIG;IACH,iBAFW,SAAS,QAYnB;IAED;;;;;;;;;;;;;;OAcG;IACH,oBAgCC;IAED;;;;;;;;;;;;;;OAcG;IACH,oCAgCC;IAED;;;;;OAKG;IACH,2BAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;;;;;;;OAcG;IACH,kEAJmB,MAAM,YAAW,QAAQ,KAAG,OAAO,GAEzC,OAAO,CAInB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,uDALW;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,iDAE7B,MAAM,YAAW,QAAQ,KAAG,OAAO,GACzC,OAAO,CAInB;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACH,0CAVW;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,YAE5B;QAAC,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAC;QAAA,CAAC,EAAC,MAAM,CAAA;KAAC,UAErC,WAAW,GAAC,MAAM,EAAE,iBACpB,MAAM,oBACE,MAAM,YAAW,QAAQ,KAAG,OAAO,GAEzC,MAAM,CAIlB;IAED;;;;;;OAMG;IACH;;;;;;OAMG;IACH,qBAkBC;IAED;;;;;;;;;;;;OAYG;IACH,sBAmBC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,qBAgEC;IAED;;;;;;;;;OASG;IACH,kCAuDC;IAED,2BA4JC;IAGL;;;OAGG;IACH,0BAFU,OAAO,CAEsB;CANtC;uBAp4CsB,qBAAqB;0BAClB,kCAAkC;0BAsCV,gBAAgB;4CAxCtB,oDAAoD;yBAuCrD,eAAe;4BApCf,wBAAwB;oBAP/C,gCAAgC;8BAYN,6BAA6B;yBADlD,2BAA2B;mCAEC,iCAAiC;8BAIxD,4BAA4B;oBAftC,+BAA+B;mBADhC,uCAAuC;yBAyCjC,eAAe;+BAGT,qBAAqB"}
1
+ {"version":3,"file":"PhysicsSystem.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/PhysicsSystem.js"],"names":[],"mappings":"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"}