summaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/network/network.h13
-rw-r--r--game/network/network.impl.h40
-rw-r--r--game/network/rail.cpp31
-rw-r--r--game/network/rail.h26
4 files changed, 71 insertions, 39 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();