@woosh/meep-engine 2.146.0 → 2.148.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 (105) hide show
  1. package/package.json +1 -1
  2. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +4 -4
  3. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -1
  4. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +48 -52
  5. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +23 -21
  6. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -1
  7. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +41 -406
  8. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +5 -4
  9. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -1
  10. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +400 -395
  11. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +0 -11
  12. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  13. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +8 -6
  14. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  15. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +552 -551
  16. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +8 -3
  17. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
  18. package/src/engine/control/first-person/abilities/LedgeGrab.js +213 -199
  19. package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -1
  20. package/src/engine/control/first-person/abilities/Mantle.js +195 -188
  21. package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -1
  22. package/src/engine/control/first-person/abilities/WallRun.js +183 -175
  23. package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts +9 -0
  24. package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts.map +1 -1
  25. package/src/engine/control/first-person/sensors/FirstPersonSensors.js +87 -77
  26. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +8 -0
  27. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
  28. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +229 -196
  29. package/src/engine/ecs/EntityManager.d.ts +34 -11
  30. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  31. package/src/engine/ecs/EntityManager.js +71 -42
  32. package/src/engine/interpolation/BinaryInterpolationAdapter.d.ts.map +1 -0
  33. package/src/engine/interpolation/Interpoland.d.ts +48 -0
  34. package/src/engine/interpolation/Interpoland.d.ts.map +1 -0
  35. package/src/engine/interpolation/Interpoland.js +49 -0
  36. package/src/engine/interpolation/Interpolated.d.ts +101 -0
  37. package/src/engine/interpolation/Interpolated.d.ts.map +1 -0
  38. package/src/engine/interpolation/Interpolated.js +149 -0
  39. package/src/engine/{network/sim → interpolation}/InterpolationLog.d.ts +1 -1
  40. package/src/engine/interpolation/InterpolationLog.d.ts.map +1 -0
  41. package/src/engine/{network/sim → interpolation}/InterpolationLog.js +2 -2
  42. package/src/engine/interpolation/InterpolationSystem.d.ts +116 -0
  43. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -0
  44. package/src/engine/interpolation/InterpolationSystem.js +233 -0
  45. package/src/engine/interpolation/PoseInterpolationAdapter.d.ts +17 -0
  46. package/src/engine/interpolation/PoseInterpolationAdapter.d.ts.map +1 -0
  47. package/src/engine/interpolation/PoseInterpolationAdapter.js +61 -0
  48. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts +35 -0
  49. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -0
  50. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +57 -0
  51. package/src/engine/interpolation/pose_interpoland.d.ts +18 -0
  52. package/src/engine/interpolation/pose_interpoland.d.ts.map +1 -0
  53. package/src/engine/interpolation/pose_interpoland.js +27 -0
  54. package/src/engine/network/NetworkSession.d.ts +2 -2
  55. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  56. package/src/engine/network/NetworkSession.js +2 -2
  57. package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts +1 -1
  58. package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts.map +1 -1
  59. package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +1 -1
  60. package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts +1 -1
  61. package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts.map +1 -1
  62. package/src/engine/network/adapters/TransformInterpolationAdapter.js +1 -1
  63. package/src/engine/network/adapters/Vector3InterpolationAdapter.d.ts +1 -1
  64. package/src/engine/network/adapters/Vector3InterpolationAdapter.d.ts.map +1 -1
  65. package/src/engine/network/adapters/Vector3InterpolationAdapter.js +1 -1
  66. package/src/engine/physics/INTEPOLATION_SYSTEM_PLAN.md +287 -0
  67. package/src/engine/physics/PLAN.md +10 -9
  68. package/src/engine/physics/body/SolverBodyState.d.ts +142 -0
  69. package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -0
  70. package/src/engine/physics/body/SolverBodyState.js +251 -0
  71. package/src/engine/physics/broadphase/generate_pairs.d.ts +2 -1
  72. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
  73. package/src/engine/physics/broadphase/generate_pairs.js +5 -3
  74. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  75. package/src/engine/physics/constraint/solve_constraints.js +691 -673
  76. package/src/engine/physics/ecs/PhysicsSystem.d.ts +82 -15
  77. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  78. package/src/engine/physics/ecs/PhysicsSystem.js +387 -87
  79. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +23 -0
  80. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
  81. package/src/engine/physics/inertia/world_inverse_inertia.js +116 -77
  82. package/src/engine/physics/integration/integrate_position.d.ts +11 -1
  83. package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
  84. package/src/engine/physics/integration/integrate_position.js +97 -79
  85. package/src/engine/physics/integration/integrate_velocity.d.ts +12 -3
  86. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
  87. package/src/engine/physics/integration/integrate_velocity.js +201 -160
  88. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
  89. package/src/engine/physics/narrowphase/box_box_manifold.js +750 -665
  90. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -1
  91. package/src/engine/physics/narrowphase/box_triangle_contact.js +19 -46
  92. package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts +16 -0
  93. package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts.map +1 -0
  94. package/src/engine/physics/narrowphase/clip_against_axis_uv.js +49 -0
  95. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  96. package/src/engine/physics/narrowphase/narrowphase_step.js +52 -4
  97. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  98. package/src/engine/physics/queries/raycast.js +7 -4
  99. package/src/engine/physics/solver/solve_contacts.d.ts +2 -2
  100. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
  101. package/src/engine/physics/solver/solve_contacts.js +1341 -1173
  102. package/src/engine/network/sim/BinaryInterpolationAdapter.d.ts.map +0 -1
  103. package/src/engine/network/sim/InterpolationLog.d.ts.map +0 -1
  104. /package/src/engine/{network/sim → interpolation}/BinaryInterpolationAdapter.d.ts +0 -0
  105. /package/src/engine/{network/sim → interpolation}/BinaryInterpolationAdapter.js +0 -0
@@ -1,188 +1,195 @@
1
- import { FirstPersonPosture } from "../pose/FirstPersonPosture.js";
2
- import { Ability } from "./Ability.js";
3
-
4
- /**
5
- * Smoothstep-style horizontal interpolation: slow-fast-slow.
6
- * @param {number} t [0..1]
7
- */
8
- function easeInOutCubic(t) {
9
- return t < 0.5
10
- ? 4 * t * t * t
11
- : 1 - Math.pow(-2 * t + 2, 3) / 2;
12
- }
13
-
14
- /**
15
- * Front-loaded ease — fast rise then gentle settle. Used for the vertical
16
- * curve so the body lifts off the ground quickly (matching the hand-grip
17
- * pull-up dynamic) and decelerates as it approaches the surface top.
18
- * @param {number} t [0..1]
19
- */
20
- function easeOutCubic(t) {
21
- return 1 - Math.pow(1 - t, 3);
22
- }
23
-
24
- /**
25
- * Mantle ability — auto-triggers when the player walks/runs into a
26
- * reachable obstacle with forward intent. The body follows a scripted
27
- * parametric path (horizontal lerp on an ease-in-out, vertical lerp on
28
- * an ease-out) for {@link cfg.mantle.duration} seconds, landing on top
29
- * of the surface.
30
- *
31
- * Activation requires both `sensors.obstacleAhead.hit` (something in
32
- * front to climb) AND `sensors.ledgeAhead.hit` (there's a top surface
33
- * to land on). Heights between `cfg.mantle.minHeight` and `maxHeight`
34
- * are accepted; below is "just step over", above is "out of reach".
35
- *
36
- * The ability is FULLY non-interruptible once committed — `canInterrupt`
37
- * returns false throughout. This prevents the body from teleporting
38
- * mid-mantle if a higher-priority ability fires; the trade-off is the
39
- * player has limited control during the short window. Player input
40
- * for THIS frame is effectively suspended.
41
- *
42
- * Priority 30: above Slide (10) so an obstacle vault-into preempts a
43
- * slide; below Wall-run / Wall-jump so those high-air abilities still
44
- * win if their conditions are simultaneously met (which would be
45
- * unusual — typically you mantle from the ground).
46
- *
47
- * @author Alex Goldring
48
- * @copyright Company Named Limited (c) 2026
49
- */
50
- export class Mantle extends Ability {
51
- constructor() {
52
- super();
53
- this.name = "Mantle";
54
- this.priority = 30;
55
-
56
- // -- per-instance scripted-path state --
57
- /** @private Elapsed fraction of duration. */
58
- this._t = 0;
59
- /** @private Captured at activation. */
60
- this._duration = 0.5;
61
- this._startX = 0;
62
- this._startY = 0;
63
- this._startZ = 0;
64
- this._endX = 0;
65
- this._endY = 0;
66
- this._endZ = 0;
67
- }
68
-
69
- canActivate(controller, runtime, sensors) {
70
- const cfg = controller.config.mantle;
71
- if (!cfg) return false;
72
- if (sensors === undefined || sensors === null) return false;
73
-
74
- // Must have BOTH the face probe (obstacleAhead) AND the top probe
75
- // (ledgeAhead) — otherwise we don't know if there's anywhere to
76
- // land. obstacleAhead alone could be a wall too tall to climb.
77
- if (!sensors.obstacleAhead.hit) return false;
78
- if (!sensors.ledgeAhead.hit) return false;
79
-
80
- // Forward intent is required the player must be committing
81
- // into the obstacle, otherwise we don't want to grab them.
82
- if (controller.intent.move.y < 0.1) return false;
83
-
84
- // Height check: the target surface must be within the reachable
85
- // band.
86
- const surfaceTopY = sensors.ledgeAhead.point.y;
87
- const playerFootY = controller.pose.rootPosition.y;
88
- const heightDiff = surfaceTopY - playerFootY;
89
- if (heightDiff < cfg.minHeight) return false;
90
- if (heightDiff > cfg.maxHeight) return false;
91
-
92
- return true;
93
- }
94
-
95
- onActivate(controller, runtime) {
96
- const cfg = controller.config.mantle;
97
- const sensors = runtime.sensors;
98
-
99
- this._t = 0;
100
- this._duration = cfg.duration;
101
-
102
- // Capture start position (body's current world position).
103
- const startPos = controller.pose.rootPosition;
104
- this._startX = startPos.x;
105
- this._startY = startPos.y;
106
- this._startZ = startPos.z;
107
-
108
- // Compute end position: above the ledge surface, displaced
109
- // forward by `forwardOffsetOnLand` so the player ends standing
110
- // on the surface (not balancing on the edge).
111
- const yaw = runtime.bodyYaw;
112
- const fx = Math.sin(yaw);
113
- const fz = Math.cos(yaw);
114
- this._endX = sensors.ledgeAhead.point.x + fx * cfg.forwardOffsetOnLand;
115
- this._endY = sensors.ledgeAhead.point.y;
116
- this._endZ = sensors.ledgeAhead.point.z + fz * cfg.forwardOffsetOnLand;
117
-
118
- // Zero velocity — the body is on a path, not under integration.
119
- runtime.velocityX = 0;
120
- runtime.velocityY = 0;
121
- runtime.velocityZ = 0;
122
-
123
- // Clear airborne/jump state the scripted path supersedes them.
124
- runtime.midJump = false;
125
- runtime.apexFired = false;
126
- controller.state.isVariableJumpCut = false;
127
- controller.state.isAscending = false;
128
-
129
- // Body is climbing — upright posture (not Hang, even if we got
130
- // here from ledge-grab). Animators read posture for the rig
131
- // blend; this signals "switch from the hang clip to the climb /
132
- // upright clip".
133
- controller.state.posture = FirstPersonPosture.Stand;
134
-
135
- controller.signals.onLeaveGround.send1({ reason: "mantle" });
136
- }
137
-
138
- canInterrupt() {
139
- // Non-interruptible. Mantle commits.
140
- return false;
141
- }
142
-
143
- tick(controller, runtime, bodyTransform, dt, _system) {
144
- // Body is on a scripted path — no lat-accel-driven lean. Hold
145
- // the camera level for the duration of the mantle.
146
- runtime.leanTargetRad = 0;
147
- // Re-assert posture in case anything reset it. Mantle is a
148
- // committed climb; we want the rig in the climb/stand blend
149
- // until release.
150
- controller.state.posture = FirstPersonPosture.Stand;
151
-
152
- this._t += dt / this._duration;
153
-
154
- if (this._t >= 1.0) {
155
- // Completed: snap to end, mark grounded, release.
156
- bodyTransform.position.set(this._endX, this._endY, this._endZ);
157
- runtime.velocityX = 0;
158
- runtime.velocityY = 0;
159
- runtime.velocityZ = 0;
160
- controller.state.grounded = true;
161
- controller.state.verticalSpeed = 0;
162
- controller.state.airborneTime = 0;
163
- controller.state.timeSinceGrounded = 0;
164
- controller.signals.onLand.send1({ verticalSpeed: 0, kind: "soft" });
165
- return false;
166
- }
167
-
168
- // Sample the parametric path.
169
- const horizT = easeInOutCubic(this._t);
170
- const vertT = easeOutCubic(this._t);
171
- bodyTransform.position.set(
172
- this._startX + (this._endX - this._startX) * horizT,
173
- this._startY + (this._endY - this._startY) * vertT,
174
- this._startZ + (this._endZ - this._startZ) * horizT,
175
- );
176
-
177
- // Body is on a path — no integration this tick. Velocity stays 0.
178
- runtime.velocityX = 0;
179
- runtime.velocityY = 0;
180
- runtime.velocityZ = 0;
181
-
182
- return true;
183
- }
184
-
185
- onDeactivate(_controller, _runtime) {
186
- this._t = 0;
187
- }
188
- }
1
+ import { FirstPersonPosture } from "../pose/FirstPersonPosture.js";
2
+ import { Ability } from "./Ability.js";
3
+
4
+ /**
5
+ * Smoothstep-style horizontal interpolation: slow-fast-slow.
6
+ * @param {number} t [0..1]
7
+ */
8
+ function easeInOutCubic(t) {
9
+ return t < 0.5
10
+ ? 4 * t * t * t
11
+ : 1 - Math.pow(-2 * t + 2, 3) / 2;
12
+ }
13
+
14
+ /**
15
+ * Front-loaded ease — fast rise then gentle settle. Used for the vertical
16
+ * curve so the body lifts off the ground quickly (matching the hand-grip
17
+ * pull-up dynamic) and decelerates as it approaches the surface top.
18
+ * @param {number} t [0..1]
19
+ */
20
+ function easeOutCubic(t) {
21
+ return 1 - Math.pow(1 - t, 3);
22
+ }
23
+
24
+ /**
25
+ * Mantle ability — auto-triggers when the player walks/runs into a
26
+ * reachable obstacle with forward intent. The body follows a scripted
27
+ * parametric path (horizontal lerp on an ease-in-out, vertical lerp on
28
+ * an ease-out) for {@link cfg.mantle.duration} seconds, landing on top
29
+ * of the surface.
30
+ *
31
+ * Activation requires both `sensors.obstacleAhead.hit` (something in
32
+ * front to climb) AND `sensors.ledgeAhead.hit` (there's a top surface
33
+ * to land on). Heights between `cfg.mantle.minHeight` and `maxHeight`
34
+ * are accepted; below is "just step over", above is "out of reach".
35
+ *
36
+ * The ability is FULLY non-interruptible once committed — `canInterrupt`
37
+ * returns false throughout. This prevents the body from teleporting
38
+ * mid-mantle if a higher-priority ability fires; the trade-off is the
39
+ * player has limited control during the short window. Player input
40
+ * for THIS frame is effectively suspended.
41
+ *
42
+ * Priority 30: above Slide (10) so an obstacle vault-into preempts a
43
+ * slide; below Wall-run / Wall-jump so those high-air abilities still
44
+ * win if their conditions are simultaneously met (which would be
45
+ * unusual — typically you mantle from the ground).
46
+ *
47
+ * @author Alex Goldring
48
+ * @copyright Company Named Limited (c) 2026
49
+ */
50
+ export class Mantle extends Ability {
51
+ constructor() {
52
+ super();
53
+ this.name = "Mantle";
54
+ this.priority = 30;
55
+
56
+ // -- per-instance scripted-path state --
57
+ /** @private Elapsed fraction of duration. */
58
+ this._t = 0;
59
+ /** @private Captured at activation. */
60
+ this._duration = 0.5;
61
+ this._startX = 0;
62
+ this._startY = 0;
63
+ this._startZ = 0;
64
+ this._endX = 0;
65
+ this._endY = 0;
66
+ this._endZ = 0;
67
+ }
68
+
69
+ canActivate(controller, runtime, sensors) {
70
+ const cfg = controller.config.mantle;
71
+ if (!cfg) return false;
72
+ if (sensors === undefined || sensors === null) return false;
73
+
74
+ // Must have BOTH the face probe (obstacleAhead) AND the top probe
75
+ // (ledgeAhead) — otherwise we don't know if there's anywhere to
76
+ // land. obstacleAhead alone could be a wall too tall to climb.
77
+ if (!sensors.obstacleAhead.hit) return false;
78
+ if (!sensors.ledgeAhead.hit) return false;
79
+
80
+ // Only vault onto a top we can actually STAND on. A too-thin wall /
81
+ // knife-edge isn't a mantle target the body would land overhanging
82
+ // and fall right back off (on a wall-run wall this is the reported
83
+ // violent snap-then-drop). Ledge-grab, which can hang from a thin
84
+ // edge, takes those instead.
85
+ if (!sensors.ledgeStandable) return false;
86
+
87
+ // Forward intent is required — the player must be committing
88
+ // into the obstacle, otherwise we don't want to grab them.
89
+ if (controller.intent.move.y < 0.1) return false;
90
+
91
+ // Height check: the target surface must be within the reachable
92
+ // band.
93
+ const surfaceTopY = sensors.ledgeAhead.point.y;
94
+ const playerFootY = controller.pose.rootPosition.y;
95
+ const heightDiff = surfaceTopY - playerFootY;
96
+ if (heightDiff < cfg.minHeight) return false;
97
+ if (heightDiff > cfg.maxHeight) return false;
98
+
99
+ return true;
100
+ }
101
+
102
+ onActivate(controller, runtime) {
103
+ const cfg = controller.config.mantle;
104
+ const sensors = runtime.sensors;
105
+
106
+ this._t = 0;
107
+ this._duration = cfg.duration;
108
+
109
+ // Capture start position (body's current world position).
110
+ const startPos = controller.pose.rootPosition;
111
+ this._startX = startPos.x;
112
+ this._startY = startPos.y;
113
+ this._startZ = startPos.z;
114
+
115
+ // Compute end position: above the ledge surface, displaced
116
+ // forward by `forwardOffsetOnLand` so the player ends standing
117
+ // on the surface (not balancing on the edge).
118
+ const yaw = runtime.bodyYaw;
119
+ const fx = Math.sin(yaw);
120
+ const fz = Math.cos(yaw);
121
+ this._endX = sensors.ledgeAhead.point.x + fx * cfg.forwardOffsetOnLand;
122
+ this._endY = sensors.ledgeAhead.point.y;
123
+ this._endZ = sensors.ledgeAhead.point.z + fz * cfg.forwardOffsetOnLand;
124
+
125
+ // Zero velocity — the body is on a path, not under integration.
126
+ runtime.velocityX = 0;
127
+ runtime.velocityY = 0;
128
+ runtime.velocityZ = 0;
129
+
130
+ // Clear airborne/jump state the scripted path supersedes them.
131
+ runtime.midJump = false;
132
+ runtime.apexFired = false;
133
+ controller.state.isVariableJumpCut = false;
134
+ controller.state.isAscending = false;
135
+
136
+ // Body is climbing — upright posture (not Hang, even if we got
137
+ // here from ledge-grab). Animators read posture for the rig
138
+ // blend; this signals "switch from the hang clip to the climb /
139
+ // upright clip".
140
+ controller.state.posture = FirstPersonPosture.Stand;
141
+
142
+ controller.signals.onLeaveGround.send1({ reason: "mantle" });
143
+ }
144
+
145
+ canInterrupt() {
146
+ // Non-interruptible. Mantle commits.
147
+ return false;
148
+ }
149
+
150
+ tick(controller, runtime, bodyTransform, dt, _system) {
151
+ // Body is on a scripted path — no lat-accel-driven lean. Hold
152
+ // the camera level for the duration of the mantle.
153
+ runtime.leanTargetRad = 0;
154
+ // Re-assert posture in case anything reset it. Mantle is a
155
+ // committed climb; we want the rig in the climb/stand blend
156
+ // until release.
157
+ controller.state.posture = FirstPersonPosture.Stand;
158
+
159
+ this._t += dt / this._duration;
160
+
161
+ if (this._t >= 1.0) {
162
+ // Completed: snap to end, mark grounded, release.
163
+ bodyTransform.position.set(this._endX, this._endY, this._endZ);
164
+ runtime.velocityX = 0;
165
+ runtime.velocityY = 0;
166
+ runtime.velocityZ = 0;
167
+ controller.state.grounded = true;
168
+ controller.state.verticalSpeed = 0;
169
+ controller.state.airborneTime = 0;
170
+ controller.state.timeSinceGrounded = 0;
171
+ controller.signals.onLand.send1({ verticalSpeed: 0, kind: "soft" });
172
+ return false;
173
+ }
174
+
175
+ // Sample the parametric path.
176
+ const horizT = easeInOutCubic(this._t);
177
+ const vertT = easeOutCubic(this._t);
178
+ bodyTransform.position.set(
179
+ this._startX + (this._endX - this._startX) * horizT,
180
+ this._startY + (this._endY - this._startY) * vertT,
181
+ this._startZ + (this._endZ - this._startZ) * horizT,
182
+ );
183
+
184
+ // Body is on a path — no integration this tick. Velocity stays 0.
185
+ runtime.velocityX = 0;
186
+ runtime.velocityY = 0;
187
+ runtime.velocityZ = 0;
188
+
189
+ return true;
190
+ }
191
+
192
+ onDeactivate(_controller, _runtime) {
193
+ this._t = 0;
194
+ }
195
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"WallRun.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/control/first-person/abilities/WallRun.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;IAMQ,qDAAqD;IACrD,iBAAiB;IACjB,yDAAyD;IACzD,cAAgB;IAGpB,kEA6BC;IAED,gDAqBC;IAED;;;;OAIG;IACH,wBAEC;IAED,uFAgEC;CAKJ;wBA7KuB,cAAc"}
1
+ {"version":3,"file":"WallRun.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/control/first-person/abilities/WallRun.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;IAMQ,qDAAqD;IACrD,iBAAiB;IACjB,yDAAyD;IACzD,cAAgB;IAGpB,kEAqCC;IAED,gDAqBC;IAED;;;;OAIG;IACH,wBAEC;IAED,uFAgEC;CAKJ;wBArLuB,cAAc"}