mirror of https://codeberg.org/topola/topola.git
egui,autorouter,router: display infringement shapes (aka. "ghosts")
This commit is contained in:
parent
727eb37c6e
commit
b6cb89c017
|
|
@ -1,14 +1,16 @@
|
||||||
use petgraph::graph::EdgeIndex;
|
use petgraph::graph::EdgeIndex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{
|
|
||||||
invoker::{GetMaybeNavmesh, GetMaybeTrace},
|
|
||||||
Autorouter, AutorouterError, AutorouterStatus,
|
|
||||||
},
|
|
||||||
board::mesadata::AccessMesadata,
|
board::mesadata::AccessMesadata,
|
||||||
|
geometry::primitive::PrimitiveShape,
|
||||||
router::{navmesh::Navmesh, route::Route, trace::Trace, Router, RouterStatus},
|
router::{navmesh::Navmesh, route::Route, trace::Trace, Router, RouterStatus},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace},
|
||||||
|
Autorouter, AutorouterError, AutorouterStatus,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Autoroute {
|
pub struct Autoroute {
|
||||||
ratlines_iter: Box<dyn Iterator<Item = EdgeIndex<usize>>>,
|
ratlines_iter: Box<dyn Iterator<Item = EdgeIndex<usize>>>,
|
||||||
route: Option<Route>,
|
route: Option<Route>,
|
||||||
|
|
@ -83,14 +85,6 @@ impl Autoroute {
|
||||||
|
|
||||||
Ok(AutorouterStatus::Running)
|
Ok(AutorouterStatus::Running)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn navmesh(&self) -> Option<&Navmesh> {
|
|
||||||
self.route.as_ref().map(|route| route.navmesh())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn trace(&self) -> Option<&Trace> {
|
|
||||||
self.route.as_ref().map(|route| route.trace())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavmesh for Autoroute {
|
impl GetMaybeNavmesh for Autoroute {
|
||||||
|
|
@ -104,3 +98,9 @@ impl GetMaybeTrace for Autoroute {
|
||||||
self.route.as_ref().map(|route| route.trace())
|
self.route.as_ref().map(|route| route.trace())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GetGhosts for Autoroute {
|
||||||
|
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
|
self.route.as_ref().map_or(&[], |route| route.ghosts())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ use crate::{
|
||||||
Autorouter, AutorouterError, AutorouterStatus,
|
Autorouter, AutorouterError, AutorouterStatus,
|
||||||
},
|
},
|
||||||
board::mesadata::AccessMesadata,
|
board::mesadata::AccessMesadata,
|
||||||
|
drawing::graph::PrimitiveIndex,
|
||||||
|
geometry::primitive::PrimitiveShape,
|
||||||
layout::via::ViaWeight,
|
layout::via::ViaWeight,
|
||||||
router::{navmesh::Navmesh, trace::Trace},
|
router::{navmesh::Navmesh, trace::Trace},
|
||||||
};
|
};
|
||||||
|
|
@ -26,6 +28,11 @@ pub trait GetMaybeTrace {
|
||||||
fn maybe_trace(&self) -> Option<&Trace>;
|
fn maybe_trace(&self) -> Option<&Trace>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch]
|
||||||
|
pub trait GetGhosts {
|
||||||
|
fn ghosts(&self) -> &[PrimitiveShape];
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, Clone)]
|
#[derive(Error, Debug, Clone)]
|
||||||
pub enum InvokerError {
|
pub enum InvokerError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
|
@ -46,7 +53,7 @@ pub enum Command {
|
||||||
PlaceVia(ViaWeight),
|
PlaceVia(ViaWeight),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace)]
|
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts)]
|
||||||
pub enum Execute {
|
pub enum Execute {
|
||||||
Autoroute(Autoroute),
|
Autoroute(Autoroute),
|
||||||
PlaceVia(PlaceVia),
|
PlaceVia(PlaceVia),
|
||||||
|
|
@ -129,6 +136,12 @@ impl GetMaybeTrace for ExecuteWithStatus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GetGhosts for ExecuteWithStatus {
|
||||||
|
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
|
self.execute.ghosts()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Invoker<M: AccessMesadata> {
|
pub struct Invoker<M: AccessMesadata> {
|
||||||
autorouter: Autorouter<M>,
|
autorouter: Autorouter<M>,
|
||||||
history: History,
|
history: History,
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{
|
|
||||||
invoker::{GetMaybeNavmesh, GetMaybeTrace},
|
|
||||||
Autorouter, AutorouterError,
|
|
||||||
},
|
|
||||||
board::mesadata::AccessMesadata,
|
board::mesadata::AccessMesadata,
|
||||||
|
drawing::graph::PrimitiveIndex,
|
||||||
|
geometry::primitive::PrimitiveShape,
|
||||||
layout::via::ViaWeight,
|
layout::via::ViaWeight,
|
||||||
router::{navmesh::Navmesh, trace::Trace},
|
router::{navmesh::Navmesh, trace::Trace},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace},
|
||||||
|
Autorouter, AutorouterError,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PlaceVia {
|
pub struct PlaceVia {
|
||||||
weight: ViaWeight,
|
weight: ViaWeight,
|
||||||
|
|
@ -37,3 +40,9 @@ impl GetMaybeTrace for PlaceVia {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GetGhosts for PlaceVia {
|
||||||
|
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ use petgraph::{
|
||||||
visit::{EdgeRef, IntoEdgeReferences},
|
visit::{EdgeRef, IntoEdgeReferences},
|
||||||
};
|
};
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::invoker::{Command, ExecuteWithStatus, GetMaybeNavmesh, GetMaybeTrace, Invoker},
|
autorouter::invoker::{
|
||||||
|
Command, ExecuteWithStatus, GetGhosts, GetMaybeNavmesh, GetMaybeTrace, Invoker,
|
||||||
|
},
|
||||||
board::mesadata::AccessMesadata,
|
board::mesadata::AccessMesadata,
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
|
|
@ -213,11 +215,11 @@ impl Viewport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*for ghost in shared_data.ghosts.iter() {
|
|
||||||
painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if let Some(execute) = maybe_execute {
|
if let Some(execute) = maybe_execute {
|
||||||
|
for ghost in execute.ghosts().iter() {
|
||||||
|
painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150));
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(navmesh) = execute.maybe_navmesh() {
|
if let Some(navmesh) = execute.maybe_navmesh() {
|
||||||
if let (origin, destination) = (navmesh.origin(), navmesh.destination()) {
|
if let (origin, destination) = (navmesh.origin(), navmesh.destination()) {
|
||||||
painter.paint_dot(
|
painter.paint_dot(
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AstarStrategy<G, K, PS, PE, R>
|
pub trait AstarStrategy<G, K, R>
|
||||||
where
|
where
|
||||||
G: GraphBase,
|
G: GraphBase,
|
||||||
G::NodeId: Eq + Hash,
|
G::NodeId: Eq + Hash,
|
||||||
|
|
@ -108,7 +108,7 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
graph: &'a G,
|
graph: &'a G,
|
||||||
edge: <&'a G as IntoEdgeReferences>::EdgeRef,
|
edge: <&'a G as IntoEdgeReferences>::EdgeRef,
|
||||||
) -> Result<(K, PS), PE>;
|
) -> Option<K>;
|
||||||
fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K;
|
fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,14 +140,14 @@ pub enum AstarError {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AstarStatus<G, K, PS, PE, R>
|
pub enum AstarStatus<G, K, R>
|
||||||
where
|
where
|
||||||
G: GraphBase,
|
G: GraphBase,
|
||||||
G::NodeId: Eq + Hash,
|
G::NodeId: Eq + Hash,
|
||||||
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
||||||
K: Measure + Copy,
|
K: Measure + Copy,
|
||||||
{
|
{
|
||||||
Probed(Result<PS, PE>),
|
Probed,
|
||||||
Visited,
|
Visited,
|
||||||
Finished(K, Vec<G::NodeId>, R),
|
Finished(K, Vec<G::NodeId>, R),
|
||||||
}
|
}
|
||||||
|
|
@ -159,11 +159,7 @@ where
|
||||||
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
||||||
K: Measure + Copy,
|
K: Measure + Copy,
|
||||||
{
|
{
|
||||||
pub fn new<PS, PE, R>(
|
pub fn new<R>(graph: G, start: G::NodeId, strategy: &mut impl AstarStrategy<G, K, R>) -> Self {
|
||||||
graph: G,
|
|
||||||
start: G::NodeId,
|
|
||||||
strategy: &mut impl AstarStrategy<G, K, PS, PE, R>,
|
|
||||||
) -> Self {
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
graph,
|
graph,
|
||||||
visit_next: BinaryHeap::new(),
|
visit_next: BinaryHeap::new(),
|
||||||
|
|
@ -183,10 +179,10 @@ where
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step<PS, PE, R>(
|
pub fn step<R>(
|
||||||
&mut self,
|
&mut self,
|
||||||
strategy: &mut impl AstarStrategy<G, K, PS, PE, R>,
|
strategy: &mut impl AstarStrategy<G, K, R>,
|
||||||
) -> Result<AstarStatus<G, K, PS, PE, R>, AstarError> {
|
) -> Result<AstarStatus<G, K, R>, AstarError> {
|
||||||
if let Some(curr_node) = self.maybe_curr_node {
|
if let Some(curr_node) = self.maybe_curr_node {
|
||||||
if let Some(edge_id) = self.edge_ids.pop_front() {
|
if let Some(edge_id) = self.edge_ids.pop_front() {
|
||||||
// This lookup can be unwrapped without fear of panic since the node was
|
// This lookup can be unwrapped without fear of panic since the node was
|
||||||
|
|
@ -194,8 +190,7 @@ where
|
||||||
let node_score = self.scores[&curr_node];
|
let node_score = self.scores[&curr_node];
|
||||||
let edge = (&self.graph).edge_ref(edge_id);
|
let edge = (&self.graph).edge_ref(edge_id);
|
||||||
|
|
||||||
match strategy.probe(&self.graph, edge) {
|
if let Some(edge_cost) = strategy.probe(&self.graph, edge) {
|
||||||
Ok((edge_cost, probe_status)) => {
|
|
||||||
let next = edge.target();
|
let next = edge.target();
|
||||||
let next_score = node_score + edge_cost;
|
let next_score = node_score + edge_cost;
|
||||||
|
|
||||||
|
|
@ -204,7 +199,7 @@ where
|
||||||
// No need to add neighbors that we have already reached through a
|
// No need to add neighbors that we have already reached through a
|
||||||
// shorter path than now.
|
// shorter path than now.
|
||||||
if *entry.get() <= next_score {
|
if *entry.get() <= next_score {
|
||||||
return Ok(AstarStatus::Probed(Ok(probe_status)));
|
return Ok(AstarStatus::Probed);
|
||||||
}
|
}
|
||||||
entry.insert(next_score);
|
entry.insert(next_score);
|
||||||
}
|
}
|
||||||
|
|
@ -217,15 +212,13 @@ where
|
||||||
let next_estimate_score =
|
let next_estimate_score =
|
||||||
next_score + strategy.estimate_cost(&self.graph, next);
|
next_score + strategy.estimate_cost(&self.graph, next);
|
||||||
self.visit_next.push(MinScored(next_estimate_score, next));
|
self.visit_next.push(MinScored(next_estimate_score, next));
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(AstarStatus::Probed(Ok(probe_status)));
|
return Ok(AstarStatus::Probed);
|
||||||
}
|
}
|
||||||
Err(probe_err) => return Ok(AstarStatus::Probed(Err(probe_err))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.maybe_curr_node = None;
|
self.maybe_curr_node = None;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let Some(MinScored(estimate_score, node)) = self.visit_next.pop() else {
|
let Some(MinScored(estimate_score, node)) = self.visit_next.pop() else {
|
||||||
return Err(AstarError::NotFound);
|
return Err(AstarError::NotFound);
|
||||||
|
|
@ -258,10 +251,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn astar<G, K, PS, PE, R>(
|
pub fn astar<G, K, R>(
|
||||||
graph: G,
|
graph: G,
|
||||||
start: G::NodeId,
|
start: G::NodeId,
|
||||||
strategy: &mut impl AstarStrategy<G, K, PS, PE, R>,
|
strategy: &mut impl AstarStrategy<G, K, R>,
|
||||||
) -> Result<(K, Vec<G::NodeId>, R), AstarError>
|
) -> Result<(K, Vec<G::NodeId>, R), AstarError>
|
||||||
where
|
where
|
||||||
G: GraphBase,
|
G: GraphBase,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,10 @@ use crate::{
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::AccessRules,
|
rules::AccessRules,
|
||||||
},
|
},
|
||||||
geometry::{primitive::AccessPrimitiveShape, shape::AccessShape},
|
geometry::{
|
||||||
|
primitive::{AccessPrimitiveShape, PrimitiveShape},
|
||||||
|
shape::AccessShape,
|
||||||
|
},
|
||||||
graph::GetPetgraphIndex,
|
graph::GetPetgraphIndex,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
router::{
|
router::{
|
||||||
|
|
@ -33,6 +36,7 @@ use crate::{
|
||||||
pub struct Route {
|
pub struct Route {
|
||||||
astar: Astar<Navmesh, f64>,
|
astar: Astar<Navmesh, f64>,
|
||||||
trace: Trace,
|
trace: Trace,
|
||||||
|
ghosts: Vec<PrimitiveShape>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Route {
|
impl Route {
|
||||||
|
|
@ -60,8 +64,13 @@ impl Route {
|
||||||
|
|
||||||
let mut strategy = RouterAstarStrategy::new(tracer, &mut trace, target);
|
let mut strategy = RouterAstarStrategy::new(tracer, &mut trace, target);
|
||||||
let astar = Astar::new(navmesh, source_navvertex, &mut strategy);
|
let astar = Astar::new(navmesh, source_navvertex, &mut strategy);
|
||||||
|
let ghosts = vec![];
|
||||||
|
|
||||||
Self { astar, trace }
|
Self {
|
||||||
|
astar,
|
||||||
|
trace,
|
||||||
|
ghosts,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step(
|
pub fn step(
|
||||||
|
|
@ -72,10 +81,13 @@ impl Route {
|
||||||
let target = self.astar.graph.destination();
|
let target = self.astar.graph.destination();
|
||||||
let mut strategy = RouterAstarStrategy::new(tracer, &mut self.trace, target);
|
let mut strategy = RouterAstarStrategy::new(tracer, &mut self.trace, target);
|
||||||
|
|
||||||
match self.astar.step(&mut strategy)? {
|
let result = match self.astar.step(&mut strategy)? {
|
||||||
AstarStatus::Probed(..) | AstarStatus::Visited => Ok(RouterStatus::Running),
|
AstarStatus::Probed | AstarStatus::Visited => Ok(RouterStatus::Running),
|
||||||
AstarStatus::Finished(_cost, _path, band) => Ok(RouterStatus::Finished(band)),
|
AstarStatus::Finished(_cost, _path, band) => Ok(RouterStatus::Finished(band)),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
self.ghosts = strategy.ghosts;
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn navmesh(&self) -> &Navmesh {
|
pub fn navmesh(&self) -> &Navmesh {
|
||||||
|
|
@ -85,4 +97,8 @@ impl Route {
|
||||||
pub fn trace(&self) -> &Trace {
|
pub fn trace(&self) -> &Trace {
|
||||||
&self.trace
|
&self.trace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
|
&self.ghosts
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,20 +10,23 @@ use crate::{
|
||||||
head::{GetFace, Head},
|
head::{GetFace, Head},
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::AccessRules,
|
rules::AccessRules,
|
||||||
|
Collision, Infringement, LayoutException,
|
||||||
},
|
},
|
||||||
geometry::{
|
geometry::{
|
||||||
primitive::AccessPrimitiveShape,
|
primitive::{AccessPrimitiveShape, PrimitiveShape},
|
||||||
shape::{AccessShape, MeasureLength},
|
shape::{AccessShape, MeasureLength},
|
||||||
},
|
},
|
||||||
graph::GetPetgraphIndex,
|
graph::GetPetgraphIndex,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
router::{
|
};
|
||||||
astar::{AstarError, AstarStatus, AstarStrategy, PathTracker},
|
|
||||||
|
use super::{
|
||||||
|
astar::{AstarError, AstarStrategy, PathTracker},
|
||||||
|
draw::DrawException,
|
||||||
navmesh::{Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex},
|
navmesh::{Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex},
|
||||||
route::Route,
|
route::Route,
|
||||||
trace::Trace,
|
trace::Trace,
|
||||||
tracer::Tracer,
|
tracer::{Tracer, TracerException},
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Error, Debug, Clone)]
|
#[derive(Error, Debug, Clone)]
|
||||||
|
|
@ -44,6 +47,7 @@ pub struct RouterAstarStrategy<'a, R: AccessRules> {
|
||||||
pub tracer: Tracer<'a, R>,
|
pub tracer: Tracer<'a, R>,
|
||||||
pub trace: &'a mut Trace,
|
pub trace: &'a mut Trace,
|
||||||
pub target: FixedDotIndex,
|
pub target: FixedDotIndex,
|
||||||
|
pub ghosts: Vec<PrimitiveShape>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> {
|
impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> {
|
||||||
|
|
@ -52,6 +56,7 @@ impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> {
|
||||||
tracer,
|
tracer,
|
||||||
trace,
|
trace,
|
||||||
target,
|
target,
|
||||||
|
ghosts: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +76,7 @@ impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, (), (), BandFirstSegIndex>
|
impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandFirstSegIndex>
|
||||||
for RouterAstarStrategy<'a, R>
|
for RouterAstarStrategy<'a, R>
|
||||||
{
|
{
|
||||||
fn is_goal(
|
fn is_goal(
|
||||||
|
|
@ -92,9 +97,9 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, (), (), BandFirstSegIndex>
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn probe(&mut self, navmesh: &Navmesh, edge: NavmeshEdgeReference) -> Result<(f64, ()), ()> {
|
fn probe(&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 Err(());
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let prev_bihead_length = self.bihead_length();
|
let prev_bihead_length = self.bihead_length();
|
||||||
|
|
@ -106,11 +111,32 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, (), (), BandFirstSegIndex>
|
||||||
|
|
||||||
let probe_length = self.bihead_length() - prev_bihead_length;
|
let probe_length = self.bihead_length() - prev_bihead_length;
|
||||||
|
|
||||||
if result.is_ok() {
|
match result {
|
||||||
|
Ok(..) => {
|
||||||
self.trace.undo_step(&mut self.tracer);
|
self.trace.undo_step(&mut self.tracer);
|
||||||
Ok((probe_length, ()))
|
Some(probe_length)
|
||||||
} else {
|
}
|
||||||
Err(())
|
Err(err) => {
|
||||||
|
if let TracerException::CannotDraw(draw_err) = err {
|
||||||
|
let layout_err = match draw_err {
|
||||||
|
DrawException::NoTangents(..) => return None,
|
||||||
|
DrawException::CannotFinishIn(.., layout_err) => layout_err,
|
||||||
|
DrawException::CannotWrapAround(.., layout_err) => layout_err,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (ghost, ..) = match layout_err {
|
||||||
|
LayoutException::NoTangents(..) => return None,
|
||||||
|
LayoutException::Infringement(Infringement(ghost, obstacle)) => {
|
||||||
|
(ghost, obstacle)
|
||||||
|
}
|
||||||
|
LayoutException::Collision(Collision(ghost, obstacle)) => (ghost, obstacle),
|
||||||
|
LayoutException::AlreadyConnected(..) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.ghosts = vec![ghost];
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue