diff options
Diffstat (limited to 'mons_math/src/mat4.c')
-rw-r--r-- | mons_math/src/mat4.c | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/mons_math/src/mat4.c b/mons_math/src/mat4.c new file mode 100644 index 0000000..bb92ca8 --- /dev/null +++ b/mons_math/src/mat4.c @@ -0,0 +1,321 @@ +#include "mons_math/mat4.h" +#include "mons_math/mat3.h" +#include "mons_math/vec4.h" +#include <stdio.h> + +mons_mat4 mons_mat4_add(mons_mat4 a, mons_mat4 b) { + mons_mat4 result = { + mons_vec4_add(a.m1, b.m1), + mons_vec4_add(a.m2, b.m2), + mons_vec4_add(a.m3, b.m3), + mons_vec4_add(a.m4, b.m4), + }; + return result; +} + +void mons_mat4_add_inplace(mons_mat4 *a, mons_mat4 b) { + mons_vec4_add_inplace(&a->m1, b.m1); + mons_vec4_add_inplace(&a->m2, b.m2); + mons_vec4_add_inplace(&a->m3, b.m3); + mons_vec4_add_inplace(&a->m4, b.m4); +} + +mons_mat4 mons_mat4_mul_f(mons_mat4 a, float b) { + mons_mat4 result = { + mons_vec4_mul_f(a.m1, b), + mons_vec4_mul_f(a.m2, b), + mons_vec4_mul_f(a.m3, b), + mons_vec4_mul_f(a.m4, b), + }; + return result; +} + +mons_mat4 mons_mat4_mul_i(mons_mat4 a, int b) { + mons_mat4 result = { + mons_vec4_mul_i(a.m1, b), + mons_vec4_mul_i(a.m2, b), + mons_vec4_mul_i(a.m3, b), + mons_vec4_mul_i(a.m4, b), + }; + return result; +} + +void mons_mat4_mul_f_inplace(mons_mat4 *a, float b) { + mons_vec4_mul_f_inplace(&a->m1, b); + mons_vec4_mul_f_inplace(&a->m2, b); + mons_vec4_mul_f_inplace(&a->m3, b); + mons_vec4_mul_f_inplace(&a->m4, b); +} + +void mons_mat4_mul_i_inplace(mons_mat4 *a, int b) { + mons_vec4_mul_i_inplace(&a->m1, b); + mons_vec4_mul_i_inplace(&a->m2, b); + mons_vec4_mul_i_inplace(&a->m3, b); + mons_vec4_mul_i_inplace(&a->m4, b); +} + +mons_mat4 mons_mat4_mul(mons_mat4 a, mons_mat4 b) { + mons_vec4 b_n1 = mons_mat4_n1(b); + mons_vec4 b_n2 = mons_mat4_n2(b); + mons_vec4 b_n3 = mons_mat4_n3(b); + mons_vec4 b_n4 = mons_mat4_n4(b); + + mons_mat4 result = { + { + mons_vec4_dot(a.m1, b_n1), + mons_vec4_dot(a.m1, b_n2), + mons_vec4_dot(a.m1, b_n3), + mons_vec4_dot(a.m1, b_n4), + }, + { + mons_vec4_dot(a.m2, b_n1), + mons_vec4_dot(a.m2, b_n2), + mons_vec4_dot(a.m2, b_n3), + mons_vec4_dot(a.m2, b_n4), + }, + { + mons_vec4_dot(a.m3, b_n1), + mons_vec4_dot(a.m3, b_n2), + mons_vec4_dot(a.m3, b_n3), + mons_vec4_dot(a.m3, b_n4), + }, + { + mons_vec4_dot(a.m4, b_n1), + mons_vec4_dot(a.m4, b_n2), + mons_vec4_dot(a.m4, b_n3), + mons_vec4_dot(a.m4, b_n4), + }, + }; + return result; +} + +mons_mat4 mons_mat4_transpose(mons_mat4 a) { + mons_mat4 result = { + mons_mat4_n1(a), + mons_mat4_n2(a), + mons_mat4_n3(a), + mons_mat4_n4(a), + }; + return result; +} + +void mons_mat4_transpose_inplace(mons_mat4 *a) { *a = mons_mat4_transpose(*a); } + +mons_vec4 mons_mat4_n1(mons_mat4 a) { + mons_vec4 result = { + a.m1.x, + a.m2.x, + a.m3.x, + a.m4.x, + }; + return result; +} + +mons_vec4 mons_mat4_n2(mons_mat4 a) { + mons_vec4 result = { + a.m1.y, + a.m2.y, + a.m3.y, + a.m4.y, + }; + return result; +} + +mons_vec4 mons_mat4_n3(mons_mat4 a) { + mons_vec4 result = { + a.m1.z, + a.m2.z, + a.m3.z, + a.m4.z, + }; + return result; +} + +mons_vec4 mons_mat4_n4(mons_mat4 a) { + mons_vec4 result = { + a.m1.w, + a.m2.w, + a.m3.w, + a.m4.w, + }; + return result; +} + +float mons_mat4_determinant(mons_mat4 a) { + mons_mat3 minor_1_1 = { + {a.m2.y, a.m2.z, a.m2.w}, + {a.m3.y, a.m3.z, a.m3.w}, + {a.m4.y, a.m4.z, a.m4.w}, + }; + mons_mat3 minor_1_2 = { + {a.m2.x, a.m2.z, a.m2.w}, + {a.m3.x, a.m3.z, a.m3.w}, + {a.m4.x, a.m4.z, a.m4.w}, + }; + mons_mat3 minor_1_3 = { + {a.m2.x, a.m2.y, a.m2.w}, + {a.m3.x, a.m3.y, a.m3.w}, + {a.m4.x, a.m4.y, a.m4.w}, + }; + mons_mat3 minor_1_4 = { + {a.m2.x, a.m2.y, a.m2.z}, + {a.m3.x, a.m3.y, a.m3.z}, + {a.m4.x, a.m4.y, a.m4.z}, + }; + + return (a.m1.x * mons_mat3_determinant(minor_1_1)) - + (a.m1.y * mons_mat3_determinant(minor_1_2)) + + (a.m1.z * mons_mat3_determinant(minor_1_3)) - + (a.m1.w * mons_mat3_determinant(minor_1_4)); +} + +mons_mat4 mons_mat4_minor(mons_mat4 a) { + // First Row + mons_mat3 minor_1_1 = { + {a.m2.y, a.m2.z, a.m2.w}, + {a.m3.y, a.m3.z, a.m3.w}, + {a.m4.y, a.m4.z, a.m4.w}, + }; + float det_1_1 = mons_mat3_determinant(minor_1_1); + mons_mat3 minor_1_2 = { + {a.m2.x, a.m2.z, a.m2.w}, + {a.m3.x, a.m3.z, a.m3.w}, + {a.m4.x, a.m4.z, a.m4.w}, + }; + float det_1_2 = mons_mat3_determinant(minor_1_2); + mons_mat3 minor_1_3 = { + {a.m2.x, a.m2.y, a.m2.w}, + {a.m3.x, a.m3.y, a.m3.w}, + {a.m4.x, a.m4.y, a.m4.w}, + }; + float det_1_3 = mons_mat3_determinant(minor_1_3); + mons_mat3 minor_1_4 = { + {a.m2.x, a.m2.y, a.m2.z}, + {a.m3.x, a.m3.y, a.m3.z}, + {a.m4.x, a.m4.y, a.m4.z}, + }; + float det_1_4 = mons_mat3_determinant(minor_1_4); + // Second Row + mons_mat3 minor_2_1 = { + {a.m1.y, a.m1.z, a.m1.w}, + {a.m3.y, a.m3.z, a.m3.w}, + {a.m4.y, a.m4.z, a.m4.w}, + }; + float det_2_1 = mons_mat3_determinant(minor_2_1); + mons_mat3 minor_2_2 = { + {a.m1.x, a.m1.z, a.m1.w}, + {a.m3.x, a.m3.z, a.m3.w}, + {a.m4.x, a.m4.z, a.m4.w}, + }; + float det_2_2 = mons_mat3_determinant(minor_2_2); + mons_mat3 minor_2_3 = { + {a.m1.x, a.m1.y, a.m1.w}, + {a.m3.x, a.m3.y, a.m3.w}, + {a.m4.x, a.m4.y, a.m4.w}, + }; + float det_2_3 = mons_mat3_determinant(minor_2_3); + mons_mat3 minor_2_4 = { + {a.m1.x, a.m1.y, a.m1.z}, + {a.m3.x, a.m3.y, a.m3.z}, + {a.m4.x, a.m4.y, a.m4.z}, + }; + float det_2_4 = mons_mat3_determinant(minor_2_4); + // Third Row + mons_mat3 minor_3_1 = { + {a.m1.y, a.m1.z, a.m1.w}, + {a.m2.y, a.m2.z, a.m2.w}, + {a.m4.y, a.m4.z, a.m4.w}, + }; + float det_3_1 = mons_mat3_determinant(minor_3_1); + mons_mat3 minor_3_2 = { + {a.m1.x, a.m1.z, a.m1.w}, + {a.m2.x, a.m2.z, a.m2.w}, + {a.m4.x, a.m4.z, a.m4.w}, + }; + float det_3_2 = mons_mat3_determinant(minor_3_2); + mons_mat3 minor_3_3 = { + {a.m1.x, a.m1.y, a.m1.w}, + {a.m2.x, a.m2.y, a.m2.w}, + {a.m4.x, a.m4.y, a.m4.w}, + }; + float det_3_3 = mons_mat3_determinant(minor_3_3); + mons_mat3 minor_3_4 = { + {a.m1.x, a.m1.y, a.m1.z}, + {a.m2.x, a.m2.y, a.m2.z}, + {a.m4.x, a.m4.y, a.m4.z}, + }; + float det_3_4 = mons_mat3_determinant(minor_3_4); + // Fourth Row + mons_mat3 minor_4_1 = { + {a.m1.y, a.m1.z, a.m1.w}, + {a.m2.y, a.m2.z, a.m2.w}, + {a.m3.y, a.m3.z, a.m3.w}, + }; + float det_4_1 = mons_mat3_determinant(minor_4_1); + mons_mat3 minor_4_2 = { + {a.m1.x, a.m1.z, a.m1.w}, + {a.m2.x, a.m2.z, a.m2.w}, + {a.m3.x, a.m3.z, a.m3.w}, + }; + float det_4_2 = mons_mat3_determinant(minor_4_2); + mons_mat3 minor_4_3 = { + {a.m1.x, a.m1.y, a.m1.w}, + {a.m2.x, a.m2.y, a.m2.w}, + {a.m3.x, a.m3.y, a.m3.w}, + }; + float det_4_3 = mons_mat3_determinant(minor_4_3); + mons_mat3 minor_4_4 = { + {a.m1.x, a.m1.y, a.m1.z}, + {a.m2.x, a.m2.y, a.m2.z}, + {a.m3.x, a.m3.y, a.m3.z}, + }; + float det_4_4 = mons_mat3_determinant(minor_4_4); + + mons_mat4 result = { + {det_1_1, det_1_2, det_1_3, det_1_4}, + {det_2_1, det_2_2, det_2_3, det_2_4}, + {det_3_1, det_3_2, det_3_3, det_3_4}, + {det_4_1, det_4_2, det_4_3, det_4_4}, + }; + return result; +} + +mons_mat4 mons_mat4_cofactor(mons_mat4 a) { + mons_mat4 result = mons_mat4_minor(a); + result.m1.y *= -1; + result.m1.w *= -1; + result.m2.x *= -1; + result.m2.z *= -1; + result.m3.y *= -1; + result.m3.w *= -1; + result.m4.x *= -1; + result.m4.z *= -1; + return result; +} + +mons_mat4 mons_mat4_adjoint(mons_mat4 a) { + return mons_mat4_transpose(mons_mat4_cofactor(a)); +} + +mons_mat4 mons_mat4_inverse(mons_mat4 a) { + return mons_mat4_mul_f(mons_mat4_adjoint(a), + 1.0 / mons_mat4_determinant(a)); +} + +int mons_mat4_equal(mons_mat4 a, mons_mat4 b) { + return mons_vec4_equal(a.m1, b.m1) + && mons_vec4_equal(a.m2, b.m2) + && mons_vec4_equal(a.m3, b.m3) + && mons_vec4_equal(a.m4, b.m4); +} + +void mons_mat4_mul_inplace(mons_mat4 *a, mons_mat4 b) { + *a = mons_mat4_mul(*a, b); +} + +void mons_mat4_print(mons_mat4 mat) { + printf("[%.3f %.3f %.3f %.3f]\n", mat.m1.x, mat.m2.x, mat.m3.x, mat.m4.x); + printf("[%.3f %.3f %.3f %.3f]\n", mat.m1.y, mat.m2.y, mat.m3.y, mat.m4.y); + printf("[%.3f %.3f %.3f %.3f]\n", mat.m1.z, mat.m2.z, mat.m3.z, mat.m4.z); + printf("[%.3f %.3f %.3f %.3f]\n", mat.m1.w, mat.m2.w, mat.m3.w, mat.m4.w); +} |