diff options
Diffstat (limited to 'game')
-rw-r--r-- | game/network/network.cpp | 25 | ||||
-rw-r--r-- | game/network/network.h | 21 | ||||
-rw-r--r-- | game/network/network.impl.h | 36 |
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); +} |