diff --git a/src/router/navmesh.rs b/src/router/navmesh.rs index f628fb8..ef057f4 100644 --- a/src/router/navmesh.rs +++ b/src/router/navmesh.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use enum_dispatch::enum_dispatch; use geo::Point; use petgraph::{ + data::DataMap, graph::UnGraph, stable_graph::NodeIndex, visit::{ @@ -106,9 +107,9 @@ pub enum NavmeshError { pub struct Navmesh { graph: UnGraph, source: FixedDotIndex, - source_navvertex: NodeIndex, + source_navvertex: NavvertexIndex, target: FixedDotIndex, - target_navvertex: NodeIndex, + target_navvertex: NavvertexIndex, } impl Navmesh { @@ -204,9 +205,9 @@ impl Navmesh { Ok(Self { graph, source, - source_navvertex: source_navvertex.unwrap(), + source_navvertex: NavvertexIndex(source_navvertex.unwrap()), target, - target_navvertex: target_navvertex.unwrap(), + target_navvertex: NavvertexIndex(target_navvertex.unwrap()), }) } @@ -218,7 +219,7 @@ impl Navmesh { self.source } - pub fn source_navvertex(&self) -> NodeIndex { + pub fn source_navvertex(&self) -> NavvertexIndex { self.source_navvertex } @@ -226,7 +227,7 @@ impl Navmesh { self.target } - pub fn target_navvertex(&self) -> NodeIndex { + pub fn target_navvertex(&self) -> NavvertexIndex { self.target_navvertex } } @@ -241,6 +242,16 @@ impl Data for Navmesh { type EdgeWeight = (); } +impl DataMap for Navmesh { + fn node_weight(&self, vertex: Self::NodeId) -> Option<&Self::NodeWeight> { + self.graph.node_weight(vertex.petgraph_index()) + } + + fn edge_weight(&self, _edge: Self::EdgeId) -> Option<&Self::EdgeWeight> { + None + } +} + #[derive(Debug, Clone, Copy)] pub struct NavmeshEdgeReference { from: NavvertexIndex, diff --git a/src/router/router.rs b/src/router/router.rs index 056f8e8..b26864c 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -1,5 +1,6 @@ use geo::EuclideanDistance; use petgraph::{ + data::DataMap, graph::{EdgeReference, NodeIndex, UnGraph}, visit::EdgeRef, }; @@ -20,7 +21,10 @@ use crate::{ router::{ astar::{astar, AstarError, AstarStrategy, PathTracker}, draw::DrawException, - navmesh::{BinavvertexNodeIndex, Navmesh, NavmeshError, NavvertexWeight}, + navmesh::{ + BinavvertexNodeIndex, Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex, + NavvertexWeight, + }, tracer::{Trace, Tracer}, }, }; @@ -83,33 +87,29 @@ impl<'a, R: RulesTrait> RouterAstarStrategy<'a, R> { } } -impl<'a, R: RulesTrait> AstarStrategy<&UnGraph, f64, BandFirstSegIndex> +impl<'a, R: RulesTrait> AstarStrategy<&Navmesh, f64, BandFirstSegIndex> for RouterAstarStrategy<'a, R> { fn is_goal( &mut self, - graph: &&UnGraph, - vertex: NodeIndex, - tracker: &PathTracker<&UnGraph>, + navmesh: &&Navmesh, + vertex: NavvertexIndex, + tracker: &PathTracker<&Navmesh>, ) -> Option { let new_path = tracker.reconstruct_path_to(vertex); let width = self.trace.width; self.tracer - .rework_path(*graph, &mut self.trace, &new_path[..], width) + .rework_path(navmesh, &mut self.trace, &new_path[..], width) .unwrap(); self.tracer - .finish(*graph, &mut self.trace, self.target, width) + .finish(navmesh, &mut self.trace, self.target, width) .ok() } - fn edge_cost( - &mut self, - graph: &&UnGraph, - edge: EdgeReference<(), usize>, - ) -> Option { - if edge.target() == self.target.petgraph_index() { + fn edge_cost(&mut self, navmesh: &&Navmesh, edge: NavmeshEdgeReference) -> Option { + if edge.target().petgraph_index() == self.target.petgraph_index() { return None; } @@ -118,24 +118,20 @@ impl<'a, R: RulesTrait> AstarStrategy<&UnGraph, f64, let width = self.trace.width; let result = self .tracer - .step(*graph, &mut self.trace, edge.target(), width); + .step(navmesh, &mut self.trace, edge.target(), width); let probe_length = self.bihead_length() - prev_bihead_length; if result.is_ok() { - self.tracer.undo_step(*graph, &mut self.trace); + self.tracer.undo_step(navmesh, &mut self.trace); Some(probe_length) } else { None } } - fn estimate_cost( - &mut self, - graph: &&UnGraph, - vertex: NodeIndex, - ) -> f64 { - let start_point = PrimitiveIndex::from(graph.node_weight(vertex).unwrap().node) + fn estimate_cost(&mut self, navmesh: &&Navmesh, vertex: NavvertexIndex) -> f64 { + let start_point = PrimitiveIndex::from(navmesh.node_weight(vertex).unwrap().node) .primitive(self.tracer.layout.drawing()) .shape() .center(); @@ -172,14 +168,14 @@ impl Router { ) -> Result { let mut tracer = Tracer::new(layout); let trace = tracer.start( - self.navmesh.graph(), + &self.navmesh, self.navmesh.source(), self.navmesh.source_navvertex(), width, ); let (_cost, _path, band) = astar( - self.navmesh.graph(), + &self.navmesh, self.navmesh.source_navvertex(), &mut RouterAstarStrategy::new(tracer, trace, self.navmesh.target()), )?; diff --git a/src/router/tracer.rs b/src/router/tracer.rs index 4232cb3..4947432 100644 --- a/src/router/tracer.rs +++ b/src/router/tracer.rs @@ -1,5 +1,8 @@ use contracts::{debug_ensures, debug_requires}; -use petgraph::graph::{NodeIndex, UnGraph}; +use petgraph::{ + data::DataMap, + graph::{NodeIndex, UnGraph}, +}; use thiserror::Error; use crate::{ @@ -14,7 +17,7 @@ use crate::{ layout::Layout, router::{ draw::{Draw, DrawException}, - navmesh::{BinavvertexNodeIndex, NavvertexWeight}, + navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex, NavvertexWeight}, }, }; @@ -28,7 +31,7 @@ pub enum TracerException { #[derive(Debug)] pub struct Trace { - pub path: Vec>, + pub path: Vec, pub head: Head, pub width: f64, } @@ -45,9 +48,9 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { pub fn start( &mut self, - _graph: &UnGraph, + _navmesh: &Navmesh, source: FixedDotIndex, - source_navvertex: NodeIndex, + source_navvertex: NavvertexIndex, width: f64, ) -> Trace { Trace { @@ -59,7 +62,7 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { pub fn finish( &mut self, - graph: &UnGraph, + _navmesh: &Navmesh, trace: &mut Trace, target: FixedDotIndex, width: f64, @@ -71,9 +74,9 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { #[debug_ensures(ret.is_ok() -> trace.path.len() == path.len())] pub fn rework_path( &mut self, - graph: &UnGraph, + navmesh: &Navmesh, trace: &mut Trace, - path: &[NodeIndex], + path: &[NavvertexIndex], width: f64, ) -> Result<(), TracerException> { let prefix_length = trace @@ -84,21 +87,21 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { .count(); let length = trace.path.len(); - self.undo_path(graph, trace, length - prefix_length); - Ok::<(), TracerException>(self.path(graph, trace, &path[prefix_length..], width)?) + self.undo_path(navmesh, trace, length - prefix_length); + Ok::<(), TracerException>(self.path(navmesh, trace, &path[prefix_length..], width)?) } #[debug_ensures(ret.is_ok() -> trace.path.len() == old(trace.path.len() + path.len()))] pub fn path( &mut self, - graph: &UnGraph, + navmesh: &Navmesh, trace: &mut Trace, - path: &[NodeIndex], + path: &[NavvertexIndex], width: f64, ) -> Result<(), TracerException> { for (i, vertex) in path.iter().enumerate() { - if let Err(err) = self.step(graph, trace, *vertex, width) { - self.undo_path(graph, trace, i); + if let Err(err) = self.step(navmesh, trace, *vertex, width) { + self.undo_path(navmesh, trace, i); return Err(err.into()); } } @@ -107,14 +110,9 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { } #[debug_ensures(trace.path.len() == old(trace.path.len() - step_count))] - pub fn undo_path( - &mut self, - graph: &UnGraph, - trace: &mut Trace, - step_count: usize, - ) { + pub fn undo_path(&mut self, navmesh: &Navmesh, trace: &mut Trace, step_count: usize) { for _ in 0..step_count { - self.undo_step(graph, trace); + self.undo_step(navmesh, trace); } } @@ -123,12 +121,12 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { #[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))] pub fn step( &mut self, - graph: &UnGraph, + navmesh: &Navmesh, trace: &mut Trace, - to: NodeIndex, + to: NavvertexIndex, width: f64, ) -> Result<(), TracerException> { - trace.head = self.wrap(graph, trace.head, to, width)?.into(); + trace.head = self.wrap(navmesh, trace.head, to, width)?.into(); trace.path.push(to); Ok::<(), TracerException>(()) @@ -136,29 +134,29 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { fn wrap( &mut self, - graph: &UnGraph, + navmesh: &Navmesh, head: Head, - around: NodeIndex, + around: NavvertexIndex, width: f64, ) -> Result { let cw = self - .maybe_cw(graph, around) + .maybe_cw(navmesh, around) .ok_or(TracerException::CannotWrap)?; - match self.binavvertex(graph, around) { + match self.binavvertex(navmesh, around) { BinavvertexNodeIndex::FixedDot(dot) => { - self.wrap_around_fixed_dot(graph, head, dot, cw, width) + self.wrap_around_fixed_dot(navmesh, head, dot, cw, width) } BinavvertexNodeIndex::FixedBend(_fixed_bend) => todo!(), BinavvertexNodeIndex::LooseBend(loose_bend) => { - self.wrap_around_loose_bend(graph, head, loose_bend, cw, width) + self.wrap_around_loose_bend(navmesh, head, loose_bend, cw, width) } } } fn wrap_around_fixed_dot( &mut self, - graph: &UnGraph, + _navmesh: &Navmesh, head: Head, around: FixedDotIndex, cw: bool, @@ -169,7 +167,7 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { fn wrap_around_loose_bend( &mut self, - graph: &UnGraph, + _navmesh: &Navmesh, head: Head, around: LooseBendIndex, cw: bool, @@ -179,7 +177,7 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { } #[debug_ensures(trace.path.len() == old(trace.path.len() - 1))] - pub fn undo_step(&mut self, graph: &UnGraph, trace: &mut Trace) { + pub fn undo_step(&mut self, _navmesh: &Navmesh, trace: &mut Trace) { if let Head::Cane(head) = trace.head { trace.head = Draw::new(self.layout).undo_cane(head).unwrap(); } else { @@ -189,27 +187,15 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { trace.path.pop(); } - fn maybe_cw( - &self, - graph: &UnGraph, - navvertex: NodeIndex, - ) -> Option { - graph.node_weight(navvertex).unwrap().maybe_cw + fn maybe_cw(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> Option { + navmesh.node_weight(navvertex).unwrap().maybe_cw } - fn binavvertex( - &self, - graph: &UnGraph, - navvertex: NodeIndex, - ) -> BinavvertexNodeIndex { - graph.node_weight(navvertex).unwrap().node + fn binavvertex(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> BinavvertexNodeIndex { + navmesh.node_weight(navvertex).unwrap().node } - fn primitive( - &self, - graph: &UnGraph, - navvertex: NodeIndex, - ) -> PrimitiveIndex { - self.binavvertex(graph, navvertex).into() + fn primitive(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> PrimitiveIndex { + self.binavvertex(navmesh, navvertex).into() } }