diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-02-09 13:02:09 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-02-09 13:02:09 +0000 |
commit | 62fd9391bbfde47177fb36434d9664e47f4cf656 (patch) | |
tree | 83c1361b41bac431f8dbddb92859fb28e76455a5 | |
parent | Big of validation on getSurface (diff) | |
download | ilt-62fd9391bbfde47177fb36434d9664e47f4cf656.tar.bz2 ilt-62fd9391bbfde47177fb36434d9664e47f4cf656.tar.xz ilt-62fd9391bbfde47177fb36434d9664e47f4cf656.zip |
Initial commit setting terrain during network construction
This is all in the wrong place, it shouldn't be part of the network interface.
-rw-r--r-- | game/network/network.h | 17 | ||||
-rw-r--r-- | game/network/network.impl.h | 61 | ||||
-rw-r--r-- | game/terrain.cpp | 2 | ||||
-rw-r--r-- | lib/collections.h | 9 | ||||
-rw-r--r-- | ui/builders/freeExtend.cpp | 14 | ||||
-rw-r--r-- | ui/builders/freeExtend.h | 4 | ||||
-rw-r--r-- | ui/builders/join.cpp | 8 | ||||
-rw-r--r-- | ui/builders/join.h | 2 | ||||
-rw-r--r-- | ui/builders/straight.cpp | 6 | ||||
-rw-r--r-- | ui/builders/straight.h | 2 |
10 files changed, 91 insertions, 34 deletions
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 <utility> class SceneShader; -class Surface; +struct Surface; +class GeoData; template<typename> class Ray; template<size_t... n> using GenDef = std::tuple<glm::vec<n, GlobalDistance>...>; @@ -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 <game/geoData.h> #include <gfx/gl/sceneShader.h> #include <gfx/models/texture.h> @@ -72,28 +74,69 @@ NetworkOf<T, Links...>::candidateExtend(GlobalPosition3D start, GlobalPosition3D template<typename T, typename... Links> Link::CCollection -NetworkOf<T, Links...>::addStraight(GlobalPosition3D n1, GlobalPosition3D n2) +NetworkOf<T, Links...>::addStraight(const GeoData * geoData, GlobalPosition3D n1, GlobalPosition3D n2) { - return {addLink<typename T::StraightLink>(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<typename T::StraightLink>(n1, surfaceEdgePosition)); + n1 = surfaceEdgePosition; + } + }); + out.emplace_back(addLink<typename T::StraightLink>(n1, n2)); + return out; +} + +template<typename T, typename... Links> +Link::CCollection +NetworkOf<T, Links...>::addCurve(const GeoData * geoData, const GenCurveDef & curve) +{ + auto [cstart, cend, centre] = curve; + Link::CCollection out; + std::set<GeoData::WalkStepCurve, SortedBy<&GeoData::WalkStepCurve::angle>> 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<GlobalPosition3D> 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<typename T::CurveLink>(a, b, centre); + }); + return out; } template<typename T, typename... Links> Link::CCollection -NetworkOf<T, Links...>::addJoins(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf<T, Links...>::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<typename T::CurveLink>(c1s, c1e, c1c), addLink<typename T::CurveLink>(c2s, c2e, c2c)}; + return addCurve(geoData, defs.first) + addCurve(geoData, defs.second); } template<typename T, typename... Links> Link::CCollection -NetworkOf<T, Links...>::addExtend(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf<T, Links...>::addExtend(const GeoData * geoData, GlobalPosition3D start, GlobalPosition3D end) { - const auto [cstart, cend, centre] = genCurveDef(start, end, findNodeDirection(nodeAt(start))); - return {addLink<typename T::CurveLink>(cstart, cend, centre)}; + return addCurve(geoData, genCurveDef(start, end, findNodeDirection(nodeAt(start)))); } diff --git a/game/terrain.cpp b/game/terrain.cpp index 39aa99a..c834379 100644 --- a/game/terrain.cpp +++ b/game/terrain.cpp @@ -77,7 +77,9 @@ Terrain::render(const SceneShader & shader) const { shader.landmass.use(); grass->bind(); + // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); meshes.apply(&Mesh::Draw); + // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } void diff --git a/lib/collections.h b/lib/collections.h index 6f26eae..fcd65d3 100644 --- a/lib/collections.h +++ b/lib/collections.h @@ -107,6 +107,15 @@ operator+=(std::vector<T...> & in, std::vector<T...> && src) return in; } +template<typename... T> +constexpr auto +operator+(std::vector<T...> in1, std::vector<T...> in2) +{ + in1.reserve(in1.size() + in2.size()); + std::move(in2.begin(), in2.end(), std::back_inserter(in1)); + return in1; +} + template<typename... T, typename Vn> [[nodiscard]] constexpr auto operator+(const std::vector<T...> & in, Vn && vn) diff --git a/ui/builders/freeExtend.cpp b/ui/builders/freeExtend.cpp index fa08af6..ab5a998 100644 --- a/ui/builders/freeExtend.cpp +++ b/ui/builders/freeExtend.cpp @@ -38,11 +38,11 @@ BuilderFreeExtend::click( case SDL_BUTTON_LEFT: if (p1) { if (const auto p = network->intersectRayNodes(ray)) { - createJoin(network, *p1, p->pos); + createJoin(network, geoData, *p1, p->pos); p1 = p->pos; } else if (const auto p = geoData->intersectRay(ray)) { - createExtend(network, *p1, p->first); + createExtend(network, geoData, *p1, p->first); p1 = p->first; } } @@ -59,17 +59,19 @@ BuilderFreeExtend::click( } Link::CCollection -BuilderFreeExtend::createJoin(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const +BuilderFreeExtend::createJoin( + Network * network, const GeoData * geoData, GlobalPosition3D p1, GlobalPosition3D p2) const { - const auto links = network->addJoins(p1, p2); + const auto links = network->addJoins(geoData, p1, p2); setHeightsFor(network, links); return links; } Link::CCollection -BuilderFreeExtend::createExtend(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const +BuilderFreeExtend::createExtend( + Network * network, const GeoData * geoData, GlobalPosition3D p1, GlobalPosition3D p2) const { - const auto links = network->addExtend(p1, p2); + const auto links = network->addExtend(geoData, p1, p2); setHeightsFor(network, links); return links; } diff --git a/ui/builders/freeExtend.h b/ui/builders/freeExtend.h index 8e30ef4..6f28493 100644 --- a/ui/builders/freeExtend.h +++ b/ui/builders/freeExtend.h @@ -13,8 +13,8 @@ private: const Ray<GlobalPosition3D> & ray) override; public: - Link::CCollection createJoin(Network * network, GlobalPosition3D, GlobalPosition3D) const; - Link::CCollection createExtend(Network * network, GlobalPosition3D, GlobalPosition3D) const; + Link::CCollection createJoin(Network * network, const GeoData *, GlobalPosition3D, GlobalPosition3D) const; + Link::CCollection createExtend(Network * network, const GeoData *, GlobalPosition3D, GlobalPosition3D) const; private: std::optional<GlobalPosition3D> p1; diff --git a/ui/builders/join.cpp b/ui/builders/join.cpp index ee14d63..6941e23 100644 --- a/ui/builders/join.cpp +++ b/ui/builders/join.cpp @@ -25,13 +25,13 @@ BuilderJoin::move(Network * network, const GeoData *, const SDL_MouseMotionEvent void BuilderJoin::click( - Network * network, const GeoData *, const SDL_MouseButtonEvent & e, const Ray<GlobalPosition3D> & ray) + Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray<GlobalPosition3D> & ray) { switch (e.button) { case SDL_BUTTON_LEFT: if (const auto p = network->intersectRayNodes(ray)) { if (p1) { - create(network, p1, p); + create(network, geoData, p1, p); p1.reset(); candidateLinks.removeAll(); } @@ -47,9 +47,9 @@ BuilderJoin::click( } Link::CCollection -BuilderJoin::create(Network * network, const Node::Ptr & p1, const Node::Ptr & p2) const +BuilderJoin::create(Network * network, const GeoData * geoData, const Node::Ptr & p1, const Node::Ptr & p2) const { - const auto links = network->addJoins(p1->pos, p2->pos); + const auto links = network->addJoins(geoData, p1->pos, p2->pos); setHeightsFor(network, links); return links; } diff --git a/ui/builders/join.h b/ui/builders/join.h index d92037c..326d23d 100644 --- a/ui/builders/join.h +++ b/ui/builders/join.h @@ -12,7 +12,7 @@ private: void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e, const Ray<GlobalPosition3D> & ray) override; - Link::CCollection create(Network * network, const Node::Ptr & p1, const Node::Ptr & p2) const; + Link::CCollection create(Network * network, const GeoData *, const Node::Ptr & p1, const Node::Ptr & p2) const; Node::Ptr p1; }; diff --git a/ui/builders/straight.cpp b/ui/builders/straight.cpp index b9f1831..338aa8a 100644 --- a/ui/builders/straight.cpp +++ b/ui/builders/straight.cpp @@ -33,7 +33,7 @@ BuilderStraight::click( case SDL_BUTTON_LEFT: if (const auto p = geoData->intersectRay(ray)) { if (p1) { - create(network, *p1, p->first); + create(network, geoData, *p1, p->first); candidateLinks.removeAll(); p1.reset(); } @@ -50,9 +50,9 @@ BuilderStraight::click( } Link::CCollection -BuilderStraight::create(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const +BuilderStraight::create(Network * network, const GeoData * geoData, GlobalPosition3D p1, GlobalPosition3D p2) const { - const auto links = network->addStraight(p1, p2); + const auto links = network->addStraight(geoData, p1, p2); setHeightsFor(network, links); return links; } diff --git a/ui/builders/straight.h b/ui/builders/straight.h index 1717cad..0a6f290 100644 --- a/ui/builders/straight.h +++ b/ui/builders/straight.h @@ -13,7 +13,7 @@ private: const Ray<GlobalPosition3D> & ray) override; public: - Link::CCollection create(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const; + Link::CCollection create(Network * network, const GeoData *, GlobalPosition3D p1, GlobalPosition3D p2) const; private: std::optional<GlobalPosition3D> p1; |