1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use slotmap::new_key_type;
use crate::{CoordinateSystem, nav_data::NodeRef};
new_key_type! {
/// The ID of an [`AnimationLink`].
pub struct AnimationLinkId;
}
/// A link connecting two edges where an agent must perform some action (or
/// animation) to use the link.
///
/// This is often referred to as an off-mesh link in other navigation systems.
pub struct AnimationLink<CS: CoordinateSystem> {
/// The edge that the agent must reach to use the animation link.
///
/// The order of the edge is arbitrary.
pub start_edge: (CS::Coordinate, CS::Coordinate),
/// The edge that the agent will be sent to after using the animation link.
///
/// The order of the edge must match the order of `start_edge`. So
/// `start_edge.0` will take the agent to `end_edge.0` and the same for `.1`.
pub end_edge: (CS::Coordinate, CS::Coordinate),
/// The kind of the animation link.
///
/// This is an arbitrary number that can be filtered on.
pub kind: usize,
/// The cost of taking this animation link.
pub cost: f32,
/// Whether the link can be traversed in either direction.
///
/// This is a convenience to avoid needing to create two links to go in both
/// directions.
pub bidirectional: bool,
}
/// The state of an animation link.
pub(crate) struct AnimationLinkState<CS: CoordinateSystem> {
/// The link given to us by the user.
pub(crate) main_link: AnimationLink<CS>,
/// The portals that this animation link can be taken from.
pub(crate) start_portals: Vec<NodePortal>,
/// The portals that this animation link leads to.
pub(crate) end_portals: Vec<NodePortal>,
}
impl<CS: CoordinateSystem> AnimationLinkState<CS> {
pub(crate) fn new(link: AnimationLink<CS>) -> Self {
Self {
main_link: link,
start_portals: Default::default(),
end_portals: Default::default(),
}
}
}
impl<CS: CoordinateSystem<Coordinate: std::fmt::Debug>> std::fmt::Debug
for AnimationLink<CS>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AnimationLink")
.field("start_edge", &self.start_edge)
.field("end_edge", &self.end_edge)
.field("kind", &self.kind)
.field("cost", &self.cost)
.finish()
}
}
impl<CS: CoordinateSystem<Coordinate: std::fmt::Debug>> std::fmt::Debug
for AnimationLinkState<CS>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AnimationLinkState")
.field("main_link", &self.main_link)
.field("start_portals", &self.start_portals)
.field("end_portals", &self.end_portals)
.finish()
}
}
/// A node portal created from a world portal.
#[derive(Clone, Copy, PartialEq, Debug)]
pub(crate) struct NodePortal {
/// The node that this portal belongs to.
pub(crate) node: NodeRef,
/// The interval along the original world portal that this node portal takes
/// up. The values are always in ascending order, and both are in the range
/// [0-1]. This is a fraction along the world portal.
pub(crate) interval: (f32, f32),
}