use crate::{
scene::legacy_physics::dim3::ColliderHandle, scene::legacy_physics::dim3::NativeColliderHandle,
};
use rapier3d::geometry::{Collider, ColliderSet};
use rg3d_core::BiDirHashMap;
pub struct ColliderContainer {
pub(super) set: ColliderSet,
pub(super) handle_map: BiDirHashMap<ColliderHandle, NativeColliderHandle>,
}
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 fn from_raw_parts(
set: ColliderSet,
handle_map: BiDirHashMap<ColliderHandle, NativeColliderHandle>,
) -> 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 collider container because handle map is out of sync!",
);
}
}
Ok(Self { set, handle_map })
}
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: NativeColliderHandle) -> 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: NativeColliderHandle) -> Option<&Collider> {
self.set.get(handle)
}
pub fn handle_map(&self) -> &BiDirHashMap<ColliderHandle, NativeColliderHandle> {
&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
}
}