diff --git a/src/matrix.rs b/src/matrix.rs index 399e0a2..148ab50 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -263,16 +263,13 @@ pub trait Matrix where Self: Index::Column>, Self: IndexMut::Column>, Self: ApproxEq::Element>, - // FIXME: blocked by rust-lang/rust#20671 - // - // for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>, - // for<'a, 'b> &'a Self: Sub<&'b Self, Output = Self>, - // for<'a, 'b> &'a Self: Mul<&'b Self, Output = Self>, - // for<'a, 'b> &'a Self: Mul<&'b V, Output = V>, - // - // for<'a> &'a Self: Mul, - // for<'a> &'a Self: Div, - // for<'a> &'a Self: Rem, + + Self: Add, + Self: Sub, + + Self: Mul<::Element, Output = Self>, + Self: Div<::Element, Output = Self>, + Self: Rem<::Element, Output = Self>, { /// The type of the elements in the matrix. type Element: BaseFloat; @@ -316,22 +313,6 @@ pub trait Matrix where /// Create a matrix with all of the elements set to zero. fn zero() -> Self; - /// Multiply the matrix by another matrix, - fn mul_m(&self, other: &Self::Transpose) -> Self; - - /// Multiply the matrix by a column vector. - fn mul_v(&self, column: Self::Column) -> Self::Column; - - /// Multiply this matrix by a scalar, returning the new matrix. - fn mul_s(&self, scalar: Self::Element) -> Self; - /// Divide this matrix by a scalar, returning the new matrix. - fn div_s(&self, scalar: Self::Element) -> Self; - - /// Multiply this matrix by a scalar, in-place. - fn mul_self_s(&mut self, scalar: Self::Element); - /// Divide this matrix by a scalar, in-place. - fn div_self_s(&mut self, scalar: Self::Element); - /// Transpose this matrix, returning a new matrix. fn transpose(&self) -> Self::Transpose; } @@ -344,6 +325,8 @@ pub trait SquareMatrix where Row = ::ColumnRow, Transpose = Self, >, + Self: Mul<::Column, Output = ::Column>, + Self: Mul, { // FIXME: Will not be needed once equality constraints in where clauses are implemented /// The row/column vector of the matrix. @@ -362,19 +345,6 @@ pub trait SquareMatrix where /// matrix with another has no effect. fn identity() -> Self; - /// Add this matrix with another matrix, returning the new metrix. - fn add_m(&self, m: &Self) -> Self; - /// Subtract another matrix from this matrix, returning the new matrix. - fn sub_m(&self, m: &Self) -> Self; - - /// Add this matrix with another matrix, in-place. - fn add_self_m(&mut self, m: &Self); - /// Subtract another matrix from this matrix, in-place. - fn sub_self_m(&mut self, m: &Self); - - /// Multiply this matrix by another matrix, in-place. - fn mul_self_m(&mut self, m: &Self) { *self = self.mul_m(m); } - /// Transpose this matrix in-place. fn transpose_self(&mut self); /// Take the determinant of this matrix. @@ -453,30 +423,6 @@ impl Matrix for Matrix2 { S::zero(), S::zero()) } - #[inline] - fn mul_m(&self, other: &Matrix2) -> Matrix2 { self * other } - - #[inline] - fn mul_v(&self, v: Vector2) -> Vector2 { self * v } - - #[inline] - fn mul_s(&self, s: S) -> Matrix2 { self * s } - - #[inline] - fn div_s(&self, s: S) -> Matrix2 { self / s } - - #[inline] - fn mul_self_s(&mut self, s: S) { - self[0] = self[0] * s; - self[1] = self[1] * s; - } - - #[inline] - fn div_self_s(&mut self, s: S) { - self[0] = self[0] / s; - self[1] = self[1] / s; - } - fn transpose(&self) -> Matrix2 { Matrix2::new(self[0][0], self[1][0], self[0][1], self[1][1]) @@ -503,24 +449,6 @@ impl SquareMatrix for Matrix2 { Matrix2::from_value(S::one()) } - #[inline] - fn add_m(&self, m: &Matrix2) -> Matrix2 { self + m } - - #[inline] - fn sub_m(&self, m: &Matrix2) -> Matrix2 { self - m } - - #[inline] - fn add_self_m(&mut self, m: &Matrix2) { - self[0] = self[0] + m[0]; - self[1] = self[1] + m[1]; - } - - #[inline] - fn sub_self_m(&mut self, m: &Matrix2) { - self[0] = self[0] - m[0]; - self[1] = self[1] - m[1]; - } - #[inline] fn transpose_self(&mut self) { self.swap_elements((0, 1), (1, 0)); @@ -601,32 +529,6 @@ impl Matrix for Matrix3 { S::zero(), S::zero(), S::zero()) } - #[inline] - fn mul_m(&self, other: &Matrix3) -> Matrix3 { self * other } - - #[inline] - fn mul_v(&self, v: Vector3) -> Vector3 { self * v} - - #[inline] - fn mul_s(&self, s: S) -> Matrix3 { self * s } - - #[inline] - fn div_s(&self, s: S) -> Matrix3 { self / s } - - #[inline] - fn mul_self_s(&mut self, s: S) { - self[0] = self[0] * s; - self[1] = self[1] * s; - self[2] = self[2] * s; - } - - #[inline] - fn div_self_s(&mut self, s: S) { - self[0] = self[0] / s; - self[1] = self[1] / s; - self[2] = self[2] / s; - } - fn transpose(&self) -> Matrix3 { Matrix3::new(self[0][0], self[1][0], self[2][0], self[0][1], self[1][1], self[2][1], @@ -656,26 +558,6 @@ impl SquareMatrix for Matrix3 { Matrix3::from_value(S::one()) } - #[inline] - fn add_m(&self, m: &Matrix3) -> Matrix3 { self + m } - - #[inline] - fn sub_m(&self, m: &Matrix3) -> Matrix3 { self - m } - - #[inline] - fn add_self_m(&mut self, m: &Matrix3) { - self[0] = self[0] + m[0]; - self[1] = self[1] + m[1]; - self[2] = self[2] + m[2]; - } - - #[inline] - fn sub_self_m(&mut self, m: &Matrix3) { - self[0] = self[0] - m[0]; - self[1] = self[1] - m[1]; - self[2] = self[2] - m[2]; - } - #[inline] fn transpose_self(&mut self) { self.swap_elements((0, 1), (1, 0)); @@ -770,34 +652,6 @@ impl Matrix for Matrix4 { S::zero(), S::zero(), S::zero(), S::zero()) } - #[inline] - fn mul_m(&self, other: &Matrix4) -> Matrix4 { self * other } - - #[inline] - fn mul_v(&self, v: Vector4) -> Vector4 { self * v } - - #[inline] - fn mul_s(&self, s: S) -> Matrix4 { self * s } - - #[inline] - fn div_s(&self, s: S) -> Matrix4 { self / s } - - #[inline] - fn mul_self_s(&mut self, s: S) { - self[0] = self[0] * s; - self[1] = self[1] * s; - self[2] = self[2] * s; - self[3] = self[3] * s; - } - - #[inline] - fn div_self_s(&mut self, s: S) { - self[0] = self[0] / s; - self[1] = self[1] / s; - self[2] = self[2] / s; - self[3] = self[3] / s; - } - 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], @@ -830,28 +684,6 @@ impl SquareMatrix for Matrix4 { Matrix4::from_value(S::one()) } - #[inline] - fn add_m(&self, m: &Matrix4) -> Matrix4 { self + m } - - #[inline] - fn sub_m(&self, m: &Matrix4) -> Matrix4 { self - m } - - #[inline] - fn add_self_m(&mut self, m: &Matrix4) { - self[0] = self[0] + m[0]; - self[1] = self[1] + m[1]; - self[2] = self[2] + m[2]; - self[3] = self[3] + m[3]; - } - - #[inline] - fn sub_self_m(&mut self, m: &Matrix4) { - self[0] = self[0] - m[0]; - self[1] = self[1] - m[1]; - self[2] = self[2] - m[2]; - self[3] = self[3] - m[3]; - } - fn transpose_self(&mut self) { self.swap_elements((0, 1), (1, 0)); self.swap_elements((0, 2), (2, 0)); @@ -1010,116 +842,71 @@ impl Neg for Matrix4 { } } -macro_rules! impl_scalar_binary_operator { - ($Binop:ident :: $binop:ident, $MatrixN:ident { $($field:ident),+ }) => { - impl<'a, S: BaseFloat> $Binop for &'a $MatrixN { - type Output = $MatrixN; +macro_rules! impl_binary_operators { + ($MatrixN:ident, $VectorN:ident { $($field:ident : $row_index:expr),+ }) => { + impl_binary_operator!( Mul for $MatrixN { + fn mul(matrix, scalar) -> $MatrixN { $MatrixN { $($field: matrix.$field * scalar),+ } } + }); + impl_binary_operator!( Div for $MatrixN { + fn div(matrix, scalar) -> $MatrixN { $MatrixN { $($field: matrix.$field / scalar),+ } } + }); + impl_binary_operator!( Rem for $MatrixN { + fn rem(matrix, scalar) -> $MatrixN { $MatrixN { $($field: matrix.$field % scalar),+ } } + }); - #[inline] - fn $binop(self, s: S) -> $MatrixN { - $MatrixN { $($field: self.$field.$binop(s)),+ } - } - } + impl_binary_operator!( Add<$MatrixN > for $MatrixN { + fn add(lhs, rhs) -> $MatrixN { $MatrixN { $($field: lhs.$field + rhs.$field ),+ } } + }); + impl_binary_operator!( Sub<$MatrixN > for $MatrixN { + fn sub(lhs, rhs) -> $MatrixN { $MatrixN { $($field: lhs.$field - rhs.$field ),+ } } + }); + + impl_binary_operator!( Mul<$VectorN > for $MatrixN { + fn mul(matrix, vector) -> $VectorN { $VectorN::new($(matrix.row($row_index).dot(vector.clone())),+) } + }); } } -impl_scalar_binary_operator!(Mul::mul, Matrix2 { x, y }); -impl_scalar_binary_operator!(Mul::mul, Matrix3 { x, y, z }); -impl_scalar_binary_operator!(Mul::mul, Matrix4 { x, y, z, w }); -impl_scalar_binary_operator!(Div::div, Matrix2 { x, y }); -impl_scalar_binary_operator!(Div::div, Matrix3 { x, y, z }); -impl_scalar_binary_operator!(Div::div, Matrix4 { x, y, z, w }); -impl_scalar_binary_operator!(Rem::rem, Matrix2 { x, y }); -impl_scalar_binary_operator!(Rem::rem, Matrix3 { x, y, z }); -impl_scalar_binary_operator!(Rem::rem, Matrix4 { x, y, z, w }); +impl_binary_operators!(Matrix2, Vector2 { x: 0, y: 1 }); +impl_binary_operators!(Matrix3, Vector3 { x: 0, y: 1, z: 2 }); +impl_binary_operators!(Matrix4, Vector4 { x: 0, y: 1, z: 2, w: 3 }); -macro_rules! impl_binary_operator { - ($Binop:ident :: $binop:ident, $MatrixN:ident { $($field:ident),+ }) => { - impl<'a, 'b, S: BaseFloat> $Binop<&'a $MatrixN> for &'b $MatrixN { - type Output = $MatrixN; - - #[inline] - fn $binop(self, other: &'a $MatrixN) -> $MatrixN { - $MatrixN { $($field: self.$field.$binop(other.$field)),+ } - } - } +impl_binary_operator!( Mul > for Matrix2 { + fn mul(lhs, rhs) -> Matrix2 { + Matrix2::new(lhs.row(0).dot(rhs[0]), lhs.row(1).dot(rhs[0]), + lhs.row(0).dot(rhs[1]), lhs.row(1).dot(rhs[1])) } +}); + +impl_binary_operator!( Mul > for Matrix3 { + fn mul(lhs, rhs) -> Matrix3 { + Matrix3::new(lhs.row(0).dot(rhs[0]), lhs.row(1).dot(rhs[0]), lhs.row(2).dot(rhs[0]), + lhs.row(0).dot(rhs[1]), lhs.row(1).dot(rhs[1]), lhs.row(2).dot(rhs[1]), + lhs.row(0).dot(rhs[2]), lhs.row(1).dot(rhs[2]), lhs.row(2).dot(rhs[2])) + } +}); + +// Using self.row(0).dot(other[0]) like the other matrix multiplies +// causes the LLVM to miss identical loads and multiplies. This optimization +// causes the code to be auto vectorized properly increasing the performance +// around ~4 times. +macro_rules! dot_matrix4 { + ($A:expr, $B:expr, $I:expr, $J:expr) => { + ($A[0][$I]) * ($B[$J][0]) + + ($A[1][$I]) * ($B[$J][1]) + + ($A[2][$I]) * ($B[$J][2]) + + ($A[3][$I]) * ($B[$J][3]) + }; } -impl_binary_operator!(Add::add, Matrix2 { x, y }); -impl_binary_operator!(Add::add, Matrix3 { x, y, z }); -impl_binary_operator!(Add::add, Matrix4 { x, y, z, w }); -impl_binary_operator!(Sub::sub, Matrix2 { x, y }); -impl_binary_operator!(Sub::sub, Matrix3 { x, y, z }); -impl_binary_operator!(Sub::sub, Matrix4 { x, y, z, w }); - -macro_rules! impl_vector_mul_operators { - ($MatrixN:ident, $VectorN:ident { $($row_index:expr),+ }) => { - impl<'a, S: BaseFloat> Mul<$VectorN> for &'a $MatrixN { - type Output = $VectorN; - - fn mul(self, v: $VectorN) -> $VectorN { - $VectorN::new($(self.row($row_index).dot(v)),+) - } - } - - impl<'a, 'b, S: BaseFloat> Mul<&'a $VectorN> for &'b $MatrixN { - type Output = $VectorN; - - fn mul(self, v: &'a $VectorN) -> $VectorN { - $VectorN::new($(self.row($row_index).dot(*v)),+) - } - } +impl_binary_operator!( Mul > for Matrix4 { + fn mul(lhs, rhs) -> Matrix4 { + Matrix4::new(dot_matrix4!(lhs, rhs, 0, 0), dot_matrix4!(lhs, rhs, 1, 0), dot_matrix4!(lhs, rhs, 2, 0), dot_matrix4!(lhs, rhs, 3, 0), + dot_matrix4!(lhs, rhs, 0, 1), dot_matrix4!(lhs, rhs, 1, 1), dot_matrix4!(lhs, rhs, 2, 1), dot_matrix4!(lhs, rhs, 3, 1), + dot_matrix4!(lhs, rhs, 0, 2), dot_matrix4!(lhs, rhs, 1, 2), dot_matrix4!(lhs, rhs, 2, 2), dot_matrix4!(lhs, rhs, 3, 2), + dot_matrix4!(lhs, rhs, 0, 3), dot_matrix4!(lhs, rhs, 1, 3), dot_matrix4!(lhs, rhs, 2, 3), dot_matrix4!(lhs, rhs, 3, 3)) } -} - -impl_vector_mul_operators!(Matrix2, Vector2 { 0, 1 }); -impl_vector_mul_operators!(Matrix3, Vector3 { 0, 1, 2 }); -impl_vector_mul_operators!(Matrix4, Vector4 { 0, 1, 2, 3 }); - -impl<'a, 'b, S: BaseFloat> Mul<&'a Matrix2> for &'b Matrix2 { - type Output = Matrix2; - - fn mul(self, other: &'a Matrix2) -> Matrix2 { - Matrix2::new(self.row(0).dot(other[0]), self.row(1).dot(other[0]), - self.row(0).dot(other[1]), self.row(1).dot(other[1])) - } -} - -impl<'a, 'b, S: BaseFloat> Mul<&'a Matrix3> for &'b Matrix3 { - type Output = Matrix3; - - fn mul(self, other: &'a Matrix3) -> Matrix3 { - Matrix3::new(self.row(0).dot(other[0]),self.row(1).dot(other[0]),self.row(2).dot(other[0]), - self.row(0).dot(other[1]),self.row(1).dot(other[1]),self.row(2).dot(other[1]), - self.row(0).dot(other[2]),self.row(1).dot(other[2]),self.row(2).dot(other[2])) - } -} - -impl<'a, 'b, S: BaseFloat> Mul<&'a Matrix4> for &'b Matrix4 { - type Output = Matrix4; - - fn mul(self, other: &'a Matrix4) -> Matrix4 { - // Using self.row(0).dot(other[0]) like the other matrix multiplies - // causes the LLVM to miss identical loads and multiplies. This optimization - // causes the code to be auto vectorized properly increasing the performance - // around ~4 times. - macro_rules! dot_matrix4 { - ($A:expr, $B:expr, $I:expr, $J:expr) => { - ($A[0][$I]) * ($B[$J][0]) + - ($A[1][$I]) * ($B[$J][1]) + - ($A[2][$I]) * ($B[$J][2]) + - ($A[3][$I]) * ($B[$J][3]) - }; - }; - - Matrix4::new(dot_matrix4!(self, other, 0, 0), dot_matrix4!(self, other, 1, 0), dot_matrix4!(self, other, 2, 0), dot_matrix4!(self, other, 3, 0), - dot_matrix4!(self, other, 0, 1), dot_matrix4!(self, other, 1, 1), dot_matrix4!(self, other, 2, 1), dot_matrix4!(self, other, 3, 1), - dot_matrix4!(self, other, 0, 2), dot_matrix4!(self, other, 1, 2), dot_matrix4!(self, other, 2, 2), dot_matrix4!(self, other, 3, 2), - dot_matrix4!(self, other, 0, 3), dot_matrix4!(self, other, 1, 3), dot_matrix4!(self, other, 2, 3), dot_matrix4!(self, other, 3, 3)) - - } -} +}); macro_rules! index_operators { ($MatrixN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => { diff --git a/src/rotation.rs b/src/rotation.rs index 9efd908..d69e648 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -15,7 +15,7 @@ use angle::{Angle, Rad}; use approx::ApproxEq; -use matrix::{Matrix, SquareMatrix}; +use matrix::SquareMatrix; use matrix::{Matrix2, Matrix3}; use num::BaseFloat; use point::{Point, Point2, Point3}; @@ -150,7 +150,7 @@ pub trait Rotation3: Rotation> /// /// // This is exactly equivalent to using the raw matrix itself: /// let unit_y2: Matrix2<_> = rot.into(); -/// let unit_y2 = unit_y2.mul_v(unit_x); +/// let unit_y2 = unit_y2 * unit_x; /// assert_eq!(unit_y2, unit_y); /// /// // Note that we can also concatenate rotations: @@ -190,13 +190,13 @@ impl Rotation> for Basis2 { } #[inline] - fn rotate_vector(&self, vec: Vector2) -> Vector2 { self.mat.mul_v(vec) } + fn rotate_vector(&self, vec: Vector2) -> Vector2 { self.mat * vec } #[inline] - fn concat(&self, other: &Basis2) -> Basis2 { Basis2 { mat: self.mat.mul_m(&other.mat) } } + fn concat(&self, other: &Basis2) -> Basis2 { Basis2 { mat: self.mat * other.mat } } #[inline] - fn concat_self(&mut self, other: &Basis2) { self.mat.mul_self_m(&other.mat); } + fn concat_self(&mut self, other: &Basis2) { self.mat = self.mat * other.mat; } // TODO: we know the matrix is orthogonal, so this could be re-written // to be faster @@ -274,13 +274,13 @@ impl Rotation> for Basis3 { } #[inline] - fn rotate_vector(&self, vec: Vector3) -> Vector3 { self.mat.mul_v(vec) } + fn rotate_vector(&self, vec: Vector3) -> Vector3 { self.mat * vec } #[inline] - fn concat(&self, other: &Basis3) -> Basis3 { Basis3 { mat: self.mat.mul_m(&other.mat) } } + fn concat(&self, other: &Basis3) -> Basis3 { Basis3 { mat: self.mat * other.mat } } #[inline] - fn concat_self(&mut self, other: &Basis3) { self.mat.mul_self_m(&other.mat); } + fn concat_self(&mut self, other: &Basis3) { self.mat = self.mat * other.mat; } // TODO: we know the matrix is orthogonal, so this could be re-written // to be faster diff --git a/src/transform.rs b/src/transform.rs index 4f5c958..dfe99fd 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -189,17 +189,17 @@ impl Transform> for AffineMatrix3 { #[inline] fn transform_vector(&self, vec: Vector3) -> Vector3 { - self.mat.mul_v(vec.extend(S::zero())).truncate() + (self.mat * vec.extend(S::zero())).truncate() } #[inline] fn transform_point(&self, point: Point3) -> Point3 { - Point3::from_homogeneous(self.mat.mul_v(point.to_homogeneous())) + Point3::from_homogeneous(self.mat * point.to_homogeneous()) } #[inline] fn concat(&self, other: &AffineMatrix3) -> AffineMatrix3 { - AffineMatrix3 { mat: self.mat.mul_m(&other.mat) } + AffineMatrix3 { mat: self.mat * other.mat } } #[inline] diff --git a/tests/matrix.rs b/tests/matrix.rs index 2a931d2..dbc3432 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -78,16 +78,15 @@ pub mod matrix4 { #[test] fn test_neg() { - // Matrix2 assert_eq!(-matrix2::A, Matrix2::new(-1.0f64, -3.0f64, -2.0f64, -4.0f64)); - // Matrix3 + assert_eq!(-matrix3::A, Matrix3::new(-1.0f64, -4.0f64, -7.0f64, -2.0f64, -5.0f64, -8.0f64, -3.0f64, -6.0f64, -9.0f64)); - // Matrix4 + assert_eq!(-matrix4::A, Matrix4::new(-1.0f64, -5.0f64, -9.0f64, -13.0f64, -2.0f64, -6.0f64, -10.0f64, -14.0f64, @@ -96,126 +95,84 @@ fn test_neg() { } #[test] -fn test_mul_s() { - // Matrix2 - assert_eq!(matrix2::A.mul_s(matrix2::F), +fn test_mul_scalar() { + assert_eq!(matrix2::A * matrix2::F, Matrix2::new(0.5f64, 1.5f64, 1.0f64, 2.0f64)); - let mut mut_a = matrix2::A; - mut_a.mul_self_s(matrix2::F); - assert_eq!(mut_a, matrix2::A.mul_s(matrix2::F)); - // Matrix3 - assert_eq!(matrix3::A.mul_s(matrix3::F), + assert_eq!(matrix3::A * matrix3::F, Matrix3::new(0.5f64, 2.0f64, 3.5f64, 1.0f64, 2.5f64, 4.0f64, 1.5f64, 3.0f64, 4.5f64)); - let mut mut_a = matrix3::A; - mut_a.mul_self_s(matrix3::F); - assert_eq!(mut_a, matrix3::A.mul_s(matrix3::F)); - // Matrix4 - assert_eq!(matrix4::A.mul_s(matrix4::F), + assert_eq!(matrix4::A * matrix4::F, Matrix4::new(0.5f64, 2.5f64, 4.5f64, 6.5f64, 1.0f64, 3.0f64, 5.0f64, 7.0f64, 1.5f64, 3.5f64, 5.5f64, 7.5f64, 2.0f64, 4.0f64, 6.0f64, 8.0f64)); - let mut mut_a = matrix4::A; - mut_a.mul_self_s(matrix4::F); - assert_eq!(mut_a, matrix4::A.mul_s(matrix4::F)); } #[test] -fn test_add_m() { - // Matrix2 - assert_eq!(matrix2::A.add_m(&matrix2::B), +fn test_add_matrix() { + assert_eq!(matrix2::A + matrix2::B, Matrix2::new(3.0f64, 7.0f64, 5.0f64, 9.0f64)); - let mut mut_a = matrix2::A; - mut_a.add_self_m(&matrix2::B); - assert_eq!(mut_a, matrix2::A.add_m(&matrix2::B)); - assert_eq!(mut_a, &matrix2::A + &matrix2::B); - // Matrix3 - assert_eq!(matrix3::A.add_m(&matrix3::B), + assert_eq!(matrix3::A + matrix3::B, Matrix3::new(3.0f64, 9.0f64, 15.0f64, 5.0f64, 11.0f64, 17.0f64, 7.0f64, 13.0f64, 19.0f64)); - let mut mut_a = matrix3::A; - mut_a.add_self_m(&matrix3::B); - assert_eq!(mut_a, matrix3::A.add_m(&matrix3::B)); - assert_eq!(mut_a, &matrix3::A + &matrix3::B); - // Matrix4 - assert_eq!(matrix4::A.add_m(&matrix4::B), + assert_eq!(matrix4::A + matrix4::B, Matrix4::new(3.0f64, 11.0f64, 19.0f64, 27.0f64, 5.0f64, 13.0f64, 21.0f64, 29.0f64, 7.0f64, 15.0f64, 23.0f64, 31.0f64, 9.0f64, 17.0f64, 25.0f64, 33.0f64)); - let mut mut_a = matrix4::A; - mut_a.add_self_m(&matrix4::B); - assert_eq!(mut_a, matrix4::A.add_m(&matrix4::B)); - assert_eq!(mut_a, &matrix4::A + &matrix4::B); } #[test] -fn test_sub_m() { - // Matrix2 - assert_eq!(matrix2::A.sub_m(&matrix2::B), +fn test_sub_matrix() { + assert_eq!(matrix2::A - matrix2::B, Matrix2::new(-1.0f64, -1.0f64, -1.0f64, -1.0f64)); - let mut mut_a = matrix2::A; - mut_a.sub_self_m(&matrix2::B); - assert_eq!(mut_a, matrix2::A.sub_m(&matrix2::B)); - assert_eq!(matrix2::A.sub_m(&matrix2::B), &matrix2::A - &matrix2::B); - // Matrix3 - assert_eq!(matrix3::A.sub_m(&matrix3::B), + assert_eq!(matrix3::A - matrix3::B, Matrix3::new(-1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64)); - let mut mut_a = matrix3::A; - mut_a.sub_self_m(&matrix3::B); - assert_eq!(mut_a, matrix3::A.sub_m(&matrix3::B)); - assert_eq!(matrix3::A.sub_m(&matrix3::B), &matrix3::A - &matrix3::B); - // Matrix4 - assert_eq!(matrix4::A.sub_m(&matrix4::B), + assert_eq!(matrix4::A - matrix4::B, Matrix4::new(-1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64, -1.0f64)); - let mut mut_a = matrix4::A; - mut_a.sub_self_m(&matrix4::B); - assert_eq!(mut_a, matrix4::A.sub_m(&matrix4::B)); - assert_eq!(matrix4::A.sub_m(&matrix4::B), &matrix4::A - &matrix4::B); } #[test] -fn test_mul_v() { - assert_eq!(matrix2::A.mul_v(matrix2::V), Vector2::new(5.0f64, 11.0f64)); - assert_eq!(matrix3::A.mul_v(matrix3::V), Vector3::new(14.0f64, 32.0f64, 50.0f64)); - assert_eq!(matrix4::A.mul_v(matrix4::V), Vector4::new(30.0f64, 70.0f64, 110.0f64, 150.0f64)); +fn test_mul_vector() { + assert_eq!(matrix2::A * matrix2::V, Vector2::new(5.0f64, 11.0f64)); + assert_eq!(matrix3::A * matrix3::V, Vector3::new(14.0f64, 32.0f64, 50.0f64)); + assert_eq!(matrix4::A * matrix4::V, Vector4::new(30.0f64, 70.0f64, 110.0f64, 150.0f64)); } #[test] -fn test_mul_m() { - assert_eq!(matrix2::A.mul_m(&matrix2::B), +fn test_mul_matrix() { + assert_eq!(matrix2::A * matrix2::B, Matrix2::new(10.0f64, 22.0f64, 13.0f64, 29.0f64)); - assert_eq!(matrix3::A.mul_m(&matrix3::B), + assert_eq!(matrix3::A * matrix3::B, Matrix3::new(36.0f64, 81.0f64, 126.0f64, 42.0f64, 96.0f64, 150.0f64, 48.0f64, 111.0f64, 174.0f64)); - assert_eq!(matrix4::A.mul_m(&matrix4::B), + assert_eq!(matrix4::A * matrix4::B, Matrix4::new(100.0f64, 228.0f64, 356.0f64, 484.0f64, 110.0f64, 254.0f64, 398.0f64, 542.0f64, 120.0f64, 280.0f64, 440.0f64, 600.0f64, 130.0f64, 306.0f64, 482.0f64, 658.0f64)); - assert_eq!(matrix2::A.mul_m(&matrix2::B), &matrix2::A * &matrix2::B); - assert_eq!(matrix3::A.mul_m(&matrix3::B), &matrix3::A * &matrix3::B); - assert_eq!(matrix4::A.mul_m(&matrix4::B), &matrix4::A * &matrix4::B); + assert_eq!(matrix2::A * matrix2::B, &matrix2::A * &matrix2::B); + assert_eq!(matrix3::A * matrix3::B, &matrix3::A * &matrix3::B); + assert_eq!(matrix4::A * matrix4::B, &matrix4::A * &matrix4::B); } #[test] @@ -292,11 +249,11 @@ fn test_invert() { // Matrix4 assert!(Matrix4::::identity().invert().unwrap().is_identity()); - assert!(matrix4::C.invert().unwrap().approx_eq(& + assert!(matrix4::C.invert().unwrap().approx_eq(&( Matrix4::new( 5.0f64, -4.0f64, 1.0f64, 0.0f64, -4.0f64, 8.0f64, -4.0f64, 0.0f64, 4.0f64, -8.0f64, 4.0f64, 8.0f64, - -3.0f64, 4.0f64, 1.0f64, -8.0f64).mul_s(0.125f64))); + -3.0f64, 4.0f64, 1.0f64, -8.0f64) * 0.125f64))); let mut mut_c = matrix4::C; mut_c.invert_self(); assert_eq!(mut_c, matrix4::C.invert().unwrap()); @@ -305,32 +262,32 @@ fn test_invert() { -0., 0.631364f64, 0.775487f64, 0.0f64, -0.991261f64, 0.1023f64, -0.083287f64, 0.0f64, 0., -1.262728f64, -1.550973f64, 1.0f64); - assert!(mat_c.invert().unwrap().mul_m(&mat_c).is_identity()); + assert!((mat_c.invert().unwrap() * mat_c).is_identity()); let mat_d = Matrix4::new( 0.065455f64, -0.720002f64, 0.690879f64, 0.0f64, -0., 0.692364f64, 0.721549f64, 0.0f64, -0.997856f64, -0.047229f64, 0.045318f64, 0.0f64, 0., -1.384727f64, -1.443098f64, 1.0f64); - assert!(mat_d.invert().unwrap().mul_m(&mat_d).is_identity()); + assert!((mat_d.invert().unwrap() * mat_d).is_identity()); let mat_e = Matrix4::new( 0.409936f64, 0.683812f64, -0.603617f64, 0.0f64, 0., 0.661778f64, 0.7497f64, 0.0f64, 0.912114f64, -0.307329f64, 0.271286f64, 0.0f64, -0., -1.323555f64, -1.499401f64, 1.0f64); - assert!(mat_e.invert().unwrap().mul_m(&mat_e).is_identity()); + assert!((mat_e.invert().unwrap() * mat_e).is_identity()); let mat_f = Matrix4::new(-0.160691f64, -0.772608f64, 0.614211f64, 0.0f64, -0., 0.622298f64, 0.78278f64, 0.0f64, -0.987005f64, 0.125786f64, -0.099998f64, 0.0f64, 0., -1.244597f64, -1.565561f64, 1.0f64); - assert!(mat_f.invert().unwrap().mul_m(&mat_f).is_identity()); + assert!((mat_f.invert().unwrap() * mat_f).is_identity()); } #[test] fn test_from_translation() { let mat = Matrix4::from_translation(Vector3::new(1.0f64, 2.0f64, 3.0f64)); let vertex = Vector4::new(0.0f64, 0.0f64, 0.0f64, 1.0f64); - let res = mat.mul_v(vertex); + let res = mat * vertex; assert_eq!(res, Vector4::new(1., 2., 3., 1.)); } @@ -398,13 +355,13 @@ fn test_predicates() { fn test_from_angle() { // Rotate the vector (1, 0) by π/2 radians to the vector (0, 1) let rot1 = Matrix2::from_angle(rad(0.5f64 * f64::consts::PI)); - assert!(rot1.mul_v(Vector2::unit_x()).approx_eq(&Vector2::unit_y())); + assert!((rot1 * Vector2::unit_x()).approx_eq(&Vector2::unit_y())); // Rotate the vector (-1, 0) by -π/2 radians to the vector (0, 1) let rot2 = -rot1; - assert!(rot2.mul_v(-Vector2::unit_x()).approx_eq(&Vector2::unit_y())); + assert!((rot2 * -Vector2::unit_x()).approx_eq(&Vector2::unit_y())); // Rotate the vector (1, 1) by π radians to the vector (-1, -1) let rot3: Matrix2 = Matrix2::from_angle(rad(f64::consts::PI)); - assert!(rot3.mul_v(Vector2::new(1.0, 1.0)).approx_eq(&Vector2::new(-1.0, -1.0))); + assert!((rot3 * Vector2::new(1.0, 1.0)).approx_eq(&Vector2::new(-1.0, -1.0))); } diff --git a/tests/projection.rs b/tests/projection.rs index 324e918..9a38c45 100644 --- a/tests/projection.rs +++ b/tests/projection.rs @@ -15,7 +15,7 @@ extern crate cgmath; -use cgmath::{Vector4, ortho, Matrix, Matrix4}; +use cgmath::{Vector4, ortho, Matrix4}; #[test] fn test_ortho_scale() { @@ -28,9 +28,9 @@ fn test_ortho_scale() { let vec_far: Vector4 = Vector4::new(1., 1., 1., 1.); let o: Matrix4 = ortho(-1., 1., -1., 1., -1., 1.); - let near = o.mul_v(vec_near); - let orig = o.mul_v(vec_orig); - let far = o.mul_v(vec_far); + let near = o * vec_near; + let orig = o * vec_orig; + let far = o * vec_far; assert_eq!(near, Vector4::new(-1f32, -1., 1., 1.)); assert_eq!(orig, Vector4::new(0f32, 0., 0., 1.)); @@ -38,9 +38,9 @@ fn test_ortho_scale() { let o: Matrix4 = ortho(-2., 2., -2., 2., -2., 2.); - let near = o.mul_v(vec_near); - let orig = o.mul_v(vec_orig); - let far = o.mul_v(vec_far); + let near = o * vec_near; + let orig = o * vec_orig; + let far = o * vec_far; assert_eq!(near, Vector4::new(-0.5f32, -0.5, 0.5, 1.)); assert_eq!(orig, Vector4::new(0f32, 0., 0., 1.)); @@ -56,14 +56,14 @@ fn test_ortho_translate() { let vec_orig: Vector4 = Vector4::new(0., 0., 0., 1.); let o: Matrix4 = ortho(-1., 1., -1., 1., -1., 1.); - let orig = o.mul_v(vec_orig); + let orig = o * vec_orig; assert_eq!(orig, Vector4::new(0., 0., 0., 1.)); let o: Matrix4 = ortho(0., 2., 0., 2., 0., 2.); - let orig = o.mul_v(vec_orig); + let orig = o * vec_orig; assert_eq!(orig, Vector4::new(-1., -1., -1., 1.)); let o: Matrix4 = ortho(-2., 0., -2., 0., -2., 0.); - let orig = o.mul_v(vec_orig); + let orig = o * vec_orig; assert_eq!(orig, Vector4::new(1., 1., 1., 1.)); }