Repository: bitshifter/glam-rs
Pull request #609 (2025-02-18 09:49:39)

Added `from_mat3_translation` to 4x4 matrix types.
This method already existed on 3D affine types.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f99495d..1b97b69 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,9 @@ The format is based on [Keep a Changelog], and this project adheres to
   `chebyshev_distance` methods to integer vector types which calculates the
   Manhattan Distance and the Chebyshev Distance between two vectors.
 
+* Added 4x4 matrix `from_mat3_translation` method to have parity with the 3D
+  affine type.
+
 ### Fixed
 
 * `Quat::rotate_towards()` now returns the target `Quat` if the angle is small.
diff --git a/codegen/templates/mat.rs.tera b/codegen/templates/mat.rs.tera
index 40d4cb5..1503467 100644
--- a/codegen/templates/mat.rs.tera
+++ b/codegen/templates/mat.rs.tera
@@ -789,6 +789,21 @@ impl {{ self_t }} {
         )
     }
 
+    /// Creates an affine transformation matrics from a 3x3 matrix (expressing scale, shear and 
+    /// rotation) and a translation vector.
+    ///
+    /// Equivalent to `{{ self_t }}::from_translation(translation) * {{ self_t }}::from_mat3(mat3)`
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_translation(mat3: {{ mat3_t }}, translation: {{ vec3_t }}) -> Self {
+        Self::from_cols(
+            {{ col_t }}::from((mat3.x_axis, 0.0)),
+            {{ col_t }}::from((mat3.y_axis, 0.0)),
+            {{ col_t }}::from((mat3.z_axis, 0.0)),
+            {{ col_t }}::from((translation, 1.0)),
+        )
+    }
+
 {% if scalar_t == "f32" %}
     /// Creates an affine transformation matrix from the given 3x3 linear transformation
     /// matrix.
diff --git a/src/f32/coresimd/mat4.rs b/src/f32/coresimd/mat4.rs
index d4b7e9f..a063997 100644
--- a/src/f32/coresimd/mat4.rs
+++ b/src/f32/coresimd/mat4.rs
@@ -302,6 +302,21 @@ impl Mat4 {
         )
     }
 
+    /// Creates an affine transformation matrics from a 3x3 matrix (expressing scale, shear and
+    /// rotation) and a translation vector.
+    ///
+    /// Equivalent to `Mat4::from_translation(translation) * Mat4::from_mat3(mat3)`
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
+        Self::from_cols(
+            Vec4::from((mat3.x_axis, 0.0)),
+            Vec4::from((mat3.y_axis, 0.0)),
+            Vec4::from((mat3.z_axis, 0.0)),
+            Vec4::from((translation, 1.0)),
+        )
+    }
+
     /// Creates an affine transformation matrix from the given 3x3 linear transformation
     /// matrix.
     ///
diff --git a/src/f32/neon/mat4.rs b/src/f32/neon/mat4.rs
index c688954..b118a88 100644
--- a/src/f32/neon/mat4.rs
+++ b/src/f32/neon/mat4.rs
@@ -302,6 +302,21 @@ impl Mat4 {
         )
     }
 
+    /// Creates an affine transformation matrics from a 3x3 matrix (expressing scale, shear and
+    /// rotation) and a translation vector.
+    ///
+    /// Equivalent to `Mat4::from_translation(translation) * Mat4::from_mat3(mat3)`
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
+        Self::from_cols(
+            Vec4::from((mat3.x_axis, 0.0)),
+            Vec4::from((mat3.y_axis, 0.0)),
+            Vec4::from((mat3.z_axis, 0.0)),
+            Vec4::from((translation, 1.0)),
+        )
+    }
+
     /// Creates an affine transformation matrix from the given 3x3 linear transformation
     /// matrix.
     ///
diff --git a/src/f32/scalar/mat4.rs b/src/f32/scalar/mat4.rs
index 2c292d3..39cdc97 100644
--- a/src/f32/scalar/mat4.rs
+++ b/src/f32/scalar/mat4.rs
@@ -314,6 +314,21 @@ impl Mat4 {
         )
     }
 
+    /// Creates an affine transformation matrics from a 3x3 matrix (expressing scale, shear and
+    /// rotation) and a translation vector.
+    ///
+    /// Equivalent to `Mat4::from_translation(translation) * Mat4::from_mat3(mat3)`
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
+        Self::from_cols(
+            Vec4::from((mat3.x_axis, 0.0)),
+            Vec4::from((mat3.y_axis, 0.0)),
+            Vec4::from((mat3.z_axis, 0.0)),
+            Vec4::from((translation, 1.0)),
+        )
+    }
+
     /// Creates an affine transformation matrix from the given 3x3 linear transformation
     /// matrix.
     ///
diff --git a/src/f32/sse2/mat4.rs b/src/f32/sse2/mat4.rs
index 322c62b..b5884ff 100644
--- a/src/f32/sse2/mat4.rs
+++ b/src/f32/sse2/mat4.rs
@@ -305,6 +305,21 @@ impl Mat4 {
         )
     }
 
+    /// Creates an affine transformation matrics from a 3x3 matrix (expressing scale, shear and
+    /// rotation) and a translation vector.
+    ///
+    /// Equivalent to `Mat4::from_translation(translation) * Mat4::from_mat3(mat3)`
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
+        Self::from_cols(
+            Vec4::from((mat3.x_axis, 0.0)),
+            Vec4::from((mat3.y_axis, 0.0)),
+            Vec4::from((mat3.z_axis, 0.0)),
+            Vec4::from((translation, 1.0)),
+        )
+    }
+
     /// Creates an affine transformation matrix from the given 3x3 linear transformation
     /// matrix.
     ///
diff --git a/src/f32/wasm32/mat4.rs b/src/f32/wasm32/mat4.rs
index ffbee0b..6e00ed2 100644
--- a/src/f32/wasm32/mat4.rs
+++ b/src/f32/wasm32/mat4.rs
@@ -302,6 +302,21 @@ impl Mat4 {
         )
     }
 
+    /// Creates an affine transformation matrics from a 3x3 matrix (expressing scale, shear and
+    /// rotation) and a translation vector.
+    ///
+    /// Equivalent to `Mat4::from_translation(translation) * Mat4::from_mat3(mat3)`
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
+        Self::from_cols(
+            Vec4::from((mat3.x_axis, 0.0)),
+            Vec4::from((mat3.y_axis, 0.0)),
+            Vec4::from((mat3.z_axis, 0.0)),
+            Vec4::from((translation, 1.0)),
+        )
+    }
+
     /// Creates an affine transformation matrix from the given 3x3 linear transformation
     /// matrix.
     ///
diff --git a/src/f64/dmat4.rs b/src/f64/dmat4.rs
index 4857b5f..801bc61 100644
--- a/src/f64/dmat4.rs
+++ b/src/f64/dmat4.rs
@@ -312,6 +312,21 @@ impl DMat4 {
         )
     }
 
+    /// Creates an affine transformation matrics from a 3x3 matrix (expressing scale, shear and
+    /// rotation) and a translation vector.
+    ///
+    /// Equivalent to `DMat4::from_translation(translation) * DMat4::from_mat3(mat3)`
+    #[inline]
+    #[must_use]
+    pub fn from_mat3_translation(mat3: DMat3, translation: DVec3) -> Self {
+        Self::from_cols(
+            DVec4::from((mat3.x_axis, 0.0)),
+            DVec4::from((mat3.y_axis, 0.0)),
+            DVec4::from((mat3.z_axis, 0.0)),
+            DVec4::from((translation, 1.0)),
+        )
+    }
+
     /// Creates an affine transformation matrix from the given 3D `translation`.
     ///
     /// The resulting matrix can be used to transform 3D points and vectors. See


Test patch:
diff --git a/tests/mat4.rs b/tests/mat4.rs
index 4b07330..ecb5709 100644
--- a/tests/mat4.rs
+++ b/tests/mat4.rs
@@ -179,6 +179,16 @@ macro_rules! impl_mat4_tests {
                 ]),
                 m4
             );
+
+            let t = $vec3::new(10.0, 11.0, 12.0);
+            let m4 = $mat4::from_mat3_translation(m3, t);
+            assert_eq!($mat4::from_cols_array_2d(&[
+                    [1.0, 2.0, 3.0, 0.0],
+                    [4.0, 5.0, 6.0, 0.0],
+                    [7.0, 8.0, 9.0, 0.0],
+                    [10.0, 11.0, 12.0, 1.0]
+            ]),
+                m4);
         });
 
         glam_test!(test_mat4_mul, {