From 869cee70b1383c3ff486df2c9926dd39a32b3502 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 07:41:58 -0700 Subject: [PATCH] fix(painter): reject NaN endpoints and zero-length lines in paintAlongPath Two bugs: 1. NaN start/end produced NaN distances that the chunk-skip check (dist > width + 40) treated as 'always within range', so every chunk got painted. 2. Zero-length line caused glm::normalize to return NaN; same downstream effect. Compute lineDir manually after the length check so we never hit the divide-by-zero path. --- tools/editor/texture_painter.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/editor/texture_painter.cpp b/tools/editor/texture_painter.cpp index 5233623a..95d50493 100644 --- a/tools/editor/texture_painter.cpp +++ b/tools/editor/texture_painter.cpp @@ -243,11 +243,18 @@ void TexturePainter::autoPaintBySlope(float slopeThreshold, const std::string& s void TexturePainter::paintAlongPath(const glm::vec3& start, const glm::vec3& end, float width, const std::string& texturePath) { if (!terrain_ || texturePath.empty()) return; + if (!std::isfinite(start.x) || !std::isfinite(start.y) || + !std::isfinite(end.x) || !std::isfinite(end.y) || + !std::isfinite(width) || width <= 0.0f) return; uint32_t texId = ensureTextureInList(texturePath); glm::vec2 lineStart(start.x, start.y); glm::vec2 lineEnd(end.x, end.y); - glm::vec2 lineDir = glm::normalize(lineEnd - lineStart); float lineLen = glm::length(lineEnd - lineStart); + // Reject zero-length lines: glm::normalize would produce NaN, then + // every subsequent dist would be NaN and the chunk-skip check would + // pass — painting full strength on every chunk in the tile. + if (lineLen < 1e-4f) return; + glm::vec2 lineDir = (lineEnd - lineStart) / lineLen; for (int ci = 0; ci < 256; ci++) { auto& chunk = terrain_->chunks[ci];