ncollide3d/shape/
shape.rsuse crate::bounding_volume::{BoundingSphere, AABB};
use crate::math::{Isometry, Vector};
use crate::query::{PointQuery, RayCast};
use crate::shape::{CompositeShape, ConvexPolyhedron, DeformableShape, FeatureId, SupportMap};
use downcast_rs::Downcast;
use na::{self, RealField, Unit};
use std::ops::Deref;
use std::sync::Arc;
pub trait ShapeClone<N: RealField + Copy> {
fn clone_arc(&self) -> Arc<dyn Shape<N>>;
}
impl<N: RealField + Copy, T: 'static + Shape<N> + Clone> ShapeClone<N> for T {
fn clone_arc(&self) -> Arc<dyn Shape<N>> {
Arc::new(self.clone())
}
}
pub trait Shape<N: RealField + Copy>: Send + Sync + Downcast + ShapeClone<N> {
fn aabb(&self, m: &Isometry<N>) -> AABB<N>;
#[inline]
fn local_aabb(&self) -> AABB<N> {
self.aabb(&Isometry::identity())
}
#[inline]
fn bounding_sphere(&self, m: &Isometry<N>) -> BoundingSphere<N> {
let aabb = self.aabb(m);
BoundingSphere::new(aabb.center(), aabb.half_extents().norm())
}
#[inline]
fn local_bounding_sphere(&self) -> BoundingSphere<N> {
let aabb = self.local_aabb();
BoundingSphere::new(aabb.center(), aabb.half_extents().norm())
}
fn tangent_cone_contains_dir(
&self,
_feature: FeatureId,
_m: &Isometry<N>,
_deformations: Option<&[N]>,
_dir: &Unit<Vector<N>>,
) -> bool;
fn subshape_containing_feature(&self, _i: FeatureId) -> usize {
0
}
#[inline]
fn as_ray_cast(&self) -> Option<&dyn RayCast<N>> {
None
}
#[inline]
fn as_point_query(&self) -> Option<&dyn PointQuery<N>> {
None
}
#[inline]
fn as_convex_polyhedron(&self) -> Option<&dyn ConvexPolyhedron<N>> {
None
}
#[inline]
fn as_support_map(&self) -> Option<&dyn SupportMap<N>> {
None
}
#[inline]
fn as_composite_shape(&self) -> Option<&dyn CompositeShape<N>> {
None
}
#[inline]
fn as_deformable_shape(&self) -> Option<&dyn DeformableShape<N>> {
None
}
#[inline]
fn as_deformable_shape_mut(&mut self) -> Option<&mut dyn DeformableShape<N>> {
None
}
#[inline]
fn is_convex_polyhedron(&self) -> bool {
self.as_convex_polyhedron().is_some()
}
#[inline]
fn is_support_map(&self) -> bool {
self.as_support_map().is_some()
}
#[inline]
fn is_composite_shape(&self) -> bool {
self.as_composite_shape().is_some()
}
#[inline]
fn is_deformable_shape(&self) -> bool {
self.as_deformable_shape().is_some()
}
}
impl_downcast!(Shape<N> where N: RealField + Copy);
impl<N: RealField + Copy> dyn Shape<N> {
#[inline]
pub fn is_shape<T: Shape<N>>(&self) -> bool {
self.is::<T>()
}
#[inline]
pub fn as_shape<T: Shape<N>>(&self) -> Option<&T> {
self.downcast_ref()
}
}
#[derive(Clone)]
pub struct ShapeHandle<N: RealField + Copy>(Arc<dyn Shape<N>>);
impl<N: RealField + Copy> ShapeHandle<N> {
#[inline]
pub fn new<S: Shape<N>>(shape: S) -> ShapeHandle<N> {
ShapeHandle(Arc::new(shape))
}
pub fn from_arc(shape: Arc<dyn Shape<N>>) -> ShapeHandle<N> {
ShapeHandle(shape)
}
pub fn as_arc(&self) -> &Arc<dyn Shape<N>> {
&self.0
}
pub(crate) fn make_mut(&mut self) -> &mut dyn Shape<N> {
if Arc::get_mut(&mut self.0).is_none() {
let unique_self = self.0.clone_arc();
self.0 = unique_self;
}
Arc::get_mut(&mut self.0).unwrap()
}
}
impl<N: RealField + Copy> AsRef<dyn Shape<N>> for ShapeHandle<N> {
#[inline]
fn as_ref(&self) -> &dyn Shape<N> {
&*self.0
}
}
impl<N: RealField + Copy> Deref for ShapeHandle<N> {
type Target = dyn Shape<N>;
#[inline]
fn deref(&self) -> &dyn Shape<N> {
&*self.0
}
}