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},
|
autorouter::ratsnest::{Ratsnest, RatsnestVertexIndex},
|
||||||
drawing::{dot::FixedDotIndex, rules::RulesTrait},
|
drawing::{dot::FixedDotIndex, rules::RulesTrait},
|
||||||
layout::{connectivity::BandIndex, Layout},
|
layout::{connectivity::BandIndex, Layout},
|
||||||
router::{Router, RouterObserverTrait, RoutingError},
|
router::{navmesh::Navmesh, Router, RouterObserverTrait, RoutingError},
|
||||||
triangulation::GetVertexIndex,
|
triangulation::GetVertexIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Autoroute {
|
pub struct Autoroute {
|
||||||
edge_indices: EdgeIndices<usize>,
|
edge_indices: EdgeIndices<usize>,
|
||||||
|
navmesh: Navmesh, // Useful for debugging.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Autoroute {
|
impl Autoroute {
|
||||||
|
|
@ -30,9 +31,9 @@ impl Autoroute {
|
||||||
};
|
};
|
||||||
let (from, to) = autorouter.ratsnest.graph().edge_endpoints(ratline).unwrap();
|
let (from, to) = autorouter.ratsnest.graph().edge_endpoints(ratline).unwrap();
|
||||||
|
|
||||||
let (from_dot, to_dot) = {
|
let (navmesh, from_dot, to_dot) = {
|
||||||
let layout = autorouter.router.layout();
|
let mut layout = autorouter.layout.lock().unwrap();
|
||||||
let mut layout = layout.lock().unwrap();
|
let navmesh = Navmesh::new(&layout).unwrap();
|
||||||
|
|
||||||
let from_dot = match autorouter
|
let from_dot = match autorouter
|
||||||
.ratsnest
|
.ratsnest
|
||||||
|
|
@ -56,28 +57,33 @@ impl Autoroute {
|
||||||
RatsnestVertexIndex::Zone(zone) => layout.zone_apex(zone),
|
RatsnestVertexIndex::Zone(zone) => layout.zone_apex(zone),
|
||||||
};
|
};
|
||||||
|
|
||||||
(from_dot, to_dot)
|
(navmesh, from_dot, to_dot)
|
||||||
};
|
};
|
||||||
|
|
||||||
autorouter
|
let router = Router::new_with_navmesh(
|
||||||
.router
|
&mut autorouter.layout,
|
||||||
|
std::mem::replace(&mut self.navmesh, navmesh),
|
||||||
|
);
|
||||||
|
router
|
||||||
|
.unwrap()
|
||||||
.route_band(from_dot, to_dot, 100.0, observer);
|
.route_band(from_dot, to_dot, 100.0, observer);
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn navmesh(&self) -> &Navmesh {
|
||||||
|
&self.navmesh
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Autorouter<R: RulesTrait> {
|
pub struct Autorouter<R: RulesTrait> {
|
||||||
ratsnest: Ratsnest,
|
ratsnest: Ratsnest,
|
||||||
router: Router<R>,
|
layout: Arc<Mutex<Layout<R>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Autorouter<R> {
|
impl<R: RulesTrait> Autorouter<R> {
|
||||||
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Result<Self, InsertionError> {
|
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Result<Self, InsertionError> {
|
||||||
let ratsnest = Ratsnest::new(&layout.lock().unwrap())?;
|
let ratsnest = Ratsnest::new(&layout.lock().unwrap())?;
|
||||||
Ok(Self {
|
Ok(Self { ratsnest, layout })
|
||||||
ratsnest,
|
|
||||||
router: Router::new(layout),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn autoroute(&mut self, observer: &mut impl RouterObserverTrait<R>) {
|
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 {
|
pub fn autoroute_iter(&mut self) -> Autoroute {
|
||||||
Autoroute {
|
Autoroute {
|
||||||
edge_indices: self.ratsnest.graph().edge_indices(),
|
edge_indices: self.ratsnest.graph().edge_indices(),
|
||||||
|
navmesh: Navmesh::new(&self.layout.lock().unwrap()).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn router(&self) -> &Router<R> {
|
pub fn layout(&self) -> &Arc<Mutex<Layout<R>>> {
|
||||||
&self.router
|
&self.layout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,14 @@ use topola::{
|
||||||
geometry::{
|
geometry::{
|
||||||
compound::CompoundManagerTrait,
|
compound::CompoundManagerTrait,
|
||||||
primitive::{BendShape, DotShape, PrimitiveShape, PrimitiveShapeTrait, SegShape},
|
primitive::{BendShape, DotShape, PrimitiveShape, PrimitiveShapeTrait, SegShape},
|
||||||
|
shape::ShapeTrait,
|
||||||
GenericNode,
|
GenericNode,
|
||||||
},
|
},
|
||||||
layout::{zone::MakePolyShape, Layout},
|
layout::{zone::MakePolyShape, Layout},
|
||||||
math::Circle,
|
math::Circle,
|
||||||
router::{
|
router::{
|
||||||
draw::DrawException,
|
draw::DrawException,
|
||||||
navmesh::{NavmeshEdgeReference, VertexIndex},
|
navmesh::{Navmesh, NavmeshEdgeReference, VertexIndex},
|
||||||
tracer::{Trace, Tracer},
|
tracer::{Trace, Tracer},
|
||||||
RouterObserverTrait,
|
RouterObserverTrait,
|
||||||
},
|
},
|
||||||
|
|
@ -37,6 +38,7 @@ use crate::{overlay::Overlay, painter::Painter};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct SharedData {
|
struct SharedData {
|
||||||
|
pub navmesh: Option<Navmesh>,
|
||||||
pub path: Vec<VertexIndex>,
|
pub path: Vec<VertexIndex>,
|
||||||
pub ghosts: Vec<PrimitiveShape>,
|
pub ghosts: Vec<PrimitiveShape>,
|
||||||
pub highlighteds: Vec<PrimitiveIndex>,
|
pub highlighteds: Vec<PrimitiveIndex>,
|
||||||
|
|
@ -197,7 +199,17 @@ impl eframe::App for App {
|
||||||
|
|
||||||
execute(async move {
|
execute(async move {
|
||||||
let mut autorouter = Autorouter::new(layout).unwrap();
|
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 {
|
} else {
|
||||||
egui::Color32::from_rgb(52, 52, 200)
|
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) {
|
for zone in layout.layer_zone_nodes(1) {
|
||||||
|
|
@ -289,7 +301,7 @@ impl eframe::App for App {
|
||||||
} else {
|
} else {
|
||||||
egui::Color32::from_rgb(200, 52, 52)
|
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) {
|
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));
|
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() {
|
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!();
|
//unreachable!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ impl<'a> Painter<'a> {
|
||||||
Self { ui, transform }
|
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 {
|
let epaint_shape = match shape {
|
||||||
PrimitiveShape::Dot(dot) => egui::Shape::circle_filled(
|
PrimitiveShape::Dot(dot) => egui::Shape::circle_filled(
|
||||||
self.transform
|
self.transform
|
||||||
|
|
|
||||||
|
|
@ -406,7 +406,7 @@ fn render_times(
|
||||||
};
|
};
|
||||||
|
|
||||||
let shape = node.primitive(drawing).shape();
|
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) {
|
for zone in drawing.layer_zones(1) {
|
||||||
|
|
@ -425,7 +425,7 @@ fn render_times(
|
||||||
};
|
};
|
||||||
|
|
||||||
let shape = node.primitive(drawing).shape();
|
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) {
|
for zone in drawing.layer_zones(0) {
|
||||||
|
|
@ -437,13 +437,13 @@ fn render_times(
|
||||||
}
|
}
|
||||||
|
|
||||||
for ghost in ghosts {
|
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 {
|
if let Some(ref navmesh) = maybe_navmesh {
|
||||||
for edge in navmesh.edge_references() {
|
for edge in navmesh.edge_references() {
|
||||||
let to = edge.source().primitive(drawing).shape().center();
|
let from = edge.source().primitive(drawing).shape().center();
|
||||||
let from = edge.target().primitive(drawing).shape().center();
|
let to = edge.target().primitive(drawing).shape().center();
|
||||||
|
|
||||||
let color = 'blk: {
|
let color = 'blk: {
|
||||||
if let (Some(source_pos), Some(target_pos)) = (
|
if let (Some(source_pos), Some(target_pos)) = (
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ impl<'a> Painter<'a> {
|
||||||
Self { canvas }
|
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_stroke_style(color);
|
||||||
self.canvas.set_fill_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);
|
fn on_estimate(&mut self, tracer: &Tracer<R>, vertex: VertexIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Router<R: RulesTrait> {
|
pub struct Router<'a, R: RulesTrait> {
|
||||||
layout: Arc<Mutex<Layout<R>>>,
|
layout: &'a mut Arc<Mutex<Layout<R>>>,
|
||||||
|
navmesh: Navmesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RouterAstarStrategy<'a, RO: RouterObserverTrait<R>, R: RulesTrait> {
|
struct RouterAstarStrategy<'a, RO: RouterObserverTrait<R>, R: RulesTrait> {
|
||||||
tracer: Tracer<'a, R>,
|
tracer: Tracer<R>,
|
||||||
trace: Trace,
|
trace: Trace,
|
||||||
to: FixedDotIndex,
|
to: FixedDotIndex,
|
||||||
observer: &'a mut RO,
|
observer: &'a mut RO,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> RouterAstarStrategy<'a, RO, R> {
|
impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> RouterAstarStrategy<'a, RO, R> {
|
||||||
pub fn new(
|
pub fn new(tracer: Tracer<R>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO) -> Self {
|
||||||
tracer: Tracer<'a, R>,
|
|
||||||
trace: Trace,
|
|
||||||
to: FixedDotIndex,
|
|
||||||
observer: &'a mut RO,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
tracer,
|
tracer,
|
||||||
trace,
|
trace,
|
||||||
|
|
@ -146,9 +142,17 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: RulesTrait> Router<R> {
|
impl<'a, R: RulesTrait> Router<'a, R> {
|
||||||
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Self {
|
pub fn new(layout: &'a mut Arc<Mutex<Layout<R>>>) -> Result<Self, InsertionError> {
|
||||||
Router { layout }
|
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(
|
pub fn route_band(
|
||||||
|
|
@ -158,22 +162,13 @@ impl<R: RulesTrait> Router<R> {
|
||||||
width: f64,
|
width: f64,
|
||||||
observer: &mut impl RouterObserverTrait<R>,
|
observer: &mut impl RouterObserverTrait<R>,
|
||||||
) -> Result<BandIndex, RoutingError> {
|
) -> Result<BandIndex, RoutingError> {
|
||||||
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
|
let mut tracer = self.tracer();
|
||||||
// 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 trace = tracer.start(from, width);
|
let trace = tracer.start(from, width);
|
||||||
let band = trace.band;
|
let band = trace.band;
|
||||||
|
|
||||||
let (_cost, _path) = astar(
|
let (_cost, _path) = astar(
|
||||||
&mesh,
|
&self.navmesh,
|
||||||
from.into(),
|
from.into(),
|
||||||
&mut RouterAstarStrategy::new(tracer, trace, to.into(), observer),
|
&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)
|
self.route_band(from_dot, to_dot, width, observer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tracer<'a>(&'a mut self, mesh: &'a Navmesh) -> Tracer<R> {
|
fn tracer(&mut self) -> Tracer<R> {
|
||||||
Tracer::new(self.layout.clone(), mesh)
|
Tracer::new(self.layout.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout(&self) -> Arc<Mutex<Layout<R>>> {
|
pub fn layout(&self) -> Arc<Mutex<Layout<R>>> {
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,13 @@ pub struct Trace {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Tracer<'a, R: RulesTrait> {
|
pub struct Tracer<R: RulesTrait> {
|
||||||
pub layout: Arc<Mutex<Layout<R>>>,
|
pub layout: Arc<Mutex<Layout<R>>>,
|
||||||
pub navmesh: &'a Navmesh,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: RulesTrait> Tracer<'a, R> {
|
impl<R: RulesTrait> Tracer<R> {
|
||||||
pub fn new(layout: Arc<Mutex<Layout<R>>>, navmesh: &'a Navmesh) -> Self {
|
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Self {
|
||||||
Tracer { layout, navmesh }
|
Tracer { layout }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace {
|
pub fn start(&mut self, from: FixedDotIndex, width: f64) -> Trace {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue