feat(router/navmesh): Add not-yet-functional leap navnodes to navmesh

This commit is contained in:
Mikolaj Wielgus 2025-05-22 21:51:13 +02:00
parent fe6a286e32
commit 260f2066cc
2 changed files with 30 additions and 19 deletions

View File

@ -274,9 +274,9 @@ impl Viewport {
{ {
from += match from_sense { from += match from_sense {
RotationSense::Counterclockwise => { 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 { to += match to_sense {
RotationSense::Counterclockwise => { 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(),
} }
} }

View File

@ -139,10 +139,10 @@ pub enum NavnodeWeight {
/// Navnode corresponding to a counterclockwise wrap around the layout node. /// Navnode corresponding to a counterclockwise wrap around the layout node.
CounterclockwiseStep(NavigableNodeIndex), 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. /// Navnode corresponding to a clockwise wrap around the layout node.
ClockwiseStep(NavigableNodeIndex), 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 /// Unlike the others, origin and destination layout nodes each are assigned
/// only one navnode, which we call the "terminal navnode". /// only one navnode, which we call the "terminal navnode".
@ -154,6 +154,7 @@ impl NavnodeWeight {
match self { match self {
NavnodeWeight::CounterclockwiseStep(node) => *node, NavnodeWeight::CounterclockwiseStep(node) => *node,
NavnodeWeight::ClockwiseStep(node) => *node, NavnodeWeight::ClockwiseStep(node) => *node,
NavnodeWeight::Leap(node) => *node,
NavnodeWeight::Terminal(node) => *node, NavnodeWeight::Terminal(node) => *node,
} }
} }
@ -162,6 +163,7 @@ impl NavnodeWeight {
match self { match self {
NavnodeWeight::CounterclockwiseStep(..) => Some(RotationSense::Counterclockwise), NavnodeWeight::CounterclockwiseStep(..) => Some(RotationSense::Counterclockwise),
NavnodeWeight::ClockwiseStep(..) => Some(RotationSense::Clockwise), NavnodeWeight::ClockwiseStep(..) => Some(RotationSense::Clockwise),
NavnodeWeight::Leap(..) => None,
NavnodeWeight::Terminal(..) => None, NavnodeWeight::Terminal(..) => None,
} }
} }
@ -173,7 +175,7 @@ pub enum NavmeshError {
Insertion(#[from] InsertionError), 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 /// 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 /// 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 /// 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())); let navnode = graph.add_node(NavnodeWeight::Terminal(trianvertex.into()));
origin_navnode = Some(navnode); origin_navnode = Some(navnode);
map.insert(trianvertex, vec![(navnode, navnode)]); map.insert(trianvertex, vec![(navnode, navnode, navnode)]);
} else if trianvertex == destination.into() { } else if trianvertex == destination.into() {
let navnode = graph.add_node(NavnodeWeight::Terminal(trianvertex.into())); let navnode = graph.add_node(NavnodeWeight::Terminal(trianvertex.into()));
destination_navnode = Some(navnode); destination_navnode = Some(navnode);
map.insert(trianvertex, vec![(navnode, navnode)]); map.insert(trianvertex, vec![(navnode, navnode, navnode)]);
} else { } else {
map.insert(trianvertex, vec![]); map.insert(trianvertex, vec![]);
@ -264,7 +266,7 @@ impl Navmesh {
Into::<GearIndex>::into(Into::<NavigableNodeIndex>::into(trianvertex)); Into::<GearIndex>::into(Into::<NavigableNodeIndex>::into(trianvertex));
if options.squeeze_through_under_bends { 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 graph,
&mut map, &mut map,
trianvertex, trianvertex,
@ -273,7 +275,7 @@ impl Navmesh {
if options.wrap_around_bands { if options.wrap_around_bands {
while let Some(bend) = gear.ref_(layout.drawing()).next_gear() { 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 graph,
&mut map, &mut map,
trianvertex, trianvertex,
@ -290,14 +292,14 @@ impl Navmesh {
gear = bend.into(); gear = bend.into();
} }
Self::add_node_to_graph_and_map_as_binavnode( Self::add_node_to_graph_and_map_as_trinavnode(
&mut graph, &mut graph,
&mut map, &mut map,
trianvertex, trianvertex,
bend.into(), bend.into(),
); );
} else { } else {
Self::add_node_to_graph_and_map_as_binavnode( Self::add_node_to_graph_and_map_as_trinavnode(
&mut graph, &mut graph,
&mut map, &mut map,
trianvertex, trianvertex,
@ -308,12 +310,17 @@ impl Navmesh {
} }
for edge in triangulation.edge_references() { for edge in triangulation.edge_references() {
for (from_navnode1, from_navnode2) in map[&edge.source()].iter() { for (from_navnode1, from_navnode2, from_navnode3) in map[&edge.source()].iter() {
for (to_navnode1, to_navnode2) in map[&edge.target()].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_navnode1, ());
graph.update_edge(*from_navnode1, *to_navnode2, ()); 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_navnode1, ());
graph.update_edge(*from_navnode2, *to_navnode2, ()); 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<NavnodeWeight, (), usize>, graph: &mut UnGraph<NavnodeWeight, (), usize>,
map: &mut BTreeMap<TrianvertexNodeIndex, Vec<(NodeIndex<usize>, NodeIndex<usize>)>>, map: &mut BTreeMap<
TrianvertexNodeIndex,
Vec<(NodeIndex<usize>, NodeIndex<usize>, NodeIndex<usize>)>,
>,
trianvertex: TrianvertexNodeIndex, trianvertex: TrianvertexNodeIndex,
node: NavigableNodeIndex, node: NavigableNodeIndex,
) { ) {
let navnode1 = graph.add_node(NavnodeWeight::CounterclockwiseStep(node)); 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) map.get_mut(&trianvertex)
.unwrap() .unwrap()
.push((navnode1, navnode2)); .push((navnode1, navnode2, navnode3));
} }
/// Returns the navmesh's underlying petgraph graph structure. /// Returns the navmesh's underlying petgraph graph structure.