Skip to content

Commit b47c30c

Browse files
authored
Expose EllipseColliderShape and RegularPolygonColliderShape (#596)
# Objective Fixes #595. Currently, `EllipseWrapper` and `RegularPolygonWrapper` are not public, so you cannot access their information at runtime for colliders. ## Solution Make them public, and rename them to `EllipseColliderShape` and `RegularPolygonColliderShape` for clarity.
1 parent 5cd89f1 commit b47c30c

File tree

3 files changed

+39
-28
lines changed

3 files changed

+39
-28
lines changed

src/collision/collider/parry/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod primitives2d;
1414
mod primitives3d;
1515

1616
#[cfg(feature = "2d")]
17-
pub(crate) use primitives2d::{EllipseWrapper, RegularPolygonWrapper};
17+
pub use primitives2d::{EllipseColliderShape, RegularPolygonColliderShape};
1818

1919
impl<T: IntoCollider<Collider>> From<T> for Collider {
2020
fn from(value: T) -> Self {
@@ -717,7 +717,7 @@ impl Collider {
717717
/// Creates a collider with an ellipse shape defined by a half-width and half-height.
718718
#[cfg(feature = "2d")]
719719
pub fn ellipse(half_width: Scalar, half_height: Scalar) -> Self {
720-
SharedShape::new(EllipseWrapper(Ellipse::new(
720+
SharedShape::new(EllipseColliderShape(Ellipse::new(
721721
half_width as f32,
722722
half_height as f32,
723723
)))
@@ -1317,7 +1317,7 @@ fn scale_shape(
13171317
Ok(SharedShape::ball(b.radius * scale.x.abs()))
13181318
} else {
13191319
// A 2D circle becomes an ellipse when scaled non-uniformly.
1320-
Ok(SharedShape::new(EllipseWrapper(Ellipse {
1320+
Ok(SharedShape::new(EllipseColliderShape(Ellipse {
13211321
half_size: Vec2::splat(b.radius as f32) * scale.f32().abs(),
13221322
})))
13231323
}
@@ -1467,14 +1467,14 @@ fn scale_shape(
14671467
TypedShape::Custom(_shape) => {
14681468
#[cfg(feature = "2d")]
14691469
{
1470-
if let Some(ellipse) = _shape.as_shape::<EllipseWrapper>() {
1471-
return Ok(SharedShape::new(EllipseWrapper(Ellipse {
1470+
if let Some(ellipse) = _shape.as_shape::<EllipseColliderShape>() {
1471+
return Ok(SharedShape::new(EllipseColliderShape(Ellipse {
14721472
half_size: ellipse.half_size * scale.f32().abs(),
14731473
})));
14741474
}
1475-
if let Some(polygon) = _shape.as_shape::<RegularPolygonWrapper>() {
1475+
if let Some(polygon) = _shape.as_shape::<RegularPolygonColliderShape>() {
14761476
if scale.x == scale.y {
1477-
return Ok(SharedShape::new(RegularPolygonWrapper(
1477+
return Ok(SharedShape::new(RegularPolygonColliderShape(
14781478
RegularPolygon::new(
14791479
polygon.circumradius() * scale.x.abs() as f32,
14801480
polygon.sides,

src/collision/collider/parry/primitives2d.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{math, AdjustPrecision, Scalar, Vector, FRAC_PI_2, PI, TAU};
22

33
use super::{AsF32, Collider, IntoCollider};
4-
use bevy::prelude::Deref;
4+
use bevy::prelude::{Deref, DerefMut};
55
use bevy_math::{bounding::Bounded2d, prelude::*};
66
use nalgebra::{Point2, UnitVector2, Vector2};
77
use parry::{
@@ -25,14 +25,18 @@ impl IntoCollider<Collider> for Circle {
2525

2626
impl IntoCollider<Collider> for Ellipse {
2727
fn collider(&self) -> Collider {
28-
Collider::from(SharedShape::new(EllipseWrapper(*self)))
28+
Collider::from(SharedShape::new(EllipseColliderShape(*self)))
2929
}
3030
}
3131

32-
#[derive(Clone, Copy, Debug, Deref)]
33-
pub(crate) struct EllipseWrapper(pub(crate) Ellipse);
32+
/// An ellipse shape that can be stored in a [`SharedShape`] for an ellipse [`Collider`].
33+
///
34+
/// This wrapper is required to allow implementing the necessary traits from [`parry`]
35+
/// for Bevy's [`Ellipse`] type.
36+
#[derive(Clone, Copy, Debug, Deref, DerefMut)]
37+
pub struct EllipseColliderShape(pub Ellipse);
3438

35-
impl SupportMap for EllipseWrapper {
39+
impl SupportMap for EllipseColliderShape {
3640
#[inline]
3741
fn local_support_point(&self, direction: &Vector2<Scalar>) -> Point2<Scalar> {
3842
let [a, b] = self.half_size.adjust_precision().to_array();
@@ -41,7 +45,7 @@ impl SupportMap for EllipseWrapper {
4145
}
4246
}
4347

44-
impl Shape for EllipseWrapper {
48+
impl Shape for EllipseColliderShape {
4549
fn clone_dyn(&self) -> Box<dyn Shape> {
4650
Box::new(*self)
4751
}
@@ -52,7 +56,7 @@ impl Shape for EllipseWrapper {
5256
_num_subdivisions: u32,
5357
) -> Option<Box<dyn parry::shape::Shape>> {
5458
let half_size = Vector::from(*scale).f32() * self.half_size;
55-
Some(Box::new(EllipseWrapper(Ellipse::new(
59+
Some(Box::new(EllipseColliderShape(Ellipse::new(
5660
half_size.x,
5761
half_size.y,
5862
))))
@@ -131,7 +135,7 @@ impl Shape for EllipseWrapper {
131135
}
132136
}
133137

134-
impl RayCast for EllipseWrapper {
138+
impl RayCast for EllipseColliderShape {
135139
fn cast_local_ray_and_get_normal(
136140
&self,
137141
ray: &parry::query::Ray,
@@ -148,7 +152,7 @@ impl RayCast for EllipseWrapper {
148152
}
149153
}
150154

151-
impl PointQuery for EllipseWrapper {
155+
impl PointQuery for EllipseColliderShape {
152156
fn project_local_point(
153157
&self,
154158
pt: &parry::math::Point<Scalar>,
@@ -239,14 +243,18 @@ impl IntoCollider<Collider> for BoxedPolygon {
239243

240244
impl IntoCollider<Collider> for RegularPolygon {
241245
fn collider(&self) -> Collider {
242-
Collider::from(SharedShape::new(RegularPolygonWrapper(*self)))
246+
Collider::from(SharedShape::new(RegularPolygonColliderShape(*self)))
243247
}
244248
}
245249

246-
#[derive(Clone, Copy, Debug, Deref)]
247-
pub(crate) struct RegularPolygonWrapper(pub(crate) RegularPolygon);
250+
/// A regular polygon shape that can be stored in a [`SharedShape`] for a regular polygon [`Collider`].
251+
///
252+
/// This wrapper is required to allow implementing the necessary traits from [`parry`]
253+
/// for Bevy's [`RegularPolygon`] type.
254+
#[derive(Clone, Copy, Debug, Deref, DerefMut)]
255+
pub struct RegularPolygonColliderShape(pub RegularPolygon);
248256

249-
impl SupportMap for RegularPolygonWrapper {
257+
impl SupportMap for RegularPolygonColliderShape {
250258
#[inline]
251259
fn local_support_point(&self, direction: &Vector2<Scalar>) -> Point2<Scalar> {
252260
// TODO: For polygons with a small number of sides, maybe just iterating
@@ -273,7 +281,7 @@ impl SupportMap for RegularPolygonWrapper {
273281
}
274282
}
275283

276-
impl PolygonalFeatureMap for RegularPolygonWrapper {
284+
impl PolygonalFeatureMap for RegularPolygonColliderShape {
277285
#[inline]
278286
fn local_support_feature(
279287
&self,
@@ -315,7 +323,7 @@ impl PolygonalFeatureMap for RegularPolygonWrapper {
315323
}
316324
}
317325

318-
impl Shape for RegularPolygonWrapper {
326+
impl Shape for RegularPolygonColliderShape {
319327
fn clone_dyn(&self) -> Box<dyn Shape> {
320328
Box::new(*self)
321329
}
@@ -326,7 +334,7 @@ impl Shape for RegularPolygonWrapper {
326334
_num_subdivisions: u32,
327335
) -> Option<Box<dyn parry::shape::Shape>> {
328336
let circumradius = Vector::from(*scale).f32() * self.circumradius();
329-
Some(Box::new(RegularPolygonWrapper(RegularPolygon::new(
337+
Some(Box::new(RegularPolygonColliderShape(RegularPolygon::new(
330338
circumradius.length(),
331339
self.sides,
332340
))))
@@ -437,7 +445,7 @@ impl Shape for RegularPolygonWrapper {
437445
}
438446
}
439447

440-
impl RayCast for RegularPolygonWrapper {
448+
impl RayCast for RegularPolygonColliderShape {
441449
fn cast_local_ray_and_get_normal(
442450
&self,
443451
ray: &parry::query::Ray,
@@ -454,7 +462,7 @@ impl RayCast for RegularPolygonWrapper {
454462
}
455463
}
456464

457-
impl PointQuery for RegularPolygonWrapper {
465+
impl PointQuery for RegularPolygonColliderShape {
458466
fn project_local_point(
459467
&self,
460468
pt: &parry::math::Point<Scalar>,

src/debug_render/gizmos.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,14 +432,17 @@ impl PhysicsGizmoExt for Gizmos<'_, '_, PhysicsGizmos> {
432432
TypedShape::Custom(_id) => {
433433
#[cfg(feature = "2d")]
434434
{
435-
if let Some(ellipse) = collider.shape_scaled().as_shape::<EllipseWrapper>() {
435+
if let Some(ellipse) =
436+
collider.shape_scaled().as_shape::<EllipseColliderShape>()
437+
{
436438
let isometry = Isometry2d::new(
437439
position.f32(),
438440
Rot2::from_sin_cos(rotation.sin as f32, rotation.cos as f32),
439441
);
440442
self.primitive_2d(&ellipse.0, isometry, color);
441-
} else if let Some(polygon) =
442-
collider.shape_scaled().as_shape::<RegularPolygonWrapper>()
443+
} else if let Some(polygon) = collider
444+
.shape_scaled()
445+
.as_shape::<RegularPolygonColliderShape>()
443446
{
444447
let isometry = Isometry2d::new(
445448
position.f32(),

0 commit comments

Comments
 (0)