mirror of https://codeberg.org/topola/topola.git
egui: draw the navmesh
This required some considerable rearrangements in `Router`.
This commit is contained in:
parent
63561e6a4a
commit
eaecb99146
|
|
@ -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<usize>,
|
||||
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<R: RulesTrait> {
|
||||
ratsnest: Ratsnest,
|
||||
router: Router<R>,
|
||||
layout: Arc<Mutex<Layout<R>>>,
|
||||
}
|
||||
|
||||
impl<R: RulesTrait> Autorouter<R> {
|
||||
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Result<Self, InsertionError> {
|
||||
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<R>) {
|
||||
|
|
@ -90,10 +96,11 @@ impl<R: RulesTrait> Autorouter<R> {
|
|||
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<R> {
|
||||
&self.router
|
||||
pub fn layout(&self) -> &Arc<Mutex<Layout<R>>> {
|
||||
&self.layout
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Navmesh>,
|
||||
pub path: Vec<VertexIndex>,
|
||||
pub ghosts: Vec<PrimitiveShape>,
|
||||
pub highlighteds: Vec<PrimitiveIndex>,
|
||||
|
|
@ -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!();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)) = (
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,24 +57,20 @@ pub trait RouterObserverTrait<R: RulesTrait> {
|
|||
fn on_estimate(&mut self, tracer: &Tracer<R>, vertex: VertexIndex);
|
||||
}
|
||||
|
||||
pub struct Router<R: RulesTrait> {
|
||||
layout: Arc<Mutex<Layout<R>>>,
|
||||
pub struct Router<'a, R: RulesTrait> {
|
||||
layout: &'a mut Arc<Mutex<Layout<R>>>,
|
||||
navmesh: Navmesh,
|
||||
}
|
||||
|
||||
struct RouterAstarStrategy<'a, RO: RouterObserverTrait<R>, R: RulesTrait> {
|
||||
tracer: Tracer<'a, R>,
|
||||
tracer: Tracer<R>,
|
||||
trace: Trace,
|
||||
to: FixedDotIndex,
|
||||
observer: &'a mut RO,
|
||||
}
|
||||
|
||||
impl<'a, RO: RouterObserverTrait<R>, 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<R>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO) -> Self {
|
||||
Self {
|
||||
tracer,
|
||||
trace,
|
||||
|
|
@ -146,9 +142,17 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64>
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: RulesTrait> Router<R> {
|
||||
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Self {
|
||||
Router { layout }
|
||||
impl<'a, R: RulesTrait> Router<'a, R> {
|
||||
pub fn new(layout: &'a mut Arc<Mutex<Layout<R>>>) -> Result<Self, InsertionError> {
|
||||
let navmesh = Navmesh::new(&layout.lock().unwrap())?;
|
||||
Self::new_with_navmesh(layout, navmesh)
|
||||
}
|
||||
|
||||
pub fn new_with_navmesh(
|
||||
layout: &'a mut Arc<Mutex<Layout<R>>>,
|
||||
navmesh: Navmesh,
|
||||
) -> Result<Self, InsertionError> {
|
||||
Ok(Self { layout, navmesh })
|
||||
}
|
||||
|
||||
pub fn route_band(
|
||||
|
|
@ -158,22 +162,13 @@ impl<R: RulesTrait> Router<R> {
|
|||
width: f64,
|
||||
observer: &mut impl RouterObserverTrait<R>,
|
||||
) -> Result<BandIndex, RoutingError> {
|
||||
// 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<R: RulesTrait> Router<R> {
|
|||
self.route_band(from_dot, to_dot, width, observer)
|
||||
}
|
||||
|
||||
pub fn tracer<'a>(&'a mut self, mesh: &'a Navmesh) -> Tracer<R> {
|
||||
Tracer::new(self.layout.clone(), mesh)
|
||||
fn tracer(&mut self) -> Tracer<R> {
|
||||
Tracer::new(self.layout.clone())
|
||||
}
|
||||
|
||||
pub fn layout(&self) -> Arc<Mutex<Layout<R>>> {
|
||||
|
|
|
|||
|
|
@ -25,14 +25,13 @@ pub struct Trace {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Tracer<'a, R: RulesTrait> {
|
||||
pub struct Tracer<R: RulesTrait> {
|
||||
pub layout: Arc<Mutex<Layout<R>>>,
|
||||
pub navmesh: &'a Navmesh,
|
||||
}
|
||||
|
||||
impl<'a, R: RulesTrait> Tracer<'a, R> {
|
||||
pub fn new(layout: Arc<Mutex<Layout<R>>>, navmesh: &'a Navmesh) -> Self {
|
||||
Tracer { layout, navmesh }
|
||||
impl<R: RulesTrait> Tracer<R> {
|
||||
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Self {
|
||||
Tracer { layout }
|
||||
}
|
||||
|
||||
pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace {
|
||||
|
|
|
|||
Loading…
Reference in New Issue