Repository: bitshifter/glam-rs
Pull request #624 (2025-03-31 22:50:13)

Add precision conversion functions for affine types
This PR addresses #621. There are no breaking changes. Tests were added.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c47cf8e..a8a6edb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog], and this project adheres to
 [Semantic Versioning].
 
+## [Unreleased]
+
+## Added
+
+- Added precision conversion functions for Affine types: `Affine3A::as_daffine3`,
+  `DAffine3::as_affine3a`, `Affine2::as_daffine2` and `DAffine3::as_affine2`
+
 ## [0.30.1] - 2025-03-20
 
 ## Added
diff --git a/src/f32/affine2.rs b/src/f32/affine2.rs
index b41db49..658eae8 100644
--- a/src/f32/affine2.rs
+++ b/src/f32/affine2.rs
@@ -313,6 +313,13 @@ impl Affine2 {
             translation,
         }
     }
+
+    /// Casts all elements of `self` to `f64`.
+    #[inline]
+    #[must_use]
+    pub fn as_daffine2(&self) -> crate::DAffine2 {
+        crate::DAffine2::from_mat2_translation(self.matrix2.as_dmat2(), self.translation.as_dvec2())
+    }
 }
 
 impl Default for Affine2 {
diff --git a/src/f32/affine3a.rs b/src/f32/affine3a.rs
index 8110101..0d30de1 100644
--- a/src/f32/affine3a.rs
+++ b/src/f32/affine3a.rs
@@ -457,6 +457,13 @@ impl Affine3A {
             translation,
         }
     }
+
+    /// Casts all elements of `self` to `f64`.
+    #[inline]
+    #[must_use]
+    pub fn as_daffine3(&self) -> crate::DAffine3 {
+        crate::DAffine3::from_mat3_translation(self.matrix3.as_dmat3(), self.translation.as_dvec3())
+    }
 }
 
 impl Default for Affine3A {
diff --git a/src/f64/daffine2.rs b/src/f64/daffine2.rs
index fd29d5e..1a2b4bb 100644
--- a/src/f64/daffine2.rs
+++ b/src/f64/daffine2.rs
@@ -302,6 +302,13 @@ impl DAffine2 {
             translation,
         }
     }
+
+    /// Casts all elements of `self` to `f32`.
+    #[inline]
+    #[must_use]
+    pub fn as_affine2(&self) -> crate::Affine2 {
+        crate::Affine2::from_mat2_translation(self.matrix2.as_mat2(), self.translation.as_vec2())
+    }
 }
 
 impl Default for DAffine2 {
diff --git a/src/f64/daffine3.rs b/src/f64/daffine3.rs
index 25459ac..e048287 100644
--- a/src/f64/daffine3.rs
+++ b/src/f64/daffine3.rs
@@ -442,6 +442,13 @@ impl DAffine3 {
             translation,
         }
     }
+
+    /// Casts all elements of `self` to `f32`.
+    #[inline]
+    #[must_use]
+    pub fn as_affine3a(&self) -> crate::Affine3A {
+        crate::Affine3A::from_mat3_translation(self.matrix3.as_mat3(), self.translation.as_vec3())
+    }
 }
 
 impl Default for DAffine3 {
diff --git a/templates/affine.rs.tera b/templates/affine.rs.tera
index 5a99cea..4033678 100644
--- a/templates/affine.rs.tera
+++ b/templates/affine.rs.tera
@@ -702,6 +702,42 @@ impl {{ self_t }} {
             translation,
         }
     }
+
+{% if scalar_t == "f64" %}
+    {% if dim == 2 %}
+    /// Casts all elements of `self` to `f32`.
+    #[inline]
+    #[must_use]
+    pub fn as_affine2(&self) -> crate::Affine2 {
+        crate::Affine2::from_mat2_translation(self.matrix2.as_mat2(), self.translation.as_vec2())
+    }
+    {% elif dim == 3 %}
+    /// Casts all elements of `self` to `f32`.
+    #[inline]
+    #[must_use]
+    pub fn as_affine3a(&self) -> crate::Affine3A {
+        crate::Affine3A::from_mat3_translation(self.matrix3.as_mat3(), self.translation.as_vec3())
+    }
+    {% endif %}
+{% endif %}
+
+{% if scalar_t == "f32" %}
+    {% if dim == 2 %}
+    /// Casts all elements of `self` to `f64`.
+    #[inline]
+    #[must_use]
+    pub fn as_daffine2(&self) -> crate::DAffine2 {
+        crate::DAffine2::from_mat2_translation(self.matrix2.as_dmat2(), self.translation.as_dvec2())
+    }
+    {% elif dim == 3 %}
+    /// Casts all elements of `self` to `f64`.
+    #[inline]
+    #[must_use]
+    pub fn as_daffine3(&self) -> crate::DAffine3 {
+        crate::DAffine3::from_mat3_translation(self.matrix3.as_dmat3(), self.translation.as_dvec3())
+    }
+    {% endif %}
+{% endif %}
 }
 
 impl Default for {{ self_t }} {


Test patch:
diff --git a/tests/affine2.rs b/tests/affine2.rs
index 0f56e7e..b5f44a2 100644
--- a/tests/affine2.rs
+++ b/tests/affine2.rs
@@ -304,6 +304,14 @@ mod affine2 {
         assert_eq!(m, Mat3A::from(a));
     });
 
+    glam_test!(test_as, {
+        use glam::DAffine2;
+        assert_eq!(
+            DAffine2::from_cols_array(&[1., 2., 3., 4., 5., 6.]),
+            Affine2::from_cols_array(&[1., 2., 3., 4., 5., 6.]).as_daffine2(),
+        );
+    });
+
     impl_affine2_tests!(f32, Affine2, Vec2, Mat2, Mat3);
 }
 
@@ -339,5 +347,13 @@ mod daffine2 {
         assert_eq!(16, mem::align_of::<DAffine2>());
     });
 
+    glam_test!(test_as, {
+        use glam::Affine2;
+        assert_eq!(
+            Affine2::from_cols_array(&[1., 2., 3., 4., 5., 6.]),
+            DAffine2::from_cols_array(&[1., 2., 3., 4., 5., 6.]).as_affine2()
+        );
+    });
+
     impl_affine2_tests!(f64, DAffine2, DVec2, DMat2, DMat3);
 }
diff --git a/tests/affine3.rs b/tests/affine3.rs
index 46b704c..1218ebd 100644
--- a/tests/affine3.rs
+++ b/tests/affine3.rs
@@ -389,6 +389,15 @@ mod affine3a {
         assert_approx_eq!(Vec3A::new(1.0, 2.0, 4.5), result3, 1.0e-6);
     });
 
+    glam_test!(test_as, {
+        use glam::DAffine3;
+        assert_eq!(
+            DAffine3::from_cols_array(&[1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.]),
+            Affine3A::from_cols_array(&[1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.])
+                .as_daffine3(),
+        );
+    });
+
     impl_affine3_tests!(f32, Affine3A, Quat, Vec3, Mat3, Mat4);
 }
 
@@ -416,5 +425,14 @@ mod daffine3 {
         assert_eq!(mem::align_of::<f64>(), mem::align_of::<DAffine3>());
     });
 
+    glam_test!(test_as, {
+        use glam::Affine3A;
+        assert_eq!(
+            Affine3A::from_cols_array(&[1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.]),
+            DAffine3::from_cols_array(&[1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.])
+                .as_affine3a(),
+        );
+    });
+
     impl_affine3_tests!(f64, DAffine3, DQuat, DVec3, DMat3, DMat4);
 }