Added README
[gl4] / matrix.c
1 #include <string.h>
2 #include <math.h>
3 #include "matrix.h"
4
5 void mat_identity(float *mat)
6 {
7         memset(mat, 0, 16 * sizeof *mat);
8         mat[0] = mat[5] = mat[10] = mat[15] = 1.0f;
9 }
10
11 void mat_copy(float *dest, float *src)
12 {
13         memcpy(dest, src, 16 * sizeof *dest);
14 }
15
16 #define M(i,j)  (((i) << 2) + (j))
17 void mat_mul(float *res, float *m2)
18 {
19         int i, j;
20         float m1[16];
21
22         memcpy(m1, res, sizeof m1);
23
24         for(i=0; i<4; i++) {
25                 for(j=0; j<4; j++) {
26                         *res++ = m1[M(0,j)] * m2[M(i,0)] +
27                                 m1[M(1,j)] * m2[M(i,1)] +
28                                 m1[M(2,j)] * m2[M(i,2)] +
29                                 m1[M(3,j)] * m2[M(i,3)];
30                 }
31         }
32 }
33
34 void mat_translate(float *mat, float x, float y, float z)
35 {
36         float m[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
37         m[12] = x;
38         m[13] = y;
39         m[14] = z;
40         mat_mul(mat, m);
41 }
42
43 void mat_rotate(float *mat, float deg, float x, float y, float z)
44 {
45         float m[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
46
47         float angle = M_PI * deg / 180.0f;
48         float sina = sin(angle);
49         float cosa = cos(angle);
50         float one_minus_cosa = 1.0f - cosa;
51         float nxsq = x * x;
52         float nysq = y * y;
53         float nzsq = z * z;
54
55         m[0] = nxsq + (1.0f - nxsq) * cosa;
56         m[4] = x * y * one_minus_cosa - z * sina;
57         m[8] = x * z * one_minus_cosa + y * sina;
58         m[1] = x * y * one_minus_cosa + z * sina;
59         m[5] = nysq + (1.0 - nysq) * cosa;
60         m[9] = y * z * one_minus_cosa - x * sina;
61         m[2] = x * z * one_minus_cosa - y * sina;
62         m[6] = y * z * one_minus_cosa + x * sina;
63         m[10] = nzsq + (1.0 - nzsq) * cosa;
64         m[15] = 1.0f;
65
66         mat_mul(mat, m);
67 }
68
69 void mat_perspective(float *mat, float vfov_deg, float aspect, float znear, float zfar)
70 {
71         float m[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
72
73         float vfov = M_PI * vfov_deg / 180.0f;
74         float s = 1.0f / tan(vfov * 0.5f);
75         float range = znear - zfar;
76
77         m[0] = s / aspect;
78         m[5] = s;
79         m[10] = (znear + zfar) / range;
80         m[11] = -1.0f;
81         m[14] = 2.0f * znear * zfar / range;
82
83         mat_mul(mat, m);
84 }
85
86 void mat_transform(float *mat, float *vec)
87 {
88         float x = mat[0] * vec[0] + mat[4] * vec[1] + mat[8] * vec[2] + mat[12];
89         float y = mat[1] * vec[0] + mat[5] * vec[1] + mat[9] * vec[2] + mat[13];
90         float z = mat[2] * vec[0] + mat[6] * vec[1] + mat[10] * vec[2] + mat[14];
91
92         vec[0] = x;
93         vec[1] = y;
94         vec[2] = z;
95 }