diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-12-18 14:55:33 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-12-18 14:55:33 +0000 |
commit | c54004cc4003698cd4583ea49e50f8993a9f953b (patch) | |
tree | 25df848e7440b7727545e29bf2556250d43f3eaa | |
parent | 2D vector_normal to work on any arithmetic (diff) | |
download | ilt-c54004cc4003698cd4583ea49e50f8993a9f953b.tar.bz2 ilt-c54004cc4003698cd4583ea49e50f8993a9f953b.tar.xz ilt-c54004cc4003698cd4583ea49e50f8993a9f953b.zip |
Don't make arbitrary changes to mesh for triangle corners
Making these arbitrary changes can lead to inverted adjacent faces,
instead just:
a) use the near node where it is, or
b) create the edge split along its length without lateral movement
Removes the check that these are already used and/or boundaries as
they're not being changed now anyway.
-rw-r--r-- | game/geoData.cpp | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp index d3b5485..8d7e18a 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -437,12 +437,6 @@ GeoData::setHeights(const std::span<const GlobalPosition3D> triangleStrip, const return std::make_pair(e, Triangle<2> {fromPoint, toPoint, p}.height()); }; }; - const auto notBoundary = std::views::filter([this](auto handleItr) { - return !is_boundary(*handleItr); - }); - const auto notEdgeBoundary = std::views::filter([this](auto handleItr) { - return !is_boundary(edge_handle(*handleItr)); - }); std::set<VertexHandle> newOrChangedVerts; auto addVertexForNormalUpdate = [this, &newOrChangedVerts](const VertexHandle vertex) { @@ -450,31 +444,36 @@ GeoData::setHeights(const std::span<const GlobalPosition3D> triangleStrip, const std::ranges::copy(vv_range(vertex), std::inserter(newOrChangedVerts, newOrChangedVerts.end())); }; - std::vector<VertexHandle> newVerts; - auto newVertexOnFace = [this, &vertexDistFrom, &opts, &vertexDistFromE, &newVerts, ¬Boundary, ¬EdgeBoundary]( - GlobalPosition3D tsPoint) { + auto newVertexOnFace = [this, &vertexDistFrom, &opts, &vertexDistFromE](GlobalPosition3D tsPoint) { const auto face = findPoint(tsPoint); // Check vertices - if (const auto nearest = std::ranges::min(std::views::iota(fv_begin(face), fv_end(face)) | notBoundary - | std::views::transform(vertexDistFrom(tsPoint)), - {}, &std::pair<VertexHandle, float>::second); - nearest.second < opts.nearNodeTolerance && !std::ranges::contains(newVerts, nearest.first)) { - point(nearest.first) = tsPoint; + if (const auto nearest = std::ranges::min( + std::views::iota(fv_begin(face), fv_end(face)) | std::views::transform(vertexDistFrom(tsPoint)), {}, + &std::pair<VertexHandle, float>::second); + nearest.second < opts.nearNodeTolerance) { return nearest.first; } // Check edges - if (const auto nearest = std::ranges::min(std::views::iota(fh_begin(face), fh_end(face)) | notEdgeBoundary - | std::views::transform(vertexDistFromE(tsPoint)), + if (const auto nearest = std::ranges::min( + std::views::iota(fh_begin(face), fh_end(face)) | std::views::transform(vertexDistFromE(tsPoint)), {}, &std::pair<HalfedgeHandle, float>::second); nearest.second < opts.nearNodeTolerance) { - return split(edge_handle(nearest.first), tsPoint); + const auto from = point(from_vertex_handle(nearest.first)).xy(); + const auto to = point(to_vertex_handle(nearest.first)).xy(); + const auto v = vector_normal(from - to); + const auto inter = linesIntersectAt(from, to, tsPoint.xy(), tsPoint.xy() + v); + if (!inter) { + throw std::runtime_error("Perpendicular lines do not cross"); + } + return split(edge_handle(nearest.first), *inter || tsPoint.z); } // Nothing close, split face return split(face, tsPoint); }; // New vertices for each vertex in triangleStrip - newVerts.reserve(newVerts.size()); + std::vector<VertexHandle> newVerts; + newVerts.reserve(triangleStrip.size()); std::transform(triangleStrip.begin(), triangleStrip.end(), std::back_inserter(newVerts), newVertexOnFace); std::ranges::for_each(newVerts, addVertexForNormalUpdate); |