1use std::fmt;
2
3use super::*;
4use crate::math::Vect;
5use rapier::geometry::{RoundShape, Shape, SharedShape};
6use rapier::parry::either::Either;
7use rapier::parry::shape::TypedShape;
8
9#[cfg(doc)]
10use rapier::parry;
11
12#[derive(Copy, Clone)]
14pub enum ColliderView<'a> {
15 Ball(BallView<'a>),
17 Cuboid(CuboidView<'a>),
19 Capsule(CapsuleView<'a>),
21 Segment(SegmentView<'a>),
23 Triangle(TriangleView<'a>),
25 Voxels(VoxelsView<'a>),
27 TriMesh(TriMeshView<'a>),
29 Polyline(PolylineView<'a>),
31 HalfSpace(HalfSpaceView<'a>),
33 HeightField(HeightFieldView<'a>),
35 Compound(CompoundView<'a>),
37 #[cfg(feature = "dim2")]
39 ConvexPolygon(ConvexPolygonView<'a>),
40 #[cfg(feature = "dim3")]
42 ConvexPolyhedron(ConvexPolyhedronView<'a>),
43 #[cfg(feature = "dim3")]
44 Cylinder(CylinderView<'a>),
46 #[cfg(feature = "dim3")]
47 Cone(ConeView<'a>),
49 RoundCuboid(RoundCuboidView<'a>),
51 RoundTriangle(RoundTriangleView<'a>),
53 #[cfg(feature = "dim3")]
59 RoundCylinder(RoundCylinderView<'a>),
60 #[cfg(feature = "dim3")]
62 RoundCone(RoundConeView<'a>),
63 #[cfg(feature = "dim3")]
65 RoundConvexPolyhedron(RoundConvexPolyhedronView<'a>),
66 #[cfg(feature = "dim2")]
68 RoundConvexPolygon(RoundConvexPolygonView<'a>),
69 Custom(&'a dyn Shape),
71}
72impl fmt::Debug for ColliderView<'_> {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 match self {
75 ColliderView::Ball(view) => write!(f, "{:?}", view.raw),
76 ColliderView::Cuboid(view) => write!(f, "{:?}", view.raw),
77 ColliderView::Capsule(view) => write!(f, "{:?}", view.raw),
78 ColliderView::Segment(view) => write!(f, "{:?}", view.raw),
79 ColliderView::Triangle(view) => write!(f, "{:?}", view.raw),
80 ColliderView::Voxels(view) => write!(f, "{:?}", view.raw),
81 ColliderView::TriMesh(_) => write!(f, "Trimesh (not representable)"),
82 ColliderView::Polyline(_) => write!(f, "Polyline (not representable)"),
83 ColliderView::HalfSpace(view) => write!(f, "{:?}", view.raw),
84 ColliderView::HeightField(view) => write!(f, "{:?}", view.raw),
85 ColliderView::Compound(_) => write!(f, "Compound (not representable)"),
86 #[cfg(feature = "dim2")]
87 ColliderView::ConvexPolygon(view) => write!(f, "{:?}", view.raw),
88 #[cfg(feature = "dim3")]
89 ColliderView::ConvexPolyhedron(view) => write!(f, "{:?}", view.raw),
90 #[cfg(feature = "dim3")]
91 ColliderView::Cylinder(view) => write!(f, "{:?}", view.raw),
92 #[cfg(feature = "dim3")]
93 ColliderView::Cone(view) => write!(f, "{:?}", view.raw),
94 ColliderView::RoundCuboid(view) => write!(f, "{:?}", view.raw),
95 ColliderView::RoundTriangle(view) => write!(f, "{:?}", view.raw),
96 #[cfg(feature = "dim3")]
97 ColliderView::RoundCylinder(view) => write!(f, "{:?}", view.raw),
98 #[cfg(feature = "dim3")]
99 ColliderView::RoundCone(view) => write!(f, "{:?}", view.raw),
100 #[cfg(feature = "dim3")]
101 ColliderView::RoundConvexPolyhedron(view) => write!(f, "{:?}", view.raw),
102 #[cfg(feature = "dim2")]
103 ColliderView::RoundConvexPolygon(view) => write!(f, "{:?}", view.raw),
104 ColliderView::Custom(_) => write!(f, "Custom (not representable)"),
105 }
106 }
107}
108
109impl<'a> From<TypedShape<'a>> for ColliderView<'a> {
110 fn from(typed_shape: TypedShape<'a>) -> ColliderView<'a> {
111 match typed_shape {
112 TypedShape::Ball(s) => ColliderView::Ball(BallView { raw: s }),
113 TypedShape::Cuboid(s) => ColliderView::Cuboid(CuboidView { raw: s }),
114 TypedShape::Capsule(s) => ColliderView::Capsule(CapsuleView { raw: s }),
115 TypedShape::Segment(s) => ColliderView::Segment(SegmentView { raw: s }),
116 TypedShape::Triangle(s) => ColliderView::Triangle(TriangleView { raw: s }),
117 TypedShape::Voxels(s) => ColliderView::Voxels(VoxelsView { raw: s }),
118 TypedShape::TriMesh(s) => ColliderView::TriMesh(TriMeshView { raw: s }),
119 TypedShape::Polyline(s) => ColliderView::Polyline(PolylineView { raw: s }),
120 TypedShape::HalfSpace(s) => ColliderView::HalfSpace(HalfSpaceView { raw: s }),
121 TypedShape::HeightField(s) => ColliderView::HeightField(HeightFieldView { raw: s }),
122 TypedShape::Compound(s) => ColliderView::Compound(CompoundView { raw: s }),
123 #[cfg(feature = "dim2")]
124 TypedShape::ConvexPolygon(s) => {
125 ColliderView::ConvexPolygon(ConvexPolygonView { raw: s })
126 }
127 #[cfg(feature = "dim3")]
128 TypedShape::ConvexPolyhedron(s) => {
129 ColliderView::ConvexPolyhedron(ConvexPolyhedronView { raw: s })
130 }
131 #[cfg(feature = "dim3")]
132 TypedShape::Cylinder(s) => ColliderView::Cylinder(CylinderView { raw: s }),
133 #[cfg(feature = "dim3")]
134 TypedShape::Cone(s) => ColliderView::Cone(ConeView { raw: s }),
135 TypedShape::RoundCuboid(s) => ColliderView::RoundCuboid(RoundCuboidView { raw: s }),
136 TypedShape::RoundTriangle(s) => {
137 ColliderView::RoundTriangle(RoundTriangleView { raw: s })
138 }
139 #[cfg(feature = "dim2")]
140 TypedShape::RoundConvexPolygon(s) => {
141 ColliderView::RoundConvexPolygon(RoundConvexPolygonView { raw: s })
142 }
143 #[cfg(feature = "dim3")]
144 TypedShape::RoundCylinder(s) => {
145 ColliderView::RoundCylinder(RoundCylinderView { raw: s })
146 }
147 #[cfg(feature = "dim3")]
148 TypedShape::RoundCone(s) => ColliderView::RoundCone(RoundConeView { raw: s }),
149 #[cfg(feature = "dim3")]
150 TypedShape::RoundConvexPolyhedron(s) => {
151 ColliderView::RoundConvexPolyhedron(RoundConvexPolyhedronView { raw: s })
152 }
153 TypedShape::Custom(s) => ColliderView::Custom(s),
154 }
155 }
156}
157
158impl<'a> From<ColliderView<'a>> for TypedShape<'a> {
159 fn from(collider_view: ColliderView<'a>) -> TypedShape<'a> {
160 collider_view.as_typed_shape()
161 }
162}
163
164impl<'a> From<ColliderView<'a>> for SharedShape {
165 fn from(collider_view: ColliderView<'a>) -> SharedShape {
166 collider_view.to_shared_shape()
167 }
168}
169
170impl<'a> ColliderView<'a> {
171 pub fn as_typed_shape(self) -> TypedShape<'a> {
173 match self {
174 ColliderView::Ball(BallView { raw: s }) => TypedShape::Ball(s),
175 ColliderView::Cuboid(CuboidView { raw: s }) => TypedShape::Cuboid(s),
176 ColliderView::Capsule(CapsuleView { raw: s }) => TypedShape::Capsule(s),
177 ColliderView::Segment(SegmentView { raw: s }) => TypedShape::Segment(s),
178 ColliderView::Triangle(TriangleView { raw: s }) => TypedShape::Triangle(s),
179 ColliderView::Voxels(VoxelsView { raw: s }) => TypedShape::Voxels(s),
180 ColliderView::TriMesh(TriMeshView { raw: s }) => TypedShape::TriMesh(s),
181 ColliderView::Polyline(PolylineView { raw: s }) => TypedShape::Polyline(s),
182 ColliderView::HalfSpace(HalfSpaceView { raw: s }) => TypedShape::HalfSpace(s),
183 ColliderView::HeightField(HeightFieldView { raw: s }) => TypedShape::HeightField(s),
184 ColliderView::Compound(CompoundView { raw: s }) => TypedShape::Compound(s),
185 #[cfg(feature = "dim2")]
186 ColliderView::ConvexPolygon(ConvexPolygonView { raw: s }) => {
187 TypedShape::ConvexPolygon(s)
188 }
189 #[cfg(feature = "dim3")]
190 ColliderView::ConvexPolyhedron(ConvexPolyhedronView { raw: s }) => {
191 TypedShape::ConvexPolyhedron(s)
192 }
193 #[cfg(feature = "dim3")]
194 ColliderView::Cylinder(CylinderView { raw: s }) => TypedShape::Cylinder(s),
195 #[cfg(feature = "dim3")]
196 ColliderView::Cone(ConeView { raw: s }) => TypedShape::Cone(s),
197 ColliderView::RoundCuboid(RoundCuboidView { raw: s }) => TypedShape::RoundCuboid(s),
198 ColliderView::RoundTriangle(RoundTriangleView { raw: s }) => {
199 TypedShape::RoundTriangle(s)
200 }
201 #[cfg(feature = "dim2")]
202 ColliderView::RoundConvexPolygon(RoundConvexPolygonView { raw: s }) => {
203 TypedShape::RoundConvexPolygon(s)
204 }
205 #[cfg(feature = "dim3")]
206 ColliderView::RoundCylinder(RoundCylinderView { raw: s }) => {
207 TypedShape::RoundCylinder(s)
208 }
209 #[cfg(feature = "dim3")]
210 ColliderView::RoundCone(RoundConeView { raw: s }) => TypedShape::RoundCone(s),
211 #[cfg(feature = "dim3")]
212 ColliderView::RoundConvexPolyhedron(RoundConvexPolyhedronView { raw: s }) => {
213 TypedShape::RoundConvexPolyhedron(s)
214 }
215 ColliderView::Custom(s) => TypedShape::Custom(s),
216 }
217 }
218
219 pub fn to_shared_shape(self) -> SharedShape {
221 match self {
222 ColliderView::Ball(BallView { raw }) => SharedShape::new(*raw),
223 ColliderView::Cuboid(CuboidView { raw }) => SharedShape::new(*raw),
224 ColliderView::Capsule(CapsuleView { raw }) => SharedShape::new(*raw),
225 ColliderView::Segment(SegmentView { raw }) => SharedShape::new(*raw),
226 ColliderView::Triangle(TriangleView { raw }) => SharedShape::new(*raw),
227 ColliderView::Voxels(VoxelsView { raw }) => SharedShape::new(raw.clone()),
228 ColliderView::TriMesh(TriMeshView { raw }) => SharedShape::new(raw.clone()),
229 ColliderView::Polyline(PolylineView { raw }) => SharedShape::new(raw.clone()),
230 ColliderView::HalfSpace(HalfSpaceView { raw }) => SharedShape::new(*raw),
231 ColliderView::HeightField(HeightFieldView { raw }) => SharedShape::new(raw.clone()),
232 ColliderView::Compound(CompoundView { raw }) => SharedShape::new(raw.clone()),
233 #[cfg(feature = "dim2")]
234 ColliderView::ConvexPolygon(ConvexPolygonView { raw }) => SharedShape::new(raw.clone()),
235 #[cfg(feature = "dim3")]
236 ColliderView::ConvexPolyhedron(ConvexPolyhedronView { raw }) => {
237 SharedShape::new(raw.clone())
238 }
239 #[cfg(feature = "dim3")]
240 ColliderView::Cylinder(CylinderView { raw }) => SharedShape::new(*raw),
241 #[cfg(feature = "dim3")]
242 ColliderView::Cone(ConeView { raw }) => SharedShape::new(*raw),
243 ColliderView::RoundCuboid(RoundCuboidView { raw }) => SharedShape::new(*raw),
244 ColliderView::RoundTriangle(RoundTriangleView { raw }) => SharedShape::new(*raw),
245 #[cfg(feature = "dim2")]
246 ColliderView::RoundConvexPolygon(RoundConvexPolygonView { raw }) => {
247 SharedShape::new(raw.clone())
248 }
249 #[cfg(feature = "dim3")]
250 ColliderView::RoundCylinder(RoundCylinderView { raw }) => SharedShape::new(*raw),
251 #[cfg(feature = "dim3")]
252 ColliderView::RoundCone(RoundConeView { raw }) => SharedShape::new(*raw),
253 #[cfg(feature = "dim3")]
254 ColliderView::RoundConvexPolyhedron(RoundConvexPolyhedronView { raw }) => {
255 SharedShape::new(raw.clone())
256 }
257 ColliderView::Custom(raw) => SharedShape(raw.clone_dyn().into()),
258 }
259 }
260
261 pub fn raw_scale_by(&self, scale: Vect, num_subdivisions: u32) -> Option<SharedShape> {
263 let result = match self {
264 ColliderView::Cuboid(s) => SharedShape::new(s.raw.scaled(scale)),
265 ColliderView::RoundCuboid(s) => SharedShape::new(RoundShape {
266 border_radius: s.raw.border_radius,
267 inner_shape: s.raw.inner_shape.scaled(scale),
268 }),
269 ColliderView::Capsule(c) => match c.raw.scaled(scale, num_subdivisions) {
270 None => {
271 log::error!("Failed to apply scale {scale} to Capsule shape.");
272 SharedShape::ball(0.0)
273 }
274 Some(Either::Left(b)) => SharedShape::new(b),
275 Some(Either::Right(b)) => SharedShape::new(b),
276 },
277 ColliderView::Ball(b) => match b.raw.scaled(scale, num_subdivisions) {
278 None => {
279 log::error!("Failed to apply scale {scale} to Ball shape.");
280 SharedShape::ball(0.0)
281 }
282 Some(Either::Left(b)) => SharedShape::new(b),
283 Some(Either::Right(b)) => SharedShape::new(b),
284 },
285 ColliderView::Segment(s) => SharedShape::new(s.raw.scaled(scale)),
286 ColliderView::Triangle(t) => SharedShape::new(t.raw.scaled(scale)),
287 ColliderView::Voxels(cp) => SharedShape::new(cp.raw.clone().scaled(scale)),
288 ColliderView::RoundTriangle(t) => SharedShape::new(RoundShape {
289 border_radius: t.raw.border_radius,
290 inner_shape: t.raw.inner_shape.scaled(scale),
291 }),
292 ColliderView::TriMesh(t) => SharedShape::new(t.raw.clone().scaled(scale)),
293 ColliderView::Polyline(p) => SharedShape::new(p.raw.clone().scaled(scale)),
294 ColliderView::HalfSpace(h) => match h.raw.scaled(scale) {
295 None => {
296 log::error!("Failed to apply scale {scale} to HalfSpace shape.");
297 SharedShape::ball(0.0)
298 }
299 Some(scaled) => SharedShape::new(scaled),
300 },
301 ColliderView::HeightField(h) => SharedShape::new(h.raw.clone().scaled(scale)),
302 #[cfg(feature = "dim2")]
303 ColliderView::ConvexPolygon(cp) => match cp.raw.clone().scaled(scale) {
304 None => {
305 log::error!("Failed to apply scale {scale} to ConvexPolygon shape.");
306 SharedShape::ball(0.0)
307 }
308 Some(scaled) => SharedShape::new(scaled),
309 },
310 #[cfg(feature = "dim2")]
311 ColliderView::RoundConvexPolygon(cp) => {
312 match cp.raw.inner_shape.clone().scaled(scale) {
313 None => {
314 log::error!("Failed to apply scale {scale} to RoundConvexPolygon shape.");
315 SharedShape::ball(0.0)
316 }
317 Some(scaled) => SharedShape::new(RoundShape {
318 border_radius: cp.raw.border_radius,
319 inner_shape: scaled,
320 }),
321 }
322 }
323 #[cfg(feature = "dim3")]
324 ColliderView::ConvexPolyhedron(cp) => match cp.raw.clone().scaled(scale) {
325 None => {
326 log::error!("Failed to apply scale {scale} to ConvexPolyhedron shape.");
327 SharedShape::ball(0.0)
328 }
329 Some(scaled) => SharedShape::new(scaled),
330 },
331 #[cfg(feature = "dim3")]
332 ColliderView::RoundConvexPolyhedron(cp) => {
333 match cp.raw.clone().inner_shape.scaled(scale) {
334 None => {
335 log::error!(
336 "Failed to apply scale {scale} to RoundConvexPolyhedron shape."
337 );
338 SharedShape::ball(0.0)
339 }
340 Some(scaled) => SharedShape::new(RoundShape {
341 border_radius: cp.raw.border_radius,
342 inner_shape: scaled,
343 }),
344 }
345 }
346 #[cfg(feature = "dim3")]
347 ColliderView::Cylinder(c) => match c.raw.scaled(scale, num_subdivisions) {
348 None => {
349 log::error!("Failed to apply scale {scale} to Cylinder shape.");
350 SharedShape::ball(0.0)
351 }
352 Some(Either::Left(b)) => SharedShape::new(b),
353 Some(Either::Right(b)) => SharedShape::new(b),
354 },
355 #[cfg(feature = "dim3")]
356 ColliderView::RoundCylinder(c) => {
357 match c.raw.inner_shape.scaled(scale, num_subdivisions) {
358 None => {
359 log::error!("Failed to apply scale {scale} to RoundCylinder shape.");
360 SharedShape::ball(0.0)
361 }
362 Some(Either::Left(scaled)) => SharedShape::new(RoundShape {
363 border_radius: c.raw.border_radius,
364 inner_shape: scaled,
365 }),
366 Some(Either::Right(scaled)) => SharedShape::new(RoundShape {
367 border_radius: c.raw.border_radius,
368 inner_shape: scaled,
369 }),
370 }
371 }
372 #[cfg(feature = "dim3")]
373 ColliderView::Cone(c) => match c.raw.scaled(scale, num_subdivisions) {
374 None => {
375 log::error!("Failed to apply scale {scale} to Cone shape.");
376 SharedShape::ball(0.0)
377 }
378 Some(Either::Left(b)) => SharedShape::new(b),
379 Some(Either::Right(b)) => SharedShape::new(b),
380 },
381 #[cfg(feature = "dim3")]
382 ColliderView::RoundCone(c) => match c.raw.inner_shape.scaled(scale, num_subdivisions) {
383 None => {
384 log::error!("Failed to apply scale {scale} to RoundCone shape.");
385 SharedShape::ball(0.0)
386 }
387 Some(Either::Left(scaled)) => SharedShape::new(RoundShape {
388 border_radius: c.raw.border_radius,
389 inner_shape: scaled,
390 }),
391 Some(Either::Right(scaled)) => SharedShape::new(RoundShape {
392 border_radius: c.raw.border_radius,
393 inner_shape: scaled,
394 }),
395 },
396 ColliderView::Compound(c) => {
397 let mut scaled = Vec::with_capacity(c.shapes().len());
398
399 for (tra, rot, shape) in c.shapes() {
400 scaled.push((
401 crate::utils::pose_from(tra * scale, rot),
402 shape.raw_scale_by(scale, num_subdivisions)?,
403 ));
404 }
405 SharedShape::compound(scaled)
406 }
407 ColliderView::Custom(s) => SharedShape(s.scale_dyn(scale, num_subdivisions)?.into()),
408 };
409
410 Some(result)
411 }
412}