summaryrefslogtreecommitdiff
path: root/game/geoDataMesh.h
diff options
context:
space:
mode:
Diffstat (limited to 'game/geoDataMesh.h')
-rw-r--r--game/geoDataMesh.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/game/geoDataMesh.h b/game/geoDataMesh.h
new file mode 100644
index 0000000..00db67c
--- /dev/null
+++ b/game/geoDataMesh.h
@@ -0,0 +1,83 @@
+#pragma once
+
+#include "config/types.h"
+#include "ray.h"
+#include "triangle.h"
+#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
+#include <source_location>
+#include <thirdparty/openmesh/glmcompat.h>
+#include <thirdparty/openmesh/helpers.h>
+
+struct GeoDataTraits : public OpenMesh::DefaultTraits {
+ FaceAttributes(OpenMesh::Attributes::Status);
+ EdgeAttributes(OpenMesh::Attributes::Status);
+ VertexAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status);
+ HalfedgeAttributes(OpenMesh::Attributes::Status);
+ using Point = GlobalPosition3D;
+ using Normal = Normal3D;
+};
+
+class GeoDataMesh : public OpenMesh::TriMesh_ArrayKernelT<GeoDataTraits> {
+public:
+ struct PointFace {
+ // NOLINTNEXTLINE(hicpp-explicit-conversions)
+ PointFace(GlobalPosition2D coord) : point {coord} { }
+
+ PointFace(GlobalPosition2D coord, FaceHandle face) : point {coord}, faceCache {face} { }
+
+ PointFace(GlobalPosition2D coord, const GeoDataMesh *);
+ PointFace(GlobalPosition2D coord, GeoDataMesh const *, FaceHandle start);
+
+ const GlobalPosition2D point;
+ [[nodiscard]] FaceHandle face(const GeoDataMesh *) const;
+ [[nodiscard]] FaceHandle face(const GeoDataMesh *, FaceHandle start) const;
+
+ [[nodiscard]] bool
+ isLocated() const
+ {
+ return faceCache.is_valid();
+ }
+
+ private:
+ mutable FaceHandle faceCache;
+ };
+
+ template<glm::length_t Dim> using Triangle = ::Triangle<Dim, GlobalDistance>;
+
+ [[nodiscard]] FaceHandle findPoint(GlobalPosition2D) const;
+ [[nodiscard]] FaceHandle findPoint(GlobalPosition2D, FaceHandle) const;
+
+ [[nodiscard]] GlobalPosition3D positionAt(const PointFace &) const;
+
+protected:
+ void sanityCheck(const std::source_location & = std::source_location::current()) const;
+
+ [[nodiscard]] bool faceContainsPoint(GlobalPosition2D, FaceHandle) const;
+ [[nodiscard]] HalfedgeHandle findBoundaryStart() const;
+ [[nodiscard]] RelativePosition3D difference(HalfedgeHandle) const;
+ using HalfEdgeVertices = std::pair<VertexHandle, VertexHandle>;
+ [[nodiscard]] HalfEdgeVertices toVertexHandles(HalfedgeHandle) const;
+ using HalfEdgePoints = std::pair<GlobalPosition3D, GlobalPosition3D>;
+ [[nodiscard]] HalfEdgePoints points(HalfEdgeVertices) const;
+
+ template<glm::length_t D>
+ [[nodiscard]] RelativeDistance
+ length(HalfedgeHandle heh) const
+ {
+ return ::distance<D, GlobalDistance, glm::defaultp>(
+ point(to_vertex_handle(heh)), point(from_vertex_handle(heh)));
+ }
+
+ [[nodiscard]] GlobalPosition3D centre(HalfedgeHandle) const;
+
+ template<glm::length_t Dim>
+ [[nodiscard]] Triangle<Dim>
+ triangle(FaceHandle face) const
+ {
+ Triangle<Dim> triangle;
+ std::ranges::transform(fv_range(face), triangle.begin(), [this](auto vertex) {
+ return point(vertex);
+ });
+ return triangle;
+ }
+};