summaryrefslogtreecommitdiff
path: root/game/network
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2025-05-10 13:50:08 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2025-05-10 13:50:08 +0100
commitdf9b9bc264e0bf12e99b447be7903050c822692d (patch)
treee92ddbfb0c61cc94131512ed2d757df798157f72 /game/network
parentNew genCurveDef for 2 directions (diff)
downloadilt-df9b9bc264e0bf12e99b447be7903050c822692d.tar.bz2
ilt-df9b9bc264e0bf12e99b447be7903050c822692d.tar.xz
ilt-df9b9bc264e0bf12e99b447be7903050c822692d.zip
Add new network building interface
Imperfect, matches some legacy interface in places, has some TODO notes.
Diffstat (limited to 'game/network')
-rw-r--r--game/network/network.cpp25
-rw-r--r--game/network/network.h21
-rw-r--r--game/network/network.impl.h36
3 files changed, 82 insertions, 0 deletions
diff --git a/game/network/network.cpp b/game/network/network.cpp
index 403975c..295e6ec 100644
--- a/game/network/network.cpp
+++ b/game/network/network.cpp
@@ -142,3 +142,28 @@ Network::genCurveDef(const GlobalPosition3D & start, const GlobalPosition3D & en
return {genCurveDef(start, joint, startDir), genCurveDef(end, joint, endDir)};
}
+
+Link::Collection
+Network::create(const CreationDefinition & def)
+{
+ // TODO
+ // Where to make a straight to join because angles align?
+ // Where to drop part of S curve pair if a single curve works?
+
+ if (!def.fromEnd.direction && !def.toEnd.direction) {
+ // No specific directions at either end, straight link
+ return {create(GenStraightDef {def.fromEnd.position, def.toEnd.position})};
+ }
+ if (def.fromEnd.direction) {
+ if (def.toEnd.direction) {
+ // Two specific directions at both ends, S curves
+ const auto curves = genCurveDef(
+ def.fromEnd.position, def.toEnd.position, *def.fromEnd.direction, *def.toEnd.direction);
+ return {create(curves.first), create(curves.second)};
+ }
+ // One specific direction, single curve from there
+ return {create(genCurveDef(def.fromEnd.position, def.toEnd.position, *def.fromEnd.direction))};
+ }
+ // One specific direction, single curve from the other
+ return {create(genCurveDef(def.toEnd.position, def.fromEnd.position, *def.toEnd.direction))};
+}
diff --git a/game/network/network.h b/game/network/network.h
index 4f5d2b0..114f42b 100644
--- a/game/network/network.h
+++ b/game/network/network.h
@@ -19,8 +19,19 @@ class GeoData;
template<typename> class Ray;
template<size_t... N> using GenDef = std::tuple<glm::vec<N, GlobalDistance>...>;
+using GenStraightDef = GenDef<3, 3>;
using GenCurveDef = GenDef<3, 3, 2>;
+struct CreationDefinitionEnd {
+ GlobalPosition3D position;
+ std::optional<Angle> direction;
+};
+
+struct CreationDefinition {
+ CreationDefinitionEnd fromEnd;
+ CreationDefinitionEnd toEnd;
+};
+
class Network {
public:
using LinkEnd = std::pair<Link::Ptr, unsigned char>;
@@ -49,6 +60,9 @@ public:
[[nodiscard]] virtual float findNodeDirection(Node::AnyCPtr) const = 0;
+ [[nodiscard]] Link::Collection create(const CreationDefinition &);
+ virtual void add(const GeoData *, const Link::Ptr &) = 0;
+
[[nodiscard]] virtual const Surface * getBaseSurface() const = 0;
[[nodiscard]] virtual RelativeDistance getBaseWidth() const = 0;
@@ -58,6 +72,9 @@ protected:
static std::pair<GenCurveDef, GenCurveDef> genCurveDef(
const GlobalPosition3D & start, const GlobalPosition3D & end, float startDir, float endDir);
+ [[nodiscard]] virtual Link::Ptr create(const GenStraightDef &) = 0;
+ [[nodiscard]] virtual Link::Ptr create(const GenCurveDef &) = 0;
+
using Nodes = std::set<Node::Ptr, PtrMemberSorter<Node::Ptr, &Node::pos>>;
Nodes nodes;
Texture::Ptr texture;
@@ -111,6 +128,10 @@ public:
Link::CCollection addExtend(const GeoData *, GlobalPosition3D, GlobalPosition3D) override;
[[nodiscard]] float findNodeDirection(Node::AnyCPtr) const override;
+ using Network::create;
+ [[nodiscard]] Link::Ptr create(const GenStraightDef &) override;
+ [[nodiscard]] Link::Ptr create(const GenCurveDef &) override;
+ void add(const GeoData *, const Link::Ptr &) override;
protected:
Link::CCollection addCurve(const GeoData *, const GenCurveDef &);
diff --git a/game/network/network.impl.h b/game/network/network.impl.h
index e339922..54a5f4b 100644
--- a/game/network/network.impl.h
+++ b/game/network/network.impl.h
@@ -143,3 +143,39 @@ NetworkOf<T, Links...>::addExtend(const GeoData * geoData, GlobalPosition3D star
{
return addCurve(geoData, genCurveDef(start, end, findNodeDirection(nodeAt(start))));
}
+
+template<typename T, typename... Links>
+Link::Ptr
+NetworkOf<T, Links...>::create(const GenStraightDef & def)
+{
+ return std::make_shared<typename T::StraightLink>(
+ *this, candidateNodeAt(std::get<0>(def)).first, candidateNodeAt(std::get<1>(def)).first);
+}
+
+template<typename T, typename... Links>
+Link::Ptr
+NetworkOf<T, Links...>::create(const GenCurveDef & def)
+{
+ return std::make_shared<typename T::CurveLink>(
+ *this, candidateNodeAt(std::get<0>(def)).first, candidateNodeAt(std::get<1>(def)).first, std::get<2>(def));
+}
+
+template<typename T, typename... Links>
+void
+NetworkOf<T, Links...>::add(const GeoData *, const Link::Ptr & link)
+{
+ const auto addIf = [this](auto && lptr) {
+ if (lptr) {
+ links.emplace(lptr);
+ return true;
+ }
+ return false;
+ };
+ for (auto & end : link->ends) {
+ end.node = nodeAt(end.node->pos);
+ }
+ if (!(addIf(std::dynamic_pointer_cast<Links>(link)) || ...)) {
+ throw std::logic_error("Unsupported link type for network");
+ }
+ joinLinks(link);
+}