nphysics3d/object/
body_set.rs1use generational_arena::Arena;
2use std::hash::Hash;
3
4use crate::object::{Body, DefaultColliderHandle, Multibody, RigidBody};
5use crate::world::GeometricalWorld;
6use na::RealField;
7
8pub trait BodyHandle: Copy + Hash + PartialEq + Eq + 'static + Send + Sync {}
12
13impl<T: Copy + Hash + PartialEq + Eq + 'static + Send + Sync> BodyHandle for T {}
14
15pub trait BodySet<N: RealField + Copy> {
20 type Handle: BodyHandle;
22
23 fn get(&self, handle: Self::Handle) -> Option<&dyn Body<N>>;
25 fn get_mut(&mut self, handle: Self::Handle) -> Option<&mut dyn Body<N>>;
27
28 fn get_pair(
32 &self,
33 handle1: Self::Handle,
34 handle2: Self::Handle,
35 ) -> (Option<&dyn Body<N>>, Option<&dyn Body<N>>) {
36 (self.get(handle1), self.get(handle2))
37 }
38
39 fn contains(&self, handle: Self::Handle) -> bool;
41
42 fn foreach(&self, f: &mut dyn FnMut(Self::Handle, &dyn Body<N>));
44 fn foreach_mut(&mut self, f: &mut dyn FnMut(Self::Handle, &mut dyn Body<N>));
46
47 fn pop_removal_event(&mut self) -> Option<Self::Handle>;
55}
56
57pub struct DefaultBodySet<N: RealField + Copy> {
61 bodies: Arena<Box<dyn Body<N>>>,
62 removed: Vec<DefaultBodyHandle>,
63}
64
65impl<N: RealField + Copy> DefaultBodySet<N> {
66 pub fn new() -> Self {
68 DefaultBodySet {
69 bodies: Arena::new(),
70 removed: Vec::new(),
71 }
72 }
73
74 pub fn insert(&mut self, body: impl Body<N>) -> DefaultBodyHandle {
76 self.bodies.insert(Box::new(body))
77 }
78
79 pub fn insert_boxed(&mut self, body: Box<dyn Body<N>>) -> DefaultBodyHandle {
81 self.bodies.insert(body)
82 }
83
84 pub fn remove(&mut self, to_remove: DefaultBodyHandle) -> Option<Box<dyn Body<N>>> {
86 let res = self.bodies.remove(to_remove)?;
87 self.removed.push(to_remove);
88 Some(res)
89 }
90
91 fn contains(&self, handle: DefaultBodyHandle) -> bool {
93 self.bodies.contains(handle)
94 }
95
96 pub fn get(&self, handle: DefaultBodyHandle) -> Option<&dyn Body<N>> {
98 self.bodies.get(handle).map(|b| &**b)
99 }
100
101 pub fn get_mut(&mut self, handle: DefaultBodyHandle) -> Option<&mut dyn Body<N>> {
103 self.bodies.get_mut(handle).map(|b| &mut **b)
104 }
105
106 pub fn iter(&self) -> impl Iterator<Item = (DefaultBodyHandle, &dyn Body<N>)> {
108 self.bodies.iter().map(|b| (b.0, &**b.1))
109 }
110
111 pub fn iter_mut(&mut self) -> impl Iterator<Item = (DefaultBodyHandle, &mut dyn Body<N>)> {
113 self.bodies.iter_mut().map(|b| (b.0, &mut **b.1))
114 }
115
116 pub fn rigid_body(&self, handle: DefaultBodyHandle) -> Option<&RigidBody<N>> {
120 self.get(handle).and_then(|b| b.downcast_ref())
121 }
122
123 pub fn rigid_body_mut(&mut self, handle: DefaultBodyHandle) -> Option<&mut RigidBody<N>> {
127 self.get_mut(handle).and_then(|b| b.downcast_mut())
128 }
129
130 pub fn multibody(&self, handle: DefaultBodyHandle) -> Option<&Multibody<N>> {
134 self.get(handle).and_then(|b| b.downcast_ref())
135 }
136
137 pub fn multibody_mut(&mut self, handle: DefaultBodyHandle) -> Option<&mut Multibody<N>> {
141 self.get_mut(handle).and_then(|b| b.downcast_mut())
142 }
143}
144
145impl<N: RealField + Copy> BodySet<N> for DefaultBodySet<N> {
146 type Handle = DefaultBodyHandle;
147
148 fn get(&self, handle: Self::Handle) -> Option<&dyn Body<N>> {
149 self.get(handle)
150 }
151
152 fn get_mut(&mut self, handle: Self::Handle) -> Option<&mut dyn Body<N>> {
153 self.get_mut(handle)
154 }
155
156 fn contains(&self, handle: Self::Handle) -> bool {
157 self.contains(handle)
158 }
159
160 fn foreach(&self, f: &mut dyn FnMut(Self::Handle, &dyn Body<N>)) {
161 for (h, b) in self.iter() {
162 f(h, b)
163 }
164 }
165
166 fn foreach_mut(&mut self, f: &mut dyn FnMut(Self::Handle, &mut dyn Body<N>)) {
167 for (h, b) in self.iter_mut() {
168 f(h, b)
169 }
170 }
171
172 fn pop_removal_event(&mut self) -> Option<Self::Handle> {
173 self.removed.pop()
174 }
175}
176
177pub type DefaultBodyHandle = generational_arena::Index;
179pub type DefaultBodyPartHandle = BodyPartHandle<DefaultBodyHandle>;
181
182#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
184pub struct BodyPartHandle<Handle: BodyHandle>(pub Handle, pub usize);
185
186pub trait BodyDesc<N: RealField + Copy> {
188 type Body: Body<N>;
190
191 fn build_with_handle(
193 &self,
194 gworld: &mut GeometricalWorld<N, DefaultBodyHandle, DefaultColliderHandle>,
195 handle: DefaultBodyHandle,
196 ) -> Self::Body;
197}