diff options
-rw-r--r-- | game/geoData.cpp | 26 | ||||
-rw-r--r-- | game/geoData.h | 10 | ||||
-rw-r--r-- | test/test-geoData.cpp | 3 |
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)); |