summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/terrain2.cpp33
-rw-r--r--game/terrain2.h21
-rw-r--r--test/test-terrain.cpp16
3 files changed, 49 insertions, 21 deletions
diff --git a/game/terrain2.cpp b/game/terrain2.cpp
index 5d1c595..8d29143 100644
--- a/game/terrain2.cpp
+++ b/game/terrain2.cpp
@@ -54,22 +54,32 @@ TerrainMesh::findPoint(glm::vec2 p) const
return findPoint(p, *faces_begin());
}
-bool
-TerrainMesh::locate(const TerrainMesh::PointFace & pointFace, FaceHandle start) const
+TerrainMesh::PointFace::PointFace(const glm::vec2 p, const TerrainMesh * mesh) :
+ PointFace {p, mesh, *mesh->faces_begin()}
+{
+}
+
+TerrainMesh::PointFace::PointFace(const glm::vec2 p, const TerrainMesh * mesh, FaceHandle start) :
+ PointFace {p, mesh->findPoint(p, start)}
{
- if (pointFace.face.is_valid()) {
- assert(triangleContainsPoint(pointFace.point, pointFace.face));
- return true;
+}
+
+TerrainMesh::FaceHandle
+TerrainMesh::PointFace::face(const TerrainMesh * mesh, FaceHandle start) const
+{
+ if (_face.is_valid()) {
+ assert(mesh->triangleContainsPoint(point, _face));
+ return _face;
}
else {
- return (pointFace.face = findPoint(pointFace.point, start)).is_valid();
+ return (_face = mesh->findPoint(point, start));
}
}
-bool
-TerrainMesh::locate(const TerrainMesh::PointFace & pointFace) const
+TerrainMesh::FaceHandle
+TerrainMesh::PointFace::face(const TerrainMesh * mesh) const
{
- return locate(pointFace, *faces_begin());
+ return face(mesh, *mesh->faces_begin());
}
namespace {
@@ -126,9 +136,8 @@ TerrainMesh::walk(const PointFace & from, const glm::vec2 to, const std::functio
void
TerrainMesh::walkUntil(const PointFace & from, const glm::vec2 to, const std::function<bool(FaceHandle)> & op) const
{
- locate(from);
- assert(from.face.is_valid()); // TODO replace with a boundary search
- auto f = from.face;
+ assert(from.face(this).is_valid()); // TODO replace with a boundary search
+ auto f = from.face(this);
FaceHandle previousFace;
while (f.is_valid() && !op(f)) {
for (auto next = cfh_iter(f); next.is_valid(); ++next) {
diff --git a/game/terrain2.h b/game/terrain2.h
index 1a4e263..641d608 100644
--- a/game/terrain2.h
+++ b/game/terrain2.h
@@ -19,10 +19,26 @@ public:
explicit TerrainMesh(const std::filesystem::path &);
struct PointFace {
+ // NOLINTNEXTLINE(hicpp-explicit-conversions)
PointFace(const glm::vec2 p) : point {p} { }
+ PointFace(const glm::vec2 p, FaceHandle face) : point {p}, _face {face} { }
+
+ PointFace(const glm::vec2 p, const TerrainMesh *);
+ PointFace(const glm::vec2 p, const TerrainMesh *, FaceHandle start);
+
const glm::vec2 point;
- mutable FaceHandle face {};
+ [[nodiscard]] FaceHandle face(const TerrainMesh *) const;
+ [[nodiscard]] FaceHandle face(const TerrainMesh *, FaceHandle start) const;
+
+ [[nodiscard]] bool
+ isLocated() const
+ {
+ return _face.is_valid();
+ }
+
+ private:
+ mutable FaceHandle _face {};
};
[[nodiscard]] FaceHandle findPoint(glm::vec2) const;
@@ -35,7 +51,4 @@ protected:
[[nodiscard]] static bool triangleContainsPoint(const glm::vec2, const glm::vec2, const glm::vec2, const glm::vec2);
[[nodiscard]] bool triangleContainsPoint(const glm::vec2, FaceHandle) const;
[[nodiscard]] bool triangleContainsPoint(const glm::vec2, ConstFaceVertexIter) const;
-
- bool locate(const PointFace &) const;
- bool locate(const PointFace &, FaceHandle start) const;
};
diff --git a/test/test-terrain.cpp b/test/test-terrain.cpp
index bf30179..bf73356 100644
--- a/test/test-terrain.cpp
+++ b/test/test-terrain.cpp
@@ -49,10 +49,16 @@ BOOST_AUTO_TEST_CASE(trianglesContainsPoints)
BOOST_AUTO_TEST_CASE(locatePointFace)
{
const PointFace pf {{310002, 490003}};
- BOOST_CHECK(!pf.face.is_valid());
- BOOST_CHECK(locate(pf));
- BOOST_CHECK(pf.face.is_valid());
- BOOST_CHECK_EQUAL(pf.face.idx(), 0);
+ BOOST_CHECK(!pf.isLocated());
+ BOOST_CHECK(pf.face(this).is_valid());
+ BOOST_CHECK_EQUAL(pf.face(this).idx(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(preLocatePointFace)
+{
+ const PointFace pf {{310002, 490003}, this};
+ BOOST_CHECK(pf.isLocated());
+ BOOST_CHECK_EQUAL(pf.face(this).idx(), 0);
}
BOOST_AUTO_TEST_SUITE_END();
@@ -107,7 +113,7 @@ BOOST_DATA_TEST_CASE(walkTerrainSetsFromFace,
{
TerrainMesh::PointFace pf {from};
BOOST_CHECK_NO_THROW(fixedTerrtain.walk(pf, to, [](auto) {}));
- BOOST_CHECK_EQUAL(pf.face.idx(), visits.front());
+ BOOST_CHECK_EQUAL(pf.face(&fixedTerrtain).idx(), visits.front());
}
BOOST_DATA_TEST_CASE(walkTerrainUntil,