1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// Queries.
use 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> {
    /// Construct an `Arc` that refers to a uniquely-owned copy of `self`
    fn clone_arc(&self) -> Arc<dyn Shape<N>>;
}

impl<N: RealField, T: 'static + Shape<N> + Clone> ShapeClone<N> for T {
    fn clone_arc(&self) -> Arc<dyn Shape<N>> {
        Arc::new(self.clone())
    }
}

/// Trait implemented by all shapes supported by ncollide.
///
/// This allows dynamic inspection of the shape capabilities.
pub trait Shape<N: RealField>: Send + Sync + Downcast + ShapeClone<N> {
    /// The AABB of `self` transformed by `m`.
    fn aabb(&self, m: &Isometry<N>) -> AABB<N>;

    /// The AABB of `self`.
    #[inline]
    fn local_aabb(&self) -> AABB<N> {
        self.aabb(&Isometry::identity())
    }

    /// The bounding sphere of `self` transformed by `m`.
    #[inline]
    fn bounding_sphere(&self, m: &Isometry<N>) -> BoundingSphere<N> {
        let aabb = self.aabb(m);
        BoundingSphere::new(aabb.center(), aabb.half_extents().norm())
    }

    /// The bounding sphere of `self`.
    #[inline]
    fn local_bounding_sphere(&self) -> BoundingSphere<N> {
        let aabb = self.local_aabb();
        BoundingSphere::new(aabb.center(), aabb.half_extents().norm())
    }

    /// Check if if the feature `_feature` of the `i-th` subshape of `self` transformed by `m` has a tangent
    /// cone that contains `dir` at the point `pt`.
    // NOTE: for the moment, we assume the tangent cone is the same for the whole feature.
    fn tangent_cone_contains_dir(
        &self,
        _feature: FeatureId,
        _m: &Isometry<N>,
        _deformations: Option<&[N]>,
        _dir: &Unit<Vector<N>>,
    ) -> bool;

    /// Returns the id of the subshape containing the specified feature.
    ///
    /// If several subshape contains the same feature, any one is returned.
    fn subshape_containing_feature(&self, _i: FeatureId) -> usize {
        0
    }

    /// The `RayCast` implementation of `self`.
    #[inline]
    fn as_ray_cast(&self) -> Option<&dyn RayCast<N>> {
        None
    }

    /// The `PointQuery` implementation of `self`.
    #[inline]
    fn as_point_query(&self) -> Option<&dyn PointQuery<N>> {
        None
    }

    /// The convex polyhedron representation of `self` if applicable.
    #[inline]
    fn as_convex_polyhedron(&self) -> Option<&dyn ConvexPolyhedron<N>> {
        None
    }

    /// The support mapping of `self` if applicable.
    #[inline]
    fn as_support_map(&self) -> Option<&dyn SupportMap<N>> {
        None
    }

    /// The composite shape representation of `self` if applicable.
    #[inline]
    fn as_composite_shape(&self) -> Option<&dyn CompositeShape<N>> {
        None
    }

    /// The deformable shape representation of `self` if applicable.
    #[inline]
    fn as_deformable_shape(&self) -> Option<&dyn DeformableShape<N>> {
        None
    }

    /// The mutable deformable shape representation of `self` if applicable.
    #[inline]
    fn as_deformable_shape_mut(&mut self) -> Option<&mut dyn DeformableShape<N>> {
        None
    }

    /// Whether `self` uses a convex polyhedron representation.
    #[inline]
    fn is_convex_polyhedron(&self) -> bool {
        self.as_convex_polyhedron().is_some()
    }

    /// Whether `self` uses a support-mapping based representation.
    #[inline]
    fn is_support_map(&self) -> bool {
        self.as_support_map().is_some()
    }

    /// Whether `self` uses a composite shape-based representation.
    #[inline]
    fn is_composite_shape(&self) -> bool {
        self.as_composite_shape().is_some()
    }

    /// Whether `self` uses a composite shape-based representation.
    #[inline]
    fn is_deformable_shape(&self) -> bool {
        self.as_deformable_shape().is_some()
    }
}

impl_downcast!(Shape<N> where N: RealField);

/// Trait for casting shapes to its exact represetation.
impl<N: RealField> dyn Shape<N> {
    /// Tests if this shape has a specific type `T`.
    #[inline]
    pub fn is_shape<T: Shape<N>>(&self) -> bool {
        self.is::<T>()
    }

    /// Performs the cast.
    #[inline]
    pub fn as_shape<T: Shape<N>>(&self) -> Option<&T> {
        self.downcast_ref()
    }
}

/// A shared handle to an abstract shape.
///
/// This can be mutated using COW.
#[derive(Clone)]
pub struct ShapeHandle<N: RealField>(Arc<dyn Shape<N>>);

impl<N: RealField> ShapeHandle<N> {
    /// Creates a sharable shape handle from a shape.
    #[inline]
    pub fn new<S: Shape<N>>(shape: S) -> ShapeHandle<N> {
        ShapeHandle(Arc::new(shape))
    }

    /// Creates a sharable shape handle from a shape trait object.
    pub fn from_arc(shape: Arc<dyn Shape<N>>) -> ShapeHandle<N> {
        ShapeHandle(shape)
    }

    /// Gets a reference the `Arc` refcounted shape object.
    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> AsRef<dyn Shape<N>> for ShapeHandle<N> {
    #[inline]
    fn as_ref(&self) -> &dyn Shape<N> {
        &*self.0
    }
}

impl<N: RealField> Deref for ShapeHandle<N> {
    type Target = dyn Shape<N>;

    #[inline]
    fn deref(&self) -> &dyn Shape<N> {
        &*self.0
    }
}