From b9bad5e157ee2d808f22679b04cfa62227b038b7 Mon Sep 17 00:00:00 2001 From: Jonathan Goren Date: Sun, 17 Mar 2024 10:24:04 +0200 Subject: [PATCH 1/3] use `Dir3` in `Transform::look_to` family --- .../src/components/transform.rs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index ae58c50d850fb..115aae02be67d 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -122,11 +122,11 @@ impl Transform { /// /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases: /// * if `target` is the same as the transform translation, `Vec3::Z` is used instead - /// * if `up` is zero, `Vec3::Y` is used instead + /// * if `up` fails converting to `Dir3`, `Dir3::Y` is used instead /// * if the resulting forward direction is parallel with `up`, an orthogonal vector is used as the "right" direction #[inline] #[must_use] - pub fn looking_at(mut self, target: Vec3, up: Vec3) -> Self { + pub fn looking_at(mut self, target: Vec3, up: impl TryInto) -> Self { self.look_at(target, up); self } @@ -135,12 +135,12 @@ impl Transform { /// points in the given `direction` and [`Transform::up`] points towards `up`. /// /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases: - /// * if `direction` is zero, `Vec3::Z` is used instead - /// * if `up` is zero, `Vec3::Y` is used instead + /// * if `direction` fails converting to `Dir3` (e.g if it is `Vec3::ZERO`), `Dir3::Z` is used instead + /// * if `up` fails converting to `Dir3`, `Dir3::Y` is used instead /// * if `direction` is parallel with `up`, an orthogonal vector is used as the "right" direction #[inline] #[must_use] - pub fn looking_to(mut self, direction: Vec3, up: Vec3) -> Self { + pub fn looking_to(mut self, direction: impl TryInto, up: impl TryInto) -> Self { self.look_to(direction, up); self } @@ -373,10 +373,10 @@ impl Transform { /// /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases: /// * if `target` is the same as the transform translation, `Vec3::Z` is used instead - /// * if `up` is zero, `Vec3::Y` is used instead + /// * if `up` fails converting to `Dir3` (e.g if it is `Vec3::ZERO`), `Dir3::Y` is used instead /// * if the resulting forward direction is parallel with `up`, an orthogonal vector is used as the "right" direction #[inline] - pub fn look_at(&mut self, target: Vec3, up: Vec3) { + pub fn look_at(&mut self, target: Vec3, up: impl TryInto) { self.look_to(target - self.translation, up); } @@ -384,19 +384,19 @@ impl Transform { /// and [`Transform::up`] points towards `up`. /// /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases: - /// * if `direction` is zero, `Vec3::NEG_Z` is used instead - /// * if `up` is zero, `Vec3::Y` is used instead + /// * if `direction` fails converting to `Dir3` (e.g if it is `Vec3::ZERO`), `Dir3::NEG_Z` is used instead + /// * if `up` fails converting to `Dir3`, `Dir3::Y` is used instead /// * if `direction` is parallel with `up`, an orthogonal vector is used as the "right" direction #[inline] - pub fn look_to(&mut self, direction: Vec3, up: Vec3) { - let back = -direction.try_normalize().unwrap_or(Vec3::NEG_Z); - let up = up.try_normalize().unwrap_or(Vec3::Y); + pub fn look_to(&mut self, direction: impl TryInto, up: impl TryInto) { + let back = -direction.try_into().unwrap_or(Dir3::NEG_Z); + let up = up.try_into().unwrap_or(Dir3::Y); let right = up - .cross(back) + .cross(back.into()) .try_normalize() .unwrap_or_else(|| up.any_orthonormal_vector()); let up = back.cross(right); - self.rotation = Quat::from_mat3(&Mat3::from_cols(right, up, back)); + self.rotation = Quat::from_mat3(&Mat3::from_cols(right, up, back.into())); } /// Rotates this [`Transform`] so that the `main_axis` vector, reinterpreted in local coordinates, points From bf981922e976986a37c2fbfb0511ba02f8a847d4 Mon Sep 17 00:00:00 2001 From: Jonathan Goren Date: Sun, 17 Mar 2024 10:37:17 +0200 Subject: [PATCH 2/3] use `Dir3` in `Transform::align,aligned_by` Adjust documentation --- .../src/components/transform.rs | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index 115aae02be67d..b30265a9af81a 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -145,29 +145,29 @@ impl Transform { self } - /// Returns this [`Transform`] with a rotation so that the `handle` vector, reinterpreted in local coordinates, - /// points in the given `direction`, while `weak_handle` points towards `weak_direction`. - /// + /// Rotates this [`Transform`] so that the `main_axis` vector, reinterpreted in local coordinates, points + /// in the given `main_direction`, while `secondary_axis` points towards `secondary_direction`. /// For example, if a spaceship model has its nose pointing in the X-direction in its own local coordinates - /// and its dorsal fin pointing in the Y-direction, then `Transform::aligned_by(Vec3::X, v, Vec3::Y, w)` will - /// make the spaceship's nose point in the direction of `v`, while the dorsal fin does its best to point in the - /// direction `w`. + /// and its dorsal fin pointing in the Y-direction, then `align(Dir3::X, v, Dir3::Y, w)` will make the spaceship's + /// nose point in the direction of `v`, while the dorsal fin does its best to point in the direction `w`. + /// /// /// In some cases a rotation cannot be constructed. Another axis will be picked in those cases: - /// * if `handle` or `direction` is zero, `Vec3::X` takes its place - /// * if `weak_handle` or `weak_direction` is zero, `Vec3::Y` takes its place - /// * if `handle` is parallel with `weak_handle` or `direction` is parallel with `weak_direction`, a rotation is - /// constructed which takes `handle` to `direction` but ignores the weak counterparts (i.e. is otherwise unspecified) + /// * if `main_axis` or `main_direction` fail converting to `Dir3` (e.g are zero), `Dir3::X` takes their place + /// * if `secondary_axis` or `secondary_direction` fail converting, `Dir3::Y` takes their place + /// * if `main_axis` is parallel with `secondary_axis` or `main_direction` is parallel with `secondary_direction`, + /// a rotation is constructed which takes `main_axis` to `main_direction` along a great circle, ignoring the secondary + /// counterparts /// /// See [`Transform::align`] for additional details. #[inline] #[must_use] pub fn aligned_by( mut self, - main_axis: Vec3, - main_direction: Vec3, - secondary_axis: Vec3, - secondary_direction: Vec3, + main_axis: impl TryInto, + main_direction: impl TryInto, + secondary_axis: impl TryInto, + secondary_direction: impl TryInto, ) -> Self { self.align( main_axis, @@ -403,7 +403,7 @@ impl Transform { /// in the given `main_direction`, while `secondary_axis` points towards `secondary_direction`. /// /// For example, if a spaceship model has its nose pointing in the X-direction in its own local coordinates - /// and its dorsal fin pointing in the Y-direction, then `align(Vec3::X, v, Vec3::Y, w)` will make the spaceship's + /// and its dorsal fin pointing in the Y-direction, then `align(Dir3::X, v, Dir3::Y, w)` will make the spaceship's /// nose point in the direction of `v`, while the dorsal fin does its best to point in the direction `w`. /// /// More precisely, the [`Transform::rotation`] produced will be such that: @@ -411,62 +411,62 @@ impl Transform { /// * applying it to `secondary_axis` produces a vector that lies in the half-plane generated by `main_direction` and /// `secondary_direction` (with positive contribution by `secondary_direction`) /// - /// [`Transform::look_to`] is recovered, for instance, when `main_axis` is `Vec3::NEG_Z` (the [`Transform::forward`] - /// direction in the default orientation) and `secondary_axis` is `Vec3::Y` (the [`Transform::up`] direction in the default + /// [`Transform::look_to`] is recovered, for instance, when `main_axis` is `Dir3::NEG_Z` (the [`Transform::forward`] + /// direction in the default orientation) and `secondary_axis` is `Dir3::Y` (the [`Transform::up`] direction in the default /// orientation). (Failure cases may differ somewhat.) /// /// In some cases a rotation cannot be constructed. Another axis will be picked in those cases: - /// * if `main_axis` or `main_direction` is zero, `Vec3::X` takes its place - /// * if `secondary_axis` or `secondary_direction` is zero, `Vec3::Y` takes its place + /// * if `main_axis` or `main_direction` fail converting to `Dir3` (e.g are zero), `Dir3::X` takes their place + /// * if `secondary_axis` or `secondary_direction` fail converting, `Dir3::Y` takes their place /// * if `main_axis` is parallel with `secondary_axis` or `main_direction` is parallel with `secondary_direction`, /// a rotation is constructed which takes `main_axis` to `main_direction` along a great circle, ignoring the secondary /// counterparts /// /// Example /// ``` - /// # use bevy_math::{Vec3, Quat}; + /// # use bevy_math::{Dir3, Vec3, Quat}; /// # use bevy_transform::components::Transform; /// # let mut t1 = Transform::IDENTITY; /// # let mut t2 = Transform::IDENTITY; - /// t1.align(Vec3::X, Vec3::Y, Vec3::new(1., 1., 0.), Vec3::Z); - /// let main_axis_image = t1.rotation * Vec3::X; + /// t1.align(Dir3::X, Dir3::Y, Vec3::new(1., 1., 0.), Dir3::Z); + /// let main_axis_image = t1.rotation * Dir3::X; /// let secondary_axis_image = t1.rotation * Vec3::new(1., 1., 0.); /// assert!(main_axis_image.abs_diff_eq(Vec3::Y, 1e-5)); /// assert!(secondary_axis_image.abs_diff_eq(Vec3::new(0., 1., 1.), 1e-5)); /// - /// t1.align(Vec3::ZERO, Vec3::Z, Vec3::ZERO, Vec3::X); - /// t2.align(Vec3::X, Vec3::Z, Vec3::Y, Vec3::X); + /// t1.align(Vec3::ZERO, Dir3::Z, Vec3::ZERO, Dir3::X); + /// t2.align(Dir3::X, Dir3::Z, Dir3::Y, Dir3::X); /// assert_eq!(t1.rotation, t2.rotation); /// - /// t1.align(Vec3::X, Vec3::Z, Vec3::X, Vec3::Y); + /// t1.align(Dir3::X, Dir3::Z, Dir3::X, Dir3::Y); /// assert_eq!(t1.rotation, Quat::from_rotation_arc(Vec3::X, Vec3::Z)); /// ``` #[inline] pub fn align( &mut self, - main_axis: Vec3, - main_direction: Vec3, - secondary_axis: Vec3, - secondary_direction: Vec3, + main_axis: impl TryInto, + main_direction: impl TryInto, + secondary_axis: impl TryInto, + secondary_direction: impl TryInto, ) { - let main_axis = main_axis.try_normalize().unwrap_or(Vec3::X); - let main_direction = main_direction.try_normalize().unwrap_or(Vec3::X); - let secondary_axis = secondary_axis.try_normalize().unwrap_or(Vec3::Y); - let secondary_direction = secondary_direction.try_normalize().unwrap_or(Vec3::Y); + let main_axis = main_axis.try_into().unwrap_or(Dir3::X); + let main_direction = main_direction.try_into().unwrap_or(Dir3::X); + let secondary_axis = secondary_axis.try_into().unwrap_or(Dir3::Y); + let secondary_direction = secondary_direction.try_into().unwrap_or(Dir3::Y); // The solution quaternion will be constructed in two steps. // First, we start with a rotation that takes `main_axis` to `main_direction`. - let first_rotation = Quat::from_rotation_arc(main_axis, main_direction); + let first_rotation = Quat::from_rotation_arc(main_axis.into(), main_direction.into()); // Let's follow by rotating about the `main_direction` axis so that the image of `secondary_axis` // is taken to something that lies in the plane of `main_direction` and `secondary_direction`. Since // `main_direction` is fixed by this rotation, the first criterion is still satisfied. let secondary_image = first_rotation * secondary_axis; let secondary_image_ortho = secondary_image - .reject_from_normalized(main_direction) + .reject_from_normalized(main_direction.into()) .try_normalize(); let secondary_direction_ortho = secondary_direction - .reject_from_normalized(main_direction) + .reject_from_normalized(main_direction.into()) .try_normalize(); // If one of the two weak vectors was parallel to `main_direction`, then we just do the first part From 1c735b21f7ecb0251f3b5f3cecad829d47190bad Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sun, 17 Mar 2024 12:23:56 -0400 Subject: [PATCH 3/3] Clarify comment Co-authored-by: IQuick 143 --- crates/bevy_transform/src/components/transform.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index b30265a9af81a..9cb4fa9f0f59c 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -122,7 +122,7 @@ impl Transform { /// /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases: /// * if `target` is the same as the transform translation, `Vec3::Z` is used instead - /// * if `up` fails converting to `Dir3`, `Dir3::Y` is used instead + /// * if `up` fails converting to `Dir3` (e.g if it is `Vec3::ZERO`), `Dir3::Y` is used instead /// * if the resulting forward direction is parallel with `up`, an orthogonal vector is used as the "right" direction #[inline] #[must_use]