summaryrefslogtreecommitdiff
path: root/stage3/math3d.h
blob: 5d9c759ccfd17457d0638b98d5fa5b0361c08273 (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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#ifndef MATH3D_H
#define MATH3D_H

#include "math.h"

static inline void mat_id(float mat[4][4])
{
	for (int i = 0; i < 4; i++)
	for (int j = 0; j < 4; j++)
		mat[i][j] = i == j ? 1.0 : 0.0;
}

static inline void mat_translate(float mat[4][4], float vec[3])
{
	mat_id(mat);
	for (int i = 0; i < 3; i++)
		mat[3][i] = vec[i];
}

static inline void mat_scale(float mat[4][4], float vec[3])
{
	mat_id(mat);
	for (int i = 0; i < 3; i++)
		mat[i][i] = vec[i];
}

static inline void mat_rot_x(float mat[4][4], float a)
{
	mat_id(mat);
	mat[1][1] = cos(a); mat[2][1] = -sin(a);
	mat[1][2] = sin(a); mat[2][2] = cos(a);
}

static inline void mat_rot_y(float mat[4][4], float a)
{
	mat_id(mat);
	mat[0][0] = cos(a); mat[2][0] = sin(a);
	mat[0][2] = -sin(a); mat[2][2] = cos(a);
}

static inline void mat_rot_z(float mat[4][4], float a)
{
	mat_id(mat);
	mat[0][0] = cos(a); mat[1][0] = -sin(a);
	mat[0][1] = sin(a); mat[1][1] = cos(a);
}

static inline void mat_copy(float dst[4][4], float src[4][4])
{
	for (int i = 0; i < 4; i++)
	for (int j = 0; j < 4; j++)
		dst[i][j] = src[i][j];
}

static inline void mat_mul(float a[4][4], float b[4][4])
{
	float out[4][4];
	for (int i = 0; i < 4; i++)
	for (int j = 0; j < 4; j++) {
		out[i][j] = 0;
		for (int k = 0; k < 4; k++)
			out[i][j] += a[k][j] * b[i][k];
	}
	mat_copy(a, out);
}

static inline void vec_copy(float dst[4], float src[4])
{
	for (int i = 0; i < 4; i++)
		dst[i] = src[i];
}

static inline void mat_mul_vec(float mat[4][4], float vec[4])
{
	float out[4];

	for (int j = 0; j < 4; j++) {
		out[j] = 0;
		for (int k = 0; k < 4; k++)
			out[j] += mat[k][j] * vec[k];
	}

	vec_copy(vec, out);
}


static inline void mat_perspective(float mat[4][4], float fov, float aspect, float near, float far)
{
	float a = 1.0 / tan(fov / 2.0);

	mat_scale(mat, (float []) { a/aspect, a, -(far + near) / (far - near) });
	mat[2][3] = -1.0;
	mat[3][2] = -2.0 * far * near / (far - near);
	mat[3][3] = 0.0;
}

static inline float tri_area(float a[2], float b[2], float c[2])
{
	return (b[0] - a[0])*(c[1] - a[1]) - (b[1] - a[1])*(c[0] - a[0]);
}

#endif