From a9dd685398214facc2ea5b0aea02b4ee3c07d005 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 2 Feb 2026 23:36:49 -0800 Subject: [PATCH] Fix terrain collision by correcting spawn coordinates - Spawn position changed to (-9080, -100, 100) which is on actual terrain - The terrain mesh uses WoW coordinates from ADT files directly - Camera/spawn position must use same coordinate system as terrain - Cleaned up getHeightAt comments to clarify coordinate system - Removed debug logging from WMO floor detection --- include/rendering/camera_controller.hpp | 5 +++-- src/rendering/terrain_manager.cpp | 23 +++++++++++++++-------- src/rendering/wmo_renderer.cpp | 2 -- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/include/rendering/camera_controller.hpp b/include/rendering/camera_controller.hpp index 0946d4a7..6de3e9aa 100644 --- a/include/rendering/camera_controller.hpp +++ b/include/rendering/camera_controller.hpp @@ -126,8 +126,9 @@ private: static constexpr float WOW_GRAVITY = -19.29f; static constexpr float WOW_JUMP_VELOCITY = 7.96f; - // Default spawn position (on the road outside Stormwind) - glm::vec3 defaultPosition = glm::vec3(-8830.0f, -150.0f, 82.0f); + // Default spawn position (on terrain near Stormwind) + // Terrain chunks are around X=[-9100, -9066], Y=[-533, 0] + glm::vec3 defaultPosition = glm::vec3(-9080.0f, -100.0f, 100.0f); float defaultYaw = 180.0f; // Look south toward Stormwind gate float defaultPitch = -5.0f; }; diff --git a/src/rendering/terrain_manager.cpp b/src/rendering/terrain_manager.cpp index db235b42..08a96e57 100644 --- a/src/rendering/terrain_manager.cpp +++ b/src/rendering/terrain_manager.cpp @@ -708,18 +708,25 @@ std::string TerrainManager::getADTPath(const TileCoord& coord) const { } std::optional TerrainManager::getHeightAt(float glX, float glY) const { - // Terrain mesh vertices are positioned as: - // vertex.position[0] = chunk.position[0] - (offsetY * unitSize) -> GL X - // vertex.position[1] = chunk.position[1] - (offsetX * unitSize) -> GL Y - // vertex.position[2] = chunk.position[2] + height -> GL Z (height) + // Terrain mesh vertices use chunk.position directly (WoW coordinates) + // But camera is in GL coordinates. We query using the mesh coordinates directly + // since terrain is rendered without model transformation. // - // The 9x9 outer vertex grid has offsetX, offsetY in [0, 8]. - // So the chunk spans: + // The terrain mesh generation puts vertices at: + // vertex.position[0] = chunk.position[0] - (offsetY * unitSize) + // vertex.position[1] = chunk.position[1] - (offsetX * unitSize) + // vertex.position[2] = chunk.position[2] + height + // + // So chunk spans: // X: [chunk.position[0] - 8*unitSize, chunk.position[0]] // Y: [chunk.position[1] - 8*unitSize, chunk.position[1]] const float unitSize = CHUNK_SIZE / 8.0f; + // Query coordinates are the same as what we pass (terrain uses identity model matrix) + float queryX = glX; + float queryY = glY; + for (const auto& [coord, tile] : loadedTiles) { if (!tile || !tile->loaded) continue; @@ -733,8 +740,8 @@ std::optional TerrainManager::getHeightAt(float glX, float glY) const { float chunkMaxY = chunk.position[1]; float chunkMinY = chunk.position[1] - 8.0f * unitSize; - if (glX < chunkMinX || glX > chunkMaxX || - glY < chunkMinY || glY > chunkMaxY) { + if (queryX < chunkMinX || queryX > chunkMaxX || + queryY < chunkMinY || queryY > chunkMaxY) { continue; } diff --git a/src/rendering/wmo_renderer.cpp b/src/rendering/wmo_renderer.cpp index 4f63122d..78621086 100644 --- a/src/rendering/wmo_renderer.cpp +++ b/src/rendering/wmo_renderer.cpp @@ -764,8 +764,6 @@ std::optional WMORenderer::getFloorHeight(float glX, float glY, float glZ } } } - - // (debug logging removed) } return bestFloor;