batbox_la/mat/_4x4/
transform.rs

1use super::*;
2
3impl<T: Num + Copy> mat4<T> {
4    /// Construct a uniform scale matrix.
5    ///
6    /// # Examples
7    /// ```
8    /// # use batbox_la::*;
9    /// let matrix = mat4::scale_uniform(2);
10    /// assert_eq!(matrix * vec4(1, 2, 3, 1), vec4(2, 4, 6, 1));
11    /// ```
12    pub fn scale_uniform(factor: T) -> Self {
13        Self::scale(vec3(factor, factor, factor))
14    }
15
16    /// Construct a scale matrix.
17    ///
18    /// # Examples
19    /// ```
20    /// # use batbox_la::*;
21    /// let matrix = mat4::scale(vec3(1, 2, 3));
22    /// assert_eq!(matrix * vec4(1, 2, 3, 1), vec4(1, 4, 9, 1));
23    /// ```
24    pub fn scale(factor: vec3<T>) -> Self {
25        let mut result = Self::zero();
26        result[(0, 0)] = factor.x;
27        result[(1, 1)] = factor.y;
28        result[(2, 2)] = factor.z;
29        result[(3, 3)] = T::ONE;
30        result
31    }
32
33    /// Construct a translation matrix.
34    ///
35    /// # Examples
36    /// ```
37    /// # use batbox_la::*;
38    /// let matrix = mat4::translate(vec3(3, 2, 1));
39    /// assert_eq!(matrix * vec4(1, 2, 3, 1), vec4(4, 4, 4, 1));
40    /// ```
41    pub fn translate(dv: vec3<T>) -> Self {
42        let mut result = Self::identity();
43        result[(0, 3)] = dv.x;
44        result[(1, 3)] = dv.y;
45        result[(2, 3)] = dv.z;
46        result
47    }
48}
49
50impl<T: Float> mat4<T> {
51    /// Construct matrix rotating around x axis.
52    pub fn rotate_x(angle: Angle<T>) -> Self {
53        let mut result = Self::identity();
54        let (sin, cos) = angle.sin_cos();
55        result[(1, 1)] = cos;
56        result[(1, 2)] = -sin;
57        result[(2, 1)] = sin;
58        result[(2, 2)] = cos;
59        result
60    }
61
62    /// Construct matrix rotating around y axis.
63    pub fn rotate_y(angle: Angle<T>) -> Self {
64        let mut result = Self::identity();
65        let (sin, cos) = angle.sin_cos();
66        result[(2, 2)] = cos;
67        result[(2, 0)] = -sin;
68        result[(0, 2)] = sin;
69        result[(0, 0)] = cos;
70        result
71    }
72
73    /// Construct matrix rotating around z axis.
74    pub fn rotate_z(angle: Angle<T>) -> Self {
75        let mut result = Self::identity();
76        let (sin, cos) = angle.sin_cos();
77        result[(0, 0)] = cos;
78        result[(0, 1)] = -sin;
79        result[(1, 0)] = sin;
80        result[(1, 1)] = cos;
81        result
82    }
83
84    /// Construct a rotational matrix around given axis
85    pub fn rotate(v: vec3<T>, angle: Angle<T>) -> Self
86    where
87        T: SubAssign + AddAssign,
88    {
89        let cs = angle.cos();
90        let sn = angle.sin();
91        let mut res = Self::zero();
92        for i in 0..3 {
93            for j in 0..3 {
94                res[(i, j)] = v[i] * v[j] * (T::ONE - cs);
95            }
96        }
97        for i in 0..3 {
98            res[(i, i)] += cs;
99        }
100        res[(0, 1)] -= v.z * sn;
101        res[(0, 2)] += v.y * sn;
102        res[(1, 0)] += v.z * sn;
103        res[(1, 2)] -= v.x * sn;
104        res[(2, 0)] -= v.y * sn;
105        res[(2, 1)] += v.x * sn;
106        res[(3, 3)] = T::ONE;
107        res
108    }
109}