spirv_std/
matrix.rs

1//! a set of common SPIR-V Matrices, used for intrinsics
2
3use glam::{Affine3A, Mat3, Mat3A, Mat4, Vec3, Vec3A};
4
5/// A Matrix with 4 columns of [`Vec3`], very similar to glam's [`Affine3A`].
6///
7/// Primarily used in ray tracing extensions to represent object rotation, scale and translation.
8#[derive(Clone, Copy, Default, PartialEq)]
9#[repr(C)]
10#[spirv(matrix)]
11#[allow(missing_docs)]
12pub struct Matrix4x3 {
13    pub x: Vec3A,
14    pub y: Vec3A,
15    pub z: Vec3A,
16    pub w: Vec3A,
17}
18
19/// The `from_*` fn signatures should match [`Affine3A`], to make it easier to switch to [`Affine3A`] later.
20/// The `to_*` fn signatures are custom
21impl Matrix4x3 {
22    /// Convert from glam's [`Affine3A`]
23    pub fn from_affine3a(affine: Affine3A) -> Self {
24        Self {
25            x: affine.x_axis,
26            y: affine.y_axis,
27            z: affine.z_axis,
28            w: affine.w_axis,
29        }
30    }
31
32    /// Creates an affine transform from a 3x3 matrix (expressing scale, shear and
33    /// rotation)
34    pub fn from_mat3(mat3: Mat3) -> Self {
35        Self::from_affine3a(Affine3A::from_mat3(mat3))
36    }
37
38    /// Creates an affine transform from a 3x3 matrix (expressing scale, shear and rotation)
39    /// and a translation vector.
40    ///
41    /// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_mat3(mat3)`
42    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
43        Self::from_affine3a(Affine3A::from_mat3_translation(mat3, translation))
44    }
45
46    /// The given `Mat4` must be an affine transform,
47    /// i.e. contain no perspective transform.
48    pub fn from_mat4(m: Mat4) -> Self {
49        Self::from_affine3a(Affine3A::from_mat4(m))
50    }
51
52    /// Convert to glam's [`Affine3A`]
53    pub fn to_affine3a(self) -> Affine3A {
54        Affine3A {
55            matrix3: Mat3A {
56                x_axis: self.x,
57                y_axis: self.y,
58                z_axis: self.z,
59            },
60            translation: self.w,
61        }
62    }
63
64    /// Creates a 3x3 matrix representing the rotation and scale, cutting off the translation
65    pub fn to_mat3a(self) -> Mat3A {
66        self.to_affine3a().matrix3
67    }
68
69    /// Creates a 3x3 matrix representing the rotation and scale, cutting off the translation
70    pub fn to_mat3(self) -> Mat3 {
71        Mat3::from(self.to_mat3a())
72    }
73
74    /// Creates a 4x4 matrix from this affine transform
75    pub fn to_mat4(self) -> Mat4 {
76        Mat4::from(self.to_affine3a())
77    }
78}