Repository: bitshifter/glam-rs
Pull request #258 (2021-11-23 02:55:48)

Add Neg for matrix types


Patch:
diff --git a/src/core/sse2/matrix.rs b/src/core/sse2/matrix.rs
index bf75c33..a703374 100644
--- a/src/core/sse2/matrix.rs
+++ b/src/core/sse2/matrix.rs
@@ -132,6 +132,11 @@ impl FloatMatrix2x2<f32, XY<f32>> for __m128 {
             _mm_mul_ps(dbca, tmp)
         }
     }
+
+    #[inline]
+    fn neg_matrix(&self) -> Self {
+        unsafe { _mm_xor_ps(*self, _mm_set1_ps(-0.0)) }
+    }
 }
 
 impl MatrixConst for Columns3<__m128> {
diff --git a/src/core/traits/matrix.rs b/src/core/traits/matrix.rs
index aee7193..b251c8c 100644
--- a/src/core/traits/matrix.rs
+++ b/src/core/traits/matrix.rs
@@ -143,6 +143,11 @@ pub trait FloatMatrix2x2<T: FloatEx, V2: FloatVector2<T>>: Matrix2x2<T, V2> {
             && self.y_axis().abs_diff_eq(*other.y_axis(), max_abs_diff)
     }
 
+    #[inline]
+    fn neg_matrix(&self) -> Self {
+        Self::from_cols(self.x_axis().neg(), self.y_axis().neg())
+    }
+
     #[inline]
     fn from_scale_angle(scale: V2, angle: T) -> Self {
         let (sin, cos) = angle.sin_cos();
@@ -345,6 +350,15 @@ pub trait FloatMatrix3x3<T: FloatEx, V3: FloatVector3<T>>: Matrix3x3<T, V3> {
             && self.z_axis().abs_diff_eq(*other.z_axis(), max_abs_diff)
     }
 
+    #[inline]
+    fn neg_matrix(&self) -> Self {
+        Self::from_cols(
+            self.x_axis().neg(),
+            self.y_axis().neg(),
+            self.z_axis().neg(),
+        )
+    }
+
     #[inline]
     fn from_angle(angle: T) -> Self {
         let (sin, cos) = angle.sin_cos();
@@ -693,6 +707,16 @@ pub trait FloatMatrix4x4<T: FloatEx, V4: FloatVector4<T> + Quaternion<T>>:
             && self.w_axis().abs_diff_eq(*other.w_axis(), max_abs_diff)
     }
 
+    #[inline]
+    fn neg_matrix(&self) -> Self {
+        Self::from_cols(
+            self.x_axis().neg(),
+            self.y_axis().neg(),
+            self.z_axis().neg(),
+            self.w_axis().neg(),
+        )
+    }
+
     #[inline]
     fn quaternion_to_axes(rotation: V4) -> (V4, V4, V4) {
         glam_assert!(rotation.is_normalized());
diff --git a/src/core/wasm32/matrix.rs b/src/core/wasm32/matrix.rs
index ea206a8..eca5602 100644
--- a/src/core/wasm32/matrix.rs
+++ b/src/core/wasm32/matrix.rs
@@ -108,6 +108,11 @@ impl FloatMatrix2x2<f32, XY<f32>> for v128 {
         FloatVector4::abs_diff_eq(*self, *other, max_abs_diff)
     }
 
+    #[inline]
+    fn neg_matrix(&self) -> Self {
+        f32x4_neg(*self)
+    }
+
     #[inline]
     fn inverse(&self) -> Self {
         const SIGN: v128 = const_f32x4!([1.0, -1.0, -1.0, 1.0]);
diff --git a/src/mat.rs b/src/mat.rs
index b19e901..b97e8ed 100644
--- a/src/mat.rs
+++ b/src/mat.rs
@@ -39,6 +39,14 @@ macro_rules! impl_matn_common_traits {
             }
         }
 
+        impl Neg for $matn {
+            type Output = Self;
+            #[inline(always)]
+            fn neg(self) -> Self::Output {
+                Self(self.0.neg_matrix())
+            }
+        }
+
         impl Mul<$matn> for $matn {
             type Output = Self;
             #[inline(always)]
diff --git a/src/mat2.rs b/src/mat2.rs
index 9d757c7..ddc843a 100644
--- a/src/mat2.rs
+++ b/src/mat2.rs
@@ -6,7 +6,7 @@ use crate::{DMat3, DVec2, Mat3, Vec2};
 #[cfg(not(target_arch = "spirv"))]
 use core::fmt;
 use core::iter::{Product, Sum};
-use core::ops::{Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Sub, SubAssign};
+use core::ops::{Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Neg, Sub, SubAssign};
 
 #[cfg(all(
     target_arch = "x86",
diff --git a/src/mat3.rs b/src/mat3.rs
index ec5a6ae..3b1a360 100644
--- a/src/mat3.rs
+++ b/src/mat3.rs
@@ -6,7 +6,7 @@ use crate::{DMat2, DMat4, DQuat, DVec2, DVec3, EulerRot, Mat2, Mat4, Quat, Vec2,
 #[cfg(not(target_arch = "spirv"))]
 use core::fmt;
 use core::iter::{Product, Sum};
-use core::ops::{Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Sub, SubAssign};
+use core::ops::{Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Neg, Sub, SubAssign};
 
 #[cfg(all(
     target_arch = "x86",
diff --git a/src/mat4.rs b/src/mat4.rs
index bfb5634..3a37b8c 100644
--- a/src/mat4.rs
+++ b/src/mat4.rs
@@ -26,7 +26,7 @@ use core::arch::wasm32::v128;
 #[cfg(not(target_arch = "spirv"))]
 use core::fmt;
 use core::iter::{Product, Sum};
-use core::ops::{Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Sub, SubAssign};
+use core::ops::{Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Neg, Sub, SubAssign};
 
 //macro_rules! define_mat4_struct {
 //    ($mat4:ident, $inner:ident) => {


Test patch:
diff --git a/tests/mat2.rs b/tests/mat2.rs
index 9267a0e..860f25a 100644
--- a/tests/mat2.rs
+++ b/tests/mat2.rs
@@ -154,10 +154,12 @@ macro_rules! impl_mat2_tests {
         glam_test!(test_mat2_ops, {
             let m0 = $mat2::from_cols_array_2d(&MATRIX);
             let m0x2 = $mat2::from_cols_array_2d(&[[2.0, 4.0], [6.0, 8.0]]);
+            let m0_neg = $mat2::from_cols_array_2d(&[[-1.0, -2.0], [-3.0, -4.0]]);
             assert_eq!(m0x2, m0 * 2.0);
             assert_eq!(m0x2, 2.0 * m0);
             assert_eq!(m0x2, m0 + m0);
             assert_eq!($mat2::ZERO, m0 - m0);
+            assert_eq!(m0_neg, -m0);
             assert_approx_eq!(m0, m0 * $mat2::IDENTITY);
             assert_approx_eq!(m0, $mat2::IDENTITY * m0);
 
diff --git a/tests/mat3.rs b/tests/mat3.rs
index 1a2c497..0f015df 100644
--- a/tests/mat3.rs
+++ b/tests/mat3.rs
@@ -291,10 +291,16 @@ macro_rules! impl_mat3_tests {
                 [8.0, 10.0, 12.0],
                 [14.0, 16.0, 18.0],
             ]);
+            let m0_neg = $mat3::from_cols_array_2d(&[
+                [-1.0, -2.0, -3.0],
+                [-4.0, -5.0, -6.0],
+                [-7.0, -8.0, -9.0],
+            ]);
             assert_eq!(m0x2, m0 * 2.0);
             assert_eq!(m0x2, 2.0 * m0);
             assert_eq!(m0x2, m0 + m0);
             assert_eq!($mat3::ZERO, m0 - m0);
+            assert_eq!(m0_neg, -m0);
             assert_approx_eq!(m0, m0 * $mat3::IDENTITY);
             assert_approx_eq!(m0, $mat3::IDENTITY * m0);
 
diff --git a/tests/mat4.rs b/tests/mat4.rs
index 27bb52d..b20546e 100644
--- a/tests/mat4.rs
+++ b/tests/mat4.rs
@@ -590,10 +590,17 @@ macro_rules! impl_mat4_tests {
                 [18.0, 20.0, 22.0, 24.0],
                 [26.0, 28.0, 30.0, 32.0],
             ]);
+            let m0_neg = $mat4::from_cols_array_2d(&[
+                [-1.0, -2.0, -3.0, -4.0],
+                [-5.0, -6.0, -7.0, -8.0],
+                [-9.0, -10.0, -11.0, -12.0],
+                [-13.0, -14.0, -15.0, -16.0],
+            ]);
             assert_eq!(m0x2, m0 * 2.0);
             assert_eq!(m0x2, 2.0 * m0);
             assert_eq!(m0x2, m0 + m0);
             assert_eq!($mat4::ZERO, m0 - m0);
+            assert_eq!(m0_neg, -m0);
             assert_approx_eq!(m0, m0 * $mat4::IDENTITY);
             assert_approx_eq!(m0, $mat4::IDENTITY * m0);