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