From 61fb486b9e050915d55418c402e63ed02f44fb4f Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 08:49:26 -0700 Subject: [PATCH] fix(m2): degenerate-normal guard during walkable-floor raycast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The matrix-transformed normal could be near-zero if the M2 instance has a degenerate scale; glm::normalize then returns NaN that contaminates the slope check (NaN < 0.35 is false → no early-out) and bestNormalZ goes NaN, breaking the walkable-floor heuristic. Length-check the transformed normal and fall back to the (0,0,1) flat default — same pattern as the WMO renderer. --- src/rendering/m2_renderer_instance.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/rendering/m2_renderer_instance.cpp b/src/rendering/m2_renderer_instance.cpp index 5be32b13..5b2ff476 100644 --- a/src/rendering/m2_renderer_instance.cpp +++ b/src/rendering/m2_renderer_instance.cpp @@ -765,8 +765,12 @@ std::optional M2Renderer::getFloorHeight(float glX, float glY, float glZ, if (nLen > 0.001f) { localN /= nLen; if (localN.z < 0.0f) localN = -localN; - worldN = glm::normalize( - glm::vec3(instance.modelMatrix * glm::vec4(localN, 0.0f))); + glm::vec3 transformedN = glm::vec3( + instance.modelMatrix * glm::vec4(localN, 0.0f)); + float wnLen = glm::length(transformedN); + if (wnLen > 0.001f) { + worldN = transformedN / wnLen; + } // else: keep worldN = (0,0,1) flat default if (std::abs(worldN.z) < 0.35f) continue; // too steep (~70° max slope) }