Enhancement: Mtx_Inverse() returns a non-zero determinant if the matrix passed in can be inverted, otherwise returns zero if the matrix is singular/degenerative.

This commit is contained in:
Thompson Lee 2016-08-05 01:18:03 -04:00
parent acdcc69119
commit 237e22cdd1
2 changed files with 8 additions and 4 deletions

View File

@ -303,7 +303,7 @@ void Mtx_Multiply(C3D_Mtx* out, const C3D_Mtx* a, const C3D_Mtx* b);
* @retval true Matrix was inverted * @retval true Matrix was inverted
* @retval false Matrix is degenerate * @retval false Matrix is degenerate
*/ */
bool Mtx_Inverse(C3D_Mtx* out); float Mtx_Inverse(C3D_Mtx* out);
/** /**
* @brief Multiply 3x3 matrix by a FVec3 * @brief Multiply 3x3 matrix by a FVec3

View File

@ -1,8 +1,11 @@
#include <float.h> #include <float.h>
#include <c3d/maths.h> #include <c3d/maths.h>
bool Mtx_Inverse(C3D_Mtx* out) float Mtx_Inverse(C3D_Mtx* out)
{ {
//Mtx_Inverse can be used to calculate the determinant and the inverse of the matrix.
//It's an enhancement.
C3D_Mtx inv; C3D_Mtx inv;
float det; float det;
int i; int i;
@ -39,7 +42,8 @@ bool Mtx_Inverse(C3D_Mtx* out)
out->r[0].z * inv.r[2].x + out->r[0].w * inv.r[3].x; out->r[0].z * inv.r[2].x + out->r[0].w * inv.r[3].x;
if (fabsf(det) < FLT_EPSILON) if (fabsf(det) < FLT_EPSILON)
return false; //Returns 0.0f if we find the determinant is less than +/- FLT_EPSILON.
return 0.0f;
inv.r[0].y = -out->r[0].y * out->r[2].z * out->r[3].w + inv.r[0].y = -out->r[0].y * out->r[2].z * out->r[3].w +
out->r[0].y * out->r[2].w * out->r[3].z + out->r[0].y * out->r[2].w * out->r[3].z +
@ -130,5 +134,5 @@ bool Mtx_Inverse(C3D_Mtx* out)
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
out->m[i] = inv.m[i] * det; out->m[i] = inv.m[i] * det;
return true; return det;
} }