From 9a83100a4ac1b040bde8aa63c868be3ad806758a Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Thu, 28 May 2015 14:35:55 +0200 Subject: [PATCH] eina: add the beginning of an Eina_Matrix4 API. --- src/Makefile_Eina.am | 5 +- src/lib/eina/eina_matrix.c | 103 +++++++++++++++++++++++++++++ src/lib/eina/eina_matrix.h | 135 ++++++++++++++++++++++++++++++++++++++ src/tests/eina/eina_suite.c | 5 +- src/tests/eina/eina_suite.h | 1 + src/tests/eina/eina_test_matrix.c | 100 ++++++++++++++++++++++++++++ 6 files changed, 344 insertions(+), 5 deletions(-) create mode 100644 src/tests/eina/eina_test_matrix.c diff --git a/src/Makefile_Eina.am b/src/Makefile_Eina.am index 532c051..6cf5ae5 100644 --- a/src/Makefile_Eina.am +++ b/src/Makefile_Eina.am @@ -310,9 +310,8 @@ tests/eina/eina_test_trash.c \ tests/eina/eina_test_lock.c \ tests/eina/eina_test_xattr.c \ tests/eina/eina_test_crc.c \ -tests/eina/eina_test_quad.c -# tests/eina/eina_test_model.c - +tests/eina/eina_test_quad.c \ +tests/eina/eina_test_matrix.c tests_eina_eina_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ -DTESTS_WD=\"`pwd`\" \ diff --git a/src/lib/eina/eina_matrix.c b/src/lib/eina/eina_matrix.c index 468acf5..8e2d0be 100644 --- a/src/lib/eina/eina_matrix.c +++ b/src/lib/eina/eina_matrix.c @@ -32,12 +32,19 @@ #define MATRIX_XX(m) (m)->xx #define MATRIX_XY(m) (m)->xy #define MATRIX_XZ(m) (m)->xz +#define MATRIX_XW(m) (m)->xw #define MATRIX_YX(m) (m)->yx #define MATRIX_YY(m) (m)->yy #define MATRIX_YZ(m) (m)->yz +#define MATRIX_YW(m) (m)->yw #define MATRIX_ZX(m) (m)->zx #define MATRIX_ZY(m) (m)->zy #define MATRIX_ZZ(m) (m)->zz +#define MATRIX_ZW(m) (m)->zw +#define MATRIX_WX(m) (m)->wx +#define MATRIX_WY(m) (m)->wy +#define MATRIX_WZ(m) (m)->wz +#define MATRIX_WW(m) (m)->ww #define MATRIX_SIZE 9 #define QUAD_X0(q) q->x0 @@ -109,6 +116,17 @@ eina_matrix3_type_get(const Eina_Matrix3 *m) } EAPI Eina_Matrix_Type +eina_matrix4_type_get(const Eina_Matrix4 *m) +{ + if ((MATRIX_XX(m) == 1) && (MATRIX_XY(m) == 0) && (MATRIX_XZ(m) == 0) && (MATRIX_XW(m) == 0) && + (MATRIX_YX(m) == 0) && (MATRIX_YY(m) == 1) && (MATRIX_YZ(m) == 0) && (MATRIX_YW(m) == 0) && + (MATRIX_ZX(m) == 0) && (MATRIX_ZY(m) == 0) && (MATRIX_ZZ(m) == 1) && (MATRIX_ZW(m) == 0) && + (MATRIX_WX(m) == 0) && (MATRIX_WY(m) == 0) && (MATRIX_WZ(m) == 0) && (MATRIX_WW(m) == 1)) + return EINA_MATRIX_TYPE_IDENTITY; + return EINA_MATRIX_TYPE_AFFINE; +} + +EAPI Eina_Matrix_Type eina_matrix3_f16p16_type_get(const Eina_Matrix3_F16p16 *m) { if ((MATRIX_ZX(m) != 0) || (MATRIX_ZY(m) != 0) || (MATRIX_ZZ(m) != 65536)) @@ -158,6 +176,56 @@ eina_matrix3_values_get(const Eina_Matrix3 *m, } EAPI void +eina_matrix4_values_set(Eina_Matrix4 *m, + double xx, double xy, double xz, double xw, + double yx, double yy, double yz, double yw, + double zx, double zy, double zz, double zw, + double wx, double wy, double wz, double ww) +{ + MATRIX_XX(m) = xx; + MATRIX_XY(m) = xy; + MATRIX_XZ(m) = xz; + MATRIX_XW(m) = xw; + MATRIX_YX(m) = yx; + MATRIX_YY(m) = yy; + MATRIX_YZ(m) = yz; + MATRIX_YW(m) = yw; + MATRIX_ZX(m) = zx; + MATRIX_ZY(m) = zy; + MATRIX_ZZ(m) = zz; + MATRIX_ZW(m) = zw; + MATRIX_WX(m) = wx; + MATRIX_WY(m) = wy; + MATRIX_WZ(m) = wz; + MATRIX_WW(m) = ww; +} + +EAPI void +eina_matrix4_values_get(const Eina_Matrix4 *m, + double *xx, double *xy, double *xz, double *xw, + double *yx, double *yy, double *yz, double *yw, + double *zx, double *zy, double *zz, double *zw, + double *wx, double *wy, double *wz, double *ww) +{ + if (xx) *xx = MATRIX_XX(m); + if (xy) *xy = MATRIX_XY(m); + if (xz) *xz = MATRIX_XZ(m); + if (xw) *xw = MATRIX_XW(m); + if (yx) *yx = MATRIX_YX(m); + if (yy) *yy = MATRIX_YY(m); + if (yz) *yz = MATRIX_YZ(m); + if (yw) *yw = MATRIX_YW(m); + if (zx) *zx = MATRIX_ZX(m); + if (zy) *zy = MATRIX_ZY(m); + if (zz) *zz = MATRIX_ZZ(m); + if (zw) *zw = MATRIX_ZW(m); + if (wx) *wx = MATRIX_WX(m); + if (wy) *wy = MATRIX_WY(m); + if (wz) *wz = MATRIX_WZ(m); + if (ww) *ww = MATRIX_WW(m); +} + +EAPI void eina_matrix3_fixed_values_get(const Eina_Matrix3 *m, Eina_F16p16 *xx, Eina_F16p16 *xy, Eina_F16p16 *xz, Eina_F16p16 *yx, Eina_F16p16 *yy, Eina_F16p16 *yz, @@ -590,3 +658,38 @@ eina_matrix3_quad_quad_map(Eina_Matrix3 *m, return EINA_TRUE; } + +EAPI void +eina_matrix4_matrix3_to(Eina_Matrix3 *m3, const Eina_Matrix4 *m4) +{ + MATRIX_XX(m3) = MATRIX_XX(m4); + MATRIX_XY(m3) = MATRIX_XY(m4); + MATRIX_XZ(m3) = MATRIX_XZ(m4); + MATRIX_YX(m3) = MATRIX_YX(m4); + MATRIX_YY(m3) = MATRIX_YY(m4); + MATRIX_YZ(m3) = MATRIX_YZ(m4); + MATRIX_ZX(m3) = MATRIX_ZX(m4); + MATRIX_ZY(m3) = MATRIX_ZY(m4); + MATRIX_ZZ(m3) = MATRIX_ZZ(m4); +} + +EAPI void +eina_matrix3_matrix4_to(Eina_Matrix4 *m4, const Eina_Matrix3 *m3) +{ + MATRIX_XX(m4) = MATRIX_XX(m3); + MATRIX_XY(m4) = MATRIX_XY(m3); + MATRIX_XZ(m4) = MATRIX_XZ(m3); + MATRIX_XW(m4) = 0; + MATRIX_YX(m4) = MATRIX_YX(m3); + MATRIX_YY(m4) = MATRIX_YY(m3); + MATRIX_YZ(m4) = MATRIX_YZ(m3); + MATRIX_YW(m4) = 0; + MATRIX_ZX(m4) = MATRIX_ZX(m3); + MATRIX_ZY(m4) = MATRIX_ZY(m3); + MATRIX_ZZ(m4) = MATRIX_ZZ(m3); + MATRIX_ZW(m4) = 0; + MATRIX_WX(m4) = 0; + MATRIX_WY(m4) = 0; + MATRIX_WZ(m4) = 0; + MATRIX_WW(m4) = 1; +} diff --git a/src/lib/eina/eina_matrix.h b/src/lib/eina/eina_matrix.h index 4f6c23e..83fff16 100644 --- a/src/lib/eina/eina_matrix.h +++ b/src/lib/eina/eina_matrix.h @@ -398,5 +398,140 @@ EAPI Eina_Bool eina_matrix3_quad_square_map(Eina_Matrix3 *m, /** * @} + * @defgroup Eina_Matrix4 Matrices in floating point + * @ingroup Eina_Basic + * @brief Matrix definition and operations + * @{ + */ + +typedef struct _Eina_Matrix4 Eina_Matrix4; +struct _Eina_Matrix4 +{ + double xx; /**< xx in x' = (x * xx) + (y * xy) + (z * xz) + xw */ + double xy; /**< xy in x' = (x * xx) + (y * xy) + (z * xz) + xw */ + double xz; /**< xz in x' = (x * xx) + (y * xy) + (z * xz) + xw */ + double xw; /**< xw in x' = (x * xx) + (y * xy) + (z * xz) + xw */ + + double yx; /**< yx in y' = (x * yx) + (y * yy) + (z * yz) + yw */ + double yy; /**< yy in y' = (x * yx) + (y * yy) + (z * yz) + yw */ + double yz; /**< yz in y' = (x * yx) + (y * yy) + (z * yz) + yw */ + double yw; /**< yw in y' = (x * yx) + (y * yy) + (z * yz) + yw */ + + double zx; /**< zx in z' = (x * zx) + (y * zy) + (z * zz) + zw */ + double zy; /**< zy in z' = (x * zx) + (y * zy) + (z * zz) + zw */ + double zz; /**< zz in z' = (x * zx) + (y * zy) + (z * zz) + zw */ + double zw; /**< zw in z' = (x * zx) + (y * zy) + (z * zz) + zw */ + + double wx; /**< wx in w' = (x * wx) + (y * wy) + (z * wz) + ww */ + double wy; /**< wy in w' = (x * wx) + (y * wy) + (z * wz) + ww */ + double wz; /**< wz in w' = (x * wx) + (y * wy) + (z * wz) + ww */ + double ww; /**< ww in w' = (x * wx) + (y * wy) + (z * wz) + ww */ +}; + +/** + * @brief Return the type of the given floating point matrix. + * + * @param m The floating point matrix. + * @return The type of the matrix. + * + * This function returns the type of the matrix @p m. No check is done + * on @p m. + * + * @since 1.15 + */ +EAPI Eina_Matrix_Type eina_matrix4_type_get(const Eina_Matrix4 *m); + +/** + * @brief Set the values of the coefficients of the given floating + * point matrix. + * + * @param m The floating point matrix. + * @param xx The first coefficient value. + * @param xy The second coefficient value. + * @param xz The third coefficient value. + * @param xw The fourth coefficient value. + * @param yx The fifth coefficient value. + * @param yy The sixth coefficient value. + * @param yz The seventh coefficient value. + * @param yw The heighth coefficient value. + * @param zx The nineth coefficient value. + * @param zy The tenth coefficient value. + * @param zz The eleventh coefficient value. + * @param zw The twelfth coefficient value. + * @param wx The thirteenth coefficient value. + * @param wy The fourteenth coefficient value. + * @param wz The fifteenth coefficient value. + * @param ww The sizteenth coefficient value. + * + * This function sets the values of the coefficients of the matrix + * @p m. No check is done on @p m. + * + * @see eina_matrix4_values_get() + * + * @since 1.15 + */ +EAPI void eina_matrix4_values_set(Eina_Matrix4 *m, + double xx, double xy, double xz, double xw, + double yx, double yy, double yz, double yw, + double zx, double zy, double zz, double zw, + double wx, double wy, double wz, double ww); + +/** + * @brief Get the values of the coefficients of the given floating + * point matrix. + * + * @param m The floating point matrix. + * @param xx The first coefficient value. + * @param xy The second coefficient value. + * @param xz The third coefficient value. + * @param xw The fourth coefficient value. + * @param yx The fifth coefficient value. + * @param yy The sixth coefficient value. + * @param yz The seventh coefficient value. + * @param yw The heighth coefficient value. + * @param zx The nineth coefficient value. + * @param zy The tenth coefficient value. + * @param zz The eleventh coefficient value. + * @param zw The twelfth coefficient value. + * @param wx The thirteenth coefficient value. + * @param wy The fourteenth coefficient value. + * @param wz The fifteenth coefficient value. + * @param ww The sizteenth coefficient value. + * + * This function gets the values of the coefficients of the matrix + * @p m. No check is done on @p m. + * + * @see eina_matrix4_values_set() + * + * @since 1.15 + */ +EAPI void eina_matrix4_values_get(const Eina_Matrix4 *m, + double *xx, double *xy, double *xz, double *xw, + double *yx, double *yy, double *yz, double *yw, + double *zx, double *zy, double *zz, double *zw, + double *wx, double *wy, double *wz, double *ww); + +/** + * @brief Convert an Eina_Matrix4 into an Eina_Matrix3. + * + * @param m3 The destination Eina_Matrix3. + * @param m4 The source Eina_Matrix4. + * + * @since 1.15 + */ +EAPI void eina_matrix4_matrix3_to(Eina_Matrix3 *m3, const Eina_Matrix4 *m4); + +/** + * @brief Convert an Eina_Matrix3 into an Eina_Matrix4. + * + * @param m3 The destination Eina_Matrix3. + * @param m4 The source Eina_Matrix4. + * + * @since 1.15 + */ +EAPI void eina_matrix3_matrix4_to(Eina_Matrix4 *m4, const Eina_Matrix3 *m3); + +/** + * @} */ #endif /*EINA_MATRIX3_H_*/ diff --git a/src/tests/eina/eina_suite.c b/src/tests/eina/eina_suite.c index 17706cf..5383bb6 100644 --- a/src/tests/eina/eina_suite.c +++ b/src/tests/eina/eina_suite.c @@ -79,8 +79,9 @@ static const Eina_Test_Case etc[] = { #ifdef XATTR_TEST_DIR { "Xattr", eina_test_xattr }, #endif - {"Crc", eina_test_crc }, - {"Quad", eina_test_quad }, + { "Crc", eina_test_crc }, + { "Quad", eina_test_quad }, + { "Matrix", eina_test_matrix }, { NULL, NULL } }; diff --git a/src/tests/eina/eina_suite.h b/src/tests/eina/eina_suite.h index 9f3df3a..d39254d 100644 --- a/src/tests/eina/eina_suite.h +++ b/src/tests/eina/eina_suite.h @@ -66,5 +66,6 @@ void eina_test_trash(TCase *tc); void eina_test_xattr(TCase *tc); void eina_test_crc(TCase *tc); void eina_test_quad(TCase *tc); +void eina_test_matrix(TCase *tc); #endif /* EINA_SUITE_H_ */ diff --git a/src/tests/eina/eina_test_matrix.c b/src/tests/eina/eina_test_matrix.c new file mode 100644 index 0000000..046876d --- /dev/null +++ b/src/tests/eina/eina_test_matrix.c @@ -0,0 +1,100 @@ +/* EINA - EFL data type library + * Copyright (C) 2015 Cedric Bail + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "eina_suite.h" +#include "Eina.h" + +START_TEST(eina_matrix4) +{ + Eina_Matrix4 m; + double xx, xy, xz, xw, + yx, yy, yz, yw, + zx, zy, zz, zw, + wx, wy, wz, ww; + + eina_init(); + + eina_matrix4_values_set(&m, + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + fail_if(eina_matrix4_type_get(&m) != EINA_MATRIX_TYPE_IDENTITY); + + eina_matrix4_values_get(&m, + &xx, &xy, &xz, &xw, + &yx, &yy, &yz, &yw, + &zx, &zy, &zz, &zw, + &wx, &wy, &wz, &ww); + + fail_if(xx != yy || + yy != zz || + zz != ww || + ww != 1); + fail_if(xy != xz || + xz != xw || + xw != yx || + yx != yz || + yz != yw || + yw != zx || + zx != zy || + zy != zw || + zw != wx || + wx != wy || + wy != wz || + wz != 0); + + eina_shutdown(); +} +END_TEST + +START_TEST(eina_matrix4_2_3) +{ + Eina_Matrix4 m4, m4b; + Eina_Matrix3 m3; + + eina_init(); + + eina_matrix4_values_set(&m4, + 1, 3, 2, 0, + 3, 1, 4, 0, + 2, 4, 1, 0, + 0, 0, 0, 1); + + eina_matrix4_matrix3_to(&m3, &m4); + eina_matrix3_matrix4_to(&m4b, &m3); + + fail_if(memcmp(&m4, &m4b, sizeof (Eina_Matrix4)) != 0); + + eina_shutdown(); +} +END_TEST + +void +eina_test_matrix(TCase *tc) +{ + tcase_add_test(tc, eina_matrix4); + tcase_add_test(tc, eina_matrix4_2_3); +} -- 2.7.4