diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-04-01 20:07:00 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-04-01 20:07:00 +0100 |
commit | a4b3f04803aceb9c750d4317a3e7cf3e56996518 (patch) | |
tree | 7f7ae6c8a5dad3b111567e5a168eb20e6a80e4d3 | |
parent | Factor out some helper lambdas into members (diff) | |
download | ilt-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
-rw-r--r-- | game/geoData.cpp | 56 | ||||
-rw-r--r-- | game/geoData.h | 3 |
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 {}; }; |