oxygengine_navigation/
components.rs1use crate::resources::{NavMeshID, NavPathMode, NavQuery, NavVec3};
2use core::{
3 ecs::Entity,
4 id::ID,
5 prefab::{Prefab, PrefabComponent},
6 Scalar,
7};
8use serde::{Deserialize, Serialize};
9
10pub type NavAgentId = ID<NavAgent>;
12
13#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
15pub struct SimpleNavDriverTag;
16
17impl Prefab for SimpleNavDriverTag {}
18impl PrefabComponent for SimpleNavDriverTag {}
19
20#[derive(Debug, Clone, Copy)]
22pub enum NavAgentTarget {
23 Point(NavVec3),
25 Entity(Entity),
27}
28
29impl NavAgentTarget {
30 pub fn is_point(&self) -> bool {
31 matches!(self, NavAgentTarget::Point(_))
32 }
33
34 pub fn is_entity(&self) -> bool {
35 matches!(self, NavAgentTarget::Entity(_))
36 }
37}
38
39#[derive(Debug, Clone)]
41pub struct NavAgentDestination {
42 pub target: NavAgentTarget,
44 pub query: NavQuery,
46 pub mode: NavPathMode,
48 pub mesh: NavMeshID,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct NavAgent {
55 id: NavAgentId,
56 pub position: NavVec3,
58 pub direction: NavVec3,
60 pub speed: Scalar,
62 pub radius: Scalar,
64 pub min_target_distance: Scalar,
67 #[serde(skip)]
68 pub(crate) destination: Option<NavAgentDestination>,
69 #[serde(skip)]
70 pub(crate) path: Option<Vec<NavVec3>>,
71 #[serde(skip)]
72 pub(crate) dirty_path: bool,
73}
74
75impl Default for NavAgent {
76 fn default() -> Self {
77 Self::new(Default::default())
78 }
79}
80
81impl NavAgent {
82 pub fn new(position: NavVec3) -> Self {
83 Self::new_with_direction(position, Default::default())
84 }
85
86 pub fn new_with_direction(position: NavVec3, direction: NavVec3) -> Self {
87 Self {
88 id: Default::default(),
89 position,
90 direction: direction.normalize(),
91 speed: 10.0,
92 radius: 1.0,
93 min_target_distance: 1.0,
94 destination: None,
95 path: None,
96 dirty_path: false,
97 }
98 }
99
100 pub fn id(&self) -> NavAgentId {
101 self.id
102 }
103
104 pub fn target(&self) -> Option<NavAgentTarget> {
105 self.destination
106 .as_ref()
107 .map(|destination| destination.target)
108 }
109
110 pub fn destination(&self) -> Option<&NavAgentDestination> {
111 self.destination.as_ref()
112 }
113
114 pub fn set_destination(
122 &mut self,
123 target: NavAgentTarget,
124 query: NavQuery,
125 mode: NavPathMode,
126 mesh: NavMeshID,
127 ) {
128 self.destination = Some(NavAgentDestination {
129 target,
130 query,
131 mode,
132 mesh,
133 });
134 self.dirty_path = true;
135 }
136
137 pub fn clear_path(&mut self) {
138 self.destination = None;
139 self.dirty_path = false;
140 self.path = None;
141 }
142
143 pub fn recalculate_path(&mut self) {
144 self.dirty_path = true;
145 }
146
147 pub fn path(&self) -> Option<&[NavVec3]> {
148 if let Some(path) = &self.path {
149 Some(path)
150 } else {
151 None
152 }
153 }
154
155 pub fn set_path(&mut self, path: Vec<NavVec3>) {
156 self.path = Some(path);
157 self.dirty_path = false;
158 }
159}
160
161impl Prefab for NavAgent {}
162impl PrefabComponent for NavAgent {}