diff --git a/CHANGELOG.md b/CHANGELOG.md index dbff56ad..5cd8491f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,21 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.16.0] - 2018-01-03 + +### Added + +- Add `InnerSpace::project_on` +- Add `Array::len` +- Re-export `Bounded` and implement for vectors, points, and angles +- Add vector subtraction to `EuclideanSpace` +- Add swizzle functions behinde that `"swizzle"` feature +- Add `Matrix4::look_at_dir` + +### Changed + +- Return `Option` from cast functions + ## [v0.15.0] - 2017-07-30 ### Added @@ -274,7 +289,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## v0.0.1 - 2014-06-24 -[Unreleased]: https://github.com/brendanzab/cgmath/compare/v0.15.0...HEAD +[Unreleased]: https://github.com/brendanzab/cgmath/compare/v0.16.0...HEAD +[v0.16.0]: https://github.com/brendanzab/cgmath/compare/v0.15.0...v0.16.0 [v0.15.0]: https://github.com/brendanzab/cgmath/compare/v0.14.1...v0.15.0 [v0.14.1]: https://github.com/brendanzab/cgmath/compare/v0.14.0...v0.14.1 [v0.14.0]: https://github.com/brendanzab/cgmath/compare/v0.13.1...v0.14.0 diff --git a/Cargo.toml b/Cargo.toml index 6f0f8802..eea2a38f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cgmath" -version = "0.15.0" +version = "0.16.0" authors = ["Brendan Zabarauskas "] license = "Apache-2.0" description = "A linear algebra and mathematics library for computer graphics." @@ -22,12 +22,12 @@ swizzle = [] [dependencies] approx = "0.1" -mint = { version = "0.4.1", optional = true } +mint = { version = "0.5", optional = true } num-traits = "0.1" rand = "0.4" serde = { version = "1.0", features = ["serde_derive"], optional = true } simd = { version = "0.2", optional = true } [dev-dependencies] -glium = "0.17" +glium = "0.19" serde_json = "1.0" diff --git a/benches/construction.rs b/benches/construction.rs index f80d5049..b3a2a7b9 100644 --- a/benches/construction.rs +++ b/benches/construction.rs @@ -15,16 +15,17 @@ #![feature(test)] +extern crate cgmath; extern crate rand; extern crate test; -extern crate cgmath; use rand::{IsaacRng, Rng}; use test::Bencher; use cgmath::*; -#[path="common/macros.rs"] -#[macro_use] mod macros; +#[path = "common/macros.rs"] +#[macro_use] +mod macros; fn bench_from_axis_angle>(bh: &mut Bencher) { const LEN: usize = 1 << 13; @@ -39,7 +40,8 @@ fn bench_from_axis_angle>(bh: &mut Bencher) { i = (i + 1) & (LEN - 1); unsafe { - let res: T = Rotation3::from_axis_angle(*axis.get_unchecked(i), *angle.get_unchecked(i)); + let res: T = + Rotation3::from_axis_angle(*axis.get_unchecked(i), *angle.get_unchecked(i)); test::black_box(res) } }) @@ -55,7 +57,19 @@ fn _bench_rot3_from_axisangle(bh: &mut Bencher) { bench_from_axis_angle::>(bh) } -bench_construction!(_bench_rot2_from_axisangle, Basis2, Basis2::from_angle [ angle: Rad ]); +bench_construction!( + _bench_rot2_from_axisangle, + Basis2, + Basis2::from_angle[angle: Rad] +); -bench_construction!(_bench_quat_from_euler_angles, Quaternion, Quaternion::from [src: Euler>]); -bench_construction!(_bench_rot3_from_euler_angles, Basis3, Basis3::from [src: Euler>]); +bench_construction!( + _bench_quat_from_euler_angles, + Quaternion, + Quaternion::from[src: Euler>] +); +bench_construction!( + _bench_rot3_from_euler_angles, + Basis3, + Basis3::from[src: Euler>] +); diff --git a/benches/mat.rs b/benches/mat.rs index 88efab90..5400792e 100644 --- a/benches/mat.rs +++ b/benches/mat.rs @@ -15,9 +15,9 @@ #![feature(test)] +extern crate cgmath; extern crate rand; extern crate test; -extern crate cgmath; use rand::{IsaacRng, Rng}; use std::ops::*; @@ -25,8 +25,9 @@ use test::Bencher; use cgmath::*; -#[path="common/macros.rs"] -#[macro_use] mod macros; +#[path = "common/macros.rs"] +#[macro_use] +mod macros; bench_binop!(_bench_matrix2_mul_m, Matrix2, Matrix2, mul); bench_binop!(_bench_matrix3_mul_m, Matrix3, Matrix3, mul); diff --git a/benches/quat.rs b/benches/quat.rs index 81b4f9e0..57b0f931 100644 --- a/benches/quat.rs +++ b/benches/quat.rs @@ -15,9 +15,9 @@ #![feature(test)] +extern crate cgmath; extern crate rand; extern crate test; -extern crate cgmath; use rand::{IsaacRng, Rng}; use std::ops::*; @@ -25,8 +25,9 @@ use test::Bencher; use cgmath::*; -#[path="common/macros.rs"] -#[macro_use] mod macros; +#[path = "common/macros.rs"] +#[macro_use] +mod macros; bench_binop!(_bench_quat_add_q, Quaternion, Quaternion, add); bench_binop!(_bench_quat_sub_q, Quaternion, Quaternion, sub); diff --git a/benches/vec.rs b/benches/vec.rs index 92fbe1a3..7d062759 100644 --- a/benches/vec.rs +++ b/benches/vec.rs @@ -15,9 +15,9 @@ #![feature(test)] +extern crate cgmath; extern crate rand; extern crate test; -extern crate cgmath; use rand::{IsaacRng, Rng}; use std::ops::*; @@ -25,8 +25,9 @@ use test::Bencher; use cgmath::*; -#[path="common/macros.rs"] -#[macro_use] mod macros; +#[path = "common/macros.rs"] +#[macro_use] +mod macros; bench_binop!(_bench_vector2_add_v, Vector2, Vector2, add); bench_binop!(_bench_vector3_add_v, Vector3, Vector3, add); diff --git a/src/angle.rs b/src/angle.rs index ba5342d2..1ab59385 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -45,14 +45,20 @@ pub struct Rad(pub S); #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Deg(pub S); -impl From> for Deg where S: BaseFloat { +impl From> for Deg +where + S: BaseFloat, +{ #[inline] fn from(rad: Rad) -> Deg { Deg(rad.0 * cast(180.0 / f64::consts::PI).unwrap()) } } -impl From> for Rad where S: BaseFloat { +impl From> for Rad +where + S: BaseFloat, +{ #[inline] fn from(deg: Deg) -> Rad { Rad(deg.0 * cast(f64::consts::PI / 180.0).unwrap()) diff --git a/src/euler.rs b/src/euler.rs index 4ba855da..b3661fd6 100644 --- a/src/euler.rs +++ b/src/euler.rs @@ -75,8 +75,7 @@ use num::BaseFloat; /// [gimbal lock]: https://en.wikipedia.org/wiki/Gimbal_lock#Gimbal_lock_in_applied_mathematics /// [convert]: #defining-rotations-using-euler-angles #[repr(C)] -#[derive(Copy, Clone, Debug)] -#[derive(PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Euler { /// The angle to apply around the _x_ axis. Also known at the _pitch_. @@ -162,23 +161,27 @@ impl ApproxEq for Euler { #[inline] fn relative_eq(&self, other: &Self, epsilon: A::Epsilon, max_relative: A::Epsilon) -> bool { - A::relative_eq(&self.x, &other.x, epsilon, max_relative) && - A::relative_eq(&self.y, &other.y, epsilon, max_relative) && - A::relative_eq(&self.z, &other.z, epsilon, max_relative) + A::relative_eq(&self.x, &other.x, epsilon, max_relative) + && A::relative_eq(&self.y, &other.y, epsilon, max_relative) + && A::relative_eq(&self.z, &other.z, epsilon, max_relative) } #[inline] fn ulps_eq(&self, other: &Self, epsilon: A::Epsilon, max_ulps: u32) -> bool { - A::ulps_eq(&self.x, &other.x, epsilon, max_ulps) && - A::ulps_eq(&self.y, &other.y, epsilon, max_ulps) && - A::ulps_eq(&self.z, &other.z, epsilon, max_ulps) + A::ulps_eq(&self.x, &other.x, epsilon, max_ulps) + && A::ulps_eq(&self.y, &other.y, epsilon, max_ulps) + && A::ulps_eq(&self.z, &other.z, epsilon, max_ulps) } } impl Rand for Euler { #[inline] fn rand(rng: &mut R) -> Euler { - Euler { x: rng.gen(), y: rng.gen(), z: rng.gen() } + Euler { + x: rng.gen(), + y: rng.gen(), + z: rng.gen(), + } } } diff --git a/src/lib.rs b/src/lib.rs index d68585e5..a1f7b45a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,8 +58,8 @@ extern crate approx; #[cfg(feature = "mint")] pub extern crate mint; -pub extern crate num_traits; extern crate rand; +pub extern crate num_traits; #[cfg(feature = "serde")] #[macro_use] @@ -76,7 +76,7 @@ pub use structure::*; pub use matrix::{Matrix2, Matrix3, Matrix4}; pub use quaternion::Quaternion; -pub use vector::{Vector1, Vector2, Vector3, Vector4, dot, vec1, vec2, vec3, vec4}; +pub use vector::{dot, Vector1, Vector2, Vector3, Vector4, vec1, vec2, vec3, vec4}; pub use angle::{Deg, Rad}; pub use euler::Euler; diff --git a/src/matrix.rs b/src/matrix.rs index ba28843d..c9600645 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -80,14 +80,11 @@ pub struct Matrix4 { pub w: Vector4, } - impl Matrix2 { /// Create a new matrix, providing values for each index. #[inline] - pub fn new(c0r0: S, c0r1: S, - c1r0: S, c1r1: S) -> Matrix2 { - Matrix2::from_cols(Vector2::new(c0r0, c0r1), - Vector2::new(c1r0, c1r1)) + pub fn new(c0r0: S, c0r1: S, c1r0: S, c1r1: S) -> Matrix2 { + Matrix2::from_cols(Vector2::new(c0r0, c0r1), Vector2::new(c1r0, c1r1)) } /// Create a new matrix, providing columns. @@ -107,26 +104,34 @@ impl Matrix2 { pub fn from_angle>>(theta: A) -> Matrix2 { let (s, c) = Rad::sin_cos(theta.into()); - Matrix2::new(c, s, - -s, c) + Matrix2::new(c, s, -s, c) } } impl Matrix3 { /// Create a new matrix, providing values for each index. #[inline] - pub fn new(c0r0:S, c0r1:S, c0r2:S, - c1r0:S, c1r1:S, c1r2:S, - c2r0:S, c2r1:S, c2r2:S) -> Matrix3 { - Matrix3::from_cols(Vector3::new(c0r0, c0r1, c0r2), - Vector3::new(c1r0, c1r1, c1r2), - Vector3::new(c2r0, c2r1, c2r2)) + #[cfg_attr(rustfmt, rustfmt_skip)] + pub fn new( + c0r0:S, c0r1:S, c0r2:S, + c1r0:S, c1r1:S, c1r2:S, + c2r0:S, c2r1:S, c2r2:S, + ) -> Matrix3 { + Matrix3::from_cols( + Vector3::new(c0r0, c0r1, c0r2), + Vector3::new(c1r0, c1r1, c1r2), + Vector3::new(c2r0, c2r1, c2r2), + ) } /// Create a new matrix, providing columns. #[inline] pub fn from_cols(c0: Vector3, c1: Vector3, c2: Vector3) -> Matrix3 { - Matrix3 { x: c0, y: c1, z: c2 } + Matrix3 { + x: c0, + y: c1, + z: c2, + } } /// Create a rotation matrix that will cause a vector to point at @@ -143,27 +148,39 @@ impl Matrix3 { pub fn from_angle_x>>(theta: A) -> Matrix3 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations let (s, c) = Rad::sin_cos(theta.into()); - Matrix3::new(S::one(), S::zero(), S::zero(), - S::zero(), c, s, - S::zero(), -s, c) + + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + S::one(), S::zero(), S::zero(), + S::zero(), c, s, + S::zero(), -s, c, + ) } /// Create a rotation matrix from a rotation around the `y` axis (yaw). pub fn from_angle_y>>(theta: A) -> Matrix3 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations let (s, c) = Rad::sin_cos(theta.into()); - Matrix3::new(c, S::zero(), -s, - S::zero(), S::one(), S::zero(), - s, S::zero(), c) + + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + c, S::zero(), -s, + S::zero(), S::one(), S::zero(), + s, S::zero(), c, + ) } /// Create a rotation matrix from a rotation around the `z` axis (roll). pub fn from_angle_z>>(theta: A) -> Matrix3 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations let (s, c) = Rad::sin_cos(theta.into()); - Matrix3::new( c, s, S::zero(), - -s, c, S::zero(), - S::zero(), S::zero(), S::one()) + + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + c, s, S::zero(), + -s, c, S::zero(), + S::zero(), S::zero(), S::one(), + ) } /// Create a rotation matrix from an angle around an arbitrary axis. @@ -173,46 +190,62 @@ impl Matrix3 { let (s, c) = Rad::sin_cos(angle.into()); let _1subc = S::one() - c; - Matrix3::new(_1subc * axis.x * axis.x + c, - _1subc * axis.x * axis.y + s * axis.z, - _1subc * axis.x * axis.z - s * axis.y, + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + _1subc * axis.x * axis.x + c, + _1subc * axis.x * axis.y + s * axis.z, + _1subc * axis.x * axis.z - s * axis.y, - _1subc * axis.x * axis.y - s * axis.z, - _1subc * axis.y * axis.y + c, - _1subc * axis.y * axis.z + s * axis.x, + _1subc * axis.x * axis.y - s * axis.z, + _1subc * axis.y * axis.y + c, + _1subc * axis.y * axis.z + s * axis.x, - _1subc * axis.x * axis.z + s * axis.y, - _1subc * axis.y * axis.z - s * axis.x, - _1subc * axis.z * axis.z + c) + _1subc * axis.x * axis.z + s * axis.y, + _1subc * axis.y * axis.z - s * axis.x, + _1subc * axis.z * axis.z + c, + ) } } impl Matrix4 { /// Create a new matrix, providing values for each index. #[inline] - pub fn new(c0r0: S, c0r1: S, c0r2: S, c0r3: S, - c1r0: S, c1r1: S, c1r2: S, c1r3: S, - c2r0: S, c2r1: S, c2r2: S, c2r3: S, - c3r0: S, c3r1: S, c3r2: S, c3r3: S) -> Matrix4 { - Matrix4::from_cols(Vector4::new(c0r0, c0r1, c0r2, c0r3), - Vector4::new(c1r0, c1r1, c1r2, c1r3), - Vector4::new(c2r0, c2r1, c2r2, c2r3), - Vector4::new(c3r0, c3r1, c3r2, c3r3)) + #[cfg_attr(rustfmt, rustfmt_skip)] + pub fn new( + c0r0: S, c0r1: S, c0r2: S, c0r3: S, + c1r0: S, c1r1: S, c1r2: S, c1r3: S, + c2r0: S, c2r1: S, c2r2: S, c2r3: S, + c3r0: S, c3r1: S, c3r2: S, c3r3: S, + ) -> Matrix4 { + Matrix4::from_cols( + Vector4::new(c0r0, c0r1, c0r2, c0r3), + Vector4::new(c1r0, c1r1, c1r2, c1r3), + Vector4::new(c2r0, c2r1, c2r2, c2r3), + Vector4::new(c3r0, c3r1, c3r2, c3r3), + ) } /// Create a new matrix, providing columns. #[inline] pub fn from_cols(c0: Vector4, c1: Vector4, c2: Vector4, c3: Vector4) -> Matrix4 { - Matrix4 { x: c0, y: c1, z: c2, w: c3 } + Matrix4 { + x: c0, + y: c1, + z: c2, + w: c3, + } } /// Create a homogeneous transformation matrix from a translation vector. #[inline] pub fn from_translation(v: Vector3) -> Matrix4 { - Matrix4::new(S::one(), S::zero(), S::zero(), S::zero(), - S::zero(), S::one(), S::zero(), S::zero(), - S::zero(), S::zero(), S::one(), S::zero(), - v.x, v.y, v.z, S::one()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + S::one(), S::zero(), S::zero(), S::zero(), + S::zero(), S::one(), S::zero(), S::zero(), + S::zero(), S::zero(), S::one(), S::zero(), + v.x, v.y, v.z, S::one(), + ) } /// Create a homogeneous transformation matrix from a scale value. @@ -224,10 +257,13 @@ impl Matrix4 { /// Create a homogeneous transformation matrix from a set of scale values. #[inline] pub fn from_nonuniform_scale(x: S, y: S, z: S) -> Matrix4 { - Matrix4::new(x, S::zero(), S::zero(), S::zero(), - S::zero(), y, S::zero(), S::zero(), - S::zero(), S::zero(), z, S::zero(), - S::zero(), S::zero(), S::zero(), S::one()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + x, S::zero(), S::zero(), S::zero(), + S::zero(), y, S::zero(), S::zero(), + S::zero(), S::zero(), z, S::zero(), + S::zero(), S::zero(), S::zero(), S::one(), + ) } /// Create a homogeneous transformation matrix that will cause a vector to point at @@ -237,10 +273,13 @@ impl Matrix4 { let s = f.cross(up).normalize(); let u = s.cross(f); - 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()) + #[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 @@ -253,30 +292,42 @@ impl Matrix4 { pub fn from_angle_x>>(theta: A) -> Matrix4 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations let (s, c) = Rad::sin_cos(theta.into()); - Matrix4::new(S::one(), S::zero(), S::zero(), S::zero(), - S::zero(), c, s, S::zero(), - S::zero(), -s, c, S::zero(), - S::zero(), S::zero(), S::zero(), S::one()) + + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + S::one(), S::zero(), S::zero(), S::zero(), + S::zero(), c, s, S::zero(), + S::zero(), -s, c, S::zero(), + S::zero(), S::zero(), S::zero(), S::one(), + ) } /// Create a homogeneous transformation matrix from a rotation around the `y` axis (yaw). pub fn from_angle_y>>(theta: A) -> Matrix4 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations let (s, c) = Rad::sin_cos(theta.into()); - Matrix4::new(c, S::zero(), -s, S::zero(), - S::zero(), S::one(), S::zero(), S::zero(), - s, S::zero(), c, S::zero(), - S::zero(), S::zero(), S::zero(), S::one()) + + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + c, S::zero(), -s, S::zero(), + S::zero(), S::one(), S::zero(), S::zero(), + s, S::zero(), c, S::zero(), + S::zero(), S::zero(), S::zero(), S::one(), + ) } /// Create a homogeneous transformation matrix from a rotation around the `z` axis (roll). pub fn from_angle_z>>(theta: A) -> Matrix4 { // http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations let (s, c) = Rad::sin_cos(theta.into()); - Matrix4::new( c, s, S::zero(), S::zero(), - -s, c, S::zero(), S::zero(), - S::zero(), S::zero(), S::one(), S::zero(), - S::zero(), S::zero(), S::zero(), S::one()) + + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + c, s, S::zero(), S::zero(), + -s, c, S::zero(), S::zero(), + S::zero(), S::zero(), S::one(), S::zero(), + S::zero(), S::zero(), S::zero(), S::one(), + ) } /// Create a homogeneous transformation matrix from an angle around an arbitrary axis. @@ -286,33 +337,36 @@ impl Matrix4 { let (s, c) = Rad::sin_cos(angle.into()); let _1subc = S::one() - c; - Matrix4::new(_1subc * axis.x * axis.x + c, - _1subc * axis.x * axis.y + s * axis.z, - _1subc * axis.x * axis.z - s * axis.y, - S::zero(), + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + _1subc * axis.x * axis.x + c, + _1subc * axis.x * axis.y + s * axis.z, + _1subc * axis.x * axis.z - s * axis.y, + S::zero(), - _1subc * axis.x * axis.y - s * axis.z, - _1subc * axis.y * axis.y + c, - _1subc * axis.y * axis.z + s * axis.x, - S::zero(), + _1subc * axis.x * axis.y - s * axis.z, + _1subc * axis.y * axis.y + c, + _1subc * axis.y * axis.z + s * axis.x, + S::zero(), - _1subc * axis.x * axis.z + s * axis.y, - _1subc * axis.y * axis.z - s * axis.x, - _1subc * axis.z * axis.z + c, - S::zero(), + _1subc * axis.x * axis.z + s * axis.y, + _1subc * axis.y * axis.z - s * axis.x, + _1subc * axis.z * axis.z + c, + S::zero(), - S::zero(), - S::zero(), - S::zero(), - S::one()) + S::zero(), S::zero(), S::zero(), S::one(), + ) } } impl Zero for Matrix2 { #[inline] fn zero() -> Matrix2 { - Matrix2::new(S::zero(), S::zero(), - S::zero(), S::zero()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix2::new( + S::zero(), S::zero(), + S::zero(), S::zero(), + ) } #[inline] @@ -324,9 +378,12 @@ impl Zero for Matrix2 { impl Zero for Matrix3 { #[inline] fn zero() -> Matrix3 { - Matrix3::new(S::zero(), S::zero(), S::zero(), - S::zero(), S::zero(), S::zero(), - S::zero(), S::zero(), S::zero()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + S::zero(), S::zero(), S::zero(), + S::zero(), S::zero(), S::zero(), + S::zero(), S::zero(), S::zero(), + ) } #[inline] @@ -338,10 +395,13 @@ impl Zero for Matrix3 { impl Zero for Matrix4 { #[inline] fn zero() -> Matrix4 { - Matrix4::new(S::zero(), S::zero(), S::zero(), S::zero(), - S::zero(), S::zero(), S::zero(), S::zero(), - S::zero(), S::zero(), S::zero(), S::zero(), - S::zero(), S::zero(), S::zero(), S::zero()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + S::zero(), S::zero(), S::zero(), S::zero(), + S::zero(), S::zero(), S::zero(), S::zero(), + S::zero(), S::zero(), S::zero(), S::zero(), + S::zero(), S::zero(), S::zero(), S::zero(), + ) } #[inline] @@ -390,8 +450,7 @@ impl Matrix for Matrix2 { #[inline] fn row(&self, r: usize) -> Vector2 { - Vector2::new(self[0][r], - self[1][r]) + Vector2::new(self[0][r], self[1][r]) } #[inline] @@ -413,8 +472,11 @@ impl Matrix for Matrix2 { } fn transpose(&self) -> Matrix2 { - Matrix2::new(self[0][0], self[1][0], - self[0][1], self[1][1]) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix2::new( + self[0][0], self[1][0], + self[0][1], self[1][1], + ) } } @@ -423,14 +485,20 @@ impl SquareMatrix for Matrix2 { #[inline] fn from_value(value: S) -> Matrix2 { - Matrix2::new(value, S::zero(), - S::zero(), value) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix2::new( + value, S::zero(), + S::zero(), value, + ) } #[inline] fn from_diagonal(value: Vector2) -> Matrix2 { - Matrix2::new(value.x, S::zero(), - S::zero(), value.y) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix2::new( + value.x, S::zero(), + S::zero(), value.y, + ) } #[inline] @@ -445,8 +513,7 @@ impl SquareMatrix for Matrix2 { #[inline] fn diagonal(&self) -> Vector2 { - Vector2::new(self[0][0], - self[1][1]) + Vector2::new(self[0][0], self[1][1]) } #[inline] @@ -455,24 +522,22 @@ impl SquareMatrix for Matrix2 { if det == S::zero() { None } else { - Some(Matrix2::new(self[1][1] / det, - -self[0][1] / det, - -self[1][0] / det, - self[0][0] / det)) + #[cfg_attr(rustfmt, rustfmt_skip)] + Some(Matrix2::new( + self[1][1] / det, -self[0][1] / det, + -self[1][0] / det, self[0][0] / det, + )) } } #[inline] fn is_diagonal(&self) -> bool { - ulps_eq!(self[0][1], &S::zero()) && - ulps_eq!(self[1][0], &S::zero()) + ulps_eq!(self[0][1], &S::zero()) && ulps_eq!(self[1][0], &S::zero()) } - #[inline] fn is_symmetric(&self) -> bool { - ulps_eq!(self[0][1], &self[1][0]) && - ulps_eq!(self[1][0], &self[0][1]) + ulps_eq!(self[0][1], &self[1][0]) && ulps_eq!(self[1][0], &self[0][1]) } } @@ -483,9 +548,7 @@ impl Matrix for Matrix3 { #[inline] fn row(&self, r: usize) -> Vector3 { - Vector3::new(self[0][r], - self[1][r], - self[2][r]) + Vector3::new(self[0][r], self[1][r], self[2][r]) } #[inline] @@ -508,9 +571,12 @@ impl Matrix for Matrix3 { } fn transpose(&self) -> Matrix3 { - Matrix3::new(self[0][0], self[1][0], self[2][0], - self[0][1], self[1][1], self[2][1], - self[0][2], self[1][2], self[2][2]) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + self[0][0], self[1][0], self[2][0], + self[0][1], self[1][1], self[2][1], + self[0][2], self[1][2], self[2][2], + ) } } @@ -519,16 +585,22 @@ impl SquareMatrix for Matrix3 { #[inline] fn from_value(value: S) -> Matrix3 { - Matrix3::new(value, S::zero(), S::zero(), - S::zero(), value, S::zero(), - S::zero(), S::zero(), value) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + value, S::zero(), S::zero(), + S::zero(), value, S::zero(), + S::zero(), S::zero(), value, + ) } #[inline] fn from_diagonal(value: Vector3) -> Matrix3 { - Matrix3::new(value.x, S::zero(), S::zero(), - S::zero(), value.y, S::zero(), - S::zero(), S::zero(), value.z) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + value.x, S::zero(), S::zero(), + S::zero(), value.y, S::zero(), + S::zero(), S::zero(), value.z, + ) } #[inline] @@ -539,16 +611,14 @@ impl SquareMatrix for Matrix3 { } fn determinant(&self) -> S { - self[0][0] * (self[1][1] * self[2][2] - self[2][1] * self[1][2]) - - self[1][0] * (self[0][1] * self[2][2] - self[2][1] * self[0][2]) + - self[2][0] * (self[0][1] * self[1][2] - self[1][1] * self[0][2]) + self[0][0] * (self[1][1] * self[2][2] - self[2][1] * self[1][2]) + - self[1][0] * (self[0][1] * self[2][2] - self[2][1] * self[0][2]) + + self[2][0] * (self[0][1] * self[1][2] - self[1][1] * self[0][2]) } #[inline] fn diagonal(&self) -> Vector3 { - Vector3::new(self[0][0], - self[1][1], - self[2][2]) + Vector3::new(self[0][0], self[1][1], self[2][2]) } fn invert(&self) -> Option> { @@ -556,32 +626,26 @@ impl SquareMatrix for Matrix3 { if det == S::zero() { None } else { - Some(Matrix3::from_cols(self[1].cross(self[2]) / det, - self[2].cross(self[0]) / det, - self[0].cross(self[1]) / det).transpose()) + Some( + Matrix3::from_cols( + self[1].cross(self[2]) / det, + self[2].cross(self[0]) / det, + self[0].cross(self[1]) / det, + ).transpose(), + ) } } fn is_diagonal(&self) -> bool { - ulps_eq!(self[0][1], &S::zero()) && - ulps_eq!(self[0][2], &S::zero()) && - - ulps_eq!(self[1][0], &S::zero()) && - ulps_eq!(self[1][2], &S::zero()) && - - ulps_eq!(self[2][0], &S::zero()) && - ulps_eq!(self[2][1], &S::zero()) + ulps_eq!(self[0][1], &S::zero()) && ulps_eq!(self[0][2], &S::zero()) + && ulps_eq!(self[1][0], &S::zero()) && ulps_eq!(self[1][2], &S::zero()) + && ulps_eq!(self[2][0], &S::zero()) && ulps_eq!(self[2][1], &S::zero()) } fn is_symmetric(&self) -> bool { - ulps_eq!(self[0][1], &self[1][0]) && - ulps_eq!(self[0][2], &self[2][0]) && - - ulps_eq!(self[1][0], &self[0][1]) && - ulps_eq!(self[1][2], &self[2][1]) && - - ulps_eq!(self[2][0], &self[0][2]) && - ulps_eq!(self[2][1], &self[1][2]) + ulps_eq!(self[0][1], &self[1][0]) && ulps_eq!(self[0][2], &self[2][0]) + && ulps_eq!(self[1][0], &self[0][1]) && ulps_eq!(self[1][2], &self[2][1]) + && ulps_eq!(self[2][0], &self[0][2]) && ulps_eq!(self[2][1], &self[1][2]) } } @@ -592,10 +656,7 @@ impl Matrix for Matrix4 { #[inline] fn row(&self, r: usize) -> Vector4 { - Vector4::new(self[0][r], - self[1][r], - self[2][r], - self[3][r]) + Vector4::new(self[0][r], self[1][r], self[2][r], self[3][r]) } #[inline] @@ -619,31 +680,39 @@ impl Matrix for Matrix4 { } fn transpose(&self) -> Matrix4 { - Matrix4::new(self[0][0], self[1][0], self[2][0], self[3][0], - self[0][1], self[1][1], self[2][1], self[3][1], - self[0][2], self[1][2], self[2][2], self[3][2], - self[0][3], self[1][3], self[2][3], self[3][3]) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + self[0][0], self[1][0], self[2][0], self[3][0], + self[0][1], self[1][1], self[2][1], self[3][1], + self[0][2], self[1][2], self[2][2], self[3][2], + self[0][3], self[1][3], self[2][3], self[3][3], + ) } } - impl SquareMatrix for Matrix4 { type ColumnRow = Vector4; #[inline] fn from_value(value: S) -> Matrix4 { - Matrix4::new(value, S::zero(), S::zero(), S::zero(), - S::zero(), value, S::zero(), S::zero(), - S::zero(), S::zero(), value, S::zero(), - S::zero(), S::zero(), S::zero(), value) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + value, S::zero(), S::zero(), S::zero(), + S::zero(), value, S::zero(), S::zero(), + S::zero(), S::zero(), value, S::zero(), + S::zero(), S::zero(), S::zero(), value, + ) } #[inline] fn from_diagonal(value: Vector4) -> Matrix4 { - Matrix4::new(value.x, S::zero(), S::zero(), S::zero(), - S::zero(), value.y, S::zero(), S::zero(), - S::zero(), S::zero(), value.z, S::zero(), - S::zero(), S::zero(), S::zero(), value.w) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + value.x, S::zero(), S::zero(), S::zero(), + S::zero(), value.y, S::zero(), S::zero(), + S::zero(), S::zero(), value.z, S::zero(), + S::zero(), S::zero(), S::zero(), value.w, + ) } fn transpose_self(&mut self) { @@ -656,18 +725,13 @@ impl SquareMatrix for Matrix4 { } fn determinant(&self) -> S { - let tmp = unsafe { - det_sub_proc_unsafe(self, 1, 2, 3) - }; + let tmp = unsafe { det_sub_proc_unsafe(self, 1, 2, 3) }; tmp.dot(Vector4::new(self[0][0], self[1][0], self[2][0], self[3][0])) } #[inline] fn diagonal(&self) -> Vector4 { - Vector4::new(self[0][0], - self[1][1], - self[2][2], - self[3][3]) + Vector4::new(self[0][0], self[1][1], self[2][2], self[3][3]) } // The new implementation results in negative optimization when used @@ -685,27 +749,40 @@ impl SquareMatrix for Matrix4 { let t = self.transpose(); let cf = |i, j| { let mat = match i { - 0 => Matrix3::from_cols(t.y.truncate_n(j), t.z.truncate_n(j), t.w.truncate_n(j)), - 1 => Matrix3::from_cols(t.x.truncate_n(j), t.z.truncate_n(j), t.w.truncate_n(j)), - 2 => Matrix3::from_cols(t.x.truncate_n(j), t.y.truncate_n(j), t.w.truncate_n(j)), - 3 => Matrix3::from_cols(t.x.truncate_n(j), t.y.truncate_n(j), t.z.truncate_n(j)), + 0 => { + Matrix3::from_cols(t.y.truncate_n(j), t.z.truncate_n(j), t.w.truncate_n(j)) + } + 1 => { + Matrix3::from_cols(t.x.truncate_n(j), t.z.truncate_n(j), t.w.truncate_n(j)) + } + 2 => { + Matrix3::from_cols(t.x.truncate_n(j), t.y.truncate_n(j), t.w.truncate_n(j)) + } + 3 => { + Matrix3::from_cols(t.x.truncate_n(j), t.y.truncate_n(j), t.z.truncate_n(j)) + } _ => panic!("out of range"), }; - let sign = if (i + j) & 1 == 1 { -S::one() } else { S::one() }; + let sign = if (i + j) & 1 == 1 { + -S::one() + } else { + S::one() + }; mat.determinant() * sign * inv_det }; - Some(Matrix4::new(cf(0, 0), cf(0, 1), cf(0, 2), cf(0, 3), - cf(1, 0), cf(1, 1), cf(1, 2), cf(1, 3), - cf(2, 0), cf(2, 1), cf(2, 2), cf(2, 3), - cf(3, 0), cf(3, 1), cf(3, 2), cf(3, 3))) + #[cfg_attr(rustfmt, rustfmt_skip)] + Some(Matrix4::new( + cf(0, 0), cf(0, 1), cf(0, 2), cf(0, 3), + cf(1, 0), cf(1, 1), cf(1, 2), cf(1, 3), + cf(2, 0), cf(2, 1), cf(2, 2), cf(2, 3), + cf(3, 0), cf(3, 1), cf(3, 2), cf(3, 3), + )) } } #[cfg(feature = "simd")] fn invert(&self) -> Option> { - let tmp0 = unsafe { - det_sub_proc_unsafe(self, 1, 2, 3) - }; + let tmp0 = unsafe { det_sub_proc_unsafe(self, 1, 2, 3) }; let det = tmp0.dot(Vector4::new(self[0][0], self[1][0], self[2][0], self[3][0])); if det == S::zero() { @@ -713,53 +790,29 @@ impl SquareMatrix for Matrix4 { } else { let inv_det = S::one() / det; let tmp0 = tmp0 * inv_det; - let tmp1 = unsafe { - det_sub_proc_unsafe(self, 0, 3, 2) * inv_det - }; - let tmp2 = unsafe { - det_sub_proc_unsafe(self, 0, 1, 3) * inv_det - }; - let tmp3 = unsafe { - det_sub_proc_unsafe(self, 0, 2, 1) * inv_det - }; + let tmp1 = unsafe { det_sub_proc_unsafe(self, 0, 3, 2) * inv_det }; + let tmp2 = unsafe { det_sub_proc_unsafe(self, 0, 1, 3) * inv_det }; + let tmp3 = unsafe { det_sub_proc_unsafe(self, 0, 2, 1) * inv_det }; Some(Matrix4::from_cols(tmp0, tmp1, tmp2, tmp3)) } } fn is_diagonal(&self) -> bool { - ulps_eq!(self[0][1], &S::zero()) && - ulps_eq!(self[0][2], &S::zero()) && - ulps_eq!(self[0][3], &S::zero()) && - - ulps_eq!(self[1][0], &S::zero()) && - ulps_eq!(self[1][2], &S::zero()) && - ulps_eq!(self[1][3], &S::zero()) && - - ulps_eq!(self[2][0], &S::zero()) && - ulps_eq!(self[2][1], &S::zero()) && - ulps_eq!(self[2][3], &S::zero()) && - - ulps_eq!(self[3][0], &S::zero()) && - ulps_eq!(self[3][1], &S::zero()) && - ulps_eq!(self[3][2], &S::zero()) + ulps_eq!(self[0][1], &S::zero()) && ulps_eq!(self[0][2], &S::zero()) + && ulps_eq!(self[0][3], &S::zero()) && ulps_eq!(self[1][0], &S::zero()) + && ulps_eq!(self[1][2], &S::zero()) && ulps_eq!(self[1][3], &S::zero()) + && ulps_eq!(self[2][0], &S::zero()) && ulps_eq!(self[2][1], &S::zero()) + && ulps_eq!(self[2][3], &S::zero()) && ulps_eq!(self[3][0], &S::zero()) + && ulps_eq!(self[3][1], &S::zero()) && ulps_eq!(self[3][2], &S::zero()) } fn is_symmetric(&self) -> bool { - ulps_eq!(self[0][1], &self[1][0]) && - ulps_eq!(self[0][2], &self[2][0]) && - ulps_eq!(self[0][3], &self[3][0]) && - - ulps_eq!(self[1][0], &self[0][1]) && - ulps_eq!(self[1][2], &self[2][1]) && - ulps_eq!(self[1][3], &self[3][1]) && - - ulps_eq!(self[2][0], &self[0][2]) && - ulps_eq!(self[2][1], &self[1][2]) && - ulps_eq!(self[2][3], &self[3][2]) && - - ulps_eq!(self[3][0], &self[0][3]) && - ulps_eq!(self[3][1], &self[1][3]) && - ulps_eq!(self[3][2], &self[2][3]) + ulps_eq!(self[0][1], &self[1][0]) && ulps_eq!(self[0][2], &self[2][0]) + && ulps_eq!(self[0][3], &self[3][0]) && ulps_eq!(self[1][0], &self[0][1]) + && ulps_eq!(self[1][2], &self[2][1]) && ulps_eq!(self[1][3], &self[3][1]) + && ulps_eq!(self[2][0], &self[0][2]) && ulps_eq!(self[2][1], &self[1][2]) + && ulps_eq!(self[2][3], &self[3][2]) && ulps_eq!(self[3][0], &self[0][3]) + && ulps_eq!(self[3][1], &self[1][3]) && ulps_eq!(self[3][2], &self[2][3]) } } @@ -783,14 +836,14 @@ impl ApproxEq for Matrix2 { #[inline] fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool { - Vector2::relative_eq(&self[0], &other[0], epsilon, max_relative) && - Vector2::relative_eq(&self[1], &other[1], epsilon, max_relative) + Vector2::relative_eq(&self[0], &other[0], epsilon, max_relative) + && Vector2::relative_eq(&self[1], &other[1], epsilon, max_relative) } #[inline] fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool { - Vector2::ulps_eq(&self[0], &other[0], epsilon, max_ulps) && - Vector2::ulps_eq(&self[1], &other[1], epsilon, max_ulps) + Vector2::ulps_eq(&self[0], &other[0], epsilon, max_ulps) + && Vector2::ulps_eq(&self[1], &other[1], epsilon, max_ulps) } } @@ -814,16 +867,16 @@ impl ApproxEq for Matrix3 { #[inline] fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool { - Vector3::relative_eq(&self[0], &other[0], epsilon, max_relative) && - Vector3::relative_eq(&self[1], &other[1], epsilon, max_relative) && - Vector3::relative_eq(&self[2], &other[2], epsilon, max_relative) + Vector3::relative_eq(&self[0], &other[0], epsilon, max_relative) + && Vector3::relative_eq(&self[1], &other[1], epsilon, max_relative) + && Vector3::relative_eq(&self[2], &other[2], epsilon, max_relative) } #[inline] fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool { - Vector3::ulps_eq(&self[0], &other[0], epsilon, max_ulps) && - Vector3::ulps_eq(&self[1], &other[1], epsilon, max_ulps) && - Vector3::ulps_eq(&self[2], &other[2], epsilon, max_ulps) + Vector3::ulps_eq(&self[0], &other[0], epsilon, max_ulps) + && Vector3::ulps_eq(&self[1], &other[1], epsilon, max_ulps) + && Vector3::ulps_eq(&self[2], &other[2], epsilon, max_ulps) } } @@ -847,99 +900,99 @@ impl ApproxEq for Matrix4 { #[inline] fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool { - Vector4::relative_eq(&self[0], &other[0], epsilon, max_relative) && - Vector4::relative_eq(&self[1], &other[1], epsilon, max_relative) && - Vector4::relative_eq(&self[2], &other[2], epsilon, max_relative) && - Vector4::relative_eq(&self[3], &other[3], epsilon, max_relative) + Vector4::relative_eq(&self[0], &other[0], epsilon, max_relative) + && Vector4::relative_eq(&self[1], &other[1], epsilon, max_relative) + && Vector4::relative_eq(&self[2], &other[2], epsilon, max_relative) + && Vector4::relative_eq(&self[3], &other[3], epsilon, max_relative) } #[inline] fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool { - Vector4::ulps_eq(&self[0], &other[0], epsilon, max_ulps) && - Vector4::ulps_eq(&self[1], &other[1], epsilon, max_ulps) && - Vector4::ulps_eq(&self[2], &other[2], epsilon, max_ulps) && - Vector4::ulps_eq(&self[3], &other[3], epsilon, max_ulps) + Vector4::ulps_eq(&self[0], &other[0], epsilon, max_ulps) + && Vector4::ulps_eq(&self[1], &other[1], epsilon, max_ulps) + && Vector4::ulps_eq(&self[2], &other[2], epsilon, max_ulps) + && Vector4::ulps_eq(&self[3], &other[3], epsilon, max_ulps) } } impl Transform> for Matrix3 { - fn one() -> Matrix3 { - One::one() - } - - fn look_at(eye: Point2, center: Point2, up: Vector2) -> Matrix3 { - let dir = center - eye; - Matrix3::from(Matrix2::look_at(dir, up)) - } - - fn transform_vector(&self, vec: Vector2) -> Vector2 { - (self * vec.extend(S::zero())).truncate() - } - - fn transform_point(&self, point: Point2) -> Point2 { - Point2::from_vec((self * Point3::new(point.x, point.y, S::one()).to_vec()).truncate()) - } - - fn concat(&self, other: &Matrix3) -> Matrix3 { - self * other - } - - fn inverse_transform(&self) -> Option> { - SquareMatrix::invert(self) - } + fn one() -> Matrix3 { + One::one() + } + + fn look_at(eye: Point2, center: Point2, up: Vector2) -> Matrix3 { + let dir = center - eye; + Matrix3::from(Matrix2::look_at(dir, up)) + } + + fn transform_vector(&self, vec: Vector2) -> Vector2 { + (self * vec.extend(S::zero())).truncate() + } + + fn transform_point(&self, point: Point2) -> Point2 { + Point2::from_vec((self * Point3::new(point.x, point.y, S::one()).to_vec()).truncate()) + } + + fn concat(&self, other: &Matrix3) -> Matrix3 { + self * other + } + + fn inverse_transform(&self) -> Option> { + SquareMatrix::invert(self) + } } impl Transform> for Matrix3 { - fn one() -> Matrix3 { - One::one() - } - - fn look_at(eye: Point3, center: Point3, up: Vector3) -> Matrix3 { - let dir = center - eye; - Matrix3::look_at(dir, up) - } - - fn transform_vector(&self, vec: Vector3) -> Vector3 { - self * vec - } - - fn transform_point(&self, point: Point3) -> Point3 { - Point3::from_vec(self * point.to_vec()) - } - - fn concat(&self, other: &Matrix3) -> Matrix3 { - self * other - } - - fn inverse_transform(&self) -> Option> { - SquareMatrix::invert(self) - } + fn one() -> Matrix3 { + One::one() + } + + fn look_at(eye: Point3, center: Point3, up: Vector3) -> Matrix3 { + let dir = center - eye; + Matrix3::look_at(dir, up) + } + + fn transform_vector(&self, vec: Vector3) -> Vector3 { + self * vec + } + + fn transform_point(&self, point: Point3) -> Point3 { + Point3::from_vec(self * point.to_vec()) + } + + fn concat(&self, other: &Matrix3) -> Matrix3 { + self * other + } + + fn inverse_transform(&self) -> Option> { + SquareMatrix::invert(self) + } } impl Transform> for Matrix4 { - fn one() -> Matrix4 { - One::one() - } + fn one() -> Matrix4 { + One::one() + } - fn look_at(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { - Matrix4::look_at(eye, center, up) - } + fn look_at(eye: Point3, center: Point3, up: Vector3) -> Matrix4 { + Matrix4::look_at(eye, center, up) + } - fn transform_vector(&self, vec: Vector3) -> Vector3 { - (self * vec.extend(S::zero())).truncate() - } + fn transform_vector(&self, vec: Vector3) -> Vector3 { + (self * vec.extend(S::zero())).truncate() + } - fn transform_point(&self, point: Point3) -> Point3 { - Point3::from_homogeneous(self * point.to_homogeneous()) - } + fn transform_point(&self, point: Point3) -> Point3 { + Point3::from_homogeneous(self * point.to_homogeneous()) + } - fn concat(&self, other: &Matrix4) -> Matrix4 { - self * other - } + fn concat(&self, other: &Matrix4) -> Matrix4 { + self * other + } - fn inverse_transform(&self) -> Option> { - SquareMatrix::invert(self) - } + fn inverse_transform(&self) -> Option> { + SquareMatrix::invert(self) + } } impl Transform2 for Matrix3 {} @@ -1060,6 +1113,7 @@ macro_rules! impl_scalar_ops { impl_matrix!(Matrix2, Vector2 { x: 0, y: 1 }); impl_matrix!(Matrix3, Vector3 { x: 0, y: 1, z: 2 }); +#[cfg_attr(rustfmt, rustfmt_skip)] impl_matrix!(Matrix4, Vector4 { x: 0, y: 1, z: 2, w: 3 }); macro_rules! impl_mv_operator { @@ -1073,7 +1127,9 @@ macro_rules! impl_mv_operator { impl_mv_operator!(Matrix2, Vector2 { x: 0, y: 1 }); impl_mv_operator!(Matrix3, Vector3 { x: 0, y: 1, z: 2 }); #[cfg(not(feature = "simd"))] +#[cfg_attr(rustfmt, rustfmt_skip)] impl_mv_operator!(Matrix4, Vector4 { x: 0, y: 1, z: 2, w: 3 }); + #[cfg(feature = "simd")] impl_operator!( Mul > for Matrix4 { fn mul(matrix, vector) -> Vector4 { @@ -1109,6 +1165,8 @@ impl_operator!( Mul > for Matrix4 { let b = lhs[1]; let c = lhs[2]; let d = lhs[3]; + + #[cfg_attr(rustfmt, rustfmt_skip)] Matrix4::from_cols( a*rhs[0][0] + b*rhs[0][1] + c*rhs[0][2] + d*rhs[0][3], a*rhs[1][0] + b*rhs[1][1] + c*rhs[1][2] + d*rhs[1][3], @@ -1157,7 +1215,8 @@ index_operators!(Matrix4, 4, Vector4, usize); // index_operators!(Matrix3, 3, [Vector3], RangeFull); // index_operators!(Matrix4, 4, [Vector4], RangeFull); -impl From> for Matrix3 where +impl From> for Matrix3 +where A: Angle + Into::Unitless>>, { fn from(src: Euler) -> Matrix3 { @@ -1166,13 +1225,17 @@ impl From> for Matrix3 where let (sy, cy) = Rad::sin_cos(src.y.into()); let (sz, cz) = Rad::sin_cos(src.z.into()); - Matrix3::new(cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz, - -cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz, - sy, -sx * cy, cx * cy) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz, + -cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz, + sy, -sx * cy, cx * cy, + ) } } -impl From> for Matrix4 where +impl From> for Matrix4 +where A: Angle + Into::Unitless>>, { fn from(src: Euler) -> Matrix4 { @@ -1181,10 +1244,13 @@ impl From> for Matrix4 where let (sy, cy) = Rad::sin_cos(src.y.into()); let (sz, cz) = Rad::sin_cos(src.z.into()); - Matrix4::new(cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz, A::Unitless::zero(), - -cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz, A::Unitless::zero(), - sy, -sx * cy, cx * cy, A::Unitless::zero(), - A::Unitless::zero(), A::Unitless::zero(), A::Unitless::zero(), A::Unitless::one()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz, A::Unitless::zero(), + -cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz, A::Unitless::zero(), + sy, -sx * cy, cx * cy, A::Unitless::zero(), + A::Unitless::zero(), A::Unitless::zero(), A::Unitless::zero(), A::Unitless::one(), + ) } } @@ -1314,9 +1380,12 @@ impl From> for Matrix3 { /// Clone the elements of a 2-dimensional matrix into the top-left corner /// of a 3-dimensional identity matrix. fn from(m: Matrix2) -> Matrix3 { - Matrix3::new(m[0][0], m[0][1], S::zero(), - m[1][0], m[1][1], S::zero(), - S::zero(), S::zero(), S::one()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + m[0][0], m[0][1], S::zero(), + m[1][0], m[1][1], S::zero(), + S::zero(), S::zero(), S::one(), + ) } } @@ -1324,10 +1393,13 @@ impl From> for Matrix4 { /// Clone the elements of a 2-dimensional matrix into the top-left corner /// of a 4-dimensional identity matrix. fn from(m: Matrix2) -> Matrix4 { - Matrix4::new(m[0][0], m[0][1], S::zero(), S::zero(), - m[1][0], m[1][1], S::zero(), S::zero(), - S::zero(), S::zero(), S::one(), S::zero(), - S::zero(), S::zero(), S::zero(), S::one()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + m[0][0], m[0][1], S::zero(), S::zero(), + m[1][0], m[1][1], S::zero(), S::zero(), + S::zero(), S::zero(), S::one(), S::zero(), + S::zero(), S::zero(), S::zero(), S::one(), + ) } } @@ -1335,10 +1407,13 @@ impl From> for Matrix4 { /// Clone the elements of a 3-dimensional matrix into the top-left corner /// of a 4-dimensional identity matrix. fn from(m: Matrix3) -> Matrix4 { - Matrix4::new(m[0][0], m[0][1], m[0][2], S::zero(), - m[1][0], m[1][1], m[1][2], S::zero(), - m[2][0], m[2][1], m[2][2], S::zero(), - S::zero(), S::zero(), S::zero(), S::one()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + m[0][0], m[0][1], m[0][2], S::zero(), + m[1][0], m[1][1], m[1][2], S::zero(), + m[2][0], m[2][1], m[2][2], S::zero(), + S::zero(), S::zero(), S::zero(), S::one(), + ) } } @@ -1409,39 +1484,101 @@ impl fmt::Debug for Matrix4 { impl Rand for Matrix2 { #[inline] fn rand(rng: &mut R) -> Matrix2 { - Matrix2{ x: rng.gen(), y: rng.gen() } + Matrix2 { + x: rng.gen(), + y: rng.gen(), + } } } impl Rand for Matrix3 { #[inline] fn rand(rng: &mut R) -> Matrix3 { - Matrix3{ x: rng.gen(), y: rng.gen(), z: rng.gen() } + Matrix3 { + x: rng.gen(), + y: rng.gen(), + z: rng.gen(), + } } } impl Rand for Matrix4 { #[inline] fn rand(rng: &mut R) -> Matrix4 { - Matrix4{ x: rng.gen(), y: rng.gen(), z: rng.gen(), w: rng.gen() } + Matrix4 { + x: rng.gen(), + y: rng.gen(), + z: rng.gen(), + w: rng.gen(), + } } } // Sub procedure for SIMD when dealing with determinant and inversion #[inline] -unsafe fn det_sub_proc_unsafe(m: &Matrix4, x: usize, y: usize, z: usize) -> Vector4 { +unsafe fn det_sub_proc_unsafe( + m: &Matrix4, + x: usize, + y: usize, + z: usize, +) -> Vector4 { let s: &[S; 16] = m.as_ref(); - let a = Vector4::new(*s.get_unchecked(4 + x), *s.get_unchecked(12 + x), *s.get_unchecked(x), *s.get_unchecked(8 + x)); - let b = Vector4::new(*s.get_unchecked(8 + y), *s.get_unchecked(8 + y), *s.get_unchecked(4 + y), *s.get_unchecked(4 + y)); - let c = Vector4::new(*s.get_unchecked(12 + z), *s.get_unchecked(z), *s.get_unchecked(12 + z), *s.get_unchecked(z)); - - let d = Vector4::new(*s.get_unchecked(8 + x), *s.get_unchecked(8 + x), *s.get_unchecked(4 + x), *s.get_unchecked(4 + x)); - let e = Vector4::new(*s.get_unchecked(12 + y), *s.get_unchecked(y), *s.get_unchecked(12 + y), *s.get_unchecked(y)); - let f = Vector4::new(*s.get_unchecked(4 + z), *s.get_unchecked(12 + z), *s.get_unchecked(z), *s.get_unchecked(8 + z)); - - let g = Vector4::new(*s.get_unchecked(12 + x), *s.get_unchecked(x), *s.get_unchecked(12 + x), *s.get_unchecked(x)); - let h = Vector4::new(*s.get_unchecked(4 + y), *s.get_unchecked(12 + y), *s.get_unchecked(y), *s.get_unchecked(8 + y)); - let i = Vector4::new(*s.get_unchecked(8 + z), *s.get_unchecked(8 + z), *s.get_unchecked(4 + z), *s.get_unchecked(4 + z)); + let a = Vector4::new( + *s.get_unchecked(4 + x), + *s.get_unchecked(12 + x), + *s.get_unchecked(x), + *s.get_unchecked(8 + x), + ); + let b = Vector4::new( + *s.get_unchecked(8 + y), + *s.get_unchecked(8 + y), + *s.get_unchecked(4 + y), + *s.get_unchecked(4 + y), + ); + let c = Vector4::new( + *s.get_unchecked(12 + z), + *s.get_unchecked(z), + *s.get_unchecked(12 + z), + *s.get_unchecked(z), + ); + + let d = Vector4::new( + *s.get_unchecked(8 + x), + *s.get_unchecked(8 + x), + *s.get_unchecked(4 + x), + *s.get_unchecked(4 + x), + ); + let e = Vector4::new( + *s.get_unchecked(12 + y), + *s.get_unchecked(y), + *s.get_unchecked(12 + y), + *s.get_unchecked(y), + ); + let f = Vector4::new( + *s.get_unchecked(4 + z), + *s.get_unchecked(12 + z), + *s.get_unchecked(z), + *s.get_unchecked(8 + z), + ); + + let g = Vector4::new( + *s.get_unchecked(12 + x), + *s.get_unchecked(x), + *s.get_unchecked(12 + x), + *s.get_unchecked(x), + ); + let h = Vector4::new( + *s.get_unchecked(4 + y), + *s.get_unchecked(12 + y), + *s.get_unchecked(y), + *s.get_unchecked(8 + y), + ); + let i = Vector4::new( + *s.get_unchecked(8 + z), + *s.get_unchecked(8 + z), + *s.get_unchecked(4 + z), + *s.get_unchecked(4 + z), + ); let mut tmp = a.mul_element_wise(b.mul_element_wise(c)); tmp += d.mul_element_wise(e.mul_element_wise(f)); tmp += g.mul_element_wise(h.mul_element_wise(i)); diff --git a/src/num.rs b/src/num.rs index 0e4eefce..bcf57f54 100644 --- a/src/num.rs +++ b/src/num.rs @@ -21,11 +21,41 @@ use std::ops::*; use num_traits::{Float, Num, NumCast}; /// Base numeric types with partial ordering -pub trait BaseNum: Copy + Clone + fmt::Debug + Num + NumCast + PartialOrd + AddAssign + SubAssign + MulAssign + DivAssign + RemAssign {} +pub trait BaseNum + : Copy + + Clone + + fmt::Debug + + Num + + NumCast + + PartialOrd + + AddAssign + + SubAssign + + MulAssign + + DivAssign + + RemAssign { +} -impl BaseNum for T where T: Copy + Clone + fmt::Debug + Num + NumCast + PartialOrd + AddAssign + SubAssign + MulAssign + DivAssign + RemAssign {} +impl BaseNum for T +where + T: Copy + + Clone + + fmt::Debug + + Num + + NumCast + + PartialOrd + + AddAssign + + SubAssign + + MulAssign + + DivAssign + + RemAssign, +{ +} /// Base floating point types pub trait BaseFloat: BaseNum + Float + ApproxEq {} -impl BaseFloat for T where T: BaseNum + Float + ApproxEq {} +impl BaseFloat for T +where + T: BaseNum + Float + ApproxEq, +{ +} diff --git a/src/point.rs b/src/point.rs index 21e5f0aa..62a8ea6a 100644 --- a/src/point.rs +++ b/src/point.rs @@ -17,7 +17,7 @@ //! distinguishes them from vectors, which have a length and direction, but do //! not have a fixed position. -use num_traits::{NumCast, Bounded}; +use num_traits::{Bounded, NumCast}; use std::fmt; use std::mem; use std::ops::*; @@ -25,7 +25,7 @@ use std::ops::*; use structure::*; use approx::ApproxEq; -use num::{BaseNum, BaseFloat}; +use num::{BaseFloat, BaseNum}; use vector::{Vector1, Vector2, Vector3, Vector4}; #[cfg(feature = "mint")] @@ -95,7 +95,7 @@ impl Point3 { #[inline] pub fn from_homogeneous(v: Vector4) -> Point3 { let e = v.truncate() * (S::one() / v.w); - Point3::new(e.x, e.y, e.z) //FIXME + Point3::new(e.x, e.y, e.z) //FIXME } #[inline] diff --git a/src/projection.rs b/src/projection.rs index 294c3b30..cd515f68 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use num_traits::{Zero}; +use num_traits::Zero; use num_traits::cast; use structure::Angle; @@ -26,12 +26,17 @@ use num::BaseFloat; /// /// This is the equivalent to the [gluPerspective] /// (http://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml) function. -pub fn perspective>>(fovy: A, aspect: S, near: S, far: S) -> Matrix4 { +pub fn perspective>>( + fovy: A, + aspect: S, + near: S, + far: S, +) -> Matrix4 { PerspectiveFov { - fovy: fovy.into(), + fovy: fovy.into(), aspect: aspect, - near: near, - far: far, + near: near, + far: far, }.into() } @@ -41,12 +46,12 @@ pub fn perspective>>(fovy: A, aspect: S, near: S, f /// (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function. pub fn frustum(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4 { Perspective { - left: left, - right: right, + left: left, + right: right, bottom: bottom, - top: top, - near: near, - far: far, + top: top, + near: near, + far: far, }.into() } @@ -56,12 +61,12 @@ pub fn frustum(left: S, right: S, bottom: S, top: S, near: S, far: /// (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function. pub fn ortho(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4 { Ortho { - left: left, - right: right, + left: left, + right: right, bottom: bottom, - top: top, - near: near, - far: far, + top: top, + near: near, + far: far, }.into() } @@ -70,10 +75,10 @@ pub fn ortho(left: S, right: S, bottom: S, top: S, near: S, far: S #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct PerspectiveFov { - pub fovy: Rad, + pub fovy: Rad, pub aspect: S, - pub near: S, - pub far: S, + pub near: S, + pub far: S, } impl PerspectiveFov { @@ -84,24 +89,49 @@ impl PerspectiveFov { let xmax = ymax * self.aspect; Perspective { - left: -xmax, - right: xmax, + left: -xmax, + right: xmax, bottom: -ymax, - top: ymax, - near: self.near.clone(), - far: self.far.clone(), + top: ymax, + near: self.near.clone(), + far: self.far.clone(), } } } impl From> for Matrix4 { fn from(persp: PerspectiveFov) -> Matrix4 { - assert!(persp.fovy > Rad::zero(), "The vertical field of view cannot be below zero, found: {:?}", persp.fovy); - assert!(persp.fovy < Rad::turn_div_2(), "The vertical field of view cannot be greater than a half turn, found: {:?}", persp.fovy); - assert!(persp.aspect > S::zero(), "The aspect ratio cannot be below zero, found: {:?}", persp.aspect); - assert!(persp.near > S::zero(), "The near plane distance cannot be below zero, found: {:?}", persp.near); - assert!(persp.far > S::zero(), "The far plane distance cannot be below zero, found: {:?}", persp.far); - assert!(persp.far > persp.near, "The far plane cannot be closer than the near plane, found: far: {:?}, near: {:?}", persp.far, persp.near); + assert!( + persp.fovy > Rad::zero(), + "The vertical field of view cannot be below zero, found: {:?}", + persp.fovy + ); + assert!( + persp.fovy < Rad::turn_div_2(), + "The vertical field of view cannot be greater than a half turn, found: {:?}", + persp.fovy + ); + assert!( + persp.aspect > S::zero(), + "The aspect ratio cannot be below zero, found: {:?}", + persp.aspect + ); + assert!( + persp.near > S::zero(), + "The near plane distance cannot be below zero, found: {:?}", + persp.near + ); + assert!( + persp.far > S::zero(), + "The far plane distance cannot be below zero, found: {:?}", + persp.far + ); + assert!( + persp.far > persp.near, + "The far plane cannot be closer than the near plane, found: far: {:?}, near: {:?}", + persp.far, + persp.near + ); let two: S = cast(2).unwrap(); let f = Rad::cot(persp.fovy / two); @@ -126,10 +156,13 @@ impl From> for Matrix4 { let c3r2 = (two * persp.far * persp.near) / (persp.near - persp.far); let c3r3 = S::zero(); - Matrix4::new(c0r0, c0r1, c0r2, c0r3, - c1r0, c1r1, c1r2, c1r3, - c2r0, c2r1, c2r2, c2r3, - c3r0, c3r1, c3r2, c3r3) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + c0r0, c0r1, c0r2, c0r3, + c1r0, c1r1, c1r2, c1r3, + c2r0, c2r1, c2r2, c2r3, + c3r0, c3r1, c3r2, c3r3, + ) } } @@ -137,19 +170,34 @@ impl From> for Matrix4 { #[derive(Copy, Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Perspective { - pub left: S, - pub right: S, + pub left: S, + pub right: S, pub bottom: S, - pub top: S, - pub near: S, - pub far: S, + pub top: S, + pub near: S, + pub far: S, } impl From> for Matrix4 { fn from(persp: Perspective) -> Matrix4 { - assert!(persp.left <= persp.right, "`left` cannot be greater than `right`, found: left: {:?} right: {:?}", persp.left, persp.right); - assert!(persp.bottom <= persp.top, "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}", persp.bottom, persp.top); - assert!(persp.near <= persp.far, "`near` cannot be greater than `far`, found: near: {:?} far: {:?}", persp.near, persp.far); + assert!( + persp.left <= persp.right, + "`left` cannot be greater than `right`, found: left: {:?} right: {:?}", + persp.left, + persp.right + ); + assert!( + persp.bottom <= persp.top, + "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}", + persp.bottom, + persp.top + ); + assert!( + persp.near <= persp.far, + "`near` cannot be greater than `far`, found: near: {:?} far: {:?}", + persp.near, + persp.far + ); let two: S = cast(2i8).unwrap(); @@ -173,10 +221,13 @@ impl From> for Matrix4 { let c3r2 = -(two * persp.far * persp.near) / (persp.far - persp.near); let c3r3 = S::zero(); - Matrix4::new(c0r0, c0r1, c0r2, c0r3, - c1r0, c1r1, c1r2, c1r3, - c2r0, c2r1, c2r2, c2r3, - c3r0, c3r1, c3r2, c3r3) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + c0r0, c0r1, c0r2, c0r3, + c1r0, c1r1, c1r2, c1r3, + c2r0, c2r1, c2r2, c2r3, + c3r0, c3r1, c3r2, c3r3, + ) } } @@ -184,12 +235,12 @@ impl From> for Matrix4 { #[derive(Copy, Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Ortho { - pub left: S, - pub right: S, + pub left: S, + pub right: S, pub bottom: S, - pub top: S, - pub near: S, - pub far: S, + pub top: S, + pub near: S, + pub far: S, } impl From> for Matrix4 { @@ -216,9 +267,12 @@ impl From> for Matrix4 { let c3r2 = -(ortho.far + ortho.near) / (ortho.far - ortho.near); let c3r3 = S::one(); - Matrix4::new(c0r0, c0r1, c0r2, c0r3, - c1r0, c1r1, c1r2, c1r3, - c2r0, c2r1, c2r2, c2r3, - c3r0, c3r1, c3r2, c3r3) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + c0r0, c0r1, c0r2, c0r3, + c1r0, c1r1, c1r2, c1r3, + c2r0, c2r1, c2r2, c2r3, + c3r0, c3r1, c3r2, c3r3, + ) } } diff --git a/src/quaternion.rs b/src/quaternion.rs index ce9d8167..fb07ae4b 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -18,7 +18,7 @@ use std::mem; use std::ops::*; use rand::{Rand, Rng}; -use num_traits::{NumCast, cast}; +use num_traits::{cast, NumCast}; use structure::*; @@ -28,7 +28,7 @@ use euler::Euler; use matrix::{Matrix3, Matrix4}; use num::BaseFloat; use point::Point3; -use rotation::{Rotation, Rotation3, Basis3}; +use rotation::{Basis3, Rotation, Rotation3}; use vector::Vector3; #[cfg(feature = "simd")] @@ -97,8 +97,11 @@ impl Quaternion { /// (http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another) /// - [Ogre implementation for normalized vectors] /// (https://bitbucket.org/sinbad/ogre/src/9db75e3ba05c/OgreMain/include/OgreVector3.h?fileviewer=file-view-default#cl-651) - pub fn from_arc(src: Vector3, dst: Vector3, fallback: Option>) - -> Quaternion { + pub fn from_arc( + src: Vector3, + dst: Vector3, + fallback: Option>, + ) -> Quaternion { let mag_avg = (src.magnitude2() * dst.magnitude2()).sqrt(); let dot = src.dot(dst); if ulps_eq!(dot, &mag_avg) { @@ -193,28 +196,28 @@ impl One for Quaternion { impl iter::Sum> for Quaternion { #[inline] - fn sum>>(iter: I) -> Quaternion { + fn sum>>(iter: I) -> Quaternion { iter.fold(Quaternion::::zero(), Add::add) } } impl<'a, S: 'a + BaseFloat> iter::Sum<&'a Quaternion> for Quaternion { #[inline] - fn sum>>(iter: I) -> Quaternion { + fn sum>>(iter: I) -> Quaternion { iter.fold(Quaternion::::zero(), Add::add) } } impl iter::Product> for Quaternion { #[inline] - fn product>>(iter: I) -> Quaternion { + fn product>>(iter: I) -> Quaternion { iter.fold(Quaternion::::one(), Mul::mul) } } impl<'a, S: 'a + BaseFloat> iter::Product<&'a Quaternion> for Quaternion { #[inline] - fn product>>(iter: I) -> Quaternion { + fn product>>(iter: I) -> Quaternion { iter.fold(Quaternion::::one(), Mul::mul) } } @@ -237,11 +240,11 @@ impl Quaternion { pub fn cast(&self) -> Option> { let s = match NumCast::from(self.s) { Some(s) => s, - None => return None + None => return None, }; let v = match self.v.cast() { Some(v) => v, - None => return None + None => return None, }; Some(Quaternion::from_sv(s, v)) } @@ -274,7 +277,8 @@ impl InnerSpace for Quaternion { } } -impl From> for Quaternion where +impl From> for Quaternion +where A: Angle + Into::Unitless>>, { fn from(src: Euler) -> Quaternion { @@ -288,10 +292,12 @@ impl From> for Quaternion where let (s_y, c_y) = Rad::sin_cos(src.y.into() * half); let (s_z, c_z) = Rad::sin_cos(src.z.into() * half); - Quaternion::new(-s_x * s_y * s_z + c_x * c_y * c_z, - s_x * c_y * c_z + s_y * s_z * c_x, - -s_x * s_z * c_y + s_y * c_x * c_z, - s_x * s_y * c_z + s_z * c_x * c_y) + Quaternion::new( + -s_x * s_y * s_z + c_x * c_y * c_z, + s_x * c_y * c_z + s_y * s_z * c_x, + -s_x * s_z * c_y + s_y * c_x * c_z, + s_x * s_y * c_z + s_z * c_x * c_y, + ) } } @@ -510,20 +516,24 @@ impl SubAssign for Quaternion { #[cfg(not(feature = "simd"))] impl_operator!( Mul > for Quaternion { fn mul(lhs, rhs) -> Quaternion { - Quaternion::new(lhs.s * rhs.s - lhs.v.x * rhs.v.x - lhs.v.y * rhs.v.y - lhs.v.z * rhs.v.z, - lhs.s * rhs.v.x + lhs.v.x * rhs.s + lhs.v.y * rhs.v.z - lhs.v.z * rhs.v.y, - lhs.s * rhs.v.y + lhs.v.y * rhs.s + lhs.v.z * rhs.v.x - lhs.v.x * rhs.v.z, - lhs.s * rhs.v.z + lhs.v.z * rhs.s + lhs.v.x * rhs.v.y - lhs.v.y * rhs.v.x) + Quaternion::new( + lhs.s * rhs.s - lhs.v.x * rhs.v.x - lhs.v.y * rhs.v.y - lhs.v.z * rhs.v.z, + lhs.s * rhs.v.x + lhs.v.x * rhs.s + lhs.v.y * rhs.v.z - lhs.v.z * rhs.v.y, + lhs.s * rhs.v.y + lhs.v.y * rhs.s + lhs.v.z * rhs.v.x - lhs.v.x * rhs.v.z, + lhs.s * rhs.v.z + lhs.v.z * rhs.s + lhs.v.x * rhs.v.y - lhs.v.y * rhs.v.x, + ) } }); #[cfg(feature = "simd")] impl_operator_default!( Mul > for Quaternion { fn mul(lhs, rhs) -> Quaternion { - Quaternion::new(lhs.s * rhs.s - lhs.v.x * rhs.v.x - lhs.v.y * rhs.v.y - lhs.v.z * rhs.v.z, - lhs.s * rhs.v.x + lhs.v.x * rhs.s + lhs.v.y * rhs.v.z - lhs.v.z * rhs.v.y, - lhs.s * rhs.v.y + lhs.v.y * rhs.s + lhs.v.z * rhs.v.x - lhs.v.x * rhs.v.z, - lhs.s * rhs.v.z + lhs.v.z * rhs.s + lhs.v.x * rhs.v.y - lhs.v.y * rhs.v.x) + Quaternion::new( + lhs.s * rhs.s - lhs.v.x * rhs.v.x - lhs.v.y * rhs.v.y - lhs.v.z * rhs.v.z, + lhs.s * rhs.v.x + lhs.v.x * rhs.s + lhs.v.y * rhs.v.z - lhs.v.z * rhs.v.y, + lhs.s * rhs.v.y + lhs.v.y * rhs.s + lhs.v.z * rhs.v.x - lhs.v.x * rhs.v.z, + lhs.s * rhs.v.z + lhs.v.z * rhs.s + lhs.v.x * rhs.v.y - lhs.v.y * rhs.v.x, + ) } }); @@ -593,14 +603,14 @@ impl ApproxEq for Quaternion { #[inline] fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool { - S::relative_eq(&self.s, &other.s, epsilon, max_relative) && - Vector3::relative_eq(&self.v, &other.v, epsilon, max_relative) + S::relative_eq(&self.s, &other.s, epsilon, max_relative) + && Vector3::relative_eq(&self.v, &other.v, epsilon, max_relative) } #[inline] fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool { - S::ulps_eq(&self.s, &other.s, epsilon, max_ulps) && - Vector3::ulps_eq(&self.v, &other.v, epsilon, max_ulps) + S::ulps_eq(&self.s, &other.s, epsilon, max_ulps) + && Vector3::ulps_eq(&self.v, &other.v, epsilon, max_ulps) } } @@ -623,9 +633,12 @@ impl From> for Matrix3 { let sz2 = z2 * quat.s; let sx2 = x2 * quat.s; - Matrix3::new(S::one() - yy2 - zz2, xy2 + sz2, xz2 - sy2, - xy2 - sz2, S::one() - xx2 - zz2, yz2 + sx2, - xz2 + sy2, yz2 - sx2, S::one() - xx2 - yy2) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix3::new( + S::one() - yy2 - zz2, xy2 + sz2, xz2 - sy2, + xy2 - sz2, S::one() - xx2 - zz2, yz2 + sx2, + xz2 + sy2, yz2 - sx2, S::one() - xx2 - yy2, + ) } } @@ -648,10 +661,13 @@ impl From> for Matrix4 { let sz2 = z2 * quat.s; let sx2 = x2 * quat.s; - Matrix4::new(S::one() - yy2 - zz2, xy2 + sz2, xz2 - sy2, S::zero(), - xy2 - sz2, S::one() - xx2 - zz2, yz2 + sx2, S::zero(), - xz2 + sy2, yz2 - sx2, S::one() - xx2 - yy2, S::zero(), - S::zero(), S::zero(), S::zero(), S::one()) + #[cfg_attr(rustfmt, rustfmt_skip)] + Matrix4::new( + S::one() - yy2 - zz2, xy2 + sz2, xz2 - sy2, S::zero(), + xy2 - sz2, S::one() - xx2 - zz2, yz2 + sx2, S::zero(), + xz2 + sy2, yz2 - sx2, S::one() - xx2 - yy2, S::zero(), + S::zero(), S::zero(), S::zero(), S::one(), + ) } } @@ -659,7 +675,9 @@ impl From> for Matrix4 { impl From> for Basis3 { #[inline] - fn from(quat: Quaternion) -> Basis3 { Basis3::from_quaternion(&quat) } + fn from(quat: Quaternion) -> Basis3 { + Basis3::from_quaternion(&quat) + } } impl Rotation> for Quaternion { @@ -695,10 +713,14 @@ impl Rotation> for Quaternion { } #[inline] - fn rotate_vector(&self, vec: Vector3) -> Vector3 { self * vec } + fn rotate_vector(&self, vec: Vector3) -> Vector3 { + self * vec + } #[inline] - fn invert(&self) -> Quaternion { self.conjugate() / self.magnitude2() } + fn invert(&self) -> Quaternion { + self.conjugate() / self.magnitude2() + } } impl Rotation3 for Quaternion { @@ -712,7 +734,9 @@ impl Rotation3 for Quaternion { impl Into<[S; 4]> for Quaternion { #[inline] fn into(self) -> [S; 4] { - match self.into() { (w, xi, yj, zk) => [w, xi, yj, zk] } + match self.into() { + (w, xi, yj, zk) => [w, xi, yj, zk], + } } } @@ -754,7 +778,12 @@ impl<'a, S: BaseFloat> From<&'a mut [S; 4]> for &'a mut Quaternion { impl Into<(S, S, S, S)> for Quaternion { #[inline] fn into(self) -> (S, S, S, S) { - match self { Quaternion { s, v: Vector3 { x, y, z } } => (s, x, y, z) } + match self { + Quaternion { + s, + v: Vector3 { x, y, z }, + } => (s, x, y, z), + } } } @@ -775,7 +804,9 @@ impl AsMut<(S, S, S, S)> for Quaternion { impl From<(S, S, S, S)> for Quaternion { #[inline] fn from(v: (S, S, S, S)) -> Quaternion { - match v { (w, xi, yj, zk) => Quaternion::new(w, xi, yj, zk) } + match v { + (w, xi, yj, zk) => Quaternion::new(w, xi, yj, zk), + } } } @@ -822,7 +853,7 @@ index_operators!(S, [S], RangeFull); impl Rand for Quaternion { #[inline] fn rand(rng: &mut R) -> Quaternion { - Quaternion::from_sv(rng.gen(), rng.gen()) + Quaternion::from_sv(rng.gen(), rng.gen()) } } @@ -846,7 +877,6 @@ impl Into> for Quaternion { } } - #[cfg(test)] mod tests { use quaternion::*; @@ -854,7 +884,11 @@ mod tests { const QUATERNION: Quaternion = Quaternion { s: 1.0, - v: Vector3 { x: 2.0, y: 3.0, z: 4.0 }, + v: Vector3 { + x: 2.0, + y: 3.0, + z: 4.0, + }, }; #[test] @@ -887,11 +921,11 @@ mod tests { fn test_as_mut() { let mut v = QUATERNION; { - let v: &mut[f32; 4] = v.as_mut(); + let v: &mut [f32; 4] = v.as_mut(); assert_eq!(v, &mut [1.0, 2.0, 3.0, 4.0]); } { - let v: &mut(f32, f32, f32, f32) = v.as_mut(); + let v: &mut (f32, f32, f32, f32) = v.as_mut(); assert_eq!(v, &mut (1.0, 2.0, 3.0, 4.0)); } } diff --git a/src/rotation.rs b/src/rotation.rs index 9e0fe8a4..70344ecb 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -30,7 +30,8 @@ use vector::{Vector2, Vector3}; /// A trait for a generic rotation. A rotation is a transformation that /// creates a circular motion, and preserves at least one point in the space. -pub trait Rotation: Sized + Copy + One where +pub trait Rotation: Sized + Copy + One +where // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 Self: ApproxEq, P::Scalar: BaseFloat, @@ -59,20 +60,17 @@ pub trait Rotation: Sized + Copy + One where } /// A two-dimensional rotation. -pub trait Rotation2: Rotation> - + Into> - + Into> { +pub trait Rotation2 + : Rotation> + Into> + Into> { /// Create a rotation by a given angle. Thus is a redundant case of both /// from_axis_angle() and from_euler() for 2D space. fn from_angle>>(theta: A) -> Self; } /// A three-dimensional rotation. -pub trait Rotation3: Rotation> - + Into> - + Into> - + Into> - + From>> { +pub trait Rotation3 + : Rotation> + Into> + Into> + Into> + From>> + { /// Create a rotation using an angle around a given axis. /// /// The specified axis **must be normalized**, or it represents an invalid rotation. @@ -97,7 +95,6 @@ pub trait Rotation3: Rotation> } } - /// A two-dimensional rotation matrix. /// /// The matrix is guaranteed to be orthogonal, so some operations can be @@ -144,7 +141,7 @@ pub trait Rotation3: Rotation> #[derive(PartialEq, Copy, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Basis2 { - mat: Matrix2 + mat: Matrix2, } impl AsRef> for Basis2 { @@ -156,19 +153,21 @@ impl AsRef> for Basis2 { impl From> for Matrix2 { #[inline] - fn from(b: Basis2) -> Matrix2 { b.mat } + fn from(b: Basis2) -> Matrix2 { + b.mat + } } impl iter::Product> for Basis2 { #[inline] - fn product>>(iter: I) -> Basis2 { + fn product>>(iter: I) -> Basis2 { iter.fold(Basis2::one(), Mul::mul) } } impl<'a, S: 'a + BaseFloat> iter::Product<&'a Basis2> for Basis2 { #[inline] - fn product>>(iter: I) -> Basis2 { + fn product>>(iter: I) -> Basis2 { iter.fold(Basis2::one(), Mul::mul) } } @@ -176,26 +175,38 @@ impl<'a, S: 'a + BaseFloat> iter::Product<&'a Basis2> for Basis2 { impl Rotation> for Basis2 { #[inline] fn look_at(dir: Vector2, up: Vector2) -> Basis2 { - Basis2 { mat: Matrix2::look_at(dir, up) } + Basis2 { + mat: Matrix2::look_at(dir, up), + } } #[inline] fn between_vectors(a: Vector2, b: Vector2) -> Basis2 { - Rotation2::from_angle(Rad::acos(a.dot(b)) ) + Rotation2::from_angle(Rad::acos(a.dot(b))) } #[inline] - fn rotate_vector(&self, vec: Vector2) -> Vector2 { self.mat * vec } + fn rotate_vector(&self, vec: Vector2) -> Vector2 { + self.mat * vec + } // TODO: we know the matrix is orthogonal, so this could be re-written // to be faster #[inline] - fn invert(&self) -> Basis2 { Basis2 { mat: self.mat.invert().unwrap() } } + fn invert(&self) -> Basis2 { + Basis2 { + mat: self.mat.invert().unwrap(), + } + } } impl One for Basis2 { #[inline] - fn one() -> Basis2 { Basis2 { mat: Matrix2::one() } } + fn one() -> Basis2 { + Basis2 { + mat: Matrix2::one(), + } + } } impl_operator!( Mul > for Basis2 { @@ -232,7 +243,11 @@ impl ApproxEq for Basis2 { } impl Rotation2 for Basis2 { - fn from_angle>>(theta: A) -> Basis2 { Basis2 { mat: Matrix2::from_angle(theta) } } + fn from_angle>>(theta: A) -> Basis2 { + Basis2 { + mat: Matrix2::from_angle(theta), + } + } } impl fmt::Debug for Basis2 { @@ -251,14 +266,16 @@ impl fmt::Debug for Basis2 { #[derive(PartialEq, Copy, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Basis3 { - mat: Matrix3 + mat: Matrix3, } impl Basis3 { /// Create a new rotation matrix from a quaternion. #[inline] pub fn from_quaternion(quaternion: &Quaternion) -> Basis3 { - Basis3 { mat: quaternion.clone().into() } + Basis3 { + mat: quaternion.clone().into(), + } } } @@ -271,24 +288,28 @@ impl AsRef> for Basis3 { impl From> for Matrix3 { #[inline] - fn from(b: Basis3) -> Matrix3 { b.mat } + fn from(b: Basis3) -> Matrix3 { + b.mat + } } impl From> for Quaternion { #[inline] - fn from(b: Basis3) -> Quaternion { b.mat.into() } + fn from(b: Basis3) -> Quaternion { + b.mat.into() + } } impl iter::Product> for Basis3 { #[inline] - fn product>>(iter: I) -> Basis3 { + fn product>>(iter: I) -> Basis3 { iter.fold(Basis3::one(), Mul::mul) } } impl<'a, S: 'a + BaseFloat> iter::Product<&'a Basis3> for Basis3 { #[inline] - fn product>>(iter: I) -> Basis3 { + fn product>>(iter: I) -> Basis3 { iter.fold(Basis3::one(), Mul::mul) } } @@ -296,7 +317,9 @@ impl<'a, S: 'a + BaseFloat> iter::Product<&'a Basis3> for Basis3 { impl Rotation> for Basis3 { #[inline] fn look_at(dir: Vector3, up: Vector3) -> Basis3 { - Basis3 { mat: Matrix3::look_at(dir, up) } + Basis3 { + mat: Matrix3::look_at(dir, up), + } } #[inline] @@ -306,17 +329,27 @@ impl Rotation> for Basis3 { } #[inline] - fn rotate_vector(&self, vec: Vector3) -> Vector3 { self.mat * vec } + fn rotate_vector(&self, vec: Vector3) -> Vector3 { + self.mat * vec + } // TODO: we know the matrix is orthogonal, so this could be re-written // to be faster #[inline] - fn invert(&self) -> Basis3 { Basis3 { mat: self.mat.invert().unwrap() } } + fn invert(&self) -> Basis3 { + Basis3 { + mat: self.mat.invert().unwrap(), + } + } } impl One for Basis3 { #[inline] - fn one() -> Basis3 { Basis3 { mat: Matrix3::one() } } + fn one() -> Basis3 { + Basis3 { + mat: Matrix3::one(), + } + } } impl_operator!( Mul > for Basis3 { @@ -354,23 +387,32 @@ impl ApproxEq for Basis3 { impl Rotation3 for Basis3 { fn from_axis_angle>>(axis: Vector3, angle: A) -> Basis3 { - Basis3 { mat: Matrix3::from_axis_angle(axis, angle) } + Basis3 { + mat: Matrix3::from_axis_angle(axis, angle), + } } fn from_angle_x>>(theta: A) -> Basis3 { - Basis3 { mat: Matrix3::from_angle_x(theta) } + Basis3 { + mat: Matrix3::from_angle_x(theta), + } } fn from_angle_y>>(theta: A) -> Basis3 { - Basis3 { mat: Matrix3::from_angle_y(theta) } + Basis3 { + mat: Matrix3::from_angle_y(theta), + } } fn from_angle_z>>(theta: A) -> Basis3 { - Basis3 { mat: Matrix3::from_angle_z(theta) } + Basis3 { + mat: Matrix3::from_angle_z(theta), + } } } -impl From> for Basis3 where +impl From> for Basis3 +where A: Into::Unitless>>, { /// Create a three-dimensional rotation matrix from a set of euler angles. diff --git a/src/structure.rs b/src/structure.rs index 07d80999..d165fa1e 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -23,12 +23,13 @@ use std::ops::*; use approx::ApproxEq; use angle::Rad; -use num::{BaseNum, BaseFloat}; +use num::{BaseFloat, BaseNum}; -pub use num_traits::{One, Zero, Bounded}; +pub use num_traits::{Bounded, One, Zero}; /// An array containing elements of type `Element` -pub trait Array where +pub trait Array +where // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 Self: Index::Element>, Self: IndexMut::Element>, @@ -78,10 +79,14 @@ pub trait Array where } /// The sum of the elements of the array. - fn sum(self) -> Self::Element where Self::Element: Add::Element>; + fn sum(self) -> Self::Element + where + Self::Element: Add::Element>; /// The product of the elements of the array. - fn product(self) -> Self::Element where Self::Element: Mul::Element>; + fn product(self) -> Self::Element + where + Self::Element: Mul::Element>; } /// Element-wise arithmetic operations. These are supplied for pragmatic @@ -156,7 +161,8 @@ pub trait ElementWise { /// let upscaled_translation = translation * scale_factor; /// let downscaled_translation = translation / scale_factor; /// ``` -pub trait VectorSpace: Copy + Clone where +pub trait VectorSpace: Copy + Clone +where Self: Zero, Self: Add, @@ -199,7 +205,8 @@ pub trait MetricSpace: Sized { /// finding the magnitude of a vector or normalizing it. /// /// Examples include vectors and quaternions. -pub trait InnerSpace: VectorSpace where +pub trait InnerSpace: VectorSpace +where // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 ::Scalar: BaseFloat, Self: MetricSpace::Scalar>, @@ -237,14 +244,12 @@ pub trait InnerSpace: VectorSpace where /// Returns a vector with the same direction, but with a magnitude of `1`. #[inline] - #[must_use] fn normalize(self) -> Self { self.normalize_to(Self::Scalar::one()) } /// Returns a vector with the same direction and a given magnitude. #[inline] - #[must_use] fn normalize_to(self, magnitude: Self::Scalar) -> Self { self * (magnitude / self.magnitude()) } @@ -252,7 +257,6 @@ pub trait InnerSpace: VectorSpace where /// Returns the result of linearly interpolating the magnitude of the vector /// towards the magnitude of `other` by the specified amount. #[inline] - #[must_use] fn lerp(self, other: Self, amount: Self::Scalar) -> Self { self + ((other - self) * amount) } @@ -261,7 +265,6 @@ pub trait InnerSpace: VectorSpace where /// [vector projection](https://en.wikipedia.org/wiki/Vector_projection) /// of the current inner space projected onto the supplied argument. #[inline] - #[must_use] fn project_on(self, other: Self) -> Self { other * (self.dot(other) / other.magnitude2()) } @@ -314,7 +317,8 @@ pub trait InnerSpace: VectorSpace where /// - [CGAL 4.7 - 2D and 3D Linear Geometry Kernel: 3.1 Points and Vectors](http://doc.cgal.org/latest/Kernel_23/index.html#Kernel_23PointsandVectors) /// - [What is the difference between a point and a vector](http://math.stackexchange.com/q/645827) /// -pub trait EuclideanSpace: Copy + Clone where +pub trait EuclideanSpace: Copy + Clone +where // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 Self: Array::Scalar>, @@ -382,10 +386,9 @@ pub trait EuclideanSpace: Copy + Clone where /// ``` #[inline] fn centroid(points: &[Self]) -> Self { - let total_displacement = - points.iter().fold(Self::Diff::zero(), |acc, p| { - acc + p.to_vec() - }); + let total_displacement = points + .iter() + .fold(Self::Diff::zero(), |acc, p| acc + p.to_vec()); Self::from_vec(total_displacement / cast(points.len()).unwrap()) } @@ -415,7 +418,8 @@ pub trait EuclideanSpace: Copy + Clone where /// trait. This is due to the complexities of implementing these operators with /// Rust's current type system. For the multiplication of square matrices, /// see `SquareMatrix`. -pub trait Matrix: VectorSpace where +pub trait Matrix: VectorSpace +where Self::Scalar: BaseFloat, // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 @@ -467,7 +471,8 @@ pub trait Matrix: VectorSpace where } /// A column-major major matrix where the rows and column vectors are of the same dimensions. -pub trait SquareMatrix where +pub trait SquareMatrix +where Self::Scalar: BaseFloat, Self: One, @@ -518,22 +523,27 @@ pub trait SquareMatrix where /// Return the trace of this matrix. That is, the sum of the diagonal. #[inline] - fn trace(&self) -> Self::Scalar { self.diagonal().sum() } + fn trace(&self) -> Self::Scalar { + self.diagonal().sum() + } /// Invert this matrix, returning a new matrix. `m.mul_m(m.invert())` is /// the identity matrix. Returns `None` if this matrix is not invertible /// (has a determinant of zero). - #[must_use] fn invert(&self) -> Option; /// Test if this matrix is invertible. #[inline] - fn is_invertible(&self) -> bool { ulps_ne!(self.determinant(), &Self::Scalar::zero()) } + fn is_invertible(&self) -> bool { + ulps_ne!(self.determinant(), &Self::Scalar::zero()) + } /// Test if this matrix is the identity matrix. That is, it is diagonal /// and every element in the diagonal is one. #[inline] - fn is_identity(&self) -> bool { ulps_eq!(self, &Self::identity()) } + fn is_identity(&self) -> bool { + ulps_eq!(self, &Self::identity()) + } /// Test if this is a diagonal matrix. That is, every element outside of /// the diagonal is 0. @@ -550,7 +560,8 @@ pub trait SquareMatrix where /// clear when semantic violations have occured - for example, adding degrees to /// radians, or adding a number to an angle. /// -pub trait Angle where +pub trait Angle +where Self: Copy + Clone, Self: PartialEq + cmp::PartialOrd, // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 @@ -574,7 +585,11 @@ pub trait Angle where #[inline] fn normalize(self) -> Self { let rem = self % Self::full_turn(); - if rem < Self::zero() { rem + Self::full_turn() } else { rem } + if rem < Self::zero() { + rem + Self::full_turn() + } else { + rem + } } /// Return the angle rotated by half a turn. diff --git a/src/transform.rs b/src/transform.rs index 5397c032..1d093584 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -39,7 +39,8 @@ pub trait Transform: Sized { /// Inverse transform a vector using this transform fn inverse_transform_vector(&self, vec: P::Diff) -> Option { - self.inverse_transform().and_then(|inverse| Some(inverse.transform_vector(vec))) + self.inverse_transform() + .and_then(|inverse| Some(inverse.transform_vector(vec))) } /// Transform a point using this transform. @@ -69,9 +70,10 @@ pub struct Decomposed { } impl> Transform

for Decomposed - where P::Scalar: BaseFloat, - // FIXME: Investigate why this is needed! - P::Diff: VectorSpace +where + P::Scalar: BaseFloat, + // FIXME: Investigate why this is needed! + P::Diff: VectorSpace, { #[inline] fn one() -> Decomposed { @@ -128,10 +130,10 @@ impl> Transform

for Decomposed let r = self.rot.invert(); let d = r.rotate_vector(self.disp.clone()) * -s; Some(Decomposed { - scale: s, - rot: r, - disp: d, - }) + scale: s, + rot: r, + disp: d, + }) } } } @@ -162,9 +164,10 @@ impl> Transform2 for Decomposed, R> impl> Transform3 for Decomposed, R> {} impl ApproxEq for Decomposed - where S: ApproxEq, - S::Scalar: ApproxEq, - R: ApproxEq +where + S: ApproxEq, + S::Scalar: ApproxEq, + R: ApproxEq, { type Epsilon = E; @@ -185,16 +188,16 @@ impl ApproxEq for Decomposed #[inline] fn relative_eq(&self, other: &Self, epsilon: E, max_relative: E) -> bool { - S::Scalar::relative_eq(&self.scale, &other.scale, epsilon, max_relative) && - R::relative_eq(&self.rot, &other.rot, epsilon, max_relative) && - S::relative_eq(&self.disp, &other.disp, epsilon, max_relative) + S::Scalar::relative_eq(&self.scale, &other.scale, epsilon, max_relative) + && R::relative_eq(&self.rot, &other.rot, epsilon, max_relative) + && S::relative_eq(&self.disp, &other.disp, epsilon, max_relative) } #[inline] fn ulps_eq(&self, other: &Self, epsilon: E, max_ulps: u32) -> bool { - S::Scalar::ulps_eq(&self.scale, &other.scale, epsilon, max_ulps) && - R::ulps_eq(&self.rot, &other.rot, epsilon, max_ulps) && - S::ulps_eq(&self.disp, &other.disp, epsilon, max_ulps) + S::Scalar::ulps_eq(&self.scale, &other.scale, epsilon, max_ulps) + && R::ulps_eq(&self.rot, &other.rot, epsilon, max_ulps) + && S::ulps_eq(&self.disp, &other.disp, epsilon, max_ulps) } } @@ -207,12 +210,14 @@ mod serde_ser { use serde::ser::SerializeStruct; impl Serialize for Decomposed - where V: Serialize + VectorSpace, - V::Scalar: Serialize, - R: Serialize + where + V: Serialize + VectorSpace, + V::Scalar: Serialize, + R: Serialize, { fn serialize(&self, serializer: S) -> Result - where S: serde::Serializer + where + S: serde::Serializer, { let mut struc = serializer.serialize_struct("Decomposed", 3)?; struc.serialize_field("scale", &self.scale)?; @@ -240,7 +245,8 @@ mod serde_de { impl<'a> Deserialize<'a> for DecomposedField { fn deserialize(deserializer: D) -> Result - where D: serde::Deserializer<'a> + where + D: serde::Deserializer<'a>, { struct DecomposedFieldVisitor; @@ -252,7 +258,8 @@ mod serde_de { } fn visit_str(self, value: &str) -> Result - where E: serde::de::Error + where + E: serde::de::Error, { match value { "scale" => Ok(DecomposedField::Scale), @@ -268,12 +275,14 @@ mod serde_de { } impl<'a, S: VectorSpace, R> Deserialize<'a> for Decomposed - where S: Deserialize<'a>, - S::Scalar: Deserialize<'a>, - R: Deserialize<'a> + where + S: Deserialize<'a>, + S::Scalar: Deserialize<'a>, + R: Deserialize<'a>, { fn deserialize(deserializer: D) -> Result, D::Error> - where D: serde::de::Deserializer<'a> + where + D: serde::de::Deserializer<'a>, { const FIELDS: &'static [&'static str] = &["scale", "rot", "disp"]; deserializer.deserialize_struct("Decomposed", FIELDS, DecomposedVisitor(PhantomData)) @@ -283,9 +292,10 @@ mod serde_de { struct DecomposedVisitor(PhantomData<(S, R)>); impl<'a, S: VectorSpace, R> serde::de::Visitor<'a> for DecomposedVisitor - where S: Deserialize<'a>, - S::Scalar: Deserialize<'a>, - R: Deserialize<'a> + where + S: Deserialize<'a>, + S::Scalar: Deserialize<'a>, + R: Deserialize<'a>, { type Value = Decomposed; @@ -294,7 +304,8 @@ mod serde_de { } fn visit_map(self, mut visitor: V) -> Result, V::Error> - where V: serde::de::MapAccess<'a> + where + V: serde::de::MapAccess<'a>, { let mut scale = None; let mut rot = None; @@ -330,10 +341,10 @@ mod serde_de { }; Ok(Decomposed { - scale: scale, - rot: rot, - disp: disp, - }) + scale: scale, + rot: rot, + disp: disp, + }) } } } diff --git a/src/vector.rs b/src/vector.rs index 8613baf4..8dfcb09a 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -14,7 +14,7 @@ // limitations under the License. use rand::{Rand, Rng}; -use num_traits::{NumCast, Bounded}; +use num_traits::{Bounded, NumCast}; use std::fmt; use std::iter; use std::mem; @@ -24,7 +24,7 @@ use structure::*; use angle::Rad; use approx::ApproxEq; -use num::{BaseNum, BaseFloat}; +use num::{BaseFloat, BaseNum}; #[cfg(feature = "simd")] use simd::f32x4 as Simdf32x4; @@ -659,11 +659,12 @@ impl Vector3 { /// Returns the cross product of the vector and `other`. #[inline] - #[must_use] pub fn cross(self, other: Vector3) -> Vector3 { - Vector3::new((self.y * other.z) - (self.z * other.y), - (self.z * other.x) - (self.x * other.z), - (self.x * other.y) - (self.y * other.x)) + Vector3::new( + (self.y * other.z) - (self.z * other.y), + (self.z * other.x) - (self.x * other.z), + (self.x * other.y) - (self.y * other.x), + ) } /// Create a `Vector4`, using the `x`, `y` and `z` values from this vector, and the @@ -731,7 +732,8 @@ impl Vector4 { /// Dot product of two vectors. #[inline] pub fn dot(a: V, b: V) -> V::Scalar - where V::Scalar: BaseFloat +where + V::Scalar: BaseFloat, { V::dot(a, b) } @@ -841,8 +843,6 @@ impl Vector4 { } } - - #[cfg(feature = "simd")] impl Into for Vector4 { #[inline] @@ -888,8 +888,6 @@ impl_operator_simd!{@rs } } - - #[cfg(feature = "simd")] impl_operator_simd!{ [Simdf32x4]; Neg for Vector4 { @@ -939,27 +937,46 @@ impl DivAssign for Vector4 { #[cfg(feature = "simd")] impl ElementWise for Vector4 { - #[inline] fn add_element_wise(self, rhs: Vector4) -> Vector4 { self + rhs } - #[inline] fn sub_element_wise(self, rhs: Vector4) -> Vector4 { self - rhs } - #[inline] fn mul_element_wise(self, rhs: Vector4) -> Vector4 { + #[inline] + fn add_element_wise(self, rhs: Vector4) -> Vector4 { + self + rhs + } + #[inline] + fn sub_element_wise(self, rhs: Vector4) -> Vector4 { + self - rhs + } + #[inline] + fn mul_element_wise(self, rhs: Vector4) -> Vector4 { let s: Simdf32x4 = self.into(); let rhs: Simdf32x4 = rhs.into(); (s * rhs).into() } - #[inline] fn div_element_wise(self, rhs: Vector4) -> Vector4 { + #[inline] + fn div_element_wise(self, rhs: Vector4) -> Vector4 { let s: Simdf32x4 = self.into(); let rhs: Simdf32x4 = rhs.into(); (s / rhs).into() } - #[inline] fn add_assign_element_wise(&mut self, rhs: Vector4) { (*self) += rhs; } - #[inline] fn sub_assign_element_wise(&mut self, rhs: Vector4) { (*self) -= rhs; } - #[inline] fn mul_assign_element_wise(&mut self, rhs: Vector4) { + #[inline] + fn add_assign_element_wise(&mut self, rhs: Vector4) { + (*self) += rhs; + } + + #[inline] + fn sub_assign_element_wise(&mut self, rhs: Vector4) { + (*self) -= rhs; + } + + #[inline] + fn mul_assign_element_wise(&mut self, rhs: Vector4) { let s: Simdf32x4 = (*self).into(); let rhs: Simdf32x4 = rhs.into(); *self = (s * rhs).into(); } - #[inline] fn div_assign_element_wise(&mut self, rhs: Vector4) { + + #[inline] + fn div_assign_element_wise(&mut self, rhs: Vector4) { let s: Simdf32x4 = (*self).into(); let rhs: Simdf32x4 = rhs.into(); *self = (s * rhs).into(); @@ -968,31 +985,53 @@ impl ElementWise for Vector4 { #[cfg(feature = "simd")] impl ElementWise for Vector4 { - #[inline] fn add_element_wise(self, rhs: f32) -> Vector4 { + #[inline] + fn add_element_wise(self, rhs: f32) -> Vector4 { let s: Simdf32x4 = self.into(); let rhs = Simdf32x4::splat(rhs); (s + rhs).into() } - #[inline] fn sub_element_wise(self, rhs: f32) -> Vector4 { + + #[inline] + fn sub_element_wise(self, rhs: f32) -> Vector4 { let s: Simdf32x4 = self.into(); let rhs = Simdf32x4::splat(rhs); (s - rhs).into() } - #[inline] fn mul_element_wise(self, rhs: f32) -> Vector4 { self * rhs } - #[inline] fn div_element_wise(self, rhs: f32) -> Vector4 { self / rhs } - #[inline] fn add_assign_element_wise(&mut self, rhs: f32) { + #[inline] + fn mul_element_wise(self, rhs: f32) -> Vector4 { + self * rhs + } + + #[inline] + fn div_element_wise(self, rhs: f32) -> Vector4 { + self / rhs + } + + #[inline] + fn add_assign_element_wise(&mut self, rhs: f32) { let s: Simdf32x4 = (*self).into(); let rhs = Simdf32x4::splat(rhs); *self = (s + rhs).into(); } - #[inline] fn sub_assign_element_wise(&mut self, rhs: f32) { + + #[inline] + fn sub_assign_element_wise(&mut self, rhs: f32) { let s: Simdf32x4 = (*self).into(); let rhs = Simdf32x4::splat(rhs); *self = (s - rhs).into(); } - #[inline] fn mul_assign_element_wise(&mut self, rhs: f32) { (*self) *= rhs; } - #[inline] fn div_assign_element_wise(&mut self, rhs: f32) { (*self) /= rhs; } + + #[inline] + fn mul_assign_element_wise(&mut self, rhs: f32) { + (*self) *= rhs; + } + + #[inline] + fn div_assign_element_wise(&mut self, rhs: f32) { + (*self) /= rhs; + } } #[cfg(feature = "simd")] @@ -1171,7 +1210,6 @@ impl_mint_conversions!(Vector3 { x, y, z }, Vector3); #[cfg(feature = "mint")] impl_mint_conversions!(Vector4 { x, y, z, w }, Vector4); - #[cfg(test)] mod tests { mod vector2 { diff --git a/tests/angle.rs b/tests/angle.rs index 58c8faac..309bd48e 100644 --- a/tests/angle.rs +++ b/tests/angle.rs @@ -17,7 +17,7 @@ extern crate approx; extern crate cgmath; -use cgmath::{Rad, Deg}; +use cgmath::{Deg, Rad}; #[test] fn test_conv() { @@ -43,8 +43,14 @@ mod rad { #[test] fn test_iter_sum() { - assert_eq!(Rad(2.0) + Rad(3.0) + Rad(4.0), [Rad(2.0), Rad(3.0), Rad(4.0)].iter().sum()); - assert_eq!(Rad(2.0) + Rad(3.0) + Rad(4.0), [Rad(2.0), Rad(3.0), Rad(4.0)].iter().cloned().sum()); + assert_eq!( + Rad(2.0) + Rad(3.0) + Rad(4.0), + [Rad(2.0), Rad(3.0), Rad(4.0)].iter().sum() + ); + assert_eq!( + Rad(2.0) + Rad(3.0) + Rad(4.0), + [Rad(2.0), Rad(3.0), Rad(4.0)].iter().cloned().sum() + ); } } @@ -53,7 +59,13 @@ mod deg { #[test] fn test_iter_sum() { - assert_eq!(Deg(2.0) + Deg(3.0) + Deg(4.0), [Deg(2.0), Deg(3.0), Deg(4.0)].iter().sum()); - assert_eq!(Deg(2.0) + Deg(3.0) + Deg(4.0), [Deg(2.0), Deg(3.0), Deg(4.0)].iter().cloned().sum()); + assert_eq!( + Deg(2.0) + Deg(3.0) + Deg(4.0), + [Deg(2.0), Deg(3.0), Deg(4.0)].iter().sum() + ); + assert_eq!( + Deg(2.0) + Deg(3.0) + Deg(4.0), + [Deg(2.0), Deg(3.0), Deg(4.0)].iter().cloned().sum() + ); } } diff --git a/tests/point.rs b/tests/point.rs index 0f3fc8ab..83fd1688 100644 --- a/tests/point.rs +++ b/tests/point.rs @@ -53,7 +53,7 @@ macro_rules! impl_test_rem { #[test] fn test_homogeneous() { - let p = Point3::new(1.0f64, 2.0f64, 3.0f64); + let p = Point3::new(1.0f64, 2.0f64, 3.0f64); assert_ulps_eq!(&p, &Point3::from_homogeneous(p.to_homogeneous())); } @@ -78,6 +78,12 @@ fn test_rem() { #[test] fn test_cast() { assert_ulps_eq!(Point1::new(0.9f64).cast().unwrap(), Point1::new(0.9f32)); - assert_ulps_eq!(Point2::new(0.9f64, 1.5).cast().unwrap(), Point2::new(0.9f32, 1.5)); - assert_ulps_eq!(Point3::new(1.0f64, 2.4, -3.13).cast().unwrap(), Point3::new(1.0f32, 2.4, -3.13)); + assert_ulps_eq!( + Point2::new(0.9f64, 1.5).cast().unwrap(), + Point2::new(0.9f32, 1.5) + ); + assert_ulps_eq!( + Point3::new(1.0f64, 2.4, -3.13).cast().unwrap(), + Point3::new(1.0f32, 2.4, -3.13) + ); } diff --git a/tests/projection.rs b/tests/projection.rs index 9a38c45d..3607a6d4 100644 --- a/tests/projection.rs +++ b/tests/projection.rs @@ -15,7 +15,7 @@ extern crate cgmath; -use cgmath::{Vector4, ortho, Matrix4}; +use cgmath::{ortho, Matrix4, Vector4}; #[test] fn test_ortho_scale() { @@ -36,7 +36,6 @@ fn test_ortho_scale() { assert_eq!(orig, Vector4::new(0f32, 0., 0., 1.)); assert_eq!(far, Vector4::new(1f32, 1., -1., 1.)); - let o: Matrix4 = ortho(-2., 2., -2., 2., -2., 2.); let near = o * vec_near; let orig = o * vec_orig; diff --git a/tests/quaternion.rs b/tests/quaternion.rs index 24969353..f1ffd9f2 100644 --- a/tests/quaternion.rs +++ b/tests/quaternion.rs @@ -44,19 +44,45 @@ mod operators { #[test] fn test_mul() { - impl_test_mul!(2.0f32, Quaternion::from(Euler { x: Rad(1f32), y: Rad(1f32), z: Rad(1f32) })); + impl_test_mul!( + 2.0f32, + Quaternion::from(Euler { + x: Rad(1f32), + y: Rad(1f32), + z: Rad(1f32), + }) + ); } #[test] fn test_div() { - impl_test_div!(2.0f32, Quaternion::from(Euler { x: Rad(1f32), y: Rad(1f32), z: Rad(1f32) })); + impl_test_div!( + 2.0f32, + Quaternion::from(Euler { + x: Rad(1f32), + y: Rad(1f32), + z: Rad(1f32), + }) + ); } #[test] fn test_iter_sum() { - let q1 = Quaternion::from(Euler { x: Rad(2f32), y: Rad(1f32), z: Rad(1f32) }); - let q2 = Quaternion::from(Euler { x: Rad(1f32), y: Rad(2f32), z: Rad(1f32) }); - let q3 = Quaternion::from(Euler { x: Rad(1f32), y: Rad(1f32), z: Rad(2f32) }); + let q1 = Quaternion::from(Euler { + x: Rad(2f32), + y: Rad(1f32), + z: Rad(1f32), + }); + let q2 = Quaternion::from(Euler { + x: Rad(1f32), + y: Rad(2f32), + z: Rad(1f32), + }); + let q3 = Quaternion::from(Euler { + x: Rad(1f32), + y: Rad(1f32), + z: Rad(2f32), + }); assert_eq!(q1 + q2 + q3, [q1, q2, q3].iter().sum()); assert_eq!(q1 + q2 + q3, [q1, q2, q3].iter().cloned().sum()); @@ -64,9 +90,21 @@ mod operators { #[test] fn test_iter_product() { - let q1 = Quaternion::from(Euler { x: Rad(2f32), y: Rad(1f32), z: Rad(1f32) }); - let q2 = Quaternion::from(Euler { x: Rad(1f32), y: Rad(2f32), z: Rad(1f32) }); - let q3 = Quaternion::from(Euler { x: Rad(1f32), y: Rad(1f32), z: Rad(2f32) }); + let q1 = Quaternion::from(Euler { + x: Rad(2f32), + y: Rad(1f32), + z: Rad(1f32), + }); + let q2 = Quaternion::from(Euler { + x: Rad(1f32), + y: Rad(2f32), + z: Rad(1f32), + }); + let q3 = Quaternion::from(Euler { + x: Rad(1f32), + y: Rad(1f32), + z: Rad(2f32), + }); assert_eq!(q1 * q2 * q3, [q1, q2, q3].iter().product()); assert_eq!(q1 * q2 * q3, [q1, q2, q3].iter().cloned().product()); @@ -79,22 +117,103 @@ mod to_from_euler { use cgmath::*; fn check_euler(rotation: Euler>) { - assert_relative_eq!(Euler::from(Quaternion::from(rotation)), rotation, epsilon = 0.001); + assert_relative_eq!( + Euler::from(Quaternion::from(rotation)), + rotation, + epsilon = 0.001 + ); } const HPI: f32 = f32::consts::FRAC_PI_2; - #[test] fn test_zero() { check_euler(Euler { x: Rad( 0f32), y: Rad( 0f32), z: Rad( 0f32) }); } - #[test] fn test_yaw_pos_1() { check_euler(Euler { x: Rad( 0f32), y: Rad( 1f32), z: Rad( 0f32) }); } - #[test] fn test_yaw_neg_1() { check_euler(Euler { x: Rad( 0f32), y: Rad(-1f32), z: Rad( 0f32) }); } - #[test] fn test_pitch_pos_1() { check_euler(Euler { x: Rad( 1f32), y: Rad( 0f32), z: Rad( 0f32) }); } - #[test] fn test_pitch_neg_1() { check_euler(Euler { x: Rad(-1f32), y: Rad( 0f32), z: Rad( 0f32) }); } - #[test] fn test_roll_pos_1() { check_euler(Euler { x: Rad( 0f32), y: Rad( 0f32), z: Rad( 1f32) }); } - #[test] fn test_roll_neg_1() { check_euler(Euler { x: Rad( 0f32), y: Rad( 0f32), z: Rad(-1f32) }); } - #[test] fn test_pitch_yaw_roll_pos_1() { check_euler(Euler { x: Rad( 1f32), y: Rad( 1f32), z: Rad( 1f32) }); } - #[test] fn test_pitch_yaw_roll_neg_1() { check_euler(Euler { x: Rad(-1f32), y: Rad(-1f32), z: Rad(-1f32) }); } - #[test] fn test_pitch_yaw_roll_pos_hp() { check_euler(Euler { x: Rad( 0f32), y: Rad( HPI), z: Rad( 1f32) }); } - #[test] fn test_pitch_yaw_roll_neg_hp() { check_euler(Euler { x: Rad( 0f32), y: Rad( -HPI), z: Rad( 1f32) }); } + #[test] + fn test_zero() { + check_euler(Euler { + x: Rad(0f32), + y: Rad(0f32), + z: Rad(0f32), + }); + } + #[test] + fn test_yaw_pos_1() { + check_euler(Euler { + x: Rad(0f32), + y: Rad(1f32), + z: Rad(0f32), + }); + } + #[test] + fn test_yaw_neg_1() { + check_euler(Euler { + x: Rad(0f32), + y: Rad(-1f32), + z: Rad(0f32), + }); + } + #[test] + fn test_pitch_pos_1() { + check_euler(Euler { + x: Rad(1f32), + y: Rad(0f32), + z: Rad(0f32), + }); + } + #[test] + fn test_pitch_neg_1() { + check_euler(Euler { + x: Rad(-1f32), + y: Rad(0f32), + z: Rad(0f32), + }); + } + #[test] + fn test_roll_pos_1() { + check_euler(Euler { + x: Rad(0f32), + y: Rad(0f32), + z: Rad(1f32), + }); + } + #[test] + fn test_roll_neg_1() { + check_euler(Euler { + x: Rad(0f32), + y: Rad(0f32), + z: Rad(-1f32), + }); + } + #[test] + fn test_pitch_yaw_roll_pos_1() { + check_euler(Euler { + x: Rad(1f32), + y: Rad(1f32), + z: Rad(1f32), + }); + } + #[test] + fn test_pitch_yaw_roll_neg_1() { + check_euler(Euler { + x: Rad(-1f32), + y: Rad(-1f32), + z: Rad(-1f32), + }); + } + #[test] + fn test_pitch_yaw_roll_pos_hp() { + check_euler(Euler { + x: Rad(0f32), + y: Rad(HPI), + z: Rad(1f32), + }); + } + #[test] + fn test_pitch_yaw_roll_neg_hp() { + check_euler(Euler { + x: Rad(0f32), + y: Rad(-HPI), + z: Rad(1f32), + }); + } } mod from { @@ -206,7 +325,6 @@ mod rotate_from_euler { assert_ulps_eq!(vec3(0.0, -1.0, 0.0), rot * vec); } - // tests that the Y rotation is done after the X #[test] fn test_x_then_y() { @@ -258,7 +376,10 @@ mod rotate_from_axis_angle { let vec = vec3(0.0, 0.0, 1.0); let rot = Quaternion::from_axis_angle(vec3(1.0, 1.0, 0.0).normalize(), Deg(90.0)); - assert_ulps_eq!(vec3(2.0f32.sqrt() / 2.0, -2.0f32.sqrt() / 2.0, 0.0), rot * vec); + assert_ulps_eq!( + vec3(2.0f32.sqrt() / 2.0, -2.0f32.sqrt() / 2.0, 0.0), + rot * vec + ); } #[test] @@ -266,7 +387,10 @@ mod rotate_from_axis_angle { let vec = vec3(1.0, 0.0, 0.0); let rot = Quaternion::from_axis_angle(vec3(0.0, 1.0, 1.0).normalize(), Deg(-90.0)); - assert_ulps_eq!(vec3(0.0, -2.0f32.sqrt() / 2.0, 2.0f32.sqrt() / 2.0), rot * vec); + assert_ulps_eq!( + vec3(0.0, -2.0f32.sqrt() / 2.0, 2.0f32.sqrt() / 2.0), + rot * vec + ); } #[test] @@ -274,7 +398,10 @@ mod rotate_from_axis_angle { let vec = vec3(0.0, 1.0, 0.0); let rot = Quaternion::from_axis_angle(vec3(1.0, 0.0, 1.0).normalize(), Deg(90.0)); - assert_ulps_eq!(vec3(-2.0f32.sqrt() / 2.0, 0.0, 2.0f32.sqrt() / 2.0), rot * vec); + assert_ulps_eq!( + vec3(-2.0f32.sqrt() / 2.0, 0.0, 2.0f32.sqrt() / 2.0), + rot * vec + ); } } @@ -337,7 +464,9 @@ mod cast { #[test] fn test_cast() { - assert_ulps_eq!(Quaternion::new(0.9f64, 1.5, 2.4, 7.6).cast().unwrap(), - Quaternion::new(0.9f32, 1.5, 2.4, 7.6)); + assert_ulps_eq!( + Quaternion::new(0.9f64, 1.5, 2.4, 7.6).cast().unwrap(), + Quaternion::new(0.9f32, 1.5, 2.4, 7.6) + ); } } diff --git a/tests/transform.rs b/tests/transform.rs index 3cd27531..13c9e5c5 100644 --- a/tests/transform.rs +++ b/tests/transform.rs @@ -30,7 +30,8 @@ fn test_invert() { rot: Quaternion::new(0.5f64, 0.5, 0.5, 0.5), disp: Vector3::new(6.0f64, -7.0, 8.0), }; - let ti = t.inverse_transform().expect("Expected successful inversion"); + let ti = t.inverse_transform() + .expect("Expected successful inversion"); let vt = t.transform_vector(v); assert_ulps_eq!(&v, &ti.transform_vector(vt)); } @@ -43,7 +44,8 @@ fn test_inverse_vector() { rot: Quaternion::new(0.5f64, 0.5, 0.5, 0.5), disp: Vector3::new(6.0f64, -7.0, 8.0), }; - let vt = t.inverse_transform_vector(v).expect("Expected successful inversion"); + let vt = t.inverse_transform_vector(v) + .expect("Expected successful inversion"); assert_ulps_eq!(v, t.transform_vector(vt)); } @@ -68,7 +70,8 @@ fn test_serialize() { }; let serialized = serde_json::to_string(&t).unwrap(); - let deserialized: Decomposed, Quaternion> = serde_json::from_str(&serialized).unwrap(); + let deserialized: Decomposed, Quaternion> = + serde_json::from_str(&serialized).unwrap(); assert_ulps_eq!(&t, &deserialized); } diff --git a/tests/vector.rs b/tests/vector.rs index e79cde16..325838a3 100644 --- a/tests/vector.rs +++ b/tests/vector.rs @@ -25,14 +25,26 @@ use std::iter; fn test_constructor() { assert_eq!(vec2(1f32, 2f32), Vector2::new(1f32, 2f32)); assert_eq!(vec3(1f64, 2f64, 3f64), Vector3::new(1f64, 2f64, 3f64)); - assert_eq!(vec4(1isize, 2isize, 3isize, 4isize), Vector4::new(1isize, 2isize, 3isize, 4isize)); + assert_eq!( + vec4(1isize, 2isize, 3isize, 4isize), + Vector4::new(1isize, 2isize, 3isize, 4isize) + ); } #[test] fn test_from_value() { - assert_eq!(Vector2::from_value(102isize), Vector2::new(102isize, 102isize)); - assert_eq!(Vector3::from_value(22isize), Vector3::new(22isize, 22isize, 22isize)); - assert_eq!(Vector4::from_value(76.5f64), Vector4::new(76.5f64, 76.5f64, 76.5f64, 76.5f64)); + assert_eq!( + Vector2::from_value(102isize), + Vector2::new(102isize, 102isize) + ); + assert_eq!( + Vector3::from_value(22isize), + Vector3::new(22isize, 22isize, 22isize) + ); + assert_eq!( + Vector4::from_value(76.5f64), + Vector4::new(76.5f64, 76.5f64, 76.5f64, 76.5f64) + ); } macro_rules! impl_test_add { @@ -132,8 +144,14 @@ fn test_rem() { #[test] fn test_dot() { assert_eq!(Vector2::new(1.0, 2.0).dot(Vector2::new(3.0, 4.0)), 11.0); - assert_eq!(Vector3::new(1.0, 2.0, 3.0).dot(Vector3::new(4.0, 5.0, 6.0)), 32.0); - assert_eq!(Vector4::new(1.0, 2.0, 3.0, 4.0).dot(Vector4::new(5.0, 6.0, 7.0, 8.0)), 70.0); + assert_eq!( + Vector3::new(1.0, 2.0, 3.0).dot(Vector3::new(4.0, 5.0, 6.0)), + 32.0 + ); + assert_eq!( + Vector4::new(1.0, 2.0, 3.0, 4.0).dot(Vector4::new(5.0, 6.0, 7.0, 8.0)), + 70.0 + ); } #[test] @@ -149,7 +167,12 @@ fn test_sum() { #[test] fn test_iter_sum() { - impl_test_iter_sum!(Vector4 { x, y, z, w }, f32, 2.0f32, vec4(2.0f32, 4.0, 6.0, 8.0)); + impl_test_iter_sum!( + Vector4 { x, y, z, w }, + f32, + 2.0f32, + vec4(2.0f32, 4.0, 6.0, 8.0) + ); impl_test_iter_sum!(Vector3 { x, y, z }, f32, 2.0f32, vec3(2.0f32, 4.0, 6.0)); impl_test_iter_sum!(Vector2 { x, y }, f32, 2.0f32, vec2(2.0f32, 4.0)); @@ -162,11 +185,17 @@ fn test_iter_sum() { fn test_product() { assert_eq!(Vector2::new(1isize, 2isize).product(), 2isize); assert_eq!(Vector3::new(1isize, 2isize, 3isize).product(), 6isize); - assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).product(), 24isize); + assert_eq!( + Vector4::new(1isize, 2isize, 3isize, 4isize).product(), + 24isize + ); assert_eq!(Vector2::new(3.0f64, 4.0f64).product(), 12.0f64); assert_eq!(Vector3::new(4.0f64, 5.0f64, 6.0f64).product(), 120.0f64); - assert_eq!(Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).product(), 1680.0f64); + assert_eq!( + Vector4::new(5.0f64, 6.0f64, 7.0f64, 8.0f64).product(), + 1680.0f64 + ); } #[test] @@ -180,8 +209,17 @@ fn test_cross() { #[test] fn test_is_perpendicular() { assert!(Vector2::new(1.0f64, 0.0f64).is_perpendicular(Vector2::new(0.0f64, 1.0f64))); - assert!(Vector3::new(0.0f64, 1.0f64, 0.0f64).is_perpendicular(Vector3::new(0.0f64, 0.0f64, 1.0f64))); - assert!(Vector4::new(1.0f64, 0.0f64, 0.0f64, 0.0f64).is_perpendicular(Vector4::new(0.0f64, 0.0f64, 0.0f64, 1.0f64))); + assert!( + Vector3::new(0.0f64, 1.0f64, 0.0f64).is_perpendicular(Vector3::new(0.0f64, 0.0f64, 1.0f64)) + ); + assert!( + Vector4::new(1.0f64, 0.0f64, 0.0f64, 0.0f64).is_perpendicular(Vector4::new( + 0.0f64, + 0.0f64, + 0.0f64, + 1.0f64 + )) + ); } #[cfg(test)] @@ -189,7 +227,7 @@ mod test_magnitude { use cgmath::*; #[test] - fn test_vector2(){ + fn test_vector2() { let (a, a_res) = (Vector2::new(3.0f64, 4.0f64), 5.0f64); // (3, 4, 5) Pythagorean triple let (b, b_res) = (Vector2::new(5.0f64, 12.0f64), 13.0f64); // (5, 12, 13) Pythagorean triple @@ -201,7 +239,7 @@ mod test_magnitude { } #[test] - fn test_vector3(){ + fn test_vector3() { let (a, a_res) = (Vector3::new(2.0f64, 3.0f64, 6.0f64), 7.0f64); // (2, 3, 6, 7) Pythagorean quadruple let (b, b_res) = (Vector3::new(1.0f64, 4.0f64, 8.0f64), 9.0f64); // (1, 4, 8, 9) Pythagorean quadruple @@ -213,7 +251,7 @@ mod test_magnitude { } #[test] - fn test_vector4(){ + fn test_vector4() { let (a, a_res) = (Vector4::new(1.0f64, 2.0f64, 4.0f64, 10.0f64), 11.0f64); // (1, 2, 4, 10, 11) Pythagorean quintuple let (b, b_res) = (Vector4::new(1.0f64, 2.0f64, 8.0f64, 10.0f64), 13.0f64); // (1, 2, 8, 10, 13) Pythagorean quintuple @@ -227,37 +265,106 @@ mod test_magnitude { #[test] fn test_angle() { - assert_ulps_eq!(Vector2::new(1.0f64, 0.0f64).angle(Vector2::new(0.0f64, 1.0f64)), &Rad(f64::consts::FRAC_PI_2)); - assert_ulps_eq!(Vector2::new(10.0f64, 0.0f64).angle(Vector2::new(0.0f64, 5.0f64)), &Rad(f64::consts::FRAC_PI_2)); - assert_ulps_eq!(Vector2::new(-1.0f64, 0.0f64).angle(Vector2::new(0.0f64, 1.0f64)), &-Rad(f64::consts::FRAC_PI_2)); - - assert_ulps_eq!(Vector3::new(1.0f64, 0.0f64, 1.0f64).angle(Vector3::new(1.0f64, 1.0f64, 0.0f64)), &Rad(f64::consts::FRAC_PI_3)); - assert_ulps_eq!(Vector3::new(10.0f64, 0.0f64, 10.0f64).angle(Vector3::new(5.0f64, 5.0f64, 0.0f64)), &Rad(f64::consts::FRAC_PI_3)); - assert_ulps_eq!(Vector3::new(-1.0f64, 0.0f64, -1.0f64).angle(Vector3::new(1.0f64, -1.0f64, 0.0f64)), &Rad(2.0f64 * f64::consts::FRAC_PI_3)); - - assert_ulps_eq!(Vector4::new(1.0f64, 0.0f64, 1.0f64, 0.0f64).angle(Vector4::new(0.0f64, 1.0f64, 0.0f64, 1.0f64)), &Rad(f64::consts::FRAC_PI_2)); - assert_ulps_eq!(Vector4::new(10.0f64, 0.0f64, 10.0f64, 0.0f64).angle(Vector4::new(0.0f64, 5.0f64, 0.0f64, 5.0f64)), &Rad(f64::consts::FRAC_PI_2)); - assert_ulps_eq!(Vector4::new(-1.0f64, 0.0f64, -1.0f64, 0.0f64).angle(Vector4::new(0.0f64, 1.0f64, 0.0f64, 1.0f64)), &Rad(f64::consts::FRAC_PI_2)); + assert_ulps_eq!( + Vector2::new(1.0f64, 0.0f64).angle(Vector2::new(0.0f64, 1.0f64)), + &Rad(f64::consts::FRAC_PI_2) + ); + assert_ulps_eq!( + Vector2::new(10.0f64, 0.0f64).angle(Vector2::new(0.0f64, 5.0f64)), + &Rad(f64::consts::FRAC_PI_2) + ); + assert_ulps_eq!( + Vector2::new(-1.0f64, 0.0f64).angle(Vector2::new(0.0f64, 1.0f64)), + &-Rad(f64::consts::FRAC_PI_2) + ); + + assert_ulps_eq!( + Vector3::new(1.0f64, 0.0f64, 1.0f64).angle(Vector3::new(1.0f64, 1.0f64, 0.0f64)), + &Rad(f64::consts::FRAC_PI_3) + ); + assert_ulps_eq!( + Vector3::new(10.0f64, 0.0f64, 10.0f64).angle(Vector3::new(5.0f64, 5.0f64, 0.0f64)), + &Rad(f64::consts::FRAC_PI_3) + ); + assert_ulps_eq!( + Vector3::new(-1.0f64, 0.0f64, -1.0f64).angle(Vector3::new(1.0f64, -1.0f64, 0.0f64)), + &Rad(2.0f64 * f64::consts::FRAC_PI_3) + ); + + assert_ulps_eq!( + Vector4::new(1.0f64, 0.0f64, 1.0f64, 0.0f64).angle(Vector4::new( + 0.0f64, + 1.0f64, + 0.0f64, + 1.0f64 + )), + &Rad(f64::consts::FRAC_PI_2) + ); + assert_ulps_eq!( + Vector4::new(10.0f64, 0.0f64, 10.0f64, 0.0f64).angle(Vector4::new( + 0.0f64, + 5.0f64, + 0.0f64, + 5.0f64 + )), + &Rad(f64::consts::FRAC_PI_2) + ); + assert_ulps_eq!( + Vector4::new(-1.0f64, 0.0f64, -1.0f64, 0.0f64).angle(Vector4::new( + 0.0f64, + 1.0f64, + 0.0f64, + 1.0f64 + )), + &Rad(f64::consts::FRAC_PI_2) + ); } #[test] fn test_normalize() { // TODO: test normalize_to, normalize_sel.0, and normalize_self_to - assert_ulps_eq!(Vector2::new(3.0f64, 4.0f64).normalize(), &Vector2::new(3.0/5.0, 4.0/5.0)); - assert_ulps_eq!(Vector3::new(2.0f64, 3.0f64, 6.0f64).normalize(), &Vector3::new(2.0/7.0, 3.0/7.0, 6.0/7.0)); - assert_ulps_eq!(Vector4::new(1.0f64, 2.0f64, 4.0f64, 10.0f64).normalize(), &Vector4::new(1.0/11.0, 2.0/11.0, 4.0/11.0, 10.0/11.0)); + assert_ulps_eq!( + Vector2::new(3.0f64, 4.0f64).normalize(), + &Vector2::new(3.0 / 5.0, 4.0 / 5.0) + ); + assert_ulps_eq!( + Vector3::new(2.0f64, 3.0f64, 6.0f64).normalize(), + &Vector3::new(2.0 / 7.0, 3.0 / 7.0, 6.0 / 7.0) + ); + assert_ulps_eq!( + Vector4::new(1.0f64, 2.0f64, 4.0f64, 10.0f64).normalize(), + &Vector4::new(1.0 / 11.0, 2.0 / 11.0, 4.0 / 11.0, 10.0 / 11.0) + ); } #[test] fn test_project_on() { - assert_ulps_eq!(Vector2::new(-1.0f64, 5.0).project_on(Vector2::new(2.0, 4.0)), &Vector2::new(9.0/5.0, 18.0/5.0)); - assert_ulps_eq!(Vector3::new(5.0f64, 6.0, 7.0).project_on(Vector3::new(1.0, 1.0, 1.0)), &Vector3::new(6.0, 6.0, 6.0)); - assert_ulps_eq!(Vector4::new(0.0f64, -5.0, 5.0, 5.0).project_on(Vector4::new(0.0, 1.0, 0.0, 0.5)), &Vector4::new(0.0, -2.0, 0.0, -1.0)); + assert_ulps_eq!( + Vector2::new(-1.0f64, 5.0).project_on(Vector2::new(2.0, 4.0)), + &Vector2::new(9.0 / 5.0, 18.0 / 5.0) + ); + assert_ulps_eq!( + Vector3::new(5.0f64, 6.0, 7.0).project_on(Vector3::new(1.0, 1.0, 1.0)), + &Vector3::new(6.0, 6.0, 6.0) + ); + assert_ulps_eq!( + Vector4::new(0.0f64, -5.0, 5.0, 5.0).project_on(Vector4::new(0.0, 1.0, 0.0, 0.5)), + &Vector4::new(0.0, -2.0, 0.0, -1.0) + ); } #[test] fn test_cast() { - assert_ulps_eq!(Vector2::new(0.9f64, 1.5).cast().unwrap(), Vector2::new(0.9f32, 1.5)); - assert_ulps_eq!(Vector3::new(1.0f64, 2.4, -3.13).cast().unwrap(), Vector3::new(1.0f32, 2.4, -3.13)); - assert_ulps_eq!(Vector4::new(13.5f64, -4.6, -8.3, 2.41).cast().unwrap(), Vector4::new(13.5f32, -4.6, -8.3, 2.41)); + assert_ulps_eq!( + Vector2::new(0.9f64, 1.5).cast().unwrap(), + Vector2::new(0.9f32, 1.5) + ); + assert_ulps_eq!( + Vector3::new(1.0f64, 2.4, -3.13).cast().unwrap(), + Vector3::new(1.0f32, 2.4, -3.13) + ); + assert_ulps_eq!( + Vector4::new(13.5f64, -4.6, -8.3, 2.41).cast().unwrap(), + Vector4::new(13.5f32, -4.6, -8.3, 2.41) + ); } diff --git a/tests/vector4f32.rs b/tests/vector4f32.rs index 6889471c..3a9a02fe 100644 --- a/tests/vector4f32.rs +++ b/tests/vector4f32.rs @@ -22,12 +22,18 @@ use std::f32; #[test] fn test_constructor() { - assert_eq!(vec4(1f32, 2f32, 3f32, 4f32), Vector4::new(1f32, 2f32, 3f32, 4f32)); + assert_eq!( + vec4(1f32, 2f32, 3f32, 4f32), + Vector4::new(1f32, 2f32, 3f32, 4f32) + ); } #[test] fn test_from_value() { - assert_eq!(Vector4::from_value(76.5f32), Vector4::new(76.5f32, 76.5f32, 76.5f32, 76.5f32)); + assert_eq!( + Vector4::from_value(76.5f32), + Vector4::new(76.5f32, 76.5f32, 76.5f32, 76.5f32) + ); } macro_rules! impl_test_add { @@ -84,32 +90,60 @@ macro_rules! impl_test_rem { #[test] fn test_add() { - impl_test_add!(Vector4 { x, y, z, w }, 2.0f32, vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32)); + impl_test_add!( + Vector4 { x, y, z, w }, + 2.0f32, + vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32) + ); } #[test] fn test_sub() { - impl_test_sub!(Vector4 { x, y, z, w }, 2.0f32, vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32)); + impl_test_sub!( + Vector4 { x, y, z, w }, + 2.0f32, + vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32) + ); } #[test] fn test_mul() { - impl_test_mul!(Vector4 { x, y, z, w }, 2.0f32, vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32)); + impl_test_mul!( + Vector4 { x, y, z, w }, + 2.0f32, + vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32) + ); } #[test] fn test_div() { - impl_test_div!(Vector4 { x, y, z, w }, 2.0f32, vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32)); + impl_test_div!( + Vector4 { x, y, z, w }, + 2.0f32, + vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32) + ); } #[test] fn test_rem() { - impl_test_rem!(Vector4 { x, y, z, w }, 2.0f32, vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32)); + impl_test_rem!( + Vector4 { x, y, z, w }, + 2.0f32, + vec4(2.0f32, 4.0f32, 6.0f32, 8.0f32) + ); } #[test] fn test_dot() { - assert_eq!(Vector4::new(1.0f32, 2.0f32, 3.0f32, 4.0f32).dot(Vector4::new(5.0f32, 6.0f32, 7.0f32, 8.0f32)), 70.0f32); + assert_eq!( + Vector4::new(1.0f32, 2.0f32, 3.0f32, 4.0f32).dot(Vector4::new( + 5.0f32, + 6.0f32, + 7.0f32, + 8.0f32 + )), + 70.0f32 + ); } #[test] @@ -123,12 +157,22 @@ fn test_sum() { fn test_product() { assert_eq!(Vector4::new(1f32, 2f32, 3f32, 4f32).product(), 24f32); - assert_eq!(Vector4::new(5.0f32, 6.0f32, 7.0f32, 8.0f32).product(), 1680.0f32); + assert_eq!( + Vector4::new(5.0f32, 6.0f32, 7.0f32, 8.0f32).product(), + 1680.0f32 + ); } #[test] fn test_is_perpendicular() { - assert!(Vector4::new(1.0f32, 0.0f32, 0.0f32, 0.0f32).is_perpendicular(Vector4::new(0.0f32, 0.0f32, 0.0f32, 1.0f32))); + assert!( + Vector4::new(1.0f32, 0.0f32, 0.0f32, 0.0f32).is_perpendicular(Vector4::new( + 0.0f32, + 0.0f32, + 0.0f32, + 1.0f32 + )) + ); } #[cfg(test)] @@ -136,7 +180,7 @@ mod test_magnitude { use cgmath::*; #[test] - fn test_vector4(){ + fn test_vector4() { let (a, a_res) = (Vector4::new(1.0f32, 2.0f32, 4.0f32, 10.0f32), 11.0f32); // (1, 2, 4, 10, 11) Pythagorean quintuple let (b, b_res) = (Vector4::new(1.0f32, 2.0f32, 8.0f32, 10.0f32), 13.0f32); // (1, 2, 8, 10, 13) Pythagorean quintuple @@ -150,26 +194,69 @@ mod test_magnitude { { let a = Vector4::new(1f32, 4f32, 9f32, 16f32); assert_ulps_eq!(a.sqrt_element_wide(), Vector4::new(1f32, 2f32, 3f32, 4f32)); - assert_relative_eq!(a.sqrt_element_wide().recip_element_wide(), Vector4::new(1f32, 1f32/2f32, 1f32/3f32, 1f32/4f32), max_relative = 0.005f32); - assert_relative_eq!(a.rsqrt_element_wide(), Vector4::new(1f32, 1f32/2f32, 1f32/3f32, 1f32/4f32), max_relative= 0.005f32); + assert_relative_eq!( + a.sqrt_element_wide().recip_element_wide(), + Vector4::new(1f32, 1f32 / 2f32, 1f32 / 3f32, 1f32 / 4f32), + max_relative = 0.005f32 + ); + assert_relative_eq!( + a.rsqrt_element_wide(), + Vector4::new(1f32, 1f32 / 2f32, 1f32 / 3f32, 1f32 / 4f32), + max_relative = 0.005f32 + ); } } } #[test] fn test_angle() { - assert_ulps_eq!(Vector4::new(1.0f32, 0.0f32, 1.0f32, 0.0f32).angle(Vector4::new(0.0f32, 1.0f32, 0.0f32, 1.0f32)), &Rad(f32::consts::FRAC_PI_2)); - assert_ulps_eq!(Vector4::new(10.0f32, 0.0f32, 10.0f32, 0.0f32).angle(Vector4::new(0.0f32, 5.0f32, 0.0f32, 5.0f32)), &Rad(f32::consts::FRAC_PI_2)); - assert_ulps_eq!(Vector4::new(-1.0f32, 0.0f32, -1.0f32, 0.0f32).angle(Vector4::new(0.0f32, 1.0f32, 0.0f32, 1.0f32)), &Rad(f32::consts::FRAC_PI_2)); + assert_ulps_eq!( + Vector4::new(1.0f32, 0.0f32, 1.0f32, 0.0f32).angle(Vector4::new( + 0.0f32, + 1.0f32, + 0.0f32, + 1.0f32 + )), + &Rad(f32::consts::FRAC_PI_2) + ); + assert_ulps_eq!( + Vector4::new(10.0f32, 0.0f32, 10.0f32, 0.0f32).angle(Vector4::new( + 0.0f32, + 5.0f32, + 0.0f32, + 5.0f32 + )), + &Rad(f32::consts::FRAC_PI_2) + ); + assert_ulps_eq!( + Vector4::new(-1.0f32, 0.0f32, -1.0f32, 0.0f32).angle(Vector4::new( + 0.0f32, + 1.0f32, + 0.0f32, + 1.0f32 + )), + &Rad(f32::consts::FRAC_PI_2) + ); } #[test] fn test_normalize() { // TODO: test normalize_to, normalize_sel.0f32, and normalize_self_to - assert_ulps_eq!(Vector4::new(1.0f32, 2.0f32, 4.0f32, 10.0f32).normalize(), &Vector4::new(1.0f32/11.0f32, 2.0f32/11.0f32, 4.0f32/11.0f32, 10.0f32/11.0f32)); + assert_ulps_eq!( + Vector4::new(1.0f32, 2.0f32, 4.0f32, 10.0f32).normalize(), + &Vector4::new( + 1.0f32 / 11.0f32, + 2.0f32 / 11.0f32, + 4.0f32 / 11.0f32, + 10.0f32 / 11.0f32 + ) + ); } #[test] fn test_cast() { - assert_ulps_eq!(Vector4::new(13.5f32, -4.6, -8.3, 2.41).cast().unwrap(), Vector4::new(13.5f32, -4.6, -8.3, 2.41)); + assert_ulps_eq!( + Vector4::new(13.5f32, -4.6, -8.3, 2.41).cast().unwrap(), + Vector4::new(13.5f32, -4.6, -8.3, 2.41) + ); }