From f53816a8fd9ec15ef03b5bf45472eda46e53c1ad Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 4 Nov 2023 21:05:35 +0000 Subject: Refactor to further simplify line/point operations Adds another perf test --- game/geoData.cpp | 18 +++++++++--------- test/perf-geoData.cpp | 13 +++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/game/geoData.cpp b/game/geoData.cpp index 5e49c94..c58658a 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -111,12 +111,16 @@ GeoData::PointFace::face(const GeoData * mesh) const } namespace { - [[nodiscard]] constexpr inline bool - pointLeftOfLine(const glm::vec2 p, const glm::vec2 e1, const glm::vec2 e2) + template typename Op> + [[nodiscard]] constexpr inline auto + pointLineOp(const glm::vec2 p, const glm::vec2 e1, const glm::vec2 e2) { - return (e2.x - e1.x) * (p.y - e1.y) > (e2.y - e1.y) * (p.x - e1.x); + return Op {}((e2.x - e1.x) * (p.y - e1.y), (e2.y - e1.y) * (p.x - e1.x)); } + constexpr auto pointLeftOfLine = pointLineOp; + constexpr auto pointLeftOfOrOnLine = pointLineOp; + static_assert(pointLeftOfLine({1, 2}, {1, 1}, {2, 2})); static_assert(pointLeftOfLine({2, 1}, {2, 2}, {1, 1})); static_assert(pointLeftOfLine({2, 2}, {1, 2}, {2, 1})); @@ -217,12 +221,8 @@ GeoData::walkUntil(const PointFace & from, const glm::vec2 to, const std::functi bool GeoData::triangleContainsPoint(const glm::vec2 p, const Triangle<2> & t) { - 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 * mul(t[1], t[0], p) >= 0 && det * mul(t[2], t[1], p) >= 0 && det * mul(t[0], t[2], p) >= 0; + return pointLeftOfOrOnLine(p, t[0], t[1]) && pointLeftOfOrOnLine(p, t[1], t[2]) + && pointLeftOfOrOnLine(p, t[2], t[0]); } bool diff --git a/test/perf-geoData.cpp b/test/perf-geoData.cpp index e1546c1..2d79a90 100644 --- a/test/perf-geoData.cpp +++ b/test/perf-geoData.cpp @@ -11,8 +11,21 @@ namespace { benchmark::DoNotOptimize(tm.findPoint({315555, 495556})); } } + + void + terrain_walk(benchmark::State & state) + { + const glm::vec2 point {310001, 490000}; + const GeoData::PointFace start {point, tm.findPoint(point)}; + for (auto _ : state) { + tm.walk(start, {319999, 500000}, [](auto f) { + benchmark::DoNotOptimize(f); + }); + } + } } BENCHMARK(terrain_findPoint); +BENCHMARK(terrain_walk); BENCHMARK_MAIN(); -- cgit v1.2.3