@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
@@ -1,4 +1,5 @@
1
1
  import { assert } from "../../../core/assert.js";
2
+ import { BinaryBuffer } from "../../../core/binary/BinaryBuffer.js";
2
3
  import { BVH } from "../../../core/bvh2/bvh3/BVH.js";
3
4
  import Signal from "../../../core/events/signal/Signal.js";
4
5
  import Vector3 from "../../../core/geom/Vector3.js";
@@ -21,6 +22,7 @@ import { narrowphase_step } from "../narrowphase/narrowphase_step.js";
21
22
  import { overlap_shape as overlap_shape_query } from "../queries/overlap_shape.js";
22
23
  import { raycast as raycast_query } from "../queries/raycast.js";
23
24
  import { shape_cast as shape_cast_query } from "../queries/shape_cast.js";
25
+ import { ccd_resolve } from "../ccd/linear_sweep.js";
24
26
  import { returnTrue } from "../../../core/function/returnTrue.js";
25
27
  import {
26
28
  prepare_contacts,
@@ -46,6 +48,7 @@ import { Collider, COLLIDER_UNBOUND } from "./Collider.js";
46
48
  import { RIGID_BODY_UNALLOCATED, RigidBody } from "./RigidBody.js";
47
49
  import { RigidBodyFlags } from "./RigidBodyFlags.js";
48
50
  import { SleepState } from "./SleepState.js";
51
+ import { Interpolated } from "../../interpolation/Interpolated.js";
49
52
 
50
53
  /**
51
54
  * Reusable scratch buffer for world-AABB construction so the link path is
@@ -294,6 +297,23 @@ export class PhysicsSystem extends System {
294
297
  */
295
298
  this.__pseudo_velocity = new Float64Array(0);
296
299
 
300
+ /**
301
+ * Master switch for the continuous-collision pass. When false the
302
+ * {@link RigidBodyFlags.CCD} flag is ignored and no swept queries run.
303
+ * @type {boolean}
304
+ */
305
+ this.ccdEnabled = true;
306
+
307
+ /**
308
+ * Start-of-step world positions for CCD-flagged bodies — 3 doubles per
309
+ * body slot index (`[x, y, z]`). Captured in Stage 1 before the substep
310
+ * loop integrates poses; the CCD pass ({@link ccd_resolve}) sweeps from
311
+ * here to the final pose. Grows to `storage.high_water_mark * 3`; only
312
+ * CCD-flagged slots are written each step.
313
+ * @type {Float64Array}
314
+ */
315
+ this.__ccd_start_pos = new Float64Array(0);
316
+
297
317
  /**
298
318
  * Bound reference to {@link __pair_filter} so we hand the same
299
319
  * callable to {@link generate_pairs} each step without per-step
@@ -301,6 +321,26 @@ export class PhysicsSystem extends System {
301
321
  * @private
302
322
  */
303
323
  this.__pair_filter_bound = (idA, idB) => this.__pair_filter(idA, idB);
324
+
325
+ /**
326
+ * Optional shared interpolation log to produce per-step pose snapshots
327
+ * into (the {@link InterpolationSystem}'s log). When set — and only then —
328
+ * each fixedUpdate restores every awake {@link Interpolated} body's live
329
+ * components from the previous tick (undoing render-time interpolation so
330
+ * the sim reads authoritative state), then records the post-step state
331
+ * under the current `entityManager.fixedStepTick`. Null on a headless /
332
+ * non-rendering world, where the producer work is skipped entirely.
333
+ * @type {InterpolationLog|null}
334
+ */
335
+ this.interpolationLog = null;
336
+
337
+ /**
338
+ * Reusable decode buffer for restoring interpolated snapshots.
339
+ * @private
340
+ * @type {BinaryBuffer}
341
+ */
342
+ this.__interp_scratch = new BinaryBuffer();
343
+ this.__interp_scratch.fromArrayBuffer(new ArrayBuffer(256));
304
344
  }
305
345
 
306
346
  /**
@@ -586,20 +626,16 @@ export class PhysicsSystem extends System {
586
626
  }
587
627
 
588
628
  /**
589
- * Linear scan over body slots looking for the one whose entity matches.
590
- * O(N) where N is the live body countonly called on the link/unlink
591
- * paths, not during simulation, so the scan cost is bounded.
629
+ * Resolve an entity to its body index, or -1 if no live body owns it.
630
+ * O(1) via {@link BodyStorage#index_of_entity}'s entity index mapused
631
+ * on the collider attach / detach and joint link paths.
592
632
  *
593
633
  * @private
594
634
  * @param {number} entity
595
635
  * @returns {number} body index or -1
596
636
  */
597
637
  __find_body_index_by_entity(entity) {
598
- const hwm = this.storage.high_water_mark;
599
- for (let i = 0; i < hwm; i++) {
600
- if (this.storage.entity_at(i) === entity) return i;
601
- }
602
- return -1;
638
+ return this.storage.index_of_entity(entity);
603
639
  }
604
640
 
605
641
  /**
@@ -815,6 +851,50 @@ export class PhysicsSystem extends System {
815
851
  }
816
852
  }
817
853
 
854
+ /**
855
+ * Teleport a body to a new pose, bypassing integration: writes the body's
856
+ * Transform directly and wakes it. For an interpolated body this also flags a
857
+ * render `snap` on its {@link Interpolated} component, so the producer keeps
858
+ * this pose (rather than restoring the previous tick over it) and the
859
+ * renderer shows the new pose without sliding across the jump.
860
+ *
861
+ * This is the authoritative way to reposition an interpolated body — a raw
862
+ * `Transform` write would be undone by the per-step restore. Velocity is left
863
+ * as-is; zero it via {@link setLinearVelocity} if the teleport should also
864
+ * stop the body.
865
+ *
866
+ * @param {RigidBody} rigidBody
867
+ * @param {Vector3|{x:number,y:number,z:number}} position world position
868
+ * @param {Quaternion|{x:number,y:number,z:number,w:number}} rotation world unit-quaternion rotation
869
+ */
870
+ setPose(rigidBody, position, rotation) {
871
+ const idx = body_id_index(rigidBody._bodyId);
872
+ const transform = this.__transforms[idx];
873
+ if (transform === undefined) {
874
+ return;
875
+ }
876
+
877
+ transform.position.set(position.x, position.y, position.z);
878
+ transform.rotation.set(rotation.x, rotation.y, rotation.z, rotation.w);
879
+
880
+ this.__wake_body(rigidBody);
881
+
882
+ // Flag a snap on the body's Interpolated component, if any, so the
883
+ // interpolation producer (restore) and consumer (blend) treat this pose
884
+ // as authoritative this frame instead of interpolating across the jump.
885
+ const em = this.entityManager;
886
+ if (em !== null && em !== undefined) {
887
+ const dataset = em.dataset;
888
+ if (dataset !== null && dataset !== undefined) {
889
+ const entity = this.storage.entity_at(idx);
890
+ const interpolated = dataset.getComponent(entity, Interpolated);
891
+ if (interpolated !== undefined && interpolated !== null) {
892
+ interpolated.snap = true;
893
+ }
894
+ }
895
+ }
896
+ }
897
+
818
898
  /**
819
899
  * Force the body awake. Static bodies are ignored.
820
900
  * @param {RigidBody} rigidBody
@@ -1259,7 +1339,103 @@ export class PhysicsSystem extends System {
1259
1339
  }
1260
1340
  }
1261
1341
 
1342
+ /**
1343
+ * Producer — restore pass. At the top of a fixed step, reset every awake
1344
+ * {@link Interpolated} body's live components to their authoritative state
1345
+ * from the previous tick's snapshot, undoing any render-time interpolation
1346
+ * the {@link InterpolationSystem} wrote between frames so the sim integrates
1347
+ * from truth, not an interpolated pose. A body with no previous snapshot
1348
+ * (first step ever, or just woken) is left as-is — its live state is already
1349
+ * authoritative. No-op unless {@link interpolationLog} is wired.
1350
+ * @private
1351
+ */
1352
+ __interp_restore() {
1353
+ const log = this.interpolationLog;
1354
+ const em = this.entityManager;
1355
+ if (log === null || em === null || em === undefined) return;
1356
+ const dataset = em.dataset;
1357
+ if (dataset === null || dataset === undefined) return;
1358
+
1359
+ const prev_tick = em.fixedStepTick - 1;
1360
+ if (prev_tick < 0) return;
1361
+
1362
+ const storage = this.storage;
1363
+ const count = storage.awake_count;
1364
+ const scratch = this.__interp_scratch;
1365
+
1366
+ for (let i = 0; i < count; i++) {
1367
+ const idx = storage.awake_at(i);
1368
+ const entity = storage.entity_at(idx);
1369
+ const interpolated = dataset.getComponent(entity, Interpolated);
1370
+ if (interpolated === undefined || interpolated === null) continue;
1371
+ // A teleported body (snap set, e.g. via setPose) keeps its live pose
1372
+ // this step — restoring the previous tick would undo the teleport.
1373
+ if (interpolated.snap) continue;
1374
+ const key = interpolated.key;
1375
+ if (key < 0) continue;
1376
+
1377
+ const interpolands = interpolated.interpolands;
1378
+ for (let k = 0; k < interpolands.length; k++) {
1379
+ const ip = interpolands[k];
1380
+ scratch.position = 0;
1381
+ // Snap to the previous tick's snapshot (both offsets equal → t irrelevant).
1382
+ const ok = log.interpolate(scratch, key, ip.type_id, prev_tick, prev_tick, 0, ip.interpolation_adapter);
1383
+ if (!ok) continue;
1384
+ const target = dataset.getComponent(entity, ip.component_class);
1385
+ if (target === undefined || target === null) continue;
1386
+ scratch.position = 0;
1387
+ ip.serialization_adapter.deserialize(scratch, target);
1388
+ }
1389
+ }
1390
+ }
1391
+
1392
+ /**
1393
+ * Producer — record pass. At the end of a fixed step, snapshot every awake
1394
+ * {@link Interpolated} body's live components into the shared log under the
1395
+ * current `entityManager.fixedStepTick`. The render-time
1396
+ * {@link InterpolationSystem} blends consecutive ticks from these snapshots.
1397
+ * Only awake (moving) bodies are recorded, so the log stays sparse. No-op
1398
+ * unless {@link interpolationLog} is wired.
1399
+ * @private
1400
+ */
1401
+ __interp_record() {
1402
+ const log = this.interpolationLog;
1403
+ const em = this.entityManager;
1404
+ if (log === null || em === null || em === undefined) return;
1405
+ const dataset = em.dataset;
1406
+ if (dataset === null || dataset === undefined) return;
1407
+
1408
+ const tick = em.fixedStepTick;
1409
+ const storage = this.storage;
1410
+ const count = storage.awake_count;
1411
+
1412
+ log.begin_tick(tick);
1413
+ for (let i = 0; i < count; i++) {
1414
+ const idx = storage.awake_at(i);
1415
+ const entity = storage.entity_at(idx);
1416
+ const interpolated = dataset.getComponent(entity, Interpolated);
1417
+ if (interpolated === undefined || interpolated === null) continue;
1418
+ const key = interpolated.key;
1419
+ if (key < 0) continue;
1420
+
1421
+ const interpolands = interpolated.interpolands;
1422
+ for (let k = 0; k < interpolands.length; k++) {
1423
+ const ip = interpolands[k];
1424
+ const target = dataset.getComponent(entity, ip.component_class);
1425
+ if (target === undefined || target === null) continue;
1426
+ const buf = log.begin_record(key, ip.type_id);
1427
+ ip.serialization_adapter.serialize(buf, target);
1428
+ log.end_record();
1429
+ }
1430
+ }
1431
+ log.end_tick();
1432
+ }
1433
+
1262
1434
  fixedUpdate(dt) {
1435
+ // Producer: restore authoritative pose (undo render interpolation)
1436
+ // before the sim reads any Transform this step.
1437
+ this.__interp_restore();
1438
+
1263
1439
  const gx = this.gravity.x;
1264
1440
  const gy = this.gravity.y;
1265
1441
  const gz = this.gravity.z;
@@ -1347,6 +1523,34 @@ export class PhysicsSystem extends System {
1347
1523
  const h = dt / N;
1348
1524
  const count_after_wake = this.storage.awake_count;
1349
1525
 
1526
+ // CCD: capture start-of-step positions for flagged bodies over the
1527
+ // post-wake awake set (poses are unchanged until the substep loop below
1528
+ // integrates them). The CCD pass after the solver sweeps from here to
1529
+ // each body's final pose. Reads the primary collider's transform so the
1530
+ // start matches the end the resolve pass reads. Zero-cost when no body
1531
+ // is flagged.
1532
+ const ccd_on = this.ccdEnabled;
1533
+ if (ccd_on) {
1534
+ const ccd_need = this.storage.high_water_mark * 3;
1535
+ if (this.__ccd_start_pos.length < ccd_need) {
1536
+ this.__ccd_start_pos = new Float64Array(ccd_need);
1537
+ }
1538
+ const ccd_start = this.__ccd_start_pos;
1539
+ for (let i = 0; i < count_after_wake; i++) {
1540
+ const idx = this.storage.awake_at(i);
1541
+ const rb = this.__bodies[idx];
1542
+ if (rb.kind !== BodyKind.Dynamic) continue;
1543
+ if ((rb.flags & RigidBodyFlags.CCD) === 0) continue;
1544
+ const list = this.__body_collider_lists[idx];
1545
+ if (list === undefined || list.length === 0) continue;
1546
+ const cp = list[0].transform.position;
1547
+ const cb = idx * 3;
1548
+ ccd_start[cb] = cp[0];
1549
+ ccd_start[cb + 1] = cp[1];
1550
+ ccd_start[cb + 2] = cp[2];
1551
+ }
1552
+ }
1553
+
1350
1554
  // Size the pseudo-velocity buffer ONCE (it may reallocate on growth),
1351
1555
  // then capture the reference. Inside the loop we only zero its live
1352
1556
  // region per substep — re-capturing is unnecessary since it won't
@@ -1403,6 +1607,21 @@ export class PhysicsSystem extends System {
1403
1607
  // the approach velocity captured at prepare time.
1404
1608
  apply_restitution(this.manifolds, this);
1405
1609
 
1610
+ // Stage 8.5: continuous collision — sweep CCD-flagged fast movers along
1611
+ // their net step translation and stop them at the first blocker, so they
1612
+ // can't tunnel through thin geometry between discrete steps. Runs on the
1613
+ // final post-solve poses, before the sleep test sees the clamped
1614
+ // velocities. No-op when no awake body is flagged.
1615
+ if (ccd_on) {
1616
+ ccd_resolve(this);
1617
+ }
1618
+
1619
+ // Producer: record the post-step authoritative pose of every awake
1620
+ // interpolated body under this step's tick. Before the sleep test, so a
1621
+ // body that settles this step still records its final pose for the last
1622
+ // interpolation interval.
1623
+ this.__interp_record();
1624
+
1406
1625
  // Stage 9: sleep test.
1407
1626
  this.__sleep_test(dt);
1408
1627
 
@@ -8,6 +8,11 @@
8
8
  * component during solve.
9
9
  * - {@link DisableSleep }: this body never enters the sleeping set. Bodies near it
10
10
  * may still sleep when stable.
11
+ * - {@link CCD }: opt-in continuous collision detection. After the solver, the
12
+ * body's net step translation is shape-cast against the broadphase and the
13
+ * body is stopped at the first blocker, so a fast mover can't tunnel through
14
+ * thin geometry between discrete steps. Off by default — it costs one swept
15
+ * query per fast-moving flagged body per step. See `ccd/linear_sweep.js`.
11
16
  */
12
17
  export type RigidBodyFlags = number;
13
18
  export namespace RigidBodyFlags {
@@ -17,5 +22,6 @@ export namespace RigidBodyFlags {
17
22
  let LockRotY: number;
18
23
  let LockRotZ: number;
19
24
  let DisableSleep: number;
25
+ let CCD: number;
20
26
  }
21
27
  //# sourceMappingURL=RigidBodyFlags.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RigidBodyFlags.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/RigidBodyFlags.js"],"names":[],"mappings":";;;;;;;;;;;6BAYU,MAAM"}
1
+ {"version":3,"file":"RigidBodyFlags.d.ts","sourceRoot":"","sources":["../../../../../src/engine/physics/ecs/RigidBodyFlags.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;6BAiBU,MAAM"}
@@ -8,6 +8,11 @@
8
8
  * component during solve.
9
9
  * - {@link DisableSleep}: this body never enters the sleeping set. Bodies near it
10
10
  * may still sleep when stable.
11
+ * - {@link CCD}: opt-in continuous collision detection. After the solver, the
12
+ * body's net step translation is shape-cast against the broadphase and the
13
+ * body is stopped at the first blocker, so a fast mover can't tunnel through
14
+ * thin geometry between discrete steps. Off by default — it costs one swept
15
+ * query per fast-moving flagged body per step. See `ccd/linear_sweep.js`.
11
16
  *
12
17
  * @readonly
13
18
  * @enum {number}
@@ -19,4 +24,5 @@ export const RigidBodyFlags = {
19
24
  LockRotY: 4,
20
25
  LockRotZ: 8,
21
26
  DisableSleep: 16,
27
+ CCD: 32,
22
28
  };