avian3d/collider_tree/
proxy_key.rs1use core::hint::unreachable_unchecked;
2
3use bevy::{ecs::component::Component, reflect::Reflect};
4
5use crate::prelude::RigidBody;
6
7#[derive(Component, Clone, Copy, Debug, PartialEq, Eq, Hash, Reflect)]
15pub struct ColliderTreeProxyKey(u32);
16
17impl ColliderTreeProxyKey {
18 pub const PLACEHOLDER: Self = ColliderTreeProxyKey(u32::MAX);
20
21 #[inline]
23 pub const fn new(id: ProxyId, tree_type: ColliderTreeType) -> Self {
24 ColliderTreeProxyKey((id.id() << 2) | (tree_type as u32))
26 }
27
28 #[inline]
30 pub const fn id(&self) -> ProxyId {
31 ProxyId::new(self.0 >> 2)
32 }
33
34 #[inline]
36 pub const fn tree_type(&self) -> ColliderTreeType {
37 match self.0 & 0b11 {
38 0 => ColliderTreeType::Dynamic,
39 1 => ColliderTreeType::Kinematic,
40 2 => ColliderTreeType::Static,
41 3 => ColliderTreeType::Standalone,
42 _ => unsafe { unreachable_unchecked() },
44 }
45 }
46
47 #[inline]
51 pub const fn body(&self) -> Option<RigidBody> {
52 match self.0 & 0b11 {
53 0 => Some(RigidBody::Dynamic),
54 1 => Some(RigidBody::Kinematic),
55 2 => Some(RigidBody::Static),
56 3 => None,
57 _ => unsafe { unreachable_unchecked() },
59 }
60 }
61
62 #[inline]
64 pub const fn is_dynamic(&self) -> bool {
65 if let Some(body) = self.body() {
66 body as u32 == RigidBody::Dynamic as u32
67 } else {
68 false
69 }
70 }
71
72 #[inline]
74 pub const fn is_kinematic(&self) -> bool {
75 if let Some(body) = self.body() {
76 body as u32 == RigidBody::Kinematic as u32
77 } else {
78 false
79 }
80 }
81
82 #[inline]
84 pub const fn is_static(&self) -> bool {
85 if let Some(body) = self.body() {
86 body as u32 == RigidBody::Static as u32
87 } else {
88 false
89 }
90 }
91
92 #[inline]
94 pub const fn is_standalone(&self) -> bool {
95 self.body().is_none()
96 }
97}
98
99#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Reflect)]
103pub struct ProxyId(u32);
104
105impl ProxyId {
106 pub const PLACEHOLDER: Self = ProxyId(u32::MAX >> 2);
108
109 #[inline]
117 pub const fn new(id: u32) -> Self {
118 debug_assert!(id < (1 << 30), "ProxyId can only use lower 30 bits");
119 ProxyId(id)
120 }
121
122 #[inline]
124 pub const fn id(&self) -> u32 {
125 self.0
126 }
127
128 #[inline]
130 pub const fn index(&self) -> usize {
131 self.0 as usize
132 }
133}
134
135impl From<u32> for ProxyId {
136 #[inline]
137 fn from(id: u32) -> Self {
138 ProxyId::new(id)
139 }
140}
141
142impl From<ProxyId> for u32 {
143 #[inline]
144 fn from(proxy_id: ProxyId) -> Self {
145 proxy_id.id()
146 }
147}
148
149impl PartialOrd for ProxyId {
150 #[inline]
151 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
152 Some(self.cmp(other))
153 }
154}
155
156impl Ord for ProxyId {
157 #[inline]
158 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
159 self.0.cmp(&other.0)
160 }
161}
162
163#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Reflect)]
165pub enum ColliderTreeType {
166 Dynamic = 0,
168 Kinematic = 1,
170 Static = 2,
172 Standalone = 3,
174}
175
176impl ColliderTreeType {
177 pub const ALL: [ColliderTreeType; 4] = [
179 ColliderTreeType::Dynamic,
180 ColliderTreeType::Kinematic,
181 ColliderTreeType::Static,
182 ColliderTreeType::Standalone,
183 ];
184
185 #[inline]
189 pub const fn from_body(body: Option<RigidBody>) -> Self {
190 match body {
191 Some(RigidBody::Dynamic) => ColliderTreeType::Dynamic,
192 Some(RigidBody::Kinematic) => ColliderTreeType::Kinematic,
193 Some(RigidBody::Static) => ColliderTreeType::Static,
194 None => ColliderTreeType::Standalone,
195 }
196 }
197
198 #[inline]
200 pub const fn is_dynamic(&self) -> bool {
201 matches!(self, ColliderTreeType::Dynamic)
202 }
203
204 #[inline]
206 pub const fn is_kinematic(&self) -> bool {
207 matches!(self, ColliderTreeType::Kinematic)
208 }
209
210 #[inline]
212 pub const fn is_static(&self) -> bool {
213 matches!(self, ColliderTreeType::Static)
214 }
215
216 #[inline]
218 pub const fn is_standalone(&self) -> bool {
219 matches!(self, ColliderTreeType::Standalone)
220 }
221}
222
223impl From<Option<RigidBody>> for ColliderTreeType {
224 #[inline]
225 fn from(body: Option<RigidBody>) -> Self {
226 match body {
227 Some(RigidBody::Dynamic) => ColliderTreeType::Dynamic,
228 Some(RigidBody::Kinematic) => ColliderTreeType::Kinematic,
229 Some(RigidBody::Static) => ColliderTreeType::Static,
230 None => ColliderTreeType::Standalone,
231 }
232 }
233}
234
235impl From<ColliderTreeType> for Option<RigidBody> {
236 #[inline]
237 fn from(tree_type: ColliderTreeType) -> Self {
238 match tree_type {
239 ColliderTreeType::Dynamic => Some(RigidBody::Dynamic),
240 ColliderTreeType::Kinematic => Some(RigidBody::Kinematic),
241 ColliderTreeType::Static => Some(RigidBody::Static),
242 ColliderTreeType::Standalone => None,
243 }
244 }
245}
246
247impl From<RigidBody> for ColliderTreeType {
248 #[inline]
249 fn from(body: RigidBody) -> Self {
250 match body {
251 RigidBody::Dynamic => ColliderTreeType::Dynamic,
252 RigidBody::Kinematic => ColliderTreeType::Kinematic,
253 RigidBody::Static => ColliderTreeType::Static,
254 }
255 }
256}