From e700c19394a5c87989f4d03563b0c595e63b531b Mon Sep 17 00:00:00 2001 From: Kelsi Date: Thu, 5 Feb 2026 17:48:58 -0800 Subject: [PATCH] Fix falling through upper floors in multi-story buildings Don't snap player down when detected floor is >2 units below current position. This prevents falling through upper floors when the raycast accidentally detects the ground floor through geometry gaps. --- src/rendering/camera_controller.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/rendering/camera_controller.cpp b/src/rendering/camera_controller.cpp index d6576d77..72645e1b 100644 --- a/src/rendering/camera_controller.cpp +++ b/src/rendering/camera_controller.cpp @@ -535,13 +535,16 @@ void CameraController::update(float deltaTime) { if (groundH) { float groundDiff = *groundH - lastGroundZ; - if (std::abs(groundDiff) < 2.0f) { + if (groundDiff > 2.0f) { + // Landing on a higher ledge - snap up + lastGroundZ = *groundH; + } else if (groundDiff > -2.0f) { // Small height difference - smooth it lastGroundZ += groundDiff * std::min(1.0f, deltaTime * 15.0f); - } else { - // Large height difference - snap (for falling onto ledges) - lastGroundZ = *groundH; } + // If groundDiff < -2.0f (floor much lower), ignore it - we're likely + // on an upper floor and detecting ground floor through a gap. + // Let gravity handle actual falls. if (targetPos.z <= lastGroundZ + 0.1f && verticalVelocity <= 0.0f) { targetPos.z = lastGroundZ; @@ -836,8 +839,18 @@ void CameraController::update(float deltaTime) { } if (groundH) { - lastGroundZ = *groundH; - float groundZ = *groundH + eyeHeight; + float groundDiff = *groundH - lastGroundZ; + if (groundDiff > 2.0f) { + // Landing on a higher ledge - snap up + lastGroundZ = *groundH; + } else if (groundDiff > -2.0f) { + // Small difference - accept it + lastGroundZ = *groundH; + } + // If groundDiff < -2.0f (floor much lower), ignore it - we're likely + // on an upper floor and detecting ground floor through a gap. + + float groundZ = lastGroundZ + eyeHeight; if (newPos.z <= groundZ) { newPos.z = groundZ; verticalVelocity = 0.0f;