From f584e729537262cb0166586933396763f353784d Mon Sep 17 00:00:00 2001 From: James Beilby Date: Fri, 4 Feb 2022 02:09:24 +0000 Subject: [PATCH] Add Transform::rotate_around method (#3107) # Objective - Missing obvious way to rotate a transform around a point. This is popularly used for rotation of an object in world space ("orbiting" a point), or for local rotation of an object around a pivot point on that object. - Present in other (not to be named) game engines - Was question from user on Discord today (thread "object rotation") ## Solution - Added Transform::rotate_around method where point is specified in reference frame of the parent (if any) or in world space. --- .../src/components/global_transform.rs | 7 +++++++ crates/bevy_transform/src/components/transform.rs | 12 ++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index 7b66f7defc509..dd163cc2f5570 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -196,6 +196,13 @@ impl GlobalTransform { self.rotation = rotation * self.rotation; } + #[doc(hidden)] + #[inline] + pub fn rotate_around(&mut self, point: Vec3, rotation: Quat) { + self.translation = point + rotation * (self.translation - point); + self.rotation *= rotation; + } + /// Multiplies `self` with `transform` component by component, returning the /// resulting [`GlobalTransform`] #[inline] diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index 225690155406f..c9b5ec52a1cfa 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -205,6 +205,14 @@ impl Transform { self.rotation = rotation * self.rotation; } + /// 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. + #[inline] + pub fn rotate_around(&mut self, point: Vec3, rotation: Quat) { + self.translation = point + rotation * (self.translation - point); + self.rotation *= rotation; + } + /// Multiplies `self` with `transform` component by component, returning the /// resulting [`Transform`] #[inline] @@ -235,8 +243,8 @@ impl Transform { self.scale *= scale_factor; } - /// Rotates this [`Transform`] so that its unit vector in the local z direction is toward - /// `target` and its unit vector in the local y direction is toward `up`. + /// 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);