navmesh: some rearrangements in preparation for interactive routing

This commit is contained in:
Mikolaj Wielgus 2024-08-29 02:04:27 +02:00
parent 5d9753d941
commit 994b9e8e9b
1 changed files with 35 additions and 26 deletions

View File

@ -116,21 +116,21 @@ pub struct Navmesh {
impl Navmesh { impl Navmesh {
pub fn new( pub fn new(
layout: &Layout<impl AccessRules>, layout: &Layout<impl AccessRules>,
source: FixedDotIndex, origin: FixedDotIndex,
target: FixedDotIndex, destination: FixedDotIndex,
) -> Result<Self, NavmeshError> { ) -> Result<Self, NavmeshError> {
let mut triangulation: Triangulation<TrianvertexNodeIndex, TrianvertexWeight, ()> = let mut triangulation: Triangulation<TrianvertexNodeIndex, TrianvertexWeight, ()> =
Triangulation::new(layout.drawing().geometry().graph().node_bound()); Triangulation::new(layout.drawing().geometry().graph().node_bound());
let layer = layout.drawing().primitive(source).layer(); let layer = layout.drawing().primitive(origin).layer();
let maybe_net = layout.drawing().primitive(source).maybe_net(); let maybe_net = layout.drawing().primitive(origin).maybe_net();
for node in layout.drawing().layer_primitive_nodes(layer) { for node in layout.drawing().layer_primitive_nodes(layer) {
let primitive = node.primitive(layout.drawing()); let primitive = node.primitive(layout.drawing());
if let Some(primitive_net) = primitive.maybe_net() { if let Some(primitive_net) = primitive.maybe_net() {
if node == source.into() if node == origin.into()
|| node == target.into() || node == destination.into()
|| Some(primitive_net) != maybe_net || Some(primitive_net) != maybe_net
{ {
match node { match node {
@ -152,30 +152,38 @@ impl Navmesh {
} }
} }
Self::new_from_triangulation(triangulation, origin, destination)
}
fn new_from_triangulation(
triangulation: Triangulation<TrianvertexNodeIndex, TrianvertexWeight, ()>,
origin: FixedDotIndex,
destination: FixedDotIndex,
) -> Result<Self, NavmeshError> {
let mut graph: UnGraph<NavvertexWeight, (), usize> = UnGraph::default(); let mut graph: UnGraph<NavvertexWeight, (), usize> = UnGraph::default();
let mut source_navvertex = None; let mut origin_navvertex = None;
let mut target_navvertex = None; let mut destination_navvertex = None;
// `HashMap` is obviously suboptimal here. // `HashMap` is obviously suboptimal here.
let mut map = HashMap::new(); let mut map = HashMap::new();
for trianvertex in triangulation.node_identifiers() { for trianvertex in triangulation.node_identifiers() {
let binavvertex = if trianvertex == source.into() { let binavvertex = if trianvertex == origin.into() {
let navvertex = graph.add_node(NavvertexWeight { let navvertex = graph.add_node(NavvertexWeight {
node: trianvertex.into(), node: trianvertex.into(),
maybe_cw: None, maybe_cw: None,
}); });
source_navvertex = Some(navvertex); origin_navvertex = Some(navvertex);
(navvertex, navvertex) vec![(navvertex, navvertex)]
} else if trianvertex == target.into() { } else if trianvertex == destination.into() {
let navvertex = graph.add_node(NavvertexWeight { let navvertex = graph.add_node(NavvertexWeight {
node: trianvertex.into(), node: trianvertex.into(),
maybe_cw: None, maybe_cw: None,
}); });
target_navvertex = Some(navvertex); destination_navvertex = Some(navvertex);
(navvertex, navvertex) vec![(navvertex, navvertex)]
} else { } else {
let navvertex1 = graph.add_node(NavvertexWeight { let navvertex1 = graph.add_node(NavvertexWeight {
node: trianvertex.into(), node: trianvertex.into(),
@ -187,28 +195,29 @@ impl Navmesh {
maybe_cw: Some(true), maybe_cw: Some(true),
}); });
(navvertex1, navvertex2) vec![(navvertex1, navvertex2)]
}; };
map.insert(trianvertex, binavvertex); map.insert(trianvertex, binavvertex);
} }
for edge in triangulation.edge_references() { for edge in triangulation.edge_references() {
let (from_navvertex1, from_navvertex2) = map[&edge.source()]; for (from_navvertex1, from_navvertex2) in map[&edge.source()].iter() {
let (to_navvertex1, to_navvertex2) = map[&edge.target()]; for (to_navvertex1, to_navvertex2) in map[&edge.target()].iter() {
graph.update_edge(*from_navvertex1, *to_navvertex1, ());
graph.update_edge(from_navvertex1, to_navvertex1, ()); graph.update_edge(*from_navvertex1, *to_navvertex2, ());
graph.update_edge(from_navvertex1, to_navvertex2, ()); graph.update_edge(*from_navvertex2, *to_navvertex1, ());
graph.update_edge(from_navvertex2, to_navvertex1, ()); graph.update_edge(*from_navvertex2, *to_navvertex2, ());
graph.update_edge(from_navvertex2, to_navvertex2, ()); }
}
} }
Ok(Self { Ok(Self {
graph, graph,
origin: source, origin,
origin_navvertex: NavvertexIndex(source_navvertex.unwrap()), origin_navvertex: NavvertexIndex(origin_navvertex.unwrap()),
destination: target, destination,
destination_navvertex: NavvertexIndex(target_navvertex.unwrap()), destination_navvertex: NavvertexIndex(destination_navvertex.unwrap()),
}) })
} }