mirror of https://codeberg.org/topola/topola.git
refactor(router/navmesh): Change `NavnodeWeight` from struct to enum
This commit is contained in:
parent
1acae9ab41
commit
fe6a286e32
|
|
@ -255,20 +255,22 @@ impl Viewport {
|
||||||
|
|
||||||
for edge in navmesh.edge_references() {
|
for edge in navmesh.edge_references() {
|
||||||
let mut from = PrimitiveIndex::from(
|
let mut from = PrimitiveIndex::from(
|
||||||
navmesh.node_weight(edge.source()).unwrap().node,
|
navmesh.node_weight(edge.source()).unwrap().node(),
|
||||||
)
|
)
|
||||||
.primitive(board.layout().drawing())
|
.primitive(board.layout().drawing())
|
||||||
.shape()
|
.shape()
|
||||||
.center();
|
.center();
|
||||||
let mut to = PrimitiveIndex::from(
|
let mut to = PrimitiveIndex::from(
|
||||||
navmesh.node_weight(edge.target()).unwrap().node,
|
navmesh.node_weight(edge.target()).unwrap().node(),
|
||||||
)
|
)
|
||||||
.primitive(board.layout().drawing())
|
.primitive(board.layout().drawing())
|
||||||
.shape()
|
.shape()
|
||||||
.center();
|
.center();
|
||||||
|
|
||||||
if let Some(from_sense) =
|
if let Some(from_sense) = navmesh
|
||||||
navmesh.node_weight(edge.source()).unwrap().maybe_sense
|
.node_weight(edge.source())
|
||||||
|
.unwrap()
|
||||||
|
.maybe_sense()
|
||||||
{
|
{
|
||||||
from += match from_sense {
|
from += match from_sense {
|
||||||
RotationSense::Counterclockwise => {
|
RotationSense::Counterclockwise => {
|
||||||
|
|
@ -278,8 +280,10 @@ impl Viewport {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(to_sense) =
|
if let Some(to_sense) = navmesh
|
||||||
navmesh.node_weight(edge.target()).unwrap().maybe_sense
|
.node_weight(edge.target())
|
||||||
|
.unwrap()
|
||||||
|
.maybe_sense()
|
||||||
{
|
{
|
||||||
to += match to_sense {
|
to += match to_sense {
|
||||||
RotationSense::Counterclockwise => {
|
RotationSense::Counterclockwise => {
|
||||||
|
|
@ -335,7 +339,7 @@ impl Viewport {
|
||||||
for index in navmesh.graph().node_indices() {
|
for index in navmesh.graph().node_indices() {
|
||||||
let navnode = NavnodeIndex(index);
|
let navnode = NavnodeIndex(index);
|
||||||
let mut pos = PrimitiveIndex::from(
|
let mut pos = PrimitiveIndex::from(
|
||||||
navmesh.node_weight(navnode).unwrap().node,
|
navmesh.node_weight(navnode).unwrap().node(),
|
||||||
)
|
)
|
||||||
.primitive(board.layout().drawing())
|
.primitive(board.layout().drawing())
|
||||||
.shape()
|
.shape()
|
||||||
|
|
@ -344,7 +348,7 @@ impl Viewport {
|
||||||
pos += match navmesh
|
pos += match navmesh
|
||||||
.node_weight(navnode)
|
.node_weight(navnode)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.maybe_sense
|
.maybe_sense()
|
||||||
{
|
{
|
||||||
Some(RotationSense::Counterclockwise) => {
|
Some(RotationSense::Counterclockwise) => {
|
||||||
[0.0, 150.0].into()
|
[0.0, 150.0].into()
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use crate::{
|
||||||
use super::{
|
use super::{
|
||||||
draw::Draw,
|
draw::Draw,
|
||||||
navcorder::{Navcorder, NavcorderException},
|
navcorder::{Navcorder, NavcorderException},
|
||||||
navmesh::{BinavnodeNodeIndex, Navmesh, NavnodeIndex},
|
navmesh::{NavigableNodeIndex, Navmesh, NavnodeIndex},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The `Navcord` is a data structure that holds the movable non-borrowing data
|
/// The `Navcord` is a data structure that holds the movable non-borrowing data
|
||||||
|
|
@ -71,21 +71,21 @@ impl Navcord {
|
||||||
) -> Result<CaneHead, NavcorderException> {
|
) -> Result<CaneHead, NavcorderException> {
|
||||||
let around_node_weight = navmesh.node_weight(around).unwrap();
|
let around_node_weight = navmesh.node_weight(around).unwrap();
|
||||||
let sense = around_node_weight
|
let sense = around_node_weight
|
||||||
.maybe_sense
|
.maybe_sense()
|
||||||
.ok_or(NavcorderException::CannotWrap)?;
|
.ok_or(NavcorderException::CannotWrap)?;
|
||||||
|
|
||||||
match around_node_weight.node {
|
match around_node_weight.node() {
|
||||||
BinavnodeNodeIndex::FixedDot(dot) => {
|
NavigableNodeIndex::FixedDot(dot) => {
|
||||||
layout.cane_around_dot(&mut self.recorder, head, dot, sense, self.width)
|
layout.cane_around_dot(&mut self.recorder, head, dot, sense, self.width)
|
||||||
}
|
}
|
||||||
BinavnodeNodeIndex::FixedBend(fixed_bend) => layout.cane_around_bend(
|
NavigableNodeIndex::FixedBend(fixed_bend) => layout.cane_around_bend(
|
||||||
&mut self.recorder,
|
&mut self.recorder,
|
||||||
head,
|
head,
|
||||||
fixed_bend.into(),
|
fixed_bend.into(),
|
||||||
sense,
|
sense,
|
||||||
self.width,
|
self.width,
|
||||||
),
|
),
|
||||||
BinavnodeNodeIndex::LooseBend(loose_bend) => layout.cane_around_bend(
|
NavigableNodeIndex::LooseBend(loose_bend) => layout.cane_around_bend(
|
||||||
&mut self.recorder,
|
&mut self.recorder,
|
||||||
head,
|
head,
|
||||||
loose_bend.into(),
|
loose_bend.into(),
|
||||||
|
|
@ -108,7 +108,7 @@ impl Navcord {
|
||||||
) -> Result<(), NavcorderException> {
|
) -> Result<(), NavcorderException> {
|
||||||
if to == navmesh.destination_navnode() {
|
if to == navmesh.destination_navnode() {
|
||||||
let to_node_weight = navmesh.node_weight(to).unwrap();
|
let to_node_weight = navmesh.node_weight(to).unwrap();
|
||||||
let BinavnodeNodeIndex::FixedDot(to_dot) = to_node_weight.node else {
|
let NavigableNodeIndex::FixedDot(to_dot) = to_node_weight.node() else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,28 +58,28 @@ impl GetPetgraphIndex for NavnodeIndex {
|
||||||
/// not considered navnodes.
|
/// not considered navnodes.
|
||||||
#[enum_dispatch(GetPetgraphIndex, MakePrimitive)]
|
#[enum_dispatch(GetPetgraphIndex, MakePrimitive)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum BinavnodeNodeIndex {
|
pub enum NavigableNodeIndex {
|
||||||
FixedDot(FixedDotIndex),
|
FixedDot(FixedDotIndex),
|
||||||
FixedBend(FixedBendIndex),
|
FixedBend(FixedBendIndex),
|
||||||
LooseBend(LooseBendIndex),
|
LooseBend(LooseBendIndex),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BinavnodeNodeIndex> for PrimitiveIndex {
|
impl From<NavigableNodeIndex> for PrimitiveIndex {
|
||||||
fn from(vertex: BinavnodeNodeIndex) -> Self {
|
fn from(vertex: NavigableNodeIndex) -> Self {
|
||||||
match vertex {
|
match vertex {
|
||||||
BinavnodeNodeIndex::FixedDot(dot) => PrimitiveIndex::FixedDot(dot),
|
NavigableNodeIndex::FixedDot(dot) => PrimitiveIndex::FixedDot(dot),
|
||||||
BinavnodeNodeIndex::FixedBend(bend) => PrimitiveIndex::FixedBend(bend),
|
NavigableNodeIndex::FixedBend(bend) => PrimitiveIndex::FixedBend(bend),
|
||||||
BinavnodeNodeIndex::LooseBend(bend) => PrimitiveIndex::LooseBend(bend),
|
NavigableNodeIndex::LooseBend(bend) => PrimitiveIndex::LooseBend(bend),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BinavnodeNodeIndex> for GearIndex {
|
impl From<NavigableNodeIndex> for GearIndex {
|
||||||
fn from(vertex: BinavnodeNodeIndex) -> Self {
|
fn from(vertex: NavigableNodeIndex) -> Self {
|
||||||
match vertex {
|
match vertex {
|
||||||
BinavnodeNodeIndex::FixedDot(dot) => GearIndex::FixedDot(dot),
|
NavigableNodeIndex::FixedDot(dot) => GearIndex::FixedDot(dot),
|
||||||
BinavnodeNodeIndex::FixedBend(bend) => GearIndex::FixedBend(bend),
|
NavigableNodeIndex::FixedBend(bend) => GearIndex::FixedBend(bend),
|
||||||
BinavnodeNodeIndex::LooseBend(bend) => GearIndex::LooseBend(bend),
|
NavigableNodeIndex::LooseBend(bend) => GearIndex::LooseBend(bend),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -97,16 +97,16 @@ enum TrianvertexNodeIndex {
|
||||||
FixedBend(FixedBendIndex),
|
FixedBend(FixedBendIndex),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TrianvertexNodeIndex> for BinavnodeNodeIndex {
|
impl From<TrianvertexNodeIndex> for NavigableNodeIndex {
|
||||||
fn from(vertex: TrianvertexNodeIndex) -> Self {
|
fn from(vertex: TrianvertexNodeIndex) -> Self {
|
||||||
match vertex {
|
match vertex {
|
||||||
TrianvertexNodeIndex::FixedDot(dot) => BinavnodeNodeIndex::FixedDot(dot),
|
TrianvertexNodeIndex::FixedDot(dot) => NavigableNodeIndex::FixedDot(dot),
|
||||||
TrianvertexNodeIndex::FixedBend(bend) => BinavnodeNodeIndex::FixedBend(bend),
|
TrianvertexNodeIndex::FixedBend(bend) => NavigableNodeIndex::FixedBend(bend),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone, Debug)]
|
||||||
struct TrianvertexWeight {
|
struct TrianvertexWeight {
|
||||||
pub node: TrianvertexNodeIndex,
|
pub node: TrianvertexNodeIndex,
|
||||||
pub pos: Point,
|
pub pos: Point,
|
||||||
|
|
@ -130,15 +130,41 @@ impl HasPosition for TrianvertexWeight {
|
||||||
///
|
///
|
||||||
/// See the following blog post for more information and a visualization of the navmesh
|
/// See the following blog post for more information and a visualization of the navmesh
|
||||||
/// during autorouting: <https://topola.dev/blog/2024/07/20/junejuly-2024-development-update/#advanced-debug-visualization>
|
/// during autorouting: <https://topola.dev/blog/2024/07/20/junejuly-2024-development-update/#advanced-debug-visualization>
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct NavnodeWeight {
|
pub enum NavnodeWeight {
|
||||||
pub node: BinavnodeNodeIndex,
|
/// All navigable layout nodes except origin and destination nodes are
|
||||||
|
/// assigned one or more trinavnodes.
|
||||||
|
/// Each trinavnode consists of three navnodes distinguished by the three
|
||||||
|
/// following variants:
|
||||||
|
|
||||||
/// There are two navnodes for each navigable node:
|
/// Navnode corresponding to a counterclockwise wrap around the layout node.
|
||||||
/// one is clockwise (`Some(true)`), the other counterclockwise (`Some(false)`).
|
CounterclockwiseStep(NavigableNodeIndex),
|
||||||
/// The origin and destination nodes however have
|
/// Navnode corresponding to a clockwise wrap around the layout node.
|
||||||
/// only one corresponding navmesh vertex each (`None`).
|
ClockwiseStep(NavigableNodeIndex),
|
||||||
pub maybe_sense: Option<RotationSense>,
|
/// Navnode corresponding to a leap between two step or terminal navnodes.
|
||||||
|
//Leap(NavigableNodeIndex),
|
||||||
|
|
||||||
|
/// Unlike the others, origin and destination layout nodes each are assigned
|
||||||
|
/// only one navnode, which we call the "terminal navnode".
|
||||||
|
Terminal(NavigableNodeIndex),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NavnodeWeight {
|
||||||
|
pub fn node(&self) -> NavigableNodeIndex {
|
||||||
|
match self {
|
||||||
|
NavnodeWeight::CounterclockwiseStep(node) => *node,
|
||||||
|
NavnodeWeight::ClockwiseStep(node) => *node,
|
||||||
|
NavnodeWeight::Terminal(node) => *node,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maybe_sense(&self) -> Option<RotationSense> {
|
||||||
|
match self {
|
||||||
|
NavnodeWeight::CounterclockwiseStep(..) => Some(RotationSense::Counterclockwise),
|
||||||
|
NavnodeWeight::ClockwiseStep(..) => Some(RotationSense::Clockwise),
|
||||||
|
NavnodeWeight::Terminal(..) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, Clone)]
|
#[derive(Error, Debug, Clone)]
|
||||||
|
|
@ -222,18 +248,12 @@ impl Navmesh {
|
||||||
|
|
||||||
for trianvertex in triangulation.node_identifiers() {
|
for trianvertex in triangulation.node_identifiers() {
|
||||||
if trianvertex == origin.into() {
|
if trianvertex == origin.into() {
|
||||||
let navnode = graph.add_node(NavnodeWeight {
|
let navnode = graph.add_node(NavnodeWeight::Terminal(trianvertex.into()));
|
||||||
node: trianvertex.into(),
|
|
||||||
maybe_sense: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
origin_navnode = Some(navnode);
|
origin_navnode = Some(navnode);
|
||||||
map.insert(trianvertex, vec![(navnode, navnode)]);
|
map.insert(trianvertex, vec![(navnode, navnode)]);
|
||||||
} else if trianvertex == destination.into() {
|
} else if trianvertex == destination.into() {
|
||||||
let navnode = graph.add_node(NavnodeWeight {
|
let navnode = graph.add_node(NavnodeWeight::Terminal(trianvertex.into()));
|
||||||
node: trianvertex.into(),
|
|
||||||
maybe_sense: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
destination_navnode = Some(navnode);
|
destination_navnode = Some(navnode);
|
||||||
map.insert(trianvertex, vec![(navnode, navnode)]);
|
map.insert(trianvertex, vec![(navnode, navnode)]);
|
||||||
|
|
@ -241,7 +261,7 @@ impl Navmesh {
|
||||||
map.insert(trianvertex, vec![]);
|
map.insert(trianvertex, vec![]);
|
||||||
|
|
||||||
let mut gear =
|
let mut gear =
|
||||||
Into::<GearIndex>::into(Into::<BinavnodeNodeIndex>::into(trianvertex));
|
Into::<GearIndex>::into(Into::<NavigableNodeIndex>::into(trianvertex));
|
||||||
|
|
||||||
if options.squeeze_through_under_bends {
|
if options.squeeze_through_under_bends {
|
||||||
Self::add_node_to_graph_and_map_as_binavnode(
|
Self::add_node_to_graph_and_map_as_binavnode(
|
||||||
|
|
@ -311,17 +331,10 @@ impl Navmesh {
|
||||||
graph: &mut UnGraph<NavnodeWeight, (), usize>,
|
graph: &mut UnGraph<NavnodeWeight, (), usize>,
|
||||||
map: &mut BTreeMap<TrianvertexNodeIndex, Vec<(NodeIndex<usize>, NodeIndex<usize>)>>,
|
map: &mut BTreeMap<TrianvertexNodeIndex, Vec<(NodeIndex<usize>, NodeIndex<usize>)>>,
|
||||||
trianvertex: TrianvertexNodeIndex,
|
trianvertex: TrianvertexNodeIndex,
|
||||||
node: BinavnodeNodeIndex,
|
node: NavigableNodeIndex,
|
||||||
) {
|
) {
|
||||||
let navnode1 = graph.add_node(NavnodeWeight {
|
let navnode1 = graph.add_node(NavnodeWeight::CounterclockwiseStep(node));
|
||||||
node,
|
let navnode2 = graph.add_node(NavnodeWeight::ClockwiseStep(node));
|
||||||
maybe_sense: Some(RotationSense::Counterclockwise),
|
|
||||||
});
|
|
||||||
|
|
||||||
let navnode2 = graph.add_node(NavnodeWeight {
|
|
||||||
node,
|
|
||||||
maybe_sense: Some(RotationSense::Clockwise),
|
|
||||||
});
|
|
||||||
|
|
||||||
map.get_mut(&trianvertex)
|
map.get_mut(&trianvertex)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ impl<R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex> for RouterAst
|
||||||
}
|
}
|
||||||
|
|
||||||
fn estimate_cost(&mut self, navmesh: &Navmesh, vertex: NavnodeIndex) -> f64 {
|
fn estimate_cost(&mut self, navmesh: &Navmesh, vertex: NavnodeIndex) -> f64 {
|
||||||
let start_point = PrimitiveIndex::from(navmesh.node_weight(vertex).unwrap().node)
|
let start_point = PrimitiveIndex::from(navmesh.node_weight(vertex).unwrap().node())
|
||||||
.primitive(self.layout.drawing())
|
.primitive(self.layout.drawing())
|
||||||
.shape()
|
.shape()
|
||||||
.center();
|
.center();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue