cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=bb926e2dc72740a5c6eac9954be91f1d12bc492a
commit bb926e2dc72740a5c6eac9954be91f1d12bc492a Author: Cedric BAIL <ced...@osg.samsung.com> Date: Wed Jun 24 18:57:46 2015 +0200 eina: add eina_matrix4_inverse. --- src/lib/eina/eina_matrix.c | 163 +++++++++++++++++++++++++++++++++++++++++++++ src/lib/eina/eina_matrix.h | 10 +++ 2 files changed, 173 insertions(+) diff --git a/src/lib/eina/eina_matrix.c b/src/lib/eina/eina_matrix.c index a43c5b2..6219004 100644 --- a/src/lib/eina/eina_matrix.c +++ b/src/lib/eina/eina_matrix.c @@ -752,3 +752,166 @@ eina_matrix4_normalized(Eina_Matrix4 *out, const Eina_Matrix4 *in) return EINA_TRUE; } + +EAPI Eina_Bool +eina_matrix4_inverse(Eina_Matrix4 *out, const Eina_Matrix4 *in) +{ + double det; + + MATRIX_XX(out) = + MATRIX_YY(in) * MATRIX_ZZ(in) * MATRIX_WW(in) + - MATRIX_YY(in) * MATRIX_ZW(in) * MATRIX_WZ(in) + - MATRIX_ZY(in) * MATRIX_YZ(in) * MATRIX_WW(in) + + MATRIX_ZY(in) * MATRIX_YW(in) * MATRIX_WZ(in) + + MATRIX_WY(in) * MATRIX_YZ(in) * MATRIX_ZW(in) + - MATRIX_WY(in) * MATRIX_YW(in) * MATRIX_ZZ(in); + + MATRIX_YX(out) = + - MATRIX_YX(in) * MATRIX_ZZ(in) * MATRIX_WW(in) + + MATRIX_YX(in) * MATRIX_ZW(in) * MATRIX_WZ(in) + + MATRIX_ZX(in) * MATRIX_YZ(in) * MATRIX_WW(in) + - MATRIX_ZX(in) * MATRIX_YW(in) * MATRIX_WZ(in) + - MATRIX_WX(in) * MATRIX_YZ(in) * MATRIX_ZW(in) + + MATRIX_WX(in) * MATRIX_YW(in) * MATRIX_ZZ(in); + + MATRIX_ZX(out) = + MATRIX_YX(in) * MATRIX_ZY(in) * MATRIX_WW(in) + - MATRIX_YX(in) * MATRIX_ZW(in) * MATRIX_WY(in) + - MATRIX_ZX(in) * MATRIX_YY(in) * MATRIX_WW(in) + + MATRIX_ZX(in) * MATRIX_YW(in) * MATRIX_WY(in) + + MATRIX_WX(in) * MATRIX_YY(in) * MATRIX_ZW(in) + - MATRIX_WX(in) * MATRIX_YW(in) * MATRIX_ZY(in); + + MATRIX_WX(out) = + - MATRIX_YX(in) * MATRIX_ZY(in) * MATRIX_WZ(in) + + MATRIX_YX(in) * MATRIX_ZZ(in) * MATRIX_WY(in) + + MATRIX_ZX(in) * MATRIX_YY(in) * MATRIX_WZ(in) + - MATRIX_ZX(in) * MATRIX_YZ(in) * MATRIX_WY(in) + - MATRIX_WX(in) * MATRIX_YY(in) * MATRIX_ZZ(in) + + MATRIX_WX(in) * MATRIX_YZ(in) * MATRIX_ZY(in); + + MATRIX_XY(out) = + - MATRIX_XY(in) * MATRIX_ZZ(in) * MATRIX_WW(in) + + MATRIX_XY(in) * MATRIX_ZW(in) * MATRIX_WZ(in) + + MATRIX_ZY(in) * MATRIX_XZ(in) * MATRIX_WW(in) + - MATRIX_ZY(in) * MATRIX_XW(in) * MATRIX_WZ(in) + - MATRIX_WY(in) * MATRIX_XZ(in) * MATRIX_ZW(in) + + MATRIX_WY(in) * MATRIX_XW(in) * MATRIX_ZZ(in); + + MATRIX_YY(out) = + MATRIX_XX(in) * MATRIX_ZZ(in) * MATRIX_WW(in) + - MATRIX_XX(in) * MATRIX_ZW(in) * MATRIX_WZ(in) + - MATRIX_ZX(in) * MATRIX_XZ(in) * MATRIX_WW(in) + + MATRIX_ZX(in) * MATRIX_XW(in) * MATRIX_WZ(in) + + MATRIX_WX(in) * MATRIX_XZ(in) * MATRIX_ZW(in) + - MATRIX_WX(in) * MATRIX_XW(in) * MATRIX_ZZ(in); + + MATRIX_ZY(out) = + - MATRIX_XX(in) * MATRIX_ZY(in) * MATRIX_WW(in) + + MATRIX_XX(in) * MATRIX_ZW(in) * MATRIX_WY(in) + + MATRIX_ZX(in) * MATRIX_XY(in) * MATRIX_WW(in) + - MATRIX_ZX(in) * MATRIX_XW(in) * MATRIX_WY(in) + - MATRIX_WX(in) * MATRIX_XY(in) * MATRIX_ZW(in) + + MATRIX_WX(in) * MATRIX_XW(in) * MATRIX_ZY(in); + + MATRIX_WY(out) = + MATRIX_XX(in) * MATRIX_ZY(in) * MATRIX_WZ(in) + - MATRIX_XX(in) * MATRIX_ZZ(in) * MATRIX_WY(in) + - MATRIX_ZX(in) * MATRIX_XY(in) * MATRIX_WZ(in) + + MATRIX_ZX(in) * MATRIX_XZ(in) * MATRIX_WY(in) + + MATRIX_WX(in) * MATRIX_XY(in) * MATRIX_ZZ(in) + - MATRIX_WX(in) * MATRIX_XZ(in) * MATRIX_ZY(in); + + MATRIX_XZ(out) = + MATRIX_XY(in) * MATRIX_YZ(in) * MATRIX_WW(in) + - MATRIX_XY(in) * MATRIX_YW(in) * MATRIX_WZ(in) + - MATRIX_YY(in) * MATRIX_XZ(in) * MATRIX_WW(in) + + MATRIX_YY(in) * MATRIX_XW(in) * MATRIX_WZ(in) + + MATRIX_WY(in) * MATRIX_XZ(in) * MATRIX_YW(in) + - MATRIX_WY(in) * MATRIX_XW(in) * MATRIX_YZ(in); + + MATRIX_YZ(out) = + - MATRIX_XX(in) * MATRIX_YZ(in) * MATRIX_WW(in) + + MATRIX_XX(in) * MATRIX_YW(in) * MATRIX_WZ(in) + + MATRIX_YX(in) * MATRIX_XZ(in) * MATRIX_WW(in) + - MATRIX_YX(in) * MATRIX_XW(in) * MATRIX_WZ(in) + - MATRIX_WX(in) * MATRIX_XZ(in) * MATRIX_YW(in) + + MATRIX_WX(in) * MATRIX_XW(in) * MATRIX_YZ(in); + + MATRIX_ZZ(out) = + MATRIX_XX(in) * MATRIX_YY(in) * MATRIX_WW(in) + - MATRIX_XX(in) * MATRIX_YW(in) * MATRIX_WY(in) + - MATRIX_YX(in) * MATRIX_XY(in) * MATRIX_WW(in) + + MATRIX_YX(in) * MATRIX_XW(in) * MATRIX_WY(in) + + MATRIX_WX(in) * MATRIX_XY(in) * MATRIX_YW(in) + - MATRIX_WX(in) * MATRIX_XW(in) * MATRIX_YY(in); + + MATRIX_WZ(out) = + - MATRIX_XX(in) * MATRIX_YY(in) * MATRIX_WZ(in) + + MATRIX_XX(in) * MATRIX_YZ(in) * MATRIX_WY(in) + + MATRIX_YX(in) * MATRIX_XY(in) * MATRIX_WZ(in) + - MATRIX_YX(in) * MATRIX_XZ(in) * MATRIX_WY(in) + - MATRIX_WX(in) * MATRIX_XY(in) * MATRIX_YZ(in) + + MATRIX_WX(in) * MATRIX_XZ(in) * MATRIX_YY(in); + + MATRIX_XW(out) = + - MATRIX_XY(in) * MATRIX_YZ(in) * MATRIX_ZW(in) + + MATRIX_XY(in) * MATRIX_YW(in) * MATRIX_ZZ(in) + + MATRIX_YY(in) * MATRIX_XZ(in) * MATRIX_ZW(in) + - MATRIX_YY(in) * MATRIX_XW(in) * MATRIX_ZZ(in) + - MATRIX_ZY(in) * MATRIX_XZ(in) * MATRIX_YW(in) + + MATRIX_ZY(in) * MATRIX_XW(in) * MATRIX_YZ(in); + + MATRIX_YW(out) = + MATRIX_XX(in) * MATRIX_YZ(in) * MATRIX_ZW(in) + - MATRIX_XX(in) * MATRIX_YW(in) * MATRIX_ZZ(in) + - MATRIX_YX(in) * MATRIX_XZ(in) * MATRIX_ZW(in) + + MATRIX_YX(in) * MATRIX_XW(in) * MATRIX_ZZ(in) + + MATRIX_ZX(in) * MATRIX_XZ(in) * MATRIX_YW(in) + - MATRIX_ZX(in) * MATRIX_XW(in) * MATRIX_YZ(in); + + MATRIX_ZW(out) = + - MATRIX_XX(in) * MATRIX_YY(in) * MATRIX_ZW(in) + + MATRIX_XX(in) * MATRIX_YW(in) * MATRIX_ZY(in) + + MATRIX_YX(in) * MATRIX_XY(in) * MATRIX_ZW(in) + - MATRIX_YX(in) * MATRIX_XW(in) * MATRIX_ZY(in) + - MATRIX_ZX(in) * MATRIX_XY(in) * MATRIX_YW(in) + + MATRIX_ZX(in) * MATRIX_XW(in) * MATRIX_YY(in); + + MATRIX_WW(out) = + MATRIX_XX(in) * MATRIX_YY(in) * MATRIX_ZZ(in) + - MATRIX_XX(in) * MATRIX_YZ(in) * MATRIX_ZY(in) + - MATRIX_YX(in) * MATRIX_XY(in) * MATRIX_ZZ(in) + + MATRIX_YX(in) * MATRIX_XZ(in) * MATRIX_ZY(in) + + MATRIX_ZX(in) * MATRIX_XY(in) * MATRIX_YZ(in) + - MATRIX_ZX(in) * MATRIX_XZ(in) * MATRIX_YY(in); + + det = + MATRIX_XX(in) * MATRIX_XX(out) + + MATRIX_XY(in) * MATRIX_YX(out) + + MATRIX_XZ(in) * MATRIX_ZX(out) + + MATRIX_XW(in) * MATRIX_WX(out); + + if (fabs(det) < DBL_EPSILON) return EINA_FALSE; + + det = 1.0 / det; + + MATRIX_XX(out) = MATRIX_XX(out) * det; + MATRIX_XY(out) = MATRIX_XY(out) * det; + MATRIX_XZ(out) = MATRIX_XZ(out) * det; + MATRIX_XW(out) = MATRIX_XW(out) * det; + MATRIX_YX(out) = MATRIX_YX(out) * det; + MATRIX_YY(out) = MATRIX_YY(out) * det; + MATRIX_YZ(out) = MATRIX_YZ(out) * det; + MATRIX_YW(out) = MATRIX_YW(out) * det; + MATRIX_ZX(out) = MATRIX_ZX(out) * det; + MATRIX_ZY(out) = MATRIX_ZY(out) * det; + MATRIX_ZZ(out) = MATRIX_ZZ(out) * det; + MATRIX_ZW(out) = MATRIX_ZW(out) * det; + MATRIX_WX(out) = MATRIX_WX(out) * det; + MATRIX_WY(out) = MATRIX_WY(out) * det; + MATRIX_WZ(out) = MATRIX_WZ(out) * det; + MATRIX_WW(out) = MATRIX_WW(out) * det; + + return EINA_TRUE; +} diff --git a/src/lib/eina/eina_matrix.h b/src/lib/eina/eina_matrix.h index bf02f17..1f11be3 100644 --- a/src/lib/eina/eina_matrix.h +++ b/src/lib/eina/eina_matrix.h @@ -538,6 +538,16 @@ EAPI double eina_matrix4_determinant(const Eina_Matrix4 *m); EAPI Eina_Bool eina_matrix4_normalized(Eina_Matrix4 *out, const Eina_Matrix4 *in); +/** + * @brief Return the inverse of the given matrix. + * + * @param out The inverse matrix + * @param in The matrix. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @since 1.15 + */ +EAPI Eina_Bool eina_matrix4_inverse(Eina_Matrix4 *out, const Eina_Matrix4 *in); /** * @brief Convert an Eina_Matrix4 into an Eina_Matrix3. --