diff options
Diffstat (limited to 'game/vehicles')
-rw-r--r-- | game/vehicles/linkHistory.cpp | 41 | ||||
-rw-r--r-- | game/vehicles/linkHistory.h | 21 | ||||
-rw-r--r-- | game/vehicles/railVehicle.cpp | 26 | ||||
-rw-r--r-- | game/vehicles/railVehicle.h | 29 | ||||
-rw-r--r-- | game/vehicles/railVehicleClass.cpp (renamed from game/vehicles/railloco.cpp) | 72 | ||||
-rw-r--r-- | game/vehicles/railVehicleClass.h | 33 | ||||
-rw-r--r-- | game/vehicles/railloco.h | 69 | ||||
-rw-r--r-- | game/vehicles/train.cpp | 60 | ||||
-rw-r--r-- | game/vehicles/train.h | 33 | ||||
-rw-r--r-- | game/vehicles/vehicle.cpp | 41 | ||||
-rw-r--r-- | game/vehicles/vehicle.h | 16 |
11 files changed, 248 insertions, 193 deletions
diff --git a/game/vehicles/linkHistory.cpp b/game/vehicles/linkHistory.cpp new file mode 100644 index 0000000..4fac4ba --- /dev/null +++ b/game/vehicles/linkHistory.cpp @@ -0,0 +1,41 @@ +#include "linkHistory.h" +#include "game/network/link.h" +#include <memory> + +LinkHistory::Entry +LinkHistory::add(const LinkWPtr & l, unsigned char d) +{ + links.insert(links.begin(), {l, d}); + const auto lp = l.lock(); + totalLen += lp->length; + while (totalLen >= 1000.F && !links.empty()) { + totalLen -= links.back().first.lock()->length; + links.pop_back(); + } + return {lp, d}; +} + +LinkHistory::Entry +LinkHistory::getCurrent() const +{ + return {links.front().first.lock(), links.front().second}; +} + +LinkHistory::Entry +LinkHistory::getAt(float len, float * rem) const +{ + auto litr = links.begin(); + while (len > 0.F && litr != links.end()) { + litr++; + if (litr != links.end()) { + len -= litr->first.lock()->length; + } + } + if (litr == links.end()) { + litr--; + } + if (rem) { + *rem = -len; + } + return {litr->first.lock(), litr->second}; +} diff --git a/game/vehicles/linkHistory.h b/game/vehicles/linkHistory.h new file mode 100644 index 0000000..31d0023 --- /dev/null +++ b/game/vehicles/linkHistory.h @@ -0,0 +1,21 @@ +#ifndef LINKHISTORY_H +#define LINKHISTORY_H + +#include <game/network/link.h> +#include <utility> +#include <vector> + +class LinkHistory { +public: + using WEntry = std::pair<LinkWPtr, unsigned char /*dir*/>; + using Entry = std::pair<LinkCPtr, unsigned char /*dir*/>; + Entry add(const LinkWPtr &, unsigned char); + [[nodiscard]] Entry getCurrent() const; + [[nodiscard]] Entry getAt(float, float *) const; + +private: + std::vector<WEntry> links; + float totalLen {0.F}; +}; + +#endif diff --git a/game/vehicles/railVehicle.cpp b/game/vehicles/railVehicle.cpp new file mode 100644 index 0000000..a2373e7 --- /dev/null +++ b/game/vehicles/railVehicle.cpp @@ -0,0 +1,26 @@ +#include "railVehicle.h" +#include "railVehicleClass.h" +#include "train.h" +#include <array> +#include <glm/glm.hpp> +#include <location.hpp> +#include <maths.h> +#include <memory> + +void +RailVehicle::render(const Shader & shader) const +{ + rvClass->render(shader, location, bogies); +} + +void +RailVehicle::move(const Train * t, float & trailBy) +{ + 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); + location.pos = (b1Pos.pos + b2Pos.pos) / 2.F; + location.rot = {-vector_pitch(diff), vector_yaw(diff), 0}; + trailBy += 0.6F + overhang; +} diff --git a/game/vehicles/railVehicle.h b/game/vehicles/railVehicle.h new file mode 100644 index 0000000..a089f1d --- /dev/null +++ b/game/vehicles/railVehicle.h @@ -0,0 +1,29 @@ +#ifndef RAILVEHICLE_H +#define RAILVEHICLE_H + +#include "gfx/renderable.h" +#include "railVehicleClass.h" +#include <array> +#include <location.hpp> +#include <memory> +#include <utility> + +class Shader; + +class Train; +class RailVehicle : public Renderable { +public: + 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<Location, 2> bogies; +}; +using RailVehiclePtr = std::unique_ptr<RailVehicle>; + +#endif diff --git a/game/vehicles/railloco.cpp b/game/vehicles/railVehicleClass.cpp index 6745c8f..71890b8 100644 --- a/game/vehicles/railloco.cpp +++ b/game/vehicles/railVehicleClass.cpp @@ -1,21 +1,20 @@ -#include "railloco.h" +#include "railVehicleClass.h" #include "gfx/gl/shader.h" +#include "gfx/models/mesh.h" #include "gfx/models/obj.h" #include "gfx/models/texture.h" #include <algorithm> #include <array> #include <cache.h> #include <filesystem> -#include <functional> #include <glm/glm.hpp> #include <iterator> #include <lib/resource.h> #include <location.hpp> #include <map> -#include <maths.h> #include <memory> -#include <random> #include <set> +#include <string> #include <utility> #include <vector> @@ -79,68 +78,3 @@ RailVehicleClass::objectLength(ObjParser & o) }); return mme.second->z - mme.first->z; } - -void -RailVehicle::render(const Shader & shader) const -{ - rvClass->render(shader, location, bogies); -} - -void -Train::move(TickDuration dur) -{ - static std::mt19937 gen(std::random_device {}()); - linkDist += dur.count() * speed; - auto curLink {linkHist.getCurrent()}; - while (linkDist > curLink.first->length) { - 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; - }); - if (last != nexts.begin()) { - auto off = std::uniform_int_distribution<>(0, std::distance(nexts.begin(), last) - 1)(gen); - linkDist -= curLink.first->length; - curLink = linkHist.add(nexts[off].first, nexts[off].second); - } - else { - linkDist = curLink.first->length; - speed = 0; - } - } -} - -void -Train::render(const Shader & shader) const -{ - apply(&Renderable::render, shader); -} - -Location -Train::getBogiePosition(float linkDist, float dist) const -{ - float b2linkDist {}; - const auto b2Link = linkHist.getAt(dist - linkDist, &b2linkDist); - return b2Link.first->positionAt(b2linkDist, b2Link.second); -} - -void -RailVehicle::move(const Train * t, float & trailBy) -{ - 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); - location.pos = (b1Pos.pos + b2Pos.pos) / 2.F; - location.rot = {-vector_pitch(diff), vector_yaw(diff), 0}; - trailBy += 0.6F + overhang; -} - -void -Train::tick(TickDuration dur) -{ - move(dur); - - float trailBy {0.F}; - apply(&RailVehicle::move, this, std::ref(trailBy)); -} diff --git a/game/vehicles/railVehicleClass.h b/game/vehicles/railVehicleClass.h new file mode 100644 index 0000000..b902367 --- /dev/null +++ b/game/vehicles/railVehicleClass.h @@ -0,0 +1,33 @@ +#ifndef RAILVEHICLECLASS_H +#define RAILVEHICLECLASS_H + +#include "gfx/models/mesh.h" +#include <array> +#include <memory> +#include <string> + +class Shader; +class Texture; +class ObjParser; +class Location; + +class RailVehicleClass { +public: + explicit RailVehicleClass(const std::string & name); + + void render(const Shader &, const Location &, const std::array<Location, 2> &) const; + + std::array<MeshPtr, 2> bogies; + MeshPtr bodyMesh; + std::shared_ptr<Texture> texture; + float wheelBase; + float length; + +private: + RailVehicleClass(std::unique_ptr<ObjParser> obj, std::shared_ptr<Texture>); + static float bogieOffset(ObjParser & o); + static float objectLength(ObjParser & o); +}; +using RailVehicleClassPtr = std::shared_ptr<RailVehicleClass>; + +#endif diff --git a/game/vehicles/railloco.h b/game/vehicles/railloco.h deleted file mode 100644 index 0f240e2..0000000 --- a/game/vehicles/railloco.h +++ /dev/null @@ -1,69 +0,0 @@ -#include "game/network/link.h" -#include "game/vehicles/vehicle.h" -#include "game/worldobject.h" -#include "gfx/models/mesh.h" -#include "gfx/renderable.h" -#include <array> -#include <collection.hpp> -#include <location.hpp> -#include <memory> -#include <string> -#include <utility> -#include <vector> - -class Shader; -class Texture; -class ObjParser; - -class RailVehicleClass { -public: - explicit RailVehicleClass(const std::string & name); - - void render(const Shader &, const Location &, const std::array<Location, 2> &) const; - - std::array<MeshPtr, 2> bogies; - MeshPtr bodyMesh; - std::shared_ptr<Texture> texture; - float wheelBase; - float length; - -private: - RailVehicleClass(std::unique_ptr<ObjParser> obj, std::shared_ptr<Texture>); - static float bogieOffset(ObjParser & o); - static float objectLength(ObjParser & o); -}; -using RailVehicleClassPtr = std::shared_ptr<RailVehicleClass>; - -class Train; -class RailVehicle : public Renderable { -public: - 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<Location, 2> bogies; -}; -using RailVehiclePtr = std::unique_ptr<RailVehicle>; - -class Train : public Vehicle, public Collection<RailVehicle, false> { -public: - explicit Train(const LinkPtr & link, float linkDist = 0) : Vehicle {link, linkDist} { } - - [[nodiscard]] const Location & - getLocation() const override - { - return objects.front()->location; - } - - void render(const Shader & shader) const override; - - void tick(TickDuration elapsed) override; - - void move(TickDuration dur); - [[nodiscard]] Location getBogiePosition(float linkDist, float dist) const; -}; diff --git a/game/vehicles/train.cpp b/game/vehicles/train.cpp new file mode 100644 index 0000000..e211f16 --- /dev/null +++ b/game/vehicles/train.cpp @@ -0,0 +1,60 @@ +#include "train.h" +#include "game/vehicles/linkHistory.h" +#include "game/vehicles/railVehicle.h" +#include "gfx/renderable.h" +#include "location.hpp" +#include <algorithm> +#include <array> +#include <functional> +#include <glm/glm.hpp> +#include <iterator> +#include <maths.h> +#include <random> +#include <utility> + +void +Train::move(TickDuration dur) +{ + static std::mt19937 gen(std::random_device {}()); + linkDist += dur.count() * speed; + auto curLink {linkHist.getCurrent()}; + while (linkDist > curLink.first->length) { + 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; + }); + if (last != nexts.begin()) { + auto off = std::uniform_int_distribution<>(0, std::distance(nexts.begin(), last) - 1)(gen); + linkDist -= curLink.first->length; + curLink = linkHist.add(nexts[off].first, nexts[off].second); + } + else { + linkDist = curLink.first->length; + speed = 0; + } + } +} + +void +Train::render(const Shader & shader) const +{ + apply(&Renderable::render, shader); +} + +Location +Train::getBogiePosition(float linkDist, float dist) const +{ + float b2linkDist {}; + const auto b2Link = linkHist.getAt(dist - linkDist, &b2linkDist); + return b2Link.first->positionAt(b2linkDist, b2Link.second); +} + +void +Train::tick(TickDuration dur) +{ + move(dur); + + float trailBy {0.F}; + apply(&RailVehicle::move, this, std::ref(trailBy)); +} diff --git a/game/vehicles/train.h b/game/vehicles/train.h new file mode 100644 index 0000000..34a9d28 --- /dev/null +++ b/game/vehicles/train.h @@ -0,0 +1,33 @@ +#ifndef TRAIN_H +#define TRAIN_H + +#include "game/network/link.h" +#include "game/worldobject.h" +#include "railVehicle.h" +#include "vehicle.h" +#include <collection.hpp> +#include <location.hpp> +#include <memory> +#include <vector> + +class Shader; + +class Train : public Vehicle, public Collection<RailVehicle, false> { +public: + explicit Train(const LinkPtr & link, float linkDist = 0) : Vehicle {link, linkDist} { } + + [[nodiscard]] const Location & + getLocation() const override + { + return objects.front()->location; + } + + void render(const Shader & shader) const override; + + void tick(TickDuration elapsed) override; + + void move(TickDuration dur); + [[nodiscard]] Location getBogiePosition(float linkDist, float dist) const; +}; + +#endif diff --git a/game/vehicles/vehicle.cpp b/game/vehicles/vehicle.cpp index 26e33d4..d98533e 100644 --- a/game/vehicles/vehicle.cpp +++ b/game/vehicles/vehicle.cpp @@ -1,47 +1,8 @@ #include "vehicle.h" #include "game/network/link.h" -#include <memory> -#include <utility> +#include "game/vehicles/linkHistory.h" Vehicle::Vehicle(const LinkPtr & l, float ld) : linkDist {ld} { linkHist.add(l, 0); } - -LinkHistory::Entry -LinkHistory::add(const LinkWPtr & l, unsigned char d) -{ - links.insert(links.begin(), {l, d}); - const auto lp = l.lock(); - totalLen += lp->length; - while (totalLen >= 1000.F && !links.empty()) { - totalLen -= links.back().first.lock()->length; - links.pop_back(); - } - return {lp, d}; -} - -LinkHistory::Entry -LinkHistory::getCurrent() const -{ - return {links.front().first.lock(), links.front().second}; -} - -LinkHistory::Entry -LinkHistory::getAt(float len, float * rem) const -{ - auto litr = links.begin(); - while (len > 0.F && litr != links.end()) { - litr++; - if (litr != links.end()) { - len -= litr->first.lock()->length; - } - } - if (litr == links.end()) { - litr--; - } - if (rem) { - *rem = -len; - } - return {litr->first.lock(), litr->second}; -} diff --git a/game/vehicles/vehicle.h b/game/vehicles/vehicle.h index 89a6901..659821f 100644 --- a/game/vehicles/vehicle.h +++ b/game/vehicles/vehicle.h @@ -1,28 +1,14 @@ #ifndef VEHICLE_H #define VEHICLE_H +#include "linkHistory.h" #include <game/network/link.h> #include <game/worldobject.h> #include <gfx/renderable.h> #include <memory> -#include <utility> -#include <vector> class Location; -class LinkHistory { -public: - using WEntry = std::pair<LinkWPtr, unsigned char /*dir*/>; - using Entry = std::pair<LinkCPtr, unsigned char /*dir*/>; - Entry add(const LinkWPtr &, unsigned char); - [[nodiscard]] Entry getCurrent() const; - [[nodiscard]] Entry getAt(float, float *) const; - -private: - std::vector<WEntry> links; - float totalLen {0.F}; -}; - class Vehicle : public WorldObject, public Renderable { public: explicit Vehicle(const LinkPtr & link, float linkDist = 0); |