5 #define M(r, c) ((r << 2) + c)
7 static const float idmat[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
9 void mat4_identity(float *m)
11 memcpy(m, idmat, sizeof idmat);
14 void mat4_copy(float *dest, float *src)
16 memcpy(dest, src, 16 * sizeof(float));
19 void mat4_mul(float *dest, float *a, float *b)
25 memcpy(tmp, a, sizeof tmp);
27 } else if(dest == b) {
28 memcpy(tmp, b, sizeof tmp);
34 dest[M(i, j)] = a[M(i, 0)] * b[M(0, j)] + a[M(i, 1)] * b[M(1, j)] +
35 a[M(i, 2)] * b[M(2, j)] + a[M(i, 3)] * b[M(3, j)];
41 void mat4_xform3(float *vdest, float *m, float *v)
43 float x = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12];
44 float y = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13];
45 vdest[2] = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14];
50 void mat4_xform4(float *vdest, float *m, float *v)
52 float x = m[0] * v[0] + m[4] * v[1] + m[8] * v[2] + m[12] * v[3];
53 float y = m[1] * v[0] + m[5] * v[1] + m[9] * v[2] + m[13] * v[3];
54 float z = m[2] * v[0] + m[6] * v[1] + m[10] * v[2] + m[14] * v[3];
55 vdest[3] = m[3] * v[0] + m[7] * v[1] + m[11] * v[2] + m[15] * v[3];
62 float *mat4_row(float *m, int row)
64 return m + (row << 2);
67 float mat4_elem(float *m, int row, int col)
69 return m[M(row, col)];
73 void mat4_upper3x3(float *m)
75 m[3] = m[7] = m[11] = m[12] = m[13] = m[14] = 0.0f;
86 void mat4_transpose(float *m)
96 float mat4_determinant(float *m)
98 float d11 = (m[M(1, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(2, 3)] * m[M(3, 2)])) -
99 (m[M(2, 1)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(1, 3)] * m[M(3, 2)])) +
100 (m[M(3, 1)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(1, 3)] * m[M(2, 2)]));
102 float d12 = (m[M(0, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(2, 3)] * m[M(3, 2)])) -
103 (m[M(2, 1)] * (m[M(0, 2)] * m[M(3, 3)] - m[M(0, 3)] * m[M(3, 2)])) +
104 (m[M(3, 1)] * (m[M(0, 2)] * m[M(2, 3)] - m[M(0, 3)] * m[M(2, 2)]));
106 float d13 = (m[M(0, 1)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(1, 3)] * m[M(3, 2)])) -
107 (m[M(1, 1)] * (m[M(0, 2)] * m[M(3, 3)] - m[M(0, 3)] * m[M(3, 2)])) +
108 (m[M(3, 1)] * (m[M(0, 2)] * m[M(1, 3)] - m[M(0, 3)] * m[M(1, 2)]));
110 float d14 = (m[M(0, 1)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(1, 3)] * m[M(2, 2)])) -
111 (m[M(1, 1)] * (m[M(0, 2)] * m[M(2, 3)] - m[M(0, 3)] * m[M(2, 2)])) +
112 (m[M(2, 1)] * (m[M(0, 2)] * m[M(1, 3)] - m[M(0, 3)] * m[M(1, 2)]));
114 return m[M(0, 0)] * d11 - m[M(1, 0)] * d12 + m[M(2, 0)] * d13 - m[M(3, 0)] * d14;
117 void mat4_adjoint(float *res, float *m)
122 cof[M(0, 0)] = (m[M(1, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(2, 3)] * m[M(3, 2)])) -
123 (m[M(2, 1)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(1, 3)] * m[M(3, 2)])) +
124 (m[M(3, 1)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(1, 3)] * m[M(2, 2)]));
125 cof[M(0, 1)] = (m[M(0, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(2, 3)] * m[M(3, 2)])) -
126 (m[M(2, 1)] * (m[M(0, 2)] * m[M(3, 3)] - m[M(0, 3)] * m[M(3, 2)])) +
127 (m[M(3, 1)] * (m[M(0, 2)] * m[M(2, 3)] - m[M(0, 3)] * m[M(2, 2)]));
128 cof[M(0, 2)] = (m[M(0, 1)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(1, 3)] * m[M(3, 2)])) -
129 (m[M(1, 1)] * (m[M(0, 2)] * m[M(3, 3)] - m[M(0, 3)] * m[M(3, 2)])) +
130 (m[M(3, 1)] * (m[M(0, 2)] * m[M(1, 3)] - m[M(0, 3)] * m[M(1, 2)]));
131 cof[M(0, 3)] = (m[M(0, 1)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(1, 3)] * m[M(2, 2)])) -
132 (m[M(1, 1)] * (m[M(0, 2)] * m[M(2, 3)] - m[M(0, 3)] * m[M(2, 2)])) +
133 (m[M(2, 1)] * (m[M(0, 2)] * m[M(1, 3)] - m[M(0, 3)] * m[M(1, 2)]));
135 cof[M(1, 0)] = (m[M(1, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(2, 3)] * m[M(3, 2)])) -
136 (m[M(2, 0)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(1, 3)] * m[M(3, 2)])) +
137 (m[M(3, 0)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(1, 3)] * m[M(2, 2)]));
138 cof[M(1, 1)] = (m[M(0, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(2, 3)] * m[M(3, 2)])) -
139 (m[M(2, 0)] * (m[M(0, 2)] * m[M(3, 3)] - m[M(0, 3)] * m[M(3, 2)])) +
140 (m[M(3, 0)] * (m[M(0, 2)] * m[M(2, 3)] - m[M(0, 3)] * m[M(2, 2)]));
141 cof[M(1, 2)] = (m[M(0, 0)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(1, 3)] * m[M(3, 2)])) -
142 (m[M(1, 0)] * (m[M(0, 2)] * m[M(3, 3)] - m[M(0, 3)] * m[M(3, 2)])) +
143 (m[M(3, 0)] * (m[M(0, 2)] * m[M(1, 3)] - m[M(0, 3)] * m[M(1, 2)]));
144 cof[M(1, 3)] = (m[M(0, 0)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(1, 3)] * m[M(2, 2)])) -
145 (m[M(1, 0)] * (m[M(0, 2)] * m[M(2, 3)] - m[M(0, 3)] * m[M(2, 2)])) +
146 (m[M(2, 0)] * (m[M(0, 2)] * m[M(1, 3)] - m[M(0, 3)] * m[M(1, 2)]));
148 cof[M(2, 0)] = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(2, 3)] * m[M(3, 1)])) -
149 (m[M(2, 0)] * (m[M(1, 1)] * m[M(3, 3)] - m[M(1, 3)] * m[M(3, 1)])) +
150 (m[M(3, 0)] * (m[M(1, 1)] * m[M(2, 3)] - m[M(1, 3)] * m[M(2, 1)]));
151 cof[M(2, 1)] = (m[M(0, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(2, 3)] * m[M(3, 1)])) -
152 (m[M(2, 0)] * (m[M(0, 1)] * m[M(3, 3)] - m[M(0, 3)] * m[M(3, 1)])) +
153 (m[M(3, 0)] * (m[M(0, 1)] * m[M(2, 3)] - m[M(0, 3)] * m[M(2, 1)]));
154 cof[M(2, 2)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(3, 3)] - m[M(1, 3)] * m[M(3, 1)])) -
155 (m[M(1, 0)] * (m[M(0, 1)] * m[M(3, 3)] - m[M(0, 3)] * m[M(3, 1)])) +
156 (m[M(3, 0)] * (m[M(0, 1)] * m[M(1, 3)] - m[M(0, 3)] * m[M(1, 1)]));
157 cof[M(2, 3)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(2, 3)] - m[M(1, 3)] * m[M(2, 1)])) -
158 (m[M(1, 0)] * (m[M(0, 1)] * m[M(2, 3)] - m[M(0, 3)] * m[M(2, 1)])) +
159 (m[M(2, 0)] * (m[M(0, 1)] * m[M(1, 3)] - m[M(0, 3)] * m[M(1, 1)]));
161 cof[M(3, 0)] = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(2, 2)] * m[M(3, 1)])) -
162 (m[M(2, 0)] * (m[M(1, 1)] * m[M(3, 2)] - m[M(1, 2)] * m[M(3, 1)])) +
163 (m[M(3, 0)] * (m[M(1, 1)] * m[M(2, 2)] - m[M(1, 2)] * m[M(2, 1)]));
164 cof[M(3, 1)] = (m[M(0, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(2, 2)] * m[M(3, 1)])) -
165 (m[M(2, 0)] * (m[M(0, 1)] * m[M(3, 2)] - m[M(0, 2)] * m[M(3, 1)])) +
166 (m[M(3, 0)] * (m[M(0, 1)] * m[M(2, 2)] - m[M(0, 2)] * m[M(2, 1)]));
167 cof[M(3, 2)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(3, 2)] - m[M(1, 2)] * m[M(3, 1)])) -
168 (m[M(1, 0)] * (m[M(0, 1)] * m[M(3, 2)] - m[M(0, 2)] * m[M(3, 1)])) +
169 (m[M(3, 0)] * (m[M(0, 1)] * m[M(1, 2)] - m[M(0, 2)] * m[M(1, 1)]));
170 cof[M(3, 3)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(2, 2)] - m[M(1, 2)] * m[M(2, 1)])) -
171 (m[M(1, 0)] * (m[M(0, 1)] * m[M(2, 2)] - m[M(0, 2)] * m[M(2, 1)])) +
172 (m[M(2, 0)] * (m[M(0, 1)] * m[M(1, 2)] - m[M(0, 2)] * m[M(1, 1)]));
176 float val = j % 2 ? -cof[M(j, i)] : cof[M(j, i)];
177 res[M(j, i)] = (i % 2) ? -val : val;
182 int mat4_inverse(float *m)
188 mat4_adjoint(adj, m);
189 det = mat4_determinant(m);
196 m[M(j, i)] = adj[M(j, i)] / det;
203 void mat4_translation(float *m, float x, float y, float z)
211 void mat4_rotation_x(float *m, float angle)
224 void mat4_rotation_y(float *m, float angle)
237 void mat4_rotation_z(float *m, float angle)
250 void mat4_rotation(float *m, float angle, float x, float y, float z)
252 float sa = sin(angle);
253 float ca = cos(angle);
254 float invca = 1.0f - ca;
260 m[0] = xsq + (1.0f - xsq) * ca;
261 m[4] = x * y * invca - z * sa;
262 m[8] = x * z * invca + y * sa;
264 m[1] = x * y * invca + z * sa;
265 m[5] = ysq + (1.0f - ysq) * ca;
266 m[9] = y * z * invca - x * sa;
268 m[2] = x * z * invca - y * sa;
269 m[6] = y * z * invca + x * sa;
270 m[10] = zsq + (1.0f - zsq) * ca;
273 void mat4_scaling(float *m, float sx, float sy, float sz)
282 void mat4_translate(float *m, float x, float y, float z)
285 mat4_translation(tmp, x, y, z);
289 void mat4_rotate_x(float *m, float angle)
292 mat4_rotation_x(tmp, angle);
296 void mat4_rotate_y(float *m, float angle)
299 mat4_rotation_y(tmp, angle);
303 void mat4_rotate_z(float *m, float angle)
306 mat4_rotation_z(tmp, angle);
310 void mat4_rotate(float *m, float angle, float x, float y, float z)
313 mat4_rotation(tmp, angle, x, y, z);
317 void mat4_scale(float *m, float sx, float sy, float sz)
320 mat4_scaling(tmp, sx, sy, sz);
325 void mat4_pre_translate(float *m, float x, float y, float z)
328 mat4_translation(tmp, x, y, z);
332 void mat4_pre_rotate_x(float *m, float angle)
335 mat4_rotation_x(tmp, angle);
339 void mat4_pre_rotate_y(float *m, float angle)
342 mat4_rotation_y(tmp, angle);
346 void mat4_pre_rotate_z(float *m, float angle)
349 mat4_rotation_z(tmp, angle);
353 void mat4_pre_rotate(float *m, float angle, float x, float y, float z)
356 mat4_rotation(tmp, angle, x, y, z);
360 void mat4_pre_scale(float *m, float sx, float sy, float sz)
363 mat4_scaling(tmp, sx, sy, sz);
367 static void normalize(float *v)
369 float len = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
371 float s = 1.0f / len;
378 static void cross(float *res, float *a, float *b)
380 res[0] = a[1] * b[2] - a[2] * b[1];
381 res[1] = a[2] * b[0] - a[0] * b[2];
382 res[2] = a[0] * b[1] - a[1] * b[0];
385 void mat4_lookat(float *m, float x, float y, float z, float tx, float ty, float tz, float ux, float uy, float uz)
388 float dir[3], right[3], up[3];
398 cross(right, dir, up);
401 cross(up, right, dir);
412 mat4_translate(m, x, y, z);
415 void mat4_inv_lookat(float *m, float x, float y, float z, float tx, float ty, float tz, float ux, float uy, float uz)
418 float dir[3], right[3], up[3];
428 cross(right, dir, up);
431 cross(up, right, dir);
437 m[i << 2] = right[i];
438 m[(i << 2) + 1] = up[i];
439 m[(i << 2) + 2] = -dir[i];
442 mat4_pre_translate(m, -x, -y, -z);
445 void mat4_ortho(float *m, float left, float right, float bottom, float top, float znear, float zfar)
447 float dx = right - left;
448 float dy = top - bottom;
449 float dz = zfar - znear;
455 m[12] = -(right + left) / dx;
456 m[13] = -(top + bottom) / dy;
457 m[14] = -(zfar + znear) / dz;
460 void mat4_frustum(float *m, float left, float right, float bottom, float top, float znear, float zfar)
462 float dx = right - left;
463 float dy = top - bottom;
464 float dz = zfar - znear;
466 memset(m, 0, 16 * sizeof *m);
467 m[0] = 2.0f * znear / dx;
468 m[5] = 2.0f * znear / dy;
469 m[8] = (right + left) / dx;
470 m[9] = (top + bottom) / dy;
471 m[10] = -(zfar + znear) / dz;
472 m[14] = -2.0f * zfar * znear / dz;
476 void mat4_perspective(float *m, float fov, float aspect, float znear, float zfar)
478 float s = 1.0f / tan(fov / 2.0f);
479 float range = znear - zfar;
481 memset(m, 0, 16 * sizeof *m);
484 m[10] = (znear + zfar) / range;
485 m[14] = 2.0f * znear * zfar / range;
490 void mat4_mirror(float *m, float a, float b, float c, float d)
492 m[0] = 1.0f - 2.0f * a * a;
493 m[5] = 1.0f - 2.0f * b * b;
494 m[10] = 1.0f - 2.0f * c * c;
497 m[1] = m[4] = -2.0f * a * b;
498 m[2] = m[8] = -2.0f * a * c;
499 m[6] = m[9] = -2.0f * b * c;
501 m[12] = -2.0f * a * d;
502 m[13] = -2.0f * b * d;
503 m[14] = -2.0f * c * d;
505 m[3] = m[7] = m[11] = 0.0f;
509 void mat4_print(float *m, FILE *fp)
514 fprintf(fp, "[ %4.4g %4.4g %4.4g %4.4g ]\n", m[0], m[1], m[2], m[3]);