summaryrefslogtreecommitdiff
path: root/camera.c
blob: f09d38cbf6f45cf3665b17556ebbe1cfb10056f8 (plain)
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);
}