From b216d15fe7ea5190a518e295f653d0c9376bbc27 Mon Sep 17 00:00:00 2001 From: "se.osadchy" Date: Fri, 5 Feb 2016 08:07:42 +0100 Subject: [PATCH] eina: add eina_vector3 as static inline. Summary: Move evas_vec3 to eina_vector3 and add documentation. Reviewers: stefan_schmidt, jpeg, cedric Reviewed By: cedric Subscribers: jpeg Differential Revision: https://phab.enlightenment.org/D3569 Signed-off-by: Cedric BAIL --- src/lib/eina/eina_inline_vector.x | 263 ++++++++++++++++++++++++- src/lib/eina/eina_vector.h | 316 +++++++++++++++++++++++++++++- 2 files changed, 564 insertions(+), 15 deletions(-) diff --git a/src/lib/eina/eina_inline_vector.x b/src/lib/eina/eina_inline_vector.x index e61c2c1191..1332a90865 100644 --- a/src/lib/eina/eina_inline_vector.x +++ b/src/lib/eina/eina_inline_vector.x @@ -117,12 +117,8 @@ static inline void eina_vector2_transform(Eina_Vector2 *out, const Eina_Matrix2 *m, const Eina_Vector2 *v) { - Eina_Vector2 tmp; - - tmp.x = (m->xx * v->x) + (m->yx * v->y); - tmp.y = (m->xy * v->x) + (m->yy * v->y); - - eina_vector2_copy(out, &tmp); + out->x = (m->xx * v->x) + (m->yx * v->y); + out->y = (m->xy * v->x) + (m->yy * v->y); } static inline void @@ -143,12 +139,259 @@ eina_vector2_homogeneous_direction_transform(Eina_Vector2 *out, const Eina_Matrix3 *m, const Eina_Vector2 *v) { - Eina_Vector2 tmp; + out->x = (m->xx * v->x) + (m->yx * v->y); + out->y = (m->xy * v->x) + (m->yy * v->y); +} - tmp.x = (m->xx * v->x) + (m->yx * v->y); - tmp.y = (m->xy * v->x) + (m->yy * v->y); +static inline void +eina_vector3_set(Eina_Vector3 *dst, double x, double y, double z) +{ + dst->x = x; + dst->y = y; + dst->z = z; +} - eina_vector2_copy(out, &tmp); +static inline void +eina_vector3_array_set(Eina_Vector3 *dst, const double *v) +{ + dst->x = v[0]; + dst->y = v[1]; + dst->z = v[2]; +} + +static inline void +eina_vector3_copy(Eina_Vector3 *dst, const Eina_Vector3 *src) +{ + dst->x = src->x; + dst->y = src->y; + dst->z = src->z; +} + +static inline void +eina_vector3_negate(Eina_Vector3 *out, const Eina_Vector3 *v) +{ + out->x = -v->x; + out->y = -v->y; + out->z = -v->z; +} + +static inline void +eina_vector3_add(Eina_Vector3 *out, const Eina_Vector3 *a, const Eina_Vector3 *b) +{ + out->x = a->x + b->x; + out->y = a->y + b->y; + out->z = a->z + b->z; +} + +static inline void +eina_vector3_subtract(Eina_Vector3 *out, const Eina_Vector3 *a, const Eina_Vector3 *b) +{ + out->x = a->x - b->x; + out->y = a->y - b->y; + out->z = a->z - b->z; +} + +static inline void +eina_vector3_scale(Eina_Vector3 *out, const Eina_Vector3 *v, double scale) +{ + out->x = scale * v->x; + out->y = scale * v->y; + out->z = scale * v->z; +} + +static inline void +eina_vector3_multiply(Eina_Vector3 *out, const Eina_Vector3 *a, const Eina_Vector3 *b) +{ + out->x = a->x * b->x; + out->y = a->y * b->y; + out->z = a->z * b->z; +} + +static inline double +eina_vector3_dot_product(const Eina_Vector3 *a, const Eina_Vector3 *b) +{ + return (a->x * b->x) + (a->y * b->y) + (a->z * b->z); +} + +static inline void +eina_vector3_cross_product(Eina_Vector3 *out, const Eina_Vector3 *a, const Eina_Vector3 *b) +{ + out->x = a->y * b->z - a->z * b->y; + out->y = a->z * b->x - a->x * b->z; + out->z = a->x * b->y - a->y * b->x; +} + +static inline double +eina_vector3_length_get(const Eina_Vector3 *v) +{ + return (double)sqrt((double)((v->x * v->x) + (v->y * v->y) + (v->z * v->z))); +} + +static inline double +eina_vector3_length_square_get(const Eina_Vector3 *v) +{ + return (v->x * v->x) + (v->y * v->y) + (v->z * v->z); +} + +static inline double +eina_vector3_distance_get(const Eina_Vector3 *a, const Eina_Vector3 *b) +{ + Eina_Vector3 v; + + eina_vector3_subtract(&v, a, b); + return eina_vector3_length_get(&v); +} + +static inline double +eina_vector3_distance_square_get(const Eina_Vector3 *a, const Eina_Vector3 *b) +{ + Eina_Vector3 v; + + eina_vector3_subtract(&v, a, b); + return eina_vector3_length_square_get(&v); +} + +static inline double +eina_vector3_angle_get(const Eina_Vector3 *a, const Eina_Vector3 *b) +{ + double angle; + + angle = eina_vector3_dot_product(a, b) / + (eina_vector3_length_get(a) * eina_vector3_length_get(b)); + return angle; +} + +static inline void +eina_vector3_normalize(Eina_Vector3 *out, const Eina_Vector3 *v) +{ + /* Assume "v" is not a zero vector */ + eina_vector3_scale(out, v, 1.0 / eina_vector3_length_get(v)); +} + +static inline void +eina_vector3_transform(Eina_Vector3 *out, const Eina_Matrix3 *m, const Eina_Vector3 *v) +{ + if (eina_matrix3_type_get(m) == EINA_MATRIX_TYPE_IDENTITY) + { + eina_vector3_copy(out, v); + return; + } + + out->x = (m->xx * v->x) + (m->yx * v->y) + (m->zx * v->z); + out->y = (m->xy * v->x) + (m->yy * v->y) + (m->zy * v->z); + out->z = (m->xz * v->x) + (m->yz * v->y) + (m->zz * v->z); +} + +static inline void +eina_vector3_homogeneous_position_transform(Eina_Vector3 *out, const Eina_Matrix4 *m, + const Eina_Vector3 *v) +{ + Eina_Vector3 tmp; + + if (eina_matrix4_type_get(m) == EINA_MATRIX_TYPE_IDENTITY) + { + eina_vector3_copy(out, v); + return; + } + + if (((m->xw * v->x) + (m->yw * v->y) + (m->zw * v->z) + m->ww) == 0.0) + return; + + tmp.x = (m->xx * v->x) + (m->yx * v->y) + (m->zx * v->z) + m->wx; + tmp.y = (m->xy * v->x) + (m->yy * v->y) + (m->zy * v->z) + m->wy; + tmp.z = (m->xz * v->x) + (m->yz * v->y) + (m->zz * v->z) + m->wz; + + eina_vector3_scale(out, &tmp, + 1.0 / ((m->xw * v->x) + (m->yw * v->y) + (m->zw * v->z) + m->ww)); +} + +static inline void +eina_vector3_quaternion_rotate(Eina_Vector3 *out, const Eina_Vector3 *v, + const Eina_Quaternion *q) +{ + Eina_Vector3 uv, uuv; + Eina_Vector3 axis; + + eina_vector3_set(&axis, q->x, q->y, q->z); + + eina_vector3_cross_product(&uv, &axis, v); + eina_vector3_cross_product(&uuv, &axis, &uv); + + eina_vector3_scale(&uv, &uv, 2.0 * q->w); + eina_vector3_scale(&uuv, &uuv, 2.0); + + out->x = v->x + uv.x + uuv.x; + out->y = v->y + uv.y + uuv.y; + out->z = v->z + uv.z + uuv.z; +} + +static inline void +eina_vector3_orthogonal_projection_on_plane(Eina_Vector3 *out, const Eina_Vector3 *v, + const Eina_Vector3 *normal) +{ + double a; + Eina_Vector3 projection; + + /* Orthoprojection of vector on the plane is the difference + between a vector and its orthogonal projection onto the orthogonal + complement to the plane */ + a = eina_vector3_dot_product(v, normal) / eina_vector3_length_square_get(normal); + eina_vector3_scale(&projection, normal, a); + eina_vector3_subtract(out, v, &projection); + + return; +} + +static inline void +eina_vector3_plane_by_points(Eina_Quaternion *out, const Eina_Vector3 *a, + const Eina_Vector3 *b, const Eina_Vector3 *c) +{ + out->x = (b->y - a->y) * (c->z - a->z) - (b->z - a->z) * (c->y - a->y); + out->y = -(b->x - a->x) * (c->z - a->z) + (b->z - a->z) * (c->x - a->x); + out->z = (b->x - a->x) * (c->y - a->y) - (b->y - a->y) * (c->x - a->x); + out->w = (-a->x) * ((b->y - a->y)*(c->z - a->z) - (b->z - a->z) * (c->y - a->y)) - + (-a->y) * ((b->x - a->x) * (c->z - a->z) - (b->z - a->z) * (c->x - a->x)) + + (-a->z) * ((b->x - a->x) * (c->y - a->y) - (b->y - a->y) * (c->x - a->x)); +} + +static inline void +eina_vector3_homogeneous_position_set(Eina_Vector3 *out, const Eina_Quaternion *v) +{ + /* Assume "v" is a positional vector. (v->w != 0.0) */ + double h = 1.0 / v->w; + + out->x = v->x * h; + out->y = v->y * h; + out->z = v->z * h; +} + +static inline void +eina_vector3_homogeneous_direction_set(Eina_Vector3 *out, const Eina_Quaternion *v) +{ + /* Assume "v" is a directional vector. (v->w == 0.0) */ + out->x = v->x; + out->y = v->y; + out->z = v->z; +} + +static inline Eina_Bool +eina_vector3_equivalent(Eina_Vector3 *a, const Eina_Vector3 *b) +{ + /* Assume "v" is a directional vector. (v->w == 0.0) */ + return ((a->x == b->x) && (a->y == b->y) && (a->z == b->z)); +} + +static inline Eina_Bool +eina_vector3_triangle_equivalent(Eina_Vector3 *v0, Eina_Vector3 *v1, + Eina_Vector3 *v2, Eina_Vector3 *w0, + Eina_Vector3 *w1, Eina_Vector3 *w2) +{ + if (((v0->x == w0->x) && (v0->y == w0->y) && (v0->z == w0->z)) && + ((v1->x == w1->x) && (v1->y == w1->y) && (v1->z == w1->z)) && + ((v2->x == w2->x) && (v2->y == w2->y) && (v2->z == w2->z))) + return EINA_TRUE; + + return EINA_FALSE; } #endif diff --git a/src/lib/eina/eina_vector.h b/src/lib/eina/eina_vector.h index 9ba95a0911..1c95c3d57e 100644 --- a/src/lib/eina/eina_vector.h +++ b/src/lib/eina/eina_vector.h @@ -1,5 +1,5 @@ /* EINA - EFL data type library - * Copyright (C) 2016 Cedric Bail + * Copyright (C) 2016 Sergey Osadchy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,14 +20,17 @@ #define EINA_VECTOR_H_ #include "eina_matrix.h" +#include "eina_quaternion.h" /** * @file * @ender_group{Eina_Vector_Type} * @ender_group{Eina_Vector2} + * @ender_group{Eina_Vector3} */ typedef struct _Eina_Vector2 Eina_Vector2; +typedef struct _Eina_Vector3 Eina_Vector3; /** * @} @@ -43,6 +46,21 @@ struct _Eina_Vector2 double y; }; +/** + * @} + * @defgroup Eina_Vector3 Vectors in floating point + * @ingroup Eina_Basic + * @brief Vector definition and operations + * @{ + */ + +struct _Eina_Vector3 +{ + double x; + double y; + double z; +}; + /** * @brief Set parameters to vector. * @@ -187,7 +205,7 @@ static inline void eina_vector2_normalize(Eina_Vector2 *out, const Eina_Vector2 * * @param out The resulting vector. * @param m The matrix for transform. - * @param v The ector for transform. + * @param v The vector for transform. * * @since 1.17 */ @@ -198,23 +216,311 @@ static inline void eina_vector2_transform(Eina_Vector2 *out, const Eina_Matrix2 * * @param out The resulting vector. * @param m The matrix for transform. - * @param v The ector for transform. + * @param v The vector for transform. * * @since 1.17 */ static inline void eina_vector2_homogeneous_position_transform(Eina_Vector2 *out, const Eina_Matrix3 *m, const Eina_Vector2 *v); /** - * @brief Homogeneous direction ransform vector. + * @brief Homogeneous direction transform vector. * * @param out The resulting vector. * @param m The matrix for transform. - * @param v The ector for transform. + * @param v The vector for transform. * * @since 1.17 */ static inline void eina_vector2_homogeneous_direction_transform(Eina_Vector2 *out, const Eina_Matrix3 *m, const Eina_Vector2 *v); +/** + * @brief Set parameters to vector. + * + * @param dst The resulting vector. + * @param x The x component. + * @param y The y component. + * @param z The z component. + * + * @since 1.18 + */ +static inline void eina_vector3_set(Eina_Vector3 *dst, double x, double y, double z); + +/** + * @brief Set array to vector. + * + * @param dst The resulting vector. + * @param v The the array[3] for set. + * + * Set to vector first 3 elements from array. + * + * @since 1.18 + */ +static inline void eina_vector3_array_set(Eina_Vector3 *dst, const double *v); + +/** + * @brief Copy vector. + * + * @param dst The vector copy. + * @param src The vector for copy. + * + * @since 1.18 + */ +static inline void eina_vector3_copy(Eina_Vector3 *dst, const Eina_Vector3 *src); + +/** + * @brief Make negative vector. + * + * @param out The resulting vector. + * @param v The current vector. + * + * @since 1.18 + */ +static inline void eina_vector3_negate(Eina_Vector3 *out, const Eina_Vector3 *v); + +/** + * @brief Add two vectors. + * + * @param out The resulting vector. + * @param a The first member of the add. + * @param b The second member of the add. + * + * @since 1.18 + */ +static inline void eina_vector3_add(Eina_Vector3 *out, const Eina_Vector3 *a, + const Eina_Vector3 *b); + +/** + * @brief Subtract two vectors + * + * @param out The resulting vector + * @param a The first member of the subtract + * @param b The second member of the subtract + * + * @since 1.18 + */ +static inline void eina_vector3_subtract(Eina_Vector3 *out, const Eina_Vector3 *a, + const Eina_Vector3 *b); + +/** + * @brief Scale vector. + * + * @param out The resulting vector. + * @param v The vector for scale. + * @param scale The scale value. + * + * @since 1.18 + */ +static inline void eina_vector3_scale(Eina_Vector3 *out, const Eina_Vector3 *v, double scale); + +/** + * @brief Multiply two vectors + * + * @param out The resulting vector + * @param a The first member + * @param b The second member + * + * @since 1.18 + */ +static inline void eina_vector3_multiply(Eina_Vector3 *out, const Eina_Vector3 *a, + const Eina_Vector3 *b); + +/** + * @brief Return the dot product of the two vectors. + * + * @param a The first member. + * @param b The secondt member. + * @return The dot product. + * + * @since 1.18 + */ +static inline double eina_vector3_dot_product(const Eina_Vector3 *a, const Eina_Vector3 *b); + +/** + * @brief Create the cross product of the two vectors. + * + * @param out The resulting vector. + * @param a The first member. + * @param b The secondt member. + * + * @since 1.18 + */ +static inline void eina_vector3_cross_product(Eina_Vector3 *out, const Eina_Vector3 *a, + const Eina_Vector3 *b); + +/** + * @brief Return the length of the given vector. + * + * @param v The vector. + * @return The length. + * + * @since 1.18 + */ +static inline double eina_vector3_length_get(const Eina_Vector3 *v); + +/** + * @brief Return the length in square of the given vector. + * + * @param v The vector. + * @return The length in square. + * + * @since 1.18 + */ +static inline double eina_vector3_length_square_get(const Eina_Vector3 *v); + +/** + * @brief Return the distance between of two vectors. + * + * @param a The first vector. + * @param b The second vector. + * @return The distance. + * + * @since 1.18 + */ +static inline double eina_vector3_distance_get(const Eina_Vector3 *a, const Eina_Vector3 *b); + +/** + * @brief Return the distance in square between of two vectors. + * + * @param a The first vector. + * @param b The second vector. + * @return The distance in square. + * + * @since 1.18 + */ +static inline double eina_vector3_distance_square_get(const Eina_Vector3 *a, + const Eina_Vector3 *b); + +/** + * @brief Return the angle between of two vectors. + * + * @param a The first vector. + * @param b The second vector. + * @return The angle. + * + * @since 1.18 + */ +static inline double eina_vector3_angle_get(const Eina_Vector3 *a, const Eina_Vector3 *b); + +/** + * @brief normalize vector. + * + * @param out The resulting vector. + * @param v The not NULL vector for normalize. + * + * @since 1.18 + */ +static inline void eina_vector3_normalize(Eina_Vector3 *out, const Eina_Vector3 *v); + +/** + * @brief Transform vector. + * + * @param out The resulting vector. + * @param m The matrix for transform. + * @param v The vector for transform. + * + * @since 1.18 + */ +static inline void eina_vector3_transform(Eina_Vector3 *out, const Eina_Matrix3 *m, + const Eina_Vector3 *v); + +/** + * @brief Homogeneous position transform vector. + * + * @param out The resulting vector. + * @param m The matrix for transform. + * @param v The vector for transform. + * + * @since 1.18 + */ +static inline void eina_vector3_homogeneous_position_transform(Eina_Vector3 *out, const Eina_Matrix4 *m, + const Eina_Vector3 *v); + + +/** + * @brief Rotate vector. + * + * @param out The resulting vector. + * @param v The vector for rotate. + * @param q The quaternion in radians for rotate. + * + * @since 1.18 + */ +static inline void eina_vector3_quaternion_rotate(Eina_Vector3 *out, const Eina_Vector3 *v, + const Eina_Quaternion *q); + +/** + * @brief Create orthogonal projection on plane between vector and normal. + * + * @param out The resulting vector. + * @param v The vector for projection. + * @param normal The normal for projection. + * + * @since 1.18 + */ +static inline void eina_vector3_orthogonal_projection_on_plane(Eina_Vector3 *out, const Eina_Vector3 *v, + const Eina_Vector3 *normal); + +/** + * @brief Plane by points between three vectors. + * + * @param out The resulting quaternion of plane. + * @param a The first member. + * @param b The second member. + * @param c The third member. + * + * @since 1.18 + */ +static inline void eina_vector3_plane_by_points(Eina_Quaternion *out, const Eina_Vector3 *a, + const Eina_Vector3 *b, const Eina_Vector3 *c); + +/** + * @brief Homogeneous position set. + * + * @param out The resulting vector. + * @param v The quaternion for position. + * + * @since 1.18 + */ +static inline void eina_vector3_homogeneous_position_set(Eina_Vector3 *out, const Eina_Quaternion *v); + +/** + * @brief Homogeneous direction set. + * + * @param out The resulting vector. + * @param v The quaternion for direction. + * + * @since 1.18 + */ +static inline void eina_vector3_homogeneous_direction_set(Eina_Vector3 *out, const Eina_Quaternion *v); + +/** + * @brief Check the equivalent between of two vectors. + * + * @param a The first vector. + * @param b The second vector. + * @return The EINA_TRUE if equivalent. + * + * @since 1.18 + */ +static inline Eina_Bool eina_vector3_equivalent(Eina_Vector3 *a, const Eina_Vector3 *b); + +/** + * @brief Check the equivalent between of two triangles of vectors. + * + * @param v0 The first member of first triangle. + * @param v1 The second member of first triangle. + * @param v2 The third member of first triangle. + * @param w0 The first member of second triangle. + * @param w1 The second member of second triangle. + * @param w2 The third member of second triangle. + * @return The EINA_TRUE if equivalent. + * + * @since 1.18 + */ +static inline Eina_Bool eina_vector3_triangle_equivalent(Eina_Vector3 *v0, Eina_Vector3 *v1, + Eina_Vector3 *v2, Eina_Vector3 *w0, + Eina_Vector3 *w1, Eina_Vector3 *w2); + /** @} */ #include "eina_inline_vector.x"