summaryrefslogtreecommitdiff
path: root/src/util/matrix.h
blob: 6657323b6f56451bf9c7983d8364e3fe9cfcc1d4 (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
#pragma once
#include "typedef.h"
#include "vector.h"

typedef struct {
  F32 m[4][4];
} MAT4;

inline void mat4_identity( MAT4* out ) {
  for( I32 i = 0; i < 16; i++ ) {
    out->m[0][i] = (i % 5 == 0) ? 1.0f : 0.0f;
  }
}

inline void mat4_mul( MAT4* a, MAT4* b, MAT4* out ) {
  for( I32 row = 0; row < 4; row++ ) {
    for( I32 col = 0; col < 4; col++ ) {
      out->m[row][col] = 0.0f;
      for( I32 k = 0; k < 4; k++ ) {
        out->m[row][col] += a->m[row][k] * b->m[k][col];
      }
    }
  }
}

inline void mat4_mul_vec4( MAT4 *m, VEC4 *in, VEC4 *out ) {
  out->x = m->m[0][0] * in->x + m->m[0][1] * in->y + m->m[0][2] * in->z + m->m[0][3] * in->w;
  out->y = m->m[1][0] * in->x + m->m[1][1] * in->y + m->m[1][2] * in->z + m->m[1][3] * in->w;
  out->z = m->m[2][0] * in->x + m->m[2][1] * in->y + m->m[2][2] * in->z + m->m[2][3] * in->w;
  out->w = m->m[3][0] * in->x + m->m[3][1] * in->y + m->m[3][2] * in->z + m->m[3][3] * in->w;
}

inline void mat4_perspective( MAT4* out, F32 fovy_radians, F32 aspect, F32 znear, F32 zfar ) {
  mat4_identity( out );
  F32 f = 1.f / tanf( fovy_radians * .5f );

  out->m[0][0] = f / aspect;
  out->m[1][1] = f;
  out->m[2][2] = (zfar + znear) / (znear - zfar);
  out->m[2][3] = (2.f * zfar * znear) / (znear - zfar);
  out->m[3][2] = -1.f;
  out->m[3][3] = 0.f;
}

inline void mat4_translation( MAT4* out, F32 tx, F32 ty, F32 tz ) {
  mat4_identity( out );
  out->m[0][3] = tx;
  out->m[1][3] = ty;
  out->m[2][3] = tz;
}

inline void mat4_rotation_x( MAT4* out, F32 angle ) {
  mat4_identity( out );
  F32 c = cosf( angle );
  F32 s = sinf( angle );
  out->m[1][1] = c;
  out->m[1][2] = -s;
  out->m[2][1] = s;
  out->m[2][2] = c;
}

inline void mat4_rotation_y( MAT4* out, F32 angle ) {
  mat4_identity( out );
  F32 c = cosf( angle );
  F32 s = sinf( angle );
  out->m[0][0] = c;
  out->m[0][2] = -s;
  out->m[2][0] = s;
  out->m[2][2] = c;
}

inline void mat4_rotation_z( MAT4* out, F32 angle ) {
  mat4_identity( out );
  F32 c = cosf( angle );
  F32 s = sinf( angle );
  out->m[0][0] = c;
  out->m[0][1] = -s;
  out->m[1][0] = s;
  out->m[1][1] = c;
}