From d8ee91b44e31cf1500926d37b7391e8c94bbf14a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 21 Dec 2024 03:30:18 +0000 Subject: Fix calculating radius and length of curved links --- game/network/link.h | 6 +++--- game/network/rail.cpp | 11 ++++++----- game/network/rail.h | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'game/network') diff --git a/game/network/link.h b/game/network/link.h index 725e023..4cca52c 100644 --- a/game/network/link.h +++ b/game/network/link.h @@ -16,7 +16,7 @@ template class Ray; // it has location class Node : public StdTypeDefs { public: - explicit Node(GlobalPosition3D p) noexcept : pos(p) {}; + explicit Node(GlobalPosition3D p) noexcept : pos(p) { }; virtual ~Node() noexcept = default; NO_COPY(Node); NO_MOVE(Node); @@ -38,7 +38,7 @@ public: Nexts nexts {}; }; - Link(End, End, float); + Link(End, End, RelativeDistance length); virtual ~Link() = default; NO_COPY(Link); NO_MOVE(Link); @@ -76,7 +76,7 @@ LinkStraight::~LinkStraight() = default; class LinkCurve : public virtual Link { public: inline ~LinkCurve() override = 0; - LinkCurve(GlobalPosition3D, RelativeDistance, Arc); + LinkCurve(GlobalPosition3D centreBase, RelativeDistance radius, Arc); NO_COPY(LinkCurve); NO_MOVE(LinkCurve); diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 6f04070..69422aa 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -108,16 +108,17 @@ RailLinkStraight::RailLinkStraight( { } -RailLinkCurve::RailLinkCurve(NetworkLinkHolder & instances, const Node::Ptr & a, const Node::Ptr & b, - GlobalPosition2D c) : RailLinkCurve(instances, a, b, c || a->pos.z, {c, a->pos, b->pos}) +RailLinkCurve::RailLinkCurve( + NetworkLinkHolder & instances, const Node::Ptr & a, const Node::Ptr & b, GlobalPosition2D c) : + RailLinkCurve(instances, a, b, c || a->pos.z, glm::length(difference(a->pos.xy(), c)), {c, a->pos, b->pos}) { } RailLinkCurve::RailLinkCurve(NetworkLinkHolder & instances, const Node::Ptr & a, const Node::Ptr & b, - GlobalPosition3D c, const Arc arc) : + GlobalPosition3D c, RelativeDistance radius, const Arc arc) : Link({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)}, - glm::length(RelativePosition3D(a->pos - c)) * arc.length()), - LinkCurve {c, glm::length(RelativePosition3D(ends[0].node->pos - c)), arc}, + glm::length(RelativePosition2D {radius * arc.length(), difference(a->pos, b->pos).z})), + LinkCurve {c, radius, arc}, instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2000.F), half_pi - arc.first, half_pi - arc.second, radius)} { diff --git a/game/network/rail.h b/game/network/rail.h index c8effef..0aae718 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -62,8 +62,8 @@ public: }; private: - RailLinkCurve( - NetworkLinkHolder &, const Node::Ptr &, const Node::Ptr &, GlobalPosition3D, const Arc); + RailLinkCurve(NetworkLinkHolder &, const Node::Ptr &, const Node::Ptr &, GlobalPosition3D centreBase, + RelativeDistance radius, Arc); InstanceVertices::InstanceProxy instance; }; -- cgit v1.2.3 From 2e66a686cd6cf589c583060921430a94b2849e83 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 21 Dec 2024 14:10:01 +0000 Subject: Expose network link interface to define a base area of the link --- game/network/link.cpp | 35 +++++++++++++++++++++++++++++++++++ game/network/link.h | 3 +++ 2 files changed, 38 insertions(+) (limited to 'game/network') diff --git a/game/network/link.cpp b/game/network/link.cpp index 79af92a..61e8771 100644 --- a/game/network/link.cpp +++ b/game/network/link.cpp @@ -38,6 +38,20 @@ LinkStraight::intersectRay(const Ray & ray) const std::array {GlobalPosition3D {ends.front().node->pos}, GlobalPosition3D {ends.back().node->pos}}, 1000); } +std::vector +LinkStraight::getBase(RelativeDistance width) const +{ + const auto start = ends.front().node->pos; + const auto end = ends.back().node->pos; + const auto direction = (vector_normal(normalize(::difference(start, end).xy())) * width / 2.F) || 0.F; + return { + start - direction, + start + direction, + end - direction, + end + direction, + }; +} + Location LinkCurve::positionAt(float dist, unsigned char start) const { @@ -73,3 +87,24 @@ LinkCurve::intersectRay(const Ray & ray) const } return ray.passesCloseToEdges(points, 1.F); } + +std::vector +LinkCurve::getBase(RelativeDistance width) const +{ + const auto start = ends.front().node->pos; + const auto end = ends.back().node->pos; + const auto segs = std::ceil(15.F * arc.length()); + const auto step {glm::vec<2, RelativeDistance> {arc.length(), end.z - start.z} / segs}; + + auto segCount = static_cast(segs) + 1; + std::vector out; + out.reserve(segCount); + for (RelativePosition2D swing = {arc.first, centreBase.z - start.z}; segCount != 0U; swing += step, --segCount) { + const auto direction = sincos(swing.x); + const auto linkCentre = centreBase + ((direction * radius) || swing.y); + const auto toEdge = (direction * width / 2.F) || 0.F; + out.emplace_back(linkCentre + toEdge); + out.emplace_back(linkCentre - toEdge); + } + return out; +} diff --git a/game/network/link.h b/game/network/link.h index 4cca52c..59bbb65 100644 --- a/game/network/link.h +++ b/game/network/link.h @@ -45,6 +45,7 @@ public: [[nodiscard]] virtual Location positionAt(RelativeDistance dist, unsigned char start) const = 0; [[nodiscard]] virtual bool intersectRay(const Ray &) const = 0; + [[nodiscard]] virtual std::vector getBase(RelativeDistance width) const = 0; std::array ends; float length; @@ -69,6 +70,7 @@ public: [[nodiscard]] Location positionAt(RelativeDistance dist, unsigned char start) const override; [[nodiscard]] bool intersectRay(const Ray &) const override; + [[nodiscard]] std::vector getBase(RelativeDistance width) const override; }; LinkStraight::~LinkStraight() = default; @@ -82,6 +84,7 @@ public: [[nodiscard]] Location positionAt(RelativeDistance dist, unsigned char start) const override; [[nodiscard]] bool intersectRay(const Ray &) const override; + [[nodiscard]] std::vector getBase(RelativeDistance width) const override; GlobalPosition3D centreBase; RelativeDistance radius; -- cgit v1.2.3 From 4481f97f2114d07d999744224e53039b85b04553 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 21 Dec 2024 19:13:20 +0000 Subject: Adjust track height to blend into terrain --- game/network/rail.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'game/network') diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 69422aa..f226327 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -8,7 +8,7 @@ template class NetworkOf; constexpr auto RAIL_CROSSSECTION_VERTICES {5U}; -constexpr Size3D RAIL_HEIGHT {0, 0, 250.F}; +constexpr Size3D RAIL_HEIGHT {0, 0, 50.F}; RailLinks::RailLinks() : NetworkOf {"rails.jpg"} { } @@ -74,11 +74,11 @@ RailLinks::addLinksBetween(GlobalPosition3D start, GlobalPosition3D end) } constexpr const std::array railCrossSection {{ - {-1900.F, 0.F, 0.F}, + {-1900.F, 0.F, -RAIL_HEIGHT.z * 2}, {-608.F, 0.F, RAIL_HEIGHT.z}, - {0, 0.F, RAIL_HEIGHT.z * .7F}, + {0, 0.F, RAIL_HEIGHT.z / 2}, {608.F, 0.F, RAIL_HEIGHT.z}, - {1900.F, 0.F, 0.F}, + {1900.F, 0.F, -RAIL_HEIGHT.z * 2}, }}; constexpr const std::array railTexturePos { 0.F, -- cgit v1.2.3 From 8b388c4ee59961f4d307c7f9f87641beffb76a53 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 22 Dec 2024 13:29:15 +0000 Subject: Expose network base width and surface --- game/network/network.h | 4 ++++ game/network/rail.cpp | 14 ++++++++++++++ game/network/rail.h | 3 +++ 3 files changed, 21 insertions(+) (limited to 'game/network') diff --git a/game/network/network.h b/game/network/network.h index be0900b..f8739b8 100644 --- a/game/network/network.h +++ b/game/network/network.h @@ -14,6 +14,7 @@ #include class SceneShader; +class Surface; template class Ray; template using GenDef = std::tuple...>; @@ -47,6 +48,9 @@ public: [[nodiscard]] virtual float findNodeDirection(Node::AnyCPtr) const = 0; + [[nodiscard]] virtual const Surface * getBaseSurface() const = 0; + [[nodiscard]] virtual RelativeDistance getBaseWidth() const = 0; + protected: static void joinLinks(const Link::Ptr & l, const Link::Ptr & ol); static GenCurveDef genCurveDef(const GlobalPosition3D & start, const GlobalPosition3D & end, float startDir); diff --git a/game/network/rail.cpp b/game/network/rail.cpp index f226327..dc62cf3 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -1,4 +1,6 @@ #include "rail.h" +#include "game/gamestate.h" +#include "game/geoData.h" #include "network.h" #include // IWYU pragma: keep #include @@ -169,3 +171,15 @@ RailLinks::render(const SceneShader & shader) const glBindVertexArray(0); } } + +const Surface * +RailLinks::getBaseSurface() const +{ + return std::dynamic_pointer_cast(gameState->assets.at("terrain.surface.gravel")).get(); +} + +RelativeDistance +RailLinks::getBaseWidth() const +{ + return 5'700; +} diff --git a/game/network/rail.h b/game/network/rail.h index 0aae718..fa64eda 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -77,6 +77,9 @@ public: std::shared_ptr addLinksBetween(GlobalPosition3D start, GlobalPosition3D end); void render(const SceneShader &) const override; + [[nodiscard]] const Surface * getBaseSurface() const override; + [[nodiscard]] RelativeDistance getBaseWidth() const override; + private: void tick(TickDuration elapsed) override; }; -- cgit v1.2.3 From 485143ae90aa692aef47c1c7aba8775818a026aa Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 24 Dec 2024 15:02:10 +0000 Subject: Fix calculations for sleeper texture coords --- game/network/rail.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'game/network') diff --git a/game/network/rail.cpp b/game/network/rail.cpp index dc62cf3..baf48f3 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -91,10 +91,17 @@ constexpr const std::array railTexturePos { }; constexpr auto sleepers {5.F}; // There are 5 repetitions of sleepers in the texture -inline auto -round_sleepers(const float v) -{ - return round_frac(v, sleepers); +namespace { + template constexpr T SLEEPERS_PER_TEXTURE {5}; + template constexpr T TEXTURE_LENGTH {2'000}; + template constexpr T SLEEPER_LENGTH {T {1} / SLEEPERS_PER_TEXTURE}; + + template + constexpr auto + roundSleepers(const T length) + { + return round_frac(length / TEXTURE_LENGTH, SLEEPER_LENGTH); + } } RailLinkStraight::RailLinkStraight(NetworkLinkHolder & instances, const Node::Ptr & a, @@ -106,7 +113,7 @@ RailLinkStraight::RailLinkStraight( NetworkLinkHolder & instances, Node::Ptr a, Node::Ptr b, const RelativePosition3D & diff) : Link({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff)), instance {instances.vertices.acquire( - ends[0].node->pos, ends[1].node->pos, flat_orientation(diff), round_sleepers(length / 2000.F))} + ends[0].node->pos, ends[1].node->pos, flat_orientation(diff), roundSleepers(length))} { } @@ -120,9 +127,8 @@ RailLinkCurve::RailLinkCurve(NetworkLinkHolder & instances, const GlobalPosition3D c, RelativeDistance radius, const Arc arc) : Link({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)}, glm::length(RelativePosition2D {radius * arc.length(), difference(a->pos, b->pos).z})), - LinkCurve {c, radius, arc}, - instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2000.F), - half_pi - arc.first, half_pi - arc.second, radius)} + LinkCurve {c, radius, arc}, instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, + roundSleepers(length), half_pi - arc.first, half_pi - arc.second, radius)} { } -- cgit v1.2.3 From 6ad6d935d8a601908d49a82fb56f1f2c14871573 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 24 Dec 2024 15:07:32 +0000 Subject: Enable min mipmap on network texture --- game/network/network.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'game/network') diff --git a/game/network/network.cpp b/game/network/network.cpp index 6ba3ed6..1666c4d 100644 --- a/game/network/network.cpp +++ b/game/network/network.cpp @@ -8,7 +8,13 @@ #include #include -Network::Network(const std::string & tn) : texture {std::make_shared(tn)} { } +Network::Network(const std::string & tn) : + texture {std::make_shared(tn, + TextureOptions { + .minFilter = GL_NEAREST_MIPMAP_LINEAR, + })} +{ +} Node::Ptr Network::nodeAt(GlobalPosition3D pos) -- cgit v1.2.3 From 4e6539a9cfb4fa19c87ac23b929a8bd2683c5626 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 24 Dec 2024 15:29:57 +0000 Subject: Update rails render for being atop a surface --- game/network/rail.cpp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'game/network') diff --git a/game/network/rail.cpp b/game/network/rail.cpp index baf48f3..2820cca 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -75,23 +75,21 @@ RailLinks::addLinksBetween(GlobalPosition3D start, GlobalPosition3D end) return addLink(start, end, centre.first); } -constexpr const std::array railCrossSection {{ - {-1900.F, 0.F, -RAIL_HEIGHT.z * 2}, - {-608.F, 0.F, RAIL_HEIGHT.z}, - {0, 0.F, RAIL_HEIGHT.z / 2}, - {608.F, 0.F, RAIL_HEIGHT.z}, - {1900.F, 0.F, -RAIL_HEIGHT.z * 2}, -}}; -constexpr const std::array railTexturePos { - 0.F, - .34F, - .5F, - .66F, - 1.F, -}; -constexpr auto sleepers {5.F}; // There are 5 repetitions of sleepers in the texture - namespace { + constexpr const std::array RAIL_CROSS_SECTION {{ + {-1330.F, 0.F, 0}, + {-608.F, 0.F, RAIL_HEIGHT.z}, + {0, 0.F, RAIL_HEIGHT.z / 2}, + {608.F, 0.F, RAIL_HEIGHT.z}, + {1330.F, 0.F, 0}, + }}; + constexpr const std::array RAIL_TEXTURE_POS { + 0.15F, + .34F, + .5F, + .66F, + 0.85F, + }; template constexpr T SLEEPERS_PER_TEXTURE {5}; template constexpr T TEXTURE_LENGTH {2'000}; template constexpr T SLEEPER_LENGTH {T {1} / SLEEPERS_PER_TEXTURE}; @@ -160,7 +158,7 @@ namespace { renderType(const NetworkLinkHolder & n, auto & s) { if (auto count = n.vertices.size()) { - s.use(railCrossSection, railTexturePos); + s.use(RAIL_CROSS_SECTION, RAIL_TEXTURE_POS); glBindVertexArray(n.vao); glDrawArrays(GL_POINTS, 0, static_cast(count)); } @@ -172,8 +170,11 @@ RailLinks::render(const SceneShader & shader) const { if (!links.objects.empty()) { texture->bind(); + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1, 0); renderType(*this, shader.networkStraight); renderType(*this, shader.networkCurve); + glDisable(GL_POLYGON_OFFSET_FILL); glBindVertexArray(0); } } -- cgit v1.2.3 From 1aba027462a861f2c1155672792dbbe555d7dc0a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 13 Jan 2025 01:45:43 +0000 Subject: Add distance helper Works with integer positions, first template param allows forcing to N dimensions --- game/network/network.cpp | 4 ++-- game/network/network.impl.h | 4 ++-- game/network/rail.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'game/network') diff --git a/game/network/network.cpp b/game/network/network.cpp index 1666c4d..e67942f 100644 --- a/game/network/network.cpp +++ b/game/network/network.cpp @@ -121,8 +121,8 @@ Network::genCurveDef(const GlobalPosition3D & start, const GlobalPosition3D & en endDir += pi; const auto flatStart {start.xy()}, flatEnd {end.xy()}; auto midheight = [&](auto mid) { - const auto sm = glm::length(RelativePosition2D(flatStart - mid)), - em = glm::length(RelativePosition2D(flatEnd - mid)); + const auto sm = ::distance<2>(flatStart, mid); + const auto em = ::distance<2>(flatEnd, mid); return start.z + GlobalDistance(RelativeDistance(end.z - start.z) * (sm / (sm + em))); }; if (const auto radii = find_arcs_radius(flatStart, startDir, flatEnd, endDir); radii.first < radii.second) { diff --git a/game/network/network.impl.h b/game/network/network.impl.h index ff29088..33b0a86 100644 --- a/game/network/network.impl.h +++ b/game/network/network.impl.h @@ -52,7 +52,7 @@ template Link::CCollection NetworkOf::candidateJoins(GlobalPosition3D start, GlobalPosition3D end) { - if (glm::length(RelativePosition3D(start - end)) < 2000.F) { + if (::distance(start, end) < 2000.F) { return {}; } const auto defs = genCurveDef( @@ -81,7 +81,7 @@ template Link::CCollection NetworkOf::addJoins(GlobalPosition3D start, GlobalPosition3D end) { - if (glm::length(RelativePosition3D(start - end)) < 2000.F) { + if (::distance(start, end) < 2000.F) { return {}; } const auto defs = genCurveDef(start, end, findNodeDirection(nodeAt(start)), findNodeDirection(nodeAt(end))); diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 2820cca..d7de231 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -40,8 +40,8 @@ RailLinks::addLinksBetween(GlobalPosition3D start, GlobalPosition3D end) const auto flatStart {start.xy()}, flatEnd {end.xy()}; if (node2ins.second == NodeIs::InNetwork) { auto midheight = [&](auto mid) { - const auto sm = glm::length(RelativePosition2D(flatStart - mid)), - em = glm::length(RelativePosition2D(flatEnd - mid)); + const auto sm = ::distance<2>(flatStart, mid); + const auto em = ::distance<2>(flatEnd, mid); return start.z + GlobalDistance(RelativeDistance(end.z - start.z) * (sm / (sm + em))); }; const float dir2 = pi + findNodeDirection(node2ins.first); @@ -117,7 +117,7 @@ RailLinkStraight::RailLinkStraight( RailLinkCurve::RailLinkCurve( NetworkLinkHolder & instances, const Node::Ptr & a, const Node::Ptr & b, GlobalPosition2D c) : - RailLinkCurve(instances, a, b, c || a->pos.z, glm::length(difference(a->pos.xy(), c)), {c, a->pos, b->pos}) + RailLinkCurve(instances, a, b, c || a->pos.z, ::distance<2>(a->pos.xy(), c), {c, a->pos, b->pos}) { } -- cgit v1.2.3 From 62fd9391bbfde47177fb36434d9664e47f4cf656 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 9 Feb 2025 13:02:09 +0000 Subject: Initial commit setting terrain during network construction This is all in the wrong place, it shouldn't be part of the network interface. --- game/network/network.h | 17 +++++++------ game/network/network.impl.h | 61 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 17 deletions(-) (limited to 'game/network') diff --git a/game/network/network.h b/game/network/network.h index f8739b8..291c4ec 100644 --- a/game/network/network.h +++ b/game/network/network.h @@ -14,7 +14,8 @@ #include class SceneShader; -class Surface; +struct Surface; +class GeoData; template class Ray; template using GenDef = std::tuple...>; @@ -42,9 +43,9 @@ public: virtual Link::CCollection candidateStraight(GlobalPosition3D, GlobalPosition3D) = 0; virtual Link::CCollection candidateJoins(GlobalPosition3D, GlobalPosition3D) = 0; virtual Link::CCollection candidateExtend(GlobalPosition3D, GlobalPosition3D) = 0; - virtual Link::CCollection addStraight(GlobalPosition3D, GlobalPosition3D) = 0; - virtual Link::CCollection addJoins(GlobalPosition3D, GlobalPosition3D) = 0; - virtual Link::CCollection addExtend(GlobalPosition3D, GlobalPosition3D) = 0; + virtual Link::CCollection addStraight(const GeoData *, GlobalPosition3D, GlobalPosition3D) = 0; + virtual Link::CCollection addJoins(const GeoData *, GlobalPosition3D, GlobalPosition3D) = 0; + virtual Link::CCollection addExtend(const GeoData *, GlobalPosition3D, GlobalPosition3D) = 0; [[nodiscard]] virtual float findNodeDirection(Node::AnyCPtr) const = 0; @@ -106,12 +107,12 @@ public: Link::CCollection candidateStraight(GlobalPosition3D n1, GlobalPosition3D n2) override; Link::CCollection candidateJoins(GlobalPosition3D, GlobalPosition3D) override; Link::CCollection candidateExtend(GlobalPosition3D, GlobalPosition3D) override; - Link::CCollection addStraight(GlobalPosition3D n1, GlobalPosition3D n2) override; - Link::CCollection addJoins(GlobalPosition3D, GlobalPosition3D) override; - Link::CCollection addExtend(GlobalPosition3D, GlobalPosition3D) override; + Link::CCollection addStraight(const GeoData *, GlobalPosition3D n1, GlobalPosition3D n2) override; + Link::CCollection addJoins(const GeoData *, GlobalPosition3D, GlobalPosition3D) override; + Link::CCollection addExtend(const GeoData *, GlobalPosition3D, GlobalPosition3D) override; [[nodiscard]] float findNodeDirection(Node::AnyCPtr) const override; protected: - Link::CCollection addJoins(); + Link::CCollection addCurve(const GeoData *, const GenCurveDef &); }; diff --git a/game/network/network.impl.h b/game/network/network.impl.h index 33b0a86..c683378 100644 --- a/game/network/network.impl.h +++ b/game/network/network.impl.h @@ -1,4 +1,6 @@ +#include "collections.h" #include "network.h" +#include #include #include @@ -72,28 +74,69 @@ NetworkOf::candidateExtend(GlobalPosition3D start, GlobalPosition3D template Link::CCollection -NetworkOf::addStraight(GlobalPosition3D n1, GlobalPosition3D n2) +NetworkOf::addStraight(const GeoData * geoData, GlobalPosition3D n1, GlobalPosition3D n2) { - return {addLink(n1, n2)}; + Link::CCollection out; + geoData->walk(n1.xy(), n2, [geoData, &out, this, &n1](const GeoData::WalkStep & step) { + if (step.previous.is_valid() && geoData->getSurface(step.current) != geoData->getSurface(step.previous)) { + const auto surfaceEdgePosition = geoData->positionAt(GeoData::PointFace(step.exitPosition, step.current)); + out.emplace_back(addLink(n1, surfaceEdgePosition)); + n1 = surfaceEdgePosition; + } + }); + out.emplace_back(addLink(n1, n2)); + return out; +} + +template +Link::CCollection +NetworkOf::addCurve(const GeoData * geoData, const GenCurveDef & curve) +{ + auto [cstart, cend, centre] = curve; + Link::CCollection out; + std::set> breaks; + const auto radiusMid = ::distance(cstart.xy(), centre); + for (const auto radiusOffset : {-getBaseWidth() / 2.F, 0.F, getBaseWidth() / 2.F}) { + const auto radius = radiusOffset + radiusMid; + const auto start = centre + (difference(cstart.xy(), centre) * radius) / radiusMid; + const auto end = centre + (difference(cend.xy(), centre) * radius) / radiusMid; + geoData->walk(start, end, centre, [geoData, &breaks](const GeoData::WalkStepCurve & step) { + if (step.previous.is_valid() && geoData->getSurface(step.current) != geoData->getSurface(step.previous)) { + breaks.insert(step); + } + }); + } + std::vector points; + points.reserve(breaks.size() + 2); + points.push_back(cstart); + std::ranges::transform( + breaks, std::back_inserter(points), [geoData, centre, radiusMid](const GeoData::WalkStepCurve & step) { + return (centre + (sincos(step.angle) * radiusMid)) + || geoData->positionAt(GeoData::PointFace(step.exitPosition, step.current)).z; + }); + points.push_back(cend); + mergeClose(points, ::distance<3, GlobalDistance>, ::midpoint<3, GlobalDistance>, 2'000.F); + std::ranges::transform(points | std::views::pairwise, std::back_inserter(out), [this, centre](const auto pair) { + const auto [a, b] = pair; + return addLink(a, b, centre); + }); + return out; } template Link::CCollection -NetworkOf::addJoins(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf::addJoins(const GeoData * geoData, GlobalPosition3D start, GlobalPosition3D end) { if (::distance(start, end) < 2000.F) { return {}; } const auto defs = genCurveDef(start, end, findNodeDirection(nodeAt(start)), findNodeDirection(nodeAt(end))); - const auto & [c1s, c1e, c1c] = defs.first; - const auto & [c2s, c2e, c2c] = defs.second; - return {addLink(c1s, c1e, c1c), addLink(c2s, c2e, c2c)}; + return addCurve(geoData, defs.first) + addCurve(geoData, defs.second); } template Link::CCollection -NetworkOf::addExtend(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf::addExtend(const GeoData * geoData, GlobalPosition3D start, GlobalPosition3D end) { - const auto [cstart, cend, centre] = genCurveDef(start, end, findNodeDirection(nodeAt(start))); - return {addLink(cstart, cend, centre)}; + return addCurve(geoData, genCurveDef(start, end, findNodeDirection(nodeAt(start)))); } -- cgit v1.2.3 From 27e1da72e5ff30d4e5b94bd1d8a674bf1e645222 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 23 Feb 2025 23:58:56 +0000 Subject: Improve number of segments in LinkCurve bases --- game/network/link.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'game/network') diff --git a/game/network/link.cpp b/game/network/link.cpp index 61e8771..c84524c 100644 --- a/game/network/link.cpp +++ b/game/network/link.cpp @@ -93,7 +93,7 @@ LinkCurve::getBase(RelativeDistance width) const { const auto start = ends.front().node->pos; const auto end = ends.back().node->pos; - const auto segs = std::ceil(15.F * arc.length()); + const auto segs = std::ceil(std::sqrt(radius) * 0.02F * arc.length()); const auto step {glm::vec<2, RelativeDistance> {arc.length(), end.z - start.z} / segs}; auto segCount = static_cast(segs) + 1; -- cgit v1.2.3