From 94f0e426bc8f298aec90fd0d4fcf6f823f8c399c Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 10 Jan 2022 02:07:53 +0000 Subject: Ray Trace cursor clicks to terrain surface --- game/geoData.cpp | 34 ++++++++++++++++++++++++++++++++++ game/geoData.h | 4 ++++ 2 files changed, 38 insertions(+) (limited to 'game') diff --git a/game/geoData.cpp b/game/geoData.cpp index 32ec55e..c9e909b 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -4,8 +4,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -132,6 +134,38 @@ GeoData::RayTracer::next() return cur; } +std::optional +GeoData::intersectRay(const Ray & ray) const +{ + if (glm::length(!ray.direction) <= 0) { + return {}; + } + RayTracer rt {ray.start / scale, ray.direction}; + while (true) { + const auto n {rt.next() * scale}; + try { + const auto point = quad(n); + for (auto offset : {0U, 1U}) { + glm::vec2 bary; + float distance; + if (glm::intersectRayTriangle(ray.start, ray.direction, point[offset], point[offset + 1], + point[offset + 2], bary, distance)) { + return point[offset] + ((point[offset + 1] - point[offset]) * bary[0]) + + ((point[offset + 2] - point[offset]) * bary[1]); + } + } + } + catch (std::range_error &) { + const auto rel = n / !ray.direction; + if (rel.x > 0 && rel.y > 0) { + return {}; + } + } + } + + return {}; +} + unsigned int GeoData::at(glm::ivec2 coord) const { diff --git a/game/geoData.h b/game/geoData.h index a296205..42c2d9d 100644 --- a/game/geoData.h +++ b/game/geoData.h @@ -2,10 +2,13 @@ #include #include +#include #include #include #include +class Ray; + class GeoData { public: struct Node { @@ -22,6 +25,7 @@ public: void loadFromImages(const std::filesystem::path &, float scale); [[nodiscard]] glm::vec3 positionAt(glm::vec2) const; + [[nodiscard]] std::optional intersectRay(const Ray &) const; [[nodiscard]] unsigned int at(glm::ivec2) const; [[nodiscard]] unsigned int at(int x, int y) const; -- cgit v1.2.3