diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-11-02 20:38:10 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-11-02 20:38:10 +0000 |
commit | 8a5d36623e4fa261aea16731954c9987dcbb1ef1 (patch) | |
tree | 1b00a22c77affc45babb1401e9ffe73d07347224 | |
parent | Generic N-dimensional terrain triangle (diff) | |
download | ilt-8a5d36623e4fa261aea16731954c9987dcbb1ef1.tar.bz2 ilt-8a5d36623e4fa261aea16731954c9987dcbb1ef1.tar.xz ilt-8a5d36623e4fa261aea16731954c9987dcbb1ef1.zip |
Terrain mesh method for getting the height/position at a point on the surface
-rw-r--r-- | game/terrain2.cpp | 11 | ||||
-rw-r--r-- | game/terrain2.h | 2 | ||||
-rw-r--r-- | test/test-terrain.cpp | 23 |
3 files changed, 36 insertions, 0 deletions
diff --git a/game/terrain2.cpp b/game/terrain2.cpp index 8d29143..b129284 100644 --- a/game/terrain2.cpp +++ b/game/terrain2.cpp @@ -1,5 +1,7 @@ #include "terrain2.h" #include <fstream> +#include <glm/gtx/intersect.hpp> +#include <maths.h> TerrainMesh::TerrainMesh(const std::filesystem::path & input) { @@ -124,6 +126,15 @@ TerrainMesh::findPoint(glm::vec2 p, OpenMesh::FaceHandle f) const return f; } +glm::vec3 +TerrainMesh::positionAt(const PointFace & p) const +{ + glm::vec3 out {}; + Triangle<3> t {this, fv_range(p.face(this))}; + glm::intersectLineTriangle(p.point ^ 0.F, up, t[0], t[1], t[2], out); + return p.point ^ out[0]; +} + void TerrainMesh::walk(const PointFace & from, const glm::vec2 to, const std::function<void(FaceHandle)> & op) const { diff --git a/game/terrain2.h b/game/terrain2.h index c2c3d19..f1d288e 100644 --- a/game/terrain2.h +++ b/game/terrain2.h @@ -58,6 +58,8 @@ public: [[nodiscard]] FaceHandle findPoint(glm::vec2) const; [[nodiscard]] FaceHandle findPoint(glm::vec2, FaceHandle start) const; + [[nodiscard]] glm::vec3 positionAt(const PointFace &) const; + void walk(const PointFace & from, const glm::vec2 to, const std::function<void(FaceHandle)> & op) const; void walkUntil(const PointFace & from, const glm::vec2 to, const std::function<bool(FaceHandle)> & op) const; diff --git a/test/test-terrain.cpp b/test/test-terrain.cpp index bf73356..38cb51f 100644 --- a/test/test-terrain.cpp +++ b/test/test-terrain.cpp @@ -1,4 +1,5 @@ #define BOOST_TEST_MODULE terrain +#include "testHelpers.h" #include <boost/test/data/test_case.hpp> #include <boost/test/unit_test.hpp> #include <stream_support.h> @@ -81,6 +82,28 @@ BOOST_DATA_TEST_CASE(findPointOnTerrain, BOOST_CHECK_EQUAL(fh, fixedTerrtain.findPoint(p, TerrainMesh::FaceHandle(start)).idx()); } +using FindPositionData = std::tuple<glm::vec2, float>; + +BOOST_DATA_TEST_CASE(findPositionAt, + boost::unit_test::data::make<FindPositionData>({ + // corners + {{310000, 490000}, 32.8F}, + {{310050, 490050}, 33.0F}, + {{310000, 490050}, 32.7F}, + {{310050, 490000}, 33.2F}, + {{310750, 490150}, 58.4F}, + // midpoints + {{310025, 490025}, 32.9F}, + {{310025, 490050}, 32.85F}, + {{310000, 490025}, 32.75F}, + // other + {{310751, 490152}, 58.326F}, + }), + p, h) +{ + BOOST_CHECK_CLOSE_VEC(fixedTerrtain.positionAt(p), p ^ h); +} + using WalkTerrainData = std::tuple<glm::vec2, glm::vec2, std::vector<int>>; BOOST_DATA_TEST_CASE(walkTerrain, |