Skip to main content

bevy_math/
affine3.rs

1use glam::{vec3, Affine3, Affine3A, Mat3, Vec3Swizzles, Vec4, Vec4Swizzles};
2
3/// Extension trait for [`Affine3`]
4pub trait Affine3Ext {
5    /// Generates an [`Affine3`] from a transposed 3x4 matrix.
6    ///
7    /// This is the inverse of [`Self::to_transpose`].
8    fn from_transpose(transposed: [Vec4; 3]) -> Self;
9    /// Calculates the transpose of the affine 4x3 matrix to a 3x4 and formats it for packing into GPU buffers
10    fn to_transpose(self) -> [Vec4; 3];
11    /// Calculates the inverse transpose of the 3x3 matrix and formats it for packing into GPU buffers
12    fn inverse_transpose_3x3(self) -> ([Vec4; 2], f32);
13}
14
15impl Affine3Ext for Affine3 {
16    fn from_transpose(transposed: [Vec4; 3]) -> Self {
17        let transpose_3x3 = Mat3::from_cols(
18            transposed[0].xyz(),
19            transposed[1].xyz(),
20            transposed[2].xyz(),
21        );
22        let translation = vec3(transposed[0].w, transposed[1].w, transposed[2].w);
23        Affine3::from_mat3_translation(transpose_3x3.transpose(), translation)
24    }
25
26    #[inline]
27    fn to_transpose(self) -> [Vec4; 3] {
28        let transpose_3x3 = self.matrix3.transpose();
29        [
30            transpose_3x3.x_axis.extend(self.translation.x),
31            transpose_3x3.y_axis.extend(self.translation.y),
32            transpose_3x3.z_axis.extend(self.translation.z),
33        ]
34    }
35
36    #[inline]
37    fn inverse_transpose_3x3(self) -> ([Vec4; 2], f32) {
38        let inverse_transpose_3x3 = Affine3A::from(self).inverse().matrix3.transpose();
39        (
40            [
41                (inverse_transpose_3x3.x_axis, inverse_transpose_3x3.y_axis.x).into(),
42                (
43                    inverse_transpose_3x3.y_axis.yz(),
44                    inverse_transpose_3x3.z_axis.xy(),
45                )
46                    .into(),
47            ],
48            inverse_transpose_3x3.z_axis.z,
49        )
50    }
51}