ncollide3d/shape/
shape.rs

1// Queries.
2use crate::bounding_volume::{BoundingSphere, AABB};
3use crate::math::{Isometry, Vector};
4use crate::query::{PointQuery, RayCast};
5use crate::shape::{CompositeShape, ConvexPolyhedron, DeformableShape, FeatureId, SupportMap};
6use downcast_rs::Downcast;
7use na::{self, RealField, Unit};
8use std::ops::Deref;
9use std::sync::Arc;
10
11pub trait ShapeClone<N: RealField + Copy> {
12    /// Construct an `Arc` that refers to a uniquely-owned copy of `self`
13    fn clone_arc(&self) -> Arc<dyn Shape<N>>;
14}
15
16impl<N: RealField + Copy, T: 'static + Shape<N> + Clone> ShapeClone<N> for T {
17    fn clone_arc(&self) -> Arc<dyn Shape<N>> {
18        Arc::new(self.clone())
19    }
20}
21
22/// Trait implemented by all shapes supported by ncollide.
23///
24/// This allows dynamic inspection of the shape capabilities.
25pub trait Shape<N: RealField + Copy>: Send + Sync + Downcast + ShapeClone<N> {
26    /// The AABB of `self` transformed by `m`.
27    fn aabb(&self, m: &Isometry<N>) -> AABB<N>;
28
29    /// The AABB of `self`.
30    #[inline]
31    fn local_aabb(&self) -> AABB<N> {
32        self.aabb(&Isometry::identity())
33    }
34
35    /// The bounding sphere of `self` transformed by `m`.
36    #[inline]
37    fn bounding_sphere(&self, m: &Isometry<N>) -> BoundingSphere<N> {
38        let aabb = self.aabb(m);
39        BoundingSphere::new(aabb.center(), aabb.half_extents().norm())
40    }
41
42    /// The bounding sphere of `self`.
43    #[inline]
44    fn local_bounding_sphere(&self) -> BoundingSphere<N> {
45        let aabb = self.local_aabb();
46        BoundingSphere::new(aabb.center(), aabb.half_extents().norm())
47    }
48
49    /// Check if if the feature `_feature` of the `i-th` subshape of `self` transformed by `m` has a tangent
50    /// cone that contains `dir` at the point `pt`.
51    // NOTE: for the moment, we assume the tangent cone is the same for the whole feature.
52    fn tangent_cone_contains_dir(
53        &self,
54        _feature: FeatureId,
55        _m: &Isometry<N>,
56        _deformations: Option<&[N]>,
57        _dir: &Unit<Vector<N>>,
58    ) -> bool;
59
60    /// Returns the id of the subshape containing the specified feature.
61    ///
62    /// If several subshape contains the same feature, any one is returned.
63    fn subshape_containing_feature(&self, _i: FeatureId) -> usize {
64        0
65    }
66
67    /// The `RayCast` implementation of `self`.
68    #[inline]
69    fn as_ray_cast(&self) -> Option<&dyn RayCast<N>> {
70        None
71    }
72
73    /// The `PointQuery` implementation of `self`.
74    #[inline]
75    fn as_point_query(&self) -> Option<&dyn PointQuery<N>> {
76        None
77    }
78
79    /// The convex polyhedron representation of `self` if applicable.
80    #[inline]
81    fn as_convex_polyhedron(&self) -> Option<&dyn ConvexPolyhedron<N>> {
82        None
83    }
84
85    /// The support mapping of `self` if applicable.
86    #[inline]
87    fn as_support_map(&self) -> Option<&dyn SupportMap<N>> {
88        None
89    }
90
91    /// The composite shape representation of `self` if applicable.
92    #[inline]
93    fn as_composite_shape(&self) -> Option<&dyn CompositeShape<N>> {
94        None
95    }
96
97    /// The deformable shape representation of `self` if applicable.
98    #[inline]
99    fn as_deformable_shape(&self) -> Option<&dyn DeformableShape<N>> {
100        None
101    }
102
103    /// The mutable deformable shape representation of `self` if applicable.
104    #[inline]
105    fn as_deformable_shape_mut(&mut self) -> Option<&mut dyn DeformableShape<N>> {
106        None
107    }
108
109    /// Whether `self` uses a convex polyhedron representation.
110    #[inline]
111    fn is_convex_polyhedron(&self) -> bool {
112        self.as_convex_polyhedron().is_some()
113    }
114
115    /// Whether `self` uses a support-mapping based representation.
116    #[inline]
117    fn is_support_map(&self) -> bool {
118        self.as_support_map().is_some()
119    }
120
121    /// Whether `self` uses a composite shape-based representation.
122    #[inline]
123    fn is_composite_shape(&self) -> bool {
124        self.as_composite_shape().is_some()
125    }
126
127    /// Whether `self` uses a composite shape-based representation.
128    #[inline]
129    fn is_deformable_shape(&self) -> bool {
130        self.as_deformable_shape().is_some()
131    }
132}
133
134impl_downcast!(Shape<N> where N: RealField + Copy);
135
136/// Trait for casting shapes to its exact represetation.
137impl<N: RealField + Copy> dyn Shape<N> {
138    /// Tests if this shape has a specific type `T`.
139    #[inline]
140    pub fn is_shape<T: Shape<N>>(&self) -> bool {
141        self.is::<T>()
142    }
143
144    /// Performs the cast.
145    #[inline]
146    pub fn as_shape<T: Shape<N>>(&self) -> Option<&T> {
147        self.downcast_ref()
148    }
149}
150
151/// A shared handle to an abstract shape.
152///
153/// This can be mutated using COW.
154#[derive(Clone)]
155pub struct ShapeHandle<N: RealField + Copy>(Arc<dyn Shape<N>>);
156
157impl<N: RealField + Copy> ShapeHandle<N> {
158    /// Creates a sharable shape handle from a shape.
159    #[inline]
160    pub fn new<S: Shape<N>>(shape: S) -> ShapeHandle<N> {
161        ShapeHandle(Arc::new(shape))
162    }
163
164    /// Creates a sharable shape handle from a shape trait object.
165    pub fn from_arc(shape: Arc<dyn Shape<N>>) -> ShapeHandle<N> {
166        ShapeHandle(shape)
167    }
168
169    /// Gets a reference the `Arc` refcounted shape object.
170    pub fn as_arc(&self) -> &Arc<dyn Shape<N>> {
171        &self.0
172    }
173
174    pub(crate) fn make_mut(&mut self) -> &mut dyn Shape<N> {
175        if Arc::get_mut(&mut self.0).is_none() {
176            let unique_self = self.0.clone_arc();
177            self.0 = unique_self;
178        }
179        Arc::get_mut(&mut self.0).unwrap()
180    }
181}
182
183impl<N: RealField + Copy> AsRef<dyn Shape<N>> for ShapeHandle<N> {
184    #[inline]
185    fn as_ref(&self) -> &dyn Shape<N> {
186        &*self.0
187    }
188}
189
190impl<N: RealField + Copy> Deref for ShapeHandle<N> {
191    type Target = dyn Shape<N>;
192
193    #[inline]
194    fn deref(&self) -> &dyn Shape<N> {
195        &*self.0
196    }
197}