diff --git a/src/lib/eina/eina_matrix.c b/src/lib/eina/eina_matrix.c index 4263322ae1..a7bdddfc8e 100644 --- a/src/lib/eina/eina_matrix.c +++ b/src/lib/eina/eina_matrix.c @@ -939,113 +939,348 @@ eina_matrix4_transpose(Eina_Matrix4 *out, const Eina_Matrix4 *in) } EAPI void -eina_matrix4_multiply(Eina_Matrix4 *out, - const Eina_Matrix4 *a, const Eina_Matrix4 *b) +eina_matrix4_multiply_copy(Eina_Matrix4 *out, + const Eina_Matrix4 *mat_a, const Eina_Matrix4 *mat_b) { - // FIXME: start implementing SSE multiplication here - MATRIX_XX(out) = - MATRIX_XX(a) * MATRIX_XX(b) - + MATRIX_XY(a) * MATRIX_YX(b) - + MATRIX_XZ(a) * MATRIX_ZX(b) - + MATRIX_XW(a) * MATRIX_WX(b); + if (out != mat_a && out != mat_b) + { + eina_matrix4_multiply(out, mat_a, mat_b); + } + else + { + Eina_Matrix4 result; - MATRIX_XY(out) = - MATRIX_XX(a) * MATRIX_XY(b) - + MATRIX_XY(a) * MATRIX_YY(b) - + MATRIX_XZ(a) * MATRIX_ZY(b) - + MATRIX_XW(a) * MATRIX_WY(b); - - MATRIX_XZ(out) = - MATRIX_XX(a) * MATRIX_XZ(b) - + MATRIX_XY(a) * MATRIX_YZ(b) - + MATRIX_XZ(a) * MATRIX_ZZ(b) - + MATRIX_XW(a) * MATRIX_WZ(b); - - MATRIX_XW(out) = - MATRIX_XX(a) * MATRIX_XW(b) - + MATRIX_XY(a) * MATRIX_YW(b) - + MATRIX_XZ(a) * MATRIX_ZW(b) - + MATRIX_XW(a) * MATRIX_WW(b); - - MATRIX_YX(out) = - MATRIX_YX(a) * MATRIX_XX(b) - + MATRIX_YY(a) * MATRIX_YX(b) - + MATRIX_YZ(a) * MATRIX_ZX(b) - + MATRIX_YW(a) * MATRIX_WX(b); - - MATRIX_YY(out) = - MATRIX_YX(a) * MATRIX_XY(b) - + MATRIX_YY(a) * MATRIX_YY(b) - + MATRIX_YZ(a) * MATRIX_ZY(b) - + MATRIX_YW(a) * MATRIX_WY(b); - - MATRIX_YZ(out) = - MATRIX_YX(a) * MATRIX_XZ(b) - + MATRIX_YY(a) * MATRIX_YZ(b) - + MATRIX_YZ(a) * MATRIX_ZZ(b) - + MATRIX_YW(a) * MATRIX_WZ(b); - - MATRIX_YW(out) = - MATRIX_YX(a) * MATRIX_XW(b) - + MATRIX_YY(a) * MATRIX_YW(b) - + MATRIX_YZ(a) * MATRIX_ZW(b) - + MATRIX_YW(a) * MATRIX_WW(b); - - MATRIX_ZX(out) = - MATRIX_ZX(a) * MATRIX_XX(b) - + MATRIX_ZY(a) * MATRIX_YX(b) - + MATRIX_ZZ(a) * MATRIX_ZX(b) - + MATRIX_ZW(a) * MATRIX_WX(b); - - MATRIX_ZY(out) = - MATRIX_ZX(a) * MATRIX_XY(b) - + MATRIX_ZY(a) * MATRIX_YY(b) - + MATRIX_ZZ(a) * MATRIX_ZY(b) - + MATRIX_ZW(a) * MATRIX_WY(b); - - MATRIX_ZZ(out) = - MATRIX_ZX(a) * MATRIX_XZ(b) - + MATRIX_ZY(a) * MATRIX_YZ(b) - + MATRIX_ZZ(a) * MATRIX_ZZ(b) - + MATRIX_ZW(a) * MATRIX_WZ(b); - - MATRIX_ZW(out) = - MATRIX_ZX(a) * MATRIX_XW(b) - + MATRIX_ZY(a) * MATRIX_YW(b) - + MATRIX_ZZ(a) * MATRIX_ZW(b) - + MATRIX_ZW(a) * MATRIX_WW(b); - - MATRIX_WX(out) = - MATRIX_WX(a) * MATRIX_XX(b) - + MATRIX_WY(a) * MATRIX_YX(b) - + MATRIX_WZ(a) * MATRIX_ZX(b) - + MATRIX_WW(a) * MATRIX_WX(b); - - MATRIX_WY(out) = - MATRIX_WX(a) * MATRIX_XY(b) - + MATRIX_WY(a) * MATRIX_YY(b) - + MATRIX_WZ(a) * MATRIX_ZY(b) - + MATRIX_WW(a) * MATRIX_WY(b); - - MATRIX_WZ(out) = - MATRIX_WX(a) * MATRIX_XZ(b) - + MATRIX_WY(a) * MATRIX_YZ(b) - + MATRIX_WZ(a) * MATRIX_ZZ(b) - + MATRIX_WW(a) * MATRIX_WZ(b); - - MATRIX_WW(out) = - MATRIX_WX(a) * MATRIX_XW(b) - + MATRIX_WY(a) * MATRIX_YW(b) - + MATRIX_WZ(a) * MATRIX_ZW(b) - + MATRIX_WW(a) * MATRIX_WW(b); + eina_matrix4_multiply(&result, mat_a, mat_b); + eina_matrix4_copy(out, &result); + } } EAPI void eina_matrix4_identity(Eina_Matrix4 *out) { memset(out, 0, sizeof (Eina_Matrix4)); - MATRIX_XX(out) = 1; - MATRIX_YY(out) = 1; - MATRIX_ZZ(out) = 1; - MATRIX_WW(out) = 1; + + MATRIX_XX(out) = 1.0; + MATRIX_YY(out) = 1.0; + MATRIX_ZZ(out) = 1.0; + MATRIX_WW(out) = 1.0; +} + +EAPI Eina_Matrix_Type +eina_matrix2_type_get(const Eina_Matrix2 *m) +{ + if ((MATRIX_XX(m) == 1) && (MATRIX_XY(m) == 0) && + (MATRIX_YX(m) == 0) && (MATRIX_YY(m) == 1)) + return EINA_MATRIX_TYPE_IDENTITY; + return EINA_MATRIX_TYPE_AFFINE; +} + +EAPI void +eina_matrix4_array_set(Eina_Matrix4 *m, const double *v) +{ + memcpy(&MATRIX_XX(m), v, sizeof(double) * 16); +} + +EAPI void +eina_matrix4_copy(Eina_Matrix4 *dst, const Eina_Matrix4 *src) +{ + memcpy(dst, src, sizeof(Eina_Matrix4)); +} + +EAPI void +eina_matrix4_multiply(Eina_Matrix4 *out, const Eina_Matrix4 *mat_a, + const Eina_Matrix4 *mat_b) +{ + if (eina_matrix4_type_get(mat_a) & EINA_MATRIX_TYPE_IDENTITY) + { + eina_matrix4_copy(out, mat_b); + return; + } + + if (eina_matrix4_type_get(mat_b) & EINA_MATRIX_TYPE_IDENTITY) + { + eina_matrix4_copy(out, mat_a); + return; + } + + MATRIX_XX(out) = MATRIX_XX(mat_a) * MATRIX_XX(mat_b) + MATRIX_YX(mat_a) * MATRIX_XY(mat_b) + + MATRIX_ZX(mat_a) * MATRIX_XZ(mat_b) + mat_a->wx * MATRIX_XW(mat_b); + MATRIX_YX(out) = MATRIX_XX(mat_a) * MATRIX_YX(mat_b) + MATRIX_YX(mat_a) * MATRIX_YY(mat_b) + + MATRIX_ZX(mat_a) * MATRIX_YZ(mat_b) + mat_a->wx * MATRIX_YW(mat_b); + MATRIX_ZX(out) = MATRIX_XX(mat_a) * MATRIX_ZX(mat_b) + MATRIX_YX(mat_a) * MATRIX_ZY(mat_b) + + MATRIX_ZX(mat_a) * MATRIX_ZZ(mat_b) + mat_a->wx * MATRIX_ZW(mat_b); + MATRIX_WX(out) = MATRIX_XX(mat_a) * MATRIX_WX(mat_b) + MATRIX_YX(mat_a) * MATRIX_WY(mat_b) + + MATRIX_ZX(mat_a) * MATRIX_WZ(mat_b) + mat_a->wx * MATRIX_WW(mat_b); + + MATRIX_XY(out) = MATRIX_XY(mat_a) * MATRIX_XX(mat_b) + MATRIX_YY(mat_a) * MATRIX_XY(mat_b) + + MATRIX_ZY(mat_a) * MATRIX_XZ(mat_b) + mat_a->wy * MATRIX_XW(mat_b); + MATRIX_YY(out) = MATRIX_XY(mat_a) * MATRIX_YX(mat_b) + MATRIX_YY(mat_a) * MATRIX_YY(mat_b) + + MATRIX_ZY(mat_a) * MATRIX_YZ(mat_b) + mat_a->wy * MATRIX_YW(mat_b); + MATRIX_ZY(out) = MATRIX_XY(mat_a) * MATRIX_ZX(mat_b) + MATRIX_YY(mat_a) * MATRIX_ZY(mat_b) + + MATRIX_ZY(mat_a) * MATRIX_ZZ(mat_b) + mat_a->wy * MATRIX_ZW(mat_b); + MATRIX_WY(out) = MATRIX_XY(mat_a) * MATRIX_WX(mat_b) + MATRIX_YY(mat_a) * MATRIX_WY(mat_b) + + MATRIX_ZY(mat_a) * MATRIX_WZ(mat_b) + mat_a->wy * MATRIX_WW(mat_b); + + MATRIX_XZ(out) = MATRIX_XZ(mat_a) * MATRIX_XX(mat_b) + MATRIX_YZ(mat_a) * MATRIX_XY(mat_b) + + MATRIX_ZZ(mat_a) * MATRIX_XZ(mat_b) + mat_a->wz * MATRIX_XW(mat_b); + MATRIX_YZ(out) = MATRIX_XZ(mat_a) * MATRIX_YX(mat_b) + MATRIX_YZ(mat_a) * MATRIX_YY(mat_b) + + MATRIX_ZZ(mat_a) * MATRIX_YZ(mat_b) + mat_a->wz * MATRIX_YW(mat_b); + MATRIX_ZZ(out) = MATRIX_XZ(mat_a) * MATRIX_ZX(mat_b) + MATRIX_YZ(mat_a) * MATRIX_ZY(mat_b) + + MATRIX_ZZ(mat_a) * MATRIX_ZZ(mat_b) + mat_a->wz * MATRIX_ZW(mat_b); + MATRIX_WZ(out) = MATRIX_XZ(mat_a) * MATRIX_WX(mat_b) + MATRIX_YZ(mat_a) * MATRIX_WY(mat_b) + + MATRIX_ZZ(mat_a) * MATRIX_WZ(mat_b) + mat_a->wz * MATRIX_WW(mat_b); + + MATRIX_XW(out) = MATRIX_XW(mat_a) * MATRIX_XX(mat_b) + MATRIX_YW(mat_a) * MATRIX_XY(mat_b) + + MATRIX_ZW(mat_a) * MATRIX_XZ(mat_b) + mat_a->ww * MATRIX_XW(mat_b); + MATRIX_YW(out) = MATRIX_XW(mat_a) * MATRIX_YX(mat_b) + MATRIX_YW(mat_a) * MATRIX_YY(mat_b) + + MATRIX_ZW(mat_a) * MATRIX_YZ(mat_b) + mat_a->ww * MATRIX_YW(mat_b); + MATRIX_ZW(out) = MATRIX_XW(mat_a) * MATRIX_ZX(mat_b) + MATRIX_YW(mat_a) * MATRIX_ZY(mat_b) + + MATRIX_ZW(mat_a) * MATRIX_ZZ(mat_b) + mat_a->ww * MATRIX_ZW(mat_b); + MATRIX_WW(out) = MATRIX_XW(mat_a) * MATRIX_WX(mat_b) + MATRIX_YW(mat_a) * MATRIX_WY(mat_b) + + MATRIX_ZW(mat_a) * MATRIX_WZ(mat_b) + mat_a->ww * MATRIX_WW(mat_b); +} + +EAPI void +eina_matrix4_ortho_set(Eina_Matrix4 *m, + double left, double right, double bottom, double top, + double dnear, double dfar) +{ + double w = right - left; + double h = top - bottom; + double depth = dnear - dfar; + + MATRIX_XX(m) = 2.0f / w; + MATRIX_XY(m) = 0.0f; + MATRIX_XZ(m) = 0.0f; + MATRIX_XW(m) = 0.0f; + + MATRIX_YX(m) = 0.0f; + MATRIX_YY(m) = 2.0f / h; + MATRIX_YZ(m) = 0.0f; + MATRIX_YW(m) = 0.0f; + + MATRIX_ZX(m) = 0.0f; + MATRIX_ZY(m) = 0.0f; + MATRIX_ZZ(m) = 2.0f / depth; + MATRIX_ZW(m) = 0.0f; + + MATRIX_WX(m) = -(right + left) / w; + MATRIX_WY(m) = -(top + bottom) / h; + MATRIX_WZ(m) = (dfar + dnear) / depth; + MATRIX_WW(m) = 1.0f; +} + +EAPI void +eina_matrix3_array_set(Eina_Matrix3 *m, const double *v) +{ + memcpy(&MATRIX_XX(m), v, sizeof(double) * 9); +} + +EAPI void +eina_matrix3_copy(Eina_Matrix3 *dst, const Eina_Matrix3 *src) +{ + memcpy(dst, src, sizeof(Eina_Matrix3)); +} + +EAPI void +eina_matrix3_multiply(Eina_Matrix3 *out, const Eina_Matrix3 *mat_a, const Eina_Matrix3 *mat_b) +{ + if (eina_matrix3_type_get(mat_a) & EINA_MATRIX_TYPE_IDENTITY) + { + eina_matrix3_copy(out, mat_b); + return; + } + + if (eina_matrix3_type_get(mat_b) & EINA_MATRIX_TYPE_IDENTITY) + { + eina_matrix3_copy(out, mat_a); + return; + } + + MATRIX_XX(out) = MATRIX_XX(mat_b) * MATRIX_XX(mat_a) + MATRIX_YX(mat_b) * MATRIX_XY(mat_a) + MATRIX_ZX(mat_b) * MATRIX_XZ(mat_a); + MATRIX_XY(out) = MATRIX_XY(mat_b) * MATRIX_XX(mat_a) + MATRIX_YY(mat_b) * MATRIX_XY(mat_a) + MATRIX_ZY(mat_b) * MATRIX_XZ(mat_a); + MATRIX_XZ(out) = MATRIX_XZ(mat_b) * MATRIX_XX(mat_a) + MATRIX_YZ(mat_b) * MATRIX_XY(mat_a) + MATRIX_ZZ(mat_b) * MATRIX_XZ(mat_a); + + MATRIX_YX(out) = MATRIX_XX(mat_b) * MATRIX_YX(mat_a) + MATRIX_YX(mat_b) * MATRIX_YY(mat_a) + MATRIX_ZX(mat_b) * MATRIX_YZ(mat_a); + MATRIX_YY(out) = MATRIX_XY(mat_b) * MATRIX_YX(mat_a) + MATRIX_YY(mat_b) * MATRIX_YY(mat_a) + MATRIX_ZY(mat_b) * MATRIX_YZ(mat_a); + MATRIX_YZ(out) = MATRIX_XZ(mat_b) * MATRIX_YX(mat_a) + MATRIX_YZ(mat_b) * MATRIX_YY(mat_a) + MATRIX_ZZ(mat_b) * MATRIX_YZ(mat_a); + + MATRIX_ZX(out) = MATRIX_XX(mat_b) * MATRIX_ZX(mat_a) + MATRIX_YX(mat_b) * MATRIX_ZY(mat_a) + MATRIX_ZX(mat_b) * MATRIX_ZZ(mat_a); + MATRIX_ZY(out) = MATRIX_XY(mat_b) * MATRIX_ZX(mat_a) + MATRIX_YY(mat_b) * MATRIX_ZY(mat_a) + MATRIX_ZY(mat_b) * MATRIX_ZZ(mat_a); + MATRIX_ZZ(out) = MATRIX_XZ(mat_b) * MATRIX_ZX(mat_a) + MATRIX_YZ(mat_b) * MATRIX_ZY(mat_a) + MATRIX_ZZ(mat_b) * MATRIX_ZZ(mat_a); +} + +EAPI void +eina_matrix3_multiply_copy(Eina_Matrix3 *out, const Eina_Matrix3 *mat_a, const Eina_Matrix3 *mat_b) +{ + if (out != mat_a && out != mat_b) + { + eina_matrix3_multiply(out, mat_a, mat_b); + } + else + { + Eina_Matrix3 tmp; + + eina_matrix3_multiply(&tmp, mat_a, mat_b); + eina_matrix3_copy(out, &tmp); + } +} + +EAPI void +eina_matrix3_position_transform_set(Eina_Matrix3 *out, const double p_x, + const double p_y) +{ + eina_matrix3_identity(out); + MATRIX_XZ(out) = p_x; + MATRIX_YZ(out) = p_y; +} + +EAPI void +eina_matrix3_scale_transform_set(Eina_Matrix3 *out, double s_x, double s_y) +{ + eina_matrix3_identity(out); + MATRIX_XX(out) = s_x; + MATRIX_YY(out) = s_y; +} + +EAPI void +eina_normal_matrix3_get(Eina_Matrix3 *out, const Eina_Matrix4 *m) +{ + /* Normal matrix is a transposed matrix of inversed modelview. + * And we need only upper-left 3x3 terms to work with. */ + + double det; + + double a = MATRIX_XX(m); + double b = MATRIX_YX(m); + double c = MATRIX_ZX(m); + + double d = MATRIX_XY(m); + double e = MATRIX_YY(m); + double f = MATRIX_ZY(m); + + double g = MATRIX_XZ(m); + double h = MATRIX_YZ(m); + double i = MATRIX_ZZ(m); + + det = a * e * i + b * f * g + c * d * h - g * e * c - h * f * a - i * d * b; + det = 1.0 / det; + + MATRIX_XX(out) = (e * i - f * h) * det; + MATRIX_XY(out) = (h * c - i * b) * det; + MATRIX_XZ(out) = (b * f - c * e) * det; + + MATRIX_YX(out) = (g * f - d * i) * det; + MATRIX_YY(out) = (a * i - g * c) * det; + MATRIX_YZ(out) = (d * c - a * f) * det; + + MATRIX_ZX(out) = (d * h - g * e) * det; + MATRIX_ZY(out) = (g * b - a * h) * det; + MATRIX_ZZ(out) = (a * e - d * b) * det; +} + +EAPI void +eina_matrix2_values_set(Eina_Matrix2 *m, + double xx, double xy, + double yx, double yy) +{ + MATRIX_XX(m) = xx; + MATRIX_XY(m) = xy; + MATRIX_YX(m) = yx; + MATRIX_YY(m) = yy; +} + +EAPI void +eina_matrix2_values_get(const Eina_Matrix2 *m, + double *xx, double *xy, + double *yx, double *yy) +{ + if (xx) *xx = MATRIX_XX(m); + if (xy) *xy = MATRIX_XY(m); + if (yx) *yx = MATRIX_YX(m); + if (yy) *yy = MATRIX_YY(m); +} + +EAPI void +eina_matrix2_inverse(Eina_Matrix2 *out, const Eina_Matrix2 *mat) +{ + double det; + + if (eina_matrix2_type_get(mat) & EINA_MATRIX_TYPE_IDENTITY) + { + eina_matrix2_copy(out, mat); + return; + } + + det = MATRIX_XX(mat) * MATRIX_YY(mat) - MATRIX_YX(mat) * MATRIX_XY(mat); + + if (det == 0.0) + return; + + det = 1.0 / det; + + MATRIX_XX(out) = MATRIX_YY(mat) * det; + MATRIX_XY(out) = -MATRIX_XY(mat) * det; + MATRIX_YX(out) = -MATRIX_YX(mat) * det; + MATRIX_YY(out) = MATRIX_XX(mat) * det; +} + +EAPI void +eina_matrix2_identity(Eina_Matrix2 *m) +{ + MATRIX_XX(m) = 1.0; + MATRIX_XY(m) = 0.0; + + MATRIX_YX(m) = 0.0; + MATRIX_YY(m) = 1.0; +} + +EAPI void +eina_matrix2_array_set(Eina_Matrix2 *m, const double *v) +{ + memcpy(&MATRIX_XX(m), v, sizeof(double) * 4); +} + +EAPI void +eina_matrix2_copy(Eina_Matrix2 *dst, const Eina_Matrix2 *src) +{ + memcpy(dst, src, sizeof(Eina_Matrix2)); +} + +EAPI void +eina_matrix2_multiply(Eina_Matrix2 *out, const Eina_Matrix2 *mat_a, const Eina_Matrix2 *mat_b) +{ + if (eina_matrix2_type_get(mat_a) & EINA_MATRIX_TYPE_IDENTITY) + { + eina_matrix2_copy(out, mat_b); + return; + } + + if (eina_matrix2_type_get(mat_b) & EINA_MATRIX_TYPE_IDENTITY) + { + eina_matrix2_copy(out, mat_a); + return; + } + + MATRIX_XX(out) = MATRIX_XX(mat_a) * MATRIX_XX(mat_b) + MATRIX_YX(mat_a) * MATRIX_XY(mat_b); + MATRIX_YX(out) = MATRIX_XX(mat_a) * MATRIX_YX(mat_b) + MATRIX_YX(mat_a) * MATRIX_YY(mat_b); + + MATRIX_XY(out) = MATRIX_XY(mat_a) * MATRIX_XX(mat_b) + MATRIX_YY(mat_a) * MATRIX_XY(mat_b); + MATRIX_YY(out) = MATRIX_XY(mat_a) * MATRIX_YX(mat_b) + MATRIX_YY(mat_a) * MATRIX_YY(mat_b); +} + +EAPI void +eina_matrix2_multiply_copy(Eina_Matrix2 *out, const Eina_Matrix2 *mat_a, const Eina_Matrix2 *mat_b) +{ + if (out != mat_a && out != mat_b) + { + eina_matrix2_multiply(out, mat_a, mat_b); + } + else + { + Eina_Matrix2 tmp; + + eina_matrix2_multiply(&tmp, mat_a, mat_b); + eina_matrix2_copy(out, &tmp); + } } diff --git a/src/lib/eina/eina_matrix.h b/src/lib/eina/eina_matrix.h index 0558c98d49..af3b024d89 100644 --- a/src/lib/eina/eina_matrix.h +++ b/src/lib/eina/eina_matrix.h @@ -428,6 +428,23 @@ struct _Eina_Matrix4 double ww; /**< ww in w' = (x * wx) + (y * wy) + (z * wz) + ww */ }; +/** + * @} + * @defgroup Eina_Matrix2 Matrices in floating point + * @ingroup Eina_Basic + * @brief Matrix definition and operations + * @{ + */ + +typedef struct _Eina_Matrix2 Eina_Matrix2; +struct _Eina_Matrix2 +{ + double xx; + double xy; + + double yx; + double yy; +}; /** * @brief Return the type of the given floating point matrix. * @@ -597,11 +614,265 @@ EAPI void eina_matrix4_identity(Eina_Matrix4 *out); * @param a The first member of the multiplication * @param b The second member of the multiplication * + * @since 1.17 + */ +EAPI void eina_matrix4_multiply_copy(Eina_Matrix4 *out, + const Eina_Matrix4 *mat_a, const Eina_Matrix4 *mat_b); + +/** + * @brief Set array to matrix. + * + * @param m The rsult matrix + * @param v The the array[16] for set + * + * Set to matrix first 16 elements from array + * + * @since 1.17 + */ +EAPI void eina_matrix4_array_set(Eina_Matrix4 *m, const double *v); + +/** + * @brief Copy matrix. + * + * @param dst The matrix copy + * @param src The matrix for copy. + * + * @since 1.17 + */ +EAPI void eina_matrix4_copy(Eina_Matrix4 *dst, const Eina_Matrix4 *src); + +/** + * @brief Multiply two matrix with check + * + * @param out The resulting matrix + * @param a The first member of the multiplication + * @param b The second member of the multiplication + * + * @since 1.17 + */ +EAPI void eina_matrix4_multiply(Eina_Matrix4 *out, const Eina_Matrix4 *mat_a, + const Eina_Matrix4 *mat_b); + +/** + * @brief Set orthogonality matrix + * + * @param m The resulting matrix + * @param right The right value + * @param left The left value + * @param bottom The bottom value + * @param top The top value + * @param dneat The dnear value + * @param dfar The dfar value + * + * @since 1.17 + */ +EAPI void eina_matrix4_ortho_set(Eina_Matrix4 *m, + double left, double right, double bottom, double top, + double dnear, double dfar); + +/** + * @brief Set array to matrix. + * + * @param m The rsult matrix + * @param v The the array[9] for set + * + * Set to matrix first 9 elements from array + * + * @since 1.17 + */ +EAPI void eina_matrix3_array_set(Eina_Matrix3 *m, const double *v); + +/** + * @brief Copy matrix. + * + * @param dst The matrix copy + * @param src The matrix for copy. + * * @since 1.16 */ -EAPI void eina_matrix4_multiply(Eina_Matrix4 *out, - const Eina_Matrix4 *a, const Eina_Matrix4 *b); +EAPI void eina_matrix3_copy(Eina_Matrix3 *dst, const Eina_Matrix3 *src); +/* + * @brief Multiply two matrix + * + * @param out The resulting matrix + * @param a The first member of the multiplication + * @param b The second member of the multiplication + * + * @since 1.17 + */ +EAPI void eina_matrix3_multiply(Eina_Matrix3 *out, const Eina_Matrix3 *mat_a, + const Eina_Matrix3 *mat_b); + +/** + * @brief Multiply two matrix + * + * @param out The resulting matrix + * @param a The first member of the multiplication + * @param b The second member of the multiplication + * + * @since 1.17 + */ +EAPI void eina_matrix3_multiply_copy(Eina_Matrix3 *out, const Eina_Matrix3 *mat_a, + const Eina_Matrix3 *mat_b); + +/** + * @brief Transform scale of matrix + * + * @param out The resulting matrix + * @param s_x The scale value for x + * @param s_y The scale value for y + * + * @since 1.17 + */ +EAPI void eina_matrix3_scale_transform_set(Eina_Matrix3 *out, double s_x, double s_y); + +/** + * @brief Transform position of matrix + * + * @param out The resulting matrix + * @param p_x The position value for x + * @param p_y The position value for y + * + * @since 1.17 + */ +EAPI void eina_matrix3_position_transform_set(Eina_Matrix3 *out, const double p_x, + const double p_y); + +/** + * @brief Set normal of the given matrix. + * + * @param out The result mtrix of normal + * @param m The matrix + * + * @since 1.17 + */ +EAPI void eina_normal3_matrix_get(Eina_Matrix3 *out, 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 yx The fourth coefficient value. + * @param yy The fifth coefficient value. + * + * This function sets the values of the coefficients of the matrix + * @p m. No check is done on @p m. + * + * @see eina_matrix2_values_get() + * + * @since 1.17 + */ +EAPI void eina_matrix2_values_set(Eina_Matrix2 *m, double xx, double xy, + double yx, double yy); + +/** + * @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 yx The fourth coefficient value. + * @param yy The fifth coefficient value. + * + * This function gets the values of the coefficients of the matrix + * @p m. No check is done on @p m. + * + * @see eina_matrix2_values_set() + * + * @since 1.17 + */ +EAPI void eina_matrix2_values_get(const Eina_Matrix2 *m, double *xx, double *xy, + double *yx, double *yy); + +/** + * @brief Compute the inverse with check of the given matrix. + * + * @param m The matrix to inverse. + * @param m2 The inverse matrix. + * + * This function inverse the matrix @p m and stores the result in + * @p m2. No check is done on @p m or @p m2. If @p m can not be + * invertible, then @p m2 is set to the identity matrix. + * + * @since 1.17 + */ +EAPI void eina_matrix2_inverse(Eina_Matrix2 *out, const Eina_Matrix2 *mat); + +/** + * @brief Set the given floating point matrix to the identity matrix. + * + * @param m The floating point matrix to set + * + * This function sets @p m to the identity matrix. No check is done on + * @p m. + * + * @since 1.17 + */ +EAPI void eina_matrix2_identity(Eina_Matrix2 *m); + +/** + * @brief Set array to matrix. + * + * @param m The rsult matrix + * @param v The the array[4] for set + * + * Set to matrix first 4 elements from array + * + * @since 1.17 + */ +EAPI void eina_matrix2_array_set(Eina_Matrix2 *m, const double *v); + +/** + * @brief Copy matrix. + * + * @param dst The matrix copy + * @param src The matrix for copy. + * + * @since 1.17 + */ +EAPI void eina_matrix2_copy(Eina_Matrix2 *dst, const Eina_Matrix2 *src); + +/** + * @brief Multiply two matrix + * + * @param out The resulting matrix + * @param a The first member of the multiplication + * @param b The second member of the multiplication + * + * @since 1.17 + */ +EAPI void eina_matrix2_multiply(Eina_Matrix2 *out, const Eina_Matrix2 *mat_a, + const Eina_Matrix2 *mat_b); + +/** + * @brief Multiply two matrix with check + * + * @param out The resulting matrix + * @param a The first member of the multiplication + * @param b The second member of the multiplication + * + * @since 1.17 + */ +EAPI void eina_matrix2_multiply_copy(Eina_Matrix2 *out, const Eina_Matrix2 *mat_a, + const Eina_Matrix2 *mat_b); + +/** + * @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.17 + */ +EAPI Eina_Matrix_Type eina_matrix2_type_get(const Eina_Matrix2 *m); /** * @} diff --git a/src/lib/evas/canvas/evas_canvas3d_camera.c b/src/lib/evas/canvas/evas_canvas3d_camera.c index 802bccf57f..9f874e2d4a 100644 --- a/src/lib/evas/canvas/evas_canvas3d_camera.c +++ b/src/lib/evas/canvas/evas_canvas3d_camera.c @@ -109,7 +109,7 @@ EOLIAN static void _evas_canvas3d_camera_projection_matrix_set(Eo *obj, Evas_Canvas3D_Camera_Data *pd, const Evas_Real *matrix) { - evas_mat4_array_set(&pd->projection, matrix); + eina_matrix4_array_set(&pd->projection, matrix); eo_do(obj, evas_canvas3d_object_change(EVAS_CANVAS3D_STATE_CAMERA_PROJECTION, NULL)); } @@ -118,7 +118,7 @@ _evas_canvas3d_camera_projection_matrix_get(const Eo *obj EINA_UNUSED, Evas_Canvas3D_Camera_Data *pd, Evas_Real *matrix) { - memcpy(matrix, &pd->projection.m[0], sizeof(Evas_Real) * 16); + memcpy(matrix, &pd->projection.xx, sizeof(Evas_Real) * 16); } EOLIAN static void @@ -152,15 +152,15 @@ _evas_canvas3d_camera_projection_ortho_set(Eo *obj, Evas_Canvas3D_Camera_Data *p Evas_Real bottom, Evas_Real top, Evas_Real dnear, Evas_Real dfar) { - evas_mat4_ortho_set(&pd->projection, left, right, bottom, top, dnear, dfar); + eina_matrix4_ortho_set(&pd->projection, left, right, bottom, top, dnear, dfar); eo_do(obj, evas_canvas3d_object_change(EVAS_CANVAS3D_STATE_CAMERA_PROJECTION, NULL)); } EOLIAN static Eina_Bool _evas_canvas3d_camera_node_visible_get(Eo *obj EINA_UNUSED, Evas_Canvas3D_Camera_Data *pd, Evas_Canvas3D_Node *camera_node, Evas_Canvas3D_Node *node, Evas_Canvas3D_Frustum_Mode key) { - Evas_Mat4 matrix_vp; - Evas_Vec4 planes[6]; + Eina_Matrix4 matrix_vp; + Eina_Quaternion planes[6]; Evas_Canvas3D_Node_Data *pd_node = eo_data_scope_get(node, EVAS_CANVAS3D_NODE_CLASS); Evas_Canvas3D_Node_Data *pd_camera = eo_data_scope_get(camera_node, EVAS_CANVAS3D_NODE_CLASS); Evas_Vec3 central_point; @@ -178,7 +178,7 @@ _evas_canvas3d_camera_node_visible_get(Eo *obj EINA_UNUSED, Evas_Canvas3D_Camera } /*get need matrix like multiply projection matrix with view matrix*/ - evas_mat4_multiply(&matrix_vp, &pd->projection, &pd_camera->data.camera.matrix_world_to_eye); + eina_matrix4_multiply(&matrix_vp, &pd->projection, &pd_camera->data.camera.matrix_world_to_eye); evas_frustum_calculate(planes, &matrix_vp); diff --git a/src/lib/evas/canvas/evas_canvas3d_light.c b/src/lib/evas/canvas/evas_canvas3d_light.c index d207d9b62f..2d7facd175 100644 --- a/src/lib/evas/canvas/evas_canvas3d_light.c +++ b/src/lib/evas/canvas/evas_canvas3d_light.c @@ -259,7 +259,7 @@ EOLIAN static void _evas_canvas3d_light_projection_matrix_set(Eo *obj, Evas_Canvas3D_Light_Data *pd, const Evas_Real *matrix) { - evas_mat4_array_set(&pd->projection, matrix); + eina_matrix4_array_set(&pd->projection, matrix); eo_do(obj, evas_canvas3d_object_change(EVAS_CANVAS3D_STATE_LIGHT_PROJECTION, NULL)); } @@ -268,7 +268,7 @@ _evas_canvas3d_light_projection_matrix_get(const Eo *obj EINA_UNUSED, Evas_Canvas3D_Light_Data *pd, Evas_Real *matrix) { - memcpy(matrix, &pd->projection.m[0], sizeof(Evas_Real) * 16); + memcpy(matrix, &pd->projection.xx, sizeof(Evas_Real) * 16); } EOLIAN static void @@ -302,7 +302,7 @@ _evas_canvas3d_light_projection_ortho_set(Eo *obj, Evas_Canvas3D_Light_Data *pd, Evas_Real bottom, Evas_Real top, Evas_Real dnear, Evas_Real dfar) { - evas_mat4_ortho_set(&pd->projection, left, right, bottom, top, dnear, dfar); + eina_matrix4_ortho_set(&pd->projection, left, right, bottom, top, dnear, dfar); eo_do(obj, evas_canvas3d_object_change(EVAS_CANVAS3D_STATE_LIGHT_PROJECTION, NULL)); } diff --git a/src/lib/evas/canvas/evas_canvas3d_scene.c b/src/lib/evas/canvas/evas_canvas3d_scene.c index 13dd68af22..6bc4487bd7 100644 --- a/src/lib/evas/canvas/evas_canvas3d_scene.c +++ b/src/lib/evas/canvas/evas_canvas3d_scene.c @@ -554,7 +554,7 @@ _node_pick(Evas_Canvas3D_Node *node, void *data) { Evas_Ray3 ray; Evas_Canvas3D_Pick_Data *pick = (Evas_Canvas3D_Pick_Data *)data; - Evas_Mat4 mvp; + Eina_Matrix4 mvp; Evas_Canvas3D_Node_Data *pd_node = eo_data_scope_get(node, EVAS_CANVAS3D_NODE_CLASS); if (! evas_box3_ray3_intersect(&pd_node->aabb, &pick->ray_world)) @@ -569,7 +569,7 @@ _node_pick(Evas_Canvas3D_Node *node, void *data) void *ptr; /* Transform ray into local coordinate space. */ - evas_mat4_multiply(&mvp, &pick->matrix_vp, &pd_node->data.mesh.matrix_local_to_world); + eina_matrix4_multiply(&mvp, &pick->matrix_vp, &pd_node->data.mesh.matrix_local_to_world); evas_ray3_init(&ray, pick->x, pick->y, &mvp); itr = eina_hash_iterator_data_new(pd_node->data.mesh.node_meshes); @@ -690,7 +690,7 @@ _evas_canvas3d_scene_pick(const Eo *obj, Evas_Canvas3D_Scene_Data *pd, Evas_Real eo_do(obj, evas_canvas3d_object_update()); pd_camera_node = eo_data_scope_get(pd->camera_node, EVAS_CANVAS3D_NODE_CLASS); pd_camera = eo_data_scope_get(pd_camera_node->data.camera.camera, EVAS_CANVAS3D_CAMERA_CLASS); - evas_mat4_multiply(&data.matrix_vp, + eina_matrix4_multiply(&data.matrix_vp, &pd_camera->projection, &pd_camera_node->data.camera.matrix_world_to_eye); @@ -736,7 +736,7 @@ _evas_canvas3d_scene_exist(const Eo *obj, Evas_Canvas3D_Scene_Data *pd, Evas_Rea eo_do(obj, evas_canvas3d_object_update()); pd_camera_node = eo_data_scope_get(pd->camera_node, EVAS_CANVAS3D_NODE_CLASS); pd_camera = eo_data_scope_get(pd_camera_node->data.camera.camera, EVAS_CANVAS3D_CAMERA_CLASS); - evas_mat4_multiply(&data.matrix_vp, + eina_matrix4_multiply(&data.matrix_vp, &pd_camera->projection, &pd_camera_node->data.camera.matrix_world_to_eye); diff --git a/src/lib/evas/include/evas_3d_utils.h b/src/lib/evas/include/evas_3d_utils.h index dfa0b3946b..23d338d448 100644 --- a/src/lib/evas/include/evas_3d_utils.h +++ b/src/lib/evas/include/evas_3d_utils.h @@ -16,9 +16,6 @@ typedef struct _Evas_Color Evas_Color; typedef struct _Evas_Vec2 Evas_Vec2; typedef struct _Evas_Vec3 Evas_Vec3; typedef struct _Evas_Vec4 Evas_Vec4; -typedef struct _Evas_Mat2 Evas_Mat2; -typedef struct _Evas_Mat3 Evas_Mat3; -typedef struct _Evas_Mat4 Evas_Mat4; typedef struct _Evas_Box2 Evas_Box2; typedef struct _Evas_Box3 Evas_Box3; typedef struct _Evas_Line3 Evas_Line3; @@ -55,24 +52,6 @@ struct _Evas_Vec4 Evas_Real w; }; -struct _Evas_Mat2 -{ - Evas_Real m[4]; - int flags; -}; - -struct _Evas_Mat3 -{ - Evas_Real m[9]; - int flags; -}; - -struct _Evas_Mat4 -{ - Evas_Real m[16]; - int flags; -}; - struct _Evas_Box2 { Evas_Vec2 p0; @@ -204,34 +183,34 @@ evas_vec2_normalize(Evas_Vec2 *out, const Evas_Vec2 *v) } static inline void -evas_vec2_transform(Evas_Vec2 *out, const Evas_Mat2 *m, const Evas_Vec2 *v) +evas_vec2_transform(Evas_Vec2 *out, const Eina_Matrix2 *m, const Evas_Vec2 *v) { Evas_Vec2 tmp; - tmp.x = (m->m[0] * v->x) + (m->m[2] * v->y); - tmp.y = (m->m[1] * v->x) + (m->m[3] * v->y); + tmp.x = (m->xx * v->x) + (m->yx * v->y); + tmp.y = (m->xy * v->x) + (m->yy * v->y); evas_vec2_copy(out, &tmp); } static inline void -evas_vec2_homogeneous_position_transform(Evas_Vec2 *out, const Evas_Mat3 *m, const Evas_Vec2 *v) +evas_vec2_homogeneous_position_transform(Evas_Vec2 *out, const Eina_Matrix3 *m, const Evas_Vec2 *v) { Evas_Vec2 tmp; - tmp.x = (m->m[0] * v->x) + (m->m[3] * v->y) + m->m[6]; - tmp.y = (m->m[1] * v->x) + (m->m[4] * v->y) + m->m[7]; + tmp.x = (m->xx * v->x) + (m->yx * v->y) + m->zx; + tmp.y = (m->xy * v->x) + (m->yy * v->y) + m->zy; - evas_vec2_scale(out, &tmp, 1.0 / ((m->m[2] * v->x) + (m->m[5] * v->y) + m->m[8])); + evas_vec2_scale(out, &tmp, 1.0 / ((m->xz * v->x) + (m->yz * v->y) + m->zz)); } static inline void -evas_vec2_homogeneous_direction_transform(Evas_Vec2 *out, const Evas_Mat3 *m, const Evas_Vec2 *v) +evas_vec2_homogeneous_direction_transform(Evas_Vec2 *out, const Eina_Matrix3 *m, const Evas_Vec2 *v) { Evas_Vec2 tmp; - tmp.x = (m->m[0] * v->x) + (m->m[3] * v->y); - tmp.y = (m->m[1] * v->x) + (m->m[4] * v->y); + tmp.x = (m->xx * v->x) + (m->yx * v->y); + tmp.y = (m->xy * v->x) + (m->yy * v->y); evas_vec2_copy(out, &tmp); } @@ -366,56 +345,56 @@ evas_vec3_normalize(Evas_Vec3 *out, const Evas_Vec3 *v) } static inline void -evas_vec3_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Mat3 *m) +evas_vec3_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Eina_Matrix3 *m) { Evas_Vec3 tmp; - if (m->flags & EVAS_MATRIX_IS_IDENTITY) + if (eina_matrix3_type_get(m) & EINA_MATRIX_TYPE_IDENTITY) { evas_vec3_copy(out, v); return; } - tmp.x = (m->m[0] * v->x) + (m->m[3] * v->y) + (m->m[6] * v->z); - tmp.y = (m->m[1] * v->x) + (m->m[4] * v->y) + (m->m[7] * v->z); - tmp.z = (m->m[2] * v->x) + (m->m[5] * v->y) + (m->m[8] * v->z); + tmp.x = (m->xx * v->x) + (m->yx * v->y) + (m->zx * v->z); + tmp.y = (m->xy * v->x) + (m->yy * v->y) + (m->zy * v->z); + tmp.z = (m->xz * v->x) + (m->yz * v->y) + (m->zz * v->z); evas_vec3_copy(out, &tmp); } static inline void -evas_vec3_homogeneous_position_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Mat4 *m) +evas_vec3_homogeneous_position_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Eina_Matrix4 *m) { Evas_Vec3 tmp; - if (m->flags & EVAS_MATRIX_IS_IDENTITY) + if (eina_matrix4_type_get(m) & EINA_MATRIX_TYPE_IDENTITY) { evas_vec3_copy(out, v); return; } - tmp.x = (m->m[0] * v->x) + (m->m[4] * v->y) + (m->m[8] * v->z) + m->m[12]; - tmp.y = (m->m[1] * v->x) + (m->m[5] * v->y) + (m->m[9] * v->z) + m->m[13]; - tmp.z = (m->m[2] * v->x) + (m->m[6] * v->y) + (m->m[10] * v->z) + m->m[14]; + tmp.x = (m->xx * v->x) + (m->zw * v->y) + (m->zx * v->z) + m->wx; + tmp.y = (m->xy * v->x) + (m->yx * v->y) + (m->zy * v->z) + m->wy; + tmp.z = (m->xz * v->x) + (m->yz * v->y) + (m->zz * v->z) + m->wz; evas_vec3_scale(out, &tmp, - 1.0 / ((m->m[3] * v->x) + (m->m[7] * v->y) + (m->m[11] * v->z) + m->m[15])); + 1.0 / ((m->xw * v->x) + (m->yw * v->y) + (m->zw * v->z) + m->ww)); } static inline void -evas_vec3_homogeneous_direction_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Mat4 *m) +evas_vec3_homogeneous_direction_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Eina_Matrix4 *m) { Evas_Vec3 tmp; - if (m->flags & EVAS_MATRIX_IS_IDENTITY) + if (eina_matrix4_type_get(m) & EINA_MATRIX_TYPE_IDENTITY) { evas_vec3_copy(out, v); return; } - tmp.x = (m->m[0] * v->x) + (m->m[4] * v->y) + (m->m[8] * v->z); - tmp.y = (m->m[1] * v->x) + (m->m[5] * v->y) + (m->m[9] * v->z); - tmp.z = (m->m[2] * v->x) + (m->m[6] * v->y) + (m->m[10] * v->z); + tmp.x = (m->xx * v->x) + (m->zw * v->y) + (m->zx * v->z); + tmp.y = (m->xy * v->x) + (m->yx * v->y) + (m->zy * v->z); + tmp.z = (m->xz * v->x) + (m->yz * v->y) + (m->zz * v->z); evas_vec3_copy(out, &tmp); } @@ -581,20 +560,20 @@ evas_vec4_normalize(Evas_Vec4 *out, const Evas_Vec4 *v) } static inline void -evas_vec4_transform(Evas_Vec4 *out, const Evas_Vec4 *v, const Evas_Mat4 *m) +evas_vec4_transform(Evas_Vec4 *out, const Evas_Vec4 *v, const Eina_Matrix4 *m) { Evas_Vec4 tmp; - if (m->flags & EVAS_MATRIX_IS_IDENTITY) + if (eina_matrix4_type_get(m) & EINA_MATRIX_TYPE_IDENTITY) { evas_vec4_copy(out, v); return; } - tmp.x = (m->m[0] * v->x) + (m->m[4] * v->y) + (m->m[ 8] * v->z) + (m->m[12] * v->w); - tmp.y = (m->m[1] * v->x) + (m->m[5] * v->y) + (m->m[ 9] * v->z) + (m->m[13] * v->w); - tmp.z = (m->m[2] * v->x) + (m->m[6] * v->y) + (m->m[10] * v->z) + (m->m[14] * v->w); - tmp.w = (m->m[3] * v->x) + (m->m[7] * v->y) + (m->m[11] * v->z) + (m->m[15] * v->w); + tmp.x = (m->xx * v->x) + (m->yx * v->y) + (m->zx * v->z) + (m->wx * v->w); + tmp.y = (m->xy * v->x) + (m->yy * v->y) + (m->zy * v->z) + (m->wy * v->w); + tmp.z = (m->xz * v->x) + (m->yz * v->y) + (m->zz * v->z) + (m->wz * v->w); + tmp.w = (m->xw * v->x) + (m->yw * v->y) + (m->zw * v->z) + (m->ww * v->w); evas_vec4_copy(out, &tmp); } @@ -745,108 +724,8 @@ evas_vec4_homogeneous_direction_set(Evas_Vec4 *out, const Evas_Vec3 *v) out->w = 0.0; } -/* 4x4 matrix */ static inline void -evas_mat4_identity_set(Evas_Mat4 *m) -{ - m->m[0] = 1.0; - m->m[1] = 0.0; - m->m[2] = 0.0; - m->m[3] = 0.0; - - m->m[4] = 0.0; - m->m[5] = 1.0; - m->m[6] = 0.0; - m->m[7] = 0.0; - - m->m[8] = 0.0; - m->m[9] = 0.0; - m->m[10] = 1.0; - m->m[11] = 0.0; - - m->m[12] = 0.0; - m->m[13] = 0.0; - m->m[14] = 0.0; - m->m[15] = 1.0; - - m->flags = EVAS_MATRIX_IS_IDENTITY; -} - -static inline void -evas_mat4_array_set(Evas_Mat4 *m, const Evas_Real *v) -{ - memcpy(&m->m[0], v, sizeof(Evas_Real) * 16); - m->flags = 0; -} - -static inline void -evas_mat4_copy(Evas_Mat4 *dst, const Evas_Mat4 *src) -{ - memcpy(dst, src, sizeof(Evas_Mat4)); -} - -static inline void -evas_mat4_nocheck_multiply(Evas_Mat4 *out, const Evas_Mat4 *mat_a, - const Evas_Mat4 *mat_b) -{ - Evas_Real *d = out->m; - const Evas_Real *a = mat_a->m; - const Evas_Real *b = mat_b->m; - - if (mat_a->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat4_copy(out, mat_b); - return; - } - - if (mat_b->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat4_copy(out, mat_a); - return; - } - - d[ 0] = a[ 0] * b[ 0] + a[ 4] * b[ 1] + a[ 8] * b[ 2] + a[12] * b [3]; - d[ 4] = a[ 0] * b[ 4] + a[ 4] * b[ 5] + a[ 8] * b[ 6] + a[12] * b [7]; - d[ 8] = a[ 0] * b[ 8] + a[ 4] * b[ 9] + a[ 8] * b[10] + a[12] * b[11]; - d[12] = a[ 0] * b[12] + a[ 4] * b[13] + a[ 8] * b[14] + a[12] * b[15]; - - d[ 1] = a[ 1] * b[ 0] + a[ 5] * b[ 1] + a[ 9] * b[ 2] + a[13] * b [3]; - d[ 5] = a[ 1] * b[ 4] + a[ 5] * b[ 5] + a[ 9] * b[ 6] + a[13] * b [7]; - d[ 9] = a[ 1] * b[ 8] + a[ 5] * b[ 9] + a[ 9] * b[10] + a[13] * b[11]; - d[13] = a[ 1] * b[12] + a[ 5] * b[13] + a[ 9] * b[14] + a[13] * b[15]; - - d[ 2] = a[ 2] * b[ 0] + a[ 6] * b[ 1] + a[10] * b[ 2] + a[14] * b [3]; - d[ 6] = a[ 2] * b[ 4] + a[ 6] * b[ 5] + a[10] * b[ 6] + a[14] * b [7]; - d[10] = a[ 2] * b[ 8] + a[ 6] * b[ 9] + a[10] * b[10] + a[14] * b[11]; - d[14] = a[ 2] * b[12] + a[ 6] * b[13] + a[10] * b[14] + a[14] * b[15]; - - d[ 3] = a[ 3] * b[ 0] + a[ 7] * b[ 1] + a[11] * b[ 2] + a[15] * b [3]; - d[ 7] = a[ 3] * b[ 4] + a[ 7] * b[ 5] + a[11] * b[ 6] + a[15] * b [7]; - d[11] = a[ 3] * b[ 8] + a[ 7] * b[ 9] + a[11] * b[10] + a[15] * b[11]; - d[15] = a[ 3] * b[12] + a[ 7] * b[13] + a[11] * b[14] + a[15] * b[15]; - - out->flags = 0; -} - -static inline void -evas_mat4_multiply(Evas_Mat4 *out, const Evas_Mat4 *mat_a, - const Evas_Mat4 *mat_b) -{ - if (out != mat_a && out != mat_b) - { - evas_mat4_nocheck_multiply(out, mat_a, mat_b); - } - else - { - Evas_Mat4 result; - - evas_mat4_nocheck_multiply(&result, mat_a, mat_b); - evas_mat4_copy(out, &result); - } -} - -static inline void -evas_mat4_look_at_set(Evas_Mat4 *m, +evas_mat4_look_at_set(Eina_Matrix4 *m, const Evas_Vec3 *pos, const Evas_Vec3 *center, const Evas_Vec3 *up) { Evas_Vec3 x, y, z; @@ -860,31 +739,29 @@ evas_mat4_look_at_set(Evas_Mat4 *m, evas_vec3_cross_product(&y, &z, &x); evas_vec3_normalize(&y, &y); - m->m[ 0] = x.x; - m->m[ 1] = y.x; - m->m[ 2] = z.x; - m->m[ 3] = 0.0; + m->xx = x.x; + m->xy = y.x; + m->xz = z.x; + m->xw = 0.0; - m->m[ 4] = x.y; - m->m[ 5] = y.y; - m->m[ 6] = z.y; - m->m[ 7] = 0.0; + m->yx = x.y; + m->yy = y.y; + m->yz = z.y; + m->yw = 0.0; - m->m[ 8] = x.z; - m->m[ 9] = y.z; - m->m[10] = z.z; - m->m[11] = 0.0; + m->zx = x.z; + m->zy = y.z; + m->zz = z.z; + m->zw = 0.0; - m->m[12] = -evas_vec3_dot_product(&x, pos); - m->m[13] = -evas_vec3_dot_product(&y, pos); - m->m[14] = -evas_vec3_dot_product(&z, pos); - m->m[15] = 1.0; - - m->flags = 0; + m->wx = -evas_vec3_dot_product(&x, pos); + m->wy = -evas_vec3_dot_product(&y, pos); + m->wz = -evas_vec3_dot_product(&z, pos); + m->ww = 1.0; } static inline void -evas_mat4_frustum_set(Evas_Mat4 *m, +evas_mat4_frustum_set(Eina_Matrix4 *m, Evas_Real left, Evas_Real right, Evas_Real bottom, Evas_Real top, Evas_Real dnear, Evas_Real dfar) { @@ -893,534 +770,25 @@ evas_mat4_frustum_set(Evas_Mat4 *m, Evas_Real depth = dnear - dfar; Evas_Real near_2 = 2.0f * dnear; - m->m[ 0] = near_2 / w; - m->m[ 1] = 0.0f; - m->m[ 2] = 0.0f; - m->m[ 3] = 0.0f; - - m->m[ 4] = 0.0f; - m->m[ 5] = near_2 / h; - m->m[ 6] = 0.0f; - m->m[ 7] = 0.0f; - - m->m[ 8] = (right + left) / w; - m->m[ 9] = (top + bottom) / h; - m->m[10] = (dfar + dnear) / depth; - m->m[11] = -1.0f; - - m->m[12] = 0.0f; - m->m[13] = 0.0f; - m->m[14] = near_2 * dfar / depth; - m->m[15] = 0.0f; - - m->flags = 0; -} - -static inline void -evas_mat4_ortho_set(Evas_Mat4 *m, - Evas_Real left, Evas_Real right, Evas_Real bottom, Evas_Real top, - Evas_Real dnear, Evas_Real dfar) -{ - Evas_Real w = right - left; - Evas_Real h = top - bottom; - Evas_Real depth = dnear - dfar; - - m->m[ 0] = 2.0f / w; - m->m[ 1] = 0.0f; - m->m[ 2] = 0.0f; - m->m[ 3] = 0.0f; - - m->m[ 4] = 0.0f; - m->m[ 5] = 2.0f / h; - m->m[ 6] = 0.0f; - m->m[ 7] = 0.0f; - - m->m[ 8] = 0.0f; - m->m[ 9] = 0.0f; - m->m[10] = 2.0f / depth; - m->m[11] = 0.0f; - - m->m[12] = -(right + left) / w; - m->m[13] = -(top + bottom) / h; - m->m[14] = (dfar + dnear) / depth; - m->m[15] = 1.0f; - - m->flags = 0; -} - -static inline void -evas_mat4_nocheck_inverse(Evas_Mat4 *out, const Evas_Mat4 *mat) -{ - Evas_Real *d = out->m; - const Evas_Real *m = mat->m; - Evas_Real det; - - if (mat->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat4_copy(out, mat); - return; - } - - d[ 0] = m[ 5] * m[10] * m[15] - - m[ 5] * m[11] * m[14] - - m[ 9] * m[ 6] * m[15] + - m[ 9] * m[ 7] * m[14] + - m[13] * m[ 6] * m[11] - - m[13] * m[ 7] * m[10]; - - d[ 4] = -m[ 4] * m[10] * m[15] + - m[ 4] * m[11] * m[14] + - m[ 8] * m[ 6] * m[15] - - m[ 8] * m[ 7] * m[14] - - m[12] * m[ 6] * m[11] + - m[12] * m[ 7] * m[10]; - - d[ 8] = m[ 4] * m[ 9] * m[15] - - m[ 4] * m[11] * m[13] - - m[ 8] * m[ 5] * m[15] + - m[ 8] * m[ 7] * m[13] + - m[12] * m[ 5] * m[11] - - m[12] * m[ 7] * m[ 9]; - - d[12] = -m[ 4] * m[ 9] * m[14] + - m[ 4] * m[10] * m[13] + - m[ 8] * m[ 5] * m[14] - - m[ 8] * m[ 6] * m[13] - - m[12] * m[ 5] * m[10] + - m[12] * m[ 6] * m[ 9]; - - d[ 1] = -m[ 1] * m[10] * m[15] + - m[ 1] * m[11] * m[14] + - m[ 9] * m[ 2] * m[15] - - m[ 9] * m[ 3] * m[14] - - m[13] * m[ 2] * m[11] + - m[13] * m[ 3] * m[10]; - - d[ 5] = m[ 0] * m[10] * m[15] - - m[ 0] * m[11] * m[14] - - m[ 8] * m[ 2] * m[15] + - m[ 8] * m[ 3] * m[14] + - m[12] * m[ 2] * m[11] - - m[12] * m[ 3] * m[10]; - - d[ 9] = -m[ 0] * m[ 9] * m[15] + - m[ 0] * m[11] * m[13] + - m[ 8] * m[ 1] * m[15] - - m[ 8] * m[ 3] * m[13] - - m[12] * m[ 1] * m[11] + - m[12] * m[ 3] * m[ 9]; - - d[13] = m[ 0] * m[ 9] * m[14] - - m[ 0] * m[10] * m[13] - - m[ 8] * m[ 1] * m[14] + - m[ 8] * m[ 2] * m[13] + - m[12] * m[ 1] * m[10] - - m[12] * m[ 2] * m[ 9]; - - d[ 2] = m[ 1] * m[ 6] * m[15] - - m[ 1] * m[ 7] * m[14] - - m[ 5] * m[ 2] * m[15] + - m[ 5] * m[ 3] * m[14] + - m[13] * m[ 2] * m[ 7] - - m[13] * m[ 3] * m[ 6]; - - d[ 6] = -m[ 0] * m[ 6] * m[15] + - m[ 0] * m[ 7] * m[14] + - m[ 4] * m[ 2] * m[15] - - m[ 4] * m[ 3] * m[14] - - m[12] * m[ 2] * m[ 7] + - m[12] * m[ 3] * m[ 6]; - - d[10] = m[ 0] * m[ 5] * m[15] - - m[ 0] * m[ 7] * m[13] - - m[ 4] * m[ 1] * m[15] + - m[ 4] * m[ 3] * m[13] + - m[12] * m[ 1] * m[ 7] - - m[12] * m[ 3] * m[ 5]; - - d[14] = -m[ 0] * m[ 5] * m[14] + - m[ 0] * m[ 6] * m[13] + - m[ 4] * m[ 1] * m[14] - - m[ 4] * m[ 2] * m[13] - - m[12] * m[ 1] * m[ 6] + - m[12] * m[ 2] * m[ 5]; - - d[ 3] = -m[ 1] * m[ 6] * m[11] + - m[ 1] * m[ 7] * m[10] + - m[ 5] * m[ 2] * m[11] - - m[ 5] * m[ 3] * m[10] - - m[ 9] * m[ 2] * m[ 7] + - m[ 9] * m[ 3] * m[ 6]; - - d[ 7] = m[ 0] * m[ 6] * m[11] - - m[ 0] * m[ 7] * m[10] - - m[ 4] * m[ 2] * m[11] + - m[ 4] * m[ 3] * m[10] + - m[ 8] * m[ 2] * m[ 7] - - m[ 8] * m[ 3] * m[ 6]; - - d[11] = -m[ 0] * m[ 5] * m[11] + - m[ 0] * m[ 7] * m[ 9] + - m[ 4] * m[ 1] * m[11] - - m[ 4] * m[ 3] * m[ 9] - - m[ 8] * m[ 1] * m[ 7] + - m[ 8] * m[ 3] * m[ 5]; - - d[15] = m[ 0] * m[ 5] * m[10] - - m[ 0] * m[ 6] * m[ 9] - - m[ 4] * m[ 1] * m[10] + - m[ 4] * m[ 2] * m[ 9] + - m[ 8] * m[ 1] * m[ 6] - - m[ 8] * m[ 2] * m[ 5]; - - det = m[0] * d[0] + m[1] * d[4] + m[2] * d[8] + m[3] * d[12]; - - if (det == 0.0) return; - - det = 1.0 / det; - - d[ 0] *= det; - d[ 1] *= det; - d[ 2] *= det; - d[ 3] *= det; - d[ 4] *= det; - d[ 5] *= det; - d[ 6] *= det; - d[ 7] *= det; - d[ 8] *= det; - d[ 9] *= det; - d[10] *= det; - d[11] *= det; - d[12] *= det; - d[13] *= det; - d[14] *= det; - d[15] *= det; - - out->flags = 0; -} - -static inline void -evas_mat4_inverse(Evas_Mat4 *out, const Evas_Mat4 *mat) -{ - if (out != mat) - { - evas_mat4_nocheck_inverse(out, mat); - } - else - { - Evas_Mat4 tmp; - - evas_mat4_nocheck_inverse(&tmp, mat); - evas_mat4_copy(out, &tmp); - } -} - -static inline void -evas_normal_matrix_get(Evas_Mat3 *out, const Evas_Mat4 *m) -{ - /* Normal matrix is a transposed matirx of inversed modelview. - * And we need only upper-left 3x3 terms to work with. */ - - Evas_Real det; - Evas_Real a = m->m[0]; - Evas_Real b = m->m[4]; - Evas_Real c = m->m[8]; - Evas_Real d = m->m[1]; - Evas_Real e = m->m[5]; - Evas_Real f = m->m[9]; - Evas_Real g = m->m[2]; - Evas_Real h = m->m[6]; - Evas_Real i = m->m[10]; - - det = a * e * i + b * f * g + c * d * h - g * e * c - h * f * a - i * d * b; - det = 1.0 / det; - - out->m[0] = (e * i - f * h) * det; - out->m[1] = (h * c - i * b) * det; - out->m[2] = (b * f - c * e) * det; - out->m[3] = (g * f - d * i) * det; - out->m[4] = (a * i - g * c) * det; - out->m[5] = (d * c - a * f) * det; - out->m[6] = (d * h - g * e) * det; - out->m[7] = (g * b - a * h) * det; - out->m[8] = (a * e - d * b) * det; - - out->flags = 0; -} - -/* 3x3 matrix */ -static inline void -evas_mat3_identity_set(Evas_Mat3 *m) -{ - m->m[0] = 1.0; - m->m[1] = 0.0; - m->m[2] = 0.0; - m->m[3] = 0.0; - m->m[4] = 1.0; - m->m[5] = 0.0; - m->m[6] = 0.0; - m->m[7] = 0.0; - m->m[8] = 1.0; - - m->flags = EVAS_MATRIX_IS_IDENTITY; -} - -static inline void -evas_mat3_array_set(Evas_Mat3 *m, const Evas_Real *v) -{ - memcpy(&m->m[0], v, sizeof(Evas_Real) * 9); - m->flags = 0; -} - -static inline void -evas_mat3_copy(Evas_Mat3 *dst, const Evas_Mat3 *src) -{ - memcpy(dst, src, sizeof(Evas_Mat3)); -} - -static inline void -evas_mat3_nocheck_multiply(Evas_Mat3 *out, const Evas_Mat3 *mat_a, const Evas_Mat3 *mat_b) -{ - Evas_Real *d = out->m; - const Evas_Real *a = mat_a->m; - const Evas_Real *b = mat_b->m; - - if (mat_a->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat3_copy(out, mat_b); - return; - } - - if (mat_b->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat3_copy(out, mat_a); - return; - } - - d[0] = a[0] * b[0] + a[3] * b[1] + a[6] * b[2]; - d[3] = a[0] * b[3] + a[3] * b[4] + a[6] * b[5]; - d[6] = a[0] * b[6] + a[3] * b[7] + a[6] * b[8]; - - d[1] = a[1] * b[0] + a[4] * b[1] + a[7] * b[2]; - d[4] = a[1] * b[3] + a[4] * b[4] + a[7] * b[5]; - d[7] = a[1] * b[6] + a[4] * b[7] + a[7] * b[8]; - - d[2] = a[2] * b[0] + a[5] * b[1] + a[8] * b[2]; - d[5] = a[2] * b[3] + a[5] * b[4] + a[8] * b[5]; - d[8] = a[2] * b[6] + a[5] * b[7] + a[8] * b[8]; - - out->flags = 0; -} - -static inline void -evas_mat3_multiply(Evas_Mat3 *out, const Evas_Mat3 *mat_a, const Evas_Mat3 *mat_b) -{ - if (out != mat_a && out != mat_b) - { - evas_mat3_nocheck_multiply(out, mat_a, mat_b); - } - else - { - Evas_Mat3 tmp; - - evas_mat3_nocheck_multiply(&tmp, mat_a, mat_b); - evas_mat3_copy(out, &tmp); - } -} - -static inline void -evas_mat3_nocheck_inverse(Evas_Mat3 *out, const Evas_Mat3 *mat) -{ - Evas_Real *d = &out->m[0]; - const Evas_Real *m = &mat->m[0]; - Evas_Real det; - - if (mat->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat3_copy(out, mat); - return; - } - - d[0] = m[4] * m[8] - m[7] * m[5]; - d[1] = m[7] * m[2] - m[1] * m[8]; - d[2] = m[1] * m[5] - m[4] * m[2]; - d[3] = m[6] * m[5] - m[3] * m[8]; - d[4] = m[0] * m[8] - m[6] * m[2]; - d[5] = m[3] * m[2] - m[0] * m[5]; - d[6] = m[3] * m[7] - m[6] * m[4]; - d[7] = m[6] * m[1] - m[0] * m[7]; - d[8] = m[0] * m[4] - m[3] * m[1]; - - det = m[0] * d[0] + m[1] * d[3] + m[2] * d[6]; - - if (det == 0.0) - return; - - det = 1.0 / det; - - d[0] *= det; - d[1] *= det; - d[2] *= det; - d[3] *= det; - d[4] *= det; - d[5] *= det; - d[6] *= det; - d[7] *= det; - d[8] *= det; - - out->flags = 0; -} - -static inline void -evas_mat3_invserse(Evas_Mat3 *out, const Evas_Mat3 *mat) -{ - if (out != mat) - { - evas_mat3_nocheck_inverse(out, mat); - } - else - { - Evas_Mat3 tmp; - - evas_mat3_nocheck_inverse(&tmp, mat); - evas_mat3_copy(out, &tmp); - } -} - -static inline void -evas_mat3_set_position_transform(Evas_Mat3 *out, const Evas_Real p_x, - const Evas_Real p_y) -{ - evas_mat3_identity_set(out); - out->m[2] = p_x; - out->m[5] = p_y; - if ((fabs(p_x) > FLT_EPSILON) || - (fabs(p_y) > FLT_EPSILON)) - out->flags = 0; -} - -static inline void -evas_mat3_set_scale_transform(Evas_Mat3 *out, Evas_Real s_x, Evas_Real s_y) -{ - evas_mat3_identity_set(out); - out->m[0] = s_x; - out->m[4] = s_y; - if ((fabs(s_x - 1.0) > FLT_EPSILON) || - (fabs(s_y - 1.0) > FLT_EPSILON)) - out->flags = 0; -} - -/* 2x2 matrix */ -static inline void -evas_mat2_identity_set(Evas_Mat2 *m) -{ - m->m[0] = 1.0; - m->m[1] = 0.0; - m->m[2] = 0.0; - m->m[3] = 1.0; - - m->flags = EVAS_MATRIX_IS_IDENTITY; -} - -static inline void -evas_mat2_array_set(Evas_Mat2 *m, const Evas_Real *v) -{ - memcpy(&m->m[0], v, sizeof(Evas_Real) * 4); - m->flags = 0; -} - -static inline void -evas_mat2_copy(Evas_Mat2 *dst, const Evas_Mat2 *src) -{ - memcpy(dst, src, sizeof(Evas_Mat2)); -} - -static inline void -evas_mat2_nocheck_multiply(Evas_Mat2 *out, const Evas_Mat2 *mat_a, const Evas_Mat2 *mat_b) -{ - Evas_Real *d = &out->m[0]; - const Evas_Real *a = &mat_a->m[0]; - const Evas_Real *b = &mat_b->m[0]; - - if (mat_a->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat2_copy(out, mat_b); - return; - } - - if (mat_b->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat2_copy(out, mat_a); - return; - } - - d[0] = a[0] * b[0] + a[2] * b[1]; - d[2] = a[0] * b[2] + a[2] * b[3]; - - d[1] = a[1] * b[0] + a[3] * b[1]; - d[3] = a[1] * b[2] + a[3] * b[3]; - - out->flags = 0; -} - -static inline void -evas_mat2_multiply(Evas_Mat2 *out, const Evas_Mat2 *mat_a, const Evas_Mat2 *mat_b) -{ - if (out != mat_a && out != mat_b) - { - evas_mat2_nocheck_multiply(out, mat_a, mat_b); - } - else - { - Evas_Mat2 tmp; - - evas_mat2_nocheck_multiply(&tmp, mat_a, mat_b); - evas_mat2_copy(out, &tmp); - } -} - -static inline void -evas_mat2_nocheck_inverse(Evas_Mat2 *out, const Evas_Mat2 *mat) -{ - Evas_Real *d = &out->m[0]; - const Evas_Real *m = &mat->m[0]; - Evas_Real det; - - if (mat->flags & EVAS_MATRIX_IS_IDENTITY) - { - evas_mat2_copy(out, mat); - return; - } - - det = m[0] * m[3] - m[2] * m[1]; - - if (det == 0.0) - return; - - det = 1.0 / det; - - d[0] = m[3] * det; - d[1] = -m[1] * det; - d[2] = -m[2] * det; - d[3] = m[0] * det; - - out->flags = 0; -} - -static inline void -evas_mat2_invserse(Evas_Mat2 *out, const Evas_Mat2 *mat) -{ - if (out != mat) - { - evas_mat2_nocheck_inverse(out, mat); - } - else - { - Evas_Mat2 tmp; - - evas_mat2_nocheck_inverse(&tmp, mat); - evas_mat2_copy(out, &tmp); - } + m->xx = near_2 / w; + m->xy = 0.0f; + m->xz = 0.0f; + m->xw = 0.0f; + + m->yx = 0.0f; + m->yy = near_2 / h; + m->yz = 0.0f; + m->yw = 0.0f; + + m->zx = (right + left) / w; + m->zy = (top + bottom) / h; + m->zz = (dfar + dnear) / depth; + m->zw = -1.0f; + + m->wx = 0.0f; + m->wy = 0.0f; + m->wz = near_2 * dfar / depth; + m->ww = 0.0f; } static inline void @@ -1467,13 +835,13 @@ evas_box3_union(Evas_Box3 *out, const Evas_Box3 *a, const Evas_Box3 *b) } static inline void -evas_box3_transform(Evas_Box3 *out EINA_UNUSED, const Evas_Box3 *box EINA_UNUSED, const Evas_Mat4 *mat EINA_UNUSED) +evas_box3_transform(Evas_Box3 *out EINA_UNUSED, const Evas_Box3 *box EINA_UNUSED, const Eina_Matrix4 *mat EINA_UNUSED) { /* TODO: */ } static inline void -evas_mat4_position_get(const Evas_Mat4 *matrix, Evas_Vec4 *position) +evas_mat4_position_get(const Eina_Matrix4 *matrix, Evas_Vec4 *position) { Evas_Vec4 pos; @@ -1486,7 +854,7 @@ evas_mat4_position_get(const Evas_Mat4 *matrix, Evas_Vec4 *position) } static inline void -evas_mat4_direction_get(const Evas_Mat4 *matrix, Evas_Vec3 *direction) +evas_mat4_direction_get(const Eina_Matrix4 *matrix, Evas_Vec3 *direction) { /* TODO: Check correctness. */ @@ -1540,7 +908,7 @@ evas_vec4_quaternion_inverse(Evas_Vec4 *out, const Evas_Vec4 *q) } static inline void -evas_vec4_quaternion_rotation_matrix_get(const Evas_Vec4 *q, Evas_Mat3 *mat) +evas_vec4_quaternion_rotation_matrix_get(const Evas_Vec4 *q, Eina_Matrix3 *mat) { Evas_Real x, y, z; Evas_Real xx, xy, xz; @@ -1565,57 +933,55 @@ evas_vec4_quaternion_rotation_matrix_get(const Evas_Vec4 *q, Evas_Mat3 *mat) wy = q->w * y; wz = q->w * z; - mat->m[0] = 1.0 - yy - zz; - mat->m[1] = xy + wz; - mat->m[2] = xz - wy; - mat->m[3] = xy - wz; - mat->m[4] = 1.0 - xx - zz; - mat->m[5] = yz + wx; - mat->m[6] = xz + wy; - mat->m[7] = yz - wx; - mat->m[8] = 1.0 - xx - yy; + mat->xx = 1.0 - yy - zz; + mat->xy = xy + wz; + mat->xz = xz - wy; + mat->yx = xy - wz; + mat->yy = 1.0 - xx - zz; + mat->yz = yz + wx; + mat->zx = xz + wy; + mat->zy = yz - wx; + mat->zz = 1.0 - xx - yy; } static inline void -evas_mat4_build(Evas_Mat4 *out, +evas_mat4_build(Eina_Matrix4 *out, const Evas_Vec3 *position, const Evas_Vec4 *orientation, const Evas_Vec3 *scale) { - Evas_Mat3 rot; + Eina_Matrix3 rot; evas_vec4_quaternion_rotation_matrix_get(orientation, &rot); - out->m[ 0] = scale->x * rot.m[0]; - out->m[ 1] = scale->x * rot.m[1]; - out->m[ 2] = scale->x * rot.m[2]; - out->m[ 3] = 0.0; + out->xx = scale->x * rot.xx; + out->xy = scale->y * rot.xy; + out->xz = scale->z * rot.xz; + out->xw = 0.0; - out->m[ 4] = scale->y * rot.m[3]; - out->m[ 5] = scale->y * rot.m[4]; - out->m[ 6] = scale->y * rot.m[5]; - out->m[ 7] = 0.0; + out->yx = scale->x * rot.yx; + out->yy = scale->y * rot.yy; + out->yz = scale->z * rot.yz; + out->yw = 0.0; - out->m[ 8] = scale->z * rot.m[6]; - out->m[ 9] = scale->z * rot.m[7]; - out->m[10] = scale->z * rot.m[8]; - out->m[11] = 0.0; + out->zx = scale->x * rot.zx; + out->zy = scale->y * rot.zy; + out->zz = scale->z * rot.zz; + out->zw = 0.0; - out->m[12] = position->x; - out->m[13] = position->y; - out->m[14] = position->z; - out->m[15] = 1.0; - - out->flags = 0; + out->wx = position->x; + out->wy = position->y; + out->wz = position->z; + out->ww = 1.0; } static inline void -evas_mat4_inverse_build(Evas_Mat4 *out, const Evas_Vec3 *position, +evas_mat4_inverse_build(Eina_Matrix4 *out, const Evas_Vec3 *position, const Evas_Vec4 *orientation, const Evas_Vec3 *scale) { Evas_Vec4 inv_rotation; Evas_Vec3 inv_scale; Evas_Vec3 inv_translate; - Evas_Mat3 rot; + Eina_Matrix3 rot; /* Inverse scale. */ evas_vec3_set(&inv_scale, 1.0 / scale->x, 1.0 / scale->y, 1.0 / scale->z); @@ -1631,27 +997,25 @@ evas_mat4_inverse_build(Evas_Mat4 *out, const Evas_Vec3 *position, /* Get 3x3 rotation matrix. */ evas_vec4_quaternion_rotation_matrix_get(&inv_rotation, &rot); - out->m[ 0] = inv_scale.x * rot.m[0]; - out->m[ 1] = inv_scale.y * rot.m[1]; - out->m[ 2] = inv_scale.z * rot.m[2]; - out->m[ 3] = 0.0; + out->xx = inv_scale.x * rot.xx; + out->xy = inv_scale.y * rot.xy; + out->xz = inv_scale.z * rot.xz; + out->xw = 0.0; - out->m[ 4] = inv_scale.x * rot.m[3]; - out->m[ 5] = inv_scale.y * rot.m[4]; - out->m[ 6] = inv_scale.z * rot.m[5]; - out->m[ 7] = 0.0; + out->yx = inv_scale.x * rot.yx; + out->yy = inv_scale.y * rot.yy; + out->yz = inv_scale.z * rot.yz; + out->yw = 0.0; - out->m[ 8] = inv_scale.x * rot.m[6]; - out->m[ 9] = inv_scale.y * rot.m[7]; - out->m[10] = inv_scale.z * rot.m[8]; - out->m[11] = 0.0; + out->zx = inv_scale.x * rot.zx; + out->zy = inv_scale.y * rot.zy; + out->zz = inv_scale.z * rot.zz; + out->zw = 0.0; - out->m[12] = inv_translate.x; - out->m[13] = inv_translate.y; - out->m[14] = inv_translate.z; - out->m[15] = 1.0; - - out->flags = 0; + out->wx = inv_translate.x; + out->wy = inv_translate.y; + out->wz = inv_translate.z; + out->ww = 1.0; } static inline void @@ -1673,16 +1037,16 @@ evas_color_blend(Evas_Color *dst, const Evas_Color *c0, const Evas_Color *c1, Ev } static inline void -evas_ray3_init(Evas_Ray3 *ray, Evas_Real x, Evas_Real y, const Evas_Mat4 *mvp) +evas_ray3_init(Evas_Ray3 *ray, Evas_Real x, Evas_Real y, const Eina_Matrix4 *mvp) { - Evas_Mat4 mat; + Eina_Matrix4 mat; Evas_Vec4 dnear, dfar; memset(&mat, 0, sizeof (mat)); /* Get the matrix which transforms from normalized device coordinate to modeling coodrinate. */ - evas_mat4_inverse(&mat, mvp); + eina_matrix4_inverse(&mat, mvp); /* Transform near point. */ dnear.x = x; @@ -2123,38 +1487,35 @@ evas_is_box_in_frustum(Evas_Box3 *box, Evas_Vec4 *planes) } static inline void -evas_frustum_calculate(Evas_Vec4 *planes, Evas_Mat4 *matrix_vp) +evas_frustum_calculate(Evas_Vec4 *planes, Eina_Matrix4 *matrix_vp) { int i; - evas_vec4_set(&planes[0], matrix_vp->m[3] - matrix_vp->m[0], - matrix_vp->m[7] - matrix_vp->m[4], - matrix_vp->m[11] - matrix_vp->m[8], - matrix_vp->m[15] - matrix_vp->m[12]); - evas_vec4_set(&planes[1], matrix_vp->m[3] + matrix_vp->m[0], - matrix_vp->m[7] + matrix_vp->m[4], - matrix_vp->m[11] + matrix_vp->m[8], - matrix_vp->m[15] + matrix_vp->m[12]); + evas_vec4_set(&planes[0], matrix_vp->xw - matrix_vp->xx, + matrix_vp->yw - matrix_vp->yx, + matrix_vp->zw - matrix_vp->zx, + matrix_vp->ww - matrix_vp->wx); + evas_vec4_set(&planes[1], matrix_vp->xw - matrix_vp->xx, + matrix_vp->yw - matrix_vp->yx, + matrix_vp->zw - matrix_vp->zx, + matrix_vp->ww - matrix_vp->wx); + evas_vec4_set(&planes[2], matrix_vp->xw - matrix_vp->xx, + matrix_vp->yw - matrix_vp->yx, + matrix_vp->zw - matrix_vp->zx, + matrix_vp->ww - matrix_vp->wx); + evas_vec4_set(&planes[3], matrix_vp->xw - matrix_vp->xx, + matrix_vp->yw - matrix_vp->yx, + matrix_vp->zw - matrix_vp->zx, + matrix_vp->ww - matrix_vp->wx); + evas_vec4_set(&planes[4], matrix_vp->xw - matrix_vp->xx, + matrix_vp->yw - matrix_vp->yx, + matrix_vp->zw - matrix_vp->zx, + matrix_vp->ww - matrix_vp->wx); + evas_vec4_set(&planes[5], matrix_vp->xw - matrix_vp->xx, + matrix_vp->yw - matrix_vp->yx, + matrix_vp->zw - matrix_vp->zx, + matrix_vp->ww - matrix_vp->wx); - evas_vec4_set(&planes[2], matrix_vp->m[3] + matrix_vp->m[1], - matrix_vp->m[7] + matrix_vp->m[5], - matrix_vp->m[11] + matrix_vp->m[9], - matrix_vp->m[15] + matrix_vp->m[13]); - - evas_vec4_set(&planes[3], matrix_vp->m[3] - matrix_vp->m[1], - matrix_vp->m[7] - matrix_vp->m[5], - matrix_vp->m[11] - matrix_vp->m[9], - matrix_vp->m[15] - matrix_vp->m[13]); - - evas_vec4_set(&planes[4], matrix_vp->m[3] - matrix_vp->m[2], - matrix_vp->m[7] - matrix_vp->m[6], - matrix_vp->m[11] - matrix_vp->m[10], - matrix_vp->m[15] - matrix_vp->m[14]); - - evas_vec4_set(&planes[5], matrix_vp->m[3] + matrix_vp->m[2], - matrix_vp->m[7] + matrix_vp->m[6], - matrix_vp->m[11] + matrix_vp->m[10], - matrix_vp->m[15] + matrix_vp->m[14]); for (i = 0; i < 6; i++) { evas_plane_normalize(&planes[i]); diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index f01c931db5..5e110dd24f 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -268,18 +268,18 @@ struct _Evas_Canvas3D_Node union { struct { Evas_Canvas3D_Camera *camera; - Evas_Mat4 matrix_world_to_eye; + Eina_Matrix4 matrix_world_to_eye; } camera; struct { Evas_Canvas3D_Light *light; - Evas_Mat4 matrix_local_to_world; + Eina_Matrix4 matrix_local_to_world; } light; struct { Eina_List *meshes; Eina_Hash *node_meshes; - Evas_Mat4 matrix_local_to_world; + Eina_Matrix4 matrix_local_to_world; } mesh; } data; @@ -296,7 +296,7 @@ struct _Evas_Canvas3D_Node struct _Evas_Canvas3D_Camera { - Evas_Mat4 projection; + Eina_Matrix4 projection; Eina_Hash *nodes; }; @@ -315,7 +315,7 @@ struct _Evas_Canvas3D_Light Evas_Real atten_const; Evas_Real atten_linear; Evas_Real atten_quad; - Evas_Mat4 projection; + Eina_Matrix4 projection; Eina_Hash *nodes; }; @@ -457,7 +457,7 @@ struct _Evas_Canvas3D_Pick_Data { /* Input */ Evas_Real x, y; - Evas_Mat4 matrix_vp; + Eina_Matrix4 matrix_vp; Evas_Ray3 ray_world; /* Output */ @@ -1834,10 +1834,10 @@ struct _Evas_Imaging_Font struct _Evas_Proxy_Render_Data { - Evas_Object *eo_proxy; Evas_Object_Protected_Data *proxy_obj; - Evas_Object *eo_src; Evas_Object_Protected_Data *src_obj; + Evas_Object *eo_proxy; + Evas_Object *eo_src; Eina_Bool source_clip : 1; }; diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d.c b/src/modules/evas/engines/gl_common/evas_gl_3d.c index 68fc15fa1b..1bc8fd1e49 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d.c +++ b/src/modules/evas/engines/gl_common/evas_gl_3d.c @@ -2,12 +2,12 @@ #include "evas_gl_3d_private.h" #define RENDER_MESH_NODE_ITERATE_BEGIN(param) \ - Evas_Mat4 matrix_mv; \ - Evas_Mat4 matrix_mvp; \ + Eina_Matrix4 matrix_mv; \ + Eina_Matrix4 matrix_mvp; \ Eina_Iterator *it; \ void *ptr; \ - evas_mat4_multiply(&matrix_mv, matrix_##param, &pd_mesh_node->data.mesh.matrix_local_to_world); \ - evas_mat4_multiply(&matrix_mvp, &pd->projection, &matrix_mv); \ + eina_matrix4_multiply(&matrix_mv, matrix_##param, &pd_mesh_node->data.mesh.matrix_local_to_world); \ + eina_matrix4_multiply(&matrix_mvp, &pd->projection, &matrix_mv); \ it = eina_hash_iterator_data_new(pd_mesh_node->data.mesh.node_meshes); \ while (eina_iterator_next(it, &ptr)) \ { \ @@ -49,7 +49,7 @@ e3d_texture_new(Eina_Bool use_atlas) return NULL; } - evas_mat3_identity_set(&texture->trans); + eina_matrix3_identity(&texture->trans); texture->w = 0; texture->h = 0; @@ -94,7 +94,7 @@ e3d_texture_set(Evas_Engine_GL_Context *gc, E3D_Texture *texture, Evas_GL_Image *im) { - Evas_Mat3 pt,st; + Eina_Matrix3 pt,st; Evas_Real pt_x, pt_y, st_x, st_y; texture->surface = im; @@ -115,9 +115,9 @@ e3d_texture_set(Evas_Engine_GL_Context *gc, st_x = im->tex->pt->w ? (im->w/(Evas_Real)im->tex->pt->w) : 1.0; st_y = im->tex->pt->h ? (im->h/(Evas_Real)im->tex->pt->h) : 1.0; /*Build adjusting matrix for texture unit coordinates*/ - evas_mat3_set_position_transform(&pt, pt_x, pt_y); - evas_mat3_set_scale_transform(&st, st_x, st_y); - evas_mat3_multiply(&texture->trans, &st, &pt); + eina_matrix3_position_transform_set(&pt, pt_x, pt_y); + eina_matrix3_scale_transform_set(&st, st_x, st_y); + eina_matrix3_multiply(&texture->trans, &st, &pt); } } @@ -898,7 +898,7 @@ _material_texture_build(E3D_Draw_Data *data, int frame, static inline void _light_build(E3D_Draw_Data *data, const Evas_Canvas3D_Node *light, - const Evas_Mat4 *matrix_eye) + const Eina_Matrix4 *matrix_eye) { Evas_Canvas3D_Node_Data *pd_light_node = eo_data_scope_get(light, EVAS_CANVAS3D_NODE_CLASS); Evas_Canvas3D_Light *l = pd_light_node ? pd_light_node->data.light.light : NULL; @@ -966,10 +966,10 @@ _light_build(E3D_Draw_Data *data, static inline Eina_Bool _mesh_draw_data_build(E3D_Draw_Data *data, Evas_Canvas3D_Mesh *mesh, int frame, - const Evas_Mat4 *matrix_eye, - const Evas_Mat4 *matrix_mv, - const Evas_Mat4 *matrix_mvp, - const Evas_Mat4 *matrix_light, + const Eina_Matrix4 *matrix_eye, + const Eina_Matrix4 *matrix_mv, + const Eina_Matrix4 *matrix_mvp, + const Eina_Matrix4 *matrix_light, const Evas_Canvas3D_Node *light) { Eina_List *l, *r; @@ -1011,10 +1011,10 @@ _mesh_draw_data_build(E3D_Draw_Data *data, data->index_format = pdmesh->index_format; data->indices = pdmesh->indices; - evas_mat4_copy(&data->matrix_mvp, matrix_mvp); - evas_mat4_copy(&data->matrix_mv, matrix_mv); + eina_matrix4_copy(&data->matrix_mvp, matrix_mvp); + eina_matrix4_copy(&data->matrix_mv, matrix_mv); if (matrix_light != NULL) - evas_mat4_copy(&data->matrix_light, matrix_light); + eina_matrix4_copy(&data->matrix_light, matrix_light); _mesh_frame_find(mesh, frame, &l, &r); @@ -1073,7 +1073,7 @@ _mesh_draw_data_build(E3D_Draw_Data *data, BUILD(material_texture, MATERIAL_ATTRIB_EMISSION, EINA_FALSE); _light_build(data, light, matrix_eye); - evas_normal_matrix_get(&data->matrix_normal, matrix_mv); + eina_normal3_matrix_get(&data->matrix_normal, matrix_mv); if (_flags_need_tex_coord(data->flags)) BUILD(vertex_attrib, VERTEX_ATTRIB_TEXCOORD, EINA_FALSE); @@ -1094,7 +1094,7 @@ _mesh_draw_data_build(E3D_Draw_Data *data, BUILD(material_texture, MATERIAL_ATTRIB_EMISSION, EINA_FALSE); _light_build(data, light, matrix_eye); - evas_normal_matrix_get(&data->matrix_normal, matrix_mv); + eina_normal3_matrix_get(&data->matrix_normal, matrix_mv); if (_flags_need_tex_coord(data->flags)) BUILD(vertex_attrib, VERTEX_ATTRIB_TEXCOORD, EINA_FALSE); @@ -1124,7 +1124,7 @@ _mesh_draw_data_build(E3D_Draw_Data *data, BUILD(material_texture, MATERIAL_ATTRIB_EMISSION, EINA_FALSE); _light_build(data, light, matrix_eye); - evas_normal_matrix_get(&data->matrix_normal, matrix_mv); + eina_normal3_matrix_get(&data->matrix_normal, matrix_mv); } int num; @@ -1143,7 +1143,7 @@ _mesh_draw_data_build(E3D_Draw_Data *data, static inline void _mesh_draw(E3D_Renderer *renderer, Evas_Canvas3D_Mesh *mesh, int frame, Evas_Canvas3D_Node *light, - const Evas_Mat4 *matrix_eye, const Evas_Mat4 *matrix_mv, const Evas_Mat4 *matrix_mvp, const Evas_Mat4 *matrix_light) + const Eina_Matrix4 *matrix_eye, const Eina_Matrix4 *matrix_mv, const Eina_Matrix4 *matrix_mvp, const Eina_Matrix4 *matrix_light) { E3D_Draw_Data data; @@ -1154,7 +1154,7 @@ _mesh_draw(E3D_Renderer *renderer, Evas_Canvas3D_Mesh *mesh, int frame, Evas_Can } void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, - Evas_Canvas3D_Scene_Public_Data *data, Evas_Mat4 *matrix_light_eye, + Evas_Canvas3D_Scene_Public_Data *data, Eina_Matrix4 *matrix_light_eye, Evas_Canvas3D_Node *light) { Eina_List *l; @@ -1162,7 +1162,7 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_Canvas3D_Shade_Mode shade_mode; Eina_Bool blend_enabled; Evas_Color c = {1.0, 1.0, 1.0, 1.0}; - Evas_Mat4 matrix_vp; + Eina_Matrix4 matrix_vp; glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(data->depth_offset, data->depth_constant); @@ -1178,7 +1178,7 @@ void _shadowmap_render(E3D_Drawable *drawable, E3D_Renderer *renderer, EVAS_CANVAS3D_LIGHT_CLASS); Evas_Vec4 planes[6]; - evas_mat4_multiply(&matrix_vp, &pd->projection, matrix_light_eye); + eina_matrix4_multiply(&matrix_vp, &pd->projection, matrix_light_eye); evas_frustum_calculate(planes, &matrix_vp); EINA_LIST_FOREACH(data->mesh_nodes, l, n) @@ -1212,9 +1212,9 @@ e3d_drawable_scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_C { Eina_List *l; Evas_Canvas3D_Node *n; - const Evas_Mat4 *matrix_eye; + const Eina_Matrix4 *matrix_eye; Evas_Canvas3D_Node *light; - Evas_Mat4 matrix_light_eye, matrix_vp;; + Eina_Matrix4 matrix_light_eye, matrix_vp;; Evas_Canvas3D_Light_Data *ld = NULL; Evas_Canvas3D_Node_Data *pd_light_node; Evas_Vec4 planes[6]; @@ -1240,13 +1240,13 @@ e3d_drawable_scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_C e3d_renderer_target_set(renderer, drawable); e3d_renderer_clear(renderer, &data->bg_color); - evas_mat4_multiply(&matrix_vp, &pd->projection, matrix_eye); + eina_matrix4_multiply(&matrix_vp, &pd->projection, matrix_eye); evas_frustum_calculate(planes, &matrix_vp); EINA_LIST_FOREACH(data->mesh_nodes, l, n) { - Evas_Mat4 matrix_mv; - Evas_Mat4 matrix_light; - Evas_Mat4 matrix_mvp; + Eina_Matrix4 matrix_mv; + Eina_Matrix4 matrix_light; + Eina_Matrix4 matrix_mvp; Eina_Iterator *it; void *ptr; Evas_Canvas3D_Node_Data *pd_mesh_node = eo_data_scope_get(n, EVAS_CANVAS3D_NODE_CLASS); @@ -1257,14 +1257,14 @@ e3d_drawable_scene_render(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_C if (data->shadows_enabled) { - evas_mat4_multiply(&matrix_mv, &matrix_light_eye, + eina_matrix4_multiply(&matrix_mv, &matrix_light_eye, &pd_mesh_node->data.mesh.matrix_local_to_world); - evas_mat4_multiply(&matrix_light, &ld->projection, + eina_matrix4_multiply(&matrix_light, &ld->projection, &matrix_mv); } - evas_mat4_multiply(&matrix_mv, matrix_eye, &pd_mesh_node->data.mesh.matrix_local_to_world); - evas_mat4_multiply(&matrix_mvp, &pd->projection, + eina_matrix4_multiply(&matrix_mv, matrix_eye, &pd_mesh_node->data.mesh.matrix_local_to_world); + eina_matrix4_multiply(&matrix_mvp, &pd->projection, &matrix_mv); it = eina_hash_iterator_data_new(pd_mesh_node->data.mesh.node_meshes); @@ -1290,7 +1290,7 @@ Eina_Bool e3d_drawable_scene_render_to_texture(E3D_Drawable *drawable, E3D_Renderer *renderer, Evas_Canvas3D_Scene_Public_Data *data) { - const Evas_Mat4 *matrix_eye; + const Eina_Matrix4 *matrix_eye; Evas_Canvas3D_Shade_Mode shade_mode; Eina_Stringshare *tmp; Eina_Iterator *itmn; diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d_private.h b/src/modules/evas/engines/gl_common/evas_gl_3d_private.h index a05eba7669..03970beb94 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d_private.h +++ b/src/modules/evas/engines/gl_common/evas_gl_3d_private.h @@ -56,10 +56,10 @@ struct _E3D_Draw_Data E3D_Shader_Flag flags; Evas_Canvas3D_Shade_Mode mode; - Evas_Mat4 matrix_mvp; - Evas_Mat4 matrix_mv; - Evas_Mat3 matrix_normal; - Evas_Mat4 matrix_light; + Eina_Matrix4 matrix_mvp; + Eina_Matrix4 matrix_mv; + Eina_Matrix3 matrix_normal; + Eina_Matrix4 matrix_light; struct { Evas_Canvas3D_Vertex_Buffer vertex0; @@ -96,7 +96,7 @@ struct _E3D_Draw_Data Eina_Bool alpha_test_enabled :1; struct { - Evas_Vec4 position; + Eina_Quaternion position; Evas_Vec3 spot_dir; Evas_Real spot_exp; Evas_Real spot_cutoff_cos; @@ -125,7 +125,7 @@ struct _E3D_Texture Evas_GL_Image *surface; /*Tranformation matrix, use it for adjusting texture unit coordinates*/ - Evas_Mat3 trans; + Eina_Matrix3 trans; GLuint tex; diff --git a/src/modules/evas/engines/gl_common/evas_gl_3d_shader.c b/src/modules/evas/engines/gl_common/evas_gl_3d_shader.c index 8beeb3d0a6..23b551dc87 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_3d_shader.c +++ b/src/modules/evas/engines/gl_common/evas_gl_3d_shader.c @@ -373,6 +373,35 @@ _program_uniform_init(E3D_Program *program) } } +#define UNIFORM_MATRIX3_FOREACH(m, data) \ + m[0] = data.xx; \ + m[1] = data.xy; \ + m[2] = data.xz; \ + m[3] = data.yx; \ + m[4] = data.yy; \ + m[5] = data.yz; \ + m[6] = data.zx; \ + m[7] = data.zy; \ + m[8] = data.zz; + +#define UNIFORM_MATRIX4_FOREACH(m, data) \ + m[0] = data.xx; \ + m[1] = data.xy; \ + m[2] = data.xz; \ + m[3] = data.xw; \ + m[4] = data.yx; \ + m[5] = data.yy; \ + m[6] = data.yz; \ + m[7] = data.yw; \ + m[8] = data.zx; \ + m[9] = data.zy; \ + m[10] = data.zz; \ + m[11] = data.zw; \ + m[12] = data.wx; \ + m[13] = data.wy; \ + m[14] = data.wz; \ + m[15] = data.ww; + static inline void _uniform_upload(E3D_Uniform u, GLint loc, const E3D_Draw_Data *data) { @@ -380,8 +409,7 @@ _uniform_upload(E3D_Uniform u, GLint loc, const E3D_Draw_Data *data) if (data->materials[attrib].tex##tn) \ { \ float m[9]; \ - for(int i = 0 ; i < 9 ; i++) \ - m[i] = data->materials[attrib].tex##tn->trans.m[i]; \ + UNIFORM_MATRIX3_FOREACH(m, data->materials[attrib].tex##tn->trans); \ glUniformMatrix3fv(loc, 1, EINA_FALSE, &m[0]); \ } @@ -389,29 +417,25 @@ _uniform_upload(E3D_Uniform u, GLint loc, const E3D_Draw_Data *data) { case E3D_UNIFORM_MATRIX_MVP: { float m[16]; - for(int i = 0 ; i <16 ; i++) - m[i] = data->matrix_mvp.m[i]; + UNIFORM_MATRIX4_FOREACH(m, data->matrix_mvp); glUniformMatrix4fv(loc, 1, EINA_FALSE, &m[0]); break; } case E3D_UNIFORM_MATRIX_MV: { float m[16]; - for(int i = 0 ; i <16 ; i++) - m[i] = data->matrix_mv.m[i]; + UNIFORM_MATRIX4_FOREACH(m, data->matrix_mv); glUniformMatrix4fv(loc, 1, EINA_FALSE, &m[0]); break; } case E3D_UNIFORM_MATRIX_NORMAL: { float m[9]; - for(int i = 0 ; i <9 ; i++) - m[i] = data->matrix_normal.m[i]; + UNIFORM_MATRIX3_FOREACH(m, data->matrix_normal); glUniformMatrix3fv(loc, 1, EINA_FALSE, &m[0]); break; } case E3D_UNIFORM_MATRIX_LIGHT: { float m[16]; - for(int i = 0 ; i <16 ; i++) - m[i] = data->matrix_light.m[i]; + UNIFORM_MATRIX4_FOREACH(m, data->matrix_light); glUniformMatrix4fv(loc, 1, EINA_FALSE, &m[0]); break; } diff --git a/src/tests/eina/eina_test_matrix.c b/src/tests/eina/eina_test_matrix.c index fcee52fe34..11cc2c63e7 100644 --- a/src/tests/eina/eina_test_matrix.c +++ b/src/tests/eina/eina_test_matrix.c @@ -20,12 +20,106 @@ # include "config.h" #endif +#define DBL_EPSILON 0.0000001 + #include #include #include "eina_suite.h" #include "Eina.h" +START_TEST(eina_matrix2) +{ + Eina_Matrix2 m; + Eina_Matrix2 n; + double xx, xy, yx, yy; + + eina_init(); + + eina_matrix2_values_set(&m, + 1, 0, + 0, 1); + fail_if(eina_matrix2_type_get(&m) != EINA_MATRIX_TYPE_IDENTITY); + + eina_matrix2_inverse(&n, &m); + fail_if(eina_matrix2_type_get(&n) != EINA_MATRIX_TYPE_IDENTITY); + + eina_matrix2_values_get(&m, + &xx, &xy, + &yx, &yy); + + fail_if(xx != yy || + yy != 1); + fail_if(xy != yx || + xy != 0); + + eina_shutdown(); +} +END_TEST + +START_TEST(eina_matrix2_operation) +{ + Eina_Matrix2 m1, m2, m3; + double xx, xy, yx, yy; + double arr[] = {1, 1, 1, 1}; + + eina_matrix2_values_set(&m2, + 2, 3, + 3, 2); + eina_matrix2_inverse(&m1, &m2); + eina_matrix2_values_get(&m1, + &xx, &xy, + &yx, &yy); + fail_if((xx - (-0.4) > DBL_EPSILON) || (xy - 0.6 > DBL_EPSILON) || + (yx - 0.6 > DBL_EPSILON) || (yy - (-0.4) > DBL_EPSILON)); + + eina_matrix2_identity(&m1); + eina_matrix2_values_get(&m1, + &xx, &xy, + &yx, &yy); + fail_if(xx != yy || + yy != 1 || + xy != yx || + xy != 0); + + eina_matrix2_array_set(&m1, &arr); + eina_matrix2_values_get(&m1, + &xx, &xy, + &yx, &yy); + fail_if(xx != yy || + yx != xy || + xy != 1); + + eina_matrix2_copy(&m2, &m1); + eina_matrix2_values_get(&m2, + &xx, &xy, + &yx, &yy); + fail_if(xx != yy || + yx != xy || + xy != 1); + + eina_matrix2_values_set(&m1, + 2, 3, + 3, 2); + eina_matrix2_multiply_copy(&m3, &m1, &m2); + eina_matrix2_values_get(&m3, + &xx, &xy, + &yx, &yy); + fail_if(xx != yy || + yx != xy || + xy != 5); + + eina_matrix2_multiply(&m3, &m1, &m2); + eina_matrix2_values_get(&m3, + &xx, &xy, + &yx, &yy); + fail_if(xx != yy || + yx != xy || + xy != 5); + +} +END_TEST + START_TEST(eina_matrix4) { Eina_Matrix4 m; @@ -77,6 +171,128 @@ START_TEST(eina_matrix4) } END_TEST +START_TEST(eina_matrix4_operation) +{ + double det; + double l=5, r=4, b=4, t=3, dn=3, df=2; + Eina_Matrix4 m, m1, m2; + double xx, xy, xz, xw, + yx, yy, yz, yw, + zx, zy, zz, zw, + wx, wy, wz, ww; + const double arr[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + eina_matrix4_values_set(&m, + 0, 0, 2, 0, + 2, 0, 0, 0, + 0, 0, 0, 2, + 0, 2, 0, 0); + det = eina_matrix4_determinant(&m); + fail_if(det != -16); + + eina_matrix4_inverse(&m1, &m); + eina_matrix4_values_get(&m1, + &xx, &xy, &xz, &xw, + &yx, &yy, &yz, &yw, + &zx, &zy, &zz, &zw, + &wx, &wy, &wz, &ww); + fail_if (xy != 0.5 || + yw != xy || + zx != yw || + wz != zx); + + eina_matrix4_identity(&m1); + eina_matrix4_values_get(&m1, + &xx, &xy, &xz, &xw, + &yx, &yy, &yz, &yw, + &zx, &zy, &zz, &zw, + &wx, &wy, &wz, &ww); + fail_if (xx != 1 || + yy != xx || + zz != yy || + ww != zz); + + eina_matrix4_values_set(&m1, + 0, 2, 2, 0, + 2, 0, 0, 2, + 2, 0, 0, 2, + 0, 2, 2, 0); + eina_matrix4_multiply_copy(&m2, &m1, &m); + eina_matrix4_values_get(&m2, + &xx, &xy, &xz, &xw, + &yx, &yy, &yz, &yw, + &zx, &zy, &zz, &zw, + &wx, &wy, &wz, &ww); + fail_if (xx != 4 || + xw != xx || + yy != xw || + yz != yy || + zy != yz || + zz != yy || + wx != xx || + ww != zy); + + eina_matrix4_multiply(&m2, &m1, &m); + eina_matrix4_values_get(&m2, + &xx, &xy, &xz, &xw, + &yx, &yy, &yz, &yw, + &zx, &zy, &zz, &zw, + &wx, &wy, &wz, &ww); + fail_if (xx != 4 || + xw != xx || + yy != xw || + yz != yy || + zy != yz || + zz != yy || + wx != xx || + ww != zy); + + eina_matrix4_array_set(&m1, &arr); + eina_matrix4_values_get(&m1, + &xx, &xy, &xz, &xw, + &yx, &yy, &yz, &yw, + &zx, &zy, &zz, &zw, + &wx, &wy, &wz, &ww); + fail_if (xx != 1 || + xw != xx || + yy != xw || + yz != yy || + zy != yz || + zz != yy || + wx != xx || + ww != zy); + + eina_matrix4_copy(&m, &m1); + eina_matrix4_values_get(&m1, + &xx, &xy, &xz, &xw, + &yx, &yy, &yz, &yw, + &zx, &zy, &zz, &zw, + &wx, &wy, &wz, &ww); + fail_if (xx != 1 || + xw != xx || + yy != xw || + yz != yy || + zy != yz || + zz != yy || + wx != xx || + ww != zy); + + eina_matrix4_ortho_set(&m, l, r, b, t, dn, df); + eina_matrix4_values_get(&m, + &xx, &xy, &xz, &xw, + &yx, &yy, &yz, &yw, + &zx, &zy, &zz, &zw, + &wx, &wy, &wz, &ww); + fail_if (xx != -2 || + yy != -2 || + zz != 2 || + wx != 9 || + wy != 7 || + wz != 5 || + ww != 1); +} +END_TEST + START_TEST(eina_matrix4_2_3) { Eina_Matrix4 m4; @@ -155,6 +371,7 @@ START_TEST(eina_matrix3_operations) yx, yy, yz, zx, zy, zz; double tx = 20, ty = 30, ret; + const double arr[] = {1, 1, 1, 1, 1, 1, 1, 1, 1}; eina_matrix3_values_set(&m1, 1, 0, 0, @@ -305,6 +522,68 @@ START_TEST(eina_matrix3_operations) fail_if (xx != 24 || xy != -12 || xz != -2 || yx != 5 || yy != 3 || yz != -5 || zx != -4 || zy != 2 || zz != 4); + + eina_matrix3_values_set(&m2, + 2, 2, 2, + 1, 1, 1, + 3, 3, 3); + eina_matrix3_values_set(&m3, + 3, 3, 3, + 2, 2, 2, + 1, 1, 1); + eina_matrix3_multiply_copy(&m1, &m2, &m3); + eina_matrix3_values_get(&m1, + &xx, &xy, &xz, + &yx, &yy, &yz, + &zx, &zy, &zz); + fail_if (xx != 12 || xy != 12 || xz != 12 || + yx != 6 || yy != 6 || yz != 6 || + zx != 18 || zy != 18 || zz != 18); + + eina_matrix3_values_set(&m2, + 2, 2, 2, + 1, 1, 1, + 0, 0, 0); + eina_matrix3_multiply(&m1, &m2, &m3); + eina_matrix3_values_get(&m1, + &xx, &xy, &xz, + &yx, &yy, &yz, + &zx, &zy, &zz); + fail_if (xx != 12 || xy != 12 || xz != 12 || + yx != 6 || yy != 6 || yz != 6 || + zx != 0 || zy != 0 || zz != 0); + + eina_matrix3_copy(&m1, &m2); + eina_matrix3_values_get(&m1, + &xx, &xy, &xz, + &yx, &yy, &yz, + &zx, &zy, &zz); + fail_if (xx != 2 || xy != 2 || xz != 2 || + yx != 1 || yy != 1 || yz != 1 || + zx != 0 || zy != 0 || zz != 0); + + eina_matrix3_array_set(&m1, &arr); + eina_matrix3_values_get(&m1, + &xx, &xy, &xz, + &yx, &yy, &yz, + &zx, &zy, &zz); + fail_if (xx != 1 || xy != 1 || xz != 1 || + yx != 1 || yy != 1 || yz != 1 || + zx != 1 || zy != 1 || zz != 1); + + eina_matrix3_position_transform_set(&m3, 5, 3); + eina_matrix3_values_get(&m3, + &xx, &xy, &xz, + &yx, &yy, &yz, + &zx, &zy, &zz); + fail_if (xz != 5 || yz != 3); + + eina_matrix3_scale_transform_set(&m2, 6, 7); + eina_matrix3_values_get(&m2, + &xx, &xy, &xz, + &yx, &yy, &yz, + &zx, &zy, &zz); + fail_if (xx != 6 || yy != 7); } END_TEST @@ -427,7 +706,10 @@ END_TEST void eina_test_matrix(TCase *tc) { + tcase_add_test(tc, eina_matrix2); + tcase_add_test(tc, eina_matrix2_operation); tcase_add_test(tc, eina_matrix4); + tcase_add_test(tc, eina_matrix4_operation); tcase_add_test(tc, eina_matrix4_2_3); tcase_add_test(tc, eina_matrix3); tcase_add_test(tc, eina_matrix3_operations);