ncollide3d/pipeline/object/
collision_object_set.rs

1use simba::scalar::RealField;
2
3use crate::pipeline::object::{CollisionObject, CollisionObjectRef, CollisionObjectSlabHandle};
4use slab::{Iter, IterMut, Slab};
5use std::hash::Hash;
6use std::ops::{Index, IndexMut};
7
8/// Trait implemented by a handle indentifying a collision object.
9pub trait CollisionObjectHandle: Copy + Hash + PartialEq + Eq + 'static + Send + Sync {}
10
11impl<T: Copy + Hash + PartialEq + Eq + 'static + Send + Sync> CollisionObjectHandle for T {}
12
13/// Trait implemented by sets of collision objects.
14///
15/// A set of collision object map a handle of type `Self::CollisionObjectHandle` with a collision
16/// object of type `Self::CollisionObject`.
17pub trait CollisionObjectSet<N: RealField + Copy> {
18    /// Type of the collision object stored into this set.
19    type CollisionObject: CollisionObjectRef<N>;
20    /// Type of the handles identifying collision objects.
21    type CollisionObjectHandle: CollisionObjectHandle;
22
23    /// Gets the collision object identified by the given `handle`.
24    fn collision_object(
25        &self,
26        handle: Self::CollisionObjectHandle,
27    ) -> Option<&Self::CollisionObject>;
28    /// Applies a closure to every collision object (and their handle) stored into this set.
29    fn foreach(&self, f: impl FnMut(Self::CollisionObjectHandle, &Self::CollisionObject));
30}
31
32impl<N: RealField + Copy, T> CollisionObjectSet<N> for CollisionObjectSlab<N, T> {
33    type CollisionObject = CollisionObject<N, T>;
34    type CollisionObjectHandle = CollisionObjectSlabHandle;
35
36    fn collision_object(
37        &self,
38        handle: Self::CollisionObjectHandle,
39    ) -> Option<&Self::CollisionObject> {
40        self.get(handle)
41    }
42
43    fn foreach(&self, mut f: impl FnMut(Self::CollisionObjectHandle, &Self::CollisionObject)) {
44        for co in self.objects.iter() {
45            f(CollisionObjectSlabHandle(co.0), co.1)
46        }
47    }
48}
49
50/// A set of collision objects that can be indexed by collision object handles.
51pub struct CollisionObjectSlab<N: RealField + Copy, T> {
52    pub(crate) objects: Slab<CollisionObject<N, T>>,
53}
54
55impl<N: RealField + Copy, T> CollisionObjectSlab<N, T> {
56    /// Creates a new empty collection of collision objects.
57    pub fn new() -> CollisionObjectSlab<N, T> {
58        CollisionObjectSlab {
59            objects: Slab::new(),
60        }
61    }
62
63    /// Constructs a new empty collection with the specified capacity.
64    pub fn with_capacity(capacity: usize) -> CollisionObjectSlab<N, T> {
65        CollisionObjectSlab {
66            objects: Slab::with_capacity(capacity),
67        }
68    }
69
70    /// Inserts a new collision object into this collection and returns the corresponding handle.
71    #[inline]
72    pub fn insert(&mut self, co: CollisionObject<N, T>) -> CollisionObjectSlabHandle {
73        CollisionObjectSlabHandle(self.objects.insert(co))
74    }
75
76    /// Removes from this collection the collision object identified by the given handle.
77    ///
78    /// The removed collision object structure is returned.
79    #[inline]
80    pub fn remove(&mut self, handle: CollisionObjectSlabHandle) -> CollisionObject<N, T> {
81        self.objects.remove(handle.0)
82    }
83
84    /// If it exists, retrieves a reference to the collision object identified by the given handle.
85    #[inline]
86    pub fn get(&self, handle: CollisionObjectSlabHandle) -> Option<&CollisionObject<N, T>> {
87        self.objects.get(handle.0)
88    }
89
90    /// If it exists, retrieves a mutable reference to the collision object identified by the given handle.
91    #[inline]
92    pub fn get_mut(
93        &mut self,
94        handle: CollisionObjectSlabHandle,
95    ) -> Option<&mut CollisionObject<N, T>> {
96        self.objects.get_mut(handle.0)
97    }
98
99    /// If they exists, retrieves a mutable reference to the two collision object identified by the given handles.
100    ///
101    /// Panics if both handles are equal.
102    #[inline]
103    pub fn get_pair_mut(
104        &mut self,
105        handle1: CollisionObjectSlabHandle,
106        handle2: CollisionObjectSlabHandle,
107    ) -> (
108        Option<&mut CollisionObject<N, T>>,
109        Option<&mut CollisionObject<N, T>>,
110    ) {
111        assert_ne!(handle1, handle2, "The two handles must not be the same.");
112        let a = self.objects.get_mut(handle1.0).map(|o| o as *mut _);
113        (
114            a.map(|a| unsafe { std::mem::transmute(a) }),
115            self.objects.get_mut(handle2.0),
116        )
117    }
118
119    /// Returns `true` if the specified handle identifies a collision object stored in this collection.
120    #[inline]
121    pub fn contains(&self, handle: CollisionObjectSlabHandle) -> bool {
122        self.objects.contains(handle.0)
123    }
124
125    /// Retrieves an iterator yielding references to each collision object.
126    #[inline]
127    pub fn iter(&self) -> CollisionObjects<N, T> {
128        CollisionObjects {
129            iter: self.objects.iter(),
130        }
131    }
132
133    /// Retrieves an iterator yielding references to each collision object.
134    #[inline]
135    pub fn iter_mut(&mut self) -> CollisionObjectsMut<N, T> {
136        CollisionObjectsMut {
137            iter_mut: self.objects.iter_mut(),
138        }
139    }
140
141    /// The number of collision objects on this slab.
142    #[inline]
143    pub fn len(&self) -> usize {
144        self.objects.len()
145    }
146
147    /// Return the number of values the slab can store without reallocating.
148    #[inline]
149    pub fn capacity(&self) -> usize {
150        self.objects.capacity()
151    }
152
153    /// Reserve capacity for at least `additional` more values to be stored
154    /// without allocating.
155    #[inline]
156    pub fn reserve(&mut self, additional: usize) {
157        self.objects.reserve(additional);
158    }
159
160    /// Reserve the minimum capacity required to store exactly `additional`
161    /// more values.
162    #[inline]
163    pub fn reserve_exact(&mut self, additional: usize) {
164        self.objects.reserve_exact(additional);
165    }
166}
167
168impl<N: RealField + Copy, T> Index<CollisionObjectSlabHandle> for CollisionObjectSlab<N, T> {
169    type Output = CollisionObject<N, T>;
170
171    #[inline]
172    fn index(&self, handle: CollisionObjectSlabHandle) -> &Self::Output {
173        &self.objects[handle.0]
174    }
175}
176
177impl<N: RealField + Copy, T> IndexMut<CollisionObjectSlabHandle> for CollisionObjectSlab<N, T> {
178    #[inline]
179    fn index_mut(&mut self, handle: CollisionObjectSlabHandle) -> &mut Self::Output {
180        &mut self.objects[handle.0]
181    }
182}
183
184/// An iterator yielding references to collision objects.
185pub struct CollisionObjects<'a, N: 'a + RealField + Copy, T: 'a> {
186    iter: Iter<'a, CollisionObject<N, T>>,
187}
188
189impl<'a, N: 'a + RealField + Copy, T: 'a> Iterator for CollisionObjects<'a, N, T> {
190    type Item = (CollisionObjectSlabHandle, &'a CollisionObject<N, T>);
191
192    #[inline]
193    fn next(&mut self) -> Option<Self::Item> {
194        self.iter
195            .next()
196            .map(|obj| ((CollisionObjectSlabHandle(obj.0), obj.1)))
197    }
198}
199
200/// An iterator yielding mutable references to collision objects.
201pub struct CollisionObjectsMut<'a, N: 'a + RealField + Copy, T: 'a> {
202    iter_mut: IterMut<'a, CollisionObject<N, T>>,
203}
204
205impl<'a, N: 'a + RealField + Copy, T: 'a> Iterator for CollisionObjectsMut<'a, N, T> {
206    type Item = (CollisionObjectSlabHandle, &'a mut CollisionObject<N, T>);
207
208    #[inline]
209    fn next(&mut self) -> Option<Self::Item> {
210        self.iter_mut
211            .next()
212            .map(|obj| ((CollisionObjectSlabHandle(obj.0), obj.1)))
213    }
214}