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}