summaryrefslogtreecommitdiff
path: root/game/network
diff options
context:
space:
mode:
Diffstat (limited to 'game/network')
-rw-r--r--game/network/link.cpp28
-rw-r--r--game/network/link.h34
-rw-r--r--game/network/rail.cpp31
-rw-r--r--game/network/rail.h23
4 files changed, 79 insertions, 37 deletions
diff --git a/game/network/link.cpp b/game/network/link.cpp
index ad09341..e45126f 100644
--- a/game/network/link.cpp
+++ b/game/network/link.cpp
@@ -1,9 +1,13 @@
#include "link.h"
#include <compare>
+#include <location.hpp>
+#include <maths.h>
#include <tuple>
Link::Link(End a, End b, float l) : ends {{std::move(a), std::move(b)}}, length {l} { }
+LinkCurve::LinkCurve(glm::vec3 c, float r, Arc a) : centreBase {c}, radius {r}, arc {std::move(a)} { }
+
bool
operator<(const glm::vec3 & a, const glm::vec3 & b)
{
@@ -16,3 +20,27 @@ operator<(const Node & a, const Node & b)
{
return a.pos < b.pos;
}
+
+Location
+LinkStraight::positionAt(float dist, unsigned char start) const
+{
+ const auto es {std::make_pair(ends[start].node.get(), ends[1 - start].node.get())};
+ const auto diff {es.second->pos - es.first->pos};
+ const auto dir {glm::normalize(diff)};
+ return Location {es.first->pos + vehiclePositionOffset() + dir * dist, {-vector_pitch(dir), vector_yaw(dir), 0}};
+}
+
+Location
+LinkCurve::positionAt(float dist, unsigned char start) const
+{
+ static constexpr std::array<float, 2> dirOffset {half_pi, -half_pi};
+ const auto frac {dist / length};
+ const auto es {std::make_pair(ends[start].node.get(), ends[1 - start].node.get())};
+ const auto as {std::make_pair(arc[start], arc[1 - start])};
+ const auto ang {as.first + ((as.second - as.first) * frac)};
+ const auto relPos {!sincosf(ang) * radius};
+ const auto relClimb {vehiclePositionOffset()
+ + glm::vec3 {0, -centreBase.y + es.first->pos.y + ((es.second->pos.y - es.first->pos.y) * frac), 0}};
+ const auto pitch {vector_pitch({0, (es.first->pos.y - es.second->pos.y) / length, 0})};
+ return Location {relPos + relClimb + centreBase, {pitch, normalize(ang + dirOffset[start]), 0}};
+}
diff --git a/game/network/link.h b/game/network/link.h
index a174275..16ae5f7 100644
--- a/game/network/link.h
+++ b/game/network/link.h
@@ -4,6 +4,7 @@
#include <array>
#include <glm/glm.hpp>
#include <location.hpp>
+#include <maths.h>
#include <memory>
#include <special_members.hpp>
#include <utility>
@@ -50,9 +51,42 @@ public:
std::array<End, 2> ends;
float length;
+
+protected:
+ [[nodiscard]] virtual glm::vec3
+ vehiclePositionOffset() const
+ {
+ return {};
+ }
};
bool operator<(const glm::vec3 & a, const glm::vec3 & b);
bool operator<(const Node & a, const Node & b);
+class LinkStraight : public virtual Link {
+public:
+ LinkStraight() = default;
+ inline ~LinkStraight() override = 0;
+ NO_COPY(LinkStraight);
+ NO_MOVE(LinkStraight);
+
+ [[nodiscard]] Location positionAt(float dist, unsigned char start) const override;
+};
+LinkStraight::~LinkStraight() = default;
+
+class LinkCurve : public virtual Link {
+public:
+ inline ~LinkCurve() override = 0;
+ LinkCurve(glm::vec3, float, Arc);
+ NO_COPY(LinkCurve);
+ NO_MOVE(LinkCurve);
+
+ [[nodiscard]] Location positionAt(float dist, unsigned char start) const override;
+
+ glm::vec3 centreBase;
+ float radius;
+ Arc arc;
+};
+LinkCurve::~LinkCurve() = default;
+
#endif
diff --git a/game/network/rail.cpp b/game/network/rail.cpp
index 0ef58d7..0cb2725 100644
--- a/game/network/rail.cpp
+++ b/game/network/rail.cpp
@@ -7,7 +7,6 @@
#include <game/network/network.impl.h> // IWYU pragma: keep
#include <gfx/models/vertex.hpp>
#include <glm/gtx/transform.hpp>
-#include <location.hpp>
#include <maths.h>
#include <stdexcept>
#include <utility>
@@ -123,7 +122,7 @@ round_sleepers(const float v)
RailLinkStraight::RailLinkStraight(const NodePtr & a, const NodePtr & b) : RailLinkStraight(a, b, b->pos - a->pos) { }
RailLinkStraight::RailLinkStraight(NodePtr a, NodePtr b, const glm::vec3 & diff) :
- RailLink({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff))
+ Link({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff))
{
std::vector<Vertex> vertices;
vertices.reserve(2 * railCrossSection.size());
@@ -139,24 +138,15 @@ RailLinkStraight::RailLinkStraight(NodePtr a, NodePtr b, const glm::vec3 & diff)
mesh = defaultMesh(vertices);
}
-Location
-RailLinkStraight::positionAt(float dist, unsigned char start) const
-{
- const auto es {std::make_pair(ends[start].node.get(), ends[1 - start].node.get())};
- const auto diff {es.second->pos - es.first->pos};
- const auto dir {glm::normalize(diff)};
- return Location {es.first->pos + RAIL_HEIGHT + dir * dist, {-vector_pitch(dir), vector_yaw(dir), 0}};
-}
-
RailLinkCurve::RailLinkCurve(const NodePtr & a, const NodePtr & b, glm::vec2 c) :
RailLinkCurve(a, b, {c.x, a->pos.y, c.y}, {!c, a->pos, b->pos})
{
}
RailLinkCurve::RailLinkCurve(const NodePtr & a, const NodePtr & b, glm::vec3 c, const Arc arc) :
- RailLink({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)},
+ Link({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)},
(glm::length(a->pos - c)) * arc_length(arc)),
- centreBase(c), radius {glm::length(ends[0].node->pos - centreBase)}, arc {arc}
+ LinkCurve {c, glm::length(ends[0].node->pos - c), arc}
{
const auto & e0p {ends[0].node->pos};
const auto & e1p {ends[1].node->pos};
@@ -178,17 +168,8 @@ RailLinkCurve::RailLinkCurve(const NodePtr & a, const NodePtr & b, glm::vec3 c,
mesh = defaultMesh(vertices);
}
-Location
-RailLinkCurve::positionAt(float dist, unsigned char start) const
+glm::vec3
+RailLink::vehiclePositionOffset() const
{
- static constexpr std::array<float, 2> dirOffset {half_pi, -half_pi};
- const auto frac {dist / length};
- const auto es {std::make_pair(ends[start].node.get(), ends[1 - start].node.get())};
- const auto as {std::make_pair(arc[start], arc[1 - start])};
- const auto ang {as.first + ((as.second - as.first) * frac)};
- const auto relPos {!sincosf(ang) * radius};
- const auto relClimb {RAIL_HEIGHT
- + glm::vec3 {0, -centreBase.y + es.first->pos.y + ((es.second->pos.y - es.first->pos.y) * frac), 0}};
- const auto pitch {vector_pitch({0, (es.first->pos.y - es.second->pos.y) / length, 0})};
- return Location {relPos + relClimb + centreBase, {pitch, normalize(ang + dirOffset[start]), 0}};
+ return RAIL_HEIGHT;
}
diff --git a/game/network/rail.h b/game/network/rail.h
index 3ecc59f..bfbb928 100644
--- a/game/network/rail.h
+++ b/game/network/rail.h
@@ -7,46 +7,45 @@
#include "link.h"
#include "network.h"
#include <glm/glm.hpp>
-#include <location.hpp>
-#include <maths.h>
#include <memory>
#include <span>
+#include <special_members.hpp>
class Shader;
class Vertex;
+struct Arc;
// A piece of rail track
-class RailLink : public Link, public Renderable {
+class RailLink : public virtual Link, public Renderable {
public:
- using Link::Link;
-
+ RailLink() = default;
+ inline ~RailLink() override = 0;
void render(const Shader &) const override;
+ NO_COPY(RailLink);
+ NO_MOVE(RailLink);
protected:
+ [[nodiscard]] glm::vec3 vehiclePositionOffset() const override;
[[nodiscard]] static MeshPtr defaultMesh(const std::span<Vertex> vertices);
MeshPtr mesh;
};
+RailLink::~RailLink() = default;
-class RailLinkStraight : public RailLink {
+class RailLinkStraight : public RailLink, public LinkStraight {
public:
RailLinkStraight(const NodePtr &, const NodePtr &);
- [[nodiscard]] Location positionAt(float dist, unsigned char start) const override;
private:
RailLinkStraight(NodePtr, NodePtr, const glm::vec3 & diff);
};
-class RailLinkCurve : public RailLink {
+class RailLinkCurve : public RailLink, public LinkCurve {
public:
RailLinkCurve(const NodePtr &, const NodePtr &, glm::vec2);
- [[nodiscard]] Location positionAt(float dist, unsigned char start) const override;
private:
RailLinkCurve(const NodePtr &, const NodePtr &, glm::vec3, const Arc);
- glm::vec3 centreBase;
- float radius;
- Arc arc;
};
class RailLinks : public NetworkOf<RailLink>, public WorldObject {