Repository: bitshifter/glam-rs (rust)

Issue:
Wrong determinant calculation for `Mat4`
This test case fails:

```rust
#[test]
fn test_determinant() {
    use glam::{Mat4, Vec4};
    let matrix = Mat4::from_cols(
        Vec4::new(0.0, 0.0, 0.0, 1.0),
        Vec4::new(1.0, 0.0, 0.0, 0.0),
        Vec4::new(0.0, 0.0, 1.0, 0.0),
        Vec4::new(0.0, 1.0, 0.0, 0.0),
    );
    assert_eq!(matrix.determinant(), 1.0);
}
```

The result of the determinant calculation in glam is `0.0`, while it should be `1.0`.

Pull request:
Fix bad Matrix4x4 determinant in sse&wasm implementations
This fixes #279.

There is a bug in the determinant calculation using SSE.

The code from glm was not translated correctly.

Patch:
diff --git a/src/core/sse2/matrix.rs b/src/core/sse2/matrix.rs
index a703374..5850928 100644
--- a/src/core/sse2/matrix.rs
+++ b/src/core/sse2/matrix.rs
@@ -279,11 +279,18 @@ impl Matrix4x4<f32, __m128> for Columns4<__m128> {
     #[inline]
     fn determinant(&self) -> f32 {
         unsafe {
-            // Based on https://github.com/g-truc/glm `glm_mat4_determinant`
+            // SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+            // SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+            // SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+            // SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+            // SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+            // SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+
+            // Based on https://github.com/g-truc/glm `glm_mat4_determinant_lowp`
             let swp2a = _mm_shuffle_ps(self.z_axis, self.z_axis, 0b00_01_01_10);
             let swp3a = _mm_shuffle_ps(self.w_axis, self.w_axis, 0b11_10_11_11);
             let swp2b = _mm_shuffle_ps(self.z_axis, self.z_axis, 0b11_10_11_11);
-            let swp3b = _mm_shuffle_ps(self.w_axis, self.w_axis, 0b00_10_01_10);
+            let swp3b = _mm_shuffle_ps(self.w_axis, self.w_axis, 0b00_01_01_10);
             let swp2c = _mm_shuffle_ps(self.z_axis, self.z_axis, 0b00_00_01_10);
             let swp3c = _mm_shuffle_ps(self.w_axis, self.w_axis, 0b01_10_00_00);
 
diff --git a/src/core/wasm32/matrix.rs b/src/core/wasm32/matrix.rs
index 1797a1d..d2a280a 100644
--- a/src/core/wasm32/matrix.rs
+++ b/src/core/wasm32/matrix.rs
@@ -269,7 +269,7 @@ impl Matrix4x4<f32, v128> for Columns4<v128> {
         let swp2a = i32x4_shuffle::<2, 1, 1, 0>(self.z_axis, self.z_axis);
         let swp3a = i32x4_shuffle::<3, 3, 2, 3>(self.w_axis, self.w_axis);
         let swp2b = i32x4_shuffle::<3, 3, 2, 3>(self.z_axis, self.z_axis);
-        let swp3b = i32x4_shuffle::<2, 1, 2, 0>(self.w_axis, self.w_axis);
+        let swp3b = i32x4_shuffle::<2, 1, 1, 0>(self.w_axis, self.w_axis);
         let swp2c = i32x4_shuffle::<2, 1, 0, 0>(self.z_axis, self.z_axis);
         let swp3c = i32x4_shuffle::<0, 0, 2, 1>(self.w_axis, self.w_axis);
 


Test patch:
diff --git a/tests/mat4.rs b/tests/mat4.rs
index b20546e..85d670d 100644
--- a/tests/mat4.rs
+++ b/tests/mat4.rs
@@ -300,6 +300,16 @@ macro_rules! impl_mat4_tests {
                 2.0 * 2.0 * 2.0,
                 $mat4::from_scale($newvec3(2.0, 2.0, 2.0)).determinant()
             );
+            assert_eq!(
+                1.0,
+                $newmat4(
+                    $newvec4(0.0, 0.0, 0.0, 1.0),
+                    $newvec4(1.0, 0.0, 0.0, 0.0),
+                    $newvec4(0.0, 0.0, 1.0, 0.0),
+                    $newvec4(0.0, 1.0, 0.0, 0.0),
+                )
+                .determinant()
+            );
         });
 
         glam_test!(test_mat4_inverse, {