ncollide3d/pipeline/object/
collision_object_set.rsuse simba::scalar::RealField;
use crate::pipeline::object::{CollisionObject, CollisionObjectRef, CollisionObjectSlabHandle};
use slab::{Iter, IterMut, Slab};
use std::hash::Hash;
use std::ops::{Index, IndexMut};
pub trait CollisionObjectHandle: Copy + Hash + PartialEq + Eq + 'static + Send + Sync {}
impl<T: Copy + Hash + PartialEq + Eq + 'static + Send + Sync> CollisionObjectHandle for T {}
pub trait CollisionObjectSet<N: RealField + Copy> {
type CollisionObject: CollisionObjectRef<N>;
type CollisionObjectHandle: CollisionObjectHandle;
fn collision_object(
&self,
handle: Self::CollisionObjectHandle,
) -> Option<&Self::CollisionObject>;
fn foreach(&self, f: impl FnMut(Self::CollisionObjectHandle, &Self::CollisionObject));
}
impl<N: RealField + Copy, T> CollisionObjectSet<N> for CollisionObjectSlab<N, T> {
type CollisionObject = CollisionObject<N, T>;
type CollisionObjectHandle = CollisionObjectSlabHandle;
fn collision_object(
&self,
handle: Self::CollisionObjectHandle,
) -> Option<&Self::CollisionObject> {
self.get(handle)
}
fn foreach(&self, mut f: impl FnMut(Self::CollisionObjectHandle, &Self::CollisionObject)) {
for co in self.objects.iter() {
f(CollisionObjectSlabHandle(co.0), co.1)
}
}
}
pub struct CollisionObjectSlab<N: RealField + Copy, T> {
pub(crate) objects: Slab<CollisionObject<N, T>>,
}
impl<N: RealField + Copy, T> CollisionObjectSlab<N, T> {
pub fn new() -> CollisionObjectSlab<N, T> {
CollisionObjectSlab {
objects: Slab::new(),
}
}
pub fn with_capacity(capacity: usize) -> CollisionObjectSlab<N, T> {
CollisionObjectSlab {
objects: Slab::with_capacity(capacity),
}
}
#[inline]
pub fn insert(&mut self, co: CollisionObject<N, T>) -> CollisionObjectSlabHandle {
CollisionObjectSlabHandle(self.objects.insert(co))
}
#[inline]
pub fn remove(&mut self, handle: CollisionObjectSlabHandle) -> CollisionObject<N, T> {
self.objects.remove(handle.0)
}
#[inline]
pub fn get(&self, handle: CollisionObjectSlabHandle) -> Option<&CollisionObject<N, T>> {
self.objects.get(handle.0)
}
#[inline]
pub fn get_mut(
&mut self,
handle: CollisionObjectSlabHandle,
) -> Option<&mut CollisionObject<N, T>> {
self.objects.get_mut(handle.0)
}
#[inline]
pub fn get_pair_mut(
&mut self,
handle1: CollisionObjectSlabHandle,
handle2: CollisionObjectSlabHandle,
) -> (
Option<&mut CollisionObject<N, T>>,
Option<&mut CollisionObject<N, T>>,
) {
assert_ne!(handle1, handle2, "The two handles must not be the same.");
let a = self.objects.get_mut(handle1.0).map(|o| o as *mut _);
(
a.map(|a| unsafe { std::mem::transmute(a) }),
self.objects.get_mut(handle2.0),
)
}
#[inline]
pub fn contains(&self, handle: CollisionObjectSlabHandle) -> bool {
self.objects.contains(handle.0)
}
#[inline]
pub fn iter(&self) -> CollisionObjects<N, T> {
CollisionObjects {
iter: self.objects.iter(),
}
}
#[inline]
pub fn iter_mut(&mut self) -> CollisionObjectsMut<N, T> {
CollisionObjectsMut {
iter_mut: self.objects.iter_mut(),
}
}
#[inline]
pub fn len(&self) -> usize {
self.objects.len()
}
#[inline]
pub fn capacity(&self) -> usize {
self.objects.capacity()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.objects.reserve(additional);
}
#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.objects.reserve_exact(additional);
}
}
impl<N: RealField + Copy, T> Index<CollisionObjectSlabHandle> for CollisionObjectSlab<N, T> {
type Output = CollisionObject<N, T>;
#[inline]
fn index(&self, handle: CollisionObjectSlabHandle) -> &Self::Output {
&self.objects[handle.0]
}
}
impl<N: RealField + Copy, T> IndexMut<CollisionObjectSlabHandle> for CollisionObjectSlab<N, T> {
#[inline]
fn index_mut(&mut self, handle: CollisionObjectSlabHandle) -> &mut Self::Output {
&mut self.objects[handle.0]
}
}
pub struct CollisionObjects<'a, N: 'a + RealField + Copy, T: 'a> {
iter: Iter<'a, CollisionObject<N, T>>,
}
impl<'a, N: 'a + RealField + Copy, T: 'a> Iterator for CollisionObjects<'a, N, T> {
type Item = (CollisionObjectSlabHandle, &'a CollisionObject<N, T>);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|obj| ((CollisionObjectSlabHandle(obj.0), obj.1)))
}
}
pub struct CollisionObjectsMut<'a, N: 'a + RealField + Copy, T: 'a> {
iter_mut: IterMut<'a, CollisionObject<N, T>>,
}
impl<'a, N: 'a + RealField + Copy, T: 'a> Iterator for CollisionObjectsMut<'a, N, T> {
type Item = (CollisionObjectSlabHandle, &'a mut CollisionObject<N, T>);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter_mut
.next()
.map(|obj| ((CollisionObjectSlabHandle(obj.0), obj.1)))
}
}