From b6880795627bc2f40a558c54af362df5dfc12b78 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 29 Oct 2024 00:32:44 +0000 Subject: Update operator<< for collections to work with ranges --- lib/stream_support.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/stream_support.h b/lib/stream_support.h index d71356c..423c7d4 100644 --- a/lib/stream_support.h +++ b/lib/stream_support.h @@ -17,14 +17,14 @@ concept NonStringIterableCollection namespace std { std::ostream & - operator<<(std::ostream & s, const NonStringIterableCollection auto & v) + operator<<(std::ostream & s, const NonStringIterableCollection auto & collection) { s << '('; - for (const auto & i : v) { - if (&i != &*v.begin()) { + for (size_t nth {}; const auto & element : collection) { + if (nth++) { s << ", "; } - s << i; + s << element; } return s << ')'; } -- cgit v1.2.3 From bb94eb2ac87274319875f8938407dd0a3ffc9ca4 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 29 Oct 2024 00:35:41 +0000 Subject: Update CLOG to be implemented as a function Forces capture of value before outputting anything --- lib/stream_support.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/stream_support.h b/lib/stream_support.h index 423c7d4..f21622a 100644 --- a/lib/stream_support.h +++ b/lib/stream_support.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -92,4 +93,14 @@ streamed_string(const T & v) return std::move(ss).str(); } -#define CLOG(x) std::cerr << __LINE__ << " : " #x " : " << x << "\n"; +namespace { + template + void + clogImpl(const T & value, const std::string_view name, + const std::source_location loc = std::source_location::current()) + { + std::cerr << loc.line() << " : " << name << " : " << value << "\n"; + } +} + +#define CLOG(x) clogImpl(x, #x) -- cgit v1.2.3 From ce3558ff08dddc03707851fa8177a45c0a9b5c83 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 30 Oct 2024 23:41:49 +0000 Subject: Fix GenDef for networks, should be globals --- game/network/network.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/network/network.h b/game/network/network.h index ca17581..be0900b 100644 --- a/game/network/network.h +++ b/game/network/network.h @@ -16,7 +16,7 @@ class SceneShader; template class Ray; -template using GenDef = std::tuple...>; +template using GenDef = std::tuple...>; using GenCurveDef = GenDef<3, 3, 2>; class Network { -- cgit v1.2.3 From 221b5f1f99470ccf487fb5d23eb16b7b53ed5588 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 31 Oct 2024 00:25:55 +0000 Subject: Fix train/vehicle constructors to take const links --- game/vehicles/train.h | 2 +- game/vehicles/vehicle.cpp | 2 +- game/vehicles/vehicle.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/game/vehicles/train.h b/game/vehicles/train.h index 4320103..4933347 100644 --- a/game/vehicles/train.h +++ b/game/vehicles/train.h @@ -17,7 +17,7 @@ template class Ray; class Train : public Vehicle, public Collection, public Can, public Can { public: - explicit Train(const Link::Ptr & link, float linkDist = 0) : Vehicle {link, linkDist} { } + explicit Train(const Link::CPtr & link, float linkDist = 0) : Vehicle {link, linkDist} { } [[nodiscard]] const Location & getLocation() const override diff --git a/game/vehicles/vehicle.cpp b/game/vehicles/vehicle.cpp index 0d46017..dd652bc 100644 --- a/game/vehicles/vehicle.cpp +++ b/game/vehicles/vehicle.cpp @@ -15,7 +15,7 @@ #include #include -Vehicle::Vehicle(const Link::Ptr & l, float ld) : linkDist {ld} +Vehicle::Vehicle(const Link::CPtr & l, float ld) : linkDist {ld} { linkHist.add(l, 0); currentActivity = std::make_unique(); diff --git a/game/vehicles/vehicle.h b/game/vehicles/vehicle.h index 354f904..c3b35b7 100644 --- a/game/vehicles/vehicle.h +++ b/game/vehicles/vehicle.h @@ -14,7 +14,7 @@ class Location; class Vehicle : public WorldObject, public Selectable { public: - explicit Vehicle(const Link::Ptr & link, float linkDist = 0); + explicit Vehicle(const Link::CPtr & link, float linkDist = 0); float linkDist; // distance along current link float speed {}; // speed in m/s (~75 km/h) -- cgit v1.2.3 From bce9080d6f2997aef398783bc40408cf3f952ec5 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 31 Oct 2024 01:25:39 +0000 Subject: Extract consts and fix acceleration/decelartions rates --- game/vehicles/train.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/game/vehicles/train.cpp b/game/vehicles/train.cpp index 5bddd61..2461d9c 100644 --- a/game/vehicles/train.cpp +++ b/game/vehicles/train.cpp @@ -2,7 +2,6 @@ #include "game/vehicles/linkHistory.h" #include "game/vehicles/railVehicle.h" #include "game/vehicles/railVehicleClass.h" -#include "gfx/renderable.h" #include "location.h" #include #include @@ -11,6 +10,9 @@ template class Ray; +constexpr auto DECELERATION_RATE = 60000.F; +constexpr auto ACCELERATIONS_RATE = 30000.F; + Location Train::getBogiePosition(float linkDist, float dist) const { @@ -41,8 +43,8 @@ Train::doActivity(Go * go, TickDuration dur) const auto maxSpeed = objects.front()->rvClass->maxSpeed; if (go->dist) { *go->dist -= speed * dur.count(); - if (*go->dist < (speed * speed) / 60.F) { - speed -= std::min(speed, 30.F * dur.count()); + if (*go->dist < (speed * speed) / DECELERATION_RATE) { + speed -= std::min(speed, ACCELERATIONS_RATE * dur.count()); } else { if (speed != maxSpeed) { @@ -61,6 +63,6 @@ void Train::doActivity(Idle *, TickDuration dur) { if (speed != 0.F) { - speed -= std::min(speed, 30.F * dur.count()); + speed -= std::min(speed, DECELERATION_RATE * dur.count()); } } -- cgit v1.2.3 From 511b2aded094421210b3576199bf0851e3fece78 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 31 Oct 2024 02:04:43 +0000 Subject: Extract const for link history length --- game/vehicles/linkHistory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/game/vehicles/linkHistory.cpp b/game/vehicles/linkHistory.cpp index e6bab36..45aa0a8 100644 --- a/game/vehicles/linkHistory.cpp +++ b/game/vehicles/linkHistory.cpp @@ -8,7 +8,8 @@ LinkHistory::add(const Link::WPtr & l, unsigned char d) links.insert(links.begin(), {l, d}); const auto lp = l.lock(); totalLen += lp->length; - while (totalLen >= 1000000.F && !links.empty()) { + constexpr auto HISTORY_KEEP_LENGTH = 1'000'000.F; + while (totalLen >= HISTORY_KEEP_LENGTH && !links.empty()) { totalLen -= links.back().first.lock()->length; links.pop_back(); } -- cgit v1.2.3 From 2054a4a444888ac6285aa710974729d4072e7894 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 31 Oct 2024 02:40:35 +0000 Subject: Fix pruning of link history The current size isn't important, the length after prune is, and it should be checked before adding the new link as most of the train will still be on the previous one. --- game/vehicles/linkHistory.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/game/vehicles/linkHistory.cpp b/game/vehicles/linkHistory.cpp index 45aa0a8..77840ed 100644 --- a/game/vehicles/linkHistory.cpp +++ b/game/vehicles/linkHistory.cpp @@ -1,18 +1,27 @@ #include "linkHistory.h" #include "game/network/link.h" #include +#include LinkHistory::Entry LinkHistory::add(const Link::WPtr & l, unsigned char d) { + constexpr auto HISTORY_KEEP_LENGTH = 500'000.F; + while (const auto newLength = [this]() -> std::optional { + if (!links.empty()) { + const auto newLength = totalLen - links.back().first.lock()->length; + if (newLength >= HISTORY_KEEP_LENGTH) { + return newLength; + } + } + return std::nullopt; + }()) { + totalLen = newLength.value(); + links.pop_back(); + } links.insert(links.begin(), {l, d}); const auto lp = l.lock(); totalLen += lp->length; - constexpr auto HISTORY_KEEP_LENGTH = 1'000'000.F; - while (totalLen >= HISTORY_KEEP_LENGTH && !links.empty()) { - totalLen -= links.back().first.lock()->length; - links.pop_back(); - } return {lp, d}; } -- cgit v1.2.3 From 1572e1ed7173d139df03df93bd6423ffdcc9e757 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 3 Nov 2024 14:13:00 +0000 Subject: Reuse close vertices when deforming terrain --- game/geoData.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/game/geoData.cpp b/game/geoData.cpp index d212651..8975d46 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -524,21 +524,29 @@ GeoData::setHeights(const std::span triangleStrip, const const auto doExtrusion = [this](VertexHandle & extrusionVertex, Direction2D direction, GlobalPosition3D boundaryVertex, RelativeDistance vert) { const auto extrusionDir = glm::normalize(direction || vert); + const auto intersectAsNeeded = [this, &extrusionVertex](FaceHandle face, GlobalPosition3D pos) { + if (const auto closeVertex = std::find_if(fv_begin(face), fv_end(face), + [this, pos](const auto & vertex) { + return glm::length(::difference(pos, this->point(vertex))) < 10.F; + }); + closeVertex != fv_end(face)) { + extrusionVertex = *closeVertex; + return; + } + extrusionVertex = split(face, pos); + }; if (!extrusionVertex.is_valid()) { if (const auto intersect = intersectRay({boundaryVertex, extrusionDir})) { - auto splitVertex = split(intersect->second, intersect->first); - extrusionVertex = splitVertex; + intersectAsNeeded(intersect->second, intersect->first); } else if (const auto intersect = intersectRay({boundaryVertex + GlobalPosition3D {1, 1, 0}, extrusionDir})) { - auto splitVertex = split(intersect->second, intersect->first); - extrusionVertex = splitVertex; + intersectAsNeeded(intersect->second, intersect->first); } else if (const auto intersect = intersectRay({boundaryVertex + GlobalPosition3D {1, 0, 0}, extrusionDir})) { - auto splitVertex = split(intersect->second, intersect->first); - extrusionVertex = splitVertex; + intersectAsNeeded(intersect->second, intersect->first); } } -- cgit v1.2.3 From 83fc2deeef2611c8e29b2048868767088e8cfffb Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 3 Nov 2024 14:17:01 +0000 Subject: Throw if input stream not in good state reading JSON --- lib/jsonParse-persistence.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/jsonParse-persistence.h b/lib/jsonParse-persistence.h index 6edebc7..e4e64c0 100644 --- a/lib/jsonParse-persistence.h +++ b/lib/jsonParse-persistence.h @@ -15,6 +15,9 @@ namespace Persistence { inline T loadState(std::istream & in) { + if (!in.good()) { + throw std::runtime_error("Input stream not in good state"); + } T t {}; stk.push(std::make_unique>(std::ref(t))); loadState(in); -- cgit v1.2.3 From fe38b3887b695f27baf791df34b7361ee11b379f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 3 Nov 2024 22:00:46 +0000 Subject: Remove extrusion extents that rounded to the same vertex --- game/geoData.cpp | 8 ++++++++ test/fixtures/geoData/deform/multi1.json | 21 +++++++++++++++++++++ test/test-geoData.cpp | 12 ++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 test/fixtures/geoData/deform/multi1.json diff --git a/game/geoData.cpp b/game/geoData.cpp index 8975d46..1a1e530 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -558,6 +558,14 @@ GeoData::setHeights(const std::span triangleStrip, const doExtrusion(extrusionVertex, direction, p1, -MAX_SLOPE), doExtrusion(extrusionVertex, direction, p1, MAX_SLOPE)); assert(extrusionVertex.is_valid()); + if (extrusionExtents.size() >= 2) { + const auto & last = *extrusionExtents.rbegin(); + const auto & prev = *++extrusionExtents.rbegin(); + if (last.boundaryVertex == prev.boundaryVertex + && last.extrusionVertex == prev.extrusionVertex) { + extrusionExtents.pop_back(); + } + } }; if (const Arc arc {e0, e1}; arc.length() < MIN_ARC) { addExtrusionFor(normalize(e0 + e1) / cosf(arc.length() / 2.F)); diff --git a/test/fixtures/geoData/deform/multi1.json b/test/fixtures/geoData/deform/multi1.json new file mode 100644 index 0000000..c7456b6 --- /dev/null +++ b/test/fixtures/geoData/deform/multi1.json @@ -0,0 +1,21 @@ +[ + [ + [ + [ + 100, + 100, + 100 + ], + [ + 150, + 100, + 100 + ], + [ + 100, + 150, + 100 + ] + ] + ] +] diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp index 35d6bae..b0261db 100644 --- a/test/test-geoData.cpp +++ b/test/test-geoData.cpp @@ -276,3 +276,15 @@ BOOST_DATA_TEST_CASE(deform, loadFixtureJson("geoData/deform/ Texture::save(tro.outImage, cam.second.c_str()); }); } + +BOOST_DATA_TEST_CASE( + deformMulti, loadFixtureJson>>("geoData/deform/multi1.json"), points) +{ + BOOST_REQUIRE(!points.empty()); + Surface surface; + auto gd = std::make_shared(GeoData::createFlat({0, 0}, {1000000, 1000000}, 100)); + for (const auto & strip : points) { + BOOST_REQUIRE_GE(strip.size(), 3); + BOOST_CHECK_NO_THROW(gd->setHeights(strip, surface)); + } +} -- cgit v1.2.3