1    module matrix
2    
3    def perspective (near : f32
4                     far : f32
5                     aspect_ratio : f32
6                     field_of_view : f32) =
7        let t = field_of_view / 2 |> tan
8        let m11 = 1 / aspect_ratio / t
9        let m22 = -1 / t
10       let m33 = far / (far - near)
11       let m34 = near * far / (near - far)
12       let m43 = 1
13   
14       Matrix4 m11 0   0   0
15               0   m22 0   0
16               0   0   m33 m34
17               0   0   m43 0
18   
19   def orthographic (width : f32
20                     height : f32
21                     depth : f32) =
22       let m11 = 2 / width
23       let m22 = -2 / height
24       let m33 = 1 / depth
25   
26       Matrix4 m11 0   0   0
27               0   m22 0   0
28               0   0   m33 0
29               0   0   0   1
30   
31   def rotate_x (x : f32) = Matrix4 1 0     0      0
32                                    0 x.cos -x.sin 0
33                                    0 x.sin x.cos  0
34                                    0 0     0      1
35   
36   def rotate_y (y : f32) = Matrix4 y.cos  0 y.sin 0
37                                    0      1 0     0
38                                    -y.sin 0 y.cos 0
39                                    0      0 0     1
40   
41   def rotate_z (z : f32) = Matrix4 z.cos -z.sin 0 0
42                                    z.sin z.cos  0 0
43                                    0     0      1 0
44                                    0     0      0 1
45   
46   def translate (x : f32
47                  y : f32
48                  z : f32) =
49       Matrix4 1 0 0 x
50               0 1 0 y
51               0 0 1 z
52               0 0 0 1
53   
54   def view (position : Vector3<f32>
55             direction : Vector3<f32>
56             up : Vector3<f32>) =
57       let d = direction.normalized
58       let r = up.cross d |> normalized
59       let u = d.cross r
60   
61       let rotate = Matrix4 r.x u.x d.x position.x
62                            r.y u.y d.y position.y
63                            r.z u.z d.z position.z
64                            0   0   0   1
65   
66       rotate.inverse
67