diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index 0b206813fc..dd8f4ca08f 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -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}; @@ -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 { @@ -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`]. /// diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index 0555ec2e76..f0d8901745 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -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; @@ -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`. /// @@ -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 { diff --git a/crates/bevy_transform/src/traits.rs b/crates/bevy_transform/src/traits.rs index f0984272ab..6770ebb9c2 100644 --- a/crates/bevy_transform/src/traits.rs +++ b/crates/bevy_transform/src/traits.rs @@ -1,4 +1,4 @@ -use bevy_math::{Affine3A, Mat4, Vec3}; +use bevy_math::{Affine3A, Isometry3d, Mat4, Vec3}; use crate::prelude::{GlobalTransform, Transform}; @@ -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 { + self.transform_point(point.into()).into() + } +}