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
use super::*;
impl<T: Num + Copy> mat4<T> {
/// Construct a uniform scale matrix.
///
/// # Examples
/// ```
/// # use batbox_la::*;
/// let matrix = mat4::scale_uniform(2);
/// assert_eq!(matrix * vec4(1, 2, 3, 1), vec4(2, 4, 6, 1));
/// ```
pub fn scale_uniform(factor: T) -> Self {
Self::scale(vec3(factor, factor, factor))
}
/// Construct a scale matrix.
///
/// # Examples
/// ```
/// # use batbox_la::*;
/// let matrix = mat4::scale(vec3(1, 2, 3));
/// assert_eq!(matrix * vec4(1, 2, 3, 1), vec4(1, 4, 9, 1));
/// ```
pub fn scale(factor: vec3<T>) -> Self {
let mut result = Self::zero();
result[(0, 0)] = factor.x;
result[(1, 1)] = factor.y;
result[(2, 2)] = factor.z;
result[(3, 3)] = T::ONE;
result
}
/// Construct a translation matrix.
///
/// # Examples
/// ```
/// # use batbox_la::*;
/// let matrix = mat4::translate(vec3(3, 2, 1));
/// assert_eq!(matrix * vec4(1, 2, 3, 1), vec4(4, 4, 4, 1));
/// ```
pub fn translate(dv: vec3<T>) -> Self {
let mut result = Self::identity();
result[(0, 3)] = dv.x;
result[(1, 3)] = dv.y;
result[(2, 3)] = dv.z;
result
}
}
impl<T: Float> mat4<T> {
/// Construct matrix rotating around x axis.
pub fn rotate_x(angle: Angle<T>) -> Self {
let mut result = Self::identity();
let (sin, cos) = angle.sin_cos();
result[(1, 1)] = cos;
result[(1, 2)] = -sin;
result[(2, 1)] = sin;
result[(2, 2)] = cos;
result
}
/// Construct matrix rotating around y axis.
pub fn rotate_y(angle: Angle<T>) -> Self {
let mut result = Self::identity();
let (sin, cos) = angle.sin_cos();
result[(2, 2)] = cos;
result[(2, 0)] = -sin;
result[(0, 2)] = sin;
result[(0, 0)] = cos;
result
}
/// Construct matrix rotating around z axis.
pub fn rotate_z(angle: Angle<T>) -> Self {
let mut result = Self::identity();
let (sin, cos) = angle.sin_cos();
result[(0, 0)] = cos;
result[(0, 1)] = -sin;
result[(1, 0)] = sin;
result[(1, 1)] = cos;
result
}
/// Construct a rotational matrix around given axis
pub fn rotate(v: vec3<T>, angle: Angle<T>) -> Self
where
T: SubAssign + AddAssign,
{
let cs = angle.cos();
let sn = angle.sin();
let mut res = Self::zero();
for i in 0..3 {
for j in 0..3 {
res[(i, j)] = v[i] * v[j] * (T::ONE - cs);
}
}
for i in 0..3 {
res[(i, i)] += cs;
}
res[(0, 1)] -= v.z * sn;
res[(0, 2)] += v.y * sn;
res[(1, 0)] += v.z * sn;
res[(1, 2)] -= v.x * sn;
res[(2, 0)] -= v.y * sn;
res[(2, 1)] += v.x * sn;
res[(3, 3)] = T::ONE;
res
}
}