1use crate::data::arena::Arena;
2use crate::data::{HasModifiedFlag, ModifiedObjects};
3use crate::dynamics::{IslandManager, RigidBodyHandle, RigidBodySet};
4use crate::geometry::{Collider, ColliderChanges, ColliderHandle, ColliderParent};
5use crate::math::Isometry;
6use std::ops::{Index, IndexMut};
7
8pub(crate) type ModifiedColliders = ModifiedObjects<ColliderHandle, Collider>;
9
10impl HasModifiedFlag for Collider {
11 #[inline]
12 fn has_modified_flag(&self) -> bool {
13 self.changes.contains(ColliderChanges::MODIFIED)
14 }
15
16 #[inline]
17 fn set_modified_flag(&mut self) {
18 self.changes |= ColliderChanges::MODIFIED;
19 }
20}
21
22#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
23#[derive(Clone, Default, Debug)]
24pub struct ColliderSet {
26 pub(crate) colliders: Arena<Collider>,
27 pub(crate) modified_colliders: ModifiedColliders,
28 pub(crate) removed_colliders: Vec<ColliderHandle>,
29}
30
31impl ColliderSet {
32 pub fn new() -> Self {
34 ColliderSet {
35 colliders: Arena::new(),
36 modified_colliders: Default::default(),
37 removed_colliders: Vec::new(),
38 }
39 }
40
41 pub fn with_capacity(capacity: usize) -> Self {
45 ColliderSet {
46 colliders: Arena::with_capacity(capacity),
47 modified_colliders: ModifiedColliders::with_capacity(capacity),
48 removed_colliders: Vec::new(),
49 }
50 }
51
52 pub(crate) fn take_modified(&mut self) -> ModifiedColliders {
53 std::mem::take(&mut self.modified_colliders)
54 }
55
56 pub(crate) fn take_removed(&mut self) -> Vec<ColliderHandle> {
57 std::mem::take(&mut self.removed_colliders)
58 }
59
60 pub fn invalid_handle() -> ColliderHandle {
62 ColliderHandle::from_raw_parts(crate::INVALID_U32, crate::INVALID_U32)
63 }
64
65 pub fn iter(&self) -> impl ExactSizeIterator<Item = (ColliderHandle, &Collider)> {
67 self.colliders.iter().map(|(h, c)| (ColliderHandle(h), c))
68 }
69
70 pub fn iter_enabled(&self) -> impl Iterator<Item = (ColliderHandle, &Collider)> {
72 self.colliders
73 .iter()
74 .map(|(h, c)| (ColliderHandle(h), c))
75 .filter(|(_, c)| c.is_enabled())
76 }
77
78 #[cfg(not(feature = "dev-remove-slow-accessors"))]
80 pub fn iter_mut(&mut self) -> impl Iterator<Item = (ColliderHandle, &mut Collider)> {
81 self.modified_colliders.clear();
82 let modified_colliders = &mut self.modified_colliders;
83 self.colliders.iter_mut().map(move |(h, co)| {
84 modified_colliders.push_unchecked(ColliderHandle(h), co);
87 (ColliderHandle(h), co)
88 })
89 }
90
91 #[cfg(not(feature = "dev-remove-slow-accessors"))]
93 pub fn iter_enabled_mut(&mut self) -> impl Iterator<Item = (ColliderHandle, &mut Collider)> {
94 self.iter_mut().filter(|(_, c)| c.is_enabled())
95 }
96
97 pub fn len(&self) -> usize {
99 self.colliders.len()
100 }
101
102 pub fn is_empty(&self) -> bool {
104 self.colliders.is_empty()
105 }
106
107 pub fn contains(&self, handle: ColliderHandle) -> bool {
109 self.colliders.contains(handle.0)
110 }
111
112 pub fn insert(&mut self, coll: impl Into<Collider>) -> ColliderHandle {
114 let mut coll = coll.into();
115 coll.reset_internal_references();
118 coll.parent = None;
119 let handle = ColliderHandle(self.colliders.insert(coll));
120 self.modified_colliders
124 .push_unchecked(handle, &mut self.colliders[handle.0]);
125 handle
126 }
127
128 pub fn insert_with_parent(
130 &mut self,
131 coll: impl Into<Collider>,
132 parent_handle: RigidBodyHandle,
133 bodies: &mut RigidBodySet,
134 ) -> ColliderHandle {
135 let mut coll = coll.into();
136 coll.reset_internal_references();
139
140 if let Some(prev_parent) = &mut coll.parent {
141 prev_parent.handle = parent_handle;
142 } else {
143 coll.parent = Some(ColliderParent {
144 handle: parent_handle,
145 pos_wrt_parent: coll.pos.0,
146 });
147 }
148
149 let parent = bodies
152 .get_mut_internal_with_modification_tracking(parent_handle)
153 .expect("Parent rigid body not found.");
154 let handle = ColliderHandle(self.colliders.insert(coll));
155 let coll = self.colliders.get_mut(handle.0).unwrap();
156 self.modified_colliders.push_unchecked(handle, coll);
160
161 parent.add_collider_internal(
162 handle,
163 coll.parent.as_mut().unwrap(),
164 &mut coll.pos,
165 &coll.shape,
166 &coll.mprops,
167 );
168 handle
169 }
170
171 pub fn set_parent(
174 &mut self,
175 handle: ColliderHandle,
176 new_parent_handle: Option<RigidBodyHandle>,
177 bodies: &mut RigidBodySet,
178 ) {
179 if let Some(collider) = self.get_mut(handle) {
180 let curr_parent = collider.parent.map(|p| p.handle);
181 if new_parent_handle == curr_parent {
182 return; }
184
185 collider.changes |= ColliderChanges::PARENT;
186
187 if let Some(parent_handle) = curr_parent {
188 if let Some(rb) = bodies.get_mut(parent_handle) {
189 rb.remove_collider_internal(handle);
190 }
191 }
192
193 match new_parent_handle {
194 Some(new_parent_handle) => {
195 if let Some(parent) = &mut collider.parent {
196 parent.handle = new_parent_handle;
197 } else {
198 collider.parent = Some(ColliderParent {
199 handle: new_parent_handle,
200 pos_wrt_parent: Isometry::identity(),
201 })
202 };
203
204 if let Some(rb) = bodies.get_mut(new_parent_handle) {
205 rb.add_collider_internal(
206 handle,
207 collider.parent.as_ref().unwrap(),
208 &mut collider.pos,
209 &collider.shape,
210 &collider.mprops,
211 );
212 }
213 }
214 None => collider.parent = None,
215 }
216 }
217 }
218
219 pub fn remove(
224 &mut self,
225 handle: ColliderHandle,
226 islands: &mut IslandManager,
227 bodies: &mut RigidBodySet,
228 wake_up: bool,
229 ) -> Option<Collider> {
230 let collider = self.colliders.remove(handle.0)?;
231
232 if let Some(parent) = &collider.parent {
238 if let Some(parent_rb) =
239 bodies.get_mut_internal_with_modification_tracking(parent.handle)
240 {
241 parent_rb.remove_collider_internal(handle);
242
243 if wake_up {
244 islands.wake_up(bodies, parent.handle, true);
245 }
246 }
247 }
248
249 self.removed_colliders.push(handle);
253
254 Some(collider)
255 }
256
257 pub fn get_unknown_gen(&self, i: u32) -> Option<(&Collider, ColliderHandle)> {
267 self.colliders
268 .get_unknown_gen(i)
269 .map(|(c, h)| (c, ColliderHandle(h)))
270 }
271
272 #[cfg(not(feature = "dev-remove-slow-accessors"))]
282 pub fn get_unknown_gen_mut(&mut self, i: u32) -> Option<(&mut Collider, ColliderHandle)> {
283 let (collider, handle) = self.colliders.get_unknown_gen_mut(i)?;
284 let handle = ColliderHandle(handle);
285 self.modified_colliders.push_once(handle, collider);
286 Some((collider, handle))
287 }
288
289 pub fn get(&self, handle: ColliderHandle) -> Option<&Collider> {
291 self.colliders.get(handle.0)
292 }
293
294 #[cfg(not(feature = "dev-remove-slow-accessors"))]
296 pub fn get_mut(&mut self, handle: ColliderHandle) -> Option<&mut Collider> {
297 let result = self.colliders.get_mut(handle.0)?;
298 self.modified_colliders.push_once(handle, result);
299 Some(result)
300 }
301
302 #[cfg(not(feature = "dev-remove-slow-accessors"))]
306 pub fn get_pair_mut(
307 &mut self,
308 handle1: ColliderHandle,
309 handle2: ColliderHandle,
310 ) -> (Option<&mut Collider>, Option<&mut Collider>) {
311 if handle1 == handle2 {
312 (self.get_mut(handle1), None)
313 } else {
314 let (mut co1, mut co2) = self.colliders.get2_mut(handle1.0, handle2.0);
315 if let Some(co1) = co1.as_deref_mut() {
316 self.modified_colliders.push_once(handle1, co1);
317 }
318 if let Some(co2) = co2.as_deref_mut() {
319 self.modified_colliders.push_once(handle2, co2);
320 }
321 (co1, co2)
322 }
323 }
324
325 pub(crate) fn index_mut_internal(&mut self, handle: ColliderHandle) -> &mut Collider {
326 &mut self.colliders[handle.0]
327 }
328
329 pub(crate) fn get_mut_internal(&mut self, handle: ColliderHandle) -> Option<&mut Collider> {
330 self.colliders.get_mut(handle.0)
331 }
332
333 #[allow(dead_code)]
336 pub(crate) fn get_mut_internal_with_modification_tracking(
337 &mut self,
338 handle: ColliderHandle,
339 ) -> Option<&mut Collider> {
340 let result = self.colliders.get_mut(handle.0)?;
341 self.modified_colliders.push_once(handle, result);
342 Some(result)
343 }
344}
345
346impl Index<crate::data::Index> for ColliderSet {
347 type Output = Collider;
348
349 fn index(&self, index: crate::data::Index) -> &Collider {
350 &self.colliders[index]
351 }
352}
353
354impl Index<ColliderHandle> for ColliderSet {
355 type Output = Collider;
356
357 fn index(&self, index: ColliderHandle) -> &Collider {
358 &self.colliders[index.0]
359 }
360}
361
362#[cfg(not(feature = "dev-remove-slow-accessors"))]
363impl IndexMut<ColliderHandle> for ColliderSet {
364 fn index_mut(&mut self, handle: ColliderHandle) -> &mut Collider {
365 let collider = &mut self.colliders[handle.0];
366 self.modified_colliders.push_once(handle, collider);
367 collider
368 }
369}