Skip to content

Commit

Permalink
Conversions for Isometry3d ⟷ Transform/GlobalTransform (#14478)
Browse files Browse the repository at this point in the history
# Objective

Allow interoperation between `Isometry3d` and the transform types from
bevy_transform. At least in the short term, the primary goal is to allow
the extraction of isometries from transform components by users.

## Solution

- Add explicit `from_isometry`/`to_isometry` methods to `Transform`.
- Add explicit `from_isometry`/`to_isometry` methods to
`GlobalTransform`. The former is hidden (primarily for internal use),
and the latter has the caveats originating in
[`Affine3A::to_scale_rotation_translation`](https://docs.rs/glam/latest/glam/f32/struct.Affine3A.html#method.to_scale_rotation_translation).
- Implement the `TransformPoint` trait for `Isometry3d`.
  • Loading branch information
mweatherley authored Jul 25, 2024
1 parent e7e10f2 commit 5aa998d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
21 changes: 20 additions & 1 deletion crates/bevy_transform/src/components/global_transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::ops::Mul;
use super::Transform;
#[cfg(feature = "bevy-support")]
use bevy_ecs::{component::Component, reflect::ReflectComponent};
use bevy_math::{Affine3A, Dir3, Mat4, Quat, Vec3, Vec3A};
use bevy_math::{Affine3A, Dir3, Isometry3d, Mat4, Quat, Vec3, Vec3A};
#[cfg(feature = "bevy-support")]
use bevy_reflect::{std_traits::ReflectDefault, Reflect};

Expand Down Expand Up @@ -87,6 +87,12 @@ impl GlobalTransform {
GlobalTransform(Affine3A::from_scale(scale))
}

#[doc(hidden)]
#[inline]
pub fn from_isometry(iso: Isometry3d) -> Self {
Self(iso.into())
}

/// Returns the 3d affine transformation matrix as a [`Mat4`].
#[inline]
pub fn compute_matrix(&self) -> Mat4 {
Expand All @@ -113,6 +119,19 @@ impl GlobalTransform {
}
}

/// Returns the isometric part of the transformation as an [isometry]. Any scaling done by the
/// transformation will be ignored.
///
/// The transform is expected to be non-degenerate and without shearing, or the output
/// will be invalid.
///
/// [isometry]: Isometry3d
#[inline]
pub fn to_isometry(&self) -> Isometry3d {
let (_, rotation, translation) = self.0.to_scale_rotation_translation();
Isometry3d::new(translation, rotation)
}

/// Returns the [`Transform`] `self` would have if it was a child of an entity
/// with the `parent` [`GlobalTransform`].
///
Expand Down
22 changes: 21 additions & 1 deletion crates/bevy_transform/src/components/transform.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::GlobalTransform;
#[cfg(feature = "bevy-support")]
use bevy_ecs::{component::Component, reflect::ReflectComponent};
use bevy_math::{Affine3A, Dir3, Mat3, Mat4, Quat, Vec3};
use bevy_math::{Affine3A, Dir3, Isometry3d, Mat3, Mat4, Quat, Vec3};
#[cfg(feature = "bevy-support")]
use bevy_reflect::{prelude::*, Reflect};
use std::ops::Mul;
Expand Down Expand Up @@ -120,6 +120,18 @@ impl Transform {
}
}

/// Creates a new [`Transform`] that is equivalent to the given [isometry].
///
/// [isometry]: Isometry3d
#[inline]
pub fn from_isometry(iso: Isometry3d) -> Self {
Transform {
translation: iso.translation.into(),
rotation: iso.rotation,
..Self::IDENTITY
}
}

/// Returns this [`Transform`] with a new rotation so that [`Transform::forward`]
/// points towards the `target` position and [`Transform::up`] points towards `up`.
///
Expand Down Expand Up @@ -525,6 +537,14 @@ impl Transform {
pub fn is_finite(&self) -> bool {
self.translation.is_finite() && self.rotation.is_finite() && self.scale.is_finite()
}

/// Get the [isometry] defined by this transform's rotation and translation, ignoring scale.
///
/// [isometry]: Isometry3d
#[inline]
pub fn to_isometry(&self) -> Isometry3d {
Isometry3d::new(self.translation, self.rotation)
}
}

impl Default for Transform {
Expand Down
9 changes: 8 additions & 1 deletion crates/bevy_transform/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy_math::{Affine3A, Mat4, Vec3};
use bevy_math::{Affine3A, Isometry3d, Mat4, Vec3};

use crate::prelude::{GlobalTransform, Transform};

Expand Down Expand Up @@ -35,3 +35,10 @@ impl TransformPoint for Affine3A {
self.transform_point3(point.into())
}
}

impl TransformPoint for Isometry3d {
#[inline]
fn transform_point(&self, point: impl Into<Vec3>) -> Vec3 {
self.transform_point(point.into()).into()
}
}

0 comments on commit 5aa998d

Please sign in to comment.