summaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/geoData.cpp39
-rw-r--r--game/geoData.h13
2 files changed, 52 insertions, 0 deletions
diff --git a/game/geoData.cpp b/game/geoData.cpp
index c3fb5dc..4537026 100644
--- a/game/geoData.cpp
+++ b/game/geoData.cpp
@@ -95,6 +95,45 @@ GeoData::positionAt(const glm::vec2 wcoord) const
return wcoord || heightMid;
}
+GeoData::RayTracer::RayTracer(glm::vec2 p0, glm::vec2 p1, float scale) : p {glm::floor(p0)}, d {glm::abs(p1 - p0)}
+{
+ using Limits = std::numeric_limits<typename glm::vec2::value_type>;
+ static_assert(Limits::has_infinity);
+ static constexpr const glm::vec2 inf {Limits::infinity(), -Limits::infinity()};
+
+ auto byAxis = [this, p0, p1, scale](auto axis) {
+ if (d[axis] == 0) {
+ inc[axis] = 0;
+ return inf[axis];
+ }
+ else if (p1[axis] > p0[axis]) {
+ inc[axis] = scale;
+ return (std::floor(p0[axis]) + 1 - p0[axis]) * d[1 - axis];
+ }
+ else {
+ inc[axis] = -scale;
+ return (p0[axis] - std::floor(p0[axis])) * d[1 - axis];
+ }
+ };
+
+ error = byAxis(0);
+ error -= byAxis(1);
+ inc.z = scale;
+}
+
+glm::vec2
+GeoData::RayTracer::next()
+{
+ glm::vec2 cur {p};
+
+ static constexpr const glm::vec2 m {1, -1};
+ const int axis = (error > 0) ? 1 : 0;
+ p[axis] += inc[axis];
+ error += d[1 - axis] * m[axis] * inc.z;
+
+ return cur;
+}
+
unsigned int
GeoData::at(glm::ivec2 coord) const
{
diff --git a/game/geoData.h b/game/geoData.h
index ffb7d64..7bd6ae5 100644
--- a/game/geoData.h
+++ b/game/geoData.h
@@ -32,6 +32,19 @@ public:
[[nodiscard]] float getScale() const;
[[nodiscard]] std::span<const Node> getNodes() const;
+ class RayTracer {
+ public:
+ RayTracer(glm::vec2 p0, glm::vec2 p1, float scale);
+
+ glm::vec2 next();
+
+ private:
+ glm::vec2 p;
+ const glm::vec2 d;
+ float error;
+ glm::vec3 inc;
+ };
+
protected:
Limits limit {}; // Base grid limits first(x,y) -> second(x,y)
glm::uvec2 size {};