Banjo API 0.0.1
C99 game development API
Loading...
Searching...
No Matches
mat.h
Go to the documentation of this file.
1
17#ifndef BJ_MAT_H
18#define BJ_MAT_H
19
20#include <banjo/api.h>
21#include <banjo/math.h>
22#include <banjo/vec.h>
23
28typedef bj_vec3 bj_mat3x3[3];
29
34
39typedef bj_vec2 bj_mat3x2[3];
40
45typedef bj_vec4 bj_mat4x4[4];
46
51
56typedef bj_vec3 bj_mat4x3[4];
57
63 for (int i = 0; i < 3; ++i)
64 for (int j = 0; j < 3; ++j)
65 m[i][j] = (i == j) ? BJ_F(1.0) : BJ_FZERO;
66}
67
73static BJ_INLINE void bj_mat3_copy(bj_mat3x3 to, const bj_mat3x3 from) {
74 for (int i = 0; i < 3; ++i) {
75 to[i][0] = from[i][0];
76 to[i][1] = from[i][1];
77 to[i][2] = from[i][2];
78 }
79}
80
87static BJ_INLINE void bj_mat3_row(bj_vec3 res, const bj_mat3x3 m, int r) {
88 for (int k = 0; k < 3; ++k) res[k] = m[k][r];
89}
90
97static BJ_INLINE void bj_mat3_col(bj_vec3 res, const bj_mat3x3 m, int c) {
98 for (int k = 0; k < 3; ++k) res[k] = m[c][k];
99}
100
107 for (int j = 0; j < 3; ++j)
108 for (int i = 0; i < 3; ++i)
109 res[i][j] = m[j][i];
110}
111
115static BJ_INLINE void bj_mat3_add(bj_mat3x3 res, const bj_mat3x3 a, const bj_mat3x3 b) {
116 for (int i = 0; i < 3; ++i) {
117 res[i][0] = a[i][0] + b[i][0];
118 res[i][1] = a[i][1] + b[i][1];
119 res[i][2] = a[i][2] + b[i][2];
120 }
121}
122
126static BJ_INLINE void bj_mat3_sub(bj_mat3x3 res, const bj_mat3x3 a, const bj_mat3x3 b) {
127 for (int i = 0; i < 3; ++i) {
128 res[i][0] = a[i][0] - b[i][0];
129 res[i][1] = a[i][1] - b[i][1];
130 res[i][2] = a[i][2] - b[i][2];
131 }
132}
133
137static BJ_INLINE void bj_mat3_scale(bj_mat3x3 res, const bj_mat3x3 m, bj_real k) {
138 for (int i = 0; i < 3; ++i) {
139 res[i][0] = m[i][0] * k;
140 res[i][1] = m[i][1] * k;
141 res[i][2] = m[i][2] * k;
142 }
143}
144
150 BJ_ARRAY_2D (bj_real, 3, 3, res),
151 BJ_CONST_ARRAY_2D(bj_real, 3, 3, lhs),
152 BJ_CONST_ARRAY_2D(bj_real, 3, 3, rhs)
153) {
154#ifdef BJ_MAT_NO_UNROLL
155 bj_mat3 tmp;
156 for (int c = 0; c < 3; ++c) {
157 for (int r = 0; r < 3; ++r) {
158 tmp[c][r] = BJ_FZERO;
159 for (int k = 0; k < 3; ++k)
160 tmp[c][r] += lhs[k][r] * rhs[c][k];
161 }
162 }
163 bj_mat3_copy(res, tmp);
164#else
165 const bj_real a0 = lhs[0][0], b0 = lhs[1][0], c0 = lhs[2][0];
166 const bj_real a1 = lhs[0][1], b1 = lhs[1][1], c1 = lhs[2][1];
167 const bj_real a2 = lhs[0][2], b2 = lhs[1][2], c2 = lhs[2][2];
168
169 { const bj_real r0 = rhs[0][0], r1 = rhs[0][1], r2 = rhs[0][2];
170 res[0][0] = a0*r0 + b0*r1 + c0*r2;
171 res[0][1] = a1*r0 + b1*r1 + c1*r2;
172 res[0][2] = a2*r0 + b2*r1 + c2*r2; }
173 { const bj_real r0 = rhs[1][0], r1 = rhs[1][1], r2 = rhs[1][2];
174 res[1][0] = a0*r0 + b0*r1 + c0*r2;
175 res[1][1] = a1*r0 + b1*r1 + c1*r2;
176 res[1][2] = a2*r0 + b2*r1 + c2*r2; }
177 { const bj_real r0 = rhs[2][0], r1 = rhs[2][1], r2 = rhs[2][2];
178 res[2][0] = a0*r0 + b0*r1 + c0*r2;
179 res[2][1] = a1*r0 + b1*r1 + c1*r2;
180 res[2][2] = a2*r0 + b2*r1 + c2*r2; }
181#endif
182}
183
189 BJ_ARRAY (bj_real, 3, res),
190 BJ_CONST_ARRAY_2D(bj_real, 3, 3, m),
192) {
193#ifdef BJ_MAT_NO_UNROLL
194 for (int j = 0; j < 3; ++j) {
195 res[j] = BJ_FZERO;
196 for (int i = 0; i < 3; ++i)
197 res[j] += m[i][j] * v[i];
198 }
199#else
200 const bj_real vx = v[0], vy = v[1], vz = v[2];
201 res[0] = m[0][0]*vx + m[1][0]*vy + m[2][0]*vz;
202 res[1] = m[0][1]*vx + m[1][1]*vy + m[2][1]*vz;
203 res[2] = m[0][2]*vx + m[1][2]*vy + m[2][2]*vz;
204#endif
205}
206
211static BJ_INLINE void bj_mat3_mul_point(bj_vec2 res, const bj_mat3x3 m, const bj_vec2 p) {
212 bj_vec3 v = { p[0], p[1], BJ_F(1.0) };
213 bj_vec3 o;
214 bj_mat3_mul_vec3(o, m, v);
215 bj_real w = o[2];
216 if (w != BJ_FZERO) { res[0] = o[0] / w; res[1] = o[1] / w; }
217 else { res[0] = o[0]; res[1] = o[1]; }
218}
219
224static BJ_INLINE void bj_mat3_mul_vector2(bj_vec2 res, const bj_mat3x3 m, const bj_vec2 v2) {
225 bj_vec3 v = { v2[0], v2[1], BJ_FZERO };
226 bj_vec3 o; bj_mat3_mul_vec3(o, m, v);
227 res[0] = o[0]; res[1] = o[1];
228}
229
234 bj_mat3_identity(res);
235 res[2][0] = tx;
236 res[2][1] = ty;
237}
238
243 bj_vec3 t = { tx, ty, BJ_FZERO };
244 bj_vec3 r;
245 for (int i = 0; i < 3; ++i) {
246 bj_mat3_row(r, M, i);
247 M[2][i] += r[0]*t[0] + r[1]*t[1] + r[2]*t[2];
248 }
249}
250
255 bj_mat3_identity(res);
256 res[0][0] = sx;
257 res[1][1] = sy;
258}
259
263static BJ_INLINE void bj_mat3_shear(bj_mat3x3 res, bj_real shx, bj_real shy) {
264 bj_mat3_identity(res);
265 res[1][0] = shy;
266 res[0][1] = shx;
267}
268
272static BJ_INLINE void bj_mat3_rotate(bj_mat3x3 res, bj_real angle) {
273 bj_real s = bj_sin(angle), c = bj_cos(angle);
274 res[0][0] = c; res[0][1] = s; res[0][2] = BJ_FZERO;
275 res[1][0] = -s; res[1][1] = c; res[1][2] = BJ_FZERO;
276 res[2][0] = BJ_FZERO; res[2][1] = BJ_FZERO; res[2][2] = BJ_F(1.0);
277}
278
282static BJ_INLINE void bj_mat3_inverse(bj_mat3x3 res, const bj_mat3x3 m) {
283 bj_real a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
284 bj_real a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
285 bj_real a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
286
287 bj_real b01 = a22*a11 - a12*a21;
288 bj_real b11 = -a22*a10 + a12*a20;
289 bj_real b21 = a21*a10 - a11*a20;
290
291 bj_real det = a00*b01 + a01*b11 + a02*b21;
292 bj_real inv_det = BJ_F(1.0) / det;
293
294 res[0][0] = b01 * inv_det;
295 res[0][1] = (-a22*a01 + a02*a21) * inv_det;
296 res[0][2] = ( a12*a01 - a02*a11) * inv_det;
297
298 res[1][0] = b11 * inv_det;
299 res[1][1] = ( a22*a00 - a02*a20) * inv_det;
300 res[1][2] = (-a12*a00 + a02*a10) * inv_det;
301
302 res[2][0] = b21 * inv_det;
303 res[2][1] = (-a21*a00 + a01*a20) * inv_det;
304 res[2][2] = ( a11*a00 - a01*a10) * inv_det;
305}
306
311 BJ_ARRAY_2D(bj_real, 3, 3, omat),
312 bj_real l, bj_real r,
313 bj_real b, bj_real t
314) {
315 omat[0][0] = BJ_F(2.0) / (r - l);
316 omat[0][1] = BJ_FZERO;
317 omat[0][2] = BJ_FZERO;
318
319 omat[1][0] = BJ_FZERO;
320 omat[1][1] = BJ_F(-2.0) / (t - b);
321 omat[1][2] = BJ_FZERO;
322
323 omat[2][0] = -(r + l) / (r - l);
324 omat[2][1] = (t + b) / (t - b);
325 omat[2][2] = BJ_F(1.0);
326}
327
332 BJ_ARRAY_2D(bj_real, 3, 3, vpmat),
333 bj_real x, bj_real y,
334 bj_real w, bj_real h
335) {
336 vpmat[0][0] = BJ_F(0.5) * w; vpmat[0][1] = BJ_FZERO; vpmat[0][2] = BJ_FZERO;
337 vpmat[1][0] = BJ_FZERO; vpmat[1][1] = BJ_F(0.5) * h; vpmat[1][2] = BJ_FZERO;
338 vpmat[2][0] = x + BJ_F(0.5) * w;
339 vpmat[2][1] = y + BJ_F(0.5) * h;
340 vpmat[2][2] = BJ_F(1.0);
341}
342
347 BJ_ARRAY_2D(bj_real, 3, 2, m)
348) {
349 m[0][0]=BJ_F(1.0); m[0][1]=BJ_FZERO;
350 m[1][0]=BJ_FZERO; m[1][1]=BJ_F(1.0);
351 m[2][0]=BJ_FZERO; m[2][1]=BJ_FZERO;
352}
353
358 BJ_ARRAY_2D(bj_real, 3, 2, m), bj_real tx, bj_real ty
359) {
360 m[0][0]=BJ_F(1.0); m[0][1]=BJ_FZERO;
361 m[1][0]=BJ_FZERO; m[1][1]=BJ_F(1.0);
362 m[2][0]=tx; m[2][1]=ty;
363}
364
369 BJ_ARRAY_2D(bj_real, 3, 2, m), bj_real sx, bj_real sy
370) {
371 m[0][0]=sx; m[0][1]=BJ_FZERO;
372 m[1][0]=BJ_FZERO; m[1][1]=sy;
373 m[2][0]=BJ_FZERO; m[2][1]=BJ_FZERO;
374}
375
380 BJ_ARRAY_2D(bj_real, 3, 2, m), bj_real angle
381) {
382 const bj_real c = bj_cosf(angle), s = bj_sinf(angle);
383 m[0][0]= c; m[0][1]= s;
384 m[1][0]=-s; m[1][1]= c;
385 m[2][0]=BJ_FZERO; m[2][1]=BJ_FZERO;
386}
387
392 BJ_ARRAY_2D (bj_real, 3, 2, res),
393 BJ_CONST_ARRAY_2D(bj_real, 3, 2, A),
394 BJ_CONST_ARRAY_2D(bj_real, 3, 2, B)
395) {
396#ifdef BJ_MAT_NO_UNROLL
397 res[0][0] = A[0][0]*B[0][0] + A[1][0]*B[1][0];
398 res[0][1] = A[0][1]*B[0][0] + A[1][1]*B[1][0];
399
400 res[1][0] = A[0][0]*B[0][1] + A[1][0]*B[1][1];
401 res[1][1] = A[0][1]*B[0][1] + A[1][1]*B[1][1];
402
403 res[2][0] = A[0][0]*B[2][0] + A[1][0]*B[2][1] + A[2][0];
404 res[2][1] = A[0][1]*B[2][0] + A[1][1]*B[2][1] + A[2][1];
405#else
406 const bj_real a00=A[0][0], a10=A[0][1];
407 const bj_real a01=A[1][0], a11=A[1][1];
408 const bj_real a02=A[2][0], a12=A[2][1];
409
410 const bj_real b00=B[0][0], b10=B[0][1];
411 const bj_real b01=B[1][0], b11=B[1][1];
412 const bj_real b02=B[2][0], b12=B[2][1];
413
414 res[0][0] = a00*b00 + a01*b10; res[0][1] = a10*b00 + a11*b10;
415 res[1][0] = a00*b01 + a01*b11; res[1][1] = a10*b01 + a11*b11;
416 res[2][0] = a00*b02 + a01*b12 + a02;
417 res[2][1] = a10*b02 + a11*b12 + a12;
418#endif
419}
420
425 BJ_ARRAY (bj_real, 2, r),
426 BJ_CONST_ARRAY_2D(bj_real, 3, 2, m),
428) {
429 const bj_real x=p[0], y=p[1];
430 r[0] = m[0][0]*x + m[1][0]*y + m[2][0];
431 r[1] = m[0][1]*x + m[1][1]*y + m[2][1];
432}
433
438 BJ_ARRAY (bj_real, 2, r),
439 BJ_CONST_ARRAY_2D(bj_real, 3, 2, m),
441) {
442 const bj_real x=v[0], y=v[1];
443 r[0] = m[0][0]*x + m[1][0]*y;
444 r[1] = m[0][1]*x + m[1][1]*y;
445}
446
451 BJ_ARRAY_2D (bj_real, 3, 3, out3x3),
452 BJ_CONST_ARRAY_2D(bj_real, 3, 2, a)
453) {
454 out3x3[0][0]=a[0][0]; out3x3[0][1]=a[0][1]; out3x3[0][2]=BJ_FZERO;
455 out3x3[1][0]=a[1][0]; out3x3[1][1]=a[1][1]; out3x3[1][2]=BJ_FZERO;
456 out3x3[2][0]=a[2][0]; out3x3[2][1]=a[2][1]; out3x3[2][2]=BJ_F(1.0);
457}
458
463 BJ_ARRAY_2D (bj_real, 3, 2, out3x2),
464 BJ_CONST_ARRAY_2D(bj_real, 3, 3, m)
465) {
466 out3x2[0][0]=m[0][0]; out3x2[0][1]=m[0][1];
467 out3x2[1][0]=m[1][0]; out3x2[1][1]=m[1][1];
468 out3x2[2][0]=m[2][0]; out3x2[2][1]=m[2][1];
469}
470
475{
476 for (int i = 0; i < 4; ++i)
477 for (int j = 0; j < 4; ++j)
478 mat[i][j] = i == j ? BJ_F(1.0) : BJ_FZERO;
479}
480
484static BJ_INLINE void bj_mat4_copy(bj_mat4x4 to, const bj_mat4x4 from)
485{
486 for (int i = 0; i < 4; ++i) bj_vec4_copy(to[i], from[i]);
487}
488
492static BJ_INLINE void bj_mat4_row(bj_vec4 res, const bj_mat4x4 mat, int r)
493{
494 for (int k = 0; k < 4; ++k) res[k] = mat[k][r];
495}
496
500static BJ_INLINE void bj_mat4_col(bj_vec4 res, const bj_mat4x4 mat, int c)
501{
502 for (int k = 0; k < 4; ++k) res[k] = mat[c][k];
503}
504
509{
510 for (int j = 0; j < 4; ++j)
511 for (int i = 0; i < 4; ++i)
512 res[i][j] = mat[j][i];
513}
514
518static BJ_INLINE void bj_mat4_add(bj_mat4x4 res, const bj_mat4x4 lhs, const bj_mat4x4 rhs)
519{
520 for (int i = 0; i < 4; ++i) bj_vec4_add(res[i], lhs[i], rhs[i]);
521}
522
526static BJ_INLINE void bj_mat4_sub(bj_mat4x4 res, const bj_mat4x4 lhs, const bj_mat4x4 rhs)
527{
528 for (int i = 0; i < 4; ++i) bj_vec4_sub(res[i], lhs[i], rhs[i]);
529}
530
534static BJ_INLINE void bj_mat4_scale(bj_mat4x4 res, const bj_mat4x4 lhs, bj_real k)
535{
536 for (int i = 0; i < 4; ++i) bj_vec4_scale(res[i], lhs[i], k);
537}
538
543{
544 bj_vec4_scale(res[0], mat[0], x);
545 bj_vec4_scale(res[1], mat[1], y);
546 bj_vec4_scale(res[2], mat[2], z);
547 bj_vec4_copy(res[3], mat[3]);
548}
549
554 BJ_ARRAY_2D (bj_real, 4, 4, res),
555 BJ_CONST_ARRAY_2D(bj_real, 4, 4, lhs),
556 BJ_CONST_ARRAY_2D(bj_real, 4, 4, rhs)
557) {
558#ifdef BJ_MAT_NO_UNROLL
559 bj_mat4x4 temp;
560 for (int c = 0; c < 4; ++c) {
561 for (int r = 0; r < 4; ++r) {
562 temp[c][r] = BJ_FZERO;
563 for (int k = 0; k < 4; ++k)
564 temp[c][r] += lhs[k][r] * rhs[c][k];
565 }
566 }
567 bj_mat4_copy(res, temp);
568#else
569 const bj_real a0 = lhs[0][0], b0 = lhs[1][0], c0 = lhs[2][0], d0 = lhs[3][0];
570 const bj_real a1 = lhs[0][1], b1 = lhs[1][1], c1 = lhs[2][1], d1 = lhs[3][1];
571 const bj_real a2 = lhs[0][2], b2 = lhs[1][2], c2 = lhs[2][2], d2 = lhs[3][2];
572 const bj_real a3 = lhs[0][3], b3 = lhs[1][3], c3 = lhs[2][3], d3 = lhs[3][3];
573
574 { const bj_real r0 = rhs[0][0], r1 = rhs[0][1], r2 = rhs[0][2], r3 = rhs[0][3];
575 res[0][0] = a0*r0 + b0*r1 + c0*r2 + d0*r3;
576 res[0][1] = a1*r0 + b1*r1 + c1*r2 + d1*r3;
577 res[0][2] = a2*r0 + b2*r1 + c2*r2 + d2*r3;
578 res[0][3] = a3*r0 + b3*r1 + c3*r2 + d3*r3; }
579 { const bj_real r0 = rhs[1][0], r1 = rhs[1][1], r2 = rhs[1][2], r3 = rhs[1][3];
580 res[1][0] = a0*r0 + b0*r1 + c0*r2 + d0*r3;
581 res[1][1] = a1*r0 + b1*r1 + c1*r2 + d1*r3;
582 res[1][2] = a2*r0 + b2*r1 + c2*r2 + d2*r3;
583 res[1][3] = a3*r0 + b3*r1 + c3*r2 + d3*r3; }
584 { const bj_real r0 = rhs[2][0], r1 = rhs[2][1], r2 = rhs[2][2], r3 = rhs[2][3];
585 res[2][0] = a0*r0 + b0*r1 + c0*r2 + d0*r3;
586 res[2][1] = a1*r0 + b1*r1 + c1*r2 + d1*r3;
587 res[2][2] = a2*r0 + b2*r1 + c2*r2 + d2*r3;
588 res[2][3] = a3*r0 + b3*r1 + c3*r2 + d3*r3; }
589 { const bj_real r0 = rhs[3][0], r1 = rhs[3][1], r2 = rhs[3][2], r3 = rhs[3][3];
590 res[3][0] = a0*r0 + b0*r1 + c0*r2 + d0*r3;
591 res[3][1] = a1*r0 + b1*r1 + c1*r2 + d1*r3;
592 res[3][2] = a2*r0 + b2*r1 + c2*r2 + d2*r3;
593 res[3][3] = a3*r0 + b3*r1 + c3*r2 + d3*r3; }
594#endif
595}
596
601 BJ_ARRAY (bj_real, 4, res),
602 BJ_CONST_ARRAY_2D(bj_real, 4, 4, mat),
604) {
605#ifdef BJ_MAT_NO_UNROLL
606 for (int j = 0; j < 4; ++j) {
607 res[j] = BJ_FZERO;
608 for (int i = 0; i < 4; ++i) res[j] += mat[i][j] * v[i];
609 }
610#else
611 const bj_real vx = v[0], vy = v[1], vz = v[2], vw = v[3];
612 res[0] = mat[0][0]*vx + mat[1][0]*vy + mat[2][0]*vz + mat[3][0]*vw;
613 res[1] = mat[0][1]*vx + mat[1][1]*vy + mat[2][1]*vz + mat[3][1]*vw;
614 res[2] = mat[0][2]*vx + mat[1][2]*vy + mat[2][2]*vz + mat[3][2]*vw;
615 res[3] = mat[0][3]*vx + mat[1][3]*vy + mat[2][3]*vz + mat[3][3]*vw;
616#endif
617}
618
623{
624 bj_mat4_identity(res);
625 res[3][0] = x; res[3][1] = y; res[3][2] = z;
626}
627
632{
633 bj_vec4 t = { x, y, z, BJ_FZERO };
634 bj_vec4 r;
635 for (int i = 0; i < 4; ++i) {
636 bj_mat4_row(r, M, i);
637 M[3][i] += bj_vec4_dot(r, t);
638 }
639}
640
644static BJ_INLINE void bj_mat4_mul_outer(bj_mat4x4 res, const bj_vec3 a, const bj_vec3 b)
645{
646 for (int i = 0; i < 4; ++i)
647 for (int j = 0; j < 4; ++j)
648 res[i][j] = (i < 3 && j < 3) ? a[i] * b[j] : BJ_FZERO;
649}
650
654static BJ_INLINE void bj_mat4_rotate(bj_mat4x4 res, const bj_mat4x4 mat, bj_real x, bj_real y, bj_real z, bj_real angle)
655{
656 bj_real s = bj_sin(angle), c = bj_cos(angle);
657 bj_vec3 u = { x, y, z };
658
659 if (bj_vec3_len(u) > BJ_F(1e-4)) {
660 bj_vec3_normalize(u, u);
661 bj_mat4x4 T; bj_mat4_mul_outer(T, u, u);
662
663 bj_mat4x4 S = {
664 { BJ_FZERO, u[2], -u[1], BJ_FZERO},
665 {-u[2], BJ_FZERO, u[0], BJ_FZERO},
666 { u[1], -u[0], BJ_FZERO, BJ_FZERO},
668 };
669 bj_mat4_scale(S, S, s);
670
671 bj_mat4x4 C; bj_mat4_identity(C); bj_mat4_sub(C, C, T); bj_mat4_scale(C, C, c);
672
673 bj_mat4_add(T, T, C); bj_mat4_add(T, T, S);
674 T[3][3] = BJ_F(1.0);
675 bj_mat4_mul(res, mat, T);
676 } else {
677 bj_mat4_copy(res, mat);
678 }
679}
680
684static BJ_INLINE void bj_mat4_rotate_x(bj_mat4x4 res, const bj_mat4x4 mat, bj_real angle)
685{
686 bj_real s = bj_sin(angle), c = bj_cos(angle);
687 bj_mat4x4 R = {
688 {BJ_F(1.0), BJ_FZERO, BJ_FZERO, BJ_FZERO},
689 {BJ_FZERO, c, s, BJ_FZERO},
690 {BJ_FZERO, -s, c, BJ_FZERO},
692 };
693 bj_mat4_mul(res, mat, R);
694}
695
696static BJ_INLINE void bj_mat4_rotate_y(bj_mat4x4 res, const bj_mat4x4 mat, bj_real angle)
697{
698 bj_real s = bj_sin(angle), c = bj_cos(angle);
699 bj_mat4x4 R = {
700 { c, BJ_FZERO, -s, BJ_FZERO},
701 { BJ_FZERO, BJ_F(1.0), BJ_FZERO, BJ_FZERO},
702 { s, BJ_FZERO, c, BJ_FZERO},
703 { BJ_FZERO, BJ_FZERO, BJ_FZERO, BJ_F(1.0)}
704 };
705 bj_mat4_mul(res, mat, R);
706}
707
708static BJ_INLINE void bj_mat4_rotate_z(bj_mat4x4 res, const bj_mat4x4 mat, bj_real angle)
709{
710 bj_real s = bj_sin(angle), c = bj_cos(angle);
711 bj_mat4x4 R = {
712 { c, s, BJ_FZERO, BJ_FZERO},
713 { -s, c, BJ_FZERO, BJ_FZERO},
714 { BJ_FZERO, BJ_FZERO, BJ_F(1.0), BJ_FZERO},
715 { BJ_FZERO, BJ_FZERO, BJ_FZERO, BJ_F(1.0)}
716 };
717 bj_mat4_mul(res, mat, R);
718}
719
723static BJ_INLINE void bj_mat4_rotate_arcball(bj_mat4x4 R, const bj_mat4x4 M, bj_vec2 const _a, bj_vec2 const _b, bj_real s)
724{
725 bj_vec2 a = { _a[0], _a[1] };
726 bj_vec2 b = { _b[0], _b[1] };
727
728 bj_real z_a = BJ_FZERO, z_b = BJ_FZERO;
729
730 if (bj_vec2_len(a) < BJ_F(1.0)) z_a = bj_sqrt(BJ_F(1.0) - bj_vec2_dot(a, a)); else bj_vec2_normalize(a, a);
731 if (bj_vec2_len(b) < BJ_F(1.0)) z_b = bj_sqrt(BJ_F(1.0) - bj_vec2_dot(b, b)); else bj_vec2_normalize(b, b);
732
733 bj_vec3 a_ = { a[0], a[1], z_a };
734 bj_vec3 b_ = { b[0], b[1], z_b };
735
736 bj_vec3 c_; bj_vec3_cross(c_, a_, b_);
737 bj_real const angle = bj_acos(bj_vec3_dot(a_, b_)) * s;
738 bj_mat4_rotate(R, M, c_[0], c_[1], c_[2], angle);
739}
740
744static BJ_INLINE void bj_mat4_inverse(bj_mat4x4 res, const bj_mat4x4 mat) {
745 bj_real s[6], c[6];
746 s[0] = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];
747 s[1] = mat[0][0] * mat[1][2] - mat[1][0] * mat[0][2];
748 s[2] = mat[0][0] * mat[1][3] - mat[1][0] * mat[0][3];
749 s[3] = mat[0][1] * mat[1][2] - mat[1][1] * mat[0][2];
750 s[4] = mat[0][1] * mat[1][3] - mat[1][1] * mat[0][3];
751 s[5] = mat[0][2] * mat[1][3] - mat[1][2] * mat[0][3];
752
753 c[0] = mat[2][0] * mat[3][1] - mat[3][0] * mat[2][1];
754 c[1] = mat[2][0] * mat[3][2] - mat[3][0] * mat[2][2];
755 c[2] = mat[2][0] * mat[3][3] - mat[3][0] * mat[2][3];
756 c[3] = mat[2][1] * mat[3][2] - mat[3][1] * mat[2][2];
757 c[4] = mat[2][1] * mat[3][3] - mat[3][1] * mat[2][3];
758 c[5] = mat[2][2] * mat[3][3] - mat[3][2] * mat[2][3];
759
760 bj_real idet = BJ_F(1.0) / (s[0] * c[5] - s[1] * c[4] + s[2] * c[3] + s[3] * c[2] - s[4] * c[1] + s[5] * c[0]);
761
762 res[0][0] = (mat[1][1] * c[5] - mat[1][2] * c[4] + mat[1][3] * c[3]) * idet;
763 res[0][1] = (-mat[0][1] * c[5] + mat[0][2] * c[4] - mat[0][3] * c[3]) * idet;
764 res[0][2] = (mat[3][1] * s[5] - mat[3][2] * s[4] + mat[3][3] * s[3]) * idet;
765 res[0][3] = (-mat[2][1] * s[5] + mat[2][2] * s[4] - mat[2][3] * s[3]) * idet;
766
767 res[1][0] = (-mat[1][0] * c[5] + mat[1][2] * c[2] - mat[1][3] * c[1]) * idet;
768 res[1][1] = (mat[0][0] * c[5] - mat[0][2] * c[2] + mat[0][3] * c[1]) * idet;
769 res[1][2] = (-mat[3][0] * s[5] + mat[3][2] * s[2] - mat[3][3] * s[1]) * idet;
770 res[1][3] = (mat[2][0] * s[5] - mat[2][2] * s[2] + mat[2][3] * s[1]) * idet;
771
772 res[2][0] = (mat[1][0] * c[4] - mat[1][1] * c[2] + mat[1][3] * c[0]) * idet;
773 res[2][1] = (-mat[0][0] * c[4] + mat[0][1] * c[2] - mat[0][3] * c[0]) * idet;
774 res[2][2] = (mat[3][0] * s[4] - mat[3][1] * s[2] + mat[3][3] * s[0]) * idet;
775 res[2][3] = (-mat[2][0] * s[4] + mat[2][1] * s[2] - mat[2][3] * s[0]) * idet;
776
777 res[3][0] = (-mat[1][0] * c[3] + mat[1][1] * c[1] - mat[1][2] * c[0]) * idet;
778 res[3][1] = (mat[0][0] * c[3] - mat[0][1] * c[1] + mat[0][2] * c[0]) * idet;
779 res[3][2] = (-mat[3][0] * s[3] + mat[3][1] * s[1] - mat[3][2] * s[0]) * idet;
780 res[3][3] = (mat[2][0] * s[3] - mat[2][1] * s[1] + mat[2][2] * s[0]) * idet;
781}
782
787 bj_mat4_copy(res, mat);
788 bj_real s = BJ_F(1.0);
789 bj_vec3 h;
790
791 bj_vec3_normalize(res[2], res[2]);
792
793 s = bj_vec3_dot(res[1], res[2]);
794 bj_vec3_scale(h, res[2], s);
795 bj_vec3_sub(res[1], res[1], h);
796 bj_vec3_normalize(res[1], res[1]);
797
798 s = bj_vec3_dot(res[0], res[2]);
799 bj_vec3_scale(h, res[2], s);
800 bj_vec3_sub(res[0], res[0], h);
801
802 s = bj_vec3_dot(res[0], res[1]);
803 bj_vec3_scale(h, res[1], s);
804 bj_vec3_sub(res[0], res[0], h);
805 bj_vec3_normalize(res[0], res[0]);
806}
807
812 BJ_ARRAY_2D(bj_real, 4, 4, fmat),
813 bj_real l, bj_real r,
814 bj_real b, bj_real t,
815 bj_real n, bj_real f
816) {
817 fmat[0][0] = BJ_F(2.0) * n / (r - l);
818 fmat[0][1] = fmat[0][2] = fmat[0][3] = BJ_FZERO;
819
820 fmat[1][0] = BJ_FZERO;
821 fmat[1][1] = BJ_F(-2.0) * n / (t - b);
822 fmat[1][2] = fmat[1][3] = BJ_FZERO;
823
824 fmat[2][0] = (r + l) / (r - l);
825 fmat[2][1] = (t + b) / (t - b);
826
827 fmat[2][2] = f / (f - n);
828 fmat[2][3] = BJ_F(1.0);
829
830 fmat[3][0] = BJ_FZERO;
831 fmat[3][1] = BJ_FZERO;
832 fmat[3][2] = -(f * n) / (f - n);
833 fmat[3][3] = BJ_FZERO;
834}
835
840 BJ_ARRAY_2D(bj_real, 4, 4, omat),
841 bj_real l, bj_real r,
842 bj_real b, bj_real t,
843 bj_real n, bj_real f
844) {
845 omat[0][0] = BJ_F(2.0) / (r - l);
846 omat[0][1] = omat[0][2] = omat[0][3] = BJ_FZERO;
847
848 omat[1][0] = omat[1][2] = omat[1][3] = BJ_FZERO;
849 omat[1][1] = BJ_F(-2.0) / (t - b);
850
851 omat[2][0] = omat[2][1] = omat[2][3] = BJ_FZERO;
852 omat[2][2] = BJ_F(1.0) / (f - n);
853
854 omat[3][0] = -(r + l) / (r - l);
855 omat[3][1] = (t + b) / (t - b);
856 omat[3][2] = -n / (f - n);
857 omat[3][3] = BJ_F(1.0);
858}
859
864 BJ_ARRAY_2D(bj_real, 4, 4, pmat),
865 bj_real y_fov, bj_real aspect,
866 bj_real n, bj_real f
867) {
868 const bj_real a = BJ_F(1.0) / bj_tan(y_fov / BJ_F(2.0));
869
870 pmat[0][0] = a / aspect;
871 pmat[0][1] = pmat[0][2] = pmat[0][3] = BJ_FZERO;
872
873 pmat[1][0] = BJ_FZERO;
874 pmat[1][1] = -a;
875 pmat[1][2] = pmat[1][3] = BJ_FZERO;
876
877 pmat[2][0] = BJ_FZERO; pmat[2][1] = BJ_FZERO;
878 pmat[2][2] = f / (f - n);
879 pmat[2][3] = BJ_F(1.0);
880
881 pmat[3][0] = BJ_FZERO; pmat[3][1] = BJ_FZERO;
882 pmat[3][2] = -(f * n) / (f - n);
883 pmat[3][3] = BJ_FZERO;
884}
885
890 BJ_ARRAY_2D(bj_real, 4, 4, vpmat),
891 bj_real x, bj_real y,
892 bj_real w, bj_real h
893) {
894 const bj_real z_min = BJ_FZERO, z_max = BJ_F(1.0);
895 const bj_real sx = BJ_F(0.50) * w, sy = BJ_F(0.50) * h, sz = (z_max - z_min);
896 const bj_real tx = x + BJ_F(0.50) * w, ty = y + BJ_F(0.50) * h, tz = z_min;
897
898 vpmat[0][0] = sx; vpmat[0][1] = BJ_FZERO; vpmat[0][2] = BJ_FZERO; vpmat[0][3] = BJ_FZERO;
899 vpmat[1][0] = BJ_FZERO; vpmat[1][1] = sy; vpmat[1][2] = BJ_FZERO; vpmat[1][3] = BJ_FZERO;
900 vpmat[2][0] = BJ_FZERO; vpmat[2][1] = BJ_FZERO; vpmat[2][2] = sz; vpmat[2][3] = BJ_FZERO;
901 vpmat[3][0] = tx; vpmat[3][1] = ty; vpmat[3][2] = tz; vpmat[3][3] = BJ_F(1.0);
902}
903
908 BJ_ARRAY_2D(bj_real, 4, 4, m),
909 const bj_vec3 eye,
910 const bj_vec3 center,
911 const bj_vec3 up
912) {
913 bj_vec3 f; bj_vec3_sub(f, center, eye); bj_vec3_normalize(f, f);
914 bj_vec3 s; bj_vec3_cross(s, up, f); bj_vec3_normalize(s, s);
915 bj_vec3 t; bj_vec3_cross(t, f, s);
916
917 m[0][0]=s[0]; m[0][1]=t[0]; m[0][2]=f[0]; m[0][3]=BJ_FZERO;
918 m[1][0]=s[1]; m[1][1]=t[1]; m[1][2]=f[1]; m[1][3]=BJ_FZERO;
919 m[2][0]=s[2]; m[2][1]=t[2]; m[2][2]=f[2]; m[2][3]=BJ_FZERO;
920 m[3][0]=BJ_FZERO; m[3][1]=BJ_FZERO; m[3][2]=BJ_FZERO; m[3][3]=BJ_F(1.0);
921
922 bj_mat4_translation_inplace(m, -eye[0], -eye[1], -eye[2]);
923}
924
929 BJ_ARRAY_2D(bj_real, 4, 3, m)
930) {
931 m[0][0]=BJ_F(1.0); m[0][1]=BJ_FZERO; m[0][2]=BJ_FZERO;
932 m[1][0]=BJ_FZERO; m[1][1]=BJ_F(1.0); m[1][2]=BJ_FZERO;
933 m[2][0]=BJ_FZERO; m[2][1]=BJ_FZERO; m[2][2]=BJ_F(1.0);
934 m[3][0]=BJ_FZERO; m[3][1]=BJ_FZERO; m[3][2]=BJ_FZERO;
935}
936
941 BJ_ARRAY_2D(bj_real, 4, 3, m),
942 bj_real tx, bj_real ty, bj_real tz
943) {
944 m[0][0]=BJ_F(1.0); m[0][1]=BJ_FZERO; m[0][2]=BJ_FZERO;
945 m[1][0]=BJ_FZERO; m[1][1]=BJ_F(1.0); m[1][2]=BJ_FZERO;
946 m[2][0]=BJ_FZERO; m[2][1]=BJ_FZERO; m[2][2]=BJ_F(1.0);
947 m[3][0]=tx; m[3][1]=ty; m[3][2]=tz;
948}
949
954 BJ_ARRAY_2D(bj_real, 4, 3, m),
955 bj_real sx, bj_real sy, bj_real sz
956) {
957 m[0][0]=sx; m[0][1]=BJ_FZERO; m[0][2]=BJ_FZERO;
958 m[1][0]=BJ_FZERO; m[1][1]=sy; m[1][2]=BJ_FZERO;
959 m[2][0]=BJ_FZERO; m[2][1]=BJ_FZERO; m[2][2]=sz;
960 m[3][0]=BJ_FZERO; m[3][1]=BJ_FZERO; m[3][2]=BJ_FZERO;
961}
962
967 const bj_real c = bj_cosf(angle), s = bj_sinf(angle);
968 m[0][0]=BJ_F(1.0); m[0][1]=BJ_FZERO; m[0][2]=BJ_FZERO;
969 m[1][0]=BJ_FZERO; m[1][1]= c; m[1][2]= s;
970 m[2][0]=BJ_FZERO; m[2][1]=-s; m[2][2]= c;
971 m[3][0]=BJ_FZERO; m[3][1]=BJ_FZERO; m[3][2]=BJ_FZERO;
972}
974 const bj_real c = bj_cosf(angle), s = bj_sinf(angle);
975 m[0][0]= c; m[0][1]=BJ_FZERO; m[0][2]=-s;
976 m[1][0]=BJ_FZERO; m[1][1]=BJ_F(1.0);m[1][2]=BJ_FZERO;
977 m[2][0]= s; m[2][1]=BJ_FZERO; m[2][2]= c;
978 m[3][0]=BJ_FZERO; m[3][1]=BJ_FZERO; m[3][2]=BJ_FZERO;
979}
981 const bj_real c = bj_cosf(angle), s = bj_sinf(angle);
982 m[0][0]= c; m[0][1]= s; m[0][2]=BJ_FZERO;
983 m[1][0]=-s; m[1][1]= c; m[1][2]=BJ_FZERO;
984 m[2][0]=BJ_FZERO; m[2][1]=BJ_FZERO; m[2][2]=BJ_F(1.0);
985 m[3][0]=BJ_FZERO; m[3][1]=BJ_FZERO; m[3][2]=BJ_FZERO;
986}
987
992 BJ_ARRAY_2D (bj_real, 4, 3, res),
993 BJ_CONST_ARRAY_2D(bj_real, 4, 3, A),
994 BJ_CONST_ARRAY_2D(bj_real, 4, 3, B)
995) {
996#ifdef BJ_MAT_NO_UNROLL
997 for (int r=0; r<3; ++r) {
998 res[0][r] = A[0][r]*B[0][0] + A[1][r]*B[1][0] + A[2][r]*B[2][0];
999 res[1][r] = A[0][r]*B[0][1] + A[1][r]*B[1][1] + A[2][r]*B[2][1];
1000 res[2][r] = A[0][r]*B[0][2] + A[1][r]*B[1][2] + A[2][r]*B[2][2];
1001 res[3][r] = A[0][r]*B[3][0] + A[1][r]*B[3][1] + A[2][r]*B[3][2] + A[3][r];
1002 }
1003#else
1004 const bj_real a00=A[0][0], a10=A[1][0], a20=A[2][0], a30=A[3][0];
1005 const bj_real a01=A[0][1], a11=A[1][1], a21=A[2][1], a31=A[3][1];
1006 const bj_real a02=A[0][2], a12=A[1][2], a22=A[2][2], a32=A[3][2];
1007
1008 const bj_real b00=B[0][0], b01=B[1][0], b02=B[2][0];
1009 const bj_real b10=B[0][1], b11=B[1][1], b12=B[2][1];
1010 const bj_real b20=B[0][2], b21=B[1][2], b22=B[2][2];
1011 const bj_real bt0=B[3][0], bt1=B[3][1], bt2=B[3][2];
1012
1013 res[0][0] = a00*b00 + a10*b01 + a20*b02;
1014 res[0][1] = a01*b00 + a11*b01 + a21*b02;
1015 res[0][2] = a02*b00 + a12*b01 + a22*b02;
1016
1017 res[1][0] = a00*b10 + a10*b11 + a20*b12;
1018 res[1][1] = a01*b10 + a11*b11 + a21*b12;
1019 res[1][2] = a02*b10 + a12*b11 + a22*b12;
1020
1021 res[2][0] = a00*b20 + a10*b21 + a20*b22;
1022 res[2][1] = a01*b20 + a11*b21 + a21*b22;
1023 res[2][2] = a02*b20 + a12*b21 + a22*b22;
1024
1025 res[3][0] = a00*bt0 + a10*bt1 + a20*bt2 + a30;
1026 res[3][1] = a01*bt0 + a11*bt1 + a21*bt2 + a31;
1027 res[3][2] = a02*bt0 + a12*bt1 + a22*bt2 + a32;
1028#endif
1029}
1030
1035 BJ_ARRAY (bj_real, 3, r),
1036 BJ_CONST_ARRAY_2D(bj_real, 4, 3, m),
1037 BJ_CONST_ARRAY(bj_real, 3, p)
1038) {
1039 const bj_real x=p[0], y=p[1], z=p[2];
1040 r[0] = m[0][0]*x + m[1][0]*y + m[2][0]*z + m[3][0];
1041 r[1] = m[0][1]*x + m[1][1]*y + m[2][1]*z + m[3][1];
1042 r[2] = m[0][2]*x + m[1][2]*y + m[2][2]*z + m[3][2];
1043}
1044
1049 BJ_ARRAY (bj_real, 3, r),
1050 BJ_CONST_ARRAY_2D(bj_real, 4, 3, m),
1051 BJ_CONST_ARRAY(bj_real, 3, v)
1052) {
1053 const bj_real x=v[0], y=v[1], z=v[2];
1054 r[0] = m[0][0]*x + m[1][0]*y + m[2][0]*z;
1055 r[1] = m[0][1]*x + m[1][1]*y + m[2][1]*z;
1056 r[2] = m[0][2]*x + m[1][2]*y + m[2][2]*z;
1057}
1058
1063 bj_mat4x4 out,
1064 BJ_CONST_ARRAY_2D(bj_real, 4, 3, a)
1065) {
1066 out[0][0]=a[0][0]; out[0][1]=a[0][1]; out[0][2]=a[0][2]; out[0][3]=BJ_FZERO;
1067 out[1][0]=a[1][0]; out[1][1]=a[1][1]; out[1][2]=a[1][2]; out[1][3]=BJ_FZERO;
1068 out[2][0]=a[2][0]; out[2][1]=a[2][1]; out[2][2]=a[2][2]; out[2][3]=BJ_FZERO;
1069 out[3][0]=a[3][0]; out[3][1]=a[3][1]; out[3][2]=a[3][2]; out[3][3]=BJ_F(1.0);
1070}
1071
1076 BJ_ARRAY_2D(bj_real, 4, 3, out43),
1077 const bj_mat4x4 m
1078) {
1079 out43[0][0]=m[0][0]; out43[0][1]=m[0][1]; out43[0][2]=m[0][2];
1080 out43[1][0]=m[1][0]; out43[1][1]=m[1][1]; out43[1][2]=m[1][2];
1081 out43[2][0]=m[2][0]; out43[2][1]=m[2][1]; out43[2][2]=m[2][2];
1082 out43[3][0]=m[3][0]; out43[3][1]=m[3][1]; out43[3][2]=m[3][2];
1083}
1084
1089 BJ_ARRAY_2D(bj_real, 4, 3, m),
1090 BJ_CONST_ARRAY(bj_real, 3, eye),
1091 BJ_CONST_ARRAY(bj_real, 3, center),
1092 BJ_CONST_ARRAY(bj_real, 3, up)
1093) {
1094 bj_real f[3] = { center[0]-eye[0], center[1]-eye[1], center[2]-eye[2] };
1095 { const bj_real len2 = f[0]*f[0]+f[1]*f[1]+f[2]*f[2]; const bj_real inv = BJ_F(1.0)/bj_sqrt(len2);
1096 f[0]*=inv; f[1]*=inv; f[2]*=inv; }
1097 bj_real s[3] = { up[1]*f[2]-up[2]*f[1], up[2]*f[0]-up[0]*f[2], up[0]*f[1]-up[1]*f[0] };
1098 { const bj_real len2 = s[0]*s[0]+s[1]*s[1]+s[2]*s[2]; const bj_real inv = BJ_F(1.0)/bj_sqrt(len2);
1099 s[0]*=inv; s[1]*=inv; s[2]*=inv; }
1100 const bj_real t[3] = { f[1]*s[2]-f[2]*s[1], f[2]*s[0]-f[0]*s[2], f[0]*s[1]-f[1]*s[0] };
1101
1102 m[0][0]=s[0]; m[0][1]=s[1]; m[0][2]=s[2];
1103 m[1][0]=t[0]; m[1][1]=t[1]; m[1][2]=t[2];
1104 m[2][0]=f[0]; m[2][1]=f[1]; m[2][2]=f[2];
1105
1106 m[3][0]=-(s[0]*eye[0] + s[1]*eye[1] + s[2]*eye[2]);
1107 m[3][1]=-(t[0]*eye[0] + t[1]*eye[1] + t[2]*eye[2]);
1108 m[3][2]=-(f[0]*eye[0] + f[1]*eye[1] + f[2]*eye[2]);
1109}
1110
1111#endif
General-purpose definitions for Banjo API.
#define BJ_INLINE
BJ_INLINE expands to an inline specifier appropriate for the toolchain.
Definition api.h:260
#define BJ_CONST_ARRAY(T, n, name)
Definition api.h:224
#define BJ_CONST_ARRAY_2D(T, n, m, name)
Definition api.h:226
#define BJ_ARRAY(T, n, name)
Definition api.h:225
#define BJ_ARRAY_2D(T, n, m, name)
Expands to array parameter declarations appropriate for the toolchain.
Definition api.h:227
bj_vec4 bj_mat4x4[4]
bj_mat4x4: 4×4 column-major matrix backed by bj_vec4.
Definition mat.h:45
static void bj_mat4_translation_inplace(bj_mat4x4 M, bj_real x, bj_real y, bj_real z)
Apply 4×4 translation in-place.
Definition mat.h:631
bj_real bj_vec3[3]
bj_vec3: 3D vector of bj_real values.
Definition vec.h:34
static void bj_mat3x2_from_mat3(bj_real out3x2[restrict static(3)][2], const bj_real m[restrict static(3)][3])
Extract 3×2 from 3×3.
Definition mat.h:462
static void bj_mat4x3_mul_point(bj_real r[restrict static(3)], const bj_real m[restrict static(4)][3], const bj_real p[restrict static(3)])
4×3 transform point.
Definition mat.h:1034
static void bj_mat3_copy(bj_mat3x3 to, const bj_mat3x3 from)
Copy matrix contents.
Definition mat.h:73
static void bj_mat3_row(bj_vec3 res, const bj_mat3x3 m, int r)
Extract a row as a vector (row index into second subscript).
Definition mat.h:87
bj_real bj_vec2[2]
bj_vec2: 2D vector of bj_real values.
Definition vec.h:27
static void bj_mat4_scale(bj_mat4x4 res, const bj_mat4x4 lhs, bj_real k)
Scale 4×4 by k.
Definition mat.h:534
static void bj_mat3x2_translate(bj_real m[restrict static(3)][2], bj_real tx, bj_real ty)
Build 3×2 translation.
Definition mat.h:357
static void bj_mat4x3_mul_dir(bj_real r[restrict static(3)], const bj_real m[restrict static(4)][3], const bj_real v[restrict static(3)])
4×3 transform direction (no translation).
Definition mat.h:1048
static void bj_mat4_row(bj_vec4 res, const bj_mat4x4 mat, int r)
Extract 4×4 row.
Definition mat.h:492
static void bj_mat4_translation(bj_mat4x4 res, bj_real x, bj_real y, bj_real z)
Create 4×4 translation matrix.
Definition mat.h:622
static void bj_mat3_transpose(bj_mat3x3 res, const bj_mat3x3 m)
Transpose the matrix.
Definition mat.h:106
bj_vec2 bj_mat3x2[3]
bj_mat3x2: 3×2 column-major matrix backed by bj_vec2.
Definition mat.h:39
static void bj_mat4x3_lookat(bj_real m[restrict static(4)][3], const bj_real eye[restrict static(3)], const bj_real center[restrict static(3)], const bj_real up[restrict static(3)])
Look-at builder for 4×3.
Definition mat.h:1088
#define bj_sinf
Sine (float)
Definition math.h:111
static void bj_mat4_mul(bj_real res[restrict static(4)][4], const bj_real lhs[restrict static(4)][4], const bj_real rhs[restrict static(4)][4])
4×4 multiplication: res = lhs * rhs.
Definition mat.h:553
static void bj_mat4_lookat(bj_real m[restrict static(4)][4], const bj_vec3 eye, const bj_vec3 center, const bj_vec3 up)
Look-at view matrix builder (4×4).
Definition mat.h:907
#define bj_tan
Tangent.
Definition math.h:223
static void bj_mat3_translation(bj_mat3x3 res, bj_real tx, bj_real ty)
Create a translation matrix.
Definition mat.h:233
static void bj_mat4_rotate(bj_mat4x4 res, const bj_mat4x4 mat, bj_real x, bj_real y, bj_real z, bj_real angle)
Rotate about axis, post-multiply.
Definition mat.h:654
static void bj_mat4x3_scale(bj_real m[restrict static(4)][3], bj_real sx, bj_real sy, bj_real sz)
4×3 scale.
Definition mat.h:953
static void bj_mat4_orthonormalize(bj_mat4x4 res, const bj_mat4x4 mat)
Orthonormalize upper-left 3×3 of 4×4.
Definition mat.h:786
static void bj_mat3_rotate(bj_mat3x3 res, bj_real angle)
Rotate 2D about Z.
Definition mat.h:272
static bj_real bj_vec2_len(const bj_vec2 v)
Euclidean length (L2 norm) of a 2D vector.
Definition vec.h:149
bj_real bj_vec4[4]
bj_vec4: 4D vector of bj_real values.
Definition vec.h:41
static void bj_mat3x2_rotate(bj_real m[restrict static(3)][2], bj_real angle)
Build 3×2 rotation.
Definition mat.h:379
static void bj_mat3_col(bj_vec3 res, const bj_mat3x3 m, int c)
Extract a column as a vector (column index into first subscript).
Definition mat.h:97
static void bj_mat3_mul_vec3(bj_real res[restrict static(3)], const bj_real m[restrict static(3)][3], const bj_real v[restrict static(3)])
Multiply 3×3 matrix by a 3D column vector: res = M * v.
Definition mat.h:188
static void bj_vec3_scale(bj_vec3 res, const bj_vec3 v, bj_real s)
Uniform scaling by scalar: res = v * s.
Definition vec.h:301
#define bj_acos
Arc cosine.
Definition math.h:209
static bj_real bj_vec3_dot(const bj_vec3 a, const bj_vec3 b)
Dot product of two 3D vectors.
Definition vec.h:313
static void bj_mat4_identity(bj_mat4x4 mat)
Set 4×4 to identity.
Definition mat.h:474
static void bj_mat4_copy(bj_mat4x4 to, const bj_mat4x4 from)
Copy 4×4.
Definition mat.h:484
static void bj_mat3x2_identity(bj_real m[restrict static(3)][2])
Set 3×2 to identity.
Definition mat.h:346
static void bj_mat4x3_rotate_z(bj_real m[restrict static(4)][3], bj_real angle)
Definition mat.h:980
static void bj_mat4x3_from_mat4(bj_real out43[restrict static(4)][3], const bj_mat4x4 m)
Extract 4×3 from 4×4.
Definition mat.h:1075
static void bj_mat4x3_mul(bj_real res[restrict static(4)][3], const bj_real A[restrict static(4)][3], const bj_real B[restrict static(4)][3])
4×3 multiplication: res = A * B.
Definition mat.h:991
static void bj_mat4x3_identity(bj_real m[restrict static(4)][3])
Set 4×3 to identity.
Definition mat.h:928
#define bj_sin
Sine.
Definition math.h:221
static void bj_mat4_from_mat4x3(bj_mat4x4 out, const bj_real a[restrict static(4)][3])
Promote 4×3 to 4×4 homogeneous.
Definition mat.h:1062
static void bj_mat4x3_rotate_y(bj_real m[restrict static(4)][3], bj_real angle)
Definition mat.h:973
static void bj_vec4_sub(bj_vec4 res, const bj_vec4 lhs, const bj_vec4 rhs)
Component-wise subtraction of two 4D vectors: res = lhs - rhs.
Definition vec.h:495
static bj_real bj_vec3_len(const bj_vec3 v)
Euclidean length (L2 norm) of a 3D vector.
Definition vec.h:322
#define bj_cosf
Cosine (float)
Definition math.h:102
static void bj_mat4_rotate_y(bj_mat4x4 res, const bj_mat4x4 mat, bj_real angle)
Definition mat.h:696
static void bj_mat3_viewport(bj_real vpmat[restrict static(3)][3], bj_real x, bj_real y, bj_real w, bj_real h)
Viewport transform matrix (3×3).
Definition mat.h:331
bj_vec3 bj_mat4x3[4]
bj_mat4x3: 4×3 column-major matrix backed by bj_vec3.
Definition mat.h:56
static void bj_mat4_mul_vec4(bj_real res[restrict static(4)], const bj_real mat[restrict static(4)][4], const bj_real v[restrict static(4)])
4×4 multiply by vec4.
Definition mat.h:600
static void bj_mat3_ortho(bj_real omat[restrict static(3)][3], bj_real l, bj_real r, bj_real b, bj_real t)
Orthographic projection matrix (3×3).
Definition mat.h:310
static void bj_vec4_copy(bj_vec4 res, const bj_vec4 src)
Copy a 4D vector.
Definition vec.h:579
static void bj_mat4_inverse(bj_mat4x4 res, const bj_mat4x4 mat)
Invert 4×4.
Definition mat.h:744
static void bj_mat3_sub(bj_mat3x3 res, const bj_mat3x3 a, const bj_mat3x3 b)
Component-wise subtraction: res = a - b.
Definition mat.h:126
static void bj_mat4x3_translate(bj_real m[restrict static(4)][3], bj_real tx, bj_real ty, bj_real tz)
4×3 translation.
Definition mat.h:940
bj_mat4x4 bj_mat4
bj_mat4: Alias for bj_mat4x4
Definition mat.h:50
static void bj_vec2_normalize(bj_vec2 res, const bj_vec2 v)
Normalize a 2D vector to unit length.
Definition vec.h:197
static void bj_mat4_col(bj_vec4 res, const bj_mat4x4 mat, int c)
Extract 4×4 column.
Definition mat.h:500
#define BJ_FZERO
Zero constant in bj_real.
Definition math.h:64
static void bj_mat3x2_mul(bj_real res[restrict static(3)][2], const bj_real A[restrict static(3)][2], const bj_real B[restrict static(3)][2])
3×2 multiplication: res = A * B.
Definition mat.h:391
static void bj_mat3_identity(bj_mat3x3 m)
Set to identity matrix.
Definition mat.h:62
static void bj_mat4_ortho(bj_real omat[restrict static(4)][4], bj_real l, bj_real r, bj_real b, bj_real t, bj_real n, bj_real f)
Orthographic projection (4×4).
Definition mat.h:839
static void bj_mat3x2_scale(bj_real m[restrict static(3)][2], bj_real sx, bj_real sy)
Build 3×2 scale.
Definition mat.h:368
static void bj_mat3_mul_vector2(bj_vec2 res, const bj_mat3x3 m, const bj_vec2 v2)
Transform a direction (w=0; ignores translation).
Definition mat.h:224
bj_mat3x3 bj_mat3
bj_mat3: Alias for bj_mat3x3
Definition mat.h:33
static void bj_mat4x3_rotate_x(bj_real m[restrict static(4)][3], bj_real angle)
4×3 rotate X/Y/Z.
Definition mat.h:966
static void bj_mat3_mul(bj_real res[restrict static(3)][3], const bj_real lhs[restrict static(3)][3], const bj_real rhs[restrict static(3)][3])
Matrix multiplication: res = lhs * rhs (column-major).
Definition mat.h:149
static void bj_mat4_sub(bj_mat4x4 res, const bj_mat4x4 lhs, const bj_mat4x4 rhs)
Sub 4×4.
Definition mat.h:526
static void bj_mat4_perspective(bj_real pmat[restrict static(4)][4], bj_real y_fov, bj_real aspect, bj_real n, bj_real f)
Symmetric perspective from FOV+aspect (4×4).
Definition mat.h:863
static void bj_mat4_add(bj_mat4x4 res, const bj_mat4x4 lhs, const bj_mat4x4 rhs)
Add 4×4.
Definition mat.h:518
static void bj_mat4_viewport(bj_real vpmat[restrict static(4)][4], bj_real x, bj_real y, bj_real w, bj_real h)
Viewport transform (4×4).
Definition mat.h:889
static void bj_mat3_translation_inplace(bj_mat3x3 M, bj_real tx, bj_real ty)
Apply a translation in-place.
Definition mat.h:242
#define bj_cos
Cosine.
Definition math.h:212
static bj_real bj_vec2_dot(const bj_vec2 a, const bj_vec2 b)
Dot product of two 2D vectors.
Definition vec.h:132
static void bj_mat4_mul_outer(bj_mat4x4 res, const bj_vec3 a, const bj_vec3 b)
Outer product to upper-left 3×3 block of 4×4.
Definition mat.h:644
static void bj_mat3_mul_point(bj_vec2 res, const bj_mat3x3 m, const bj_vec2 p)
Transform a point (homogeneous w=1).
Definition mat.h:211
static void bj_mat4_scale_xyz(bj_mat4x4 res, const bj_mat4x4 mat, bj_real x, bj_real y, bj_real z)
Scale basis vectors.
Definition mat.h:542
static void bj_mat4_rotate_z(bj_mat4x4 res, const bj_mat4x4 mat, bj_real angle)
Definition mat.h:708
static void bj_mat3_from_mat3x2(bj_real out3x3[restrict static(3)][3], const bj_real a[restrict static(3)][2])
Promote 3×2 to 3×3 homogeneous.
Definition mat.h:450
static void bj_mat3x2_mul_point(bj_real r[restrict static(2)], const bj_real m[restrict static(3)][2], const bj_real p[restrict static(2)])
3×2 transform point.
Definition mat.h:424
static void bj_mat3_scale_xy(bj_mat3x3 res, bj_real sx, bj_real sy)
Create 2D scaling matrix with independent X/Y scales.
Definition mat.h:254
static void bj_mat3x2_mul_dir(bj_real r[restrict static(2)], const bj_real m[restrict static(3)][2], const bj_real v[restrict static(2)])
3×2 transform direction (no translation).
Definition mat.h:437
static void bj_vec4_add(bj_vec4 res, const bj_vec4 lhs, const bj_vec4 rhs)
Component-wise addition of two 4D vectors: res = lhs + rhs.
Definition vec.h:468
static void bj_vec4_scale(bj_vec4 res, const bj_vec4 v, bj_real s)
Uniform scaling by scalar: res = v * s.
Definition vec.h:508
static void bj_mat4_transpose(bj_mat4x4 res, const bj_mat4x4 mat)
Transpose 4×4.
Definition mat.h:508
#define BJ_F(x)
Literal suffix helper for bj_real when float is selected.
Definition math.h:53
static void bj_mat4_rotate_arcball(bj_mat4x4 R, const bj_mat4x4 M, bj_vec2 const _a, bj_vec2 const _b, bj_real s)
Arcball rotation.
Definition mat.h:723
#define bj_sqrt
Square root.
Definition math.h:222
float bj_real
Selected real type for float configuration.
Definition math.h:51
static void bj_mat4_frustum(bj_real fmat[restrict static(4)][4], bj_real l, bj_real r, bj_real b, bj_real t, bj_real n, bj_real f)
Off-center perspective frustum (4×4).
Definition mat.h:811
static void bj_vec3_sub(bj_vec3 res, const bj_vec3 lhs, const bj_vec3 rhs)
Component-wise subtraction of two 3D vectors: res = lhs - rhs.
Definition vec.h:289
static void bj_mat3_add(bj_mat3x3 res, const bj_mat3x3 a, const bj_mat3x3 b)
Component-wise addition: res = a + b.
Definition mat.h:115
static void bj_mat3_inverse(bj_mat3x3 res, const bj_mat3x3 m)
Invert a 3×3.
Definition mat.h:282
static bj_real bj_vec4_dot(const bj_vec4 a, const bj_vec4 b)
Dot product of two 4D vectors.
Definition vec.h:521
static void bj_mat3_scale(bj_mat3x3 res, const bj_mat3x3 m, bj_real k)
Uniformly scale all elements by scalar k.
Definition mat.h:137
static void bj_vec3_cross(bj_vec3 res, const bj_vec3 l, const bj_vec3 r)
3D cross product: res = l × r (right-hand rule).
Definition vec.h:420
static void bj_mat4_rotate_x(bj_mat4x4 res, const bj_mat4x4 mat, bj_real angle)
Rotate about X/Y/Z, post-multiply.
Definition mat.h:684
static void bj_vec3_normalize(bj_vec3 res, const bj_vec3 v)
Normalize a 3D vector to unit length.
Definition vec.h:372
bj_vec3 bj_mat3x3[3]
bj_mat3x3: 3×3 column-major matrix backed by bj_vec3.
Definition mat.h:28
static void bj_mat3_shear(bj_mat3x3 res, bj_real shx, bj_real shy)
Create 2D shear matrix.
Definition mat.h:263
C99 math shim with bj_real precision type and scalar utilities.
vector manipulation API