summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2025-02-09 13:02:09 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2025-02-09 13:02:09 +0000
commit62fd9391bbfde47177fb36434d9664e47f4cf656 (patch)
tree83c1361b41bac431f8dbddb92859fb28e76455a5
parentBig of validation on getSurface (diff)
downloadilt-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.h17
-rw-r--r--game/network/network.impl.h61
-rw-r--r--game/terrain.cpp2
-rw-r--r--lib/collections.h9
-rw-r--r--ui/builders/freeExtend.cpp14
-rw-r--r--ui/builders/freeExtend.h4
-rw-r--r--ui/builders/join.cpp8
-rw-r--r--ui/builders/join.h2
-rw-r--r--ui/builders/straight.cpp6
-rw-r--r--ui/builders/straight.h2
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;