summaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2024-04-01 20:07:00 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2024-04-01 20:07:00 +0100
commita4b3f04803aceb9c750d4317a3e7cf3e56996518 (patch)
tree7f7ae6c8a5dad3b111567e5a168eb20e6a80e4d3 /game
parentFactor out some helper lambdas into members (diff)
downloadilt-a4b3f04803aceb9c750d4317a3e7cf3e56996518.tar.bz2
ilt-a4b3f04803aceb9c750d4317a3e7cf3e56996518.tar.xz
ilt-a4b3f04803aceb9c750d4317a3e7cf3e56996518.zip
Replace face 4-way split
Fixes integer rounding issue and returns the new face handles
Diffstat (limited to 'game')
-rw-r--r--game/geoData.cpp56
-rw-r--r--game/geoData.h3
2 files changed, 59 insertions, 0 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp
index ccad9e0..059b03d 100644
--- a/game/geoData.cpp
+++ b/game/geoData.cpp
@@ -396,6 +396,62 @@ GeoData::triangleContainsTriangle(const Triangle<2> & a, const Triangle<2> & b)
return triangleContainsPoint(a.x, b) && triangleContainsPoint(a.y, b) && triangleContainsPoint(a.z, b);
}
+std::array<GeoData::FaceHandle, 4>
+GeoData::split(FaceHandle _fh)
+{
+ // Collect halfedges of face
+ const HalfedgeHandle he0 = halfedge_handle(_fh);
+ const HalfedgeHandle he1 = next_halfedge_handle(he0);
+ const HalfedgeHandle he2 = next_halfedge_handle(he1);
+
+ const EdgeHandle eh0 = edge_handle(he0);
+ const EdgeHandle eh1 = edge_handle(he1);
+ const EdgeHandle eh2 = edge_handle(he2);
+
+ // Collect points of face
+ const VertexHandle p0 = to_vertex_handle(he0);
+ const VertexHandle p1 = to_vertex_handle(he1);
+ const VertexHandle p2 = to_vertex_handle(he2);
+
+ // Calculate midpoint coordinates
+ const Point new0 = centre(he0);
+ const Point new1 = centre(he1);
+ const Point new2 = centre(he2);
+
+ // Add vertices at midpoint coordinates
+ const VertexHandle v0 = add_vertex(new0);
+ const VertexHandle v1 = add_vertex(new1);
+ const VertexHandle v2 = add_vertex(new2);
+
+ const bool split0 = !is_boundary(eh0);
+ const bool split1 = !is_boundary(eh1);
+ const bool split2 = !is_boundary(eh2);
+
+ // delete original face
+ delete_face(_fh, false);
+
+ // split boundary edges of deleted face ( if not boundary )
+ if (split0) {
+ split(eh0, v0);
+ }
+
+ if (split1) {
+ split(eh1, v1);
+ }
+
+ if (split2) {
+ split(eh2, v2);
+ }
+
+ // Retriangulate
+ return {
+ add_face(v0, p0, v1),
+ add_face(p2, v0, v2),
+ add_face(v2, v1, p1),
+ add_face(v2, v0, v1),
+ };
+}
+
void
GeoData::setHeights(const std::span<const GlobalPosition3D> triangleStrip)
{
diff --git a/game/geoData.h b/game/geoData.h
index 88eb304..6dacd9a 100644
--- a/game/geoData.h
+++ b/game/geoData.h
@@ -115,6 +115,9 @@ protected:
void update_vertex_normals_only();
+ using OpenMesh::TriMesh_ArrayKernelT<GeoDataTraits>::split;
+ std::array<FaceHandle, 4> split(FaceHandle);
+
private:
GlobalPosition3D lowerExtent {}, upperExtent {};
};