#pragma once #include "chronology.h" #include "game/worldobject.h" #include "gfx/models/mesh.h" #include "gfx/renderable.h" #include "link.h" #include "network.h" #include #include #include #include class SceneShader; class Vertex; struct Arc; // A piece of rail track class RailLinkStraight; class RailLinkCurve; class RailLink : public virtual Link, public Renderable { public: RailLink() = default; inline ~RailLink() override = 0; using StraightLink = RailLinkStraight; using CurveLink = RailLinkCurve; void render(const SceneShader &) const override; NO_COPY(RailLink); NO_MOVE(RailLink); protected: [[nodiscard]] RelativePosition3D vehiclePositionOffset() const override; [[nodiscard]] static Mesh::Ptr defaultMesh(const std::span vertices); Mesh::Ptr mesh; }; RailLink::~RailLink() = default; class RailLinks; class RailLinkStraight : public RailLink, public LinkStraight { public: RailLinkStraight(NetworkLinkHolder &, const Node::Ptr &, const Node::Ptr &); struct Vertex { GlobalPosition3D a, b; glm::mat2 rotation; float textureRepeats; }; private: RailLinkStraight(NetworkLinkHolder &, Node::Ptr, Node::Ptr, const RelativePosition3D & diff); InstanceVertices::InstanceProxy instance; }; class RailLinkCurve : public RailLink, public LinkCurve { public: RailLinkCurve(NetworkLinkHolder &, const Node::Ptr &, const Node::Ptr &, GlobalPosition2D); struct Vertex { GlobalPosition3D a, b, c; float textureRepeats; }; private: RailLinkCurve( NetworkLinkHolder &, const Node::Ptr &, const Node::Ptr &, GlobalPosition3D, const Arc); InstanceVertices::InstanceProxy instance; }; class RailLinks : public NetworkOf, public WorldObject { public: RailLinks(); std::shared_ptr addLinksBetween(GlobalPosition3D start, GlobalPosition3D end); void render(const SceneShader &) const override; private: void tick(TickDuration elapsed) override; };