summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/geoData.cpp10
-rw-r--r--game/geoData.h2
-rw-r--r--lib/triangle.h8
-rw-r--r--test/test-geoData.cpp10
4 files changed, 23 insertions, 7 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp
index 8e662b3..eef5dc7 100644
--- a/game/geoData.cpp
+++ b/game/geoData.cpp
@@ -601,3 +601,13 @@ GeoData::setHeights(const std::span<const GlobalPosition3D> triangleStrip, const
updateAllVertexNormals(newOrChangedVerts);
}
+
+void
+GeoData::sanityCheck() const
+{
+ if (!std::ranges::all_of(faces(), [this](const auto face) {
+ return triangle<2>(face).isUp();
+ })) {
+ throw std::logic_error("Upside down faces detected");
+ }
+}
diff --git a/game/geoData.h b/game/geoData.h
index 79924d3..01582a6 100644
--- a/game/geoData.h
+++ b/game/geoData.h
@@ -98,6 +98,8 @@ public:
return property(surface, h);
}
+ void sanityCheck() const;
+
protected:
template<glm::length_t Dim>
[[nodiscard]] Triangle<Dim>
diff --git a/lib/triangle.h b/lib/triangle.h
index 888481d..d5547ab 100644
--- a/lib/triangle.h
+++ b/lib/triangle.h
@@ -84,6 +84,14 @@ struct Triangle : public glm::vec<3, glm::vec<Dim, T, Q>> {
}
[[nodiscard]] constexpr auto
+ isUp() const
+ {
+ const auto edgeAB = sideDifference(1);
+ const auto edgeAC = sideDifference(2);
+ return edgeAB.x * edgeAC.y >= edgeAB.y * edgeAC.x;
+ }
+
+ [[nodiscard]] constexpr auto
p(const glm::length_t idx) const
{
return Base::operator[](idx);
diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp
index 5998789..9ec4656 100644
--- a/test/test-geoData.cpp
+++ b/test/test-geoData.cpp
@@ -29,11 +29,9 @@ BOOST_AUTO_TEST_CASE(loadSuccess)
BOOST_CHECK_EQUAL(upper, GlobalPosition3D(319950000, 499950000, 571600));
}
-BOOST_AUTO_TEST_CASE(normalsAllPointUp)
+BOOST_AUTO_TEST_CASE(sanityCheck)
{
- BOOST_CHECK(std::ranges::all_of(vertices(), [this](auto && vertex) {
- return normal(vertex).z > 0;
- }));
+ BOOST_CHECK_NO_THROW(sanityCheck());
}
BOOST_AUTO_TEST_CASE(trianglesContainsPoints)
@@ -214,9 +212,7 @@ BOOST_DATA_TEST_CASE(deform, loadFixtureJson<DeformTerrainData>("geoData/deform/
surface.colorBias = RGB {0, 0, 1};
auto gd = std::make_shared<GeoData>(GeoData::createFlat({0, 0}, {1000000, 1000000}, 100));
BOOST_CHECK_NO_THROW(gd->setHeights(points, {.surface = surface}));
- BOOST_CHECK(std::ranges::all_of(gd->vertices(), [&gd](auto && vertex) {
- return gd->normal(vertex).z > 0;
- }));
+ BOOST_CHECK_NO_THROW(gd->sanityCheck());
ApplicationBase ab;
TestMainWindow tmw;