#include "mons_math/mat3.h" #include "mons_math/mat2.h" #include "mons_math/vec3.h" const mons_mat3 MONS_MAT3_ZERO = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, }; const mons_mat3 MONS_MAT3_IDENTITY = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, }; mons_mat3 mons_mat3_add(mons_mat3 a, mons_mat3 b) { mons_mat3 result = { mons_vec3_add(a.m1, b.m1), mons_vec3_add(a.m2, b.m2), mons_vec3_add(a.m3, b.m3), }; return result; } void mons_mat3_add_inplace(mons_mat3 *a, mons_mat3 b) { mons_vec3_add_inplace(&a->m1, b.m1); mons_vec3_add_inplace(&a->m2, b.m2); mons_vec3_add_inplace(&a->m3, b.m3); } mons_mat3 mons_mat3_mul_f(mons_mat3 a, float b) { mons_mat3 result = { mons_vec3_mul_f(a.m1, b), mons_vec3_mul_f(a.m2, b), mons_vec3_mul_f(a.m3, b), }; return result; } mons_mat3 mons_mat3_mul_i(mons_mat3 a, int b) { mons_mat3 result = { mons_vec3_mul_i(a.m1, b), mons_vec3_mul_i(a.m2, b), mons_vec3_mul_i(a.m3, b), }; return result; } mons_mat3 mons_mat3_mul(mons_mat3 a, mons_mat3 b) { mons_vec3 b_n1 = mons_mat3_n1(b); mons_vec3 b_n2 = mons_mat3_n2(b); mons_vec3 b_n3 = mons_mat3_n3(b); mons_mat3 result = { { mons_vec3_dot(a.m1, b_n1), mons_vec3_dot(a.m1, b_n2), mons_vec3_dot(a.m1, b_n3), }, { mons_vec3_dot(a.m2, b_n1), mons_vec3_dot(a.m2, b_n2), mons_vec3_dot(a.m2, b_n3), }, { mons_vec3_dot(a.m3, b_n1), mons_vec3_dot(a.m3, b_n2), mons_vec3_dot(a.m3, b_n3), }, }; return result; } void mons_mat3_mul_f_inplace(mons_mat3 *a, float b) { mons_vec3_mul_f_inplace(&a->m1, b); mons_vec3_mul_f_inplace(&a->m2, b); mons_vec3_mul_f_inplace(&a->m3, b); } void mons_mat3_mul_i_inplace(mons_mat3 *a, int b) { mons_vec3_mul_i_inplace(&a->m1, b); mons_vec3_mul_i_inplace(&a->m2, b); mons_vec3_mul_i_inplace(&a->m3, b); } mons_mat3 mons_mat3_transpose(mons_mat3 a) { mons_mat3 result = { mons_mat3_n1(a), mons_mat3_n2(a), mons_mat3_n3(a), }; } void mons_mat3_transpose_inplace(mons_mat3 *a) { *a = mons_mat3_transpose(*a); } mons_vec3 mons_mat3_n1(mons_mat3 a) { mons_vec3 result = { a.m1.x, a.m2.x, a.m3.x, }; return result; } mons_vec3 mons_mat3_n2(mons_mat3 a) { mons_vec3 result = { a.m1.y, a.m2.y, a.m3.y, }; return result; } mons_vec3 mons_mat3_n3(mons_mat3 a) { mons_vec3 result = { a.m1.z, a.m2.z, a.m3.z, }; return result; } float mons_mat3_determinant(mons_mat3 a) { /* * a * det( * e f * h i * ) * - b * det( * d f * g i * ) * + c * det( * d e * g h * ) */ mons_mat2 efhi = { {a.m2.y, a.m2.z}, {a.m3.y, a.m3.z}, }; mons_mat2 dfgi = { {a.m2.x, a.m2.z}, {a.m3.x, a.m3.z}, }; mons_mat2 degh = { {a.m2.x, a.m2.y}, {a.m3.x, a.m3.y}, }; return (a.m1.x * mons_mat2_determinant(efhi)) - (a.m1.y * mons_mat2_determinant(dfgi)) + (a.m1.z * mons_mat2_determinant(degh)); } mons_mat3 mons_mat3_minor(mons_mat3 a) { // Get determinants of minors // First row elements mons_mat2 minor_1_1 = { {a.m2.y, a.m2.z}, {a.m3.y, a.m3.z}, }; float det_1_1 = mons_mat2_determinant(minor_1_1); mons_mat2 minor_1_2 = { {a.m2.x, a.m2.z}, {a.m3.x, a.m3.z}, }; float det_1_2 = mons_mat2_determinant(minor_1_2); mons_mat2 minor_1_3 = { {a.m2.x, a.m2.y}, {a.m3.x, a.m3.y}, }; float det_1_3 = mons_mat2_determinant(minor_1_3); // Second row elements mons_mat2 minor_2_1 = { {a.m1.y, a.m1.z}, {a.m3.y, a.m3.z}, }; float det_2_1 = mons_mat2_determinant(minor_2_1); mons_mat2 minor_2_2 = { {a.m1.x, a.m1.z}, {a.m3.x, a.m3.z}, }; float det_2_2 = mons_mat2_determinant(minor_2_2); mons_mat2 minor_2_3 = { {a.m1.x, a.m1.y}, {a.m3.x, a.m3.y}, }; float det_2_3 = mons_mat2_determinant(minor_2_3); // Third row elements mons_mat2 minor_3_1 = { {a.m1.y, a.m1.z}, {a.m2.y, a.m2.z}, }; float det_3_1 = mons_mat2_determinant(minor_3_1); mons_mat2 minor_3_2 = { {a.m1.x, a.m1.z}, {a.m2.x, a.m2.z}, }; float det_3_2 = mons_mat2_determinant(minor_3_2); mons_mat2 minor_3_3 = { {a.m1.x, a.m1.y}, {a.m2.x, a.m2.y}, }; float det_3_3 = mons_mat2_determinant(minor_3_3); mons_mat3 result = { {det_1_1, det_1_2, det_1_3}, {det_2_1, det_2_2, det_2_3}, {det_3_1, det_3_2, det_3_3}, }; return result; } mons_mat3 mons_mat3_cofactor(mons_mat3 a) { mons_mat3 result = mons_mat3_minor(a); result.m1.y *= -1; result.m2.x *= -1; result.m2.z *= -1; result.m3.y *= -1; return result; } mons_mat3 mons_mat3_adjoint(mons_mat3 a) { return mons_mat3_transpose(mons_mat3_cofactor(a)); } mons_mat3 mons_mat3_inverse(mons_mat3 a) { return mons_mat3_mul_f(mons_mat3_adjoint(a), 1.0 / mons_mat3_determinant(a)); } int mons_mat3_equal(mons_mat3 a, mons_mat3 b) { return mons_vec3_equal(a.m1, b.m1) && mons_vec3_equal(a.m2, b.m2) && mons_vec3_equal(a.m3, b.m3); }