summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2024-12-18 14:55:33 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2024-12-18 14:55:33 +0000
commitc54004cc4003698cd4583ea49e50f8993a9f953b (patch)
tree25df848e7440b7727545e29bf2556250d43f3eaa
parent2D vector_normal to work on any arithmetic (diff)
downloadilt-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.cpp35
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, &notBoundary, &notEdgeBoundary](
- 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);