Skip to content

Commit

Permalink
Implement From translation and rotation for isometries (#15733)
Browse files Browse the repository at this point in the history
# Objective

Several of our APIs (namely gizmos and bounding) use isometries on
current Bevy main. This is nicer than separate properties in a lot of
cases, but users have still expressed usability concerns.

One problem is that in a lot of cases, you only care about e.g.
translation, so you end up with this:

```rust
gizmos.cross_2d(
    Isometry2d::from_translation(Vec2::new(-160.0, 120.0)),
    12.0,
    FUCHSIA,
);
```

The isometry adds quite a lot of length and verbosity, and isn't really
that relevant since only the translation is important here.

It would be nice if you could use the translation directly, and only
supply an isometry if both translation and rotation are needed. This
would make the following possible:

```rust
gizmos.cross_2d(Vec2::new(-160.0, 120.0), 12.0, FUCHSIA);
```

removing a lot of verbosity.

## Solution

Implement `From<Vec2>` and `From<Rot2>` for `Isometry2d`, and
`From<Vec3>`, `From<Vec3A>`, and `From<Quat>` for `Isometry3d`. These
are lossless conversions that fit the semantics of `From`.

This makes the proposed API possible! The methods must now simply take
an `impl Into<IsometryNd>`, and this works:

```rust
gizmos.cross_2d(Vec2::new(-160.0, 120.0), 12.0, FUCHSIA);
```
  • Loading branch information
Jondolf authored Oct 8, 2024
1 parent 8d53c0a commit 21b78b5
Show file tree
Hide file tree
Showing 24 changed files with 430 additions and 344 deletions.
8 changes: 4 additions & 4 deletions crates/bevy_gizmos/src/arcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ where
#[inline]
pub fn arc_2d(
&mut self,
isometry: Isometry2d,
isometry: impl Into<Isometry2d>,
arc_angle: f32,
radius: f32,
color: impl Into<Color>,
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
Arc2dBuilder {
gizmos: self,
isometry,
isometry: isometry.into(),
arc_angle,
radius,
color: color.into(),
Expand Down Expand Up @@ -176,13 +176,13 @@ where
&mut self,
angle: f32,
radius: f32,
isometry: Isometry3d,
isometry: impl Into<Isometry3d>,
color: impl Into<Color>,
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
Arc3dBuilder {
gizmos: self,
start_vertex: Vec3::X,
isometry,
isometry: isometry.into(),
angle,
radius,
color: color.into(),
Expand Down
20 changes: 10 additions & 10 deletions crates/bevy_gizmos/src/circles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ where
#[inline]
pub fn ellipse(
&mut self,
isometry: Isometry3d,
isometry: impl Into<Isometry3d>,
half_size: Vec2,
color: impl Into<Color>,
) -> EllipseBuilder<'_, 'w, 's, Config, Clear> {
EllipseBuilder {
gizmos: self,
isometry,
isometry: isometry.into(),
half_size,
color: color.into(),
resolution: DEFAULT_CIRCLE_RESOLUTION,
Expand Down Expand Up @@ -92,13 +92,13 @@ where
#[inline]
pub fn ellipse_2d(
&mut self,
isometry: Isometry2d,
isometry: impl Into<Isometry2d>,
half_size: Vec2,
color: impl Into<Color>,
) -> Ellipse2dBuilder<'_, 'w, 's, Config, Clear> {
Ellipse2dBuilder {
gizmos: self,
isometry,
isometry: isometry.into(),
half_size,
color: color.into(),
resolution: DEFAULT_CIRCLE_RESOLUTION,
Expand Down Expand Up @@ -131,13 +131,13 @@ where
#[inline]
pub fn circle(
&mut self,
isometry: Isometry3d,
isometry: impl Into<Isometry3d>,
radius: f32,
color: impl Into<Color>,
) -> EllipseBuilder<'_, 'w, 's, Config, Clear> {
EllipseBuilder {
gizmos: self,
isometry,
isometry: isometry.into(),
half_size: Vec2::splat(radius),
color: color.into(),
resolution: DEFAULT_CIRCLE_RESOLUTION,
Expand Down Expand Up @@ -172,13 +172,13 @@ where
#[inline]
pub fn circle_2d(
&mut self,
isometry: Isometry2d,
isometry: impl Into<Isometry2d>,
radius: f32,
color: impl Into<Color>,
) -> Ellipse2dBuilder<'_, 'w, 's, Config, Clear> {
Ellipse2dBuilder {
gizmos: self,
isometry,
isometry: isometry.into(),
half_size: Vec2::splat(radius),
color: color.into(),
resolution: DEFAULT_CIRCLE_RESOLUTION,
Expand Down Expand Up @@ -214,14 +214,14 @@ where
#[inline]
pub fn sphere(
&mut self,
isometry: Isometry3d,
isometry: impl Into<Isometry3d>,
radius: f32,
color: impl Into<Color>,
) -> SphereBuilder<'_, 'w, 's, Config, Clear> {
SphereBuilder {
gizmos: self,
radius,
isometry,
isometry: isometry.into(),
color: color.into(),
resolution: DEFAULT_CIRCLE_RESOLUTION,
}
Expand Down
16 changes: 14 additions & 2 deletions crates/bevy_gizmos/src/cross.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ where
/// }
/// # bevy_ecs::system::assert_is_system(system);
/// ```
pub fn cross(&mut self, isometry: Isometry3d, half_size: f32, color: impl Into<Color>) {
pub fn cross(
&mut self,
isometry: impl Into<Isometry3d>,
half_size: f32,
color: impl Into<Color>,
) {
let isometry = isometry.into();
let color: Color = color.into();
[Vec3::X, Vec3::Y, Vec3::Z]
.map(|axis| axis * half_size)
Expand Down Expand Up @@ -59,7 +65,13 @@ where
/// }
/// # bevy_ecs::system::assert_is_system(system);
/// ```
pub fn cross_2d(&mut self, isometry: Isometry2d, half_size: f32, color: impl Into<Color>) {
pub fn cross_2d(
&mut self,
isometry: impl Into<Isometry2d>,
half_size: f32,
color: impl Into<Color>,
) {
let isometry = isometry.into();
let color: Color = color.into();
[Vec2::X, Vec2::Y]
.map(|axis| axis * half_size)
Expand Down
11 changes: 9 additions & 2 deletions crates/bevy_gizmos/src/gizmos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,11 @@ where
/// # bevy_ecs::system::assert_is_system(system);
/// ```
#[inline]
pub fn rect(&mut self, isometry: Isometry3d, size: Vec2, color: impl Into<Color>) {
pub fn rect(&mut self, isometry: impl Into<Isometry3d>, size: Vec2, color: impl Into<Color>) {
if !self.enabled {
return;
}
let isometry = isometry.into();
let [tl, tr, br, bl] = rect_inner(size).map(|vec2| isometry * vec2.extend(0.));
self.linestrip([tl, tr, br, bl, tl], color);
}
Expand Down Expand Up @@ -709,10 +710,16 @@ where
/// # bevy_ecs::system::assert_is_system(system);
/// ```
#[inline]
pub fn rect_2d(&mut self, isometry: Isometry2d, size: Vec2, color: impl Into<Color>) {
pub fn rect_2d(
&mut self,
isometry: impl Into<Isometry2d>,
size: Vec2,
color: impl Into<Color>,
) {
if !self.enabled {
return;
}
let isometry = isometry.into();
let [tl, tr, br, bl] = rect_inner(size).map(|vec2| isometry * vec2);
self.linestrip_2d([tl, tr, br, bl, tl], color);
}
Expand Down
11 changes: 6 additions & 5 deletions crates/bevy_gizmos/src/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,14 @@ where
/// ```
pub fn grid(
&mut self,
isometry: Isometry3d,
isometry: impl Into<Isometry3d>,
cell_count: UVec2,
spacing: Vec2,
color: impl Into<Color>,
) -> GridBuilder2d<'_, 'w, 's, Config, Clear> {
GridBuilder2d {
gizmos: self,
isometry,
isometry: isometry.into(),
spacing,
cell_count,
skew: Vec2::ZERO,
Expand Down Expand Up @@ -272,14 +272,14 @@ where
/// ```
pub fn grid_3d(
&mut self,
isometry: Isometry3d,
isometry: impl Into<Isometry3d>,
cell_count: UVec3,
spacing: Vec3,
color: impl Into<Color>,
) -> GridBuilder3d<'_, 'w, 's, Config, Clear> {
GridBuilder3d {
gizmos: self,
isometry,
isometry: isometry.into(),
spacing,
cell_count,
skew: Vec3::ZERO,
Expand Down Expand Up @@ -326,11 +326,12 @@ where
/// ```
pub fn grid_2d(
&mut self,
isometry: Isometry2d,
isometry: impl Into<Isometry2d>,
cell_count: UVec2,
spacing: Vec2,
color: impl Into<Color>,
) -> GridBuilder2d<'_, 'w, 's, Config, Clear> {
let isometry = isometry.into();
GridBuilder2d {
gizmos: self,
isometry: Isometry3d::new(
Expand Down
22 changes: 3 additions & 19 deletions crates/bevy_gizmos/src/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,10 @@ fn point_light_gizmo(
) {
let position = transform.translation();
gizmos
.primitive_3d(
&Sphere {
radius: point_light.radius,
},
Isometry3d::from_translation(position),
color,
)
.primitive_3d(&Sphere::new(point_light.radius), position, color)
.resolution(16);
gizmos
.sphere(
Isometry3d::from_translation(position),
point_light.range,
color,
)
.sphere(position, point_light.range, color)
.resolution(32);
}

Expand All @@ -68,13 +58,7 @@ fn spot_light_gizmo(
) {
let (_, rotation, translation) = transform.to_scale_rotation_translation();
gizmos
.primitive_3d(
&Sphere {
radius: spot_light.radius,
},
Isometry3d::from_translation(translation),
color,
)
.primitive_3d(&Sphere::new(spot_light.radius), translation, color)
.resolution(16);

// Offset the tip of the cone to the light position.
Expand Down
Loading

0 comments on commit 21b78b5

Please sign in to comment.