From e33785685d1ff72530d3d1b7108e8d7b1688c2bd Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Mon, 8 Jun 2020 18:40:50 -0400 Subject: [PATCH 01/10] Add Transform::{look_at_rh, look_at_lh} and deprecate look_at Corresponding functions have been added to Matrix4 and Decomposed and are now consistent. Matrix3, Matrix2, and the Rotation trait are only partially updated. --- src/matrix.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++ src/transform.rs | 31 +++++++++++++++++ tests/transform.rs | 37 ++++++++++++++++++++ 3 files changed, 154 insertions(+) diff --git a/src/matrix.rs b/src/matrix.rs index ea0e9de7..c8b00e91 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -189,6 +189,7 @@ impl Matrix3 { /// Create a rotation matrix that will cause a vector to point at /// `dir`, using `up` for orientation. + #[deprecated = "Use Matrix3::look_at_lh"] pub fn look_at(dir: Vector3, up: Vector3) -> Matrix3 { let dir = dir.normalize(); let side = up.cross(dir).normalize(); @@ -197,6 +198,26 @@ impl Matrix3 { Matrix3::from_cols(side, up, dir).transpose() } + /// Create a rotation matrix that will cause a vector to point at + /// `dir`, using `up` for orientation. + pub fn look_at_lh(dir: Vector3, up: Vector3) -> Matrix3 { + let dir = dir.normalize(); + let side = up.cross(dir).normalize(); + let up = dir.cross(side).normalize(); + + Matrix3::from_cols(side, up, dir).transpose() + } + + /// Create a rotation matrix that will cause a vector to point at + /// `dir`, using `up` for orientation. + pub fn look_at_rh(dir: Vector3, up: Vector3) -> Matrix3 { + let dir = -dir.normalize(); + let side = up.cross(dir).normalize(); + let up = dir.cross(side).normalize(); + + Matrix3::from_cols(side, up, dir).transpose() + } + /// Create a rotation matrix from a rotation around the `x` axis (pitch). pub fn from_angle_x>>(theta: A) -> Matrix3 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations @@ -333,6 +354,7 @@ impl Matrix4 { /// Create a homogeneous transformation matrix that will cause a vector to point at /// `dir`, using `up` for orientation. + #[deprecated = "Use Matrix4::look_to_rh"] pub fn look_at_dir(eye: Point3, dir: Vector3, up: Vector3) -> Matrix4 { let f = dir.normalize(); let s = f.cross(up).normalize(); @@ -347,12 +369,47 @@ impl Matrix4 { ) } + /// Create a homogeneous transformation matrix that will cause a vector to point at + /// `dir`, using `up` for orientation. + pub fn look_to_rh(eye: Point3, dir: Vector3, up: Vector3) -> Matrix4 { + let f = dir.normalize(); + let s = f.cross(up).normalize(); + let u = s.cross(f); + + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + s.x.clone(), u.x.clone(), -f.x.clone(), S::zero(), + s.y.clone(), u.y.clone(), -f.y.clone(), S::zero(), + s.z.clone(), u.z.clone(), -f.z.clone(), S::zero(), + -eye.dot(s), -eye.dot(u), eye.dot(f), S::one(), + ) + } + + /// Create a homogeneous transformation matrix that will cause a vector to point at + /// `dir`, using `up` for orientation. + pub fn look_to_lh(eye: Point3, dir: Vector3, up: Vector3) -> Matrix4 { + Matrix4::look_to_rh(eye, -dir, up) + } + /// Create a homogeneous transformation matrix that will cause a vector to point at /// `center`, using `up` for orientation. + #[deprecated = "Use Matrix4::look_at_rh"] pub fn look_at(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { Matrix4::look_at_dir(eye, center - eye, up) } + /// Create a homogeneous transformation matrix that will cause a vector to point at + /// `center`, using `up` for orientation. + pub fn look_at_rh(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { + Matrix4::look_to_rh(eye, center - eye, up) + } + + /// Create a homogeneous transformation matrix that will cause a vector to point at + /// `center`, using `up` for orientation. + pub fn look_at_lh(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { + Matrix4::look_to_lh(eye, center - eye, up) + } + /// Create a homogeneous transformation matrix from a rotation around the `x` axis (pitch). pub fn from_angle_x>>(theta: A) -> Matrix4 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations @@ -1043,6 +1100,16 @@ impl Transform> for Matrix3 { Matrix3::from(Matrix2::look_at(dir, up)) } + fn look_at_lh(eye: Point2, center: Point2, up: Vector2) -> Matrix3 { + let dir = center - eye; + Matrix3::from(Matrix2::look_at(dir, up)) + } + + fn look_at_rh(eye: Point2, center: Point2, up: Vector2) -> Matrix3 { + let dir = eye - center; + Matrix3::from(Matrix2::look_at(dir, up)) + } + fn transform_vector(&self, vec: Vector2) -> Vector2 { (self * vec.extend(S::zero())).truncate() } @@ -1066,6 +1133,16 @@ impl Transform> for Matrix3 { Matrix3::look_at(dir, up) } + fn look_at_lh(eye: Point3, center: Point3, up: Vector3) -> Matrix3 { + let dir = center - eye; + Matrix3::look_at_lh(dir, up) + } + + fn look_at_rh(eye: Point3, center: Point3, up: Vector3) -> Matrix3 { + let dir = center - eye; + Matrix3::look_at_rh(dir, up) + } + fn transform_vector(&self, vec: Vector3) -> Vector3 { self * vec } @@ -1084,10 +1161,19 @@ impl Transform> for Matrix3 { } impl Transform> for Matrix4 { + #[allow(deprecated)] fn look_at(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { Matrix4::look_at(eye, center, up) } + fn look_at_lh(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { + Matrix4::look_at_lh(eye, center, up) + } + + fn look_at_rh(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { + Matrix4::look_at_rh(eye, center, up) + } + fn transform_vector(&self, vec: Vector3) -> Vector3 { (self * vec.extend(S::zero())).truncate() } diff --git a/src/transform.rs b/src/transform.rs index 0b3453cb..151bf3d7 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -30,8 +30,17 @@ use std::ops::Mul; pub trait Transform: Sized + One { /// Create a transformation that rotates a vector to look at `center` from /// `eye`, using `up` for orientation. + #[deprecated = "Use look_at_rh or look_at_lh"] fn look_at(eye: P, center: P, up: P::Diff) -> Self; + /// Create a transformation that rotates a vector to look at `center` from + /// `eye`, using `up` for orientation. + fn look_at_rh(eye: P, center: P, up: P::Diff) -> Self; + + /// Create a transformation that rotates a vector to look at `center` from + /// `eye`, using `up` for orientation. + fn look_at_lh(eye: P, center: P, up: P::Diff) -> Self; + /// Transform a vector using this transform. fn transform_vector(&self, vec: P::Diff) -> P::Diff; @@ -113,6 +122,28 @@ where } } + #[inline] + fn look_at_lh(eye: P, center: P, up: P::Diff) -> Decomposed { + let rot = R::look_at(center - eye, up); + let disp = rot.rotate_vector(P::origin() - eye); + Decomposed { + scale: P::Scalar::one(), + rot: rot, + disp: disp, + } + } + + #[inline] + fn look_at_rh(eye: P, center: P, up: P::Diff) -> Decomposed { + let rot = R::look_at(eye - center, up); + let disp = rot.rotate_vector(P::origin() - eye); + Decomposed { + scale: P::Scalar::one(), + rot: rot, + disp: disp, + } + } + #[inline] fn transform_vector(&self, vec: P::Diff) -> P::Diff { self.rot.rotate_vector(vec * self.scale) diff --git a/tests/transform.rs b/tests/transform.rs index 1dcc357d..708b8222 100644 --- a/tests/transform.rs +++ b/tests/transform.rs @@ -88,6 +88,7 @@ fn test_inverse_vector() { } #[test] +#[allow(deprecated)] fn test_look_at() { let eye = Point3::new(0.0f64, 0.0, -5.0); let center = Point3::new(0.0f64, 0.0, 0.0); @@ -98,6 +99,42 @@ fn test_look_at() { assert_ulps_eq!(&t.transform_point(point), &view_point); } +#[test] +fn test_look_at_lh() { + let eye = Point3::new(0.0f64, 0.0, -5.0); + let center = Point3::new(0.0f64, 0.0, 0.0); + let up = Vector3::new(1.0f64, 0.0, 0.0); + let t: Decomposed, Quaternion> = Transform::look_at_lh(eye, center, up); + let point = Point3::new(1.0f64, 0.0, 0.0); + let view_point = Point3::new(0.0f64, 1.0, 5.0); + assert_ulps_eq!(&t.transform_point(point), &view_point); + + // Decomposed::look_at_lh and Matrix4::look_at_lh should be consistent + let t: Matrix4 = Transform::look_at_lh(eye, center, up); + assert_ulps_eq!(&t.transform_point(point), &view_point); + + // Decomposed::look_at is inconsistent and deprecated, but verify that the behvaior + // remains the same until removed. + #[allow(deprecated)] + let t: Decomposed, Quaternion> = Transform::look_at(eye, center, up); + assert_ulps_eq!(&t.transform_point(point), &view_point); +} + +#[test] +fn test_look_at_rh() { + let eye = Point3::new(0.0f64, 0.0, -5.0); + let center = Point3::new(0.0f64, 0.0, 0.0); + let up = Vector3::new(1.0f64, 0.0, 0.0); + let t: Decomposed, Quaternion> = Transform::look_at_rh(eye, center, up); + let point = Point3::new(1.0f64, 0.0, 0.0); + let view_point = Point3::new(0.0f64, 1.0, -5.0); + assert_ulps_eq!(&t.transform_point(point), &view_point); + + // Decomposed::look_at_rh and Matrix4::look_at_rh should be consistent + let t: Matrix4 = Transform::look_at_rh(eye, center, up); + assert_ulps_eq!(&t.transform_point(point), &view_point); +} + #[cfg(feature = "serde")] #[test] fn test_serialize() { From a4ea4511571bd12eb3baccd47759b65ba5c66c8a Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Fri, 26 Jun 2020 23:13:58 -0400 Subject: [PATCH 02/10] Add more matrix4 and transform tests --- tests/matrix.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/transform.rs | 5 +++++ 2 files changed, 47 insertions(+) diff --git a/tests/matrix.rs b/tests/matrix.rs index 734c3bbd..358acdbd 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -1127,6 +1127,48 @@ pub mod matrix4 { ); } + #[test] + fn test_look_to_rh() { + let eye = Point3::new(10.0, 15.0, 20.0); + let dir = Vector3::new(1.0, 2.0, 3.0).normalize(); + let up = Vector3::unit_y(); + + let m = Matrix4::look_to_rh(eye, dir, up); + #[allow(deprecated)] + assert_ulps_eq!(m, Matrix4::look_at_dir(eye, dir, up)); + + let expected = Matrix4::from([ + [-0.9486833, -0.16903086, -0.26726127, 0.0], + [0.0, 0.84515435, -0.53452253, 0.0], + [0.31622776, -0.5070926, -0.8017838, 0.0], + [3.1622782, -0.84515476, 26.726126, 1.0_f32] + ]); + assert_ulps_eq!(expected, m); + + let m = Matrix4::look_at_rh(eye, eye + dir, up); + assert_abs_diff_eq!(expected, m, epsilon = 1.0e-4); + } + + #[test] + fn test_look_to_lh() { + let eye = Point3::new(10.0, 15.0, 20.0); + let dir = Vector3::new(1.0, 2.0, 3.0).normalize(); + let up = Vector3::unit_y(); + + let m = Matrix4::look_to_lh(eye, dir, up); + + let expected = Matrix4::from([ + [0.9486833, -0.16903086, 0.26726127, 0.0], + [0.0, 0.84515435, 0.53452253, 0.0], + [-0.31622776, -0.5070926, 0.8017838, 0.0], + [-3.1622782, -0.84515476, -26.726126, 1.0_f32] + ]); + assert_ulps_eq!(expected, m); + + let m = Matrix4::look_at_lh(eye, eye + dir, up); + assert_abs_diff_eq!(expected, m, epsilon = 1.0e-4); + } + mod from { use cgmath::*; diff --git a/tests/transform.rs b/tests/transform.rs index 708b8222..926ff832 100644 --- a/tests/transform.rs +++ b/tests/transform.rs @@ -94,6 +94,7 @@ fn test_look_at() { let center = Point3::new(0.0f64, 0.0, 0.0); let up = Vector3::new(1.0f64, 0.0, 0.0); let t: Decomposed, Quaternion> = Transform::look_at(eye, center, up); + assert_ulps_eq!(t, Decomposed::, Quaternion>::look_at(eye, center, up)); let point = Point3::new(1.0f64, 0.0, 0.0); let view_point = Point3::new(0.0f64, 1.0, 5.0); assert_ulps_eq!(&t.transform_point(point), &view_point); @@ -105,12 +106,14 @@ fn test_look_at_lh() { let center = Point3::new(0.0f64, 0.0, 0.0); let up = Vector3::new(1.0f64, 0.0, 0.0); let t: Decomposed, Quaternion> = Transform::look_at_lh(eye, center, up); + assert_ulps_eq!(t, Decomposed::, Quaternion>::look_at_lh(eye, center, up)); let point = Point3::new(1.0f64, 0.0, 0.0); let view_point = Point3::new(0.0f64, 1.0, 5.0); assert_ulps_eq!(&t.transform_point(point), &view_point); // Decomposed::look_at_lh and Matrix4::look_at_lh should be consistent let t: Matrix4 = Transform::look_at_lh(eye, center, up); + assert_ulps_eq!(t, Matrix4::::look_at_lh(eye, center, up)); assert_ulps_eq!(&t.transform_point(point), &view_point); // Decomposed::look_at is inconsistent and deprecated, but verify that the behvaior @@ -126,12 +129,14 @@ fn test_look_at_rh() { let center = Point3::new(0.0f64, 0.0, 0.0); let up = Vector3::new(1.0f64, 0.0, 0.0); let t: Decomposed, Quaternion> = Transform::look_at_rh(eye, center, up); + assert_ulps_eq!(t, Decomposed::, Quaternion>::look_at_rh(eye, center, up)); let point = Point3::new(1.0f64, 0.0, 0.0); let view_point = Point3::new(0.0f64, 1.0, -5.0); assert_ulps_eq!(&t.transform_point(point), &view_point); // Decomposed::look_at_rh and Matrix4::look_at_rh should be consistent let t: Matrix4 = Transform::look_at_rh(eye, center, up); + assert_ulps_eq!(t, Matrix4::::look_at_rh(eye, center, up)); assert_ulps_eq!(&t.transform_point(point), &view_point); } From 09593fb5021ec591a90be49d08a50b6a946d90da Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Fri, 26 Jun 2020 23:40:29 -0400 Subject: [PATCH 03/10] Add matrix3 look_at_[lh|rh] tests --- tests/matrix.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/matrix.rs b/tests/matrix.rs index 358acdbd..cdd4b7b1 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -726,6 +726,35 @@ pub mod matrix3 { ); } } + + #[test] + fn test_look_at_lh() { + let dir = Vector3::new(1.0, 2.0, 3.0).normalize(); + let up = Vector3::unit_y(); + let m = Matrix3::look_at_lh(dir, up); + + assert_ulps_eq!(m, Matrix3::from([ + [0.9486833, -0.16903085, 0.26726127], + [0.0, 0.8451542, 0.53452253], + [-0.31622776, -0.50709254, 0.8017838_f32] + ])); + + #[allow(deprecated)] + assert_ulps_eq!(m, Matrix3::look_at(dir, up)); + } + + #[test] + fn test_look_at_rh() { + let dir = Vector3::new(1.0, 2.0, 3.0).normalize(); + let up = Vector3::unit_y(); + let m = Matrix3::look_at_rh(dir, up); + + assert_ulps_eq!(m, Matrix3::from([ + [-0.9486833, -0.16903085, -0.26726127], + [0.0, 0.8451542, -0.53452253], + [0.31622776, -0.50709254, -0.8017838_f32] + ])); + } } pub mod matrix4 { From dc084e15faf007b9a6c87229228c0ed47d3bd370 Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Fri, 26 Jun 2020 23:43:27 -0400 Subject: [PATCH 04/10] Rename Matrix3::look_at_[rh|lh] to look_to_[rh|lh] This makes the Matrix3/4 and Decomposed `look_at_*` functions consistent with looking at a center/focus point and `look_to_*` functions consistent with looking in a direction. --- src/matrix.rs | 16 ++++++---------- tests/matrix.rs | 8 ++++---- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index c8b00e91..6f9b7bab 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -189,7 +189,7 @@ impl Matrix3 { /// Create a rotation matrix that will cause a vector to point at /// `dir`, using `up` for orientation. - #[deprecated = "Use Matrix3::look_at_lh"] + #[deprecated = "Use Matrix3::look_to_lh"] pub fn look_at(dir: Vector3, up: Vector3) -> Matrix3 { let dir = dir.normalize(); let side = up.cross(dir).normalize(); @@ -200,7 +200,7 @@ impl Matrix3 { /// Create a rotation matrix that will cause a vector to point at /// `dir`, using `up` for orientation. - pub fn look_at_lh(dir: Vector3, up: Vector3) -> Matrix3 { + pub fn look_to_lh(dir: Vector3, up: Vector3) -> Matrix3 { let dir = dir.normalize(); let side = up.cross(dir).normalize(); let up = dir.cross(side).normalize(); @@ -210,12 +210,8 @@ impl Matrix3 { /// Create a rotation matrix that will cause a vector to point at /// `dir`, using `up` for orientation. - pub fn look_at_rh(dir: Vector3, up: Vector3) -> Matrix3 { - let dir = -dir.normalize(); - let side = up.cross(dir).normalize(); - let up = dir.cross(side).normalize(); - - Matrix3::from_cols(side, up, dir).transpose() + pub fn look_to_rh(dir: Vector3, up: Vector3) -> Matrix3 { + Matrix3::look_to_lh(-dir, up) } /// Create a rotation matrix from a rotation around the `x` axis (pitch). @@ -1135,12 +1131,12 @@ impl Transform> for Matrix3 { fn look_at_lh(eye: Point3, center: Point3, up: Vector3) -> Matrix3 { let dir = center - eye; - Matrix3::look_at_lh(dir, up) + Matrix3::look_to_lh(dir, up) } fn look_at_rh(eye: Point3, center: Point3, up: Vector3) -> Matrix3 { let dir = center - eye; - Matrix3::look_at_rh(dir, up) + Matrix3::look_to_rh(dir, up) } fn transform_vector(&self, vec: Vector3) -> Vector3 { diff --git a/tests/matrix.rs b/tests/matrix.rs index cdd4b7b1..177ca4f5 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -728,10 +728,10 @@ pub mod matrix3 { } #[test] - fn test_look_at_lh() { + fn test_look_to_lh() { let dir = Vector3::new(1.0, 2.0, 3.0).normalize(); let up = Vector3::unit_y(); - let m = Matrix3::look_at_lh(dir, up); + let m = Matrix3::look_to_lh(dir, up); assert_ulps_eq!(m, Matrix3::from([ [0.9486833, -0.16903085, 0.26726127], @@ -744,10 +744,10 @@ pub mod matrix3 { } #[test] - fn test_look_at_rh() { + fn test_look_to_rh() { let dir = Vector3::new(1.0, 2.0, 3.0).normalize(); let up = Vector3::unit_y(); - let m = Matrix3::look_at_rh(dir, up); + let m = Matrix3::look_to_rh(dir, up); assert_ulps_eq!(m, Matrix3::from([ [-0.9486833, -0.16903085, -0.26726127], From b9350a3a5b6babd8abf9df0b8ccdddcb4b3d899c Mon Sep 17 00:00:00 2001 From: Aaron Loucks Date: Fri, 26 Jun 2020 23:51:39 -0400 Subject: [PATCH 05/10] Remove duplicate code in the deprecated Matrix3::look_at function --- src/matrix.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index 6f9b7bab..ed643c8e 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -191,11 +191,7 @@ impl Matrix3 { /// `dir`, using `up` for orientation. #[deprecated = "Use Matrix3::look_to_lh"] pub fn look_at(dir: Vector3, up: Vector3) -> Matrix3 { - let dir = dir.normalize(); - let side = up.cross(dir).normalize(); - let up = dir.cross(side).normalize(); - - Matrix3::from_cols(side, up, dir).transpose() + Matrix3::look_to_lh(dir, up) } /// Create a rotation matrix that will cause a vector to point at From faa69b678a00990795ed2eda6d8d2e171c5ad6e0 Mon Sep 17 00:00:00 2001 From: Egor Larionov Date: Mon, 10 Aug 2020 12:26:11 -0700 Subject: [PATCH 06/10] Rename look_at -> look_to for Matrix2 and related Rename functions look_at* to look_to* on Matrix2 and related rotation transforms. --- src/matrix.rs | 25 ++++++++++++++++++++----- src/rotation.rs | 6 +++--- tests/matrix.rs | 8 ++++---- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index ed643c8e..0c9d61fa 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -101,14 +101,29 @@ impl Matrix2 { impl Matrix2 { /// Create a transformation matrix that will cause `unit_x()` to point at /// `dir`. `unit_y()` will be perpendicular to `dir`, and the closest to `up`. + #[deprecated = "Use Matrix2::look_to"] pub fn look_at(dir: Vector2, up: Vector2) -> Matrix2 { - Matrix2::look_at_stable(dir, up.x * dir.y >= up.y * dir.x) + Matrix2::look_to(dir, up) } /// Crate a transformation that will cause `unit_x()` to point at - /// `dir`. This is similar to `look_at`, but does not take an `up` vector. + /// `dir`. This is similar to `look_to`, but does not take an `up` vector. /// This will not cause `unit_y()` to flip when `dir` crosses over the `up` vector. + #[deprecated = "Use Matrix2::look_to_stable"] pub fn look_at_stable(dir: Vector2, flip: bool) -> Matrix2 { + Matrix2::look_to_stable(dir, flip) + } + + /// Create a transformation matrix that will cause `unit_x()` to point at + /// `dir`. `unit_y()` will be perpendicular to `dir`, and the closest to `up`. + pub fn look_to(dir: Vector2, up: Vector2) -> Matrix2 { + Matrix2::look_to_stable(dir, up.x * dir.y >= up.y * dir.x) + } + + /// Crate a transformation that will cause `unit_x()` to point at + /// `dir`. This is similar to `look_to`, but does not take an `up` vector. + /// This will not cause `unit_y()` to flip when `dir` crosses over the `up` vector. + pub fn look_to_stable(dir: Vector2, flip: bool) -> Matrix2 { let basis1 = dir.normalize(); let basis2 = if flip { Vector2::new(basis1.y, -basis1.x) @@ -1089,17 +1104,17 @@ impl approx::UlpsEq for Matrix4 { impl Transform> for Matrix3 { fn look_at(eye: Point2, center: Point2, up: Vector2) -> Matrix3 { let dir = center - eye; - Matrix3::from(Matrix2::look_at(dir, up)) + Matrix3::from(Matrix2::look_to(dir, up)) } fn look_at_lh(eye: Point2, center: Point2, up: Vector2) -> Matrix3 { let dir = center - eye; - Matrix3::from(Matrix2::look_at(dir, up)) + Matrix3::from(Matrix2::look_to(dir, up)) } fn look_at_rh(eye: Point2, center: Point2, up: Vector2) -> Matrix3 { let dir = eye - center; - Matrix3::from(Matrix2::look_at(dir, up)) + Matrix3::from(Matrix2::look_to(dir, up)) } fn transform_vector(&self, vec: Vector2) -> Vector2 { diff --git a/src/rotation.rs b/src/rotation.rs index e7fa1f6f..33786fa8 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -169,9 +169,9 @@ pub struct Basis2 { } impl Basis2 { - pub fn look_at_stable(dir: Vector2, flip: bool) -> Basis2 { + pub fn look_to_stable(dir: Vector2, flip: bool) -> Basis2 { Basis2 { - mat: Matrix2::look_at_stable(dir, flip), + mat: Matrix2::look_to_stable(dir, flip), } } } @@ -210,7 +210,7 @@ impl Rotation for Basis2 { #[inline] fn look_at(dir: Vector2, up: Vector2) -> Basis2 { Basis2 { - mat: Matrix2::look_at(dir, up), + mat: Matrix2::look_to(dir, up), } } diff --git a/tests/matrix.rs b/tests/matrix.rs index 177ca4f5..3f25705d 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -190,18 +190,18 @@ pub mod matrix2 { } #[test] - fn test_look_at() { + fn test_look_to() { // rot should rotate unit_x() to look at the input vector - let rot = Matrix2::look_at(V, Vector2::unit_y()); + let rot = Matrix2::look_to(V, Vector2::unit_y()); assert_eq!(rot * Vector2::unit_x(), V.normalize()); let new_up = Vector2::new(-V.y, V.x).normalize(); assert_eq!(rot * Vector2::unit_y(), new_up); - let rot_down = Matrix2::look_at(V, -1.0 * Vector2::unit_y()); + let rot_down = Matrix2::look_to(V, -1.0 * Vector2::unit_y()); assert_eq!(rot_down * Vector2::unit_x(), V.normalize()); assert_eq!(rot_down * Vector2::unit_y(), -1.0 * new_up); - let rot2 = Matrix2::look_at(-V, Vector2::unit_y()); + let rot2 = Matrix2::look_to(-V, Vector2::unit_y()); assert_eq!(rot2 * Vector2::unit_x(), (-V).normalize()); } } From 64e88bd2da9de8a6f68aa2c91855d9e9f93cab04 Mon Sep 17 00:00:00 2001 From: Egor Larionov Date: Mon, 10 Aug 2020 12:33:15 -0700 Subject: [PATCH 07/10] Rename look_at to look_to in Rotation trait --- src/quaternion.rs | 2 +- src/rotation.rs | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/quaternion.rs b/src/quaternion.rs index 6ef034bd..0d8f2600 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -484,7 +484,7 @@ impl Rotation for Quaternion { type Space = Point3; #[inline] - fn look_at(dir: Vector3, up: Vector3) -> Quaternion { + fn look_to(dir: Vector3, up: Vector3) -> Quaternion { Matrix3::look_at(dir, up).into() } diff --git a/src/rotation.rs b/src/rotation.rs index 33786fa8..bd04380b 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -42,9 +42,18 @@ where type Space: EuclideanSpace; /// Create a rotation to a given direction with an 'up' vector. + #[deprecated = "Use Rotation::look_to"] fn look_at( dir: ::Diff, up: ::Diff, + ) -> Self { + Self::look_to(dir, up) + } + + /// Create a rotation to a given direction with an 'up' vector. + fn look_to( + dir: ::Diff, + up: ::Diff, ) -> Self; /// Create a shortest rotation to transform vector 'a' into 'b'. @@ -208,7 +217,7 @@ impl Rotation for Basis2 { type Space = Point2; #[inline] - fn look_at(dir: Vector2, up: Vector2) -> Basis2 { + fn look_to(dir: Vector2, up: Vector2) -> Basis2 { Basis2 { mat: Matrix2::look_to(dir, up), } @@ -363,7 +372,7 @@ impl Rotation for Basis3 { type Space = Point3; #[inline] - fn look_at(dir: Vector3, up: Vector3) -> Basis3 { + fn look_to(dir: Vector3, up: Vector3) -> Basis3 { Basis3 { mat: Matrix3::look_at(dir, up), } From 121c77b8621b39e760569f0db1416fb134f55d69 Mon Sep 17 00:00:00 2001 From: Egor Larionov Date: Mon, 10 Aug 2020 12:56:37 -0700 Subject: [PATCH 08/10] Fix deprecated look_at usage + remove repeated code Remove a repated instance of Matrix4 look_at transform. --- src/matrix.rs | 22 ++++++---------------- src/quaternion.rs | 2 +- src/rotation.rs | 2 +- src/transform.rs | 10 ++++++---- tests/matrix.rs | 4 ++-- 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index 0c9d61fa..eb668cf2 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -204,7 +204,7 @@ impl Matrix3 { /// Create a rotation matrix that will cause a vector to point at /// `dir`, using `up` for orientation. - #[deprecated = "Use Matrix3::look_to_lh"] + #[deprecated = "Use Matrix3::look_to_lh or Matrix3::look_to_rh for the right handed variation"] pub fn look_at(dir: Vector3, up: Vector3) -> Matrix3 { Matrix3::look_to_lh(dir, up) } @@ -361,19 +361,9 @@ impl Matrix4 { /// Create a homogeneous transformation matrix that will cause a vector to point at /// `dir`, using `up` for orientation. - #[deprecated = "Use Matrix4::look_to_rh"] + #[deprecated = "Use Matrix4::look_to_rh or Matrix3::look_to_lh for the left handed variation"] pub fn look_at_dir(eye: Point3, dir: Vector3, up: Vector3) -> Matrix4 { - let f = dir.normalize(); - let s = f.cross(up).normalize(); - let u = s.cross(f); - - #[cfg_attr(rustfmt, rustfmt_skip)] - Matrix4::new( - s.x.clone(), u.x.clone(), -f.x.clone(), S::zero(), - s.y.clone(), u.y.clone(), -f.y.clone(), S::zero(), - s.z.clone(), u.z.clone(), -f.z.clone(), S::zero(), - -eye.dot(s), -eye.dot(u), eye.dot(f), S::one(), - ) + Self::look_to_rh(eye, dir, up) } /// Create a homogeneous transformation matrix that will cause a vector to point at @@ -400,9 +390,9 @@ impl Matrix4 { /// Create a homogeneous transformation matrix that will cause a vector to point at /// `center`, using `up` for orientation. - #[deprecated = "Use Matrix4::look_at_rh"] + #[deprecated = "Use Matrix4::look_at_rh or look_at_lh for the left handed variation"] pub fn look_at(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { - Matrix4::look_at_dir(eye, center - eye, up) + Matrix4::look_to_rh(eye, center - eye, up) } /// Create a homogeneous transformation matrix that will cause a vector to point at @@ -1137,7 +1127,7 @@ impl Transform> for Matrix3 { impl Transform> for Matrix3 { fn look_at(eye: Point3, center: Point3, up: Vector3) -> Matrix3 { let dir = center - eye; - Matrix3::look_at(dir, up) + Matrix3::look_to_lh(dir, up) } fn look_at_lh(eye: Point3, center: Point3, up: Vector3) -> Matrix3 { diff --git a/src/quaternion.rs b/src/quaternion.rs index 0d8f2600..474a8f62 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -485,7 +485,7 @@ impl Rotation for Quaternion { #[inline] fn look_to(dir: Vector3, up: Vector3) -> Quaternion { - Matrix3::look_at(dir, up).into() + Matrix3::look_to_lh(dir, up).into() } #[inline] diff --git a/src/rotation.rs b/src/rotation.rs index bd04380b..c39f6ea8 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -374,7 +374,7 @@ impl Rotation for Basis3 { #[inline] fn look_to(dir: Vector3, up: Vector3) -> Basis3 { Basis3 { - mat: Matrix3::look_at(dir, up), + mat: Matrix3::look_to_lh(dir, up), } } diff --git a/src/transform.rs b/src/transform.rs index 151bf3d7..9b0f55ca 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -31,7 +31,9 @@ pub trait Transform: Sized + One { /// Create a transformation that rotates a vector to look at `center` from /// `eye`, using `up` for orientation. #[deprecated = "Use look_at_rh or look_at_lh"] - fn look_at(eye: P, center: P, up: P::Diff) -> Self; + fn look_at(eye: P, center: P, up: P::Diff) -> Self { + Self::look_at_lh(eye, center, up) + } /// Create a transformation that rotates a vector to look at `center` from /// `eye`, using `up` for orientation. @@ -113,7 +115,7 @@ where { #[inline] fn look_at(eye: P, center: P, up: P::Diff) -> Decomposed { - let rot = R::look_at(center - eye, up); + let rot = R::look_to(center - eye, up); let disp = rot.rotate_vector(P::origin() - eye); Decomposed { scale: P::Scalar::one(), @@ -124,7 +126,7 @@ where #[inline] fn look_at_lh(eye: P, center: P, up: P::Diff) -> Decomposed { - let rot = R::look_at(center - eye, up); + let rot = R::look_to(center - eye, up); let disp = rot.rotate_vector(P::origin() - eye); Decomposed { scale: P::Scalar::one(), @@ -135,7 +137,7 @@ where #[inline] fn look_at_rh(eye: P, center: P, up: P::Diff) -> Decomposed { - let rot = R::look_at(eye - center, up); + let rot = R::look_to(eye - center, up); let disp = rot.rotate_vector(P::origin() - eye); Decomposed { scale: P::Scalar::one(), diff --git a/tests/matrix.rs b/tests/matrix.rs index 3f25705d..cd371aea 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -740,7 +740,7 @@ pub mod matrix3 { ])); #[allow(deprecated)] - assert_ulps_eq!(m, Matrix3::look_at(dir, up)); + assert_ulps_eq!(m, Matrix3::look_to_lh(dir, up)); } #[test] @@ -1164,7 +1164,7 @@ pub mod matrix4 { let m = Matrix4::look_to_rh(eye, dir, up); #[allow(deprecated)] - assert_ulps_eq!(m, Matrix4::look_at_dir(eye, dir, up)); + assert_ulps_eq!(m, Matrix4::look_to_rh(eye, dir, up)); let expected = Matrix4::from([ [-0.9486833, -0.16903086, -0.26726127, 0.0], From f2284a54a738cb825362138b08c8161b8fed73ec Mon Sep 17 00:00:00 2001 From: Egor Larionov Date: Mon, 10 Aug 2020 13:22:45 -0700 Subject: [PATCH 09/10] Revert look_at test changes Previously look_at functions were erroneously renamed to look_to_{lh|rh} as a response to deprecation warnings. Instead what should've happened is that `allow(deprecated)` annotations are fixed to suppress tests that verify that deprecated functions are working. This commit reintroduced the tests for deprecated functions and suppresses the deprecation warnings. --- tests/matrix.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/matrix.rs b/tests/matrix.rs index cd371aea..fe79de21 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -740,7 +740,9 @@ pub mod matrix3 { ])); #[allow(deprecated)] - assert_ulps_eq!(m, Matrix3::look_to_lh(dir, up)); + { + assert_ulps_eq!(m, Matrix3::look_at(dir, up)); + } } #[test] @@ -1164,7 +1166,9 @@ pub mod matrix4 { let m = Matrix4::look_to_rh(eye, dir, up); #[allow(deprecated)] - assert_ulps_eq!(m, Matrix4::look_to_rh(eye, dir, up)); + { + assert_ulps_eq!(m, Matrix4::look_at_dir(eye, dir, up)); + } let expected = Matrix4::from([ [-0.9486833, -0.16903086, -0.26726127, 0.0], From d9d89deb04cbfcfeea053b1b9b40e208cf44942a Mon Sep 17 00:00:00 2001 From: Egor Larionov Date: Mon, 10 Aug 2020 17:42:02 -0700 Subject: [PATCH 10/10] Update docs of look_* functions This change clarifies the meaning of the _lh and _rh suffixes. --- src/matrix.rs | 24 ++++++++++++++++-------- src/rotation.rs | 1 + src/transform.rs | 12 ++++++++---- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index eb668cf2..62335820 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -366,8 +366,10 @@ impl Matrix4 { Self::look_to_rh(eye, dir, up) } - /// Create a homogeneous transformation matrix that will cause a vector to point at - /// `dir`, using `up` for orientation. + /// Creates a homogeneous right-handed look-at transformation matrix. + /// + /// This matrix will transform a vector to point in `dir` direction, using `up` for orientation + /// assuming a right-handed corrdinate system. pub fn look_to_rh(eye: Point3, dir: Vector3, up: Vector3) -> Matrix4 { let f = dir.normalize(); let s = f.cross(up).normalize(); @@ -382,8 +384,10 @@ impl Matrix4 { ) } - /// Create a homogeneous transformation matrix that will cause a vector to point at - /// `dir`, using `up` for orientation. + /// Creates a homogeneous left-handed look-at transformation matrix. + /// + /// This matrix will transform a vector to point in `dir` direction, using `up` for orientation + /// assuming a left-handed corrdinate system. pub fn look_to_lh(eye: Point3, dir: Vector3, up: Vector3) -> Matrix4 { Matrix4::look_to_rh(eye, -dir, up) } @@ -395,14 +399,18 @@ impl Matrix4 { Matrix4::look_to_rh(eye, center - eye, up) } - /// Create a homogeneous transformation matrix that will cause a vector to point at - /// `center`, using `up` for orientation. + /// Creates a homogeneous right-handed look-at transformation matrix. + /// + /// This matrix will transform a vector to point at `center`, using `up` for orientation + /// assuming a right-handed corrdinate system. pub fn look_at_rh(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { Matrix4::look_to_rh(eye, center - eye, up) } - /// Create a homogeneous transformation matrix that will cause a vector to point at - /// `center`, using `up` for orientation. + /// Creates a homogeneous left-handed look-at transformation matrix. + /// + /// This matrix will transform a vector to point at `center`, using `up` for orientation + /// assuming a left-handed corrdinate system. pub fn look_at_lh(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { Matrix4::look_to_lh(eye, center - eye, up) } diff --git a/src/rotation.rs b/src/rotation.rs index c39f6ea8..27f5b7b2 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -371,6 +371,7 @@ impl<'a, S: 'a + BaseFloat> iter::Product<&'a Basis3> for Basis3 { impl Rotation for Basis3 { type Space = Point3; + /// Construct a look-at view matrix assuming a left-handed coordinate system. #[inline] fn look_to(dir: Vector3, up: Vector3) -> Basis3 { Basis3 { diff --git a/src/transform.rs b/src/transform.rs index 9b0f55ca..0fae55a9 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -35,12 +35,16 @@ pub trait Transform: Sized + One { Self::look_at_lh(eye, center, up) } - /// Create a transformation that rotates a vector to look at `center` from - /// `eye`, using `up` for orientation. + /// Creates a right-handed look-at view transform. + /// + /// This transform rotates a vector to look at `center` from `eye`, using `up` for orientation + /// assuming a right-handed coordinate system. fn look_at_rh(eye: P, center: P, up: P::Diff) -> Self; - /// Create a transformation that rotates a vector to look at `center` from - /// `eye`, using `up` for orientation. + /// Creates a right-handed look-at view transform. + /// + /// This transform rotates a vector to look at `center` from `eye`, using `up` for orientation + /// assuming a left-handed coordinate system. fn look_at_lh(eye: P, center: P, up: P::Diff) -> Self; /// Transform a vector using this transform.