1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#include "network.h"
#include <game/geoData.h>
#include <gfx/gl/sceneShader.h>
#include <gfx/models/texture.h>
template<typename T, typename... Links>
void
NetworkOf<T, Links...>::joinLinks(const Link::Ptr & link) const
{
for (const auto & oldLink : links) {
Network::joinLinks(link, oldLink);
}
}
template<typename T, typename... Links>
Link::Ptr
NetworkOf<T, Links...>::intersectRayLinks(const Ray<GlobalPosition3D> & ray) const
{
// Click link
if (const auto link = std::find_if(links.begin(), links.end(),
[&ray](const std::shared_ptr<T> & link) {
return link->intersectRay(ray);
});
link != links.end()) {
return *link;
}
return {};
}
template<typename T, typename... Links>
float
NetworkOf<T, Links...>::findNodeDirection(Node::AnyCPtr n) const
{
for (const auto & link : links) {
for (const auto & end : link->ends) {
// cppcheck-suppress useStlAlgorithm
if (end.node.get() == n.get()) {
return end.dir;
}
}
}
throw std::runtime_error("Node exists but couldn't find it");
}
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>
bool
NetworkOf<T, Links...>::anyLinks() const
{
return !(static_cast<const NetworkLinkHolder<Links> *>(this)->vertices.empty() && ...);
}
template<typename T, typename... Links>
void
NetworkOf<T, Links...>::add(GeoData * 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);
if (geoData) {
geoData->setHeights(link->getBase(getBaseWidth()), GeoData::SetHeightsOpts {.surface = getBaseSurface()});
}
}
|