Kohi Game Engine
kmath.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include "defines.h"
17 #include "math_types.h"
18 #include "memory/kmemory.h"
19 #include <float.h>
20 
22 #define K_PI 3.14159265358979323846f
23 
25 #define K_2PI (2.0f * K_PI)
26 
28 #define K_4PI (4.0f * K_PI)
29 
31 #define K_HALF_PI (0.5f * K_PI)
32 
34 #define K_QUARTER_PI (0.25f * K_PI)
35 
37 #define K_ONE_OVER_PI (1.0f / K_PI)
38 
40 #define K_ONE_OVER_TWO_PI (1.0f / K_2PI)
41 
43 #define K_SQRT_TWO 1.41421356237309504880f
44 
46 #define K_SQRT_THREE 1.73205080756887729352f
47 
49 #define K_SQRT_ONE_OVER_TWO 0.70710678118654752440f
50 
52 #define K_SQRT_ONE_OVER_THREE 0.57735026918962576450f
53 
55 #define K_DEG2RAD_MULTIPLIER (K_PI / 180.0f)
56 
58 #define K_RAD2DEG_MULTIPLIER (180.0f / K_PI)
59 
61 #define K_SEC_TO_US_MULTIPLIER (1000.0f * 1000.0f)
62 
64 #define K_SEC_TO_MS_MULTIPLIER 1000.0f
65 
67 #define K_MS_TO_SEC_MULTIPLIER 0.001f
68 
70 #define K_INFINITY (1e30f * 1e30f)
71 
73 #define K_FLOAT_EPSILON 1.192092896e-07f
74 
75 #define K_FLOAT_MAX 3.40282e+38F
76 #define K_FLOAT_MIN -K_FLOAT_MAX
77 
78 // ------------------------------------------
79 // General math functions
80 // ------------------------------------------
81 
87 KINLINE void kswapf(f32* a, f32* b) {
88  f32 temp = *a;
89  *a = *b;
90  *b = temp;
91 }
92 
95  return x == 0.0f ? 0.0f : x < 0.0f ? -1.0f
96  : 1.0f;
97 }
98 
100 KINLINE f32 kstep(f32 edge, f32 x) {
101  return x < edge ? 0.0f : 1.0f;
102 }
103 
111 
119 
127 
135 
137 
139 
147 
195 
203 
211 
219 
227 
235 
237 
239 
241  return a + t * (b - a);
242 }
243 
251  return (value != 0) && ((value & (value - 1)) == 0);
252 }
253 
260 
269 
275 
282 
292 
301 KINLINE f32 ksmoothstep(f32 edge_0, f32 edge_1, f32 x) {
302  f32 t = KCLAMP((x - edge_0) / (edge_1 - edge_0), 0.0f, 1.0f);
303  return t * t * (3.0 - 2.0 * t);
304 }
305 
315 
321  return kabs(f_0 - f_1) < K_FLOAT_EPSILON;
322 }
323 
324 // ------------------------------------------
325 // Vector 2
326 // ------------------------------------------
327 
336  return (vec2){x, y};
337 }
338 
345 KINLINE vec2 vec2_from_scalar(f32 scalar) { return (vec2){scalar, scalar}; }
346 
351 KINLINE vec2 vec2_zero(void) { return (vec2){0.0f, 0.0f}; }
352 
357 KINLINE vec2 vec2_one(void) { return (vec2){1.0f, 1.0f}; }
358 
362 KINLINE vec2 vec2_up(void) { return (vec2){0.0f, 1.0f}; }
363 
367 KINLINE vec2 vec2_down(void) { return (vec2){0.0f, -1.0f}; }
368 
372 KINLINE vec2 vec2_left(void) { return (vec2){-1.0f, 0.0f}; }
373 
377 KINLINE vec2 vec2_right(void) { return (vec2){1.0f, 0.0f}; }
378 
386 KINLINE vec2 vec2_add(vec2 vector_0, vec2 vector_1) {
387  return (vec2){vector_0.x + vector_1.x, vector_0.y + vector_1.y};
388 }
389 
397 KINLINE vec2 vec2_sub(vec2 vector_0, vec2 vector_1) {
398  return (vec2){vector_0.x - vector_1.x, vector_0.y - vector_1.y};
399 }
400 
408 KINLINE vec2 vec2_mul(vec2 vector_0, vec2 vector_1) {
409  return (vec2){vector_0.x * vector_1.x, vector_0.y * vector_1.y};
410 }
411 
420 KINLINE vec2 vec2_mul_scalar(vec2 vector_0, f32 scalar) {
421  return (vec2){vector_0.x * scalar, vector_0.y * scalar};
422 }
423 
432 KINLINE vec2 vec2_mul_add(vec2 vector_0, vec2 vector_1, vec2 vector_2) {
433  return (vec2){
434  vector_0.x * vector_1.x + vector_2.x,
435  vector_0.y * vector_1.y + vector_2.y};
436 }
437 
445 KINLINE vec2 vec2_div(vec2 vector_0, vec2 vector_1) {
446  return (vec2){vector_0.x / vector_1.x, vector_0.y / vector_1.y};
447 }
448 
456  return vector.x * vector.x + vector.y * vector.y;
457 }
458 
466  return ksqrt(vec2_length_squared(vector));
467 }
468 
474 KINLINE void vec2_normalize(vec2* vector) {
475  const f32 length = vec2_length(*vector);
476  vector->x /= length;
477  vector->y /= length;
478 }
479 
487  vec2_normalize(&vector);
488  return vector;
489 }
490 
501 KINLINE b8 vec2_compare(vec2 vector_0, vec2 vector_1, f32 tolerance) {
502  if (kabs(vector_0.x - vector_1.x) > tolerance) {
503  return false;
504  }
505 
506  if (kabs(vector_0.y - vector_1.y) > tolerance) {
507  return false;
508  }
509 
510  return true;
511 }
512 
520 KINLINE void vec2_clamp(vec2* vector, vec2 min, vec2 max) {
521  if (vector) {
522  for (u8 i = 0; i < 2; ++i) {
523  vector->elements[i] = KCLAMP(vector->elements[i], min.elements[i], max.elements[i]);
524  }
525  }
526 }
527 
536 KINLINE vec2 vec2_clamped(vec2 vector, vec2 min, vec2 max) {
537  vec2_clamp(&vector, min, max);
538  return vector;
539 }
540 
548 KINLINE void vec2_clamp_scalar(vec2* vector, f32 min, f32 max) {
549  if (vector) {
550  for (u8 i = 0; i < 2; ++i) {
551  vector->elements[i] = KCLAMP(vector->elements[i], min, max);
552  }
553  }
554 }
555 
565  vec2_clamp_scalar(&vector, min, max);
566  return vector;
567 }
568 
576 KINLINE f32 vec2_distance(vec2 vector_0, vec2 vector_1) {
577  vec2 d = (vec2){vector_0.x - vector_1.x, vector_0.y - vector_1.y};
578  return vec2_length(d);
579 }
580 
590  vec2 d = (vec2){vector_0.x - vector_1.x, vector_0.y - vector_1.y};
591  return vec2_length_squared(d);
592 }
593 
594 KINLINE vec2 vec2_min(vec2 vector_0, vec2 vector_1) {
595  return vec2_create(
596  KMIN(vector_0.x, vector_1.x),
597  KMIN(vector_0.y, vector_1.y));
598 }
599 
600 KINLINE vec2 vec2_max(vec2 vector_0, vec2 vector_1) {
601  return vec2_create(
602  KMAX(vector_0.x, vector_1.x),
603  KMAX(vector_0.y, vector_1.y));
604 }
605 
606 // ------------------------------------------
607 // Vector 3
608 // ------------------------------------------
609 
618 #define vec3_create(x, y, z) \
619  (vec3) { x, y, z }
620 
627 KINLINE vec3 vec3_from_scalar(f32 scalar) { return (vec3){scalar, scalar, scalar}; }
628 
629 /*
630  * @brief Returns a new vec3 containing the x, y and z components of the
631  * supplied vec4, essentially dropping the w component.
632  *
633  * @param vector The 4-component vector to extract from.
634  * @return A new vec3
635  */
637  return (vec3){vector.x, vector.y, vector.z};
638 }
639 
640 /*
641  * @brief Returns a new vec3 containing the x and y components of the
642  * supplied vec2, with a z component specified.
643  *
644  * @param vector The 2-component vector to extract from.
645  * @param z The value to use for the z element.
646  * @return A new vec3
647  */
649  return (vec3){vector.x, vector.y, z};
650 }
651 
661  return (vec4){vector.x, vector.y, vector.z, w};
662 }
663 
668 KINLINE vec3 vec3_zero(void) { return (vec3){0.0f, 0.0f, 0.0f}; }
669 
674 KINLINE vec3 vec3_one(void) { return (vec3){1.0f, 1.0f, 1.0f}; }
675 
679 KINLINE vec3 vec3_up(void) { return (vec3){0.0f, 1.0f, 0.0f}; }
680 
684 KINLINE vec3 vec3_down(void) { return (vec3){0.0f, -1.0f, 0.0f}; }
685 
689 KINLINE vec3 vec3_left(void) { return (vec3){-1.0f, 0.0f, 0.0f}; }
690 
694 KINLINE vec3 vec3_right(void) { return (vec3){1.0f, 0.0f, 0.0f}; }
695 
699 KINLINE vec3 vec3_forward(void) { return (vec3){0.0f, 0.0f, -1.0f}; }
700 
704 KINLINE vec3 vec3_backward(void) { return (vec3){0.0f, 0.0f, 1.0f}; }
705 
713 KINLINE vec3 vec3_add(vec3 vector_0, vec3 vector_1) {
714  return (vec3){vector_0.x + vector_1.x, vector_0.y + vector_1.y,
715  vector_0.z + vector_1.z};
716 }
717 
725 KINLINE vec3 vec3_sub(vec3 vector_0, vec3 vector_1) {
726  return (vec3){vector_0.x - vector_1.x, vector_0.y - vector_1.y,
727  vector_0.z - vector_1.z};
728 }
729 
737 KINLINE vec3 vec3_mul(vec3 vector_0, vec3 vector_1) {
738  return (vec3){vector_0.x * vector_1.x, vector_0.y * vector_1.y,
739  vector_0.z * vector_1.z};
740 }
741 
750 KINLINE vec3 vec3_mul_scalar(vec3 vector_0, f32 scalar) {
751  return (vec3){vector_0.x * scalar, vector_0.y * scalar, vector_0.z * scalar};
752 }
753 
762 KINLINE vec3 vec3_mul_add(vec3 vector_0, vec3 vector_1, vec3 vector_2) {
763  return (vec3){
764  vector_0.x * vector_1.x + vector_2.x,
765  vector_0.y * vector_1.y + vector_2.y,
766  vector_0.z * vector_1.z + vector_2.z};
767 }
768 
776 KINLINE vec3 vec3_div(vec3 vector_0, vec3 vector_1) {
777  return (vec3){vector_0.x / vector_1.x, vector_0.y / vector_1.y,
778  vector_0.z / vector_1.z};
779 }
780 
781 KINLINE vec3 vec3_div_scalar(vec3 vector_0, f32 scalar) {
782  vec3 result;
783  for (u64 i = 0; i < 3; ++i) {
784  result.elements[i] = vector_0.elements[i] / scalar;
785  }
786  return result;
787 }
788 
796  return vector.x * vector.x + vector.y * vector.y + vector.z * vector.z;
797 }
798 
806  return ksqrt(vec3_length_squared(vector));
807 }
808 
814 KINLINE void vec3_normalize(vec3* vector) {
815  const f32 length = vec3_length(*vector);
816  vector->x /= length;
817  vector->y /= length;
818  vector->z /= length;
819 }
820 
828  vec3_normalize(&vector);
829  return vector;
830 }
831 
840 KINLINE f32 vec3_dot(vec3 vector_0, vec3 vector_1) {
841  f32 p = 0;
842  p += vector_0.x * vector_1.x;
843  p += vector_0.y * vector_1.y;
844  p += vector_0.z * vector_1.z;
845  return p;
846 }
847 
857 KINLINE vec3 vec3_cross(vec3 vector_0, vec3 vector_1) {
858  return (vec3){vector_0.y * vector_1.z - vector_0.z * vector_1.y,
859  vector_0.z * vector_1.x - vector_0.x * vector_1.z,
860  vector_0.x * vector_1.y - vector_0.y * vector_1.x};
861 }
862 
873 KINLINE b8 vec3_compare(vec3 vector_0, vec3 vector_1, f32 tolerance) {
874  if (kabs(vector_0.x - vector_1.x) > tolerance) {
875  return false;
876  }
877 
878  if (kabs(vector_0.y - vector_1.y) > tolerance) {
879  return false;
880  }
881 
882  if (kabs(vector_0.z - vector_1.z) > tolerance) {
883  return false;
884  }
885 
886  return true;
887 }
888 
896 KINLINE void vec3_clamp(vec3* vector, vec3 min, vec3 max) {
897  if (vector) {
898  for (u8 i = 0; i < 3; ++i) {
899  vector->elements[i] = KCLAMP(vector->elements[i], min.elements[i], max.elements[i]);
900  }
901  }
902 }
903 
912 KINLINE vec3 vec3_clamped(vec3 vector, vec3 min, vec3 max) {
913  vec3_clamp(&vector, min, max);
914  return vector;
915 }
916 
924 KINLINE void vec3_clamp_scalar(vec3* vector, f32 min, f32 max) {
925  if (vector) {
926  for (u8 i = 0; i < 3; ++i) {
927  vector->elements[i] = KCLAMP(vector->elements[i], min, max);
928  }
929  }
930 }
931 
941  vec3_clamp_scalar(&vector, min, max);
942  return vector;
943 }
944 
952 KINLINE f32 vec3_distance(vec3 vector_0, vec3 vector_1) {
953  vec3 d = (vec3){vector_0.x - vector_1.x, vector_0.y - vector_1.y,
954  vector_0.z - vector_1.z};
955  return vec3_length(d);
956 }
957 
967  vec3 d = (vec3){vector_0.x - vector_1.x, vector_0.y - vector_1.y,
968  vector_0.z - vector_1.z};
969  return vec3_length_squared(d);
970 }
971 
980  f32 length_sq = vec3_length_squared(v_1);
981  if (length_sq == 0.0f) {
982  // NOTE: handle divide-by-zero case (i.e. v_1 is a zero vector).
983  return vec3_zero();
984  }
985  f32 scalar = vec3_dot(v_0, v_1) / length_sq;
986  return vec3_mul_scalar(v_1, scalar);
987 }
988 
997  vec3 out;
998  out.x = v.x * m.data[0 + 0] + v.y * m.data[4 + 0] + v.z * m.data[8 + 0] + w * m.data[12 + 0];
999  out.y = v.x * m.data[0 + 1] + v.y * m.data[4 + 1] + v.z * m.data[8 + 1] + w * m.data[12 + 1];
1000  out.z = v.x * m.data[0 + 2] + v.y * m.data[4 + 2] + v.z * m.data[8 + 2] + w * m.data[12 + 2];
1001  return out;
1002 }
1003 
1004 KINLINE vec3 vec3_min(vec3 vector_0, vec3 vector_1) {
1005  return vec3_create(
1006  KMIN(vector_0.x, vector_1.x),
1007  KMIN(vector_0.y, vector_1.y),
1008  KMIN(vector_0.z, vector_1.z));
1009 }
1010 
1011 KINLINE vec3 vec3_max(vec3 vector_0, vec3 vector_1) {
1012  return vec3_create(
1013  KMAX(vector_0.x, vector_1.x),
1014  KMAX(vector_0.y, vector_1.y),
1015  KMAX(vector_0.z, vector_1.z));
1016 }
1017 
1019  return vec3_create(ksign(v.x), ksign(v.y), ksign(v.z));
1020 }
1021 
1023  vec3 u = vec3_create(q.x, q.y, q.z);
1024  f32 s = q.w;
1025 
1026  return vec3_add(
1027  vec3_add(
1028  vec3_mul_scalar(u, 2.0f * vec3_dot(u, v)),
1029  vec3_mul_scalar(v, (s * s - vec3_dot(u, u)))),
1030  vec3_mul_scalar(vec3_cross(u, v), 2.0f * s));
1031 }
1032 
1033 // ------------------------------------------
1034 // Vector 4
1035 // ------------------------------------------
1036 
1047  vec4 out_vector;
1048 #if defined(KUSE_SIMD)
1049  out_vector.data = _mm_setr_ps(x, y, z, w);
1050 #else
1051  out_vector.x = x;
1052  out_vector.y = y;
1053  out_vector.z = z;
1054  out_vector.w = w;
1055 #endif
1056  return out_vector;
1057 }
1058 
1065 KINLINE vec4 vec4_from_scalar(f32 scalar) { return (vec4){scalar, scalar, scalar, scalar}; }
1066 
1075  return (vec3){vector.x, vector.y, vector.z};
1076 }
1077 
1087 #if defined(KUSE_SIMD)
1088  vec4 out_vector;
1089  out_vector.data = _mm_setr_ps(x, y, z, w);
1090  return out_vector;
1091 #else
1092  return (vec4){vector.x, vector.y, vector.z, w};
1093 #endif
1094 }
1095 
1100 KINLINE vec4 vec4_zero(void) { return (vec4){0.0f, 0.0f, 0.0f, 0.0f}; }
1101 
1106 KINLINE vec4 vec4_one(void) { return (vec4){1.0f, 1.0f, 1.0f, 1.0f}; }
1107 
1115 KINLINE vec4 vec4_add(vec4 vector_0, vec4 vector_1) {
1116  vec4 result;
1117  for (u64 i = 0; i < 4; ++i) {
1118  result.elements[i] = vector_0.elements[i] + vector_1.elements[i];
1119  }
1120  return result;
1121 }
1122 
1130 KINLINE vec4 vec4_sub(vec4 vector_0, vec4 vector_1) {
1131  vec4 result;
1132  for (u64 i = 0; i < 4; ++i) {
1133  result.elements[i] = vector_0.elements[i] - vector_1.elements[i];
1134  }
1135  return result;
1136 }
1137 
1145 KINLINE vec4 vec4_mul(vec4 vector_0, vec4 vector_1) {
1146  vec4 result;
1147  for (u64 i = 0; i < 4; ++i) {
1148  result.elements[i] = vector_0.elements[i] * vector_1.elements[i];
1149  }
1150  return result;
1151 }
1152 
1161 KINLINE vec4 vec4_mul_scalar(vec4 vector_0, f32 scalar) {
1162  return (vec4){vector_0.x * scalar, vector_0.y * scalar, vector_0.z * scalar, vector_0.w * scalar};
1163 }
1164 
1173 KINLINE vec4 vec4_mul_add(vec4 vector_0, vec4 vector_1, vec4 vector_2) {
1174  return (vec4){
1175  vector_0.x * vector_1.x + vector_2.x,
1176  vector_0.y * vector_1.y + vector_2.y,
1177  vector_0.z * vector_1.z + vector_2.z,
1178  vector_0.w * vector_1.w + vector_2.w,
1179  };
1180 }
1181 
1189 KINLINE vec4 vec4_div(vec4 vector_0, vec4 vector_1) {
1190  vec4 result;
1191  for (u64 i = 0; i < 4; ++i) {
1192  result.elements[i] = vector_0.elements[i] / vector_1.elements[i];
1193  }
1194  return result;
1195 }
1196 
1197 KINLINE vec4 vec4_div_scalar(vec4 vector_0, f32 scalar) {
1198  vec4 result;
1199  for (u64 i = 0; i < 4; ++i) {
1200  result.elements[i] = vector_0.elements[i] / scalar;
1201  }
1202  return result;
1203 }
1204 
1212  return vector.x * vector.x + vector.y * vector.y + vector.z * vector.z +
1213  vector.w * vector.w;
1214 }
1215 
1223  return ksqrt(vec4_length_squared(vector));
1224 }
1225 
1231 KINLINE void vec4_normalize(vec4* vector) {
1232  const f32 length = vec4_length(*vector);
1233  vector->x /= length;
1234  vector->y /= length;
1235  vector->z /= length;
1236  vector->w /= length;
1237 }
1238 
1246  vec4_normalize(&vector);
1247  return vector;
1248 }
1249 
1264 KINLINE f32 vec4_dot_f32(f32 a0, f32 a1, f32 a2, f32 a3, f32 b0, f32 b1, f32 b2,
1265  f32 b3) {
1266  f32 p;
1267  p = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3;
1268  return p;
1269 }
1270 
1281 KINLINE b8 vec4_compare(vec4 vector_0, vec4 vector_1, f32 tolerance) {
1282  if (kabs(vector_0.x - vector_1.x) > tolerance) {
1283  return false;
1284  }
1285 
1286  if (kabs(vector_0.y - vector_1.y) > tolerance) {
1287  return false;
1288  }
1289 
1290  if (kabs(vector_0.z - vector_1.z) > tolerance) {
1291  return false;
1292  }
1293 
1294  if (kabs(vector_0.w - vector_1.w) > tolerance) {
1295  return false;
1296  }
1297 
1298  return true;
1299 }
1300 
1308 KINLINE void vec4_clamp(vec4* vector, vec4 min, vec4 max) {
1309  if (vector) {
1310  for (u8 i = 0; i < 4; ++i) {
1311  vector->elements[i] = KCLAMP(vector->elements[i], min.elements[i], max.elements[i]);
1312  }
1313  }
1314 }
1315 
1324 KINLINE vec4 vec4_clamped(vec4 vector, vec4 min, vec4 max) {
1325  vec4_clamp(&vector, min, max);
1326  return vector;
1327 }
1328 
1336 KINLINE void vec4_clamp_scalar(vec4* vector, f32 min, f32 max) {
1337  if (vector) {
1338  for (u8 i = 0; i < 4; ++i) {
1339  vector->elements[i] = KCLAMP(vector->elements[i], min, max);
1340  }
1341  }
1342 }
1343 
1353  vec4_clamp_scalar(&vector, min, max);
1354  return vector;
1355 }
1356 
1370  mat4 out_matrix;
1371  kzero_memory(out_matrix.data, sizeof(f32) * 16);
1372  out_matrix.data[0] = 1.0f;
1373  out_matrix.data[5] = 1.0f;
1374  out_matrix.data[10] = 1.0f;
1375  out_matrix.data[15] = 1.0f;
1376  return out_matrix;
1377 }
1378 
1386 KINLINE mat4 mat4_mul(mat4 matrix_0, mat4 matrix_1) {
1387  mat4 out_matrix = mat4_identity();
1388 
1389  const f32* m1_ptr = matrix_0.data;
1390  const f32* m2_ptr = matrix_1.data;
1391  f32* dst_ptr = out_matrix.data;
1392 
1393  for (i32 i = 0; i < 4; ++i) {
1394  for (i32 j = 0; j < 4; ++j) {
1395  *dst_ptr = m1_ptr[0] * m2_ptr[0 + j] + m1_ptr[1] * m2_ptr[4 + j] +
1396  m1_ptr[2] * m2_ptr[8 + j] + m1_ptr[3] * m2_ptr[12 + j];
1397  dst_ptr++;
1398  }
1399  m1_ptr += 4;
1400  }
1401  return out_matrix;
1402 }
1403 
1416 KINLINE mat4 mat4_orthographic(f32 left, f32 right, f32 bottom, f32 top,
1417  f32 near_clip, f32 far_clip) {
1418  mat4 out_matrix = mat4_identity();
1419 
1420  f32 lr = 1.0f / (left - right);
1421  f32 bt = 1.0f / (bottom - top);
1422  f32 nf = 1.0f / (near_clip - far_clip);
1423 
1424  out_matrix.data[0] = -2.0f * lr;
1425  out_matrix.data[5] = -2.0f * bt;
1426  out_matrix.data[10] = nf;
1427 
1428  out_matrix.data[12] = (left + right) * lr;
1429  out_matrix.data[13] = (top + bottom) * bt;
1430  out_matrix.data[14] = -near_clip * nf;
1431 
1432  return out_matrix;
1433 }
1434 
1445 KINLINE mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip, f32 far_clip) {
1446  f32 half_tan_fov = ktan(fov_radians * 0.5f);
1447  mat4 out_matrix;
1448  kzero_memory(out_matrix.data, sizeof(f32) * 16);
1449  out_matrix.data[0] = 1.0f / (aspect_ratio * half_tan_fov);
1450  out_matrix.data[5] = 1.0f / half_tan_fov;
1451  out_matrix.data[10] = far_clip / (near_clip - far_clip);
1452  out_matrix.data[11] = -1.0f;
1453  out_matrix.data[14] = (far_clip * near_clip) / (near_clip - far_clip);
1454  return out_matrix;
1455 }
1456 
1466 KINLINE mat4 mat4_look_at(vec3 position, vec3 target, vec3 up) {
1467  mat4 out_matrix;
1468  vec3 z_axis = vec3_normalized(vec3_sub(target, position));
1469  vec3 x_axis = vec3_normalized(vec3_cross(z_axis, up));
1470  vec3 y_axis = vec3_cross(x_axis, z_axis);
1471 
1472  out_matrix.data[0] = x_axis.x;
1473  out_matrix.data[1] = y_axis.x;
1474  out_matrix.data[2] = -z_axis.x;
1475  out_matrix.data[3] = 0;
1476  out_matrix.data[4] = x_axis.y;
1477  out_matrix.data[5] = y_axis.y;
1478  out_matrix.data[6] = -z_axis.y;
1479  out_matrix.data[7] = 0;
1480  out_matrix.data[8] = x_axis.z;
1481  out_matrix.data[9] = y_axis.z;
1482  out_matrix.data[10] = -z_axis.z;
1483  out_matrix.data[11] = 0;
1484  out_matrix.data[12] = -vec3_dot(x_axis, position);
1485  out_matrix.data[13] = -vec3_dot(y_axis, position);
1486  out_matrix.data[14] = vec3_dot(z_axis, position);
1487  out_matrix.data[15] = 1.0f;
1488  return out_matrix;
1489 }
1490 
1498  mat4 out_matrix;
1499  out_matrix.data[0] = matrix.data[0];
1500  out_matrix.data[1] = matrix.data[4];
1501  out_matrix.data[2] = matrix.data[8];
1502  out_matrix.data[3] = matrix.data[12];
1503  out_matrix.data[4] = matrix.data[1];
1504  out_matrix.data[5] = matrix.data[5];
1505  out_matrix.data[6] = matrix.data[9];
1506  out_matrix.data[7] = matrix.data[13];
1507  out_matrix.data[8] = matrix.data[2];
1508  out_matrix.data[9] = matrix.data[6];
1509  out_matrix.data[10] = matrix.data[10];
1510  out_matrix.data[11] = matrix.data[14];
1511  out_matrix.data[12] = matrix.data[3];
1512  out_matrix.data[13] = matrix.data[7];
1513  out_matrix.data[14] = matrix.data[11];
1514  out_matrix.data[15] = matrix.data[15];
1515  return out_matrix;
1516 }
1517 
1525  const f32* m = matrix.data;
1526 
1527  f32 t0 = m[10] * m[15];
1528  f32 t1 = m[14] * m[11];
1529  f32 t2 = m[6] * m[15];
1530  f32 t3 = m[14] * m[7];
1531  f32 t4 = m[6] * m[11];
1532  f32 t5 = m[10] * m[7];
1533  f32 t6 = m[2] * m[15];
1534  f32 t7 = m[14] * m[3];
1535  f32 t8 = m[2] * m[11];
1536  f32 t9 = m[10] * m[3];
1537  f32 t10 = m[2] * m[7];
1538  f32 t11 = m[6] * m[3];
1539 
1540  mat3 temp_mat;
1541  f32* o = temp_mat.data;
1542 
1543  o[0] = (t0 * m[5] + t3 * m[9] + t4 * m[13]) -
1544  (t1 * m[5] + t2 * m[9] + t5 * m[13]);
1545  o[1] = (t1 * m[1] + t6 * m[9] + t9 * m[13]) -
1546  (t0 * m[1] + t7 * m[9] + t8 * m[13]);
1547  o[2] = (t2 * m[1] + t7 * m[5] + t10 * m[13]) -
1548  (t3 * m[1] + t6 * m[5] + t11 * m[13]);
1549  o[3] = (t5 * m[1] + t8 * m[5] + t11 * m[9]) -
1550  (t4 * m[1] + t9 * m[5] + t10 * m[9]);
1551 
1552  f32 determinant = 1.0f / (m[0] * o[0] + m[4] * o[1] + m[8] * o[2] + m[12] * o[3]);
1553  return determinant;
1554 }
1555 
1563  const f32* m = matrix.data;
1564 
1565  f32 t0 = m[10] * m[15];
1566  f32 t1 = m[14] * m[11];
1567  f32 t2 = m[6] * m[15];
1568  f32 t3 = m[14] * m[7];
1569  f32 t4 = m[6] * m[11];
1570  f32 t5 = m[10] * m[7];
1571  f32 t6 = m[2] * m[15];
1572  f32 t7 = m[14] * m[3];
1573  f32 t8 = m[2] * m[11];
1574  f32 t9 = m[10] * m[3];
1575  f32 t10 = m[2] * m[7];
1576  f32 t11 = m[6] * m[3];
1577  f32 t12 = m[8] * m[13];
1578  f32 t13 = m[12] * m[9];
1579  f32 t14 = m[4] * m[13];
1580  f32 t15 = m[12] * m[5];
1581  f32 t16 = m[4] * m[9];
1582  f32 t17 = m[8] * m[5];
1583  f32 t18 = m[0] * m[13];
1584  f32 t19 = m[12] * m[1];
1585  f32 t20 = m[0] * m[9];
1586  f32 t21 = m[8] * m[1];
1587  f32 t22 = m[0] * m[5];
1588  f32 t23 = m[4] * m[1];
1589 
1590  mat4 out_matrix;
1591  f32* o = out_matrix.data;
1592 
1593  o[0] = (t0 * m[5] + t3 * m[9] + t4 * m[13]) -
1594  (t1 * m[5] + t2 * m[9] + t5 * m[13]);
1595  o[1] = (t1 * m[1] + t6 * m[9] + t9 * m[13]) -
1596  (t0 * m[1] + t7 * m[9] + t8 * m[13]);
1597  o[2] = (t2 * m[1] + t7 * m[5] + t10 * m[13]) -
1598  (t3 * m[1] + t6 * m[5] + t11 * m[13]);
1599  o[3] = (t5 * m[1] + t8 * m[5] + t11 * m[9]) -
1600  (t4 * m[1] + t9 * m[5] + t10 * m[9]);
1601 
1602  f32 d = 1.0f / (m[0] * o[0] + m[4] * o[1] + m[8] * o[2] + m[12] * o[3]);
1603 
1604  // Check for singular matrix (determinant near zero)
1605  if (kabs(d) < 1e-6f) {
1606  // Return identity matrix if the determinant is close to zero (singular matrix)
1607  return mat4_identity();
1608  }
1609 
1610  o[0] = d * o[0];
1611  o[1] = d * o[1];
1612  o[2] = d * o[2];
1613  o[3] = d * o[3];
1614  o[4] = d * ((t1 * m[4] + t2 * m[8] + t5 * m[12]) -
1615  (t0 * m[4] + t3 * m[8] + t4 * m[12]));
1616  o[5] = d * ((t0 * m[0] + t7 * m[8] + t8 * m[12]) -
1617  (t1 * m[0] + t6 * m[8] + t9 * m[12]));
1618  o[6] = d * ((t3 * m[0] + t6 * m[4] + t11 * m[12]) -
1619  (t2 * m[0] + t7 * m[4] + t10 * m[12]));
1620  o[7] = d * ((t4 * m[0] + t9 * m[4] + t10 * m[8]) -
1621  (t5 * m[0] + t8 * m[4] + t11 * m[8]));
1622  o[8] = d * ((t12 * m[7] + t15 * m[11] + t16 * m[15]) -
1623  (t13 * m[7] + t14 * m[11] + t17 * m[15]));
1624  o[9] = d * ((t13 * m[3] + t18 * m[11] + t21 * m[15]) -
1625  (t12 * m[3] + t19 * m[11] + t20 * m[15]));
1626  o[10] = d * ((t14 * m[3] + t19 * m[7] + t22 * m[15]) -
1627  (t15 * m[3] + t18 * m[7] + t23 * m[15]));
1628  o[11] = d * ((t17 * m[3] + t20 * m[7] + t23 * m[11]) -
1629  (t16 * m[3] + t21 * m[7] + t22 * m[11]));
1630  o[12] = d * ((t14 * m[10] + t17 * m[14] + t13 * m[6]) -
1631  (t16 * m[14] + t12 * m[6] + t15 * m[10]));
1632  o[13] = d * ((t20 * m[14] + t12 * m[2] + t19 * m[10]) -
1633  (t18 * m[10] + t21 * m[14] + t13 * m[2]));
1634  o[14] = d * ((t18 * m[6] + t23 * m[14] + t15 * m[2]) -
1635  (t22 * m[14] + t14 * m[2] + t19 * m[6]));
1636  o[15] = d * ((t22 * m[10] + t16 * m[2] + t21 * m[6]) -
1637  (t20 * m[6] + t23 * m[10] + t17 * m[2]));
1638 
1639  return out_matrix;
1640 }
1641 
1649  mat4 out_matrix = mat4_identity();
1650  out_matrix.data[12] = position.x;
1651  out_matrix.data[13] = position.y;
1652  out_matrix.data[14] = position.z;
1653  return out_matrix;
1654 }
1655 
1663  mat4 out_matrix = mat4_identity();
1664  out_matrix.data[0] = scale.x;
1665  out_matrix.data[5] = scale.y;
1666  out_matrix.data[10] = scale.z;
1667  return out_matrix;
1668 }
1669 
1679  mat4 out_matrix;
1680 
1681  out_matrix.data[0] = (1.0f - 2.0f * (r.y * r.y + r.z * r.z)) * s.x;
1682  out_matrix.data[1] = (r.x * r.y + r.z * r.w) * s.x * 2.0f;
1683  out_matrix.data[2] = (r.x * r.z - r.y * r.w) * s.x * 2.0f;
1684  out_matrix.data[3] = 0.0f;
1685  out_matrix.data[4] = (r.x * r.y - r.z * r.w) * s.y * 2.0f;
1686  out_matrix.data[5] = (1.0f - 2.0f * (r.x * r.x + r.z * r.z)) * s.y;
1687  out_matrix.data[6] = (r.y * r.z + r.x * r.w) * s.y * 2.0f;
1688  out_matrix.data[7] = 0.0f;
1689  out_matrix.data[8] = (r.x * r.z + r.y * r.w) * s.z * 2.0f;
1690  out_matrix.data[9] = (r.y * r.z - r.x * r.w) * s.z * 2.0f;
1691  out_matrix.data[10] = (1.0f - 2.0f * (r.x * r.x + r.y * r.y)) * s.z;
1692  out_matrix.data[11] = 0.0f;
1693  out_matrix.data[12] = t.x;
1694  out_matrix.data[13] = t.y;
1695  out_matrix.data[14] = t.z;
1696  out_matrix.data[15] = 1.0f;
1697 
1698  return out_matrix;
1699 }
1700 
1707 KINLINE mat4 mat4_euler_x(f32 angle_radians) {
1708  mat4 out_matrix = mat4_identity();
1709  f32 c = kcos(angle_radians);
1710  f32 s = ksin(angle_radians);
1711 
1712  out_matrix.data[5] = c;
1713  out_matrix.data[6] = s;
1714  out_matrix.data[9] = -s;
1715  out_matrix.data[10] = c;
1716  return out_matrix;
1717 }
1718 
1725 KINLINE mat4 mat4_euler_y(f32 angle_radians) {
1726  mat4 out_matrix = mat4_identity();
1727  f32 c = kcos(angle_radians);
1728  f32 s = ksin(angle_radians);
1729 
1730  out_matrix.data[0] = c;
1731  out_matrix.data[2] = -s;
1732  out_matrix.data[8] = s;
1733  out_matrix.data[10] = c;
1734  return out_matrix;
1735 }
1736 
1743 KINLINE mat4 mat4_euler_z(f32 angle_radians) {
1744  mat4 out_matrix = mat4_identity();
1745 
1746  f32 c = kcos(angle_radians);
1747  f32 s = ksin(angle_radians);
1748 
1749  out_matrix.data[0] = c;
1750  out_matrix.data[1] = s;
1751  out_matrix.data[4] = -s;
1752  out_matrix.data[5] = c;
1753  return out_matrix;
1754 }
1755 
1764 KINLINE mat4 mat4_euler_xyz(f32 x_radians, f32 y_radians, f32 z_radians) {
1765  mat4 rx = mat4_euler_x(x_radians);
1766  mat4 ry = mat4_euler_y(y_radians);
1767  mat4 rz = mat4_euler_z(z_radians);
1768  mat4 out_matrix = mat4_mul(rx, ry);
1769  out_matrix = mat4_mul(out_matrix, rz);
1770  return out_matrix;
1771 }
1772 
1780  vec3 forward;
1781  forward.x = -matrix.data[8];
1782  forward.y = -matrix.data[9];
1783  forward.z = -matrix.data[10];
1784  vec3_normalize(&forward);
1785  return forward;
1786 }
1787 
1795  vec3 backward;
1796  backward.x = matrix.data[8];
1797  backward.y = matrix.data[9];
1798  backward.z = matrix.data[10];
1799  vec3_normalize(&backward);
1800  return backward;
1801 }
1802 
1810  vec3 up;
1811  up.x = matrix.data[1];
1812  up.y = matrix.data[5];
1813  up.z = matrix.data[9];
1814  vec3_normalize(&up);
1815  return up;
1816 }
1817 
1825  vec3 down;
1826  down.x = -matrix.data[1];
1827  down.y = -matrix.data[5];
1828  down.z = -matrix.data[9];
1829  vec3_normalize(&down);
1830  return down;
1831 }
1832 
1840  vec3 left;
1841  left.x = -matrix.data[0];
1842  left.y = -matrix.data[1];
1843  left.z = -matrix.data[2];
1844  vec3_normalize(&left);
1845  return left;
1846 }
1847 
1855  vec3 right;
1856  right.x = matrix.data[0];
1857  right.y = matrix.data[1];
1858  right.z = matrix.data[2];
1859  vec3_normalize(&right);
1860  return right;
1861 }
1862 
1870  vec3 pos;
1871  pos.x = matrix.data[12];
1872  pos.y = matrix.data[13];
1873  pos.z = matrix.data[14];
1874  return pos;
1875 }
1876 
1884  return (vec3){matrix.data[0], matrix.data[5], matrix.data[10]};
1885 }
1886 
1895  return (vec3){
1896  v.x * m.data[0] + v.y * m.data[4] + v.z * m.data[8] + m.data[12],
1897  v.x * m.data[1] + v.y * m.data[5] + v.z * m.data[9] + m.data[13],
1898  v.x * m.data[2] + v.y * m.data[6] + v.z * m.data[10] + m.data[14]};
1899 }
1900 
1909  return (vec3){
1910  v.x * m.data[0] + v.y * m.data[4] + v.z * m.data[8] + m.data[12],
1911  v.x * m.data[1] + v.y * m.data[5] + v.z * m.data[9] + m.data[13],
1912  v.x * m.data[2] + v.y * m.data[6] + v.z * m.data[10] + m.data[14]};
1913 }
1914 
1923  return (vec4){
1924  v.x * m.data[0] + v.y * m.data[1] + v.z * m.data[2] + v.w * m.data[3],
1925  v.x * m.data[4] + v.y * m.data[5] + v.z * m.data[6] + v.w * m.data[7],
1926  v.x * m.data[8] + v.y * m.data[9] + v.z * m.data[10] + v.w * m.data[11],
1927  v.x * m.data[12] + v.y * m.data[13] + v.z * m.data[14] + v.w * m.data[15]};
1928 }
1929 
1938  return (vec4){
1939  v.x * m.data[0] + v.y * m.data[4] + v.z * m.data[8] + v.w * m.data[12],
1940  v.x * m.data[1] + v.y * m.data[5] + v.z * m.data[9] + v.w * m.data[13],
1941  v.x * m.data[2] + v.y * m.data[6] + v.z * m.data[10] + v.w * m.data[14],
1942  v.x * m.data[3] + v.y * m.data[7] + v.z * m.data[11] + v.w * m.data[15]};
1943 }
1944 
1945 // ------------------------------------------
1946 // Quaternion
1947 // ------------------------------------------
1948 
1954 KINLINE quat quat_identity(void) { return (quat){0, 0, 0, 1.0f}; }
1955 
1960 
1968  return ksqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
1969 }
1970 
1978  f32 normal = quat_normal(q);
1979  return (quat){q.x / normal, q.y / normal, q.z / normal, q.w / normal};
1980 }
1981 
1989 KINLINE quat quat_conjugate(quat q) { return (quat){-q.x, -q.y, -q.z, q.w}; }
1990 
1998 
2007  quat out_quaternion;
2008 
2009  out_quaternion.x =
2010  q_0.x * q_1.w + q_0.y * q_1.z - q_0.z * q_1.y + q_0.w * q_1.x;
2011 
2012  out_quaternion.y =
2013  -q_0.x * q_1.z + q_0.y * q_1.w + q_0.z * q_1.x + q_0.w * q_1.y;
2014 
2015  out_quaternion.z =
2016  q_0.x * q_1.y - q_0.y * q_1.x + q_0.z * q_1.w + q_0.w * q_1.z;
2017 
2018  out_quaternion.w =
2019  -q_0.x * q_1.x - q_0.y * q_1.y - q_0.z * q_1.z + q_0.w * q_1.w;
2020 
2021  return out_quaternion;
2022 }
2023 
2032  return q_0.x * q_1.x + q_0.y * q_1.y + q_0.z * q_1.z + q_0.w * q_1.w;
2033 }
2034 
2042 #if 0
2043  mat4 out_matrix = mat4_identity();
2044 
2045  // https://stackoverflow.com/questions/1556260/convert-quaternion-rotation-to-rotation-matrix
2046 
2047  quat n = quat_normalize(q);
2048 
2049  out_matrix.data[0] = 1.0f - 2.0f * n.y * n.y - 2.0f * n.z * n.z;
2050  out_matrix.data[1] = 2.0f * n.x * n.y - 2.0f * n.z * n.w;
2051  out_matrix.data[2] = 2.0f * n.x * n.z + 2.0f * n.y * n.w;
2052 
2053  out_matrix.data[4] = 2.0f * n.x * n.y + 2.0f * n.z * n.w;
2054  out_matrix.data[5] = 1.0f - 2.0f * n.x * n.x - 2.0f * n.z * n.z;
2055  out_matrix.data[6] = 2.0f * n.y * n.z - 2.0f * n.x * n.w;
2056 
2057  out_matrix.data[8] = 2.0f * n.x * n.z - 2.0f * n.y * n.w;
2058  out_matrix.data[9] = 2.0f * n.y * n.z + 2.0f * n.x * n.w;
2059  out_matrix.data[10] = 1.0f - 2.0f * n.x * n.x - 2.0f * n.y * n.y;
2060 
2061  return out_matrix;
2062 #else
2063  /*mat4 m;
2064  float x = q.x, y = q.y, z = q.z, w = q.w;
2065  float xx = x * x, yy = y * y, zz = z * z;
2066  float xy = x * y, xz = x * z, yz = y * z;
2067  float wx = w * x, wy = w * y, wz = w * z;
2068 
2069  // Right (X)
2070  m.data[0] = 1 - 2 * (yy + zz);
2071  m.data[1] = 2 * (xy + wz);
2072  m.data[2] = 2 * (xz - wy);
2073  m.data[3] = 0;
2074 
2075  // Up (Y)
2076  m.data[4] = 2 * (xy - wz);
2077  m.data[5] = 1 - 2 * (xx + zz);
2078  m.data[6] = 2 * (yz + wx);
2079  m.data[7] = 0;
2080 
2081  // Forward (-Z)
2082  m.data[8] = -(2 * (xz + wy));
2083  m.data[9] = -(2 * (yz - wx));
2084  m.data[10] = -(1 - 2 * (xx + yy));
2085  m.data[11] = 0;
2086 
2087  // translation = identity for now
2088  m.data[12] = 0;
2089  m.data[13] = 0;
2090  m.data[14] = 0;
2091  m.data[15] = 1;
2092 
2093  return m;*/
2094 
2095  /*
2096  quat n = quat_normalize(q);
2097 
2098  mat4 m = {0};
2099 
2100  float x = n.x, y = n.y, z = n.z, w = n.w;
2101 
2102  // Right (X)
2103  m.data[0] = 1 - 2 * y * y - 2 * z * z;
2104  m.data[1] = 2 * x * y + 2 * w * z;
2105  m.data[2] = 2 * x * z - 2 * w * y;
2106  m.data[3] = 0;
2107 
2108  // Up (Y)
2109  m.data[4] = 2 * x * y - 2 * w * z;
2110  m.data[5] = 1 - 2 * x * x - 2 * z * z;
2111  m.data[6] = 2 * y * z + 2 * w * x;
2112  m.data[7] = 0;
2113 
2114  // Forward (-Z)
2115  m.data[8] = 2 * x * z + 2 * w * y;
2116  m.data[9] = 2 * y * z - 2 * w * x;
2117  m.data[10] = -(1 - 2 * x * x - 2 * y * y);
2118  m.data[11] = 0;
2119 
2120  m.data[12] = 0;
2121  m.data[13] = 0;
2122  m.data[14] = 0;
2123  m.data[15] = 1;
2124 
2125  return m;*/
2126 
2127  quat n = quat_normalize(q);
2128  float x = n.x, y = n.y, z = n.z, w = n.w;
2129 
2130  mat4 m = {0};
2131 
2132  // Right (X)
2133  m.data[0] = 1 - 2 * y * y - 2 * z * z;
2134  m.data[1] = 2 * x * y + 2 * w * z;
2135  m.data[2] = 2 * x * z - 2 * w * y;
2136  m.data[3] = 0;
2137 
2138  // Up (Y)
2139  m.data[4] = 2 * x * y - 2 * w * z;
2140  m.data[5] = 1 - 2 * x * x - 2 * z * z;
2141  m.data[6] = 2 * y * z + 2 * w * x;
2142  m.data[7] = 0;
2143 
2144  // Forward (-Z)
2145  m.data[8] = -(2 * x * z + 2 * w * y);
2146  m.data[9] = -(2 * y * z - 2 * w * x);
2147  m.data[10] = -(1 - 2 * x * x - 2 * y * y);
2148  m.data[11] = 0;
2149 
2150  // Translation identity
2151  m.data[12] = 0;
2152  m.data[13] = 0;
2153  m.data[14] = 0;
2154  m.data[15] = 1;
2155 
2156  return m;
2157 #endif
2158 }
2159 
2169  mat4 out_matrix;
2170 
2171  f32* o = out_matrix.data;
2172  o[0] = (q.x * q.x) - (q.y * q.y) - (q.z * q.z) + (q.w * q.w);
2173  o[1] = 2.0f * ((q.x * q.y) + (q.z * q.w));
2174  o[2] = 2.0f * ((q.x * q.z) - (q.y * q.w));
2175  o[3] = center.x - center.x * o[0] - center.y * o[1] - center.z * o[2];
2176 
2177  o[4] = 2.0f * ((q.x * q.y) - (q.z * q.w));
2178  o[5] = -(q.x * q.x) + (q.y * q.y) - (q.z * q.z) + (q.w * q.w);
2179  o[6] = 2.0f * ((q.y * q.z) + (q.x * q.w));
2180  o[7] = center.y - center.x * o[4] - center.y * o[5] - center.z * o[6];
2181 
2182  o[8] = 2.0f * ((q.x * q.z) + (q.y * q.w));
2183  o[9] = 2.0f * ((q.y * q.z) - (q.x * q.w));
2184  o[10] = -(q.x * q.x) - (q.y * q.y) + (q.z * q.z) + (q.w * q.w);
2185  o[11] = center.z - center.x * o[8] - center.y * o[9] - center.z * o[10];
2186 
2187  o[12] = 0.0f;
2188  o[13] = 0.0f;
2189  o[14] = 0.0f;
2190  o[15] = 1.0f;
2191  return out_matrix;
2192 }
2193 
2202 KINLINE quat quat_from_axis_angle(vec3 axis, f32 angle, b8 normalize) {
2203  const f32 half_angle = 0.5f * angle;
2204  f32 s = ksin(half_angle);
2205  f32 c = kcos(half_angle);
2206 
2207  quat q = (quat){s * axis.x, s * axis.y, s * axis.z, c};
2208  if (normalize) {
2209  return quat_normalize(q);
2210  }
2211  return q;
2212 }
2213 
2224 KINLINE quat quat_slerp(quat q_0, quat q_1, f32 percentage) {
2225  quat out_quaternion;
2226  // Source: https://en.wikipedia.org/wiki/Slerp
2227  // Only unit quaternions are valid rotations.
2228  // Normalize to avoid undefined behavior.
2229  quat v0 = quat_normalize(q_0);
2230  quat v1 = quat_normalize(q_1);
2231 
2232  // Compute the cosine of the angle between the two vectors.
2233  f32 dot = quat_dot(v0, v1);
2234 
2235  // If the dot product is negative, slerp won't take
2236  // the shorter path. Note that v1 and -v1 are equivalent when
2237  // the negation is applied to all four components. Fix by
2238  // reversing one quaternion.
2239  if (dot < 0.0f) {
2240  v1.x = -v1.x;
2241  v1.y = -v1.y;
2242  v1.z = -v1.z;
2243  v1.w = -v1.w;
2244  dot = -dot;
2245  }
2246 
2247  const f32 DOT_THRESHOLD = 0.9995f;
2248  if (dot > DOT_THRESHOLD) {
2249  // If the inputs are too close for comfort, linearly interpolate
2250  // and normalize the result.
2251  out_quaternion = (quat){v0.x + ((v1.x - v0.x) * percentage),
2252  v0.y + ((v1.y - v0.y) * percentage),
2253  v0.z + ((v1.z - v0.z) * percentage),
2254  v0.w + ((v1.w - v0.w) * percentage)};
2255 
2256  return quat_normalize(out_quaternion);
2257  }
2258 
2259  // Since dot is in range [0, DOT_THRESHOLD], acos is safe
2260  f32 theta_0 = kacos(dot); // theta_0 = angle between input vectors
2261  f32 theta = theta_0 * percentage; // theta = angle between v0 and result
2262  f32 sin_theta = ksin(theta); // compute this value only once
2263  f32 sin_theta_0 = ksin(theta_0); // compute this value only once
2264 
2265  f32 s0 =
2266  kcos(theta) -
2267  dot * sin_theta / sin_theta_0; // == sin(theta_0 - theta) / sin(theta_0)
2268  f32 s1 = sin_theta / sin_theta_0;
2269 
2270  return (quat){(v0.x * s0) + (v1.x * s1), (v0.y * s0) + (v1.y * s1),
2271  (v0.z * s0) + (v1.z * s1), (v0.w * s0) + (v1.w * s1)};
2272 }
2273 
2280 KINLINE f32 deg_to_rad(f32 degrees) { return degrees * K_DEG2RAD_MULTIPLIER; }
2281 
2288 KINLINE f32 rad_to_deg(f32 radians) { return radians * K_RAD2DEG_MULTIPLIER; }
2289 
2300 KINLINE f32 range_convert_f32(f32 value, f32 old_min, f32 old_max, f32 new_min,
2301  f32 new_max) {
2302  return (((value - old_min) * (new_max - new_min)) / (old_max - old_min)) +
2303  new_min;
2304 }
2305 
2314 KINLINE void rgbu_to_u32(u32 r, u32 g, u32 b, u32* out_u32) {
2315  *out_u32 = (((r & 0x0FF) << 16) | ((g & 0x0FF) << 8) | (b & 0x0FF));
2316 }
2317 
2326 KINLINE void u32_to_rgb(u32 rgbu, u32* out_r, u32* out_g, u32* out_b) {
2327  *out_r = (rgbu >> 16) & 0x0FF;
2328  *out_g = (rgbu >> 8) & 0x0FF;
2329  *out_b = (rgbu) & 0x0FF;
2330 }
2331 
2341 KINLINE void rgb_u32_to_vec3(u32 r, u32 g, u32 b, vec3* out_v) {
2342  out_v->r = r / 255.0f;
2343  out_v->g = g / 255.0f;
2344  out_v->b = b / 255.0f;
2345 }
2346 
2355 KINLINE void vec3_to_rgb_u32(vec3 v, u32* out_r, u32* out_g, u32* out_b) {
2356  *out_r = v.r * 255;
2357  *out_g = v.g * 255;
2358  *out_b = v.b * 255;
2359 }
2360 
2362 
2378 KAPI kfrustum kfrustum_create(vec3 position, vec3 target, vec3 up, f32 aspect, f32 fov, f32 near, f32 far);
2379 
2381 
2389 KAPI void kfrustum_corner_points_world_space(mat4 projection_view, vec4* corners);
2390 
2399 KAPI f32 plane_signed_distance(const plane_3d* p, const vec3* position);
2400 
2411 KAPI b8 plane_intersects_sphere(const plane_3d* p, const vec3* center,
2412  f32 radius);
2413 
2423 KAPI b8 kfrustum_intersects_sphere(const kfrustum* f, const vec3* center, f32 radius);
2424 
2434 
2446 KAPI b8 plane_intersects_aabb(const plane_3d* p, const vec3* center, const vec3* extents);
2447 
2460  const vec3* extents);
2461 
2463  return (point.x >= rect.x && point.x <= rect.x + rect.width) && (point.y >= rect.y && point.y <= rect.y + rect.height);
2464 }
2465 
2466 KAPI f32 vec3_distance_to_line(vec3 point, vec3 line_start, vec3 line_direction);
2467 
2469  return (vec3){
2470  (extents.min.x + extents.max.x) * 0.5f,
2471  (extents.min.y + extents.max.y) * 0.5f,
2472  };
2473 }
2474 
2476  return (vec3){
2477  kabs(extents.min.x - extents.max.x) * 0.5f,
2478  kabs(extents.min.y - extents.max.y) * 0.5f,
2479  };
2480 }
2481 
2483  return (extents_3d){
2484  .min = vec3_zero(),
2485  .max = vec3_zero()};
2486 }
2487 
2489  return (extents_3d){
2490  .min = vec3_from_scalar(-1),
2491  .max = vec3_one()};
2492 }
2493 
2495  return (extents_3d){
2496  .min = vec3_from_scalar(-scalar),
2497  .max = vec3_from_scalar(scalar)};
2498 }
2499 
2501  return (extents_3d){
2502  .min = vec3_mul_scalar(size, -1.0f),
2503  .max = size};
2504 }
2505 
2507  return (vec3){
2508  (extents.min.x + extents.max.x) * 0.5f,
2509  (extents.min.y + extents.max.y) * 0.5f,
2510  (extents.min.z + extents.max.z) * 0.5f,
2511  };
2512 }
2513 
2515  return (vec3){
2516  kabs(extents.min.x - extents.max.x) * 0.5f,
2517  kabs(extents.min.y - extents.max.y) * 0.5f,
2518  kabs(extents.min.z - extents.max.z) * 0.5f,
2519  };
2520 }
2521 
2523  vec3 size = vec3_sub(extents.max, extents.min);
2524  return (vec3){
2525  kabs(size.x),
2526  kabs(size.y),
2527  kabs(size.z)};
2528 }
2529 
2531  return (extents_3d){
2532  .min = vec3_min(a.min, b.min),
2533  .max = vec3_max(a.max, b.max)};
2534 }
2535 
2538 }
2539 
2541  return (vec2){
2542  (v_0.x - v_1.x) * 0.5f,
2543  (v_0.y - v_1.y) * 0.5f};
2544 }
2545 
2547  return (vec3){
2548  (v_0.x - v_1.x) * 0.5f,
2549  (v_0.y - v_1.y) * 0.5f,
2550  (v_0.z - v_1.z) * 0.5f};
2551 }
2552 
2554  return vec3_add(vec3_mul_scalar(v_0, 1.0f - t), vec3_mul_scalar(v_1, t));
2555 }
2556 
2558  vec3 edge1 = vec3_sub(tri->verts[1], tri->verts[0]);
2559  vec3 edge2 = vec3_sub(tri->verts[2], tri->verts[0]);
2560 
2561  vec3 normal = vec3_cross(edge1, edge2);
2562  return vec3_normalized(normal);
2563 }
2564 
2566  normal = vec3_normalized(normal);
2567  reference_up = vec3_normalized(reference_up);
2568 
2569  // Compute rotation axis as the cross product
2570  vec3 axis = vec3_cross(reference_up, normal);
2571  f32 dot = vec3_dot(reference_up, normal);
2572 
2573  // If dot is near 1, the vectors are already aligned, return identity quaternion
2574  if (dot > 0.9999f) {
2575  return quat_identity();
2576  }
2577 
2578  // If dot is near -1, the vectors are opposite, use an arbitrary perpendicular axis
2579  if (dot < -0.9999f) {
2580  axis = vec3_normalized(vec3_cross(reference_up, (vec3){1, 0, 0})); // Try X-axis
2581  if (vec3_length_squared(axis) < K_FLOAT_EPSILON) {
2582  axis = vec3_normalized(vec3_cross(reference_up, (vec3){0, 0, 1})); // Try Z-axis
2583  }
2584  }
2585 
2586  // Compute the quaternion components
2587  f32 angle = kacos(dot); // Angle between the vectors
2588  return quat_from_axis_angle(axis, angle, false);
2589 }
2590 
2592  return (aabb){
2593  .min = min,
2594  .max = max};
2595 }
2596 
2598  return (aabb){
2599  .min = vec3_min(a_0.min, a_1.min),
2600  .max = vec3_max(a_0.max, a_1.max)};
2601 }
2602 
2604  return !(
2605  a_0.max.x < a_1.min.x || a_0.min.x > a_1.max.x ||
2606  a_0.max.y < a_1.min.y || a_0.min.y > a_1.max.y ||
2607  a_0.max.z < a_1.min.z || a_0.min.z > a_1.max.z);
2608 }
2609 
2611  f32 dx = a.max.x - a.min.x;
2612  f32 dy = a.max.y - a.min.y;
2613  f32 dz = a.max.z - a.min.z;
2614  return 2.0f * (dx * dy + dy * dz + dz * dx);
2615 }
2616 
2621  vec3 d = vec3_from_scalar(amount);
2622  return aabb_create(vec3_sub(a.min, d), vec3_add(a.max, d));
2623 }
2624 
2633 KINLINE aabb aabb_from_mat4(vec3 half_extents, mat4 mat) {
2634  vec3 center = (vec3){mat.data[12], mat.data[13], mat.data[14]}; // The center
2635  f32 ax = kabs(mat.data[0]) * half_extents.x + kabs(mat.data[4]) * half_extents.y + kabs(mat.data[8]) * half_extents.z;
2636  f32 ay = kabs(mat.data[1]) * half_extents.x + kabs(mat.data[5]) * half_extents.y + kabs(mat.data[9]) * half_extents.z;
2637  f32 az = kabs(mat.data[2]) * half_extents.x + kabs(mat.data[6]) * half_extents.y + kabs(mat.data[10]) * half_extents.z;
2638  vec3 half = (vec3){ax, ay, az};
2639  return aabb_create(vec3_sub(center, half), vec3_add(center, half));
2640 }
2641 
2642 KINLINE aabb aabb_from_mat4_extents(vec3 local_min, vec3 local_max, mat4 mat) {
2643  // Local-space center and half extents
2644  vec3 local_center = vec3_mul_scalar(vec3_add(local_min, local_max), 0.5f);
2645  vec3 half_extents = vec3_mul_scalar(vec3_sub(local_max, local_min), 0.5f);
2646 
2647  // Transform center into world space
2648  vec3 center = {
2649  mat.data[0] * local_center.x + mat.data[4] * local_center.y + mat.data[8] * local_center.z + mat.data[12],
2650  mat.data[1] * local_center.x + mat.data[5] * local_center.y + mat.data[9] * local_center.z + mat.data[13],
2651  mat.data[2] * local_center.x + mat.data[6] * local_center.y + mat.data[10] * local_center.z + mat.data[14]};
2652 
2653  // Compute world-space half extents
2654  f32 ax = kabs(mat.data[0]) * half_extents.x +
2655  kabs(mat.data[4]) * half_extents.y +
2656  kabs(mat.data[8]) * half_extents.z;
2657 
2658  f32 ay = kabs(mat.data[1]) * half_extents.x +
2659  kabs(mat.data[5]) * half_extents.y +
2660  kabs(mat.data[9]) * half_extents.z;
2661 
2662  f32 az = kabs(mat.data[2]) * half_extents.x +
2663  kabs(mat.data[6]) * half_extents.y +
2664  kabs(mat.data[10]) * half_extents.z;
2665 
2666  vec3 half = {ax, ay, az};
2667 
2668  return aabb_create(
2669  vec3_sub(center, half),
2670  vec3_add(center, half));
2671 }
2672 
2681  return (point.x >= box.min.x && point.x <= box.max.x) &&
2682  (point.y >= box.min.y && point.y <= box.max.y) &&
2683  (point.z >= box.min.z && point.z <= box.max.z);
2684 }
2685 
2694  return (
2695  b.min.x >= a.min.x &&
2696  b.min.y >= a.min.y &&
2697  b.min.z >= a.min.z &&
2698  b.max.x <= a.max.x &&
2699  b.max.y <= a.max.y &&
2700  b.max.z <= a.max.z);
2701 }
2702 
2703 KINLINE ray ray_create(vec3 position, vec3 direction) {
2704  return (ray){
2705  .origin = position,
2706  .direction = direction};
2707 }
2708 
2709 KAPI ray ray_transformed(const ray* r, mat4 transform);
2710 
2711 KAPI ray ray_from_screen(vec2i screen_pos, rect_2di viewport_rect, vec3 origin, mat4 view, mat4 projection);
2712 
2713 KAPI b8 ray_intersects_aabb(aabb box, vec3 origin, vec3 direction, f32 max, f32* out_min, f32* out_max);
2714 
2715 KAPI b8 raycast_plane_3d(const ray* r, const plane_3d* p, vec3* out_point, f32* out_distance);
2716 
2717 KAPI b8 raycast_disc_3d(const ray* r, vec3 center, vec3 normal, f32 outer_radius, f32 inner_radius, vec3* out_point, f32* out_distance);
2718 
2720 
2721 KAPI b8 ray_pick_triangle(const ray* r, b8 backface_cull, u32 vertex_count, u32 vertex_element_size, void* vertices, u32 index_count, u32* indices, triangle* out_triangle, vec3* out_hit_pos, vec3* out_hit_normal);
2722 
2723 KAPI b8 ray_intersects_sphere(const ray* r, vec3 center, f32 radius, vec3* out_point, f32* out_distance);
2724 
2725 typedef struct kintersect_result {
2731 
2732 KINLINE f32 obb_project_extents(const struct obb* o, vec3 axis) {
2733  return kabs(vec3_dot(o->axis[0], axis)) * o->half_extents.x +
2734  kabs(vec3_dot(o->axis[1], axis)) * o->half_extents.y +
2735  kabs(vec3_dot(o->axis[2], axis)) * o->half_extents.z;
2736 }
2737 
2738 KINLINE vec3 obb_closest_point(const struct obb* o, vec3 p) {
2739  vec3 d = vec3_sub(p, o->center);
2740  vec3 out = o->center;
2741 
2742  for (u8 i = 0; i < 3; ++i) {
2743  f32 dist = vec3_dot(d, o->axis[i]);
2744  f32 clamped = KCLAMP(dist, -o->half_extents.elements[i], o->half_extents.elements[i]);
2745 
2746  out = vec3_add(out, vec3_mul_scalar(o->axis[i], clamped));
2747  }
2748 
2749  return out;
2750 }
2751 
2752 KINLINE b8 sat_overlap(vec3 axis, vec3 t, const struct obb* a, const struct obb* b, f32* min_overlap, vec3* best_axis) {
2753  f32 dist = kabs(vec3_dot(t, axis));
2754  f32 ra = obb_project_extents(a, axis);
2755  f32 rb = obb_project_extents(b, axis);
2756  f32 overlap = (ra + rb) - dist;
2757 
2758  if (overlap < 0.0f) {
2759  return false;
2760  }
2761 
2762  if (overlap < *min_overlap) {
2763  *min_overlap = overlap;
2764  *best_axis = axis;
2765  }
2766 
2767  return true;
2768 }
2769 
2770 KINLINE b8 obb_intersects_obb(const struct obb* a, const struct obb* b, kintersect_result* out_result) {
2771  vec3 t = vec3_sub(b->center, a->center);
2772 
2773  f32 min_overlap = K_FLOAT_MAX;
2774  vec3 best_axis = vec3_zero();
2775 
2776  for (u8 i = 0; i < 3; ++i) {
2777  if (!sat_overlap(a->axis[i], t, a, b, &min_overlap, &best_axis)) {
2778  return false;
2779  }
2780  }
2781  for (u8 i = 0; i < 3; ++i) {
2782  if (!sat_overlap(b->axis[i], t, a, b, &min_overlap, &best_axis)) {
2783  return false;
2784  }
2785  }
2786 
2787  for (u8 i = 0; i < 3; ++i) {
2788  for (u8 j = 0; j < 3; ++j) {
2789  vec3 axis = vec3_cross(a->axis[i], b->axis[j]);
2790 
2791  f32 len = vec3_dot(axis, axis);
2792  if (len < 1e-8f) {
2793  continue;
2794  }
2795 
2796  axis = vec3_mul_scalar(axis, 1.0f / ksqrt(len));
2797 
2798  if (!sat_overlap(axis, t, a, b, &min_overlap, &best_axis)) {
2799  return false;
2800  }
2801  }
2802  }
2803 
2804  if (out_result) {
2805  // If there's a collision, get the data.
2806  vec3 n = best_axis;
2807  if (vec3_dot(n, t) < 0.0f) {
2808  n = vec3_mul_scalar(n, -1.0f); // Make sure the normal points from a -> b
2809  }
2810 
2811  out_result->normal = vec3_normalized(n);
2812  out_result->depth = min_overlap;
2813 
2814  // Get closts points.
2815  out_result->closest_point_a = obb_closest_point(a, b->center);
2816  out_result->closest_point_b = obb_closest_point(b, a->center);
2817  }
2818 
2819  return true;
2820 }
2821 
2822 KINLINE b8 obb_intersects_sphere(const struct obb* o, const struct ksphere* s) {
2823  vec3 d = vec3_sub(s->position, o->center);
2824 
2825  f32 dist_sq = 0.0f;
2826 
2827  for (u8 i = 0; i < 3; ++i) {
2828  f32 projected = vec3_dot(d, o->axis[i]);
2829  f32 clamped = KCLAMP(projected, -o->half_extents.elements[i], o->half_extents.elements[i]);
2830  f32 diff = projected - clamped;
2831  dist_sq += (diff * diff);
2832  }
2833 
2834  return dist_sq <= (s->radius * s->radius);
2835 }
2836 
2838  f32 dist_sq = vec3_distance_squared(a.position, b.position);
2839  f32 combined_radii_sq = (a.radius * a.radius) + (b.radius * b.radius);
2840 
2841  return dist_sq < combined_radii_sq;
2842 }
2843 
2845  obb out;
2846 
2847  // AABBs by default don't have half-extents and a center. Extract them.
2848  vec3 half_extents = extents_3d_half(a);
2849  out.center = extents_3d_center(a);
2850 
2851  out.center = vec3_transform(out.center, 1.0f, m);
2852 
2853  out.axis[0] = (vec3){m.data[0], m.data[4], m.data[8]};
2854  out.axis[1] = (vec3){m.data[1], m.data[5], m.data[9]};
2855  out.axis[2] = (vec3){m.data[2], m.data[6], m.data[10]};
2856 
2857  out.half_extents = half_extents;
2858 
2859  return out;
2860 }
This file contains global type definitions which are used throughout the entire engine and applicatio...
#define KAPI
Import/export qualifier.
Definition: defines.h:209
unsigned int u32
Unsigned 32-bit integer.
Definition: defines.h:27
_Bool b8
8-bit boolean type
Definition: defines.h:60
float f32
32-bit floating point number
Definition: defines.h:49
#define KMIN(x, y)
Definition: defines.h:302
signed int i32
Signed 32-bit integer.
Definition: defines.h:41
#define KMAX(x, y)
Definition: defines.h:303
#define KINLINE
Inline qualifier.
Definition: defines.h:256
#define KCLAMP(value, min, max)
Clamps value to a range of min and max (inclusive).
Definition: defines.h:236
unsigned long long u64
Unsigned 64-bit integer.
Definition: defines.h:30
unsigned char u8
Unsigned 8-bit integer.
Definition: defines.h:21
KINLINE ray ray_create(vec3 position, vec3 direction)
Definition: kmath.h:2703
KINLINE aabb aabb_from_mat4_extents(vec3 local_min, vec3 local_max, mat4 mat)
Definition: kmath.h:2642
KINLINE mat4 mat4_inverse(mat4 matrix)
Creates and returns an inverse of the provided matrix.
Definition: kmath.h:1562
#define vec3_create(x, y, z)
Creates and returns a new 3-element vector using the supplied values.
Definition: kmath.h:618
KINLINE vec3 vec3_cross(vec3 vector_0, vec3 vector_1)
Calculates and returns the cross product of the supplied vectors. The cross product is a new vector w...
Definition: kmath.h:857
KINLINE quat quat_conjugate(quat q)
Returns the conjugate of the provided quaternion. That is, The x, y and z elements are negated,...
Definition: kmath.h:1989
KINLINE vec2 vec2_mul(vec2 vector_0, vec2 vector_1)
Multiplies vector_0 by vector_1 and returns a copy of the result.
Definition: kmath.h:408
KINLINE vec4 vec4_one(void)
Creates and returns a 4-component vector with all components set to 1.0f.
Definition: kmath.h:1106
KINLINE mat4 mat4_mul(mat4 matrix_0, mat4 matrix_1)
Returns the result of multiplying matrix_0 and matrix_1.
Definition: kmath.h:1386
KINLINE vec3 vec3_sign(vec3 v)
Definition: kmath.h:1018
KAPI f32 kmod(f32 x, f32 y)
KINLINE mat4 mat4_from_translation_rotation_scale(vec3 t, quat r, vec3 s)
Returns a matrix created from the provided translation, rotation and scale (TRS).
Definition: kmath.h:1678
KAPI f32 klog2(f32 x)
Computes the base-2 logarithm of x (i.e. how many times x can be divided by 2).
KINLINE vec4 vec4_clamped(vec4 vector, vec4 min, vec4 max)
Returns a clamped copy of the provided vector.
Definition: kmath.h:1324
KINLINE vec2 vec2_max(vec2 vector_0, vec2 vector_1)
Definition: kmath.h:600
KINLINE vec4 vec4_div(vec4 vector_0, vec4 vector_1)
Divides vector_0 by vector_1 and returns a copy of the result.
Definition: kmath.h:1189
KINLINE b8 aabbs_intersect(aabb a_0, aabb a_1)
Definition: kmath.h:2603
KAPI i32 krandom_in_range(i32 min, i32 max)
Returns a random integer that is within the given range (inclusive).
KAPI f32 kacos(f32 x)
Calculates the arc cosine of x.
KINLINE vec2 vec2_one(void)
Creates and returns a 2-component vector with all components set to 1.0f.
Definition: kmath.h:357
KINLINE mat4 mat4_translation(vec3 position)
Creates and returns a translation matrix from the given position.
Definition: kmath.h:1648
KINLINE vec2 vec2_up(void)
Creates and returns a 2-component vector pointing up (0, 1).
Definition: kmath.h:362
KINLINE void rgbu_to_u32(u32 r, u32 g, u32 b, u32 *out_u32)
Converts rgb int values [0-255] to a single 32-bit integer.
Definition: kmath.h:2314
KINLINE f32 vec2_distance_squared(vec2 vector_0, vec2 vector_1)
Returns the squared distance between vector_0 and vector_1. NOTE: If purely for comparison purposes,...
Definition: kmath.h:589
KINLINE vec3 extents_2d_center(extents_2d extents)
Definition: kmath.h:2468
KINLINE vec3 vec3_backward(void)
Creates and returns a 3-component vector pointing backward (0, 0, 1).
Definition: kmath.h:704
KINLINE vec3 obb_closest_point(const struct obb *o, vec3 p)
Definition: kmath.h:2738
KINLINE vec2 vec2_from_scalar(f32 scalar)
Creates and returns a new 2-element vector using the supplied scalar for all components.
Definition: kmath.h:345
KINLINE extents_3d extents_3d_zero(void)
Definition: kmath.h:2482
KINLINE vec4 vec3_to_vec4(vec3 vector, f32 w)
Returns a new vec4 using vector as the x, y and z components and w for w.
Definition: kmath.h:660
KAPI b8 plane_intersects_sphere(const plane_3d *p, const vec3 *center, f32 radius)
Indicates if plane p intersects a sphere constructed via center and radius.
KAPI f32 ktan(f32 x)
Calculates the tangent of x.
KINLINE mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_clip, f32 far_clip)
Creates and returns a perspective matrix. Typically used to render 3d scenes.
Definition: kmath.h:1445
KINLINE vec4 vec4_mul_mat4(vec4 v, mat4 m)
Performs v * m.
Definition: kmath.h:1937
struct kintersect_result kintersect_result
KINLINE vec3 vec3_max(vec3 vector_0, vec3 vector_1)
Definition: kmath.h:1011
KINLINE f32 klerp(f32 a, f32 b, f32 t)
Definition: kmath.h:240
KINLINE vec4 vec4_clamped_scalar(vec4 vector, f32 min, f32 max)
Returns a clamped copy of the provided vector.
Definition: kmath.h:1352
KAPI b8 ray_intersects_aabb(aabb box, vec3 origin, vec3 direction, f32 max, f32 *out_min, f32 *out_max)
KINLINE f32 vec2_distance(vec2 vector_0, vec2 vector_1)
Returns the distance between vector_0 and vector_1.
Definition: kmath.h:576
KINLINE vec3 mat4_scale_get(mat4 matrix)
Returns the scale relative to the provided matrix.
Definition: kmath.h:1883
KINLINE vec3 vec3_lerp(vec3 v_0, vec3 v_1, f32 t)
Definition: kmath.h:2553
KINLINE obb aabb_to_obb(const aabb a, mat4 m)
Definition: kmath.h:2844
KINLINE mat4 mat4_identity(void)
Creates and returns an identity matrix:
Definition: kmath.h:1369
KINLINE mat4 mat4_look_at(vec3 position, vec3 target, vec3 up)
Creates and returns a look-at matrix, or a matrix looking at target from the perspective of position.
Definition: kmath.h:1466
KINLINE vec3 vec3_mid(vec3 v_0, vec3 v_1)
Definition: kmath.h:2546
KAPI ray ray_from_screen(vec2i screen_pos, rect_2di viewport_rect, vec3 origin, mat4 view, mat4 projection)
KAPI f32 kfloor(f32 x)
Returns the largest integer value less than or equal to x.
KAPI f32 ksqrt(f32 x)
Calculates the square root of x.
KINLINE void kswapf(f32 *a, f32 *b)
Definition: kmath.h:87
KINLINE vec3 mat4_right(mat4 matrix)
Returns a right vector relative to the provided matrix.
Definition: kmath.h:1854
KINLINE f32 vec4_dot_f32(f32 a0, f32 a1, f32 a2, f32 a3, f32 b0, f32 b1, f32 b2, f32 b3)
Calculates the dot product using the elements of vec4s provided in split-out format.
Definition: kmath.h:1264
KINLINE void vec4_normalize(vec4 *vector)
Normalizes the provided vector in place to a unit vector.
Definition: kmath.h:1231
KINLINE vec2 vec2_sub(vec2 vector_0, vec2 vector_1)
Subtracts vector_1 from vector_0 and returns a copy of the result.
Definition: kmath.h:397
KAPI f32 ksin(f32 x)
Calculates the sine of x.
KAPI f32 kabs(f32 x)
Calculates the absolute value of x.
KINLINE mat4 mat4_scale(vec3 scale)
Returns a scale matrix using the provided scale.
Definition: kmath.h:1662
KINLINE extents_3d extents_3d_from_size(vec3 size)
Definition: kmath.h:2500
KAPI kfrustum kfrustum_create(vec3 position, vec3 target, vec3 up, f32 aspect, f32 fov, f32 near, f32 far)
Creates and returns a frustum based on the provided position, direction vectors, aspect,...
KINLINE vec3 vec3_forward(void)
Creates and returns a 3-component vector pointing forward (0, 0, -1).
Definition: kmath.h:699
KINLINE b8 aabb_contains_point(vec3 point, aabb box)
Indicates if point is inside the provided AABB.
Definition: kmath.h:2680
KAPI f32 kfrandom_in_range(f32 min, f32 max)
Returns a random floating-point number that is within the given range (inclusive).
KINLINE aabb aabb_expand(aabb a, f32 amount)
Expand the AABB by amount on all axes.
Definition: kmath.h:2620
KINLINE vec3 vec3_from_scalar(f32 scalar)
Creates and returns a new 3-element vector using the supplied scalar for all components.
Definition: kmath.h:627
KINLINE f32 vec4_length_squared(vec4 vector)
Returns the squared length of the provided vector.
Definition: kmath.h:1211
KAPI f32 plane_signed_distance(const plane_3d *p, const vec3 *position)
Obtains the signed distance between the plane p and the provided postion.
KAPI b8 plane_intersects_aabb(const plane_3d *p, const vec3 *center, const vec3 *extents)
Indicates if plane p intersects an axis-aligned bounding box constructed via center and extents.
KAPI b8 raycast_plane_3d(const ray *r, const plane_3d *p, vec3 *out_point, f32 *out_distance)
KINLINE vec3 triangle_get_normal(const triangle *tri)
Definition: kmath.h:2557
KINLINE vec3 mat4_backward(mat4 matrix)
Returns a backward vector relative to the provided matrix.
Definition: kmath.h:1794
KINLINE extents_3d extents_3d_from_scalar(f32 scalar)
Definition: kmath.h:2494
KINLINE void vec2_normalize(vec2 *vector)
Normalizes the provided vector in place to a unit vector.
Definition: kmath.h:474
KINLINE vec3 vec3_mul(vec3 vector_0, vec3 vector_1)
Multiplies vector_0 by vector_1 and returns a copy of the result.
Definition: kmath.h:737
KINLINE vec2 vec2_right(void)
Creates and returns a 2-component vector pointing right (1, 0).
Definition: kmath.h:377
KINLINE vec2 vec2_mul_add(vec2 vector_0, vec2 vector_1, vec2 vector_2)
Multiplies vector_0 by vector_1, then adds the result to vector_2.
Definition: kmath.h:432
KINLINE mat4 mat4_orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 near_clip, f32 far_clip)
Creates and returns an orthographic projection matrix. Typically used to render flat or 2D scenes.
Definition: kmath.h:1416
KINLINE quat quat_inverse(quat q)
Returns an inverse copy of the provided quaternion.
Definition: kmath.h:1997
KINLINE vec3 vec3_mul_add(vec3 vector_0, vec3 vector_1, vec3 vector_2)
Multiplies vector_0 by vector_1, then adds the result to vector_2.
Definition: kmath.h:762
KINLINE f32 vec3_length(vec3 vector)
Returns the length of the provided vector.
Definition: kmath.h:805
KINLINE vec3 vec3_sub(vec3 vector_0, vec3 vector_1)
Subtracts vector_1 from vector_0 and returns a copy of the result.
Definition: kmath.h:725
KINLINE vec2 vec2_mul_scalar(vec2 vector_0, f32 scalar)
Multiplies all elements of vector_0 by scalar and returns a copy of the result.
Definition: kmath.h:420
KAPI f32 katan(f32 x)
Calculates the arctangent of x.
KINLINE aabb aabb_combine(aabb a_0, aabb a_1)
Definition: kmath.h:2597
KAPI f32 kattenuation_min_max(f32 min, f32 max, f32 x)
Returns the attenuation of x based off distance from the midpoint of min and max.
KINLINE vec3 mat4_mul_vec3(mat4 m, vec3 v)
Performs m * v.
Definition: kmath.h:1894
KINLINE aabb aabb_create(vec3 min, vec3 max)
Definition: kmath.h:2591
KINLINE void rgb_u32_to_vec3(u32 r, u32 g, u32 b, vec3 *out_v)
Converts rgb integer values [0-255] to a vec3 of floating-point values [0.0-1.0].
Definition: kmath.h:2341
KAPI f32 kfrandom(void)
Returns a random floating-point number.
KAPI kfrustum kfrustum_from_view_projection(mat4 view_projection)
KINLINE vec2 vec2_create(f32 x, f32 y)
Creates and returns a new 2-element vector using the supplied values.
Definition: kmath.h:335
KINLINE f32 ksmoothstep(f32 edge_0, f32 edge_1, f32 x)
Perform Hermite interpolation between two values.
Definition: kmath.h:301
#define K_RAD2DEG_MULTIPLIER
A multiplier used to convert radians to degrees.
Definition: kmath.h:58
KINLINE mat4 quat_to_rotation_matrix(quat q, vec3 center)
Calculates a rotation matrix based on the quaternion and the passed in center point.
Definition: kmath.h:2168
KINLINE vec2 vec2_down(void)
Creates and returns a 2-component vector pointing down (0, -1).
Definition: kmath.h:367
KINLINE b8 is_power_of_2(u64 value)
Indicates if the value is a power of 2. 0 is considered not a power of 2.
Definition: kmath.h:250
KINLINE vec3 vec3_clamped_scalar(vec3 vector, f32 min, f32 max)
Returns a clamped copy of the provided vector.
Definition: kmath.h:940
KAPI f32 vec3_distance_to_line(vec3 point, vec3 line_start, vec3 line_direction)
KINLINE b8 obb_intersects_sphere(const struct obb *o, const struct ksphere *s)
Definition: kmath.h:2822
KINLINE vec3 mat4_left(mat4 matrix)
Returns a left vector relative to the provided matrix.
Definition: kmath.h:1839
KINLINE f32 deg_to_rad(f32 degrees)
Converts provided degrees to radians.
Definition: kmath.h:2280
KAPI b8 kfrustum_intersects_ksphere(const kfrustum *f, const ksphere *sphere)
Indicates if the frustum intersects (or contains) a sphere constructed via center and radius.
KAPI f32 kpow(f32 x, f32 y)
KINLINE f32 vec3_length_squared(vec3 vector)
Returns the squared length of the provided vector.
Definition: kmath.h:795
KINLINE vec4 vec4_mul(vec4 vector_0, vec4 vector_1)
Multiplies vector_0 by vector_1 and returns a copy of the result.
Definition: kmath.h:1145
KINLINE vec4 vec4_add(vec4 vector_0, vec4 vector_1)
Adds vector_1 to vector_0 and returns a copy of the result.
Definition: kmath.h:1115
KINLINE vec4 vec4_mul_scalar(vec4 vector_0, f32 scalar)
Multiplies all elements of vector_0 by scalar and returns a copy of the result.
Definition: kmath.h:1161
KINLINE quat quat_normalize(quat q)
Returns a normalized copy of the provided quaternion.
Definition: kmath.h:1977
KAPI b8 raycast_disc_3d(const ray *r, vec3 center, vec3 normal, f32 outer_radius, f32 inner_radius, vec3 *out_point, f32 *out_distance)
KINLINE f32 vec2_length_squared(vec2 vector)
Returns the squared length of the provided vector.
Definition: kmath.h:455
KAPI i32 krandom(void)
Returns a random integer.
KINLINE void vec4_clamp_scalar(vec4 *vector, f32 min, f32 max)
Clamps the provided vector in-place to the given min/max values.
Definition: kmath.h:1336
KINLINE mat4 mat4_euler_x(f32 angle_radians)
Creates a rotation matrix from the provided x angle.
Definition: kmath.h:1707
KAPI f32 kceil(f32 x)
Returns the smallest integer value greater than or equal to x.
KINLINE vec4 vec4_normalized(vec4 vector)
Returns a normalized copy of the supplied vector.
Definition: kmath.h:1245
KINLINE vec2 vec2_normalized(vec2 vector)
Returns a normalized copy of the supplied vector.
Definition: kmath.h:486
KINLINE vec3 vec3_from_vec4(vec4 vector)
Definition: kmath.h:636
KAPI void kfrustum_corner_points_world_space(mat4 projection_view, vec4 *corners)
KINLINE f32 quat_dot(quat q_0, quat q_1)
Calculates the dot product of the provided quaternions.
Definition: kmath.h:2031
KAPI f32 kcos(f32 x)
Calculates the cosine of x.
KINLINE vec3 extents_3d_half(extents_3d extents)
Definition: kmath.h:2514
KAPI u64 krandom_u64(void)
Returns a random unsigned 64-bit integer.
KINLINE vec3 mat4_position(mat4 matrix)
Returns the position relative to the provided matrix.
Definition: kmath.h:1869
KAPI ray ray_transformed(const ray *r, mat4 transform)
KINLINE quat quat_from_surface_normal(vec3 normal, vec3 reference_up)
Definition: kmath.h:2565
KINLINE vec4 vec4_from_vec3(vec3 vector, f32 w)
Returns a new vec4 using vector as the x, y and z components and w for w.
Definition: kmath.h:1086
KINLINE void vec3_normalize(vec3 *vector)
Normalizes the provided vector in place to a unit vector.
Definition: kmath.h:814
KAPI b8 ray_intersects_triangle(const ray *r, const triangle *t)
KINLINE vec2 vec2_clamped_scalar(vec2 vector, f32 min, f32 max)
Returns a clamped copy of the provided vector.
Definition: kmath.h:564
KINLINE vec3 mat4_down(mat4 matrix)
Returns a downward vector relative to the provided matrix.
Definition: kmath.h:1824
KINLINE vec4 vec4_zero(void)
Creates and returns a 4-component vector with all components set to 0.0f.
Definition: kmath.h:1100
KINLINE vec2 vec2_div(vec2 vector_0, vec2 vector_1)
Divides vector_0 by vector_1 and returns a copy of the result.
Definition: kmath.h:445
KINLINE f32 vec2_length(vec2 vector)
Returns the length of the provided vector.
Definition: kmath.h:465
KINLINE f32 quat_normal(quat q)
Returns the normal of the provided quaternion.
Definition: kmath.h:1967
KINLINE b8 rect_2d_contains_point(rect_2d rect, vec2 point)
Definition: kmath.h:2462
KINLINE vec2 vec2_add(vec2 vector_0, vec2 vector_1)
Adds vector_1 to vector_0 and returns a copy of the result.
Definition: kmath.h:386
KINLINE mat4 mat4_euler_y(f32 angle_radians)
Creates a rotation matrix from the provided y angle.
Definition: kmath.h:1725
KINLINE vec3 vec3_min(vec3 vector_0, vec3 vector_1)
Definition: kmath.h:1004
KINLINE f32 mat4_determinant(mat4 matrix)
Calculates the determinant of the given matrix.
Definition: kmath.h:1524
KINLINE f32 vec3_distance_squared(vec3 vector_0, vec3 vector_1)
Returns the squared distance between vector_0 and vector_1. Less intensive than calling the non-squar...
Definition: kmath.h:966
KINLINE mat4 mat4_transposed(mat4 matrix)
Returns a transposed copy of the provided matrix (rows->colums)
Definition: kmath.h:1497
KAPI f32 katan2(f32 x, f32 y)
KINLINE f32 obb_project_extents(const struct obb *o, vec3 axis)
Definition: kmath.h:2732
KINLINE quat quat_identity(void)
Creates an identity quaternion.
Definition: kmath.h:1954
#define K_FLOAT_EPSILON
Smallest positive number where 1.0 + FLOAT_EPSILON != 0.
Definition: kmath.h:73
KINLINE f32 rad_to_deg(f32 radians)
Converts provided radians to degrees.
Definition: kmath.h:2288
KINLINE quat quat_mul(quat q_0, quat q_1)
Multiplies the provided quaternions.
Definition: kmath.h:2006
KAPI f32 klog(f32 x)
Computes the logarithm of x.
KAPI b8 ray_pick_triangle(const ray *r, b8 backface_cull, u32 vertex_count, u32 vertex_element_size, void *vertices, u32 index_count, u32 *indices, triangle *out_triangle, vec3 *out_hit_pos, vec3 *out_hit_normal)
KINLINE mat4 mat4_euler_z(f32 angle_radians)
Creates a rotation matrix from the provided z angle.
Definition: kmath.h:1743
KINLINE vec3 vec3_up(void)
Creates and returns a 3-component vector pointing up (0, 1, 0).
Definition: kmath.h:679
KINLINE vec3 vec3_mul_mat4(vec3 v, mat4 m)
Performs v * m.
Definition: kmath.h:1908
KINLINE vec4 vec4_create(f32 x, f32 y, f32 z, f32 w)
Creates and returns a new 4-element vector using the supplied values.
Definition: kmath.h:1046
KINLINE vec4 vec4_div_scalar(vec4 vector_0, f32 scalar)
Definition: kmath.h:1197
KINLINE vec3 vec3_down(void)
Creates and returns a 3-component vector pointing down (0, -1, 0).
Definition: kmath.h:684
KINLINE vec2 vec2_zero(void)
Creates and returns a 2-component vector with all components set to 0.0f.
Definition: kmath.h:351
KINLINE vec2 vec2_mid(vec2 v_0, vec2 v_1)
Definition: kmath.h:2540
KINLINE b8 extents_3d_is_zero(extents_3d extents)
Definition: kmath.h:2536
KAPI b8 quat_is_identity(quat q)
Indicates if the provided quaterion is identity. (0, 0, 0, 1)
KINLINE vec3 vec3_project(vec3 v_0, vec3 v_1)
Projects v_0 onto v_1.
Definition: kmath.h:979
KINLINE vec3 mat4_forward(mat4 matrix)
Returns a forward vector relative to the provided matrix.
Definition: kmath.h:1779
KINLINE vec4 vec4_from_scalar(f32 scalar)
Creates and returns a new 4-element vector using the supplied scalar for all components.
Definition: kmath.h:1065
KINLINE f32 ksign(f32 x)
Returns 0.0f if x == 0.0f, -1.0f if negative, otherwise 1.0f.
Definition: kmath.h:94
KINLINE b8 sat_overlap(vec3 axis, vec3 t, const struct obb *a, const struct obb *b, f32 *min_overlap, vec3 *best_axis)
Definition: kmath.h:2752
KINLINE vec2 vec2_left(void)
Creates and returns a 2-component vector pointing left (-1, 0).
Definition: kmath.h:372
KINLINE vec3 extents_3d_center(extents_3d extents)
Definition: kmath.h:2506
KINLINE b8 vec2_compare(vec2 vector_0, vec2 vector_1, f32 tolerance)
Compares all elements of vector_0 and vector_1 and ensures the difference is less than tolerance.
Definition: kmath.h:501
KINLINE vec3 vec3_mul_scalar(vec3 vector_0, f32 scalar)
Multiplies all elements of vector_0 by scalar and returns a copy of the result.
Definition: kmath.h:750
KAPI f32 kasin(f32 x)
KINLINE void vec3_to_rgb_u32(vec3 v, u32 *out_r, u32 *out_g, u32 *out_b)
Converts a vec3 of rgbvalues [0.0-1.0] to integer rgb values [0-255].
Definition: kmath.h:2355
KINLINE f32 kstep(f32 edge, f32 x)
Compares x to edge, returning 0 if x < edge; otherwise 1.0f;.
Definition: kmath.h:100
KINLINE f32 vec4_length(vec4 vector)
Returns the length of the provided vector.
Definition: kmath.h:1222
KINLINE void vec3_clamp(vec3 *vector, vec3 min, vec3 max)
Clamps the provided vector in-place to the given min/max values.
Definition: kmath.h:896
KINLINE mat4 mat4_euler_xyz(f32 x_radians, f32 y_radians, f32 z_radians)
Creates a rotation matrix from the provided x, y and z axis rotations.
Definition: kmath.h:1764
KINLINE vec3 vec3_left(void)
Creates and returns a 3-component vector pointing left (-1, 0, 0).
Definition: kmath.h:689
KINLINE mat4 quat_to_mat4(quat q)
Creates a rotation matrix from the given quaternion.
Definition: kmath.h:2041
KINLINE vec2 vec2_min(vec2 vector_0, vec2 vector_1)
Definition: kmath.h:594
KINLINE b8 kfloat_compare(f32 f_0, f32 f_1)
Compares the two floats and returns true if both are less than K_FLOAT_EPSILON apart; otherwise false...
Definition: kmath.h:320
KINLINE void vec2_clamp(vec2 *vector, vec2 min, vec2 max)
Clamps the provided vector in-place to the given min/max values.
Definition: kmath.h:520
KINLINE vec2 vec2_clamped(vec2 vector, vec2 min, vec2 max)
Returns a clamped copy of the provided vector.
Definition: kmath.h:536
KINLINE vec3 mat4_up(mat4 matrix)
Returns a upward vector relative to the provided matrix.
Definition: kmath.h:1809
KINLINE vec3 vec3_clamped(vec3 vector, vec3 min, vec3 max)
Returns a clamped copy of the provided vector.
Definition: kmath.h:912
KINLINE vec3 vec4_to_vec3(vec4 vector)
Returns a new vec3 containing the x, y and z components of the supplied vec4, essentially dropping th...
Definition: kmath.h:1074
KINLINE vec3 vec3_div_scalar(vec3 vector_0, f32 scalar)
Definition: kmath.h:781
KINLINE vec4 vec4_mul_add(vec4 vector_0, vec4 vector_1, vec4 vector_2)
Multiplies vector_0 by vector_1, then adds the result to vector_2.
Definition: kmath.h:1173
KINLINE vec3 vec3_from_vec2(vec2 vector, f32 z)
Definition: kmath.h:648
KINLINE b8 obb_intersects_obb(const struct obb *a, const struct obb *b, kintersect_result *out_result)
Definition: kmath.h:2770
KINLINE aabb aabb_from_mat4(vec3 half_extents, mat4 mat)
Constructs a tight, world-space AABB from an OBB defined by a center point (the translation of mat) a...
Definition: kmath.h:2633
KINLINE extents_3d extents_3d_one(void)
Definition: kmath.h:2488
KAPI b8 kfrustum_intersects_sphere(const kfrustum *f, const vec3 *center, f32 radius)
Indicates if the frustum intersects (or contains) a sphere constructed via center and radius.
KINLINE vec4 vec4_sub(vec4 vector_0, vec4 vector_1)
Subtracts vector_1 from vector_0 and returns a copy of the result.
Definition: kmath.h:1130
KINLINE vec3 vec3_rotate(vec3 v, quat q)
Definition: kmath.h:1022
KINLINE void vec4_clamp(vec4 *vector, vec4 min, vec4 max)
Clamps the provided vector in-place to the given min/max values.
Definition: kmath.h:1308
KINLINE b8 vec3_compare(vec3 vector_0, vec3 vector_1, f32 tolerance)
Compares all elements of vector_0 and vector_1 and ensures the difference is less than tolerance.
Definition: kmath.h:873
KAPI plane_3d plane_3d_create(vec3 p1, vec3 norm)
KINLINE vec3 vec3_right(void)
Creates and returns a 3-component vector pointing right (1, 0, 0).
Definition: kmath.h:694
KINLINE vec3 size_from_extents_3d(extents_3d extents)
Definition: kmath.h:2522
KINLINE quat quat_from_axis_angle(vec3 axis, f32 angle, b8 normalize)
Creates a quaternion from the given axis and angle.
Definition: kmath.h:2202
KINLINE vec3 extents_2d_half(extents_2d extents)
Definition: kmath.h:2475
KINLINE vec3 vec3_one(void)
Creates and returns a 3-component vector with all components set to 1.0f.
Definition: kmath.h:674
KAPI b8 kfrustum_intersects_aabb(const kfrustum *f, const vec3 *center, const vec3 *extents)
Indicates if frustum f intersects an axis-aligned bounding box constructed via center and extents.
KINLINE vec4 mat4_mul_vec4(mat4 m, vec4 v)
Performs m * v.
Definition: kmath.h:1922
KINLINE b8 vec4_compare(vec4 vector_0, vec4 vector_1, f32 tolerance)
Compares all elements of vector_0 and vector_1 and ensures the difference is less than tolerance.
Definition: kmath.h:1281
KINLINE f32 vec3_dot(vec3 vector_0, vec3 vector_1)
Returns the dot product between the provided vectors. Typically used to calculate the difference in d...
Definition: kmath.h:840
KINLINE f32 vec3_distance(vec3 vector_0, vec3 vector_1)
Returns the distance between vector_0 and vector_1.
Definition: kmath.h:952
KINLINE void u32_to_rgb(u32 rgbu, u32 *out_r, u32 *out_g, u32 *out_b)
Converts the given 32-bit integer to rgb values [0-255].
Definition: kmath.h:2326
KINLINE vec3 vec3_transform(vec3 v, f32 w, mat4 m)
Transform v by m.
Definition: kmath.h:996
KINLINE vec3 vec3_div(vec3 vector_0, vec3 vector_1)
Divides vector_0 by vector_1 and returns a copy of the result.
Definition: kmath.h:776
KINLINE quat quat_slerp(quat q_0, quat q_1, f32 percentage)
Calculates spherical linear interpolation of a given percentage between two quaternions.
Definition: kmath.h:2224
KINLINE b8 aabb_contains_aabb(aabb a, aabb b)
Indicates if AABB b is completely inside AABB a.
Definition: kmath.h:2693
KINLINE vec3 vec3_zero(void)
Creates and returns a 3-component vector with all components set to 0.0f.
Definition: kmath.h:668
KINLINE extents_3d extents_combine(extents_3d a, extents_3d b)
Definition: kmath.h:2530
KINLINE f32 aabb_surface_area(aabb a)
Definition: kmath.h:2610
KINLINE void vec2_clamp_scalar(vec2 *vector, f32 min, f32 max)
Clamps the provided vector in-place to the given min/max values.
Definition: kmath.h:548
KINLINE vec3 vec3_add(vec3 vector_0, vec3 vector_1)
Adds vector_1 to vector_0 and returns a copy of the result.
Definition: kmath.h:713
#define K_FLOAT_MAX
Definition: kmath.h:75
KINLINE f32 range_convert_f32(f32 value, f32 old_min, f32 old_max, f32 new_min, f32 new_max)
Converts value from the "old" range to the "new" range.
Definition: kmath.h:2300
#define K_DEG2RAD_MULTIPLIER
A multiplier used to convert degrees to radians.
Definition: kmath.h:55
KAPI b8 ray_intersects_sphere(const ray *r, vec3 center, f32 radius, vec3 *out_point, f32 *out_distance)
KINLINE b8 sphere_intersects_sphere(const ksphere a, const ksphere b)
Definition: kmath.h:2837
KINLINE vec3 vec3_normalized(vec3 vector)
Returns a normalized copy of the supplied vector.
Definition: kmath.h:827
KINLINE void vec3_clamp_scalar(vec3 *vector, f32 min, f32 max)
Clamps the provided vector in-place to the given min/max values.
Definition: kmath.h:924
This file contains the structures and functions of the memory system. This is responsible for memory ...
KAPI void * kzero_memory(void *block, u64 size)
Zeroes out the provided memory block.
Contains various math types required for the engine.
union vec2_u vec2
A 2-element vector.
union vec3_u vec3
A 3-element vector.
vec4 quat
A quaternion, used to represent rotational orientation.
Definition: math_types.h:275
Represents the extents of a 2d object.
Definition: math_types.h:391
vec2 max
The maximum extents of the object.
Definition: math_types.h:395
vec2 min
The minimum extents of the object.
Definition: math_types.h:393
Represents the extents of a 3d object.
Definition: math_types.h:401
vec3 min
The minimum extents of the object.
Definition: math_types.h:403
vec3 max
The maximum extents of the object.
Definition: math_types.h:405
Definition: math_types.h:500
Definition: kmath.h:2725
vec3 closest_point_b
Definition: kmath.h:2728
vec3 closest_point_a
Definition: kmath.h:2727
vec3 normal
Definition: kmath.h:2726
f32 depth
Definition: kmath.h:2729
Definition: math_types.h:665
vec3 position
Definition: math_types.h:666
f32 radius
Definition: math_types.h:667
Definition: math_types.h:413
vec3 center
Definition: math_types.h:414
vec3 axis[3]
Definition: math_types.h:416
vec3 half_extents
Definition: math_types.h:417
Definition: math_types.h:484
Represents a line which starts at an origin and proceed infinitely in the given direction....
Definition: math_types.h:638
vec3 origin
Definition: math_types.h:639
Definition: math_types.h:622
vec3 verts[3]
Definition: math_types.h:623
A 3x3 matrix.
Definition: math_types.h:377
f32 data[12]
The matrix elements.
Definition: math_types.h:379
a 4x4 matrix, typically used to represent object transformations.
Definition: math_types.h:383
f32 data[16]
The matrix elements.
Definition: math_types.h:385
A 2-element vector.
Definition: math_types.h:31
f32 x
The first element.
Definition: math_types.h:37
f32 y
The second element.
Definition: math_types.h:47
f32 elements[2]
An array of x, y.
Definition: math_types.h:33
A 2-element integer-based vector.
Definition: math_types.h:508
A 3-element vector.
Definition: math_types.h:117
f32 elements[3]
An array of x, y, z.
Definition: math_types.h:119
f32 r
The first element.
Definition: math_types.h:125
f32 b
The third element.
Definition: math_types.h:145
f32 x
The first element.
Definition: math_types.h:123
f32 g
The second element.
Definition: math_types.h:135
f32 z
The third element.
Definition: math_types.h:143
f32 y
The second element.
Definition: math_types.h:133
A 4-element vector.
Definition: math_types.h:229
f32 elements[4]
An array of x, y, z, w.
Definition: math_types.h:231
f32 height
The fourth element.
Definition: math_types.h:268
f32 x
The first element.
Definition: math_types.h:236
f32 width
The third element.
Definition: math_types.h:258
f32 z
The third element.
Definition: math_types.h:252
f32 y
The second element.
Definition: math_types.h:244
f32 w
The fourth element.
Definition: math_types.h:262
A 4-element integer-based vector.
Definition: math_types.h:574