Fix look_to resulting in NaN rotations (#7817)
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Liam Gallagher <ljpgallagher@xtra.co.nz>
This commit is contained in:
parent
1d4910a1e3
commit
b6b549e3ff
@ -120,6 +120,11 @@ impl Transform {
|
||||
|
||||
/// Returns this [`Transform`] with a new rotation so that [`Transform::forward`]
|
||||
/// points towards the `target` position 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 `target` is the same as the transform translation, `Vec3::Z` is used instead
|
||||
/// * if `up` is zero, `Vec3::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 {
|
||||
@ -129,6 +134,11 @@ impl Transform {
|
||||
|
||||
/// Returns this [`Transform`] with a new rotation so that [`Transform::forward`]
|
||||
/// 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` 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 {
|
||||
@ -325,6 +335,11 @@ impl Transform {
|
||||
|
||||
/// Rotates this [`Transform`] so that [`Transform::forward`] points towards the `target` position,
|
||||
/// 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 `target` is the same as the transtorm translation, `Vec3::Z` is used instead
|
||||
/// * if `up` is zero, `Vec3::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) {
|
||||
self.look_to(target - self.translation, up);
|
||||
@ -332,10 +347,19 @@ impl Transform {
|
||||
|
||||
/// Rotates this [`Transform`] so that [`Transform::forward`] 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` 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 forward = -direction.normalize();
|
||||
let right = up.cross(forward).normalize();
|
||||
let forward = -direction.try_normalize().unwrap_or(Vec3::Z);
|
||||
let up = up.try_normalize().unwrap_or(Vec3::Y);
|
||||
let right = up
|
||||
.cross(forward)
|
||||
.try_normalize()
|
||||
.unwrap_or_else(|| up.any_orthonormal_vector());
|
||||
let up = forward.cross(right);
|
||||
self.rotation = Quat::from_mat3(&Mat3::from_cols(right, up, forward));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user