summaryrefslogtreecommitdiff
path: root/micro/mat4.c
blob: 804c204ed585843fc7329e273bb5dabe66c911dc (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
82
83
#include "mat4.h"

#include <string.h>
#include <math.h>

void mat4_identity(mat4 m)
{
        memset(m, 0, sizeof(mat4));
        m[0][0] = 1;
        m[1][1] = 1;
        m[2][2] = 1;
        m[3][3] = 1;
}

void mat4_translate(mat4 m, float x, float y)
{
        mat4_identity(m);
        m[0][3] = x;
        m[1][3] = y;
}

void mat4_scale(mat4 m, float x, float y)
{
        mat4_identity(m);
        m[0][0] = x;
        m[1][1] = y;
}

void mat4_ortho(
        mat4 m,
        float l, float r,
        float t, float b,
        float n, float f
)
{
        mat4_identity(m);

        m[0][0] = 2.0 / (r - l);
        m[1][1] = 2.0 / (t - b);
        m[2][2] = -2.0 / (f - n);
        m[0][3] = -(r + l) / (r - l);
        m[1][3] = -(t + b) / (t - b);
        m[2][3] = -(f + n) / (f - n);
}

void mat4_perspective(mat4 mat, float yfov, float a, float n, float f)
{
        memset(mat, 0, sizeof(mat4));

        // 1000
        // 0100
        // 0010
        // 0001
        //
        // 00 01 02 03
        // 10 11 12 13
        // 20 21 22 23
        // 30 31 32 33
        //
        // 0 4 8  12
        // 1 5 9  14
        // 2 6 10 15
        // 3 7 11 16

        float cotan = 1.0 / tanf(yfov * DEG2RAD * 0.5);
        mat[0][0] = cotan / a;
        mat[1][1] = cotan;
        mat[2][2] = (f + n) / (n - f);
        mat[3][2] = -1.0;
        mat[2][3] = 2.0 * n * f / (n - f);
}


void mat4_mult(mat4 dst, mat4 a, mat4 b)
{
        mat4 res;
        for (int r = 0; r < 4; r++)
                for (int c = 0; c < 4; c++)
                        for (int k = 0; k < 4; k++)
                                res[r][c] = a[r][k] * b[k][c];
        // memcpy after so that dst can be one of a or b
        memcpy(dst, res, sizeof(mat4));
}