From 945a951aec17a7fbc6d69e4492a3a4a75f480ae8 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 29 Aug 2022 21:51:11 +0100 Subject: Link functions for testing if a ray clicks them --- game/network/link.cpp | 28 ++++++++++++++++++++++++++++ game/network/link.h | 5 +++++ 2 files changed, 33 insertions(+) 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 +#include #include #include +#include #include 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::lround(segs)) + 1; + std::vector 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 #include +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 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; -- cgit v1.2.3