From 8fee55f99ffbca18c996ebe6f8fd488e7d1e5731 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sun, 8 Feb 2026 15:13:55 -0800 Subject: [PATCH] Fix /unstuckgy hang by skipping WMO floor search Add CameraController::teleportTo() that directly places the player at the target position without the expensive floor-search loop in reset(). The loop does hundreds of WMO collision checks which hangs in cities. --- include/rendering/camera_controller.hpp | 1 + src/core/application.cpp | 3 +-- src/rendering/camera_controller.cpp | 27 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/rendering/camera_controller.hpp b/include/rendering/camera_controller.hpp index 00cd83aa..881e0aac 100644 --- a/include/rendering/camera_controller.hpp +++ b/include/rendering/camera_controller.hpp @@ -42,6 +42,7 @@ public: } void reset(); + void teleportTo(const glm::vec3& pos); void setOnlineMode(bool online) { onlineMode = online; } void startIntroPan(float durationSec = 2.8f, float orbitDegrees = 140.0f); bool isIntroActive() const { return introActive; } diff --git a/src/core/application.cpp b/src/core/application.cpp index 9cfd458b..22591a15 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -627,9 +627,8 @@ void Application::setupUICallbacks() { } glm::vec3 safePos = core::coords::canonicalToRender(safeCanonical); - *ft = safePos; cc->setDefaultSpawn(safePos, cc->getYaw(), cc->getPitch()); - cc->reset(); + cc->teleportTo(safePos); }); // Bind point update (innkeeper) diff --git a/src/rendering/camera_controller.cpp b/src/rendering/camera_controller.cpp index 15768bc2..c22505a1 100644 --- a/src/rendering/camera_controller.cpp +++ b/src/rendering/camera_controller.cpp @@ -1287,6 +1287,33 @@ void CameraController::reset() { LOG_INFO("Camera reset to default position"); } +void CameraController::teleportTo(const glm::vec3& pos) { + if (!camera) return; + + verticalVelocity = 0.0f; + grounded = true; + swimming = false; + lastGroundZ = pos.z; + + if (thirdPerson && followTarget) { + *followTarget = pos; + camera->setRotation(yaw, pitch); + glm::vec3 forward3D = camera->getForward(); + float mountedOffset = mounted_ ? mountHeightOffset_ : 0.0f; + glm::vec3 pivot = pos + glm::vec3(0.0f, 0.0f, PIVOT_HEIGHT + mountedOffset); + glm::vec3 camDir = -forward3D; + glm::vec3 camPos = pivot + camDir * currentDistance; + smoothedCamPos = camPos; + camera->setPosition(camPos); + } else { + glm::vec3 camPos = pos + glm::vec3(0.0f, 0.0f, eyeHeight); + smoothedCamPos = camPos; + camera->setPosition(camPos); + } + + LOG_INFO("Teleported to (", pos.x, ", ", pos.y, ", ", pos.z, ")"); +} + void CameraController::processMouseWheel(float delta) { // Adjust user's target distance (collision may limit actual distance) userTargetDistance -= delta * 2.0f; // 2.0 units per scroll notch