Add previous planar displacement to player locomotion options and update motion computation logic

This commit is contained in:
2026-04-11 21:43:09 +02:00
parent e8b39dad7a
commit 5ae2b3f18c

View File

@@ -76,6 +76,7 @@ export interface StepPlayerLocomotionOptions {
standingShape: FirstPersonPlayerShape;
verticalVelocity: number;
previousLocomotionState?: RuntimeLocomotionState;
previousPlanarDisplacement: Vec3;
jumpBufferRemainingMs: number;
coyoteTimeRemainingMs: number;
jumpHoldRemainingMs: number;
@@ -226,6 +227,17 @@ function computePlanarMotion(
};
}
function computePlanarSpeedFromDisplacement(
displacement: Vec3,
dt: number
): number {
if (dt <= 0) {
return 0;
}
return Math.hypot(displacement.x, displacement.z) / dt;
}
function alignPlanarMotionToGround(
planarMotion: Vec3,
groundNormal: Vec3 | null
@@ -397,12 +409,27 @@ export function stepPlayerLocomotion(
? groundedRequestedPlanarSpeed
: airborneRequestedPlanarSpeed
: groundedRequestedPlanarSpeed;
const planarMotion = computePlanarMotion(
const planarMotionFromInput = computePlanarMotion(
options.movementYawRadians,
options.input,
requestedPlanarSpeed,
options.dt
);
const preserveAirborneMomentum =
activeShape.mode !== "none" &&
!currentVolumeState.inWater &&
(jumpTriggered || !currentlyGrounded) &&
planarMotionFromInput.inputMagnitude <= 0;
const planarMotion = preserveAirborneMomentum
? {
motion: {
x: options.previousPlanarDisplacement.x,
y: 0,
z: options.previousPlanarDisplacement.z
},
inputMagnitude: 0
}
: planarMotionFromInput;
const groundedPlanarMotion =
currentlyGrounded && !jumpTriggered
@@ -527,8 +554,12 @@ export function stepPlayerLocomotion(
crouched,
sprinting,
inputMagnitude: planarMotion.inputMagnitude,
requestedPlanarSpeed:
requestedPlanarSpeed * planarMotion.inputMagnitude,
requestedPlanarSpeed: preserveAirborneMomentum
? computePlanarSpeedFromDisplacement(
options.previousPlanarDisplacement,
options.dt
)
: requestedPlanarSpeed * planarMotion.inputMagnitude,
planarSpeed: actualPlanarSpeed,
verticalVelocity,
contact: resolveContactState(resolvedMotion, groundProbe, grounded)