From 260f2066ccc44a4be13e76502682b028bd5124c3 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Thu, 22 May 2025 21:51:13 +0200 Subject: [PATCH] feat(router/navmesh): Add not-yet-functional leap navnodes to navmesh --- crates/topola-egui/src/viewport.rs | 8 +++--- src/router/navmesh.rs | 41 +++++++++++++++++++----------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/crates/topola-egui/src/viewport.rs b/crates/topola-egui/src/viewport.rs index 92d5f21..27d69b5 100644 --- a/crates/topola-egui/src/viewport.rs +++ b/crates/topola-egui/src/viewport.rs @@ -274,9 +274,9 @@ impl Viewport { { from += match from_sense { RotationSense::Counterclockwise => { - [0.0, 150.0].into() + [0.0, 200.0].into() } - RotationSense::Clockwise => [-0.0, -150.0].into(), + RotationSense::Clockwise => [-0.0, -200.0].into(), }; } @@ -287,9 +287,9 @@ impl Viewport { { to += match to_sense { RotationSense::Counterclockwise => { - [0.0, 150.0].into() + [0.0, 200.0].into() } - RotationSense::Clockwise => [-0.0, -150.0].into(), + RotationSense::Clockwise => [-0.0, -200.0].into(), } } diff --git a/src/router/navmesh.rs b/src/router/navmesh.rs index f25a262..60163ff 100644 --- a/src/router/navmesh.rs +++ b/src/router/navmesh.rs @@ -139,10 +139,10 @@ pub enum NavnodeWeight { /// Navnode corresponding to a counterclockwise wrap around the layout node. CounterclockwiseStep(NavigableNodeIndex), + /// Navnode corresponding to a leap between two step or terminal navnodes. + Leap(NavigableNodeIndex), /// Navnode corresponding to a clockwise wrap around the layout node. ClockwiseStep(NavigableNodeIndex), - /// Navnode corresponding to a leap between two step or terminal navnodes. - //Leap(NavigableNodeIndex), /// Unlike the others, origin and destination layout nodes each are assigned /// only one navnode, which we call the "terminal navnode". @@ -154,6 +154,7 @@ impl NavnodeWeight { match self { NavnodeWeight::CounterclockwiseStep(node) => *node, NavnodeWeight::ClockwiseStep(node) => *node, + NavnodeWeight::Leap(node) => *node, NavnodeWeight::Terminal(node) => *node, } } @@ -162,6 +163,7 @@ impl NavnodeWeight { match self { NavnodeWeight::CounterclockwiseStep(..) => Some(RotationSense::Counterclockwise), NavnodeWeight::ClockwiseStep(..) => Some(RotationSense::Clockwise), + NavnodeWeight::Leap(..) => None, NavnodeWeight::Terminal(..) => None, } } @@ -173,7 +175,7 @@ pub enum NavmeshError { Insertion(#[from] InsertionError), } -/// The navmesh holds the entire Topola's search space represented as a graph. +/// The navmesh holds the entire router's search space represented as a graph. /// Topola's routing works by navigating over this graph with a pathfinding /// algorithm such as A* while drawing a track segment (always a cane except /// when going directly to destination) on the layout for each leap and @@ -251,12 +253,12 @@ impl Navmesh { let navnode = graph.add_node(NavnodeWeight::Terminal(trianvertex.into())); origin_navnode = Some(navnode); - map.insert(trianvertex, vec![(navnode, navnode)]); + map.insert(trianvertex, vec![(navnode, navnode, navnode)]); } else if trianvertex == destination.into() { let navnode = graph.add_node(NavnodeWeight::Terminal(trianvertex.into())); destination_navnode = Some(navnode); - map.insert(trianvertex, vec![(navnode, navnode)]); + map.insert(trianvertex, vec![(navnode, navnode, navnode)]); } else { map.insert(trianvertex, vec![]); @@ -264,7 +266,7 @@ impl Navmesh { Into::::into(Into::::into(trianvertex)); if options.squeeze_through_under_bends { - Self::add_node_to_graph_and_map_as_binavnode( + Self::add_node_to_graph_and_map_as_trinavnode( &mut graph, &mut map, trianvertex, @@ -273,7 +275,7 @@ impl Navmesh { if options.wrap_around_bands { while let Some(bend) = gear.ref_(layout.drawing()).next_gear() { - Self::add_node_to_graph_and_map_as_binavnode( + Self::add_node_to_graph_and_map_as_trinavnode( &mut graph, &mut map, trianvertex, @@ -290,14 +292,14 @@ impl Navmesh { gear = bend.into(); } - Self::add_node_to_graph_and_map_as_binavnode( + Self::add_node_to_graph_and_map_as_trinavnode( &mut graph, &mut map, trianvertex, bend.into(), ); } else { - Self::add_node_to_graph_and_map_as_binavnode( + Self::add_node_to_graph_and_map_as_trinavnode( &mut graph, &mut map, trianvertex, @@ -308,12 +310,17 @@ impl Navmesh { } for edge in triangulation.edge_references() { - for (from_navnode1, from_navnode2) in map[&edge.source()].iter() { - for (to_navnode1, to_navnode2) in map[&edge.target()].iter() { + for (from_navnode1, from_navnode2, from_navnode3) in map[&edge.source()].iter() { + for (to_navnode1, to_navnode2, to_navnode3) in map[&edge.target()].iter() { graph.update_edge(*from_navnode1, *to_navnode1, ()); graph.update_edge(*from_navnode1, *to_navnode2, ()); + graph.update_edge(*from_navnode1, *to_navnode3, ()); graph.update_edge(*from_navnode2, *to_navnode1, ()); graph.update_edge(*from_navnode2, *to_navnode2, ()); + graph.update_edge(*from_navnode2, *to_navnode3, ()); + graph.update_edge(*from_navnode3, *to_navnode1, ()); + graph.update_edge(*from_navnode3, *to_navnode2, ()); + graph.update_edge(*from_navnode3, *to_navnode3, ()); } } } @@ -327,18 +334,22 @@ impl Navmesh { }) } - fn add_node_to_graph_and_map_as_binavnode( + fn add_node_to_graph_and_map_as_trinavnode( graph: &mut UnGraph, - map: &mut BTreeMap, NodeIndex)>>, + map: &mut BTreeMap< + TrianvertexNodeIndex, + Vec<(NodeIndex, NodeIndex, NodeIndex)>, + >, trianvertex: TrianvertexNodeIndex, node: NavigableNodeIndex, ) { let navnode1 = graph.add_node(NavnodeWeight::CounterclockwiseStep(node)); - let navnode2 = graph.add_node(NavnodeWeight::ClockwiseStep(node)); + let navnode2 = graph.add_node(NavnodeWeight::Leap(node)); + let navnode3 = graph.add_node(NavnodeWeight::ClockwiseStep(node)); map.get_mut(&trianvertex) .unwrap() - .push((navnode1, navnode2)); + .push((navnode1, navnode2, navnode3)); } /// Returns the navmesh's underlying petgraph graph structure.