naev 0.11.5
mat4.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include "naev.h"
13#include <stdio.h>
14
15#include "mat4.h"
16
17void mat4_print( const mat4 *m )
18{
19 for (int i=0; i<4; i++) {
20 for (int j=0; j<4; j++)
21 printf("%6.1f ", m->m[j][i]);
22 printf("\n");
23 }
24}
25
35void mat4_mul( mat4 *out, const mat4 *m1, const mat4 *m2 )
36{
37 for (int i=0; i<4; i++) {
38 for (int j=0; j<4; j++) {
39 GLfloat v = 0.;
40 for (int k=0; k<4; k++)
41 v += m1->m[i][k] * m2->m[k][j];
42 out->m[i][j] = v;
43 }
44 }
45}
46
53void mat4_apply( mat4 *lhs, const mat4 *rhs )
54{
55 /* Process by rows. */
56 for (int i=0; i<4; i++) {
57 float l0 = lhs->m[i][0];
58 float l1 = lhs->m[i][1];
59 float l2 = lhs->m[i][2];
60
61 float r0 = l0 * rhs->m[0][0] + l1 * rhs->m[1][0] + l2 * rhs->m[2][0];
62 float r1 = l0 * rhs->m[0][1] + l1 * rhs->m[1][1] + l2 * rhs->m[2][1];
63 float r2 = l0 * rhs->m[0][2] + l1 * rhs->m[1][2] + l2 * rhs->m[2][2];
64
65 lhs->m[i][0] = r0;
66 lhs->m[i][1] = r1;
67 lhs->m[i][2] = r2;
68 }
69 lhs->m[3][0] += rhs->m[3][0];
70 lhs->m[3][1] += rhs->m[3][1];
71 lhs->m[3][2] += rhs->m[3][2];
72}
73
82void mat4_scale( mat4 *m, double x, double y, double z )
83{
84 for (int i=0; i<4; i++) {
85 m->m[0][i] *= x;
86 m->m[1][i] *= y;
87 m->m[2][i] *= z;
88 }
89}
90
99void mat4_translate( mat4 *m, double x, double y, double z )
100{
101 for (int i=0; i<4; i++)
102 m->m[3][i] += m->m[0][i] * x + m->m[1][i] * y + m->m[2][i] * z;
103}
104
111void mat4_rotate2d( mat4 *m, double angle )
112{
113 double c, s, x, y;
114
115 c = cos(angle);
116 s = sin(angle);
117 x = m->m[0][0];
118 y = m->m[1][0];
119 m->m[0][0] = c*x + s*y;
120 m->m[1][0] = -s*x + c*y;
121
122 x = m->m[0][1];
123 y = m->m[1][1];
124 m->m[0][1] = c*x + s*y;
125 m->m[1][1] = -s*x + c*y;
126}
127
135void mat4_rotate2dv( mat4 *m, double c, double s )
136{
137 double x, y;
138
139 x = m->m[0][0];
140 y = m->m[1][0];
141 m->m[0][0] = c*x + s*y;
142 m->m[1][0] = -s*x + c*y;
143
144 x = m->m[0][1];
145 y = m->m[1][1];
146 m->m[0][1] = c*x + s*y;
147 m->m[1][1] = -s*x + c*y;
148}
149
159void mat4_rotate( mat4 *m, double angle, double x, double y, double z )
160{
161 double norm, c, s;
162 mat4 R;
163
164 norm = sqrt( pow2(x) + pow2(y) + pow2(z) );
165 c = cos(angle);
166 s = sin(angle);
167 x /= norm;
168 y /= norm;
169 z /= norm;
170 R.m[0][0] = x*x*(1.-c) + c;
171 R.m[0][1] = y*x*(1.-c) + z*s;
172 R.m[0][2] = x*z*(1.-c) - y*s;
173 R.m[0][3] = 0.;
174 R.m[1][0] = x*y*(1.-c) - z*s;
175 R.m[1][1] = y*y*(1.-c) + c;
176 R.m[1][2] = y*z*(1.-c) + x*s;
177 R.m[1][3] = 0.;
178 R.m[2][0] = x*z*(1.-c) + y*s;
179 R.m[2][1] = y*z*(1.-c) - x*s;
180 R.m[2][2] = z*z*(1.-c) + c;
181 R.m[2][3] = 0.;
182 R.m[3][0] = 0.;
183 R.m[3][1] = 0.;
184 R.m[3][2] = 0.;
185 R.m[3][3] = 1.;
186
187 mat4_apply( m, &R );
188}
189
196{
197 const mat4 m = { .m = {
198 { 1., 0., 0., 0. },
199 { 0., 1., 0., 0. },
200 { 0., 0., 1., 0. },
201 { 0., 0., 0., 1. }
202 } };
203 return m;
204}
205
209mat4 mat4_ortho( double left, double right,
210 double bottom, double top, double nearVal, double farVal )
211{
212 mat4 mat = {{{{0}}}};
213 double tx, ty, tz;
214
215 /* https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml */
216 tx = -(right + left) / (right - left);
217 ty = -(top + bottom) / (top - bottom);
218 tz = -(farVal + nearVal) / (farVal - nearVal);
219
220 mat.m[0][0] = 2. / (right - left);
221 mat.m[1][1] = 2. / (top - bottom);
222 mat.m[2][2] = -2. / (farVal - nearVal);
223 mat.m[3][3] = 1.;
224 mat.m[3][0] = tx;
225 mat.m[3][1] = ty;
226 mat.m[3][2] = tz;
227
228 return mat;
229}
230
239mat4 mat4_lookat( const vec3 *eye, const vec3 *center, const vec3 *up )
240{
241 vec3 forward, side, upc;
242 mat4 H;
243
244 vec3_sub( &forward, center, eye );
245 vec3_normalize( &forward ); /* Points towards the center from the eye. */
246
247 /* side = forward x up */
248 vec3_cross( &side, &forward, up );
249 vec3_normalize( &side ); /* Points to the side. */
250
251 /* upc = side x forward */
252 vec3_cross( &upc, &side, &forward );
253 /* No need to normalize since forward and side and unitary. */
254
255 /* First column. */
256 H.m[0][0] = side.v[0];
257 H.m[0][1] = side.v[1];
258 H.m[0][2] = side.v[2];
259 H.m[0][3] = 0.;
260 /* Second column. */
261 H.m[1][0] = upc.v[0];
262 H.m[1][1] = upc.v[1];
263 H.m[1][2] = upc.v[2];
264 H.m[1][3] = 0.;
265 /* Third column. */
266 H.m[2][0] = -forward.v[0];
267 H.m[2][1] = -forward.v[1];
268 H.m[2][2] = -forward.v[2];
269 H.m[2][3] = 0.;
270 /* Fourth column. */
271 H.m[3][0] = -eye->v[0];
272 H.m[3][1] = -eye->v[1];
273 H.m[3][2] = -eye->v[2];
274 H.m[3][3] = 1.;
275
276 return H;
277}
278
288mat4 mat4_perspective( double fov, double aspect, double near, double far )
289{
290 mat4 H;
291 double c = 1. / tan( fov * 0.5 );
292 double d = far - near;
293
294 /* First column. */
295 H.m[0][0] = c / aspect;
296 H.m[0][1] = 0.;
297 H.m[0][2] = 0.;
298 H.m[0][3] = 0.;
299 /* Second column. */
300 H.m[1][0] = 0.;
301 H.m[1][1] = c;
302 H.m[1][2] = 0.;
303 H.m[1][3] = 0.;
304 /* Third column. */
305 H.m[2][0] = 0.;
306 H.m[2][1] = 0.;
307 H.m[2][2] = -(far+near) / d;
308 H.m[2][3] = -1.;
309 /* Fourth column. */
310 H.m[3][0] = 0.;
311 H.m[3][1] = 0.;
312 H.m[3][2] = -2.*far*near / d;
313 H.m[3][3] = 0.;
314
315 return H;
316}
void mat4_translate(mat4 *m, double x, double y, double z)
Translates a homogenous transformation matrix.
Definition mat4.c:99
void mat4_apply(mat4 *lhs, const mat4 *rhs)
Applies a transformation to another, storing the result in the left hand side.
Definition mat4.c:53
mat4 mat4_lookat(const vec3 *eye, const vec3 *center, const vec3 *up)
Creates a matrix with a transformation to look at a center point from an eye with an up vector.
Definition mat4.c:239
mat4 mat4_identity(void)
Creates an identity matrix.
Definition mat4.c:195
mat4 mat4_perspective(double fov, double aspect, double near, double far)
Creates a matrix with a perspective transformation.
Definition mat4.c:288
void mat4_rotate(mat4 *m, double angle, double x, double y, double z)
Multiplies the given matrix by a rotation. (Follows the right-hand rule.)
Definition mat4.c:159
void mat4_scale(mat4 *m, double x, double y, double z)
Scales a homogeneous transformation matrix.
Definition mat4.c:82
void mat4_mul(mat4 *out, const mat4 *m1, const mat4 *m2)
Multiplies two matrices (out = m1 * m2).
Definition mat4.c:35
mat4 mat4_ortho(double left, double right, double bottom, double top, double nearVal, double farVal)
Creates an orthographic projection matrix.
Definition mat4.c:209
void mat4_rotate2d(mat4 *m, double angle)
Rotates an angle, in radians, around the z axis.
Definition mat4.c:111
void mat4_rotate2dv(mat4 *m, double c, double s)
Rotates the +x axis to the given vector.
Definition mat4.c:135
Header file with generic functions and naev-specifics.
#define pow2(x)
Definition naev.h:46
static const double c[]
Definition rng.c:264
static const double d[]
Definition rng.c:273
Definition mat4.h:10
Definition vec3.h:6