Skip to content

Commit

Permalink
Make Transform::rotate_axis and Transform::rotate_local_axis use …
Browse files Browse the repository at this point in the history
…`Dir3` (#12986)

# Objective

Related to #12981

Presently, there is a footgun where we allow non-normalized vectors to
be passed in the `axis` parameters of `Transform::rotate_axis` and
`Transform::rotate_local_axis`. These methods invoke
`Quat::from_axis_angle` which expects the vector to be normalized. This
PR aims to address this.

## Solution

Require `Dir3`-valued `axis` parameters for these functions so that the
vector's normalization can be enforced at type-level.

---

## Migration Guide

All calls to `Transform::rotate_axis` and `Transform::rotate_local_axis`
will need to be updated to use a `Dir3` for the `axis` parameter rather
than a `Vec3`. For a general input, this means calling `Dir3::new` and
handling the `Result`, but if the previous vector is already known to be
normalized, `Dir3::new_unchecked` can be called instead. Note that
literals like `Vec3::X` also have corresponding `Dir3` literals; e.g.
`Dir3::X`, `Dir3::NEG_Y` and so on.

---

## Discussion

This axis input is unambigiously a direction instead of a vector, and
that should probably be reflected and enforced by the function
signature. In previous cases where we used, e.g., `impl TryInto<Dir3>`,
the associated methods already implemented (and required!) additional
fall-back logic, since the input is conceptually more complicated than
merely specifying an axis. In this case, I think it's fairly
cut-and-dry, and I'm pretty sure these methods just predate our
direction types.
  • Loading branch information
mweatherley authored Apr 16, 2024
1 parent e3f55d6 commit 221d925
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions crates/bevy_transform/src/components/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ impl Transform {
///
/// If this [`Transform`] has a parent, the `axis` is relative to the rotation of the parent.
#[inline]
pub fn rotate_axis(&mut self, axis: Vec3, angle: f32) {
self.rotate(Quat::from_axis_angle(axis, angle));
pub fn rotate_axis(&mut self, axis: Dir3, angle: f32) {
self.rotate(Quat::from_axis_angle(axis.into(), angle));
}

/// Rotates this [`Transform`] around the `X` axis by `angle` (in radians).
Expand Down Expand Up @@ -327,8 +327,8 @@ impl Transform {

/// Rotates this [`Transform`] around its local `axis` by `angle` (in radians).
#[inline]
pub fn rotate_local_axis(&mut self, axis: Vec3, angle: f32) {
self.rotate_local(Quat::from_axis_angle(axis, angle));
pub fn rotate_local_axis(&mut self, axis: Dir3, angle: f32) {
self.rotate_local(Quat::from_axis_angle(axis.into(), angle));
}

/// Rotates this [`Transform`] around its local `X` axis by `angle` (in radians).
Expand Down

0 comments on commit 221d925

Please sign in to comment.