From e04eddd8b124aac793dfd5f27943ae8f01b36408 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 30 Jun 2022 17:43:03 +0200 Subject: [PATCH 1/8] Add helper methods for rotating `Transform`s --- .../src/components/transform.rs | 79 +++++++++++++++---- 1 file changed, 65 insertions(+), 14 deletions(-) diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index bbca98e76961d..8b9b4edacd074 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -195,20 +195,81 @@ impl Transform { self.local_z() } - /// Rotates the transform by the given rotation. + /// Rotates this [`Transform`] by the given rotation. #[inline] pub fn rotate(&mut self, rotation: Quat) { - self.rotation = rotation * self.rotation; + self.rotation *= rotation; + } + + /// Rotates this [`Transform`] on the given `axis` by `angle` (in radians). + /// + /// 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)); + } + + /// Rotates this [`Transform`] on the X axis by `angle` (in radians). + /// + /// If this [`Transform`] has a parent, the axis is relative to the rotation of the parent. + #[inline] + pub fn rotate_x(&mut self, angle: f32) { + self.rotate_axis(Vec3::X, angle); + } + + /// Rotates this [`Transform`] on the Y axis by `angle` (in radians). + /// + /// If this [`Transform`] has a parent, the axis is relative to the rotation of the parent. + #[inline] + pub fn rotate_y(&mut self, angle: f32) { + self.rotate_axis(Vec3::Y, angle); + } + + /// Rotates this [`Transform`] on the Z axis by `angle` (in radians). + /// + /// If this [`Transform`] has a parent, the axis is relative to the rotation of the parent. + #[inline] + pub fn rotate_z(&mut self, angle: f32) { + self.rotate_axis(Vec3::Z, angle); + } + + /// Rotates this [`Transform`] on its X axis by `angle` (in radians). + #[inline] + pub fn rotate_local_x(&mut self, angle: f32) { + self.rotate_axis(self.local_x(), angle); + } + + /// Rotates this [`Transform`] on its Y axis by `angle` (in radians). + #[inline] + pub fn rotate_local_y(&mut self, angle: f32) { + self.rotate_axis(self.local_y(), angle); + } + + /// Rotates this [`Transform`] on its Z axis by `angle` (in radians). + #[inline] + pub fn rotate_local_z(&mut self, angle: f32) { + self.rotate_axis(self.local_z(), angle); } - /// Rotates this [`Transform`] around a point in space. - /// If the point is a zero vector, this will rotate around the parent (if any) or the origin. + /// Rotates this [`Transform`] around a `point` in space. + /// + /// If this [`Transform`] has a parent, the `point` is relative to the [`Transform`] of the parent. #[inline] pub fn rotate_around(&mut self, point: Vec3, rotation: Quat) { self.translation = point + rotation * (self.translation - point); self.rotation *= rotation; } + /// Rotates this [`Transform`] so that its local negative z direction is toward + /// `target` and its local y direction is toward `up`. + #[inline] + pub fn look_at(&mut self, target: Vec3, up: Vec3) { + let forward = Vec3::normalize(self.translation - target); + let right = up.cross(forward).normalize(); + let up = forward.cross(right); + self.rotation = Quat::from_mat3(&Mat3::from_cols(right, up, forward)); + } + /// Multiplies `self` with `transform` component by component, returning the /// resulting [`Transform`] #[inline] @@ -239,16 +300,6 @@ impl Transform { pub fn apply_non_uniform_scale(&mut self, scale_factor: Vec3) { self.scale *= scale_factor; } - - /// Rotates this [`Transform`] so that its local z direction is toward - /// `target` and its local y direction is toward `up`. - #[inline] - pub fn look_at(&mut self, target: Vec3, up: Vec3) { - let forward = Vec3::normalize(self.translation - target); - let right = up.cross(forward).normalize(); - let up = forward.cross(right); - self.rotation = Quat::from_mat3(&Mat3::from_cols(right, up, forward)); - } } impl Default for Transform { From 45c57a0cf1cc5692e5df20d37f3d835d38c81c35 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 30 Jun 2022 17:43:33 +0200 Subject: [PATCH 2/8] Update examples --- examples/3d/lighting.rs | 6 +++--- examples/ecs/hierarchy.rs | 4 ++-- examples/games/alien_cake_addict.rs | 2 +- examples/games/contributors.rs | 2 +- examples/stress_tests/many_cubes.rs | 5 +++-- examples/stress_tests/many_foxes.rs | 4 +--- examples/stress_tests/many_lights.rs | 5 +++-- examples/stress_tests/many_sprites.rs | 2 +- examples/tools/scene_viewer.rs | 6 ++++-- examples/transforms/3d_rotation.rs | 17 +++++++---------- 10 files changed, 26 insertions(+), 27 deletions(-) diff --git a/examples/3d/lighting.rs b/examples/3d/lighting.rs index 10fff72614aa5..e8a1a067b7c13 100644 --- a/examples/3d/lighting.rs +++ b/examples/3d/lighting.rs @@ -34,7 +34,7 @@ fn setup( // left wall let mut transform = Transform::from_xyz(2.5, 2.5, 0.0); - transform.rotate(Quat::from_rotation_z(std::f32::consts::FRAC_PI_2)); + transform.rotate_z(std::f32::consts::FRAC_PI_2); commands.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::Box::new(5.0, 0.15, 5.0))), transform, @@ -47,7 +47,7 @@ fn setup( }); // back (right) wall let mut transform = Transform::from_xyz(0.0, 2.5, -2.5); - transform.rotate(Quat::from_rotation_x(std::f32::consts::FRAC_PI_2)); + transform.rotate_x(std::f32::consts::FRAC_PI_2); commands.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::Box::new(5.0, 0.15, 5.0))), transform, @@ -214,7 +214,7 @@ fn animate_light_direction( mut query: Query<&mut Transform, With>, ) { for mut transform in query.iter_mut() { - transform.rotate(Quat::from_rotation_y(time.delta_seconds() * 0.5)); + transform.rotate_y(time.delta_seconds() * 0.5); } } diff --git a/examples/ecs/hierarchy.rs b/examples/ecs/hierarchy.rs index fcb5ee6f7011e..dbd9175079756 100644 --- a/examples/ecs/hierarchy.rs +++ b/examples/ecs/hierarchy.rs @@ -94,14 +94,14 @@ fn rotate( let angle = std::f32::consts::PI / 2.0; for (parent, children) in parents_query.iter_mut() { if let Ok(mut transform) = transform_query.get_mut(parent) { - transform.rotate(Quat::from_rotation_z(-angle * time.delta_seconds())); + transform.rotate_z(-angle * time.delta_seconds()); } // To iterate through the entities children, just treat the Children component as a Vec // Alternatively, you could query entities that have a Parent component for child in children.iter() { if let Ok(mut transform) = transform_query.get_mut(*child) { - transform.rotate(Quat::from_rotation_z(angle * 2.0 * time.delta_seconds())); + transform.rotate_z(angle * 2.0 * time.delta_seconds()); } } diff --git a/examples/games/alien_cake_addict.rs b/examples/games/alien_cake_addict.rs index 24d3d657e2caf..eb53597f36106 100644 --- a/examples/games/alien_cake_addict.rs +++ b/examples/games/alien_cake_addict.rs @@ -348,7 +348,7 @@ fn spawn_bonus( fn rotate_bonus(game: Res, time: Res