diff --git a/src/lib/eina/eina_matrix.c b/src/lib/eina/eina_matrix.c index 2e994df758..a43c5b294f 100644 --- a/src/lib/eina/eina_matrix.c +++ b/src/lib/eina/eina_matrix.c @@ -23,6 +23,7 @@ #include "eina_private.h" #include +#include #include "eina_fp.h" #include "eina_rectangle.h" @@ -723,3 +724,31 @@ eina_matrix4_determinant(const Eina_Matrix4 *m) - MATRIX_XY(m) * MATRIX_YX(m) * MATRIX_ZZ(m) * MATRIX_WW(m) + MATRIX_XX(m) * MATRIX_YY(m) * MATRIX_ZZ(m) * MATRIX_WW(m); } + +EAPI Eina_Bool +eina_matrix4_normalized(Eina_Matrix4 *out, const Eina_Matrix4 *in) +{ + double det; + + det = eina_matrix4_determinant(in); + if (fabs(det) < DBL_EPSILON) return EINA_FALSE; + + MATRIX_XX(out) = MATRIX_XX(in) / det; + MATRIX_XY(out) = MATRIX_XY(in) / det; + MATRIX_XZ(out) = MATRIX_XZ(in) / det; + MATRIX_XW(out) = MATRIX_XW(in) / det; + MATRIX_YX(out) = MATRIX_YX(in) / det; + MATRIX_YY(out) = MATRIX_YY(in) / det; + MATRIX_YZ(out) = MATRIX_YZ(in) / det; + MATRIX_YW(out) = MATRIX_YW(in) / det; + MATRIX_ZX(out) = MATRIX_ZX(in) / det; + MATRIX_ZY(out) = MATRIX_ZY(in) / det; + MATRIX_ZZ(out) = MATRIX_ZZ(in) / det; + MATRIX_ZW(out) = MATRIX_ZW(in) / det; + MATRIX_WX(out) = MATRIX_WX(in) / det; + MATRIX_WY(out) = MATRIX_WY(in) / det; + MATRIX_WZ(out) = MATRIX_WZ(in) / det; + MATRIX_WW(out) = MATRIX_WW(in) / det; + + return EINA_TRUE; +} diff --git a/src/lib/eina/eina_matrix.h b/src/lib/eina/eina_matrix.h index 8dc7014037..bf02f17b5b 100644 --- a/src/lib/eina/eina_matrix.h +++ b/src/lib/eina/eina_matrix.h @@ -524,6 +524,21 @@ EAPI void eina_matrix4_values_get(const Eina_Matrix4 *m, */ EAPI double eina_matrix4_determinant(const Eina_Matrix4 *m); +/** + * @brief Return the determinant of the given matrix. + * + * @param m The matrix. + * @return The determinant. + * + * This function returns the determinant of the matrix @p m. No check + * is done on @p m. + * + * @since 1.15 + */ +EAPI Eina_Bool eina_matrix4_normalized(Eina_Matrix4 *out, + const Eina_Matrix4 *in); + + /** * @brief Convert an Eina_Matrix4 into an Eina_Matrix3. *