diff options
Diffstat (limited to 'game')
-rw-r--r-- | game/geoData.cpp | 34 | ||||
-rw-r--r-- | game/geoData.h | 4 |
2 files changed, 38 insertions, 0 deletions
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 <array> #include <cmath> #include <cstddef> +#include <glm/gtx/intersect.hpp> #include <maths.h> #include <random> +#include <ray.hpp> #include <stb/stb_image.h> #include <stdexcept> #include <util.h> @@ -132,6 +134,38 @@ GeoData::RayTracer::next() return cur; } +std::optional<glm::vec3> +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 <filesystem> #include <glm/glm.hpp> +#include <optional> #include <span> #include <utility> #include <vector> +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<glm::vec3> intersectRay(const Ray &) const; [[nodiscard]] unsigned int at(glm::ivec2) const; [[nodiscard]] unsigned int at(int x, int y) const; |