summaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/network/link.cpp28
-rw-r--r--game/network/link.h5
2 files changed, 33 insertions, 0 deletions
diff --git a/game/network/link.cpp b/game/network/link.cpp
index f3a79a6..19b60ab 100644
--- a/game/network/link.cpp
+++ b/game/network/link.cpp
@@ -1,7 +1,9 @@
#include "link.h"
#include <compare>
+#include <glm/gtx/transform.hpp>
#include <location.hpp>
#include <maths.h>
+#include <ray.hpp>
#include <tuple>
Link::Link(End a, End b, float l) : ends {{std::move(a), std::move(b)}}, length {l} { }
@@ -30,6 +32,12 @@ LinkStraight::positionAt(float dist, unsigned char start) const
return Location {es.first->pos + vehiclePositionOffset() + dir * dist, {vector_pitch(dir), vector_yaw(dir), 0}};
}
+bool
+LinkStraight::intersectRay(const Ray & ray) const
+{
+ return ray.passesCloseToEdges(std::array {ends.front().node->pos, ends.back().node->pos}, 1.F);
+}
+
Location
LinkCurve::positionAt(float dist, unsigned char start) const
{
@@ -44,3 +52,23 @@ LinkCurve::positionAt(float dist, unsigned char start) const
const auto pitch {vector_pitch({0, 0, (es.second->pos.z - es.first->pos.z) / length})};
return Location {relPos + relClimb + centreBase, {pitch, normalize(ang + dirOffset[start]), 0}};
}
+
+bool
+LinkCurve::intersectRay(const Ray & ray) const
+{
+ const auto & e0p {ends[0].node->pos};
+ const auto & e1p {ends[1].node->pos};
+ const auto slength = round_frac(length / 2.F, 5.F);
+ const auto segs = std::round(15.F * slength / std::pow(radius, 0.7F));
+ const auto step {glm::vec3 {arc_length(arc), e1p.z - e0p.z, slength} / segs};
+ const auto trans {glm::translate(centreBase)};
+
+ auto segCount = static_cast<std::size_t>(std::lround(segs)) + 1;
+ std::vector<glm::vec3> points;
+ points.reserve(segCount);
+ for (glm::vec3 swing = {arc.first, centreBase.z - e0p.z, 0.F}; segCount; swing += step, --segCount) {
+ const auto t {trans * glm::rotate(half_pi - swing.x, up) * glm::translate(glm::vec3 {radius, 0.F, swing.y})};
+ points.push_back(t * glm::vec4 {0, 0, 0, 1});
+ }
+ return ray.passesCloseToEdges(points, 1.F);
+}
diff --git a/game/network/link.h b/game/network/link.h
index 51c29ff..d9629de 100644
--- a/game/network/link.h
+++ b/game/network/link.h
@@ -9,6 +9,8 @@
#include <utility>
#include <vector>
+class Ray;
+
// Generic network node
// something that can be travelled to
// it has location
@@ -47,6 +49,7 @@ public:
NO_MOVE(Link);
[[nodiscard]] virtual Location positionAt(float dist, unsigned char start) const = 0;
+ [[nodiscard]] virtual bool intersectRay(const Ray &) const = 0;
std::array<End, 2> ends;
float length;
@@ -70,6 +73,7 @@ public:
NO_MOVE(LinkStraight);
[[nodiscard]] Location positionAt(float dist, unsigned char start) const override;
+ [[nodiscard]] bool intersectRay(const Ray &) const override;
};
LinkStraight::~LinkStraight() = default;
@@ -81,6 +85,7 @@ public:
NO_MOVE(LinkCurve);
[[nodiscard]] Location positionAt(float dist, unsigned char start) const override;
+ [[nodiscard]] bool intersectRay(const Ray &) const override;
glm::vec3 centreBase;
float radius;