From 1175f48d05888fba705363729ecf5ef2c75f0c5d Mon Sep 17 00:00:00 2001 From: Dmitry Kostenko Date: Mon, 8 Nov 2021 23:13:50 +0100 Subject: [PATCH] Detect 'insane' normals in checkMeshNormals. Detect non-zero normals which point in the opposite direction from the face plane normal. --- src/client/mesh.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/client/mesh.cpp b/src/client/mesh.cpp index c56eba2e2..070200889 100644 --- a/src/client/mesh.cpp +++ b/src/client/mesh.cpp @@ -331,6 +331,9 @@ void recalculateBoundingBox(scene::IMesh *src_mesh) bool checkMeshNormals(scene::IMesh *mesh) { + // Assume correct normals if this many first faces get it right. + static const u16 MAX_FACES_TO_CHECK = 9; + u32 buffer_count = mesh->getMeshBufferCount(); for (u32 i = 0; i < buffer_count; i++) { @@ -344,6 +347,19 @@ bool checkMeshNormals(scene::IMesh *mesh) if (!std::isfinite(length) || length < 1e-10f) return false; + + const u16 count = MYMIN(MAX_FACES_TO_CHECK * 3, buffer->getIndexCount()); + for (u16 i = 0; i < count; i += 3) { + + core::plane3df plane(buffer->getPosition(buffer->getIndices()[i]), + buffer->getPosition(buffer->getIndices()[i+1]), + buffer->getPosition(buffer->getIndices()[i+2])); + + for (u16 j = 0; j < 3; j++) + if (plane.Normal.dotProduct(buffer->getNormal(buffer->getIndices()[j])) < 0) + return false; + } + } return true;