From acd16970bc93712e7c8c3996816242a04999818b Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 6 Mar 2021 18:53:22 +0000 Subject: Introduce the Train concept as a literal collection of rail vehicles --- application/main.cpp | 5 ++-- game/vehicles/railloco.cpp | 59 ++++++++++++++++-------------------------- game/vehicles/railloco.h | 51 +++++++++++++++--------------------- game/vehicles/vehicle.h | 7 ++--- gfx/followCameraController.cpp | 2 +- 5 files changed, 51 insertions(+), 73 deletions(-) diff --git a/application/main.cpp b/application/main.cpp index 8257a79..4d5cb7f 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -79,9 +79,10 @@ public: rl->addLinksBetween(e1, j); auto e2 = rl->addLinksBetween(e, {-925, 10, -1075})->ends[0].first->pos; rl->addLinksBetween(e2, j); - auto loco = world.create(l3); + const auto & train = world.create(l3); + auto b47 = std::make_shared("brush47"); for (int n = 0; n < 6; n++) { - loco->wagons.push_back(world.create(l3)); + train->create(b47); } } diff --git a/game/vehicles/railloco.cpp b/game/vehicles/railloco.cpp index 2650120..6745c8f 100644 --- a/game/vehicles/railloco.cpp +++ b/game/vehicles/railloco.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -52,8 +53,9 @@ RailVehicleClass::bogieOffset(ObjParser & o) float wheelBase {0}; // offset bogie positions so they can be set directly for (auto & object : o.objects) { // bogie object index - if (!object.first.starts_with("Bogie")) + if (!object.first.starts_with("Bogie")) { continue; + } std::set> vertexIds; for (const auto & face : object.second) { for (const auto & faceElement : face) { @@ -85,13 +87,13 @@ RailVehicle::render(const Shader & shader) const } void -RailLoco::move(TickDuration dur) +Train::move(TickDuration dur) { static std::mt19937 gen(std::random_device {}()); linkDist += dur.count() * speed; auto curLink {linkHist.getCurrent()}; while (linkDist > curLink.first->length) { - location = curLink.first->positionAt(curLink.first->length, curLink.second); + const auto location = curLink.first->positionAt(curLink.first->length, curLink.second); auto nexts {curLink.first->nexts[1 - curLink.second]}; auto last = std::remove_if(nexts.begin(), nexts.end(), [ang = location.rot.y](const Link::Next & n) { return std::abs(normalize(n.first.lock()->ends[n.second].second - ang)) > 0.1F; @@ -108,8 +110,14 @@ RailLoco::move(TickDuration dur) } } +void +Train::render(const Shader & shader) const +{ + apply(&Renderable::render, shader); +} + Location -RailLoco::getBogiePosition(float linkDist, float dist) const +Train::getBogiePosition(float linkDist, float dist) const { float b2linkDist {}; const auto b2Link = linkHist.getAt(dist - linkDist, &b2linkDist); @@ -117,45 +125,22 @@ RailLoco::getBogiePosition(float linkDist, float dist) const } void -RailLoco::updateRailVehiclePosition(RailVehicle * w, float trailBy) const +RailVehicle::move(const Train * t, float & trailBy) { - const auto overhang {(w->rvClass->length - w->rvClass->wheelBase) / 2}; - const auto & b1Pos = w->bogies[0] = getBogiePosition(linkDist, trailBy += overhang); - const auto & b2Pos = w->bogies[1] = getBogiePosition(linkDist, trailBy + rvClass->wheelBase); + const auto overhang {(rvClass->length - rvClass->wheelBase) / 2}; + const auto & b1Pos = bogies[0] = t->getBogiePosition(t->linkDist, trailBy += overhang); + const auto & b2Pos = bogies[1] = t->getBogiePosition(t->linkDist, trailBy += rvClass->wheelBase); const auto diff = glm::normalize(b2Pos.pos - b1Pos.pos); - w->location.pos = (b1Pos.pos + b2Pos.pos) / 2.F; - w->location.rot = {-vector_pitch(diff), vector_yaw(diff), 0}; + location.pos = (b1Pos.pos + b2Pos.pos) / 2.F; + location.rot = {-vector_pitch(diff), vector_yaw(diff), 0}; + trailBy += 0.6F + overhang; } void -RailLoco::tick(TickDuration dur) +Train::tick(TickDuration dur) { move(dur); - updateRailVehiclePosition(this, 0); - updateWagons(); -} - -void -RailLoco::updateWagons() const -{ - // Drag wagons - float trailBy {rvClass->length + 0.6F}; - for (const auto & wagon : wagons) { - const auto w {wagon.lock()}; - updateRailVehiclePosition(w.get(), trailBy); - trailBy += w->rvClass->length + 0.6F; - } -} - -void RailWagon::tick(TickDuration) { } -Brush47::Brush47(const LinkPtr & l) : RailLoco(std::make_shared("brush47"), l, 0) -{ - speed = 33.6F; - linkDist = rvClass->wheelBase; -} - -Brush47Wagon::Brush47Wagon(const LinkPtr & l) : RailWagon(std::make_shared("brush47"), l, 0) -{ - linkDist = rvClass->wheelBase; + float trailBy {0.F}; + apply(&RailVehicle::move, this, std::ref(trailBy)); } diff --git a/game/vehicles/railloco.h b/game/vehicles/railloco.h index 1bc0a51..0f240e2 100644 --- a/game/vehicles/railloco.h +++ b/game/vehicles/railloco.h @@ -2,7 +2,9 @@ #include "game/vehicles/vehicle.h" #include "game/worldobject.h" #include "gfx/models/mesh.h" +#include "gfx/renderable.h" #include +#include #include #include #include @@ -32,47 +34,36 @@ private: }; using RailVehicleClassPtr = std::shared_ptr; -class RailVehicle : public Vehicle { +class Train; +class RailVehicle : public Renderable { public: - explicit RailVehicle(RailVehicleClassPtr rvc, const LinkPtr & link, float linkDist = 0) : - Vehicle {link, linkDist}, rvClass {std::move(rvc)} - { - } + explicit RailVehicle(RailVehicleClassPtr rvc) : rvClass {std::move(rvc)} { } + + void move(const Train *, float & trailBy); + void render(const Shader & shader) const override; + Location location; + RailVehicleClassPtr rvClass; std::array bogies; - - friend class RailLoco; }; +using RailVehiclePtr = std::unique_ptr; -class RailWagon : public RailVehicle { +class Train : public Vehicle, public Collection { public: - using RailVehicle::RailVehicle; - void tick(TickDuration elapsed) override; -}; -using RailWagonPtr = std::weak_ptr; + explicit Train(const LinkPtr & link, float linkDist = 0) : Vehicle {link, linkDist} { } -class RailLoco : public RailVehicle { -public: - using RailVehicle::RailVehicle; - void tick(TickDuration elapsed) override; + [[nodiscard]] const Location & + getLocation() const override + { + return objects.front()->location; + } - std::vector wagons; + void render(const Shader & shader) const override; + + void tick(TickDuration elapsed) override; -private: void move(TickDuration dur); [[nodiscard]] Location getBogiePosition(float linkDist, float dist) const; - void updateRailVehiclePosition(RailVehicle *, float trailBy) const; - void updateWagons() const; -}; - -class Brush47 : public RailLoco { -public: - explicit Brush47(const LinkPtr & p); -}; - -class Brush47Wagon : public RailWagon { -public: - explicit Brush47Wagon(const LinkPtr & p); }; diff --git a/game/vehicles/vehicle.h b/game/vehicles/vehicle.h index a511d3c..89a6901 100644 --- a/game/vehicles/vehicle.h +++ b/game/vehicles/vehicle.h @@ -4,11 +4,12 @@ #include #include #include -#include #include #include #include +class Location; + class LinkHistory { public: using WEntry = std::pair; @@ -25,10 +26,10 @@ private: class Vehicle : public WorldObject, public Renderable { public: explicit Vehicle(const LinkPtr & link, float linkDist = 0); - float linkDist; // distance long current link + float linkDist; // distance along current link float speed {50}; // speed in m/s (~75 km/h) - Location location; + [[nodiscard]] virtual const Location & getLocation() const = 0; protected: LinkHistory linkHist; diff --git a/gfx/followCameraController.cpp b/gfx/followCameraController.cpp index e8a95b3..9e32e21 100644 --- a/gfx/followCameraController.cpp +++ b/gfx/followCameraController.cpp @@ -15,7 +15,7 @@ FollowCameraController::updateCamera(Camera * camera) const { const auto [pos, rot] = [this]() { const auto t {target.lock()}; - return std::tie(t->location.pos, t->location.rot); + return std::tie(t->getLocation().pos, t->getLocation().rot); }(); switch (mode) { -- cgit v1.2.3