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
|
#include "camera.h"
#include <math.h>
struct camera
create_default_camera(void)
{
struct camera camera = {0};
camera.fov = 90.0f;
camera.near = 0.1f;
camera.far = 1000.0f;
return camera;
}
mat
get_camera_view_mat(struct camera cam)
{
return rotate_mat(make_translate(invv3(cam.pos)), cam.angles);
}
void
get_camera_vectors(struct camera camera, v3 *l, v3 *u, v3 *f)
{
f32 angle = deg2rad(camera.angles.x);
f32 cp = cosf(angle);
f32 sp = sinf(angle);
angle = deg2rad(camera.angles.y);
f32 cy = cosf(angle);
f32 sy = sinf(angle);
angle = deg2rad(camera.angles.z);
f32 cr = cosf(angle);
f32 sr = sinf(angle);
*l = (v3){cy * cr, -cy * sr, sy};
*u = (v3){sp * sy * cr + cp * sr, -sp * sy * sr + cp * cr, -sp * cy};
*f = (v3){-cp * sy * cr + sp * sr, cp * sy * sr + sp * cr, cp * cy};
}
mat
camera_lookat(struct camera camera, v3 target, v3 worldy)
{
mat translate = make_translate(invv3(camera.pos));
v3 z = normv3(subv3(camera.pos, target));
v3 x = normv3(crossv3(worldy, z));
v3 y = crossv3(z, x);
mat rotate = transpose_mat(make_rotate(x, y, z));
mat result = mulmat(rotate, translate);
return result;
}
mat
ortho(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f)
{
mat ortho = mat_identity;
ortho.c0.x = 2.0f / (r - l);
ortho.c1.y = 2.0f / (t - b);
ortho.c2.z = -2.0f / (f - n);
ortho.c3.x = -(r + l) / (r - l);
ortho.c3.y = -(t + b) / (t - b);
ortho.c3.z = -(f + n) / (f - n);
return ortho;
}
mat
perspective(f32 near, f32 far, f32 fov, f32 aspect_ratio)
{
f32 r = near * tanf(deg2rad(fov / 2.0f));
f32 t = r / aspect_ratio;
mat res = mat_identity;
res.c0.x = near / r;
res.c1.y = near / t;
res.c2.z = -(far + near) / (far - near);
res.c2.w = -1.0f;
res.c3.z = (-2.0f * far * near) / (far - near);
res.c3.w = 0.0f;
return res;
}
mat
camera_perspective(struct camera camera, f32 aspect_ratio)
{
return perspective(camera.near, camera.far, camera.fov, aspect_ratio);
}
|