From d2bf0525153e55a8171d40b56ab8d08053b36280 Mon Sep 17 00:00:00 2001 From: masonk Date: Mon, 15 Jul 2024 11:59:29 -0400 Subject: [PATCH] Clarify GlobalTransform::transform_point (#14292) The existing doc comment for GlobalTransform::transform_point is unclear, or, arguably, incorrect. https://github.com/bevyengine/bevy/discussions/8501 also mentions this. Additionally, a user reading the doc for transform_point might be looking for one of the three other transforms that I mentioned in this doc comment. --------- Co-authored-by: Mason Kramer Co-authored-by: Pascal Hertleif --- .../src/components/global_transform.rs | 51 +++++++++++++++---- .../src/components/transform.rs | 13 ++--- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index a0d2f3ab83..0b206813fc 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -7,23 +7,22 @@ use bevy_math::{Affine3A, Dir3, Mat4, Quat, Vec3, Vec3A}; #[cfg(feature = "bevy-support")] use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -/// Describe the position of an entity relative to the reference frame. +/// [`GlobalTransform`] is an affine transformation from entity-local coordinates to worldspace coordinates. +/// +/// You cannot directly mutate [`GlobalTransform`]; instead, you change an entity's transform by manipulating +/// its [`Transform`], which indirectly causes Bevy to update its [`GlobalTransform`]. /// -/// * To place or move an entity, you should set its [`Transform`]. -/// * [`GlobalTransform`] is fully managed by bevy, you cannot mutate it, use -/// [`Transform`] instead. /// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`]. /// * You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this. /// /// ## [`Transform`] and [`GlobalTransform`] /// -/// [`Transform`] is the position of an entity relative to its parent position, or the reference -/// frame if it doesn't have a [`Parent`](bevy_hierarchy::Parent). +/// [`Transform`] transforms an entity relative to its parent's reference frame, or relative to world space coordinates, +/// if it doesn't have a [`Parent`](bevy_hierarchy::Parent). /// -/// [`GlobalTransform`] is the position of an entity relative to the reference frame. -/// -/// [`GlobalTransform`] is updated from [`Transform`] by systems in the system set +/// [`GlobalTransform`] is managed by Bevy; it is computed by successively applying the [`Transform`] of each ancestor +/// entity which has a Transform. This is done automatically by Bevy-internal systems in the system set /// [`TransformPropagate`](crate::TransformSystem::TransformPropagate). /// /// This system runs during [`PostUpdate`](bevy_app::PostUpdate). If you @@ -189,9 +188,39 @@ impl GlobalTransform { (self.0.matrix3 * extents).length() } - /// Transforms the given `point`, applying shear, scale, rotation and translation. + /// Transforms the given point from local space to global space, applying shear, scale, rotation and translation. /// - /// This moves `point` into the local space of this [`GlobalTransform`]. + /// It can be used like this: + /// + /// ``` + /// # use bevy_transform::prelude::{GlobalTransform}; + /// # use bevy_math::prelude::Vec3; + /// let global_transform = GlobalTransform::from_xyz(1., 2., 3.); + /// let local_point = Vec3::new(1., 2., 3.); + /// let global_point = global_transform.transform_point(local_point); + /// assert_eq!(global_point, Vec3::new(2., 4., 6.)); + /// ``` + /// + /// ``` + /// # use bevy_transform::prelude::{GlobalTransform}; + /// # use bevy_math::Vec3; + /// let global_point = Vec3::new(2., 4., 6.); + /// let global_transform = GlobalTransform::from_xyz(1., 2., 3.); + /// let local_point = global_transform.affine().inverse().transform_point3(global_point); + /// assert_eq!(local_point, Vec3::new(1., 2., 3.)) + /// ``` + /// + /// To apply shear, scale, and rotation *without* applying translation, different functions are available: + /// ``` + /// # use bevy_transform::prelude::{GlobalTransform}; + /// # use bevy_math::prelude::Vec3; + /// let global_transform = GlobalTransform::from_xyz(1., 2., 3.); + /// let local_direction = Vec3::new(1., 2., 3.); + /// let global_direction = global_transform.affine().transform_vector3(local_direction); + /// assert_eq!(global_direction, Vec3::new(1., 2., 3.)); + /// let roundtripped_local_direction = global_transform.affine().inverse().transform_vector3(global_direction); + /// assert_eq!(roundtripped_local_direction, local_direction); + /// ``` #[inline] pub fn transform_point(&self, point: Vec3) -> Vec3 { self.0.transform_point3(point) diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index 980782d14b..0555ec2e76 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -500,14 +500,15 @@ impl Transform { /// Transforms the given `point`, applying scale, rotation and translation. /// - /// If this [`Transform`] has a parent, this will transform a `point` that is - /// relative to the parent's [`Transform`] into one relative to this [`Transform`]. + /// If this [`Transform`] has an ancestor entity with a [`Transform`] component, + /// [`Transform::transform_point`] will transform a point in local space into its + /// parent transform's space. /// - /// If this [`Transform`] does not have a parent, this will transform a `point` - /// that is in global space into one relative to this [`Transform`]. + /// If this [`Transform`] does not have a parent, [`Transform::transform_point`] will + /// transform a point in local space into worldspace coordinates. /// - /// If you want to transform a `point` in global space to the local space of this [`Transform`], - /// consider using [`GlobalTransform::transform_point()`] instead. + /// If you always want to transform a point in local space to worldspace, or if you need + /// the inverse transformations, see [`GlobalTransform::transform_point()`]. #[inline] pub fn transform_point(&self, mut point: Vec3) -> Vec3 { point = self.scale * point;