updated the collision for jumps and terrain

This commit is contained in:
phenom committed 2026-08-16 18:07:34 -04:00
1 parent c00f3211ea
commit e39aebf3a1
5 files changed
+138 -18

No files matched your search

+16 -3
View File
@@ -81,6 +81,7 @@ const BREADCRUMB_REACHED_DISTANCE = 0.04;
const PARTY_COLLISION_RADIUS = 0.34;
const PARTY_COLLISION_HALF_HEIGHT = 0.48;
const PARTY_COLLISION_CENTER_HEIGHT = PARTY_COLLISION_RADIUS + PARTY_COLLISION_HALF_HEIGHT + 0.04;
const PARTY_WALKABLE_STEP_HEIGHT = 0.32;
const PARTY_OBJECTIVE_APPROACH_SNAP_DISTANCE = 6;
const PARTY_FLOOR_SAMPLE_SPACING = 0.6;
const PARTY_FLOOR_RAY_HEIGHT = 1.25;
@@ -291,7 +292,12 @@ function PartyActors({
const resetRevision = useGameStore((state) => state.resetRevision);
const { rapier, world } = useRapier();
const navigationCapsule = useMemo(
() => new rapier.Capsule(PARTY_COLLISION_HALF_HEIGHT, PARTY_COLLISION_RADIUS),
// Trim the lower leg band while keeping the capsule top at normal head
// height. This supplies step clearance without demanding extra ceiling.
() => new rapier.Capsule(
PARTY_COLLISION_HALF_HEIGHT - PARTY_WALKABLE_STEP_HEIGHT * 0.5,
PARTY_COLLISION_RADIUS,
),
[rapier],
);
const navigationRotation = useMemo(() => new Quaternion(), []);
@@ -319,13 +325,20 @@ function PartyActors({
const dz = end[2] - start[2];
const distance = Math.hypot(dx, dy, dz);
if (!Number.isFinite(distance)) return false;
if (distance <= 0.04) return true;
const planarDistance = Math.hypot(dx, dz);
// Collision and navigation surfaces commonly disagree by a few centimeters.
// Treat a same-column height correction as grounding, not a blocked move.
if (planarDistance <= 0.04) {
return Math.abs(dy) <= PARTY_WALKABLE_STEP_HEIGHT;
}
const queryFlags = rapier.QueryFilterFlags.EXCLUDE_SENSORS
| rapier.QueryFilterFlags.EXCLUDE_DYNAMIC;
const obstacle = world.castShape(
{
x: start[0],
y: start[1] + PARTY_COLLISION_CENTER_HEIGHT,
// Raise only the trimmed lower band over walkable relief. The floor
// samples below still reject real ledges and excessive elevation.
y: start[1] + PARTY_COLLISION_CENTER_HEIGHT + PARTY_WALKABLE_STEP_HEIGHT * 0.5,
z: start[2],
},
navigationRotation,
+10 -14
View File
@@ -41,12 +41,12 @@ import {
import {
PLAYER_GROUND_PROBE_DISTANCE,
PLAYER_JUMP_VELOCITY,
PLAYER_LANDING_PRESENTATION_MS,
bufferPlayerJump,
cancelBufferedPlayerJump,
characterVerticalMotion,
createCharacterVerticalPresentationTiming,
createPlayerJumpTiming,
isWalkableGroundHit,
updateCharacterVerticalPresentation,
updatePlayerJumpTiming,
type CharacterVerticalMotion,
} from "../game/playerJump";
@@ -123,16 +123,14 @@ function PlayerController({
[rapier],
);
const jumpTimingRef = useRef(createPlayerJumpTiming());
const wasGroundedRef = useRef(true);
const landingUntilRef = useRef(Number.NEGATIVE_INFINITY);
const verticalPresentationTimingRef = useRef(createCharacterVerticalPresentationTiming());
useEffect(() => {
if (bodyRef.current) placeAtActiveSpawn(bodyRef.current, orbitRef.current);
lastReported.current = [...spawn.footPosition];
clearJumpRequest();
jumpTimingRef.current = createPlayerJumpTiming(performance.now());
wasGroundedRef.current = true;
landingUntilRef.current = Number.NEGATIVE_INFINITY;
verticalPresentationTimingRef.current = createCharacterVerticalPresentationTiming();
verticalMotionRef.current = "grounded";
}, [bodyRef, orbitRef, resetRevision, spawn, verticalMotionRef]);
@@ -189,11 +187,12 @@ function PlayerController({
if (gameplayBlocked) {
cancelBufferedPlayerJump(jumpTimingRef.current);
movingRef.current = false;
verticalMotionRef.current = characterVerticalMotion(
verticalMotionRef.current = updateCharacterVerticalPresentation(
verticalPresentationTimingRef.current,
grounded,
velocity.y,
nowMs,
landingUntilRef.current,
false,
);
body.setLinvel({ x: 0, y: velocity.y, z: 0 }, true);
return;
@@ -208,15 +207,12 @@ function PlayerController({
);
const verticalVelocity = shouldJump ? PLAYER_JUMP_VELOCITY : velocity.y;
if (shouldJump) grounded = false;
if (grounded && !wasGroundedRef.current) {
landingUntilRef.current = nowMs + PLAYER_LANDING_PRESENTATION_MS;
}
wasGroundedRef.current = grounded;
verticalMotionRef.current = characterVerticalMotion(
verticalMotionRef.current = updateCharacterVerticalPresentation(
verticalPresentationTimingRef.current,
grounded,
verticalVelocity,
nowMs,
landingUntilRef.current,
shouldJump,
);
const [worldX, worldZ] = cameraRelativeMovement(