aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kostenko <codeforsmile@gmail.com>2021-11-08 23:13:50 +0100
committerx2048 <codeforsmile@gmail.com>2022-03-07 23:45:26 +0100
commit1175f48d05888fba705363729ecf5ef2c75f0c5d (patch)
tree191bdd1f2fd4f8581063a5d128e652a67b4f71a7
parent54dccc480eb03adcf219a7add58f547284f40f76 (diff)
downloadminetest-1175f48d05888fba705363729ecf5ef2c75f0c5d.tar.gz
minetest-1175f48d05888fba705363729ecf5ef2c75f0c5d.tar.bz2
minetest-1175f48d05888fba705363729ecf5ef2c75f0c5d.zip
Detect 'insane' normals in checkMeshNormals.
Detect non-zero normals which point in the opposite direction from the face plane normal.
-rw-r--r--src/client/mesh.cpp16
1 files changed, 16 insertions, 0 deletions
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;