Fix incorrect rotation in Transform::rotate_around. (#5300)
				
					
				
			Someone noted that the `rotate_around` method did not give the results they expected: [discord thread](https://discord.com/channels/691052431525675048/996497295325544479) I tested `rotate_around` and their workaround and it seems like it was indeed incorrect. Here is a scene with some cubes at different angles all being rotated around the center on the Y axis. https://user-images.githubusercontent.com/29694403/178598432-407d7e80-1caf-4b17-b69b-66d9156c81e1.mp4 Interestingly, the middle cube rotates as you might expect. This threw me for a bit of a loop before I added the other cubes to the test haha. Here is the same scene with the order multiplication of the quaternions flipped in `rotate_around`. https://user-images.githubusercontent.com/29694403/178598446-a98026f3-524c-448b-8437-4d0d3175c6ca.mp4 That looks better :) ## Changelog * Fixed `rotate_around` rotating the wrong way around * Added `translate_around`. - Split out the translation code from `rotate_around`. * Simplified/optimized `rotate_local_*` methods. - Yep, That works somehow. <sup>Quaternions sure are wacky. Do not ask me how this works exactly, haha.</sup> Co-authored-by: devil-ira <justthecooldude@gmail.com>
This commit is contained in:
		
							parent
							
								
									2f9a886c55
								
							
						
					
					
						commit
						56d69c1427
					
				| @ -202,7 +202,7 @@ impl GlobalTransform { | |||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn rotate_around(&mut self, point: Vec3, rotation: Quat) { |     pub fn rotate_around(&mut self, point: Vec3, rotation: Quat) { | ||||||
|         self.translation = point + rotation * (self.translation - point); |         self.translation = point + rotation * (self.translation - point); | ||||||
|         self.rotation *= rotation; |         self.rotate(rotation); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Multiplies `self` with `transform` component by component, returning the
 |     /// Multiplies `self` with `transform` component by component, returning the
 | ||||||
|  | |||||||
| @ -196,6 +196,8 @@ impl Transform { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Rotates this [`Transform`] by the given rotation.
 |     /// Rotates this [`Transform`] by the given rotation.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If this [`Transform`] has a parent, the `rotation` is relative to the rotation of the parent.
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn rotate(&mut self, rotation: Quat) { |     pub fn rotate(&mut self, rotation: Quat) { | ||||||
|         self.rotation = rotation * self.rotation; |         self.rotation = rotation * self.rotation; | ||||||
| @ -233,22 +235,44 @@ impl Transform { | |||||||
|         self.rotate(Quat::from_rotation_z(angle)); |         self.rotate(Quat::from_rotation_z(angle)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Rotates this [`Transform`] around its `X` axis by `angle` (in radians).
 |     /// Rotates this [`Transform`] by the given `rotation`.
 | ||||||
|  |     ///
 | ||||||
|  |     /// The `rotation` is relative to this [`Transform`]'s current rotation.
 | ||||||
|  |     #[inline] | ||||||
|  |     pub fn rotate_local(&mut self, rotation: Quat) { | ||||||
|  |         self.rotation *= rotation; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Rotates this [`Transform`] around its local `axis` by `angle` (in radians).
 | ||||||
|  |     #[inline] | ||||||
|  |     pub fn rotate_local_axis(&mut self, axis: Vec3, angle: f32) { | ||||||
|  |         self.rotate_local(Quat::from_axis_angle(axis, angle)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Rotates this [`Transform`] around its local `X` axis by `angle` (in radians).
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn rotate_local_x(&mut self, angle: f32) { |     pub fn rotate_local_x(&mut self, angle: f32) { | ||||||
|         self.rotate_axis(self.local_x(), angle); |         self.rotate_local(Quat::from_rotation_x(angle)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Rotates this [`Transform`] around its `Y` axis by `angle` (in radians).
 |     /// Rotates this [`Transform`] around its local `Y` axis by `angle` (in radians).
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn rotate_local_y(&mut self, angle: f32) { |     pub fn rotate_local_y(&mut self, angle: f32) { | ||||||
|         self.rotate_axis(self.local_y(), angle); |         self.rotate_local(Quat::from_rotation_y(angle)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Rotates this [`Transform`] around its `Z` axis by `angle` (in radians).
 |     /// Rotates this [`Transform`] around its local `Z` axis by `angle` (in radians).
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn rotate_local_z(&mut self, angle: f32) { |     pub fn rotate_local_z(&mut self, angle: f32) { | ||||||
|         self.rotate_axis(self.local_z(), angle); |         self.rotate_local(Quat::from_rotation_z(angle)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Translates 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 translate_around(&mut self, point: Vec3, rotation: Quat) { | ||||||
|  |         self.translation = point + rotation * (self.translation - point); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Rotates this [`Transform`] around a `point` in space.
 |     /// Rotates this [`Transform`] around a `point` in space.
 | ||||||
| @ -256,8 +280,8 @@ impl Transform { | |||||||
|     /// If this [`Transform`] has a parent, the `point` is relative to the [`Transform`] of the parent.
 |     /// If this [`Transform`] has a parent, the `point` is relative to the [`Transform`] of the parent.
 | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn rotate_around(&mut self, point: Vec3, rotation: Quat) { |     pub fn rotate_around(&mut self, point: Vec3, rotation: Quat) { | ||||||
|         self.translation = point + rotation * (self.translation - point); |         self.translate_around(point, rotation); | ||||||
|         self.rotation *= rotation; |         self.rotate(rotation); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Rotates this [`Transform`] so that its local negative `Z` direction is toward
 |     /// Rotates this [`Transform`] so that its local negative `Z` direction is toward
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 ira
						ira