diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-01-17 01:08:54 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-01-20 15:08:43 +0000 |
commit | a6e28fe377b41500d6ce3e0a9a4d6e6288d97f61 (patch) | |
tree | 7a77359865cb1359071d91ded0f0c574f57215bb | |
parent | Add mail rail network to render test, include curves (diff) | |
download | ilt-a6e28fe377b41500d6ce3e0a9a4d6e6288d97f61.tar.bz2 ilt-a6e28fe377b41500d6ce3e0a9a4d6e6288d97f61.tar.xz ilt-a6e28fe377b41500d6ce3e0a9a4d6e6288d97f61.zip |
Copy render vital link data to vertex buffer
-rw-r--r-- | game/network/network.h | 13 | ||||
-rw-r--r-- | game/network/network.impl.h | 40 | ||||
-rw-r--r-- | game/network/rail.cpp | 31 | ||||
-rw-r--r-- | game/network/rail.h | 26 | ||||
-rw-r--r-- | test/test-network.cpp | 40 |
5 files changed, 97 insertions, 53 deletions
diff --git a/game/network/network.h b/game/network/network.h index fa311ac..12c006c 100644 --- a/game/network/network.h +++ b/game/network/network.h @@ -1,5 +1,6 @@ #pragma once +#include "gfx/gl/instanceVertices.h" #include "link.h" #include <collection.h> #include <gfx/renderable.h> @@ -58,7 +59,13 @@ protected: std::shared_ptr<Texture> texture; }; -template<typename T> class NetworkOf : public Network, public Renderable { +template<typename LinkType> class NetworkLinkHolder { + friend LinkType; + mutable InstanceVertices<typename LinkType::Vertex> vertices; +}; + +template<typename T, typename... Links> +class NetworkOf : public Network, public Renderable, public NetworkLinkHolder<Links>... { protected: using Network::Network; @@ -75,7 +82,7 @@ public: requires std::is_base_of_v<T, L> { const auto node1 = candidateNodeAt(a).first, node2 = candidateNodeAt(b).first; - return std::make_shared<L>(node1, node2, std::forward<Params>(params)...); + return std::make_shared<L>(*this, node1, node2, std::forward<Params>(params)...); } template<typename L, typename... Params> @@ -84,7 +91,7 @@ public: requires std::is_base_of_v<T, L> { const auto node1 = nodeAt(a), node2 = nodeAt(b); - auto l {links.template create<L>(node1, node2, std::forward<Params>(params)...)}; + auto l {links.template create<L>(*this, node1, node2, std::forward<Params>(params)...)}; joinLinks(l); return l; } diff --git a/game/network/network.impl.h b/game/network/network.impl.h index f9595ed..c1f079d 100644 --- a/game/network/network.impl.h +++ b/game/network/network.impl.h @@ -2,9 +2,9 @@ #include <gfx/gl/sceneShader.h> #include <gfx/models/texture.h> -template<typename T> +template<typename T, typename... Links> void -NetworkOf<T>::render(const SceneShader & shader) const +NetworkOf<T, Links...>::render(const SceneShader & shader) const { if constexpr (std::is_base_of_v<Renderable, T>) { shader.absolute.use(); @@ -13,18 +13,18 @@ NetworkOf<T>::render(const SceneShader & shader) const } } -template<typename T> +template<typename T, typename... Links> void -NetworkOf<T>::joinLinks(const Link::Ptr & l) const +NetworkOf<T, Links...>::joinLinks(const Link::Ptr & l) const { for (const auto & ol : links.objects) { Network::joinLinks(l, ol); } } -template<typename T> +template<typename T, typename... Links> Link::Ptr -NetworkOf<T>::intersectRayLinks(const Ray<GlobalPosition3D> & ray) const +NetworkOf<T, Links...>::intersectRayLinks(const Ray<GlobalPosition3D> & ray) const { // Click link if (const auto link = std::find_if(links.objects.begin(), links.objects.end(), @@ -37,9 +37,9 @@ NetworkOf<T>::intersectRayLinks(const Ray<GlobalPosition3D> & ray) const return {}; } -template<typename T> +template<typename T, typename... Links> float -NetworkOf<T>::findNodeDirection(Node::AnyCPtr n) const +NetworkOf<T, Links...>::findNodeDirection(Node::AnyCPtr n) const { for (const auto & l : links.objects) { for (const auto & e : l->ends) { @@ -52,16 +52,16 @@ NetworkOf<T>::findNodeDirection(Node::AnyCPtr n) const throw std::runtime_error("Node exists but couldn't find it"); } -template<typename T> +template<typename T, typename... Links> Link::CCollection -NetworkOf<T>::candidateStraight(GlobalPosition3D n1, GlobalPosition3D n2) +NetworkOf<T, Links...>::candidateStraight(GlobalPosition3D n1, GlobalPosition3D n2) { return {candidateLink<typename T::StraightLink>(n1, n2)}; } -template<typename T> +template<typename T, typename... Links> Link::CCollection -NetworkOf<T>::candidateJoins(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf<T, Links...>::candidateJoins(GlobalPosition3D start, GlobalPosition3D end) { if (glm::length(RelativePosition3D(start - end)) < 2000.F) { return {}; @@ -73,24 +73,24 @@ NetworkOf<T>::candidateJoins(GlobalPosition3D start, GlobalPosition3D end) return {candidateLink<typename T::CurveLink>(c1s, c1e, c1c), candidateLink<typename T::CurveLink>(c2s, c2e, c2c)}; } -template<typename T> +template<typename T, typename... Links> Link::CCollection -NetworkOf<T>::candidateExtend(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf<T, Links...>::candidateExtend(GlobalPosition3D start, GlobalPosition3D end) { const auto [cstart, cend, centre] = genCurveDef(start, end, findNodeDirection(candidateNodeAt(start).first)); return {candidateLink<typename T::CurveLink>(cstart, cend, centre)}; } -template<typename T> +template<typename T, typename... Links> Link::CCollection -NetworkOf<T>::addStraight(GlobalPosition3D n1, GlobalPosition3D n2) +NetworkOf<T, Links...>::addStraight(GlobalPosition3D n1, GlobalPosition3D n2) { return {addLink<typename T::StraightLink>(n1, n2)}; } -template<typename T> +template<typename T, typename... Links> Link::CCollection -NetworkOf<T>::addJoins(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf<T, Links...>::addJoins(GlobalPosition3D start, GlobalPosition3D end) { if (glm::length(RelativePosition3D(start - end)) < 2000.F) { return {}; @@ -101,9 +101,9 @@ NetworkOf<T>::addJoins(GlobalPosition3D start, GlobalPosition3D end) return {addLink<typename T::CurveLink>(c1s, c1e, c1c), addLink<typename T::CurveLink>(c2s, c2e, c2c)}; } -template<typename T> +template<typename T, typename... Links> Link::CCollection -NetworkOf<T>::addExtend(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf<T, Links...>::addExtend(GlobalPosition3D start, GlobalPosition3D end) { const auto [cstart, cend, centre] = genCurveDef(start, end, findNodeDirection(nodeAt(start))); return {addLink<typename T::CurveLink>(cstart, cend, centre)}; diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 79aaf97..3d29ea5 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -13,12 +13,12 @@ #include <utility> #include <vector> -template class NetworkOf<RailLink>; +template class NetworkOf<RailLink, RailLinkStraight, RailLinkCurve>; constexpr auto RAIL_CROSSSECTION_VERTICES {5U}; constexpr Size3D RAIL_HEIGHT {0, 0, 250.F}; -RailLinks::RailLinks() : NetworkOf<RailLink> {"rails.jpg"} { } +RailLinks::RailLinks() : NetworkOf<RailLink, RailLinkStraight, RailLinkCurve> {"rails.jpg"} { } void RailLinks::tick(TickDuration) @@ -117,15 +117,20 @@ round_sleepers(const float v) return round_frac(v, sleepers); } -RailLinkStraight::RailLinkStraight(const Node::Ptr & a, const Node::Ptr & b) : RailLinkStraight(a, b, b->pos - a->pos) +RailLinkStraight::RailLinkStraight( + NetworkLinkHolder<RailLinkStraight> & instances, const Node::Ptr & a, const Node::Ptr & b) : + RailLinkStraight(instances, a, b, b->pos - a->pos) { } -RailLinkStraight::RailLinkStraight(Node::Ptr a, Node::Ptr b, const RelativePosition3D & diff) : - Link({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff)) +RailLinkStraight::RailLinkStraight( + NetworkLinkHolder<RailLinkStraight> & instances, Node::Ptr a, Node::Ptr b, const RelativePosition3D & diff) : + Link({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff)), + instance {instances.vertices.acquire( + ends[0].node->pos, ends[1].node->pos, flat_orientation(diff), round_sleepers(length / 2.F))} { if (glGenVertexArrays) { - std::vector<Vertex> vertices; + std::vector<::Vertex> vertices; vertices.reserve(2 * railCrossSection.size()); const auto len = round_sleepers(length / 2000.F); const glm::mat3 trans {flat_orientation(diff)}; @@ -139,15 +144,19 @@ RailLinkStraight::RailLinkStraight(Node::Ptr a, Node::Ptr b, const RelativePosit } } -RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, GlobalPosition2D c) : - RailLinkCurve(a, b, c || a->pos.z, {c || 0, a->pos, b->pos}) +RailLinkCurve::RailLinkCurve( + NetworkLinkHolder<RailLinkCurve> & instances, const Node::Ptr & a, const Node::Ptr & b, GlobalPosition2D c) : + RailLinkCurve(instances, a, b, c || a->pos.z, {c || 0, a->pos, b->pos}) { } -RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, GlobalPosition3D c, const Arc arc) : +RailLinkCurve::RailLinkCurve(NetworkLinkHolder<RailLinkCurve> & instances, const Node::Ptr & a, const Node::Ptr & b, + GlobalPosition3D c, const Arc arc) : Link({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)}, glm::length(RelativePosition3D(a->pos - c)) * arc_length(arc)), - LinkCurve {c, glm::length(RelativePosition3D(ends[0].node->pos - c)), arc} + LinkCurve {c, glm::length(RelativePosition3D(ends[0].node->pos - c)), arc}, + instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2.F))} + { if (glGenVertexArrays) { const auto & e0p {ends[0].node->pos}; @@ -157,7 +166,7 @@ RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, GlobalPos const auto step {RelativePosition3D {arc_length(arc), e1p.z - e0p.z, slength / 1000.F} / segs}; auto segCount = static_cast<std::size_t>(std::lround(segs)) + 1; - std::vector<Vertex> vertices; + std::vector<::Vertex> vertices; vertices.reserve(segCount * railCrossSection.size()); for (RelativePosition3D swing = {arc.first, centreBase.z - e0p.z, 0.F}; segCount; swing += step, --segCount) { const auto t { diff --git a/game/network/rail.h b/game/network/rail.h index 986b0aa..e06568f 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -40,23 +40,39 @@ protected: RailLink::~RailLink() = default; +class RailLinks; + class RailLinkStraight : public RailLink, public LinkStraight { public: - RailLinkStraight(const Node::Ptr &, const Node::Ptr &); + RailLinkStraight(NetworkLinkHolder<RailLinkStraight> &, const Node::Ptr &, const Node::Ptr &); + + struct Vertex { + GlobalPosition3D a, b; + glm::mat2 rotation; + float textureRepeats; + }; private: - RailLinkStraight(Node::Ptr, Node::Ptr, const RelativePosition3D & diff); + RailLinkStraight(NetworkLinkHolder<RailLinkStraight> &, Node::Ptr, Node::Ptr, const RelativePosition3D & diff); + InstanceVertices<Vertex>::InstanceProxy instance; }; class RailLinkCurve : public RailLink, public LinkCurve { public: - RailLinkCurve(const Node::Ptr &, const Node::Ptr &, GlobalPosition2D); + RailLinkCurve(NetworkLinkHolder<RailLinkCurve> &, const Node::Ptr &, const Node::Ptr &, GlobalPosition2D); + + struct Vertex { + GlobalPosition3D a, b, c; + float textureRepeats; + }; private: - RailLinkCurve(const Node::Ptr &, const Node::Ptr &, GlobalPosition3D, const Arc); + RailLinkCurve( + NetworkLinkHolder<RailLinkCurve> &, const Node::Ptr &, const Node::Ptr &, GlobalPosition3D, const Arc); + InstanceVertices<Vertex>::InstanceProxy instance; }; -class RailLinks : public NetworkOf<RailLink>, public WorldObject { +class RailLinks : public NetworkOf<RailLink, RailLinkStraight, RailLinkCurve>, public WorldObject { public: RailLinks(); diff --git a/test/test-network.cpp b/test/test-network.cpp index 0274b00..dbc184d 100644 --- a/test/test-network.cpp +++ b/test/test-network.cpp @@ -23,25 +23,37 @@ BOOST_GLOBAL_FIXTURE(ApplicationBase); BOOST_GLOBAL_FIXTURE(TestMainWindow); -struct TestLink : public LinkStraight { - TestLink(const Node::Ptr & a, const Node::Ptr & b) : TestLink {a, b, (a->pos - b->pos)} { } +struct TestLinkS; - TestLink(Node::Ptr a, Node::Ptr b, RelativePosition2D l) : +struct TestLink : public virtual Link { + using StraightLink = TestLinkS; + using CurveLink = TestLinkS; +}; + +struct TestLinkS : public TestLink, public LinkStraight { + TestLinkS(NetworkLinkHolder<TestLinkS> & network, const Node::Ptr & a, const Node::Ptr & b) : + TestLinkS {network, a, b, (a->pos - b->pos)} + { + } + + TestLinkS(NetworkLinkHolder<TestLinkS> &, Node::Ptr a, Node::Ptr b, RelativePosition2D l) : Link {{std::move(a), 0}, {std::move(b), pi}, glm::length(l)} { } - TestLink(Node::Ptr a, Node::Ptr b, float l) : Link {{std::move(a), 0}, {std::move(b), pi}, l} { } + struct Vertex { }; - using StraightLink = TestLink; - using CurveLink = TestLink; + TestLinkS(NetworkLinkHolder<TestLinkS> &, Node::Ptr a, Node::Ptr b, float l) : + Link {{std::move(a), 0}, {std::move(b), pi}, l} + { + } }; constexpr GlobalPosition3D p000 {0, 0, 0}, p100 {10000, 0, 0}, p200 {20000, 0, 0}, p300 {30000, 0, 0}; constexpr GlobalPosition3D p110 {10000, 10000, 0}; -struct TestNetwork : public NetworkOf<TestLink> { - TestNetwork() : NetworkOf<TestLink> {RESDIR "rails.jpg"} +struct TestNetwork : public NetworkOf<TestLink, TestLinkS> { + TestNetwork() : NetworkOf<TestLink, TestLinkS> {RESDIR "rails.jpg"} { // 0 1 2 // p000 <-> p100 <-> p200 <-> p300 @@ -49,12 +61,12 @@ struct TestNetwork : public NetworkOf<TestLink> { // \ 5 / // 3 | 4 // \-> p110 <-/ - addLink<TestLink>(p000, p100, 1.F); - addLink<TestLink>(p100, p200, 1.F); - addLink<TestLink>(p200, p300, 1.F); - addLink<TestLink>(p000, p110, 2.F); - addLink<TestLink>(p200, p110, 2.F); - addLink<TestLink>(p100, p110, 1.F); + addLink<TestLinkS>(p000, p100, 1.F); + addLink<TestLinkS>(p100, p200, 1.F); + addLink<TestLinkS>(p200, p300, 1.F); + addLink<TestLinkS>(p000, p110, 2.F); + addLink<TestLinkS>(p200, p110, 2.F); + addLink<TestLinkS>(p100, p110, 1.F); } }; |