use crate::{
scene::legacy_physics::dim3::NativeRigidBodyHandle,
scene::legacy_physics::dim3::RigidBodyHandle,
};
use rapier3d::dynamics::{RigidBody, RigidBodySet};
use rg3d_core::BiDirHashMap;
pub struct RigidBodyContainer {
pub(super) set: RigidBodySet,
pub(super) handle_map: BiDirHashMap<RigidBodyHandle, NativeRigidBodyHandle>,
}
impl Default for RigidBodyContainer {
fn default() -> Self {
Self {
set: RigidBodySet::new(),
handle_map: Default::default(),
}
}
}
impl RigidBodyContainer {
pub fn new() -> Self {
Self {
set: RigidBodySet::new(),
handle_map: Default::default(),
}
}
pub fn from_raw_parts(
set: RigidBodySet,
handle_map: BiDirHashMap<RigidBodyHandle, NativeRigidBodyHandle>,
) -> Result<Self, &'static str> {
assert_eq!(set.len(), handle_map.len());
for handle in handle_map.forward_map().values() {
if !set.contains(*handle) {
return Err(
"Unable to create rigid body container because handle map is out of sync!",
);
}
}
Ok(Self { set, handle_map })
}
pub fn get_mut(&mut self, handle: &RigidBodyHandle) -> Option<&mut RigidBody> {
let bodies = &mut self.set;
self.handle_map
.value_of(handle)
.and_then(move |&h| bodies.get_mut(h))
}
pub fn native_mut(&mut self, handle: NativeRigidBodyHandle) -> Option<&mut RigidBody> {
self.set.get_mut(handle)
}
pub fn get(&self, handle: &RigidBodyHandle) -> Option<&RigidBody> {
let bodies = &self.set;
self.handle_map
.value_of(handle)
.and_then(move |&h| bodies.get(h))
}
pub fn native_ref(&self, handle: NativeRigidBodyHandle) -> Option<&RigidBody> {
self.set.get(handle)
}
pub fn handle_map(&self) -> &BiDirHashMap<RigidBodyHandle, NativeRigidBodyHandle> {
&self.handle_map
}
pub fn contains(&self, handle: &RigidBodyHandle) -> bool {
self.get(handle).is_some()
}
pub fn iter(&self) -> impl Iterator<Item = &RigidBody> {
self.set.iter().map(|(_, b)| b)
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut RigidBody> {
self.set.iter_mut().map(|(_, b)| b)
}
pub fn pair_iter(&self) -> impl Iterator<Item = (RigidBodyHandle, &RigidBody)> {
self.set
.iter()
.map(move |(h, b)| (self.handle_map.key_of(&h).cloned().unwrap(), b))
}
pub fn pair_iter_mut(&mut self) -> impl Iterator<Item = (RigidBodyHandle, &mut RigidBody)> {
let handle_map = &self.handle_map;
self.set
.iter_mut()
.map(move |(h, b)| (handle_map.key_of(&h).cloned().unwrap(), b))
}
pub fn len(&self) -> usize {
self.set.len()
}
pub fn is_empty(&self) -> bool {
self.set.is_empty()
}
pub fn inner_ref(&self) -> &RigidBodySet {
&self.set
}
}