From 5cba33aedccdfa79f1c291bc1da8ff2223d5c70a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 18 Dec 2024 19:56:38 +0000 Subject: Give UI builders an interface that can be programmatically called --- ui/builders/freeExtend.cpp | 16 ++++++++++++++-- ui/builders/freeExtend.h | 6 ++++++ ui/builders/join.cpp | 4 ++-- ui/builders/join.h | 3 ++- ui/builders/straight.cpp | 5 +++-- ui/builders/straight.h | 5 ++++- 6 files changed, 31 insertions(+), 8 deletions(-) (limited to 'ui') diff --git a/ui/builders/freeExtend.cpp b/ui/builders/freeExtend.cpp index db127e6..904e144 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)) { - network->addJoins(*p1, p->pos); + createJoin(network, *p1, p->pos); p1 = p->pos; } else if (const auto p = geoData->intersectRay(ray)) { - network->addExtend(*p1, p->first); + createExtend(network, *p1, p->first); p1 = p->first; } } @@ -57,3 +57,15 @@ BuilderFreeExtend::click( return; } } + +Link::CCollection +BuilderFreeExtend::createJoin(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const +{ + return network->addJoins(p1, p2); +} + +Link::CCollection +BuilderFreeExtend::createExtend(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const +{ + return network->addExtend(p1, p2); +} diff --git a/ui/builders/freeExtend.h b/ui/builders/freeExtend.h index 0d5f327..8e30ef4 100644 --- a/ui/builders/freeExtend.h +++ b/ui/builders/freeExtend.h @@ -5,11 +5,17 @@ class Network; class GeoData; class BuilderFreeExtend : public EditNetwork::Builder { +private: std::string hint() const override; void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray & ray) override; void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e, const Ray & ray) override; +public: + Link::CCollection createJoin(Network * network, GlobalPosition3D, GlobalPosition3D) const; + Link::CCollection createExtend(Network * network, GlobalPosition3D, GlobalPosition3D) const; + +private: std::optional p1; }; diff --git a/ui/builders/join.cpp b/ui/builders/join.cpp index 7474c5b..9fbbae9 100644 --- a/ui/builders/join.cpp +++ b/ui/builders/join.cpp @@ -46,8 +46,8 @@ BuilderJoin::click( } } -void +Link::CCollection BuilderJoin::create(Network * network, const Node::Ptr & p1, const Node::Ptr & p2) const { - network->addJoins(p1->pos, p2->pos); + return network->addJoins(p1->pos, p2->pos); } diff --git a/ui/builders/join.h b/ui/builders/join.h index dd57895..d92037c 100644 --- a/ui/builders/join.h +++ b/ui/builders/join.h @@ -5,13 +5,14 @@ class Network; class GeoData; class BuilderJoin : public EditNetwork::Builder { +private: std::string hint() const override; void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray & ray) override; void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e, const Ray & ray) override; - void create(Network * network, const Node::Ptr & p1, const Node::Ptr & p2) const; + Link::CCollection create(Network * network, 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 43f5ec8..014eea5 100644 --- a/ui/builders/straight.cpp +++ b/ui/builders/straight.cpp @@ -1,4 +1,5 @@ #include "straight.h" +#include "stream_support.h" #include std::string @@ -48,8 +49,8 @@ BuilderStraight::click( } } -void +Link::CCollection BuilderStraight::create(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const { - network->addStraight(p1, p2); + return network->addStraight(p1, p2); } diff --git a/ui/builders/straight.h b/ui/builders/straight.h index 28eb66e..1717cad 100644 --- a/ui/builders/straight.h +++ b/ui/builders/straight.h @@ -5,13 +5,16 @@ class Network; class GeoData; class BuilderStraight : public EditNetwork::Builder { +private: std::string hint() const override; void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray & ray) override; void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e, const Ray & ray) override; - void create(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const; +public: + Link::CCollection create(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const; +private: std::optional p1; }; -- cgit v1.2.3 From 749df22c85b83c86ec68ebc74829287e54498e26 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 22 Dec 2024 13:53:27 +0000 Subject: Set terrain heights when creating new network links --- ui/builders/freeExtend.cpp | 8 ++++++-- ui/builders/join.cpp | 4 +++- ui/builders/straight.cpp | 4 +++- ui/editNetwork.cpp | 11 +++++++++++ ui/editNetwork.h | 3 +++ 5 files changed, 26 insertions(+), 4 deletions(-) (limited to 'ui') diff --git a/ui/builders/freeExtend.cpp b/ui/builders/freeExtend.cpp index 904e144..fa08af6 100644 --- a/ui/builders/freeExtend.cpp +++ b/ui/builders/freeExtend.cpp @@ -61,11 +61,15 @@ BuilderFreeExtend::click( Link::CCollection BuilderFreeExtend::createJoin(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const { - return network->addJoins(p1, p2); + const auto links = network->addJoins(p1, p2); + setHeightsFor(network, links); + return links; } Link::CCollection BuilderFreeExtend::createExtend(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const { - return network->addExtend(p1, p2); + const auto links = network->addExtend(p1, p2); + setHeightsFor(network, links); + return links; } diff --git a/ui/builders/join.cpp b/ui/builders/join.cpp index 9fbbae9..ee14d63 100644 --- a/ui/builders/join.cpp +++ b/ui/builders/join.cpp @@ -49,5 +49,7 @@ BuilderJoin::click( Link::CCollection BuilderJoin::create(Network * network, const Node::Ptr & p1, const Node::Ptr & p2) const { - return network->addJoins(p1->pos, p2->pos); + const auto links = network->addJoins(p1->pos, p2->pos); + setHeightsFor(network, links); + return links; } diff --git a/ui/builders/straight.cpp b/ui/builders/straight.cpp index 014eea5..b9f1831 100644 --- a/ui/builders/straight.cpp +++ b/ui/builders/straight.cpp @@ -52,5 +52,7 @@ BuilderStraight::click( Link::CCollection BuilderStraight::create(Network * network, GlobalPosition3D p1, GlobalPosition3D p2) const { - return network->addStraight(p1, p2); + const auto links = network->addStraight(p1, p2); + setHeightsFor(network, links); + return links; } diff --git a/ui/editNetwork.cpp b/ui/editNetwork.cpp index ac2d93d..50d049d 100644 --- a/ui/editNetwork.cpp +++ b/ui/editNetwork.cpp @@ -63,6 +63,17 @@ EditNetwork::Builder::render(const SceneShader & shader) const candidateLinks.apply(&Renderable::render, shader); } +void +EditNetwork::Builder::setHeightsFor(Network * network, const Link::CCollection & links, GeoData::SetHeightsOpts opts) +{ + opts.surface = network->getBaseSurface(); + const auto width = network->getBaseWidth(); + + for (const auto & link : links) { + gameState->geoData->setHeights(link->getBase(width), opts); + } +} + void EditNetwork::render(const UIShader & shader, const UIComponent::Position & parentPos) const { diff --git a/ui/editNetwork.h b/ui/editNetwork.h index ec06fa7..2ae467d 100644 --- a/ui/editNetwork.h +++ b/ui/editNetwork.h @@ -1,5 +1,6 @@ #pragma once +#include "game/geoData.h" #include "gameMainSelector.h" #include "modeHelper.h" #include "toolbar.h" @@ -30,6 +31,8 @@ public: virtual void click(Network *, const GeoData *, const SDL_MouseButtonEvent &, const Ray &) = 0; virtual void move(Network *, const GeoData *, const SDL_MouseMotionEvent &, const Ray &) = 0; + static void setHeightsFor(Network *, const Link::CCollection &, GeoData::SetHeightsOpts = {}); + using Ptr = std::unique_ptr; protected: -- 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 ++++++++++++++++++++++++++++++++++++++------- game/terrain.cpp | 2 ++ lib/collections.h | 9 +++++++ ui/builders/freeExtend.cpp | 14 ++++++----- ui/builders/freeExtend.h | 4 +-- ui/builders/join.cpp | 8 +++--- ui/builders/join.h | 2 +- ui/builders/straight.cpp | 6 ++--- ui/builders/straight.h | 2 +- 10 files changed, 91 insertions(+), 34 deletions(-) (limited to 'ui') 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)))); } 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 & in, std::vector && src) return in; } +template +constexpr auto +operator+(std::vector in1, std::vector in2) +{ + in1.reserve(in1.size() + in2.size()); + std::move(in2.begin(), in2.end(), std::back_inserter(in1)); + return in1; +} + template [[nodiscard]] constexpr auto operator+(const std::vector & 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 & 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 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 & ray) + Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray & 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 & 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 & 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 p1; -- cgit v1.2.3 From 42e16ad8ad853c6e97d7eb6718ee0f78b868be30 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 9 Feb 2025 20:14:51 +0000 Subject: Combine GeoData and Terrain class hierarchies --- application/main.cpp | 8 +++----- game/gamestate.h | 4 ++-- game/terrain.cpp | 54 +++++++++++++++++++------------------------------ game/terrain.h | 13 ++++++------ test/test-geoData.cpp | 10 +++++---- test/test-render.cpp | 20 +++++++++--------- ui/editNetwork.cpp | 8 ++++---- ui/gameMainSelector.cpp | 4 ++-- 8 files changed, 54 insertions(+), 67 deletions(-) (limited to 'ui') diff --git a/application/main.cpp b/application/main.cpp index db42a63..2c0d96f 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -38,12 +38,10 @@ public: int run() { - geoData = std::make_shared(GeoData::loadFromAsciiGrid("test/fixtures/height/SD19.asc")); - windows.create(DISPLAY_WIDTH, DISPLAY_HEIGHT)->setContent(); - world.create(geoData); - world.create(geoData); + terrain = world.create(GeoData::loadFromAsciiGrid("test/fixtures/height/SD19.asc")); + world.create(terrain); assets = AssetFactory::loadAll("res"); { @@ -89,7 +87,7 @@ public: for (auto y = 491100000; y < 491130000; y += 5000) { world.create(std::dynamic_pointer_cast(assets.at(std::format("Tree-{:#02}-{}", treeDistribution(randomdev), treeVariantDistribution(randomdev)))), - Location {geoData->positionAt({{x + positionOffsetDistribution(randomdev), + Location {terrain->positionAt({{x + positionOffsetDistribution(randomdev), y + positionOffsetDistribution(randomdev)}}), {0, rotationDistribution(randomdev), 0}}); } diff --git a/game/gamestate.h b/game/gamestate.h index 892aa69..189417d 100644 --- a/game/gamestate.h +++ b/game/gamestate.h @@ -6,7 +6,7 @@ #include class WorldObject; -class GeoData; +class Terrain; class Environment; class GameState { @@ -17,7 +17,7 @@ public: NO_COPY(GameState); Collection world; - std::shared_ptr geoData; + std::shared_ptr terrain; std::shared_ptr environment; AssetFactory::Assets assets; }; diff --git a/game/terrain.cpp b/game/terrain.cpp index c834379..786b9b0 100644 --- a/game/terrain.cpp +++ b/game/terrain.cpp @@ -1,6 +1,5 @@ #include "terrain.h" #include "game/geoData.h" -#include "gfx/models/texture.h" #include #include #include @@ -15,12 +14,7 @@ #include #include -static constexpr RGB openSurface {-1}; - -Terrain::Terrain(std::shared_ptr tm) : geoData {std::move(tm)}, grass {std::make_shared("grass.png")} -{ - generateMeshes(); -} +static constexpr RGB OPEN_SURFACE {-1}; template<> VertexArrayObject & @@ -35,38 +29,34 @@ Terrain::generateMeshes() { meshes.removeAll(); std::vector indices; - indices.reserve(geoData->n_faces() * 3); + indices.reserve(n_faces() * 3); std::vector vertices; - vertices.reserve(geoData->n_vertices()); - std::map, size_t> vertexIndex; - std::for_each(geoData->vertices_sbegin(), geoData->vertices_end(), - [this, &vertexIndex, &vertices](const GeoData::VertexHandle v) { - std::for_each(geoData->vf_begin(v), geoData->vf_end(v), - [&vertexIndex, v, this, &vertices](const GeoData::FaceHandle f) { - const auto surface = geoData->getSurface(f); - if (const auto vertexIndexRef = vertexIndex.emplace(std::make_pair(v, surface), 0); - vertexIndexRef.second) { - vertexIndexRef.first->second = vertices.size(); + vertices.reserve(n_vertices()); + std::map, size_t> vertexIndex; + std::ranges::for_each(this->vertices(), [this, &vertexIndex, &vertices](const auto vertex) { + std::ranges::for_each(vf_range(vertex), [&vertexIndex, vertex, this, &vertices](const auto face) { + const auto * const surface = getSurface(face); + if (const auto vertexIndexRef = vertexIndex.emplace(std::make_pair(vertex, surface), 0); + vertexIndexRef.second) { + vertexIndexRef.first->second = vertices.size(); - vertices.emplace_back(geoData->point(v), geoData->normal(v), - surface ? surface->colorBias : openSurface); - } - }); - }); - std::for_each( - geoData->faces_sbegin(), geoData->faces_end(), [this, &vertexIndex, &indices](const GeoData::FaceHandle f) { - std::transform(geoData->fv_begin(f), geoData->fv_end(f), std::back_inserter(indices), - [&vertexIndex, f, this](const GeoData::VertexHandle v) { - return vertexIndex[std::make_pair(v, geoData->getSurface(f))]; - }); - }); + vertices.emplace_back(point(vertex), normal(vertex), surface ? surface->colorBias : OPEN_SURFACE); + } + }); + }); + std::ranges::for_each(faces(), [this, &vertexIndex, &indices](const auto face) { + std::ranges::transform( + fv_range(face), std::back_inserter(indices), [&vertexIndex, face, this](const auto vertex) { + return vertexIndex[std::make_pair(vertex, getSurface(face))]; + }); + }); meshes.create>(vertices, indices); } void Terrain::tick(TickDuration) { - if (const auto newGeneration = geoData->getGeneration(); newGeneration != geoGeneration) { + if (const auto newGeneration = getGeneration(); newGeneration != geoGeneration) { generateMeshes(); geoGeneration = newGeneration; } @@ -77,9 +67,7 @@ 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/game/terrain.h b/game/terrain.h index c9d09fe..7464bdd 100644 --- a/game/terrain.h +++ b/game/terrain.h @@ -4,17 +4,19 @@ #include "collection.h" #include "config/types.h" #include "game/worldobject.h" +#include "geoData.h" #include "gfx/models/mesh.h" #include "gfx/models/texture.h" #include "gfx/renderable.h" -#include class SceneShader; -class GeoData; -class Terrain : public WorldObject, public Renderable { +class Terrain : public GeoData, public WorldObject, public Renderable { public: - explicit Terrain(std::shared_ptr); + template explicit Terrain(P &&... params) : GeoData {std::forward

(params)...} + { + generateMeshes(); + } void render(const SceneShader & shader) const override; void shadows(const ShadowMapper &) const override; @@ -30,8 +32,7 @@ public: private: void generateMeshes(); - std::shared_ptr geoData; Collection, false> meshes; - Texture::Ptr grass; + Texture::Ptr grass = std::make_shared("grass.png"); size_t geoGeneration {}; }; diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp index dbf5f29..4979327 100644 --- a/test/test-geoData.cpp +++ b/test/test-geoData.cpp @@ -244,15 +244,13 @@ BOOST_DATA_TEST_CASE(deform, loadFixtureJson("geoData/deform/ { Surface surface; surface.colorBias = RGB {0, 0, 1}; - auto gd = std::make_shared(GeoData::createFlat({0, 0}, {1000000, 1000000}, 100)); - BOOST_CHECK_NO_THROW(gd->setHeights(points, {.surface = &surface})); ApplicationBase ab; TestMainWindow tmw; TestRenderOutput tro {{640, 480}}; struct TestTerrain : public SceneProvider { - explicit TestTerrain(std::shared_ptr gd) : terrain(std::move(gd)) { } + explicit TestTerrain(GeoData gd) : terrain(std::move(gd)) { } const Terrain terrain; @@ -281,7 +279,11 @@ BOOST_DATA_TEST_CASE(deform, loadFixtureJson("geoData/deform/ } }; - TestTerrain t {gd}; + TestTerrain t {[&points, &surface]() { + auto gd = GeoData::createFlat({0, 0}, {1000000, 1000000}, 100); + BOOST_CHECK_NO_THROW(gd.setHeights(points, {.surface = &surface})); + return gd; + }()}; SceneRenderer ss {tro.size, tro.output}; std::for_each(cams.begin(), cams.end(), [&ss, &t, &tro](const auto & cam) { ss.camera.setView(cam.first.first, glm::normalize(cam.first.second)); diff --git a/test/test-render.cpp b/test/test-render.cpp index 3966f28..3c453bd 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -30,11 +30,10 @@ class TestScene : public SceneProvider { RailVehicleClassPtr brush47rvc; std::shared_ptr train1, train2; RailLinks rail; - std::shared_ptr gd = std::make_shared(GeoData::createFlat({0, 0}, {1000000, 1000000}, 1)); std::shared_ptr env = std::make_shared(); - Terrain terrain {gd}; - Water water {gd}; + std::shared_ptr terrain = std::make_shared(GeoData::createFlat({0, 0}, {1000000, 1000000}, 1)); + Water water {terrain}; public: TestScene() @@ -71,7 +70,7 @@ public: void content(const SceneShader & shader) const override { - terrain.render(shader); + terrain->render(shader); water.render(shader); rail.render(shader); std::ranges::for_each(gameState->assets, [&shader](const auto & asset) { @@ -95,7 +94,7 @@ public: void shadows(const ShadowMapper & shadowMapper) const override { - terrain.shadows(shadowMapper); + terrain->shadows(shadowMapper); std::ranges::for_each(gameState->assets, [&shadowMapper](const auto & asset) { if (const auto renderable = std::dynamic_pointer_cast(asset.second)) { renderable->shadows(shadowMapper); @@ -167,15 +166,14 @@ BOOST_AUTO_TEST_CASE(terrain) ss.camera.setView({310000000, 490000000, 600000}, glm::normalize(glm::vec3 {1, 1, -0.5F})); class TestTerrain : public SceneProvider { - std::shared_ptr gd - = std::make_shared(GeoData::loadFromAsciiGrid(FIXTURESDIR "height/SD19.asc")); - Terrain terrain {gd}; - Water water {gd}; + std::shared_ptr terrain + = std::make_shared(GeoData::loadFromAsciiGrid(FIXTURESDIR "height/SD19.asc")); + Water water {terrain}; void content(const SceneShader & shader) const override { - terrain.render(shader); + terrain->render(shader); water.render(shader); } @@ -194,7 +192,7 @@ BOOST_AUTO_TEST_CASE(terrain) void shadows(const ShadowMapper & shadowMapper) const override { - terrain.shadows(shadowMapper); + terrain->shadows(shadowMapper); } }; diff --git a/ui/editNetwork.cpp b/ui/editNetwork.cpp index 50d049d..c4c0297 100644 --- a/ui/editNetwork.cpp +++ b/ui/editNetwork.cpp @@ -4,7 +4,7 @@ #include "builders/straight.h" #include "text.h" #include -#include +#include #include #include @@ -26,7 +26,7 @@ bool EditNetwork::click(const SDL_MouseButtonEvent & e, const Ray & ray) { if (builder && (e.button == SDL_BUTTON_LEFT || e.button == SDL_BUTTON_MIDDLE)) { - builder->click(network, gameState->geoData.get(), e, ray); + builder->click(network, gameState->terrain.get(), e, ray); return true; } return false; @@ -36,7 +36,7 @@ bool EditNetwork::move(const SDL_MouseMotionEvent & e, const Ray & ray) { if (builder) { - builder->move(network, gameState->geoData.get(), e, ray); + builder->move(network, gameState->terrain.get(), e, ray); } return false; } @@ -70,7 +70,7 @@ EditNetwork::Builder::setHeightsFor(Network * network, const Link::CCollection & const auto width = network->getBaseWidth(); for (const auto & link : links) { - gameState->geoData->setHeights(link->getBase(width), opts); + gameState->terrain->setHeights(link->getBase(width), opts); } } diff --git a/ui/gameMainSelector.cpp b/ui/gameMainSelector.cpp index 5bef48d..e9642ec 100644 --- a/ui/gameMainSelector.cpp +++ b/ui/gameMainSelector.cpp @@ -4,8 +4,8 @@ #include "ui/uiComponent.h" #include #include -#include #include +#include #include // IWYU pragma: keep #include #include @@ -83,7 +83,7 @@ GameMainSelector::defaultClick(const Ray & ray) const auto & ref = *selected.base()->get(); clicked = typeid(ref).name(); } - else if (const auto pos = gameState->geoData->intersectRay(ray)) { + else if (const auto pos = gameState->terrain->intersectRay(ray)) { clicked = streamed_string(*pos); } else { -- cgit v1.2.3