use crate::{
core::{uuid::Uuid, BiDirHashMap},
engine::{ColliderHandle, RigidBodyHandle},
scene::physics::body::RigidBodyContainer,
};
use rapier3d::{
dynamics::IslandManager,
geometry::{Collider, ColliderSet},
};
pub struct ColliderContainer {
pub(super) set: ColliderSet,
pub(super) handle_map: BiDirHashMap<ColliderHandle, rapier3d::geometry::ColliderHandle>,
}
impl Default for ColliderContainer {
fn default() -> Self {
Self {
set: ColliderSet::new(),
handle_map: Default::default(),
}
}
}
impl ColliderContainer {
pub fn new() -> Self {
Self {
set: ColliderSet::new(),
handle_map: Default::default(),
}
}
pub(super) fn add(
&mut self,
collider: Collider,
parent: &RigidBodyHandle,
container: &mut RigidBodyContainer,
) -> ColliderHandle {
let handle = self.set.insert_with_parent(
collider,
container.handle_map().value_of(parent).cloned().unwrap(),
&mut container.set,
);
let id = ColliderHandle::from(Uuid::new_v4());
self.handle_map.insert(id, handle);
id
}
pub(super) fn remove(
&mut self,
collider_handle: &ColliderHandle,
rigid_body_container: &mut RigidBodyContainer,
islands: &mut IslandManager,
) -> Option<Collider> {
let colliders = &mut self.set;
let result = self
.handle_map
.value_of(collider_handle)
.and_then(|&h| colliders.remove(h, islands, &mut rigid_body_container.set, true));
self.handle_map.remove_by_key(collider_handle);
result
}
pub fn get_mut(&mut self, handle: &ColliderHandle) -> Option<&mut Collider> {
let colliders = &mut self.set;
self.handle_map
.value_of(handle)
.and_then(move |&h| colliders.get_mut(h))
}
pub fn native_mut(
&mut self,
handle: rapier3d::geometry::ColliderHandle,
) -> Option<&mut Collider> {
self.set.get_mut(handle)
}
pub fn get(&self, handle: &ColliderHandle) -> Option<&Collider> {
let colliders = &self.set;
self.handle_map
.value_of(handle)
.and_then(move |&h| colliders.get(h))
}
pub fn native_ref(&self, handle: rapier3d::geometry::ColliderHandle) -> Option<&Collider> {
self.set.get(handle)
}
pub fn handle_map(&self) -> &BiDirHashMap<ColliderHandle, rapier3d::geometry::ColliderHandle> {
&self.handle_map
}
pub fn contains(&self, handle: &ColliderHandle) -> bool {
self.get(handle).is_some()
}
pub fn iter(&self) -> impl Iterator<Item = &Collider> {
self.set.iter().map(|(_, b)| b)
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Collider> {
self.set.iter_mut().map(|(_, b)| b)
}
pub fn pair_iter(&self) -> impl Iterator<Item = (ColliderHandle, &Collider)> {
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 = (ColliderHandle, &mut Collider)> {
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) -> &ColliderSet {
&self.set
}
}