ncollide3d/shape/
shape.rs
1use 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 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
22pub trait Shape<N: RealField + Copy>: Send + Sync + Downcast + ShapeClone<N> {
26 fn aabb(&self, m: &Isometry<N>) -> AABB<N>;
28
29 #[inline]
31 fn local_aabb(&self) -> AABB<N> {
32 self.aabb(&Isometry::identity())
33 }
34
35 #[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 #[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 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 fn subshape_containing_feature(&self, _i: FeatureId) -> usize {
64 0
65 }
66
67 #[inline]
69 fn as_ray_cast(&self) -> Option<&dyn RayCast<N>> {
70 None
71 }
72
73 #[inline]
75 fn as_point_query(&self) -> Option<&dyn PointQuery<N>> {
76 None
77 }
78
79 #[inline]
81 fn as_convex_polyhedron(&self) -> Option<&dyn ConvexPolyhedron<N>> {
82 None
83 }
84
85 #[inline]
87 fn as_support_map(&self) -> Option<&dyn SupportMap<N>> {
88 None
89 }
90
91 #[inline]
93 fn as_composite_shape(&self) -> Option<&dyn CompositeShape<N>> {
94 None
95 }
96
97 #[inline]
99 fn as_deformable_shape(&self) -> Option<&dyn DeformableShape<N>> {
100 None
101 }
102
103 #[inline]
105 fn as_deformable_shape_mut(&mut self) -> Option<&mut dyn DeformableShape<N>> {
106 None
107 }
108
109 #[inline]
111 fn is_convex_polyhedron(&self) -> bool {
112 self.as_convex_polyhedron().is_some()
113 }
114
115 #[inline]
117 fn is_support_map(&self) -> bool {
118 self.as_support_map().is_some()
119 }
120
121 #[inline]
123 fn is_composite_shape(&self) -> bool {
124 self.as_composite_shape().is_some()
125 }
126
127 #[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
136impl<N: RealField + Copy> dyn Shape<N> {
138 #[inline]
140 pub fn is_shape<T: Shape<N>>(&self) -> bool {
141 self.is::<T>()
142 }
143
144 #[inline]
146 pub fn as_shape<T: Shape<N>>(&self) -> Option<&T> {
147 self.downcast_ref()
148 }
149}
150
151#[derive(Clone)]
155pub struct ShapeHandle<N: RealField + Copy>(Arc<dyn Shape<N>>);
156
157impl<N: RealField + Copy> ShapeHandle<N> {
158 #[inline]
160 pub fn new<S: Shape<N>>(shape: S) -> ShapeHandle<N> {
161 ShapeHandle(Arc::new(shape))
162 }
163
164 pub fn from_arc(shape: Arc<dyn Shape<N>>) -> ShapeHandle<N> {
166 ShapeHandle(shape)
167 }
168
169 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}