diff --git a/codegen/templates/macros.rs.tera b/codegen/templates/macros.rs.tera index a6de0473..475ec788 100644 --- a/codegen/templates/macros.rs.tera +++ b/codegen/templates/macros.rs.tera @@ -5,3 +5,69 @@ {%- endfor -%} ) {% endmacro make_tuple_t %} + +{% macro impl_mat3_minor(mat3_t, align="") %} + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3{{ align }}_minor(m: {{ mat3_t }}, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } +{% endmacro impl_mat3_minor %} + +{% macro impl_mat4_minor(mat4_t, vec3_t) %} + {% if vec3_t == "Vec3A" %} + {% set w = "w" %} + {% set b = "Vec3A::from_vec4(" %} + {% set e = ")" %} + {% else %} + {% set w = "" %} + {% set b = "" %} + {% set e = "" %} + {% endif %} + /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 3. + #[inline] + #[must_use] + pub fn from_mat4_minor(m: {{ mat4_t }}, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols({{ b }}m.y_axis.yzw{{ w }}(){{ e }}, {{ b }}m.z_axis.yzw{{ w }}(){{ e }}, {{ b }}m.w_axis.yzw{{ w }}(){{ e }}), + (0, 1) => Self::from_cols({{ b }}m.y_axis.xzw{{ w }}(){{ e }}, {{ b }}m.z_axis.xzw{{ w }}(){{ e }}, {{ b }}m.w_axis.xzw{{ w }}(){{ e }}), + (0, 2) => Self::from_cols({{ b }}m.y_axis.xyw{{ w }}(){{ e }}, {{ b }}m.z_axis.xyw{{ w }}(){{ e }}, {{ b }}m.w_axis.xyw{{ w }}(){{ e }}), + (0, 3) => Self::from_cols({{ b }}m.y_axis.xyz{{ w }}(){{ e }}, {{ b }}m.z_axis.xyz{{ w }}(){{ e }}, {{ b }}m.w_axis.xyz{{ w }}(){{ e }}), + (1, 0) => Self::from_cols({{ b }}m.x_axis.yzw{{ w }}(){{ e }}, {{ b }}m.z_axis.yzw{{ w }}(){{ e }}, {{ b }}m.w_axis.yzw{{ w }}(){{ e }}), + (1, 1) => Self::from_cols({{ b }}m.x_axis.xzw{{ w }}(){{ e }}, {{ b }}m.z_axis.xzw{{ w }}(){{ e }}, {{ b }}m.w_axis.xzw{{ w }}(){{ e }}), + (1, 2) => Self::from_cols({{ b }}m.x_axis.xyw{{ w }}(){{ e }}, {{ b }}m.z_axis.xyw{{ w }}(){{ e }}, {{ b }}m.w_axis.xyw{{ w }}(){{ e }}), + (1, 3) => Self::from_cols({{ b }}m.x_axis.xyz{{ w }}(){{ e }}, {{ b }}m.z_axis.xyz{{ w }}(){{ e }}, {{ b }}m.w_axis.xyz{{ w }}(){{ e }}), + (2, 0) => Self::from_cols({{ b }}m.x_axis.yzw{{ w }}(){{ e }}, {{ b }}m.y_axis.yzw{{ w }}(){{ e }}, {{ b }}m.w_axis.yzw{{ w }}(){{ e }}), + (2, 1) => Self::from_cols({{ b }}m.x_axis.xzw{{ w }}(){{ e }}, {{ b }}m.y_axis.xzw{{ w }}(){{ e }}, {{ b }}m.w_axis.xzw{{ w }}(){{ e }}), + (2, 2) => Self::from_cols({{ b }}m.x_axis.xyw{{ w }}(){{ e }}, {{ b }}m.y_axis.xyw{{ w }}(){{ e }}, {{ b }}m.w_axis.xyw{{ w }}(){{ e }}), + (2, 3) => Self::from_cols({{ b }}m.x_axis.xyz{{ w }}(){{ e }}, {{ b }}m.y_axis.xyz{{ w }}(){{ e }}, {{ b }}m.w_axis.xyz{{ w }}(){{ e }}), + (3, 0) => Self::from_cols({{ b }}m.x_axis.yzw{{ w }}(){{ e }}, {{ b }}m.y_axis.yzw{{ w }}(){{ e }}, {{ b }}m.z_axis.yzw{{ w }}(){{ e }}), + (3, 1) => Self::from_cols({{ b }}m.x_axis.xzw{{ w }}(){{ e }}, {{ b }}m.y_axis.xzw{{ w }}(){{ e }}, {{ b }}m.z_axis.xzw{{ w }}(){{ e }}), + (3, 2) => Self::from_cols({{ b }}m.x_axis.xyw{{ w }}(){{ e }}, {{ b }}m.y_axis.xyw{{ w }}(){{ e }}, {{ b }}m.z_axis.xyw{{ w }}(){{ e }}), + (3, 3) => Self::from_cols({{ b }}m.x_axis.xyz{{ w }}(){{ e }}, {{ b }}m.y_axis.xyz{{ w }}(){{ e }}, {{ b }}m.z_axis.xyz{{ w }}(){{ e }}), + _ => panic!("index out of bounds"), + } + } +{% endmacro impl_mat4_minor %} diff --git a/codegen/templates/mat.rs.tera b/codegen/templates/mat.rs.tera index 67b07004..fdb0f6e1 100644 --- a/codegen/templates/mat.rs.tera +++ b/codegen/templates/mat.rs.tera @@ -1,3 +1,4 @@ +{% import "macros.rs.tera" as macros %} {% import "coresimd.rs.tera" as coresimd %} {% import "neon.rs.tera" as neon %} {% import "sse2.rs.tera" as sse2 %} @@ -437,6 +438,8 @@ impl {{ self_t }} { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + {{ macros::impl_mat3_minor(mat3_t=mat3_t) }} + {% if scalar_t == "f32" %} /// Creates a {{ nxn }} matrix from a 3x3 matrix, discarding the 2nd row and column. #[inline] @@ -445,6 +448,8 @@ impl {{ self_t }} { {# TODO: SIMD optimise #} Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + + {{ macros::impl_mat3_minor(mat3_t="Mat3A", align="a") }} {% endif %} {% elif dim == 3 %} @@ -459,6 +464,8 @@ impl {{ self_t }} { ) } + {{ macros::impl_mat4_minor(mat4_t=mat4_t, vec3_t=col_t) }} + /// Creates a 3D rotation matrix from the given quaternion. /// /// # Panics diff --git a/codegen/templates/swizzle_impl.rs.tera b/codegen/templates/swizzle_impl.rs.tera index c982a385..2da0c10e 100644 --- a/codegen/templates/swizzle_impl.rs.tera +++ b/codegen/templates/swizzle_impl.rs.tera @@ -53,7 +53,7 @@ impl Vec{{ dim }}Swizzles for {{ self_t }} { {% for j0 in indices | slice(end=dim) %} {% for j1 in indices | slice(end=dim) %} {% if i == 2 %} - {% set skip = dim == 2 and j0 == "x" and j1 == "y" %} + {% set skip = dim == 2 and j0 == 0 and j1 == 1 %} {% if not skip %} #[inline] #[must_use] @@ -64,7 +64,7 @@ impl Vec{{ dim }}Swizzles for {{ self_t }} { {% else %} {% for j2 in indices | slice(end=dim) %} {% if i == 3 %} - {% set skip = dim == 3 and j0 == "x" and j1 == "y" and j2 == "z" %} + {% set skip = dim == 3 and j0 == 0 and j1 == 1 and j2 == 2 %} {% if not skip %} #[inline] #[must_use] @@ -82,7 +82,7 @@ impl Vec{{ dim }}Swizzles for {{ self_t }} { {% endif %} {% else %} {% for j3 in indices | slice(end=dim) %} - {% set skip = dim == 4 and j0 == "x" and j1 == "y" and j2 == "z" and j3 == "w" %} + {% set skip = dim == 4 and j0 == 0 and j1 == 1 and j2 == 2 and j3 == 3 %} {% if not skip %} #[inline] #[must_use] diff --git a/src/f32/coresimd/mat2.rs b/src/f32/coresimd/mat2.rs index ce2ccd23..ffcb3ea4 100644 --- a/src/f32/coresimd/mat2.rs +++ b/src/f32/coresimd/mat2.rs @@ -114,6 +114,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. #[inline] #[must_use] @@ -121,6 +144,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from the first 4 values in `slice`. /// /// # Panics diff --git a/src/f32/coresimd/mat3a.rs b/src/f32/coresimd/mat3a.rs index 841b35ef..6e6b29ea 100644 --- a/src/f32/coresimd/mat3a.rs +++ b/src/f32/coresimd/mat3a.rs @@ -164,6 +164,100 @@ impl Mat3A { ) } + /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 3. + #[inline] + #[must_use] + pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (0, 1) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (0, 2) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (0, 3) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (1, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (1, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (1, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (1, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (2, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (2, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (2, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (2, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (3, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + ), + (3, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + ), + (3, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + ), + (3, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + ), + _ => panic!("index out of bounds"), + } + } + /// Creates a 3D rotation matrix from the given quaternion. /// /// # Panics diff --git a/src/f32/mat3.rs b/src/f32/mat3.rs index 3205d027..ba22c329 100644 --- a/src/f32/mat3.rs +++ b/src/f32/mat3.rs @@ -165,6 +165,36 @@ impl Mat3 { ) } + /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 3. + #[inline] + #[must_use] + pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()), + (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()), + (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()), + (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()), + (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()), + (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()), + (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()), + (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()), + (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()), + (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()), + (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()), + (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()), + (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()), + (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()), + (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()), + (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 3D rotation matrix from the given quaternion. /// /// # Panics diff --git a/src/f32/neon/mat2.rs b/src/f32/neon/mat2.rs index f0b27cb2..e1b0d803 100644 --- a/src/f32/neon/mat2.rs +++ b/src/f32/neon/mat2.rs @@ -130,6 +130,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. #[inline] #[must_use] @@ -137,6 +160,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from the first 4 values in `slice`. /// /// # Panics diff --git a/src/f32/neon/mat3a.rs b/src/f32/neon/mat3a.rs index 9423ffb6..3e2448db 100644 --- a/src/f32/neon/mat3a.rs +++ b/src/f32/neon/mat3a.rs @@ -164,6 +164,100 @@ impl Mat3A { ) } + /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 3. + #[inline] + #[must_use] + pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (0, 1) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (0, 2) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (0, 3) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (1, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (1, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (1, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (1, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (2, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (2, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (2, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (2, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (3, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + ), + (3, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + ), + (3, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + ), + (3, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + ), + _ => panic!("index out of bounds"), + } + } + /// Creates a 3D rotation matrix from the given quaternion. /// /// # Panics diff --git a/src/f32/scalar/mat2.rs b/src/f32/scalar/mat2.rs index 262c13de..3f6dfdc6 100644 --- a/src/f32/scalar/mat2.rs +++ b/src/f32/scalar/mat2.rs @@ -119,6 +119,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. #[inline] #[must_use] @@ -126,6 +149,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from the first 4 values in `slice`. /// /// # Panics diff --git a/src/f32/scalar/mat3a.rs b/src/f32/scalar/mat3a.rs index 0a1e2555..7bcb7679 100644 --- a/src/f32/scalar/mat3a.rs +++ b/src/f32/scalar/mat3a.rs @@ -165,6 +165,100 @@ impl Mat3A { ) } + /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 3. + #[inline] + #[must_use] + pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (0, 1) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (0, 2) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (0, 3) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (1, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (1, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (1, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (1, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (2, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (2, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (2, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (2, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (3, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + ), + (3, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + ), + (3, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + ), + (3, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + ), + _ => panic!("index out of bounds"), + } + } + /// Creates a 3D rotation matrix from the given quaternion. /// /// # Panics diff --git a/src/f32/sse2/mat2.rs b/src/f32/sse2/mat2.rs index dda21578..8821006d 100644 --- a/src/f32/sse2/mat2.rs +++ b/src/f32/sse2/mat2.rs @@ -133,6 +133,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. #[inline] #[must_use] @@ -140,6 +163,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from the first 4 values in `slice`. /// /// # Panics diff --git a/src/f32/sse2/mat3a.rs b/src/f32/sse2/mat3a.rs index 8d235c5f..c6e6ad2f 100644 --- a/src/f32/sse2/mat3a.rs +++ b/src/f32/sse2/mat3a.rs @@ -167,6 +167,100 @@ impl Mat3A { ) } + /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 3. + #[inline] + #[must_use] + pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (0, 1) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (0, 2) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (0, 3) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (1, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (1, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (1, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (1, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (2, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (2, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (2, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (2, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (3, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + ), + (3, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + ), + (3, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + ), + (3, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + ), + _ => panic!("index out of bounds"), + } + } + /// Creates a 3D rotation matrix from the given quaternion. /// /// # Panics diff --git a/src/f32/wasm32/mat2.rs b/src/f32/wasm32/mat2.rs index fc2d0a69..59bd5e7a 100644 --- a/src/f32/wasm32/mat2.rs +++ b/src/f32/wasm32/mat2.rs @@ -114,6 +114,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column. #[inline] #[must_use] @@ -121,6 +144,29 @@ impl Mat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from the first 4 values in `slice`. /// /// # Panics diff --git a/src/f32/wasm32/mat3a.rs b/src/f32/wasm32/mat3a.rs index 4e35b9bc..bbaffd62 100644 --- a/src/f32/wasm32/mat3a.rs +++ b/src/f32/wasm32/mat3a.rs @@ -164,6 +164,100 @@ impl Mat3A { ) } + /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 3. + #[inline] + #[must_use] + pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (0, 1) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (0, 2) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (0, 3) => Self::from_cols( + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (1, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (1, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (1, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (1, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (2, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.w_axis.yzww()), + ), + (2, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.w_axis.xzww()), + ), + (2, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.w_axis.xyww()), + ), + (2, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.w_axis.xyzw()), + ), + (3, 0) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.yzww()), + Vec3A::from_vec4(m.y_axis.yzww()), + Vec3A::from_vec4(m.z_axis.yzww()), + ), + (3, 1) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xzww()), + Vec3A::from_vec4(m.y_axis.xzww()), + Vec3A::from_vec4(m.z_axis.xzww()), + ), + (3, 2) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyww()), + Vec3A::from_vec4(m.y_axis.xyww()), + Vec3A::from_vec4(m.z_axis.xyww()), + ), + (3, 3) => Self::from_cols( + Vec3A::from_vec4(m.x_axis.xyzw()), + Vec3A::from_vec4(m.y_axis.xyzw()), + Vec3A::from_vec4(m.z_axis.xyzw()), + ), + _ => panic!("index out of bounds"), + } + } + /// Creates a 3D rotation matrix from the given quaternion. /// /// # Panics diff --git a/src/f64/dmat2.rs b/src/f64/dmat2.rs index b1e975d9..5798c513 100644 --- a/src/f64/dmat2.rs +++ b/src/f64/dmat2.rs @@ -115,6 +115,29 @@ impl DMat2 { Self::from_cols(m.x_axis.xy(), m.y_axis.xy()) } + /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 2. + #[inline] + #[must_use] + pub fn from_mat3_minor(m: DMat3, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()), + (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()), + (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()), + (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()), + (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()), + (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()), + (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()), + (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()), + (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 2x2 matrix from the first 4 values in `slice`. /// /// # Panics diff --git a/src/f64/dmat3.rs b/src/f64/dmat3.rs index 687d176a..4f84b1a5 100644 --- a/src/f64/dmat3.rs +++ b/src/f64/dmat3.rs @@ -165,6 +165,36 @@ impl DMat3 { ) } + /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column + /// and `j`th row. + /// + /// # Panics + /// + /// Panics if `i` or `j` is greater than 3. + #[inline] + #[must_use] + pub fn from_mat4_minor(m: DMat4, i: usize, j: usize) -> Self { + match (i, j) { + (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()), + (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()), + (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()), + (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()), + (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()), + (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()), + (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()), + (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()), + (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()), + (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()), + (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()), + (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()), + (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()), + (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()), + (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()), + (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()), + _ => panic!("index out of bounds"), + } + } + /// Creates a 3D rotation matrix from the given quaternion. /// /// # Panics diff --git a/src/swizzles/coresimd/vec3a_impl.rs b/src/swizzles/coresimd/vec3a_impl.rs index 36cb9aec..c9cc4206 100644 --- a/src/swizzles/coresimd/vec3a_impl.rs +++ b/src/swizzles/coresimd/vec3a_impl.rs @@ -122,12 +122,6 @@ impl Vec3Swizzles for Vec3A { Vec3A(simd_swizzle!(self.0, [0, 1, 1, 0]).into()) } - #[inline] - #[must_use] - fn xyz(self) -> Vec3A { - Vec3A(simd_swizzle!(self.0, [0, 1, 2, 0]).into()) - } - #[inline] #[must_use] fn xzx(self) -> Vec3A { diff --git a/src/swizzles/coresimd/vec4_impl.rs b/src/swizzles/coresimd/vec4_impl.rs index a546c893..57cd39ce 100644 --- a/src/swizzles/coresimd/vec4_impl.rs +++ b/src/swizzles/coresimd/vec4_impl.rs @@ -701,12 +701,6 @@ impl Vec4Swizzles for Vec4 { Vec4(simd_swizzle!(self.0, [0, 1, 2, 2])) } - #[inline] - #[must_use] - fn xyzw(self) -> Vec4 { - Vec4(simd_swizzle!(self.0, [0, 1, 2, 3])) - } - #[inline] #[must_use] fn xywx(self) -> Vec4 { diff --git a/src/swizzles/dvec2_impl.rs b/src/swizzles/dvec2_impl.rs index 9cd33e28..14bbc4ad 100644 --- a/src/swizzles/dvec2_impl.rs +++ b/src/swizzles/dvec2_impl.rs @@ -16,15 +16,6 @@ impl Vec2Swizzles for DVec2 { } } - #[inline] - #[must_use] - fn xy(self) -> DVec2 { - DVec2 { - x: self.x, - y: self.y, - } - } - #[inline] #[must_use] fn yx(self) -> DVec2 { diff --git a/src/swizzles/dvec3_impl.rs b/src/swizzles/dvec3_impl.rs index c8a1d811..97751a8f 100644 --- a/src/swizzles/dvec3_impl.rs +++ b/src/swizzles/dvec3_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for DVec3 { DVec3::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> DVec3 { - DVec3::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> DVec3 { diff --git a/src/swizzles/dvec4_impl.rs b/src/swizzles/dvec4_impl.rs index b5d95611..95406f0d 100644 --- a/src/swizzles/dvec4_impl.rs +++ b/src/swizzles/dvec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for DVec4 { DVec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> DVec4 { - DVec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> DVec4 { diff --git a/src/swizzles/i16vec2_impl.rs b/src/swizzles/i16vec2_impl.rs index 0bb0157e..ac1b7ce2 100644 --- a/src/swizzles/i16vec2_impl.rs +++ b/src/swizzles/i16vec2_impl.rs @@ -16,15 +16,6 @@ impl Vec2Swizzles for I16Vec2 { } } - #[inline] - #[must_use] - fn xy(self) -> I16Vec2 { - I16Vec2 { - x: self.x, - y: self.y, - } - } - #[inline] #[must_use] fn yx(self) -> I16Vec2 { diff --git a/src/swizzles/i16vec3_impl.rs b/src/swizzles/i16vec3_impl.rs index cf5752a4..8435637a 100644 --- a/src/swizzles/i16vec3_impl.rs +++ b/src/swizzles/i16vec3_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for I16Vec3 { I16Vec3::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> I16Vec3 { - I16Vec3::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> I16Vec3 { diff --git a/src/swizzles/i16vec4_impl.rs b/src/swizzles/i16vec4_impl.rs index 22b744c4..8687c94a 100644 --- a/src/swizzles/i16vec4_impl.rs +++ b/src/swizzles/i16vec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for I16Vec4 { I16Vec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> I16Vec4 { - I16Vec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> I16Vec4 { diff --git a/src/swizzles/i64vec2_impl.rs b/src/swizzles/i64vec2_impl.rs index 42cd9fc5..12f38222 100644 --- a/src/swizzles/i64vec2_impl.rs +++ b/src/swizzles/i64vec2_impl.rs @@ -16,15 +16,6 @@ impl Vec2Swizzles for I64Vec2 { } } - #[inline] - #[must_use] - fn xy(self) -> I64Vec2 { - I64Vec2 { - x: self.x, - y: self.y, - } - } - #[inline] #[must_use] fn yx(self) -> I64Vec2 { diff --git a/src/swizzles/i64vec3_impl.rs b/src/swizzles/i64vec3_impl.rs index ebed87cf..c4cbc3ba 100644 --- a/src/swizzles/i64vec3_impl.rs +++ b/src/swizzles/i64vec3_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for I64Vec3 { I64Vec3::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> I64Vec3 { - I64Vec3::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> I64Vec3 { diff --git a/src/swizzles/i64vec4_impl.rs b/src/swizzles/i64vec4_impl.rs index b936afae..a2f6141d 100644 --- a/src/swizzles/i64vec4_impl.rs +++ b/src/swizzles/i64vec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for I64Vec4 { I64Vec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> I64Vec4 { - I64Vec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> I64Vec4 { diff --git a/src/swizzles/ivec2_impl.rs b/src/swizzles/ivec2_impl.rs index 849c61c4..17645644 100644 --- a/src/swizzles/ivec2_impl.rs +++ b/src/swizzles/ivec2_impl.rs @@ -16,15 +16,6 @@ impl Vec2Swizzles for IVec2 { } } - #[inline] - #[must_use] - fn xy(self) -> IVec2 { - IVec2 { - x: self.x, - y: self.y, - } - } - #[inline] #[must_use] fn yx(self) -> IVec2 { diff --git a/src/swizzles/ivec3_impl.rs b/src/swizzles/ivec3_impl.rs index 47cf4906..707a44ea 100644 --- a/src/swizzles/ivec3_impl.rs +++ b/src/swizzles/ivec3_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for IVec3 { IVec3::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> IVec3 { - IVec3::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> IVec3 { diff --git a/src/swizzles/ivec4_impl.rs b/src/swizzles/ivec4_impl.rs index 34635a57..523a3021 100644 --- a/src/swizzles/ivec4_impl.rs +++ b/src/swizzles/ivec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for IVec4 { IVec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> IVec4 { - IVec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> IVec4 { diff --git a/src/swizzles/neon/vec3a_impl.rs b/src/swizzles/neon/vec3a_impl.rs index 99963c51..b5c87fc1 100644 --- a/src/swizzles/neon/vec3a_impl.rs +++ b/src/swizzles/neon/vec3a_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for Vec3A { Vec3A::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> Vec3A { - Vec3A::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> Vec3A { diff --git a/src/swizzles/neon/vec4_impl.rs b/src/swizzles/neon/vec4_impl.rs index 00ad1ce0..1186e27e 100644 --- a/src/swizzles/neon/vec4_impl.rs +++ b/src/swizzles/neon/vec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for Vec4 { Vec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> Vec4 { - Vec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> Vec4 { diff --git a/src/swizzles/scalar/vec3a_impl.rs b/src/swizzles/scalar/vec3a_impl.rs index 99963c51..b5c87fc1 100644 --- a/src/swizzles/scalar/vec3a_impl.rs +++ b/src/swizzles/scalar/vec3a_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for Vec3A { Vec3A::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> Vec3A { - Vec3A::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> Vec3A { diff --git a/src/swizzles/scalar/vec4_impl.rs b/src/swizzles/scalar/vec4_impl.rs index 00ad1ce0..1186e27e 100644 --- a/src/swizzles/scalar/vec4_impl.rs +++ b/src/swizzles/scalar/vec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for Vec4 { Vec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> Vec4 { - Vec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> Vec4 { diff --git a/src/swizzles/sse2/vec3a_impl.rs b/src/swizzles/sse2/vec3a_impl.rs index 7ae63795..eb56569e 100644 --- a/src/swizzles/sse2/vec3a_impl.rs +++ b/src/swizzles/sse2/vec3a_impl.rs @@ -125,12 +125,6 @@ impl Vec3Swizzles for Vec3A { Vec3A((unsafe { _mm_shuffle_ps(self.0, self.0, 0b00_01_01_00) }).into()) } - #[inline] - #[must_use] - fn xyz(self) -> Vec3A { - Vec3A((unsafe { _mm_shuffle_ps(self.0, self.0, 0b00_10_01_00) }).into()) - } - #[inline] #[must_use] fn xzx(self) -> Vec3A { diff --git a/src/swizzles/sse2/vec4_impl.rs b/src/swizzles/sse2/vec4_impl.rs index e9a3f392..c00586bc 100644 --- a/src/swizzles/sse2/vec4_impl.rs +++ b/src/swizzles/sse2/vec4_impl.rs @@ -704,12 +704,6 @@ impl Vec4Swizzles for Vec4 { Vec4(unsafe { _mm_shuffle_ps(self.0, self.0, 0b10_10_01_00) }) } - #[inline] - #[must_use] - fn xyzw(self) -> Vec4 { - Vec4(unsafe { _mm_shuffle_ps(self.0, self.0, 0b11_10_01_00) }) - } - #[inline] #[must_use] fn xywx(self) -> Vec4 { diff --git a/src/swizzles/u16vec2_impl.rs b/src/swizzles/u16vec2_impl.rs index 086140b8..13180d13 100644 --- a/src/swizzles/u16vec2_impl.rs +++ b/src/swizzles/u16vec2_impl.rs @@ -16,15 +16,6 @@ impl Vec2Swizzles for U16Vec2 { } } - #[inline] - #[must_use] - fn xy(self) -> U16Vec2 { - U16Vec2 { - x: self.x, - y: self.y, - } - } - #[inline] #[must_use] fn yx(self) -> U16Vec2 { diff --git a/src/swizzles/u16vec3_impl.rs b/src/swizzles/u16vec3_impl.rs index bce679f0..aa76b5f6 100644 --- a/src/swizzles/u16vec3_impl.rs +++ b/src/swizzles/u16vec3_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for U16Vec3 { U16Vec3::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> U16Vec3 { - U16Vec3::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> U16Vec3 { diff --git a/src/swizzles/u16vec4_impl.rs b/src/swizzles/u16vec4_impl.rs index 738dc7bc..a3904dc9 100644 --- a/src/swizzles/u16vec4_impl.rs +++ b/src/swizzles/u16vec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for U16Vec4 { U16Vec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> U16Vec4 { - U16Vec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> U16Vec4 { diff --git a/src/swizzles/u64vec2_impl.rs b/src/swizzles/u64vec2_impl.rs index 18375bf0..0acef195 100644 --- a/src/swizzles/u64vec2_impl.rs +++ b/src/swizzles/u64vec2_impl.rs @@ -16,15 +16,6 @@ impl Vec2Swizzles for U64Vec2 { } } - #[inline] - #[must_use] - fn xy(self) -> U64Vec2 { - U64Vec2 { - x: self.x, - y: self.y, - } - } - #[inline] #[must_use] fn yx(self) -> U64Vec2 { diff --git a/src/swizzles/u64vec3_impl.rs b/src/swizzles/u64vec3_impl.rs index 95c3ad93..ae62b102 100644 --- a/src/swizzles/u64vec3_impl.rs +++ b/src/swizzles/u64vec3_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for U64Vec3 { U64Vec3::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> U64Vec3 { - U64Vec3::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> U64Vec3 { diff --git a/src/swizzles/u64vec4_impl.rs b/src/swizzles/u64vec4_impl.rs index 5ac02d26..c6ddd2b0 100644 --- a/src/swizzles/u64vec4_impl.rs +++ b/src/swizzles/u64vec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for U64Vec4 { U64Vec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> U64Vec4 { - U64Vec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> U64Vec4 { diff --git a/src/swizzles/uvec2_impl.rs b/src/swizzles/uvec2_impl.rs index 6e50c3e8..b9b51d94 100644 --- a/src/swizzles/uvec2_impl.rs +++ b/src/swizzles/uvec2_impl.rs @@ -16,15 +16,6 @@ impl Vec2Swizzles for UVec2 { } } - #[inline] - #[must_use] - fn xy(self) -> UVec2 { - UVec2 { - x: self.x, - y: self.y, - } - } - #[inline] #[must_use] fn yx(self) -> UVec2 { diff --git a/src/swizzles/uvec3_impl.rs b/src/swizzles/uvec3_impl.rs index 8f82b43b..885a109b 100644 --- a/src/swizzles/uvec3_impl.rs +++ b/src/swizzles/uvec3_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for UVec3 { UVec3::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> UVec3 { - UVec3::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> UVec3 { diff --git a/src/swizzles/uvec4_impl.rs b/src/swizzles/uvec4_impl.rs index 832d2233..5f4c27ed 100644 --- a/src/swizzles/uvec4_impl.rs +++ b/src/swizzles/uvec4_impl.rs @@ -697,12 +697,6 @@ impl Vec4Swizzles for UVec4 { UVec4::new(self.x, self.y, self.z, self.z) } - #[inline] - #[must_use] - fn xyzw(self) -> UVec4 { - UVec4::new(self.x, self.y, self.z, self.w) - } - #[inline] #[must_use] fn xywx(self) -> UVec4 { diff --git a/src/swizzles/vec2_impl.rs b/src/swizzles/vec2_impl.rs index d60f6925..d7899d2e 100644 --- a/src/swizzles/vec2_impl.rs +++ b/src/swizzles/vec2_impl.rs @@ -16,15 +16,6 @@ impl Vec2Swizzles for Vec2 { } } - #[inline] - #[must_use] - fn xy(self) -> Vec2 { - Vec2 { - x: self.x, - y: self.y, - } - } - #[inline] #[must_use] fn yx(self) -> Vec2 { diff --git a/src/swizzles/vec3_impl.rs b/src/swizzles/vec3_impl.rs index 9fcf8809..9a07e4a9 100644 --- a/src/swizzles/vec3_impl.rs +++ b/src/swizzles/vec3_impl.rs @@ -118,12 +118,6 @@ impl Vec3Swizzles for Vec3 { Vec3::new(self.x, self.y, self.y) } - #[inline] - #[must_use] - fn xyz(self) -> Vec3 { - Vec3::new(self.x, self.y, self.z) - } - #[inline] #[must_use] fn xzx(self) -> Vec3 { diff --git a/src/swizzles/wasm32/vec3a_impl.rs b/src/swizzles/wasm32/vec3a_impl.rs index 7bfe7cca..85a57e84 100644 --- a/src/swizzles/wasm32/vec3a_impl.rs +++ b/src/swizzles/wasm32/vec3a_impl.rs @@ -122,12 +122,6 @@ impl Vec3Swizzles for Vec3A { Vec3A(i32x4_shuffle::<0, 1, 5, 4>(self.0, self.0).into()) } - #[inline] - #[must_use] - fn xyz(self) -> Vec3A { - Vec3A(i32x4_shuffle::<0, 1, 6, 4>(self.0, self.0).into()) - } - #[inline] #[must_use] fn xzx(self) -> Vec3A { diff --git a/src/swizzles/wasm32/vec4_impl.rs b/src/swizzles/wasm32/vec4_impl.rs index 6d42d1b5..8fd5b2ec 100644 --- a/src/swizzles/wasm32/vec4_impl.rs +++ b/src/swizzles/wasm32/vec4_impl.rs @@ -701,12 +701,6 @@ impl Vec4Swizzles for Vec4 { Vec4(i32x4_shuffle::<0, 1, 6, 6>(self.0, self.0)) } - #[inline] - #[must_use] - fn xyzw(self) -> Vec4 { - Vec4(i32x4_shuffle::<0, 1, 6, 7>(self.0, self.0)) - } - #[inline] #[must_use] fn xywx(self) -> Vec4 { diff --git a/tests/mat2.rs b/tests/mat2.rs index 0b3d1998..2746e566 100644 --- a/tests/mat2.rs +++ b/tests/mat2.rs @@ -4,19 +4,18 @@ mod support; macro_rules! impl_mat2_tests { ($t:ident, $newmat2:ident, $mat2:ident, $mat3:ident, $newvec2:ident, $vec2:ident) => { const IDENTITY: [[$t; 2]; 2] = [[1.0, 0.0], [0.0, 1.0]]; - - const MATRIX: [[$t; 2]; 2] = [[1.0, 2.0], [3.0, 4.0]]; - - const MATRIX1D: [$t; 4] = [1.0, 2.0, 3.0, 4.0]; + const ARRAY2X2: [[$t; 2]; 2] = [[1.0, 2.0], [3.0, 4.0]]; + const ARRAY1X4: [$t; 4] = [1.0, 2.0, 3.0, 4.0]; + const ARRAY3X3: [[$t; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]; glam_test!(test_const, { const M0: $mat2 = $mat2::from_cols($newvec2(1.0, 2.0), $newvec2(3.0, 4.0)); - const M1: $mat2 = $mat2::from_cols_array(&MATRIX1D); - const M2: $mat2 = $mat2::from_cols_array_2d(&MATRIX); + const M1: $mat2 = $mat2::from_cols_array(&ARRAY1X4); + const M2: $mat2 = $mat2::from_cols_array_2d(&ARRAY2X2); - assert_eq!(MATRIX1D, M0.to_cols_array()); - assert_eq!(MATRIX1D, M1.to_cols_array()); - assert_eq!(MATRIX1D, M2.to_cols_array()); + assert_eq!(ARRAY1X4, M0.to_cols_array()); + assert_eq!(ARRAY1X4, M1.to_cols_array()); + assert_eq!(ARRAY1X4, M2.to_cols_array()); }); glam_test!(test_mat2_identity, { @@ -42,7 +41,7 @@ macro_rules! impl_mat2_tests { let mut m = $mat2::ZERO; m.x_axis = $vec2::new(1.0, 2.0); m.y_axis = $vec2::new(3.0, 4.0); - assert_eq!($mat2::from_cols_array_2d(&MATRIX), m); + assert_eq!($mat2::from_cols_array_2d(&ARRAY2X2), m); assert_eq!($vec2::new(1.0, 2.0), m.x_axis); assert_eq!($vec2::new(3.0, 4.0), m.y_axis); @@ -66,8 +65,8 @@ macro_rules! impl_mat2_tests { }); glam_test!(test_mat2_from_axes, { - let a = $mat2::from_cols_array_2d(&[[1.0, 2.0], [3.0, 4.0]]); - assert_eq!(MATRIX, a.to_cols_array_2d()); + let a = $mat2::from_cols_array_2d(&ARRAY2X2); + assert_eq!(ARRAY2X2, a.to_cols_array_2d()); let b = $mat2::from_cols($newvec2(1.0, 2.0), $newvec2(3.0, 4.0)); assert_eq!(a, b); let c = $newmat2($newvec2(1.0, 2.0), $newvec2(3.0, 4.0)); @@ -103,12 +102,23 @@ macro_rules! impl_mat2_tests { }); glam_test!(test_from_mat3, { - let m3 = - $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]); + let m3 = $mat3::from_cols_array_2d(&ARRAY3X3); let m2 = $mat2::from_mat3(m3); assert_eq!($mat2::from_cols_array_2d(&[[1.0, 2.0], [4.0, 5.0]]), m2); }); + glam_test!(test_from_mat3_minor, { + let m3 = $mat3::from_cols_array_2d(&ARRAY3X3); + for i in 0..3 { + for j in 0..3 { + let m2 = $mat2::from_mat3_minor(m3, i, j); + test_matrix_minor!(3, m2, m3, i, j); + } + } + should_panic!({ $mat2::from_mat3_minor(m3, 3, 0) }); + should_panic!({ $mat2::from_mat3_minor(m3, 0, 3) }); + }); + glam_test!(test_mat2_transpose, { let m = $newmat2($newvec2(1.0, 2.0), $newvec2(3.0, 4.0)); let mt = m.transpose(); @@ -128,7 +138,7 @@ macro_rules! impl_mat2_tests { ); assert_eq!( 1.0 * 4.0 - 2.0 * 3.0, - $mat2::from_cols_array(&[1.0, 2.0, 3.0, 4.0]).determinant() + $mat2::from_cols_array(&ARRAY1X4).determinant() ); }); @@ -156,7 +166,7 @@ macro_rules! impl_mat2_tests { }); glam_test!(test_mat2_ops, { - let m0 = $mat2::from_cols_array_2d(&MATRIX); + let m0 = $mat2::from_cols_array_2d(&ARRAY2X2); 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); @@ -191,17 +201,17 @@ macro_rules! impl_mat2_tests { }); glam_test!(test_mat2_fmt, { - let a = $mat2::from_cols_array_2d(&MATRIX); + let a = $mat2::from_cols_array_2d(&ARRAY2X2); assert_eq!(format!("{}", a), "[[1, 2], [3, 4]]"); assert_eq!(format!("{:.2}", a), "[[1.00, 2.00], [3.00, 4.00]]"); }); glam_test!(test_mat2_to_from_slice, { - let m = $mat2::from_cols_slice(&MATRIX1D); - assert_eq!($mat2::from_cols_array(&MATRIX1D), m); + let m = $mat2::from_cols_slice(&ARRAY1X4); + assert_eq!($mat2::from_cols_array(&ARRAY1X4), m); let mut out: [$t; 4] = Default::default(); m.write_cols_to_slice(&mut out); - assert_eq!(MATRIX1D, out); + assert_eq!(ARRAY1X4, out); should_panic!({ $mat2::from_cols_slice(&[0.0; 3]) }); should_panic!({ $mat2::IDENTITY.write_cols_to_slice(&mut [0.0; 3]) }); @@ -231,20 +241,20 @@ macro_rules! impl_mat2_tests { macro_rules! impl_as_ref_tests { ($mat:ident) => { glam_test!(test_as_ref, { - let m = $mat::from_cols_array_2d(&MATRIX); - assert_eq!(MATRIX1D, *m.as_ref()); + let m = $mat::from_cols_array_2d(&ARRAY2X2); + assert_eq!(ARRAY1X4, *m.as_ref()); }); glam_test!(test_as_mut, { let mut m = $mat::ZERO; - *m.as_mut() = MATRIX1D; - assert_eq!($mat::from_cols_array_2d(&MATRIX), m); + *m.as_mut() = ARRAY1X4; + assert_eq!($mat::from_cols_array_2d(&ARRAY2X2), m); }); }; } mod mat2 { use super::support::deg; - use glam::{mat2, swizzles::*, vec2, Mat2, Mat3, Vec2}; + use glam::{mat2, swizzles::*, vec2, Mat2, Mat3, Mat3A, Vec2}; glam_test!(test_align, { use std::mem; @@ -257,12 +267,23 @@ mod mat2 { }); glam_test!(test_from_mat3a, { - use glam::Mat3A; - let m3 = Mat3A::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]); + let m3 = Mat3A::from_cols_array_2d(&ARRAY3X3); let m2 = Mat2::from_mat3a(m3); assert_eq!(Mat2::from_cols_array_2d(&[[1.0, 2.0], [4.0, 5.0]]), m2); }); + glam_test!(test_from_mat3a_minor, { + let m3 = Mat3A::from_cols_array_2d(&ARRAY3X3); + for i in 0..3 { + for j in 0..3 { + let m2 = Mat2::from_mat3a_minor(m3, i, j); + test_matrix_minor!(3, m2, m3, i, j); + } + } + should_panic!({ Mat2::from_mat3a_minor(m3, 3, 0) }); + should_panic!({ Mat2::from_mat3a_minor(m3, 0, 3) }); + }); + glam_test!(test_as, { use glam::DMat2; assert_eq!( diff --git a/tests/mat3.rs b/tests/mat3.rs index a881d6ca..ef36606d 100644 --- a/tests/mat3.rs +++ b/tests/mat3.rs @@ -4,10 +4,14 @@ mod support; macro_rules! impl_mat3_tests { ($t:ident, $newmat3:ident, $mat3:ident, $mat2:ident, $mat4:ident, $quat:ident, $newvec3:ident, $vec3:ident, $vec2:ident) => { const IDENTITY: [[$t; 3]; 3] = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]; - - const MATRIX: [[$t; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]; - - const MATRIX1D: [$t; 9] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]; + const ARRAY3X3: [[$t; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]; + const ARRAY1X9: [$t; 9] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]; + const ARRAY4X4: [[$t; 4]; 4] = [ + [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], + ]; glam_test!(test_const, { const M0: $mat3 = $mat3::from_cols( @@ -15,12 +19,12 @@ macro_rules! impl_mat3_tests { $newvec3(4.0, 5.0, 6.0), $newvec3(7.0, 8.0, 9.0), ); - const M1: $mat3 = $mat3::from_cols_array(&MATRIX1D); - const M2: $mat3 = $mat3::from_cols_array_2d(&MATRIX); + const M1: $mat3 = $mat3::from_cols_array(&ARRAY1X9); + const M2: $mat3 = $mat3::from_cols_array_2d(&ARRAY3X3); - assert_eq!(MATRIX1D, M0.to_cols_array()); - assert_eq!(MATRIX1D, M1.to_cols_array()); - assert_eq!(MATRIX1D, M2.to_cols_array()); + assert_eq!(ARRAY1X9, M0.to_cols_array()); + assert_eq!(ARRAY1X9, M1.to_cols_array()); + assert_eq!(ARRAY1X9, M2.to_cols_array()); }); glam_test!(test_mat3_identity, { @@ -57,7 +61,7 @@ macro_rules! impl_mat3_tests { m.x_axis = $newvec3(1.0, 2.0, 3.0); m.y_axis = $newvec3(4.0, 5.0, 6.0); m.z_axis = $newvec3(7.0, 8.0, 9.0); - assert_eq!($mat3::from_cols_array_2d(&MATRIX), m); + assert_eq!($mat3::from_cols_array_2d(&ARRAY3X3), m); assert_eq!($newvec3(1.0, 2.0, 3.0), m.x_axis); assert_eq!($newvec3(4.0, 5.0, 6.0), m.y_axis); assert_eq!($newvec3(7.0, 8.0, 9.0), m.z_axis); @@ -87,7 +91,7 @@ macro_rules! impl_mat3_tests { glam_test!(test_mat3_from_axes, { let a = $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!(MATRIX, a.to_cols_array_2d()); + assert_eq!(ARRAY3X3, a.to_cols_array_2d()); let b = $mat3::from_cols( $newvec3(1.0, 2.0, 3.0), $newvec3(4.0, 5.0, 6.0), @@ -214,12 +218,7 @@ macro_rules! impl_mat3_tests { }); glam_test!(test_from_mat4, { - let m4 = $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], - ]); + let m4 = $mat4::from_cols_array_2d(&ARRAY4X4); let m3 = $mat3::from_mat4(m4); assert_eq!( $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [5.0, 6.0, 7.0], [9.0, 10.0, 11.0]]), @@ -227,6 +226,18 @@ macro_rules! impl_mat3_tests { ); }); + glam_test!(test_from_mat4_minor, { + let m4 = $mat4::from_cols_array_2d(&ARRAY4X4); + for i in 0..4 { + for j in 0..4 { + let m3 = $mat3::from_mat4_minor(m4, i, j); + test_matrix_minor!(4, m3, m4, i, j); + } + } + should_panic!({ $mat3::from_mat4_minor(m4, 4, 0) }); + should_panic!({ $mat3::from_mat4_minor(m4, 0, 4) }); + }); + glam_test!(test_mat3_transpose, { let m = $newmat3( $newvec3(1.0, 2.0, 3.0), @@ -283,7 +294,7 @@ macro_rules! impl_mat3_tests { }); glam_test!(test_mat3_ops, { - let m0 = $mat3::from_cols_array_2d(&MATRIX); + let m0 = $mat3::from_cols_array_2d(&ARRAY3X3); let m0x2 = $mat3::from_cols_array_2d(&[ [2.0, 4.0, 6.0], [8.0, 10.0, 12.0], @@ -326,7 +337,7 @@ macro_rules! impl_mat3_tests { }); glam_test!(test_mat3_fmt, { - let a = $mat3::from_cols_array_2d(&MATRIX); + let a = $mat3::from_cols_array_2d(&ARRAY3X3); assert_eq!(format!("{}", a), "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]"); assert_eq!( format!("{:.1}", a), @@ -335,11 +346,11 @@ macro_rules! impl_mat3_tests { }); glam_test!(test_mat3_to_from_slice, { - let m = $mat3::from_cols_slice(&MATRIX1D); - assert_eq!($mat3::from_cols_array(&MATRIX1D), m); + let m = $mat3::from_cols_slice(&ARRAY1X9); + assert_eq!($mat3::from_cols_array(&ARRAY1X9), m); let mut out: [$t; 9] = Default::default(); m.write_cols_to_slice(&mut out); - assert_eq!(MATRIX1D, out); + assert_eq!(ARRAY1X9, out); should_panic!({ $mat3::from_cols_slice(&[0.0; 8]) }); should_panic!({ $mat3::IDENTITY.write_cols_to_slice(&mut [0.0; 8]) }); @@ -369,13 +380,13 @@ macro_rules! impl_mat3_tests { macro_rules! impl_as_ref_tests { ($mat:ident) => { glam_test!(test_as_ref, { - let m = $mat::from_cols_array_2d(&MATRIX); - assert_eq!(MATRIX1D, *m.as_ref()); + let m = $mat::from_cols_array_2d(&ARRAY3X3); + assert_eq!(ARRAY1X9, *m.as_ref()); }); glam_test!(test_as_mut, { let mut m = $mat::ZERO; - *m.as_mut() = MATRIX1D; - assert_eq!($mat::from_cols_array_2d(&MATRIX), m); + *m.as_mut() = ARRAY1X9; + assert_eq!($mat::from_cols_array_2d(&ARRAY3X3), m); }); }; } diff --git a/tests/mat4.rs b/tests/mat4.rs index 06c202e8..d9036331 100644 --- a/tests/mat4.rs +++ b/tests/mat4.rs @@ -9,16 +9,16 @@ macro_rules! impl_mat4_tests { [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0], ]; - const MATRIX: [[$t; 4]; 4] = [ + const ARRAY4X4: [[$t; 4]; 4] = [ [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], ]; - - const MATRIX1D: [$t; 16] = [ + const ARRAY1X16: [$t; 16] = [ 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, ]; + const ARRAY3X3: [[$t; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]; glam_test!(test_const, { const M0: $mat4 = $mat4::from_cols( @@ -27,12 +27,12 @@ macro_rules! impl_mat4_tests { $newvec4(9.0, 10.0, 11.0, 12.0), $newvec4(13.0, 14.0, 15.0, 16.0), ); - const M1: $mat4 = $mat4::from_cols_array(&MATRIX1D); - const M2: $mat4 = $mat4::from_cols_array_2d(&MATRIX); + const M1: $mat4 = $mat4::from_cols_array(&ARRAY1X16); + const M2: $mat4 = $mat4::from_cols_array_2d(&ARRAY4X4); - assert_eq!(MATRIX1D, M0.to_cols_array()); - assert_eq!(MATRIX1D, M1.to_cols_array()); - assert_eq!(MATRIX1D, M2.to_cols_array()); + assert_eq!(ARRAY1X16, M0.to_cols_array()); + assert_eq!(ARRAY1X16, M1.to_cols_array()); + assert_eq!(ARRAY1X16, M2.to_cols_array()); }); glam_test!(test_mat4_identity, { @@ -76,7 +76,7 @@ macro_rules! impl_mat4_tests { m.y_axis = $vec4::new(5.0, 6.0, 7.0, 8.0); m.z_axis = $vec4::new(9.0, 10.0, 11.0, 12.0); m.w_axis = $vec4::new(13.0, 14.0, 15.0, 16.0); - assert_eq!($mat4::from_cols_array_2d(&MATRIX), m); + assert_eq!($mat4::from_cols_array_2d(&ARRAY4X4), m); assert_eq!($vec4::new(1.0, 2.0, 3.0, 4.0), m.x_axis); assert_eq!($vec4::new(5.0, 6.0, 7.0, 8.0), m.y_axis); assert_eq!($vec4::new(9.0, 10.0, 11.0, 12.0), m.z_axis); @@ -116,7 +116,7 @@ macro_rules! impl_mat4_tests { [9.0, 10.0, 11.0, 12.0], [13.0, 14.0, 15.0, 16.0], ]); - assert_eq!(MATRIX, a.to_cols_array_2d()); + assert_eq!(ARRAY4X4, a.to_cols_array_2d()); let b = $mat4::from_cols( $newvec4(1.0, 2.0, 3.0, 4.0), $newvec4(5.0, 6.0, 7.0, 8.0), @@ -168,7 +168,7 @@ macro_rules! impl_mat4_tests { glam_test!(test_from_mat3, { let m3 = - $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]); + $mat3::from_cols_array_2d(&ARRAY3X3); let m4 = $mat4::from_mat3(m3); assert_eq!( $mat4::from_cols_array_2d(&[ @@ -584,7 +584,7 @@ macro_rules! impl_mat4_tests { }); glam_test!(test_mat4_ops, { - let m0 = $mat4::from_cols_array_2d(&MATRIX); + let m0 = $mat4::from_cols_array_2d(&ARRAY4X4); let m0x2 = $mat4::from_cols_array_2d(&[ [2.0, 4.0, 6.0, 8.0], [10.0, 12.0, 14.0, 16.0], @@ -629,7 +629,7 @@ macro_rules! impl_mat4_tests { }); glam_test!(test_mat4_fmt, { - let a = $mat4::from_cols_array_2d(&MATRIX); + let a = $mat4::from_cols_array_2d(&ARRAY4X4); assert_eq!( format!("{}", a), "[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]" @@ -641,11 +641,11 @@ macro_rules! impl_mat4_tests { }); glam_test!(test_mat4_to_from_slice, { - let m = $mat4::from_cols_slice(&MATRIX1D); - assert_eq!($mat4::from_cols_array(&MATRIX1D), m); + let m = $mat4::from_cols_slice(&ARRAY1X16); + assert_eq!($mat4::from_cols_array(&ARRAY1X16), m); let mut out: [$t; 16] = Default::default(); m.write_cols_to_slice(&mut out); - assert_eq!(MATRIX1D, out); + assert_eq!(ARRAY1X16, out); should_panic!({ $mat4::from_cols_slice(&[0.0; 15]) }); should_panic!({ $mat4::IDENTITY.write_cols_to_slice(&mut [0.0; 15]) }); @@ -697,13 +697,13 @@ macro_rules! impl_mat4_tests { macro_rules! impl_as_ref_tests { ($mat:ident) => { glam_test!(test_as_ref, { - let m = $mat::from_cols_array_2d(&MATRIX); - assert_eq!(MATRIX1D, *m.as_ref()); + let m = $mat::from_cols_array_2d(&ARRAY4X4); + assert_eq!(ARRAY1X16, *m.as_ref()); }); glam_test!(test_as_mut, { let mut m = $mat::ZERO; - *m.as_mut() = MATRIX1D; - assert_eq!($mat::from_cols_array_2d(&MATRIX), m); + *m.as_mut() = ARRAY1X16; + assert_eq!($mat::from_cols_array_2d(&ARRAY4X4), m); }); }; } @@ -720,7 +720,7 @@ mod mat4 { glam_test!(test_from_mat3a, { use glam::Mat3A; - let m3 = Mat3A::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]); + let m3 = Mat3A::from_cols_array_2d(&ARRAY3X3); let m4 = Mat4::from_mat3a(m3); assert_eq!( Mat4::from_cols_array_2d(&[ diff --git a/tests/support/macros.rs b/tests/support/macros.rs index 12d54506..4babd87a 100644 --- a/tests/support/macros.rs +++ b/tests/support/macros.rs @@ -247,3 +247,22 @@ macro_rules! vec2_float_test_vectors { ] }; } + +#[macro_export] +macro_rules! test_matrix_minor { + ($n:expr, $minor:expr, $input:expr, $i:expr, $j:expr) => { + let mut yy = 0; + for y in 0..$n { + if y != $j { + let mut xx = 0; + for x in 0..$n { + if x != $i { + assert_eq!($minor.col(xx)[yy], $input.col(x)[y]); + xx += 1; + } + } + yy += 1; + } + } + }; +}