From 2be260117a757288d419cf1564ccd6b91794399e Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 23 Nov 2024 14:18:56 +0000 Subject: Pass setHeights options as a struct with defaults --- game/geoData.cpp | 15 +++++++-------- game/geoData.h | 11 ++++++++++- test/test-geoData.cpp | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/game/geoData.cpp b/game/geoData.cpp index a63e03b..cc9a056 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -410,10 +410,8 @@ GeoData::triangleContainsTriangle(const Triangle<2> & a, const Triangle<2> & b) return triangleContainsPoint(a.x, b) && triangleContainsPoint(a.y, b) && triangleContainsPoint(a.z, b); } -static constexpr RelativeDistance MAX_SLOPE = .5F; - void -GeoData::setHeights(const std::span triangleStrip, const Surface &) +GeoData::setHeights(const std::span triangleStrip, const SetHeightsOpts & opts) { if (triangleStrip.size() < 3) { return; @@ -434,12 +432,12 @@ GeoData::setHeights(const std::span triangleStrip, const std::vector newVerts; newVerts.reserve(newVerts.size()); std::transform(triangleStrip.begin(), triangleStrip.end(), std::back_inserter(newVerts), - [this, &newVerts, &vertexDistFrom](const auto tsPoint) { + [this, &newVerts, &vertexDistFrom, &opts](const auto tsPoint) { const auto face = findPoint(tsPoint); if (const auto nearest = std::ranges::min(std::views::iota(fv_begin(face), fv_end(face)) | std::views::transform(vertexDistFrom(tsPoint)), {}, &std::pair::second); - nearest.second < 500.F && !std::ranges::contains(newVerts, nearest.first)) { + nearest.second < opts.nearNodeTolerance && !std::ranges::contains(newVerts, nearest.first)) { point(nearest.first) = tsPoint; return nearest.first; } @@ -466,7 +464,7 @@ GeoData::setHeights(const std::span triangleStrip, const // Cut along each edge of triangleStrip AB, AC, BC, BD, CD, CE etc std::map *> boundaryTriangles; - auto doBoundaryPart = [this, &boundaryTriangles, &newVerts, &vertexDistFrom]( + auto doBoundaryPart = [this, &boundaryTriangles, &newVerts, &vertexDistFrom, &opts]( VertexHandle start, VertexHandle end, const Triangle<3> & triangle) { boundaryTriangles.emplace(start, &triangle); const auto endPoint = point(end); @@ -484,7 +482,8 @@ GeoData::setHeights(const std::span triangleStrip, const if (const auto nextDist = std::ranges::min(nexts | std::views::transform(vertexDistFrom(*intersection)), {}, &std::pair::second); - nextDist.second < 500.F && !boundaryTriangles.contains(nextDist.first) + nextDist.second < opts.nearNodeTolerance + && !boundaryTriangles.contains(nextDist.first) && !std::ranges::contains(newVerts, nextDist.first)) { start = nextDist.first; point(start) = positionOnTriangle(*intersection, triangle); @@ -534,7 +533,7 @@ GeoData::setHeights(const std::span triangleStrip, const todoOutHalfEdges(toVertex); } else if (!toTriangle) { // point without the new strip, adjust vertically by limit - const auto maxOffset = static_cast(MAX_SLOPE * glm::length(difference(heh).xy())); + const auto maxOffset = static_cast(opts.maxSlope * glm::length(difference(heh).xy())); const auto newHeight = std::clamp(toPoint.z, fromPoint.z - maxOffset, fromPoint.z + maxOffset); if (newHeight != toPoint.z) { toPoint.z = newHeight; diff --git a/game/geoData.h b/game/geoData.h index 5daa7a4..51bb28b 100644 --- a/game/geoData.h +++ b/game/geoData.h @@ -142,7 +142,16 @@ public: [[nodiscard]] HalfedgeHandle findEntry(const GlobalPosition2D from, const GlobalPosition2D to) const; - void setHeights(const std::span triangleStrip, const Surface &); + struct SetHeightsOpts { + static constexpr auto DEFAULT_NEAR_NODE_TOLERANACE = 500.F; + static constexpr auto DEFAULT_MAX_SLOPE = 0.5F; + + const Surface & surface; + RelativeDistance nearNodeTolerance = DEFAULT_NEAR_NODE_TOLERANACE; + RelativeDistance maxSlope = DEFAULT_MAX_SLOPE; + }; + + void setHeights(std::span triangleStrip, const SetHeightsOpts &); [[nodiscard]] auto getExtents() const diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp index 35d6bae..17e1741 100644 --- a/test/test-geoData.cpp +++ b/test/test-geoData.cpp @@ -232,7 +232,7 @@ BOOST_DATA_TEST_CASE(deform, loadFixtureJson("geoData/deform/ Surface surface; surface.colorBias = RGB {0, 0, 1}; auto gd = std::make_shared(GeoData::createFlat({0, 0}, {1000000, 1000000}, 100)); - BOOST_CHECK_NO_THROW(gd->setHeights(points, surface)); + BOOST_CHECK_NO_THROW(gd->setHeights(points, {.surface = surface})); ApplicationBase ab; TestMainWindow tmw; -- cgit v1.2.3