router: implement (again) graph traversal traits for `Navmesh`

These were implemented in the past, but I removed it when I made
`Navmesh` store each navvertex instead of calculating tem on the fly.
This commit is contained in:
Mikolaj Wielgus 2024-06-26 20:26:52 +02:00
parent 114329a1ef
commit 5254f768e5
1 changed files with 94 additions and 1 deletions

View File

@ -5,7 +5,10 @@ use geo::Point;
use petgraph::{ use petgraph::{
graph::UnGraph, graph::UnGraph,
stable_graph::NodeIndex, stable_graph::NodeIndex,
visit::{EdgeRef, IntoEdgeReferences, IntoEdges, IntoNodeIdentifiers, NodeIndexable}, visit::{
self, Data, EdgeRef, GraphBase, IntoEdgeReferences, IntoEdges, IntoNeighbors,
IntoNodeIdentifiers, NodeIndexable,
},
}; };
use spade::{HasPosition, InsertionError, Point2}; use spade::{HasPosition, InsertionError, Point2};
use thiserror::Error; use thiserror::Error;
@ -25,6 +28,15 @@ use crate::{
triangulation::{GetTrianvertexNodeIndex, Triangulation}, triangulation::{GetTrianvertexNodeIndex, Triangulation},
}; };
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
pub struct NavvertexIndex(NodeIndex<usize>);
impl GetPetgraphIndex for NavvertexIndex {
fn petgraph_index(&self) -> NodeIndex<usize> {
self.0
}
}
#[enum_dispatch(GetPetgraphIndex, MakePrimitive)] #[enum_dispatch(GetPetgraphIndex, MakePrimitive)]
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
pub enum BinavvertexNodeIndex { pub enum BinavvertexNodeIndex {
@ -218,3 +230,84 @@ impl Navmesh {
self.target_navvertex self.target_navvertex
} }
} }
impl GraphBase for Navmesh {
type NodeId = NavvertexIndex;
type EdgeId = (NavvertexIndex, NavvertexIndex);
}
impl Data for Navmesh {
type NodeWeight = NavvertexWeight;
type EdgeWeight = ();
}
#[derive(Debug, Clone, Copy)]
pub struct NavmeshEdgeReference {
from: NavvertexIndex,
to: NavvertexIndex,
}
impl EdgeRef for NavmeshEdgeReference {
type NodeId = NavvertexIndex;
type EdgeId = (NavvertexIndex, NavvertexIndex);
type Weight = ();
fn source(&self) -> Self::NodeId {
self.from
}
fn target(&self) -> Self::NodeId {
self.to
}
fn weight(&self) -> &Self::Weight {
&()
}
fn id(&self) -> Self::EdgeId {
(self.from, self.to)
}
}
impl<'a> IntoNeighbors for &'a Navmesh {
type Neighbors = Box<dyn Iterator<Item = NavvertexIndex> + 'a>;
fn neighbors(self, vertex: Self::NodeId) -> Self::Neighbors {
Box::new(
self.graph
.neighbors(vertex.petgraph_index())
.map(|ni| NavvertexIndex(ni)),
)
}
}
impl<'a> IntoEdgeReferences for &'a Navmesh {
type EdgeRef = NavmeshEdgeReference;
type EdgeReferences = Box<dyn Iterator<Item = NavmeshEdgeReference> + 'a>;
fn edge_references(self) -> Self::EdgeReferences {
Box::new(
self.graph
.edge_references()
.map(|edge| NavmeshEdgeReference {
from: NavvertexIndex(edge.source()),
to: NavvertexIndex(edge.target()),
}),
)
}
}
impl<'a> IntoEdges for &'a Navmesh {
type Edges = Box<dyn Iterator<Item = NavmeshEdgeReference> + 'a>;
fn edges(self, vertex: Self::NodeId) -> Self::Edges {
Box::new(
self.graph
.edges(vertex.petgraph_index())
.map(|edge| NavmeshEdgeReference {
from: NavvertexIndex(edge.source()),
to: NavvertexIndex(edge.target()),
}),
)
}
}