1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use super::*;
mod extra;
mod ops;
mod projection;
mod transform;
#[repr(C)]
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub struct Mat4<T>([[T; 4]; 4]);
impl<T> Mat4<T> {
pub fn map<U, F: Fn(T) -> U>(self, f: F) -> Mat4<U> {
fn map_arr<T, U, F: Fn(T) -> U>(arr: [T; 4], f: F) -> [U; 4] {
let [a, b, c, d] = arr;
[f(a), f(b), f(c), f(d)]
}
Mat4(map_arr(self.0, |row| map_arr(row, &f)))
}
}
impl<T: Copy> Mat4<T> {
pub fn new(values: [[T; 4]; 4]) -> Self {
Self { 0: values }.transpose()
}
pub fn row(&self, row_index: usize) -> Vec4<T> {
vec4(
self[(row_index, 0)],
self[(row_index, 1)],
self[(row_index, 2)],
self[(row_index, 3)],
)
}
}
impl<T> Index<(usize, usize)> for Mat4<T> {
type Output = T;
fn index(&self, (row, col): (usize, usize)) -> &T {
&self.0[col][row]
}
}
impl<T> IndexMut<(usize, usize)> for Mat4<T> {
fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut T {
&mut self.0[col][row]
}
}
impl<T> Mat4<T> {
pub fn as_flat_array(&self) -> &[T; 16] {
unsafe { mem::transmute(self) }
}
pub fn as_flat_array_mut(&mut self) -> &mut [T; 16] {
unsafe { mem::transmute(self) }
}
}
impl<T: Num + Copy> Mat4<T> {
pub fn zero() -> Self {
Mat4([[T::ZERO; 4]; 4])
}
pub fn identity() -> Self {
let mut result = Self::zero();
for i in 0..4 {
result[(i, i)] = T::ONE;
}
result
}
}
impl<T: Float> ApproxEq for Mat4<T> {
fn approx_distance_to(&self, other: &Self) -> f32 {
let mut dist = 0.0;
for i in 0..4 {
for j in 0..4 {
dist = partial_max(dist, (other[(i, j)] - self[(i, j)]).abs().as_f32());
}
}
dist
}
}