router: make `Astar` own the navmesh

This commit is contained in:
Mikolaj Wielgus 2024-06-27 21:24:49 +02:00
parent 0b3ebdbe3c
commit 664bbee0b9
2 changed files with 46 additions and 47 deletions

View File

@ -129,7 +129,7 @@ impl<M: MesadataTrait> Board<M> {
.unwrap() .unwrap()
.to_string(); .to_string();
let mut router = Router::new_from_navmesh(navmesh); let mut router = Router::new_from_navmesh(self.layout_mut(), navmesh, 100.0);
let result = router.route_band(self.layout_mut(), 100.0); let result = router.route_band(self.layout_mut(), 100.0);
if let Ok(band) = result { if let Ok(band) = result {

View File

@ -19,7 +19,7 @@ use crate::{
graph::GetPetgraphIndex, graph::GetPetgraphIndex,
layout::Layout, layout::Layout,
router::{ router::{
astar::{astar, AstarError, AstarStrategy, PathTracker}, astar::{astar, Astar, AstarError, AstarStatus, AstarStrategy, PathTracker},
draw::DrawException, draw::DrawException,
navmesh::{ navmesh::{
BinavvertexNodeIndex, Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex, BinavvertexNodeIndex, Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex,
@ -37,17 +37,18 @@ pub enum RouterError {
} }
pub struct Router { pub struct Router {
navmesh: Navmesh, astar: Astar<Navmesh, f64>,
trace: Trace,
} }
struct RouterAstarStrategy<'a, R: RulesTrait> { struct RouterAstarStrategy<'a, R: RulesTrait> {
tracer: Tracer<'a, R>, pub tracer: Tracer<'a, R>,
trace: Trace, pub trace: &'a mut Trace,
target: FixedDotIndex, pub target: FixedDotIndex,
} }
impl<'a, R: RulesTrait> RouterAstarStrategy<'a, R> { impl<'a, R: RulesTrait> RouterAstarStrategy<'a, R> {
pub fn new(tracer: Tracer<'a, R>, trace: Trace, target: FixedDotIndex) -> Self { pub fn new(tracer: Tracer<'a, R>, trace: &'a mut Trace, target: FixedDotIndex) -> Self {
Self { Self {
tracer, tracer,
trace, trace,
@ -87,14 +88,14 @@ impl<'a, R: RulesTrait> RouterAstarStrategy<'a, R> {
} }
} }
impl<'a, R: RulesTrait> AstarStrategy<&Navmesh, f64, BandFirstSegIndex> impl<'a, R: RulesTrait> AstarStrategy<Navmesh, f64, BandFirstSegIndex>
for RouterAstarStrategy<'a, R> for RouterAstarStrategy<'a, R>
{ {
fn is_goal( fn is_goal(
&mut self, &mut self,
navmesh: &&Navmesh, navmesh: &Navmesh,
vertex: NavvertexIndex, vertex: NavvertexIndex,
tracker: &PathTracker<&Navmesh>, tracker: &PathTracker<Navmesh>,
) -> Option<BandFirstSegIndex> { ) -> Option<BandFirstSegIndex> {
let new_path = tracker.reconstruct_path_to(vertex); let new_path = tracker.reconstruct_path_to(vertex);
let width = self.trace.width; let width = self.trace.width;
@ -108,7 +109,7 @@ impl<'a, R: RulesTrait> AstarStrategy<&Navmesh, f64, BandFirstSegIndex>
.ok() .ok()
} }
fn edge_cost(&mut self, navmesh: &&Navmesh, edge: NavmeshEdgeReference) -> Option<f64> { fn edge_cost(&mut self, navmesh: &Navmesh, edge: NavmeshEdgeReference) -> Option<f64> {
if edge.target().petgraph_index() == self.target.petgraph_index() { if edge.target().petgraph_index() == self.target.petgraph_index() {
return None; return None;
} }
@ -130,7 +131,7 @@ impl<'a, R: RulesTrait> AstarStrategy<&Navmesh, f64, BandFirstSegIndex>
} }
} }
fn estimate_cost(&mut self, navmesh: &&Navmesh, vertex: NavvertexIndex) -> f64 { fn estimate_cost(&mut self, navmesh: &Navmesh, vertex: NavvertexIndex) -> f64 {
let start_point = PrimitiveIndex::from(navmesh.node_weight(vertex).unwrap().node) let start_point = PrimitiveIndex::from(navmesh.node_weight(vertex).unwrap().node)
.primitive(self.tracer.layout.drawing()) .primitive(self.tracer.layout.drawing())
.shape() .shape()
@ -149,53 +150,51 @@ impl<'a, R: RulesTrait> AstarStrategy<&Navmesh, f64, BandFirstSegIndex>
impl Router { impl Router {
pub fn new( pub fn new(
layout: &Layout<impl RulesTrait>, layout: &mut Layout<impl RulesTrait>,
from: FixedDotIndex, from: FixedDotIndex,
to: FixedDotIndex, to: FixedDotIndex,
width: f64,
) -> Result<Self, RouterError> { ) -> Result<Self, RouterError> {
let navmesh = { Navmesh::new(layout, from, to)? }; let navmesh = Navmesh::new(layout, from, to)?;
Ok(Self::new_from_navmesh(navmesh)) Ok(Self::new_from_navmesh(layout, navmesh, width))
} }
pub fn new_from_navmesh(navmesh: Navmesh) -> Self { pub fn new_from_navmesh(
Self { navmesh } layout: &mut Layout<impl RulesTrait>,
navmesh: Navmesh,
width: f64,
) -> Self {
let source = navmesh.source();
let source_navvertex = navmesh.source_navvertex();
let target = navmesh.target();
let mut tracer = Tracer::new(layout);
let mut trace = tracer.start(&navmesh, source, source_navvertex, width);
let mut strategy = RouterAstarStrategy::new(tracer, &mut trace, target);
let astar = Astar::new(navmesh, source_navvertex, &mut strategy);
Self { astar, trace }
} }
pub fn route_band( pub fn route_band(
&mut self, &mut self,
layout: &mut Layout<impl RulesTrait>, layout: &mut Layout<impl RulesTrait>,
width: f64, _width: f64,
) -> Result<BandFirstSegIndex, RouterError> { ) -> Result<BandFirstSegIndex, RouterError> {
let mut tracer = Tracer::new(layout); let tracer = Tracer::new(layout);
let trace = tracer.start( let target = self.astar.graph.target();
&self.navmesh, let mut strategy = RouterAstarStrategy::new(tracer, &mut self.trace, target);
self.navmesh.source(),
self.navmesh.source_navvertex(),
width,
);
let (_cost, _path, band) = astar( loop {
&self.navmesh, let status = match self.astar.step(&mut strategy) {
self.navmesh.source_navvertex(), Ok(status) => status,
&mut RouterAstarStrategy::new(tracer, trace, self.navmesh.target()), Err(err) => return Err(err.into()),
)?; };
Ok(band) if let AstarStatus::Finished(_cost, _path, band) = status {
return Ok(band);
}
} }
/*pub fn reroute_band(
&mut self,
band: BandIndex,
to: Point,
width: f64,
) -> Result<BandIndex, RoutingError> {
{
let mut layout = self.layout.lock().unwrap();
layout.remove_band(band);
layout.move_dot(self.navmesh.to().into(), to).unwrap(); // TODO: Remove `.unwrap()`.
} }
self.route_band(width)
}*/
} }