@@ -120,6 +120,11 @@ impl Transform {
120120
121121 /// Returns this [`Transform`] with a new rotation so that [`Transform::forward`]
122122 /// points towards the `target` position and [`Transform::up`] points towards `up`.
123+ ///
124+ /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases:
125+ /// * if `target` is the same as the transform translation, `Vec3::Z` is used instead
126+ /// * if `up` is zero, `Vec3::Y` is used instead
127+ /// * if the resulting forward direction is parallel with `up`, an orthogonal vector is used as the "right" direction
123128 #[ inline]
124129 #[ must_use]
125130 pub fn looking_at ( mut self , target : Vec3 , up : Vec3 ) -> Self {
@@ -129,6 +134,11 @@ impl Transform {
129134
130135 /// Returns this [`Transform`] with a new rotation so that [`Transform::forward`]
131136 /// points in the given `direction` and [`Transform::up`] points towards `up`.
137+ ///
138+ /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases:
139+ /// * if `direction` is zero, `Vec3::Z` is used instead
140+ /// * if `up` is zero, `Vec3::Y` is used instead
141+ /// * if `direction` is parallel with `up`, an orthogonal vector is used as the "right" direction
132142 #[ inline]
133143 #[ must_use]
134144 pub fn looking_to ( mut self , direction : Vec3 , up : Vec3 ) -> Self {
@@ -325,17 +335,31 @@ impl Transform {
325335
326336 /// Rotates this [`Transform`] so that [`Transform::forward`] points towards the `target` position,
327337 /// and [`Transform::up`] points towards `up`.
338+ ///
339+ /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases:
340+ /// * if `target` is the same as the transtorm translation, `Vec3::Z` is used instead
341+ /// * if `up` is zero, `Vec3::Y` is used instead
342+ /// * if the resulting forward direction is parallel with `up`, an orthogonal vector is used as the "right" direction
328343 #[ inline]
329344 pub fn look_at ( & mut self , target : Vec3 , up : Vec3 ) {
330345 self . look_to ( target - self . translation , up) ;
331346 }
332347
333348 /// Rotates this [`Transform`] so that [`Transform::forward`] points in the given `direction`
334349 /// and [`Transform::up`] points towards `up`.
350+ ///
351+ /// In some cases it's not possible to construct a rotation. Another axis will be picked in those cases:
352+ /// * if `direction` is zero, `Vec3::Z` is used instead
353+ /// * if `up` is zero, `Vec3::Y` is used instead
354+ /// * if `direction` is parallel with `up`, an orthogonal vector is used as the "right" direction
335355 #[ inline]
336356 pub fn look_to ( & mut self , direction : Vec3 , up : Vec3 ) {
337- let forward = -direction. normalize ( ) ;
338- let right = up. cross ( forward) . normalize ( ) ;
357+ let forward = -direction. try_normalize ( ) . unwrap_or ( Vec3 :: Z ) ;
358+ let up = up. try_normalize ( ) . unwrap_or ( Vec3 :: Y ) ;
359+ let right = up
360+ . cross ( forward)
361+ . try_normalize ( )
362+ . unwrap_or_else ( || up. any_orthonormal_vector ( ) ) ;
339363 let up = forward. cross ( right) ;
340364 self . rotation = Quat :: from_mat3 ( & Mat3 :: from_cols ( right, up, forward) ) ;
341365 }
0 commit comments