From b47bfdc644b39d31491bad55e2ae0597ba741a0a Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sun, 8 Feb 2026 20:15:34 -0800 Subject: [PATCH] Fix camera snapping to upper floors with step-up constraint and ceiling check Reduced camera floor step-up budget from 3.0f to 0.5f to prevent snapping to floors far above camera. Added upward raycast to detect ceilings/upper floors and constrain zoom distance in multi-story buildings, preventing camera from phasing through upper levels. --- src/rendering/camera_controller.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/rendering/camera_controller.cpp b/src/rendering/camera_controller.cpp index 98ec2027..881d8889 100644 --- a/src/rendering/camera_controller.cpp +++ b/src/rendering/camera_controller.cpp @@ -617,6 +617,21 @@ void CameraController::update(float deltaTime) { if (cachedInsideWMO && currentDistance > WMO_MAX_DISTANCE) { currentDistance = WMO_MAX_DISTANCE; } + + // Constrain zoom if there's a ceiling/upper floor above player + // Raycast upward from player to find ceiling, limit camera distance + glm::vec3 upRayOrigin = targetPos; + glm::vec3 upRayDir(0.0f, 0.0f, 1.0f); + float ceilingDist = wmoRenderer->raycast(upRayOrigin, upRayDir, 15.0f); + if (ceilingDist < 15.0f) { + // Found ceiling above — limit zoom to prevent camera from going through it + // Camera is behind player by currentDistance, at an angle + // Approximate: if ceiling is N units above, limit zoom to ~N units + float maxZoomForCeiling = std::max(1.5f, ceilingDist * 0.7f); + if (currentDistance > maxZoomForCeiling) { + currentDistance = maxZoomForCeiling; + } + } } // ===== Camera collision (sphere sweep approximation) ===== @@ -672,7 +687,7 @@ void CameraController::update(float deltaTime) { } } auto camFloorH = selectReachableFloor( - camTerrainH, camWmoH, smoothedCamPos.z, 3.0f); + camTerrainH, camWmoH, smoothedCamPos.z, 0.5f); if (camFloorH && smoothedCamPos.z < *camFloorH + MIN_FLOOR_CLEARANCE) { smoothedCamPos.z = *camFloorH + MIN_FLOOR_CLEARANCE; }