diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2022-10-02 18:16:27 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2022-10-02 19:29:39 +0100 |
commit | d7587defa3cedd6e7ea6d0623aa8cd0f6b27819c (patch) | |
tree | 73b2dbaae87ebb5851ae09358f206d2f0f85a6f0 | |
parent | Latest clang-formatting (diff) | |
download | ilt-d7587defa3cedd6e7ea6d0623aa8cd0f6b27819c.tar.bz2 ilt-d7587defa3cedd6e7ea6d0623aa8cd0f6b27819c.tar.xz ilt-d7587defa3cedd6e7ea6d0623aa8cd0f6b27819c.zip |
Add support for searching a network for a ray intersection
-rw-r--r-- | game/network/network.cpp | 17 | ||||
-rw-r--r-- | game/network/network.h | 10 | ||||
-rw-r--r-- | game/network/network.impl.h | 15 |
3 files changed, 42 insertions, 0 deletions
diff --git a/game/network/network.cpp b/game/network/network.cpp index f59fe1e..775d420 100644 --- a/game/network/network.cpp +++ b/game/network/network.cpp @@ -5,7 +5,9 @@ #include <filesystem> #include <game/network/link.h> #include <gfx/models/texture.h> +#include <glm/gtx/intersect.hpp> #include <initializer_list> +#include <ray.hpp> #include <stdexcept> #include <utility> @@ -33,6 +35,21 @@ Network::findNodeAt(glm::vec3 pos) const return {}; } +Network::IntersectRayResult +Network::intersectRay(const Ray & ray) const +{ + // Click within 2m of a node + if (const auto node = std::find_if(nodes.begin(), nodes.end(), + [&ray](const NodePtr & node) { + glm::vec3 ipos, inorm; + return glm::intersectRaySphere(ray.start, ray.direction, node->pos, 2.F, ipos, inorm); + }); + node != nodes.end()) { + return *node; + } + return intersectRayLinks(ray); +} + void Network::joinLinks(const LinkPtr & l, const LinkPtr & ol) { diff --git a/game/network/network.h b/game/network/network.h index 2ce45f7..64f3f91 100644 --- a/game/network/network.h +++ b/game/network/network.h @@ -9,23 +9,30 @@ #include <sorting.hpp> #include <string> #include <utility> +#include <variant> class Texture; class Shader; +class Ray; class Network { public: + using LinkEnd = std::pair<LinkPtr, unsigned char>; + using IntersectRayResult = std::variant<std::nullptr_t, NodePtr, LinkEnd, LinkPtr>; explicit Network(const std::string & textureName); + virtual ~Network() = default; [[nodiscard]] NodePtr findNodeAt(glm::vec3) const; [[nodiscard]] NodePtr nodeAt(glm::vec3); [[nodiscard]] std::pair<NodePtr, bool> newNodeAt(glm::vec3); + [[nodiscard]] IntersectRayResult intersectRay(const Ray &) const; [[nodiscard]] Link::Nexts routeFromTo(const Link::End &, glm::vec3) const; [[nodiscard]] Link::Nexts routeFromTo(const Link::End &, const NodePtr &) const; protected: static void joinLinks(const LinkPtr & l, const LinkPtr & ol); + [[nodiscard]] virtual IntersectRayResult intersectRayLinks(const Ray &) const = 0; using Nodes = std::set<NodePtr, PtrSorter<NodePtr>>; Nodes nodes; @@ -39,6 +46,9 @@ protected: Collection<T> links; void joinLinks(const LinkPtr &) const; +protected: + [[nodiscard]] IntersectRayResult intersectRayLinks(const Ray &) const override; + public: template<typename L, typename... Params> std::shared_ptr<L> diff --git a/game/network/network.impl.h b/game/network/network.impl.h index d2e9ff0..afc9304 100644 --- a/game/network/network.impl.h +++ b/game/network/network.impl.h @@ -21,3 +21,18 @@ NetworkOf<T>::joinLinks(const LinkPtr & l) const Network::joinLinks(l, ol); } } + +template<typename T> +Network::IntersectRayResult +NetworkOf<T>::intersectRayLinks(const Ray & ray) const +{ + // Click link + if (const auto link = std::find_if(links.objects.begin(), links.objects.end(), + [&ray](const std::shared_ptr<T> & link) { + return link->intersectRay(ray); + }); + link != links.objects.end()) { + return *link; + } + return {}; +} |