From eaecb99146c07922c12cf78f2665213071d33c94 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 6 May 2024 02:35:43 +0200 Subject: [PATCH] egui: draw the navmesh This required some considerable rearrangements in `Router`. --- src/autorouter/autorouter.rs | 35 +++++++++++++--------- src/bin/topola-egui/app.rs | 35 ++++++++++++++++++---- src/bin/topola-egui/painter.rs | 2 +- src/bin/topola-sdl2-demo/main.rs | 10 +++---- src/bin/topola-sdl2-demo/painter.rs | 2 +- src/router/router.rs | 45 +++++++++++++---------------- src/router/tracer.rs | 9 +++--- 7 files changed, 82 insertions(+), 56 deletions(-) diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 7eb79bf..9cd82c7 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -11,12 +11,13 @@ use crate::{ autorouter::ratsnest::{Ratsnest, RatsnestVertexIndex}, drawing::{dot::FixedDotIndex, rules::RulesTrait}, layout::{connectivity::BandIndex, Layout}, - router::{Router, RouterObserverTrait, RoutingError}, + router::{navmesh::Navmesh, Router, RouterObserverTrait, RoutingError}, triangulation::GetVertexIndex, }; pub struct Autoroute { edge_indices: EdgeIndices, + navmesh: Navmesh, // Useful for debugging. } impl Autoroute { @@ -30,9 +31,9 @@ impl Autoroute { }; let (from, to) = autorouter.ratsnest.graph().edge_endpoints(ratline).unwrap(); - let (from_dot, to_dot) = { - let layout = autorouter.router.layout(); - let mut layout = layout.lock().unwrap(); + let (navmesh, from_dot, to_dot) = { + let mut layout = autorouter.layout.lock().unwrap(); + let navmesh = Navmesh::new(&layout).unwrap(); let from_dot = match autorouter .ratsnest @@ -56,28 +57,33 @@ impl Autoroute { RatsnestVertexIndex::Zone(zone) => layout.zone_apex(zone), }; - (from_dot, to_dot) + (navmesh, from_dot, to_dot) }; - autorouter - .router + let router = Router::new_with_navmesh( + &mut autorouter.layout, + std::mem::replace(&mut self.navmesh, navmesh), + ); + router + .unwrap() .route_band(from_dot, to_dot, 100.0, observer); Some(()) } + + pub fn navmesh(&self) -> &Navmesh { + &self.navmesh + } } pub struct Autorouter { ratsnest: Ratsnest, - router: Router, + layout: Arc>>, } impl Autorouter { pub fn new(layout: Arc>>) -> Result { let ratsnest = Ratsnest::new(&layout.lock().unwrap())?; - Ok(Self { - ratsnest, - router: Router::new(layout), - }) + Ok(Self { ratsnest, layout }) } pub fn autoroute(&mut self, observer: &mut impl RouterObserverTrait) { @@ -90,10 +96,11 @@ impl Autorouter { pub fn autoroute_iter(&mut self) -> Autoroute { Autoroute { edge_indices: self.ratsnest.graph().edge_indices(), + navmesh: Navmesh::new(&self.layout.lock().unwrap()).unwrap(), } } - pub fn router(&self) -> &Router { - &self.router + pub fn layout(&self) -> &Arc>> { + &self.layout } } diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index 86756af..3384029 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -21,13 +21,14 @@ use topola::{ geometry::{ compound::CompoundManagerTrait, primitive::{BendShape, DotShape, PrimitiveShape, PrimitiveShapeTrait, SegShape}, + shape::ShapeTrait, GenericNode, }, layout::{zone::MakePolyShape, Layout}, math::Circle, router::{ draw::DrawException, - navmesh::{NavmeshEdgeReference, VertexIndex}, + navmesh::{Navmesh, NavmeshEdgeReference, VertexIndex}, tracer::{Trace, Tracer}, RouterObserverTrait, }, @@ -37,6 +38,7 @@ use crate::{overlay::Overlay, painter::Painter}; #[derive(Debug, Default)] struct SharedData { + pub navmesh: Option, pub path: Vec, pub ghosts: Vec, pub highlighteds: Vec, @@ -197,7 +199,17 @@ impl eframe::App for App { execute(async move { let mut autorouter = Autorouter::new(layout).unwrap(); - autorouter.autoroute(&mut DebugRouterObserver { shared_data }); + let mut it = autorouter.autoroute_iter(); + shared_data.lock().unwrap().navmesh = Some(it.navmesh().clone()); + + while let Some(()) = it.next( + &mut autorouter, + &mut DebugRouterObserver { + shared_data: shared_data.clone(), + }, + ) { + shared_data.lock().unwrap().navmesh = Some(it.navmesh().clone()); + } }); } } @@ -264,7 +276,7 @@ impl eframe::App for App { } else { egui::Color32::from_rgb(52, 52, 200) }; - painter.paint_shape(&shape, color); + painter.paint_primitive(&shape, color); } for zone in layout.layer_zone_nodes(1) { @@ -289,7 +301,7 @@ impl eframe::App for App { } else { egui::Color32::from_rgb(200, 52, 52) }; - painter.paint_shape(&shape, color); + painter.paint_primitive(&shape, color); } for zone in layout.layer_zone_nodes(0) { @@ -319,8 +331,21 @@ impl eframe::App for App { painter.paint_edge(from, to, egui::Color32::from_rgb(90, 90, 200)); } + if let Some(navmesh) = &shared_data.navmesh { + for edge in navmesh.edge_references() { + let from = + edge.source().primitive(layout.drawing()).shape().center(); + let to = edge.target().primitive(layout.drawing()).shape().center(); + painter.paint_edge( + from, + to, + egui::Color32::from_rgb(125, 125, 125), + ); + } + } + for ghost in shared_data.ghosts.iter() { - painter.paint_shape(&ghost, egui::Color32::from_rgb(75, 75, 150)); + painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150)); } //unreachable!(); } diff --git a/src/bin/topola-egui/painter.rs b/src/bin/topola-egui/painter.rs index 0240bf1..70306be 100644 --- a/src/bin/topola-egui/painter.rs +++ b/src/bin/topola-egui/painter.rs @@ -11,7 +11,7 @@ impl<'a> Painter<'a> { Self { ui, transform } } - pub fn paint_shape(&mut self, shape: &PrimitiveShape, color: egui::epaint::Color32) { + pub fn paint_primitive(&mut self, shape: &PrimitiveShape, color: egui::epaint::Color32) { let epaint_shape = match shape { PrimitiveShape::Dot(dot) => egui::Shape::circle_filled( self.transform diff --git a/src/bin/topola-sdl2-demo/main.rs b/src/bin/topola-sdl2-demo/main.rs index 81f2c22..80d06d7 100644 --- a/src/bin/topola-sdl2-demo/main.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -406,7 +406,7 @@ fn render_times( }; let shape = node.primitive(drawing).shape(); - painter.paint_shape(&shape, color, view.zoom); + painter.paint_primitive(&shape, color, view.zoom); } for zone in drawing.layer_zones(1) { @@ -425,7 +425,7 @@ fn render_times( }; let shape = node.primitive(drawing).shape(); - painter.paint_shape(&shape, color, view.zoom); + painter.paint_primitive(&shape, color, view.zoom); } for zone in drawing.layer_zones(0) { @@ -437,13 +437,13 @@ fn render_times( } for ghost in ghosts { - painter.paint_shape(&ghost, ColorU::new(75, 75, 150, 255), view.zoom); + painter.paint_primitive(&ghost, ColorU::new(75, 75, 150, 255), view.zoom); } if let Some(ref navmesh) = maybe_navmesh { for edge in navmesh.edge_references() { - let to = edge.source().primitive(drawing).shape().center(); - let from = edge.target().primitive(drawing).shape().center(); + let from = edge.source().primitive(drawing).shape().center(); + let to = edge.target().primitive(drawing).shape().center(); let color = 'blk: { if let (Some(source_pos), Some(target_pos)) = ( diff --git a/src/bin/topola-sdl2-demo/painter.rs b/src/bin/topola-sdl2-demo/painter.rs index e34a341..6b66d40 100644 --- a/src/bin/topola-sdl2-demo/painter.rs +++ b/src/bin/topola-sdl2-demo/painter.rs @@ -13,7 +13,7 @@ impl<'a> Painter<'a> { Self { canvas } } - pub fn paint_shape(&mut self, shape: &PrimitiveShape, color: ColorU, zoom: f32) { + pub fn paint_primitive(&mut self, shape: &PrimitiveShape, color: ColorU, zoom: f32) { self.canvas.set_stroke_style(color); self.canvas.set_fill_style(color); diff --git a/src/router/router.rs b/src/router/router.rs index 0825100..edc4e6b 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -57,24 +57,20 @@ pub trait RouterObserverTrait { fn on_estimate(&mut self, tracer: &Tracer, vertex: VertexIndex); } -pub struct Router { - layout: Arc>>, +pub struct Router<'a, R: RulesTrait> { + layout: &'a mut Arc>>, + navmesh: Navmesh, } struct RouterAstarStrategy<'a, RO: RouterObserverTrait, R: RulesTrait> { - tracer: Tracer<'a, R>, + tracer: Tracer, trace: Trace, to: FixedDotIndex, observer: &'a mut RO, } impl<'a, RO: RouterObserverTrait, R: RulesTrait> RouterAstarStrategy<'a, RO, R> { - pub fn new( - tracer: Tracer<'a, R>, - trace: Trace, - to: FixedDotIndex, - observer: &'a mut RO, - ) -> Self { + pub fn new(tracer: Tracer, trace: Trace, to: FixedDotIndex, observer: &'a mut RO) -> Self { Self { tracer, trace, @@ -146,9 +142,17 @@ impl<'a, RO: RouterObserverTrait, R: RulesTrait> AstarStrategy<&Navmesh, f64> } } -impl Router { - pub fn new(layout: Arc>>) -> Self { - Router { layout } +impl<'a, R: RulesTrait> Router<'a, R> { + pub fn new(layout: &'a mut Arc>>) -> Result { + let navmesh = Navmesh::new(&layout.lock().unwrap())?; + Self::new_with_navmesh(layout, navmesh) + } + + pub fn new_with_navmesh( + layout: &'a mut Arc>>, + navmesh: Navmesh, + ) -> Result { + Ok(Self { layout, navmesh }) } pub fn route_band( @@ -158,22 +162,13 @@ impl Router { width: f64, observer: &mut impl RouterObserverTrait, ) -> Result { - // XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look - // right. - //self.mesh.triangulate(&self.layout)?; - let mesh = Navmesh::new(&self.layout.lock().unwrap()).map_err(|err| RoutingError { - from, - to, - source: err.into(), - })?; - - let mut tracer = self.tracer(&mesh); + let mut tracer = self.tracer(); let trace = tracer.start(from, width); let band = trace.band; let (_cost, _path) = astar( - &mesh, + &self.navmesh, from.into(), &mut RouterAstarStrategy::new(tracer, trace, to.into(), observer), ) @@ -206,8 +201,8 @@ impl Router { self.route_band(from_dot, to_dot, width, observer) } - pub fn tracer<'a>(&'a mut self, mesh: &'a Navmesh) -> Tracer { - Tracer::new(self.layout.clone(), mesh) + fn tracer(&mut self) -> Tracer { + Tracer::new(self.layout.clone()) } pub fn layout(&self) -> Arc>> { diff --git a/src/router/tracer.rs b/src/router/tracer.rs index 329c8ef..5acd2dd 100644 --- a/src/router/tracer.rs +++ b/src/router/tracer.rs @@ -25,14 +25,13 @@ pub struct Trace { } #[derive(Debug)] -pub struct Tracer<'a, R: RulesTrait> { +pub struct Tracer { pub layout: Arc>>, - pub navmesh: &'a Navmesh, } -impl<'a, R: RulesTrait> Tracer<'a, R> { - pub fn new(layout: Arc>>, navmesh: &'a Navmesh) -> Self { - Tracer { layout, navmesh } +impl Tracer { + pub fn new(layout: Arc>>) -> Self { + Tracer { layout } } pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace {