plasma_prp/core/
transform.rs1use glam::{Mat4, Vec3};
9
10pub fn mat44_multiply(a: &[f32; 16], b: &[f32; 16]) -> [f32; 16] {
13 let ma = Mat4::from_cols_array(a).transpose();
15 let mb = Mat4::from_cols_array(b).transpose();
16 let result = ma * mb;
17 result.transpose().to_cols_array()
18}
19
20pub fn mat44_translation(m: &[f32; 16]) -> Vec3 {
23 Vec3::new(m[3], m[7], m[11])
24}
25
26pub fn mat44_identity() -> [f32; 16] {
28 [
29 1.0, 0.0, 0.0, 0.0,
30 0.0, 1.0, 0.0, 0.0,
31 0.0, 0.0, 1.0, 0.0,
32 0.0, 0.0, 0.0, 1.0,
33 ]
34}
35
36pub fn mat44_is_identity(m: &[f32; 16]) -> bool {
38 let id = mat44_identity();
39 m.iter()
40 .zip(id.iter())
41 .all(|(a, b)| (a - b).abs() < 1e-6)
42}
43
44pub fn mat44_transform_point(m: &[f32; 16], p: Vec3) -> Vec3 {
46 Vec3::new(
47 p.x * m[0] + p.y * m[1] + p.z * m[2] + m[3],
48 p.x * m[4] + p.y * m[5] + p.z * m[6] + m[7],
49 p.x * m[8] + p.y * m[9] + p.z * m[10] + m[11],
50 )
51}
52
53pub fn mat44_transform_direction(m: &[f32; 16], d: Vec3) -> Vec3 {
55 Vec3::new(
56 d.x * m[0] + d.y * m[1] + d.z * m[2],
57 d.x * m[4] + d.y * m[5] + d.z * m[6],
58 d.x * m[8] + d.y * m[9] + d.z * m[10],
59 )
60}
61
62pub fn propagate_transform(
67 parent_local_to_world: &[f32; 16],
68 child_local_to_parent: &[f32; 16],
69) -> [f32; 16] {
70 mat44_multiply(parent_local_to_world, child_local_to_parent)
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_identity() {
79 let id = mat44_identity();
80 assert!(mat44_is_identity(&id));
81 }
82
83 #[test]
84 fn test_transform_point() {
85 let m = [
88 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 2.0, 0.0, 0.0, 1.0, 3.0, 0.0, 0.0, 0.0, 1.0, ];
93 let p = Vec3::new(0.0, 0.0, 0.0);
94 let result = mat44_transform_point(&m, p);
95 assert!((result.x - 1.0).abs() < 0.01);
96 assert!((result.y - 2.0).abs() < 0.01);
97 assert!((result.z - 3.0).abs() < 0.01);
98 }
99
100 #[test]
101 fn test_propagate() {
102 let parent = [
104 1.0, 0.0, 0.0, 10.0, 0.0, 1.0, 0.0, 0.0,
106 0.0, 0.0, 1.0, 0.0,
107 0.0, 0.0, 0.0, 1.0,
108 ];
109 let child = [
110 1.0, 0.0, 0.0, 5.0, 0.0, 1.0, 0.0, 0.0,
112 0.0, 0.0, 1.0, 0.0,
113 0.0, 0.0, 0.0, 1.0,
114 ];
115 let result = propagate_transform(&parent, &child);
116 let pos = mat44_translation(&result);
117 assert!((pos.x - 15.0).abs() < 0.01);
118 }
119}