summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/geoData.cpp26
-rw-r--r--game/geoData.h10
-rw-r--r--test/test-geoData.cpp3
3 files changed, 19 insertions, 20 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp
index d32bf8c..5e49c94 100644
--- a/game/geoData.cpp
+++ b/game/geoData.cpp
@@ -135,8 +135,7 @@ namespace {
OpenMesh::FaceHandle
GeoData::findPoint(glm::vec2 p, OpenMesh::FaceHandle f) const
{
- ConstFaceVertexIter vertices;
- while (f.is_valid() && !triangleContainsPoint(p, vertices = cfv_iter(f))) {
+ while (f.is_valid() && !triangleContainsPoint(p, triangle<2>(f))) {
for (auto next = cfh_iter(f); next.is_valid(); ++next) {
f = opposite_face_handle(*next);
if (f.is_valid()) {
@@ -156,7 +155,7 @@ glm::vec3
GeoData::positionAt(const PointFace & p) const
{
glm::vec3 out {};
- Triangle<3> t {this, fv_range(p.face(this))};
+ const auto t = triangle<3>(p.face(this));
glm::intersectLineTriangle(p.point ^ 0.F, up, t[0], t[1], t[2], out);
return p.point ^ out[0];
}
@@ -174,7 +173,7 @@ GeoData::intersectRay(const Ray & ray, FaceHandle face) const
walkUntil(PointFace {ray.start, face}, ray.start + (ray.direction * 10000.F), [&out, &ray, this](FaceHandle face) {
glm::vec2 bari {};
float dist {};
- Triangle<3> t {this, fv_range(face)};
+ const auto t = triangle<3>(face);
if (glm::intersectRayTriangle(ray.start, ray.direction, t[0], t[1], t[2], bari, dist)) {
out = t * bari;
return true;
@@ -216,23 +215,18 @@ GeoData::walkUntil(const PointFace & from, const glm::vec2 to, const std::functi
}
bool
-GeoData::triangleContainsPoint(const glm::vec2 p, const glm::vec2 a, const glm::vec2 b, const glm::vec2 c)
+GeoData::triangleContainsPoint(const glm::vec2 p, const Triangle<2> & t)
{
- const auto det = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
+ const auto mul = [](const glm::vec2 a, const glm::vec2 b, const glm::vec2 c) {
+ return (a.x - b.x) * (c.y - b.y) - (a.y - b.y) * (c.x - b.x);
+ };
+ const auto det = mul(t[1], t[0], t[2]);
- return det * ((b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x)) >= 0
- && det * ((c.x - b.x) * (p.y - b.y) - (c.y - b.y) * (p.x - b.x)) >= 0
- && det * ((a.x - c.x) * (p.y - c.y) - (a.y - c.y) * (p.x - c.x)) >= 0;
+ return det * mul(t[1], t[0], p) >= 0 && det * mul(t[2], t[1], p) >= 0 && det * mul(t[0], t[2], p) >= 0;
}
bool
GeoData::triangleContainsPoint(const glm::vec2 p, FaceHandle face) const
{
- return triangleContainsPoint(p, cfv_iter(face));
-}
-
-bool
-GeoData::triangleContainsPoint(const glm::vec2 p, ConstFaceVertexIter vertices) const
-{
- return triangleContainsPoint(p, point(*vertices++), point(*vertices++), point(*vertices++));
+ return triangleContainsPoint(p, triangle<2>(face));
}
diff --git a/game/geoData.h b/game/geoData.h
index 3a4f98e..b8561d0 100644
--- a/game/geoData.h
+++ b/game/geoData.h
@@ -85,9 +85,15 @@ public:
}
protected:
- [[nodiscard]] static bool triangleContainsPoint(const glm::vec2, const glm::vec2, const glm::vec2, const glm::vec2);
+ template<glm::length_t Dim>
+ [[nodiscard]] Triangle<Dim>
+ triangle(FaceHandle f) const
+ {
+ return {this, fv_range(f)};
+ }
+
+ [[nodiscard]] static bool triangleContainsPoint(const glm::vec2, const Triangle<2> &);
[[nodiscard]] bool triangleContainsPoint(const glm::vec2, FaceHandle) const;
- [[nodiscard]] bool triangleContainsPoint(const glm::vec2, ConstFaceVertexIter) const;
private:
glm::vec3 lowerExtent {}, upperExtent {};
diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp
index d79f5b8..b33c61e 100644
--- a/test/test-geoData.cpp
+++ b/test/test-geoData.cpp
@@ -37,9 +37,8 @@ BOOST_AUTO_TEST_CASE(normalsAllPointUp)
BOOST_AUTO_TEST_CASE(trianglesContainsPoints)
{
const auto face = face_handle(0);
- auto vertices = cfv_iter(face);
- BOOST_TEST_CONTEXT(point(*vertices++) << point(*vertices++) << point(*vertices++)) {
+ BOOST_TEST_CONTEXT(GeoData::Triangle<2>(this, fv_range(face))) {
BOOST_CHECK(triangleContainsPoint(glm::vec2 {xllcorner, yllcorner}, face));
BOOST_CHECK(triangleContainsPoint(glm::vec2 {xllcorner + cellsize, yllcorner + cellsize}, face));
BOOST_CHECK(triangleContainsPoint(glm::vec2 {xllcorner, yllcorner + cellsize}, face));