summaryrefslogtreecommitdiff
path: root/game/network/rail.cpp
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2021-02-27 20:25:43 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2021-02-27 20:25:43 +0000
commitca1d515282c295192b0b419e481ab4f8a0b3a45d (patch)
treec96243ac1e5ab32456b158ad711e84a291c8ee8b /game/network/rail.cpp
parentCalculate the candidate radii to join to point+direction angle pairs (diff)
downloadilt-ca1d515282c295192b0b419e481ab4f8a0b3a45d.tar.bz2
ilt-ca1d515282c295192b0b419e481ab4f8a0b3a45d.tar.xz
ilt-ca1d515282c295192b0b419e481ab4f8a0b3a45d.zip
Implement joining two existing links/nodes
This will likely make stupid connections in some circumstances, but they will be mechanically sound
Diffstat (limited to 'game/network/rail.cpp')
-rw-r--r--game/network/rail.cpp25
1 files changed, 22 insertions, 3 deletions
diff --git a/game/network/rail.cpp b/game/network/rail.cpp
index c1a72fb..55d57e4 100644
--- a/game/network/rail.cpp
+++ b/game/network/rail.cpp
@@ -52,7 +52,7 @@ RailLinks::addLinksBetween(glm::vec3 start, glm::vec3 end)
std::swap(start, end);
}
// Find start link/end - opposite entry dir to existing link; so pi +...
- float dir = pi + [this](const auto & n) {
+ const auto findDir = [this](const auto & n) {
for (const auto & l : links.objects) {
for (const auto & e : l->ends) {
if (e.first == n) {
@@ -61,9 +61,28 @@ RailLinks::addLinksBetween(glm::vec3 start, glm::vec3 end)
}
}
throw std::runtime_error("Node exists but couldn't find it");
- }(*node1ins.first);
+ };
+ float dir = pi + findDir(*node1ins.first);
const glm::vec2 flatStart {start.x, start.z}, flatEnd {end.x, end.z};
- // if (node2ins.second) { // Unimplemented second arc/stright required
+ if (!node2ins.second) {
+ float dir2 = pi + findDir(*node2ins.first);
+ if (const auto radii = find_arcs_radius(flatStart, dir, flatEnd, dir2); radii.first < radii.second) {
+ const auto radius {radii.first};
+ const auto c1 = start + glm::vec3 {std::sin(dir + half_pi), 0, std::cos(dir + half_pi)} * radius;
+ const auto c2 = end + glm::vec3 {std::sin(dir2 + half_pi), 0, std::cos(dir2 + half_pi)} * radius;
+ const auto mid = (c1 + c2) / 2.F;
+ addLink<RailLinkCurve>(start, mid, !c1);
+ return addLink<RailLinkCurve>(end, mid, !c2);
+ }
+ else {
+ const auto radius {radii.second};
+ const auto c1 = start + glm::vec3 {std::sin(dir - half_pi), 0, std::cos(dir - half_pi)} * radius;
+ const auto c2 = end + glm::vec3 {std::sin(dir2 - half_pi), 0, std::cos(dir2 - half_pi)} * radius;
+ const auto mid = (c1 + c2) / 2.F;
+ addLink<RailLinkCurve>(mid, start, !(c1));
+ return addLink<RailLinkCurve>(mid, end, !c2);
+ }
+ }
const auto diff {end - start};
const auto vy {vector_yaw(diff)};
const auto n2ed {(vy * 2) - dir - pi};