From 2b5f69187e3a3e76621e349dcb3669b7db4e5226 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 05:26:46 -0700 Subject: [PATCH] fix(woc): fromTerrain skips degenerate triangles before normalize The walkability classifier did glm::normalize(cross(...)) without guarding for zero-length cross. A flat-on-itself triangle (e.g. all three vertices at the same height in a hole-edge case) produces NaN normal, NaN walkability flag, and crashes the downstream nz check. Now the cross-length is computed once and the triangle is skipped if it's effectively zero. --- src/pipeline/wowee_collision.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pipeline/wowee_collision.cpp b/src/pipeline/wowee_collision.cpp index f8e757b4..ea172576 100644 --- a/src/pipeline/wowee_collision.cpp +++ b/src/pipeline/wowee_collision.cpp @@ -74,10 +74,16 @@ WoweeCollision WoweeCollisionBuilder::fromTerrain(const ADTTerrain& terrain, glm::vec3 v01 = vtx(i01), v11 = vtx(i11); auto classifyTri = [&](const glm::vec3& a, const glm::vec3& b, const glm::vec3& c) { + // Skip degenerate triangles — would produce NaN normals + // and crash collision intersection tests downstream. + glm::vec3 cross = glm::cross(b - a, c - a); + float crossLen = glm::length(cross); + if (crossLen < 1e-8f) return; + WoweeCollision::Triangle tri; tri.v0 = a; tri.v1 = b; tri.v2 = c; - glm::vec3 normal = glm::normalize(glm::cross(b - a, c - a)); + glm::vec3 normal = cross / crossLen; float nz = std::abs(normal.z); tri.flags = 0;