From 3abe940a22d99939b666bd806214c8b986cb3ed9 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 26 Nov 2023 14:20:28 +0000 Subject: Calculate vertex normals only Doesn't require half edge normals or face normals, which uses Newell's method, which results in integer overflow... Not to mention we don't need all the other normals. --- game/geoData.cpp | 16 ++++++++++++---- game/geoData.h | 6 ++++-- test/test-geoData.cpp | 5 ----- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/game/geoData.cpp b/game/geoData.cpp index 7710efe..70133a9 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -57,8 +57,7 @@ GeoData::loadFromAsciiGrid(const std::filesystem::path & input) }); } } - mesh.update_face_normals(); - mesh.update_vertex_normals(); + mesh.update_vertex_normals_only(); return mesh; }; @@ -77,8 +76,7 @@ GeoData::createFlat(GlobalPosition2D lower, GlobalPosition2D upper, GlobalDistan mesh.add_face(ll, uu, lu); mesh.add_face(ll, ul, uu); - mesh.update_face_normals(); - mesh.update_vertex_normals(); + mesh.update_vertex_normals_only(); return mesh; } @@ -317,3 +315,13 @@ GeoData::findBoundaryStart() const return is_boundary(heh); }); } + +void +GeoData::update_vertex_normals_only() +{ + for (auto vh : all_vertices()) { + Normal3D n; + calc_vertex_normal_correct(vh, n); + this->set_normal(vh, glm::normalize(n)); + } +} diff --git a/game/geoData.h b/game/geoData.h index 3141dbe..d4d0fb3 100644 --- a/game/geoData.h +++ b/game/geoData.h @@ -10,10 +10,10 @@ #include struct GeoDataTraits : public OpenMesh::DefaultTraits { - FaceAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status); + FaceAttributes(OpenMesh::Attributes::Status); EdgeAttributes(OpenMesh::Attributes::Status); VertexAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status); - HalfedgeAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status); + HalfedgeAttributes(OpenMesh::Attributes::Status); using Point = GlobalPosition3D; using Normal = Normal3D; }; @@ -105,6 +105,8 @@ protected: [[nodiscard]] bool triangleContainsPoint(const GlobalPosition2D, FaceHandle) const; [[nodiscard]] HalfedgeHandle findBoundaryStart() const; + void update_vertex_normals_only(); + private: GlobalPosition3D lowerExtent {}, upperExtent {}; }; diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp index 4e85f73..cb0466e 100644 --- a/test/test-geoData.cpp +++ b/test/test-geoData.cpp @@ -26,11 +26,6 @@ BOOST_AUTO_TEST_CASE(loadSuccess) BOOST_AUTO_TEST_CASE(normalsAllPointUp) { - BOOST_CHECK_EQUAL(std::count_if(faces_begin(), faces_end(), - [this](auto && vh) { - return normal(vh).z > 0; - }), - n_faces()); BOOST_CHECK_EQUAL(std::count_if(vertices_begin(), vertices_end(), [this](auto && vh) { return normal(vh).z > 0; -- cgit v1.2.3