summaryrefslogtreecommitdiff
path: root/game/geoData.cpp
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2025-01-01 12:53:43 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2025-01-01 13:31:12 +0000
commitca3736b3a896557536c0aa4c0cee1f156e118b54 (patch)
treef1437deedb78992ec80f1c96539e3d3865b3a78c /game/geoData.cpp
parentAdd ArcSegment (diff)
downloadilt-ca3736b3a896557536c0aa4c0cee1f156e118b54.tar.bz2
ilt-ca3736b3a896557536c0aa4c0cee1f156e118b54.tar.xz
ilt-ca3736b3a896557536c0aa4c0cee1f156e118b54.zip
Walk terrain along a curve - edge cases exist
Diffstat (limited to 'game/geoData.cpp')
-rw-r--r--game/geoData.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp
index ce88e5b..37abc4c 100644
--- a/game/geoData.cpp
+++ b/game/geoData.cpp
@@ -290,6 +290,50 @@ GeoData::walkUntil(const PointFace & from, const GlobalPosition2D to, Tester<Wal
}
void
+GeoData::walk(const PointFace & from, GlobalPosition2D to, GlobalPosition2D centre, Consumer<WalkStep> op) const
+{
+ walkUntil(from, to, centre, [&op](const auto & fh) {
+ op(fh);
+ return false;
+ });
+}
+
+void
+GeoData::walkUntil(const PointFace & from, GlobalPosition2D to, GlobalPosition2D centre, Tester<WalkStep> op) const
+{
+ WalkStep step {
+ .current = from.face(this),
+ };
+ if (!step.current.is_valid()) {
+ const auto entryEdge = findEntry(from.point, to);
+ if (!entryEdge.is_valid()) {
+ return;
+ }
+ step.current = opposite_face_handle(entryEdge);
+ }
+ ArcSegment arc {centre, from.point, to};
+ while (step.current.is_valid() && !op(step)) {
+ step.previous = step.current;
+ for (const auto next : fh_range(step.current)) {
+ if (opposite_halfedge_handle(next) == step.exitHalfedge) {
+ continue;
+ }
+ step.current = opposite_face_handle(next);
+ if (step.current.is_valid()) {
+ const auto e1 = point(to_vertex_handle(next));
+ const auto e2 = point(to_vertex_handle(opposite_halfedge_handle(next)));
+ if (const auto intersect = arc.crossesLineAt(e1, e2)) {
+ step.exitHalfedge = next;
+ step.exitPosition = intersect.value();
+ break;
+ }
+ }
+ step.current.reset();
+ }
+ }
+}
+
+void
GeoData::boundaryWalk(Consumer<HalfedgeHandle> op) const
{
boundaryWalk(op, findBoundaryStart());