v2 / vlib / gg / m4 / graphic.v
102 lines · 93 sloc · 2.78 KB · 757929392e0e7a75fc1272116460981e589737d5
Raw
1module m4
2
3/**********************************************************************
4* Simple vector/matrix graphic utility
5* Copyright (c) 2021 Dario Deledda. All rights reserved.
6* Use of this source code is governed by an MIT license
7* that can be found in the LICENSE file.
8**********************************************************************/
9import math
10
11// Translate degrees to radians
12@[inline]
13pub fn rad(deg f32) f32 {
14 return (math.pi / 180.0) * deg
15}
16
17// Translate radians to degrees
18@[inline]
19pub fn deg(grad f32) f32 {
20 return (180.0 / math.pi) * grad
21}
22
23// calculate the Orthographic projection matrix
24pub fn ortho(left f32, right f32, bottom f32, top f32, z_near f32, z_far f32) Mat4 {
25 rml := right - left
26 rpl := right + left
27 tmb := top - bottom
28 tpb := top + bottom
29 fmn := z_far - z_near
30 fpn := z_far + z_near
31 // vfmt off
32 if fmn != 0 {
33 return Mat4{
34 e: [
35 2 / rml, 0, 0, -(rpl / rml),
36 0 , 2 / tmb, 0, -(tpb / tmb),
37 0 , 0, 2 / fmn, -(fpn / fmn),
38 0 , 0, 0, 1,
39 ]!
40 }
41 }
42 return Mat4{
43 e: [
44 2 / rml, 0, 0, -(rpl / rml),
45 0, 2 / tmb, 0, -(tpb / tmb),
46 0, 0, 0, 0,
47 0, 0, 0, 1,
48 ]!
49 }
50 // vfmt on
51}
52
53// Calculate the perspective matrix using (fov:fov, ar:aspect_ratio ,n:near_pane, f:far_plane) as parameters
54pub fn perspective(fov f32, ar f32, n f32, f f32) Mat4 {
55 ctan := f32(1.0 / math.tan(fov * (f32(math.pi) / 360.0))) // for the FOV we use 360 instead 180
56 // vfmt off
57 return Mat4{
58 e: [
59 ctan / ar, 0, 0, 0,
60 0, ctan, 0, 0,
61 0, 0, (n + f) / (n - f), -1.0,
62 0, 0, (2.0 * n * f) / (n - f), 0,
63 ]!
64 }
65 // vfmt on
66}
67
68// Calculate the look-at matrix
69pub fn look_at(eye Vec4, center Vec4, up Vec4) Mat4 {
70 f := (center - eye).normalize3()
71 s := (f % up).normalize3()
72 u := (s % f)
73 // vfmt off
74 return Mat4{e: [
75 s.e[0], u.e[0], -f.e[0], 0,
76 s.e[1], u.e[1], -f.e[1], 0,
77 s.e[2], u.e[2], -f.e[2], 0,
78 -(s * eye), -(u * eye), f * eye, 1,
79 ]!}
80 // vfmt on
81}
82
83// Get the complete transformation matrix for GLSL demos
84pub fn calc_tr_matrices(w f32, h f32, rx f32, ry f32, in_scale f32) Mat4 {
85 proj := perspective(60, w / h, 0.01, 10.0)
86 // vfmt off
87 view := look_at(
88 Vec4{ e: [f32(0.0), 1.5, 6, 0]! },
89 Vec4{ e: [f32(0), 0, 0, 0]!},
90 Vec4{ e: [f32(0), 1.0, 0, 0]!}
91 )
92 view_proj := view * proj
93
94 rxm := rotate(rad(rx), Vec4{ e: [f32(1), 0, 0, 0]! })
95 rym := rotate(rad(ry), Vec4{ e: [f32(0), 1, 0, 0]! })
96 scale_m := scale(Vec4{ e: [in_scale, in_scale, in_scale, 1]! })
97 // vfmt on
98
99 model := rym * rxm
100 res := (scale_m * model) * view_proj
101 return res
102}
103