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
use super::*;

impl<T: Float> Mat4<T> {
    /// Construct prespective projection matrix.
    pub fn perspective(fov: T, aspect: T, near: T, far: T) -> Self {
        let ymax = near * (fov / (T::ONE + T::ONE)).tan();
        let xmax = ymax * aspect;
        Self::frustum(-xmax, xmax, -ymax, ymax, near, far)
    }

    /// Construct frustum projection matrix.
    pub fn frustum(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Self {
        let double_near = near + near;
        let width = right - left;
        let height = top - bottom;
        let depth = far - near;
        Mat4::new([
            [
                double_near / width,
                T::ZERO,
                (right + left) / width,
                T::ZERO,
            ],
            [
                T::ZERO,
                double_near / height,
                (top + bottom) / height,
                T::ZERO,
            ],
            [
                T::ZERO,
                T::ZERO,
                (-far - near) / depth,
                (-double_near * far) / depth,
            ],
            [T::ZERO, T::ZERO, -T::ONE, T::ZERO],
        ])
    }
}