From b7d9306c8689bdd7f37ce31ed63ce4e65fa396e2 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sat, 24 May 2014 11:42:09 +1000 Subject: Big include and libraries clean up. --- src/libraries/LumbrJack.c | 2 +- src/libraries/evas_3d_utils.h | 1557 +++++++++++++++++++++++++++++++++++++++++ src/libraries/evas_macros.h | 217 ++++++ src/libraries/love.h | 198 ++++++ src/libraries/winFang.h | 3 - 5 files changed, 1973 insertions(+), 4 deletions(-) create mode 100644 src/libraries/evas_3d_utils.h create mode 100644 src/libraries/evas_macros.h create mode 100644 src/libraries/love.h (limited to 'src/libraries') diff --git a/src/libraries/LumbrJack.c b/src/libraries/LumbrJack.c index 27ca524..9b072b0 100644 --- a/src/libraries/LumbrJack.c +++ b/src/libraries/LumbrJack.c @@ -3,8 +3,8 @@ */ -#include "LumbrJack.h" #include +#include "LumbrJack.h" static char dateTime[DATE_TIME_LEN]; diff --git a/src/libraries/evas_3d_utils.h b/src/libraries/evas_3d_utils.h new file mode 100644 index 0000000..8adc322 --- /dev/null +++ b/src/libraries/evas_3d_utils.h @@ -0,0 +1,1557 @@ +//#ifndef EVAS_PRIVATE_H +//# error You shall not include this header directly +//#endif + +#include + +#define DEGREE_TO_RADIAN(x) (((x) * M_PI) / 180.0) +#define EVAS_MATRIX_IS_IDENTITY 0x00000001 + +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_Triangle3 Evas_Triangle3; +typedef struct _Evas_Ray3 Evas_Ray3; + +struct _Evas_Color +{ + Evas_Real r; + Evas_Real g; + Evas_Real b; + Evas_Real a; +}; + +struct _Evas_Vec2 +{ + Evas_Real x; + Evas_Real y; +}; + +struct _Evas_Vec3 +{ + Evas_Real x; + Evas_Real y; + Evas_Real z; +}; + +struct _Evas_Vec4 +{ + Evas_Real x; + Evas_Real y; + Evas_Real z; + 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; + Evas_Vec2 p1; +}; + +struct _Evas_Box3 +{ + Evas_Vec3 p0; + Evas_Vec3 p1; +}; + +struct _Evas_Triangle3 +{ + Evas_Vec3 p0; + Evas_Vec3 p1; + Evas_Vec3 p2; +}; + +struct _Evas_Ray3 +{ + Evas_Vec3 org; + Evas_Vec3 dir; +}; + +/* 2D vector */ +static inline void +evas_vec2_set(Evas_Vec2 *dst, Evas_Real x, Evas_Real y) +{ + dst->x = x; + dst->y = y; +} + +static inline void +evas_vec2_array_set(Evas_Vec2 *dst, const Evas_Real *v) +{ + dst->x = v[0]; + dst->y = v[1]; +} + +static inline void +evas_vec2_copy(Evas_Vec2 *dst, const Evas_Vec2 *src) +{ + dst->x = src->x; + dst->y = src->y; +} + +static inline void +evas_vec2_negate(Evas_Vec2 *out, const Evas_Vec2 *v) +{ + out->x = -v->x; + out->y = -v->y; +} + +static inline void +evas_vec2_add(Evas_Vec2 *out, const Evas_Vec2 *a, const Evas_Vec2 *b) +{ + out->x = a->x + b->x; + out->y = a->y + b->y; +} + +static inline void +evas_vec2_subtract(Evas_Vec2 *out, const Evas_Vec2 *a, const Evas_Vec2 *b) +{ + out->x = a->x - b->x; + out->y = a->y - b->y; +} + +static inline void +evas_vec2_scale(Evas_Vec2 *out, const Evas_Vec2 *v, Evas_Real scale) +{ + out->x = scale * v->x; + out->y = scale * v->y; +} + +static inline Evas_Real +evas_vec2_dot_product(const Evas_Vec2 *a, const Evas_Vec2 *b) +{ + return (a->x * b->x) + (a->y * b->y); +} + +static inline Evas_Real +evas_vec2_length_get(const Evas_Vec2 *v) +{ + return (Evas_Real)sqrt((double)((v->x * v->x) + (v->y * v->y))); +} + +static inline Evas_Real +evas_vec2_length_square_get(const Evas_Vec2 *v) +{ + return (v->x * v->x) + (v->y * v->y); +} + +static inline Evas_Real +evas_vec2_distance_get(const Evas_Vec2 *a, const Evas_Vec2 *b) +{ + Evas_Vec2 v; + + evas_vec2_subtract(&v, a, b); + return evas_vec2_length_get(&v); +} + +static inline Evas_Real +evas_vec2_distance_square_get(const Evas_Vec2 *a, const Evas_Vec2 *b) +{ + Evas_Vec2 v; + + evas_vec2_subtract(&v, a, b); + return evas_vec2_length_square_get(&v); +} + +static inline void +evas_vec2_normalize(Evas_Vec2 *out, const Evas_Vec2 *v) +{ + /* Assume "v" is not a zero vector */ + evas_vec2_scale(out, v, 1.0 / evas_vec2_length_get(v)); +} + +static inline void +evas_vec2_transform(Evas_Vec2 *out, const Evas_Mat2 *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); + + 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 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]; + + evas_vec2_scale(out, &tmp, 1.0 / ((m->m[2] * v->x) + (m->m[5] * v->y) + m->m[8])); +} + +static inline void +evas_vec2_homogeneous_direction_transform(Evas_Vec2 *out, const Evas_Mat3 *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); + + evas_vec2_copy(out, &tmp); +} + +/* 3D vector */ +static inline void +evas_vec3_set(Evas_Vec3 *dst, Evas_Real x, Evas_Real y, Evas_Real z) +{ + dst->x = x; + dst->y = y; + dst->z = z; +} + +static inline void +evas_vec3_array_set(Evas_Vec3 *dst, const Evas_Real *v) +{ + dst->x = v[0]; + dst->y = v[1]; + dst->z = v[2]; +} + +static inline void +evas_vec3_copy(Evas_Vec3 *dst, const Evas_Vec3 *src) +{ + dst->x = src->x; + dst->y = src->y; + dst->z = src->z; +} + +static inline void +evas_vec3_negate(Evas_Vec3 *out, const Evas_Vec3 *v) +{ + out->x = -v->x; + out->y = -v->y; + out->z = -v->z; +} + +static inline void +evas_vec3_add(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b) +{ + out->x = a->x + b->x; + out->y = a->y + b->y; + out->z = a->z + b->z; +} + +static inline void +evas_vec3_subtract(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b) +{ + out->x = a->x - b->x; + out->y = a->y - b->y; + out->z = a->z - b->z; +} + +static inline void +evas_vec3_scale(Evas_Vec3 *out, const Evas_Vec3 *v, Evas_Real scale) +{ + out->x = scale * v->x; + out->y = scale * v->y; + out->z = scale * v->z; +} + +static inline void +evas_vec3_multiply(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b) +{ + out->x = a->x * b->x; + out->y = a->y * b->y; + out->z = a->z * b->z; +} + +static inline Evas_Real +evas_vec3_dot_product(const Evas_Vec3 *a, const Evas_Vec3 *b) +{ + return (a->x * b->x) + (a->y * b->y) + (a->z * b->z); +} + +static inline void +evas_vec3_cross_product(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b) +{ + Evas_Vec3 tmp; + + tmp.x = a->y * b->z - a->z * b->y; + tmp.y = a->z * b->x - a->x * b->z; + tmp.z = a->x * b->y - a->y * b->x; + + evas_vec3_copy(out, &tmp); +} + +static inline Evas_Real +evas_vec3_length_get(const Evas_Vec3 *v) +{ + return (Evas_Real)sqrt((double)((v->x * v->x) + (v->y * v->y) + (v->z * v->z))); +} + +static inline Evas_Real +evas_vec3_length_square_get(const Evas_Vec3 *v) +{ + return (v->x * v->x) + (v->y * v->y) + (v->z * v->z); +} + +static inline Evas_Real +evas_vec3_distance_get(const Evas_Vec3 *a, const Evas_Vec3 *b) +{ + Evas_Vec3 v; + + evas_vec3_subtract(&v, a, b); + return evas_vec3_length_get(&v); +} + +static inline Evas_Real +evas_vec3_distance_square_get(const Evas_Vec3 *a, const Evas_Vec3 *b) +{ + Evas_Vec3 v; + + evas_vec3_subtract(&v, a, b); + return evas_vec3_length_square_get(&v); +} + +static inline void +evas_vec3_normalize(Evas_Vec3 *out, const Evas_Vec3 *v) +{ + /* Assume "v" is not a zero vector */ + evas_vec3_scale(out, v, 1.0 / evas_vec3_length_get(v)); +} + +static inline void +evas_vec3_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Mat3 *m) +{ + Evas_Vec3 tmp; + + if (m->flags & EVAS_MATRIX_IS_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); + + 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 tmp; + + if (m->flags & EVAS_MATRIX_IS_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]; + + 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])); +} + +static inline void +evas_vec3_homogeneous_direction_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Mat4 *m) +{ + Evas_Vec3 tmp; + + if (m->flags & EVAS_MATRIX_IS_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); + + evas_vec3_copy(out, &tmp); +} + +static inline void +evas_vec3_quaternion_rotate(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Vec4 *q) +{ + Evas_Vec3 uv, uuv; + Evas_Vec3 axis; + + evas_vec3_set(&axis, q->x, q->y, q->z); + + evas_vec3_cross_product(&uv, &axis, v); + evas_vec3_cross_product(&uuv, &axis, &uv); + + evas_vec3_scale(&uv, &uv, 2.0 * q->w); + evas_vec3_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; +} + +/* 4D vector */ +static inline void +evas_vec4_set(Evas_Vec4 *dst, Evas_Real x, Evas_Real y, Evas_Real z, Evas_Real w) +{ + dst->x = x; + dst->y = y; + dst->z = z; + dst->w = w; +} + +static inline void +evas_vec4_array_set(Evas_Vec4 *dst, const Evas_Real *v) +{ + dst->x = v[0]; + dst->y = v[1]; + dst->z = v[2]; + dst->w = v[3]; +} + +static inline void +evas_vec4_copy(Evas_Vec4 *dst, const Evas_Vec4 *src) +{ + dst->x = src->x; + dst->y = src->y; + dst->z = src->z; + dst->w = src->w; +} + +static inline void +evas_vec4_homogeneous_regulate(Evas_Vec4 *out, const Evas_Vec4 *v) +{ + if (v->w != 0.0) + { + Evas_Real scale = 1.0 / v->w; + + out->x = v->x * scale; + out->y = v->y * scale; + out->z = v->z * scale; + out->w = 1.0; + } +} + +static inline void +evas_vec4_negate(Evas_Vec4 *out, const Evas_Vec4 *v) +{ + out->x = -v->x; + out->y = -v->y; + out->z = -v->z; + out->w = -v->w; +} + +static inline void +evas_vec4_add(Evas_Vec4 *out, const Evas_Vec4 *a, const Evas_Vec4 *b) +{ + out->x = a->x + b->x; + out->y = a->y + b->y; + out->z = a->z + b->z; + out->w = a->w + b->w; +} + +static inline void +evas_vec4_subtract(Evas_Vec4 *out, const Evas_Vec4 *a, const Evas_Vec4 *b) +{ + out->x = a->x - b->x; + out->y = a->y - b->y; + out->z = a->z - b->z; + out->w = a->w - b->w; +} + +static inline void +evas_vec4_scale(Evas_Vec4 *out, const Evas_Vec4 *v, Evas_Real scale) +{ + out->x = scale * v->x; + out->y = scale * v->y; + out->z = scale * v->z; + out->w = scale * v->w; +} + +static inline void +evas_vec4_multiply(Evas_Vec4 *out, const Evas_Vec4 *a, const Evas_Vec4 *b) +{ + out->x = a->x * b->x; + out->y = a->y * b->y; + out->z = a->z * b->z; + out->w = a->w * b->w; +} + +static inline Evas_Real +evas_vec4_length_get(const Evas_Vec4 *v) +{ + return (Evas_Real)sqrt((double)((v->x * v->x) + (v->y * v->y) + + (v->z * v->z) + (v->w + v->w))); +} + +static inline Evas_Real +evas_vec4_length_square_get(const Evas_Vec4 *v) +{ + return (v->x * v->x) + (v->y * v->y) + (v->z * v->z) + (v->w * v->w); +} + +static inline Evas_Real +evas_vec4_distance_get(const Evas_Vec4 *a, const Evas_Vec4 *b) +{ + Evas_Vec4 v; + + evas_vec4_subtract(&v, a, b); + return evas_vec4_length_get(&v); +} + +static inline Evas_Real +evas_vec4_distance_square_get(const Evas_Vec4 *a, const Evas_Vec4 *b) +{ + Evas_Vec4 v; + + evas_vec4_subtract(&v, a, b); + return evas_vec4_length_square_get(&v); +} + +static inline void +evas_vec4_normalize(Evas_Vec4 *out, const Evas_Vec4 *v) +{ + /* Assume "v" is not a zero vector */ + evas_vec4_scale(out, v, 1.0 / evas_vec4_length_get(v)); +} + +static inline void +evas_vec4_transform(Evas_Vec4 *out, const Evas_Vec4 *v, const Evas_Mat4 *m) +{ + Evas_Vec4 tmp; + + if (m->flags & EVAS_MATRIX_IS_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); + + evas_vec4_copy(out, &tmp); +} + +static inline void +evas_vec3_homogeneous_position_set(Evas_Vec3 *out, const Evas_Vec4 *v) +{ + /* Assume "v" is a positional vector. (v->w != 0.0) */ + Evas_Real h = 1.0 / v->w; + + out->x = v->x * h; + out->y = v->y * h; + out->z = v->z * h; +} + +static inline void +evas_vec3_homogeneous_direction_set(Evas_Vec3 *out, const Evas_Vec4 *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 void +evas_vec4_homogeneous_position_set(Evas_Vec4 *out, const Evas_Vec3 *v) +{ + out->x = v->x; + out->y = v->y; + out->z = v->z; + out->w = 1.0; +} + +static inline void +evas_vec4_homogeneous_direction_set(Evas_Vec4 *out, const Evas_Vec3 *v) +{ + out->x = v->x; + out->y = v->y; + out->z = v->z; + 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, + const Evas_Vec3 *pos, const Evas_Vec3 *center, const Evas_Vec3 *up) +{ + Evas_Vec3 x, y, z; + + evas_vec3_subtract(&z, pos, center); + evas_vec3_normalize(&z, &z); + + evas_vec3_cross_product(&x, up, &z); + evas_vec3_normalize(&x, &x); + + 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->m[ 4] = x.y; + m->m[ 5] = y.y; + m->m[ 6] = z.y; + m->m[ 7] = 0.0; + + m->m[ 8] = x.z; + m->m[ 9] = y.z; + m->m[10] = z.z; + m->m[11] = 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; +} + +static inline void +evas_mat4_frustum_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; + 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); + } +} + +/* 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); + } +} + +static inline void +evas_box2_set(Evas_Box2 *box, Evas_Real x0, Evas_Real y0, Evas_Real x1, + Evas_Real y1) +{ + box->p0.x = x0; + box->p0.y = y0; + box->p1.x = x1; + box->p1.y = y1; +} + +static inline void +evas_box3_set(Evas_Box3 *box, Evas_Real x0, Evas_Real y0, Evas_Real z0, + Evas_Real x1, Evas_Real y1, Evas_Real z1) +{ + box->p0.x = x0; + box->p0.y = y0; + box->p0.z = z0; + box->p1.x = x1; + box->p1.y = y1; + box->p1.z = z1; +} + +static inline void +evas_box3_empty_set(Evas_Box3 *box) +{ + evas_vec3_set(&box->p0, 0.0, 0.0, 0.0); + evas_vec3_set(&box->p1, 0.0, 0.0, 0.0); +} + +static inline void +evas_box3_copy(Evas_Box3 *dst, const Evas_Box3 *src) +{ + evas_vec3_copy(&dst->p0, &src->p0); + evas_vec3_copy(&dst->p1, &src->p1); +} + +static inline void +evas_box3_union(Evas_Box3 *out, const Evas_Box3 *a, const Evas_Box3 *b) +{ + evas_vec3_set(&out->p0, MIN(a->p0.x, b->p0.x), MIN(a->p0.y, b->p0.y), MIN(a->p0.z, b->p0.z)); + evas_vec3_set(&out->p1, MAX(a->p1.x, b->p1.x), MAX(a->p1.y, b->p1.y), MAX(a->p1.z, b->p1.z)); +} + +static inline void +evas_box3_transform(Evas_Box3 *out EINA_UNUSED, const Evas_Box3 *box EINA_UNUSED, const Evas_Mat4 *mat EINA_UNUSED) +{ + /* TODO: */ +} + +static inline void +evas_mat4_position_get(const Evas_Mat4 *matrix, Evas_Vec4 *position) +{ + Evas_Vec4 pos; + + pos.x = 0.0; + pos.y = 0.0; + pos.z = 0.0; + pos.w = 1.0; + + evas_vec4_transform(position, &pos, matrix); +} + +static inline void +evas_mat4_direction_get(const Evas_Mat4 *matrix, Evas_Vec3 *direction) +{ + /* TODO: Check correctness. */ + + Evas_Vec4 dir; + + dir.x = 0.0; + dir.y = 0.0; + dir.z = 1.0; + dir.w = 1.0; + + evas_vec4_transform(&dir, &dir, matrix); + + direction->x = dir.x; + direction->y = dir.y; + direction->z = dir.z; +} + +static inline void +evas_vec4_quaternion_multiply(Evas_Vec4 *out, const Evas_Vec4 *a, const Evas_Vec4 *b) +{ + Evas_Vec4 r; + + r.x = (a->w * b->x) + (a->x * b->w) + (a->y * b->z) - (a->z * b->y); + r.y = (a->w * b->y) - (a->x * b->z) + (a->y * b->w) + (a->z * b->x); + r.z = (a->w * b->z) + (a->x * b->y) - (a->y * b->x) + (a->z * b->w); + r.w = (a->w * b->w) - (a->x * b->x) - (a->y * b->y) - (a->z * b->z); + + *out = r; +} + +static inline void +evas_vec4_quaternion_inverse(Evas_Vec4 *out, const Evas_Vec4 *q) +{ + Evas_Real norm = (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w); + + if (norm > 0.0) + { + Evas_Real inv_norm = 1.0 / norm; + out->x = -q->x * inv_norm; + out->y = -q->y * inv_norm; + out->z = -q->z * inv_norm; + out->w = q->w * inv_norm; + } + else + { + out->x = 0.0; + out->y = 0.0; + out->z = 0.0; + out->w = 0.0; + } +} + +static inline void +evas_vec4_quaternion_rotation_matrix_get(const Evas_Vec4 *q, Evas_Mat3 *mat) +{ + Evas_Real x, y, z; + Evas_Real xx, xy, xz; + Evas_Real yy, yz; + Evas_Real zz; + Evas_Real wx, wy, wz; + + x = 2.0 * q->x; + y = 2.0 * q->y; + z = 2.0 * q->z; + + xx = q->x * x; + xy = q->x * y; + xz = q->x * z; + + yy = q->y * y; + yz = q->y * z; + + zz = q->z * z; + + wx = q->w * x; + 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; +} + +static inline void +evas_mat4_build(Evas_Mat4 *out, + const Evas_Vec3 *position, const Evas_Vec4 *orientation, const Evas_Vec3 *scale) +{ + Evas_Mat3 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->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->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->m[12] = position->x; + out->m[13] = position->y; + out->m[14] = position->z; + out->m[15] = 1.0; +} + +static inline void +evas_mat4_inverse_build(Evas_Mat4 *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; + + /* Inverse scale. */ + evas_vec3_set(&inv_scale, 1.0 / scale->x, 1.0 / scale->y, 1.0 / scale->z); + + /* Inverse rotation. */ + evas_vec4_quaternion_inverse(&inv_rotation, orientation); + + /* Inverse translation. */ + evas_vec3_negate(&inv_translate, position); + evas_vec3_quaternion_rotate(&inv_translate, &inv_translate, &inv_rotation); + evas_vec3_multiply(&inv_translate, &inv_translate, &inv_scale); + + /* 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->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->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->m[12] = inv_translate.x; + out->m[13] = inv_translate.y; + out->m[14] = inv_translate.z; + out->m[15] = 1.0; +} + +static inline void +evas_color_set(Evas_Color *color, Evas_Real r, Evas_Real g, Evas_Real b, Evas_Real a) +{ + color->r = r; + color->g = g; + color->b = b; + color->a = a; +} + +static inline void +evas_color_blend(Evas_Color *dst, const Evas_Color *c0, const Evas_Color *c1, Evas_Real w) +{ + dst->r = c0->r * w + c1->r * (1.0 - w); + dst->g = c0->g * w + c1->g * (1.0 - w); + dst->b = c0->b * w + c1->b * (1.0 - w); + dst->a = c0->a * w + c1->a * (1.0 - w); +} + +static inline void +evas_ray3_init(Evas_Ray3 *ray, Evas_Real x, Evas_Real y, const Evas_Mat4 *mvp) +{ + Evas_Mat4 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); + + /* Transform near point. */ + dnear.x = x; + dnear.y = y; + dnear.z = -1.0; + dnear.w = 1.0; + + evas_vec4_transform(&dnear, &dnear, &mat); + + dnear.w = 1.0 / dnear.w; + dnear.x *= dnear.w; + dnear.y *= dnear.w; + dnear.z *= dnear.w; + + evas_vec3_set(&ray->org, dnear.x, dnear.y, dnear.z); + + /* Transform far point. */ + dfar.x = x; + dfar.y = y; + dfar.z = 1.0; + dfar.w = 1.0; + + evas_vec4_transform(&dfar, &dfar, &mat); + + dfar.w = 1.0 / dfar.w; + dfar.x *= dfar.w; + dfar.y *= dfar.w; + dfar.z *= dfar.w; + + evas_vec3_set(&ray->dir, dfar.x - dnear.x, dfar.y - dnear.y, dfar.z - dnear.z); +} + +static inline Eina_Bool +evas_box3_ray3_intersect(const Evas_Box3 *box EINA_UNUSED, const Evas_Ray3 *ray EINA_UNUSED) +{ + /* TODO: */ + return EINA_TRUE; +} + +static inline Evas_Real +evas_reciprocal_sqrt(Evas_Real x) +{ + union { + float f; + long i; + } u; + + u.f = x; + u.i = 0x5f3759df - (u.i >> 1); + return u.f * (1.5f - u.f * u.f * x * 0.5f); +} diff --git a/src/libraries/evas_macros.h b/src/libraries/evas_macros.h new file mode 100644 index 0000000..ed29dbd --- /dev/null +++ b/src/libraries/evas_macros.h @@ -0,0 +1,217 @@ +#ifndef EVAS_MACROS_H +#define EVAS_MACROS_H + +#undef ABS +#define ABS(x) (((x) < 0) ? -(x) : (x)) + +#undef SGN +#define SGN(x) (((x) < 0) ? -1 : 1) + +#undef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +#undef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#define SWAP32(x) (x) = \ + ((((x) & 0x000000ff ) << 24) | \ + (((x) & 0x0000ff00 ) << 8) | \ + (((x) & 0x00ff0000 ) >> 8) | \ + (((x) & 0xff000000 ) >> 24)) + +#define SWAP16(x) (x) = \ + ((((x) & 0x00ff ) << 8) | \ + (((x) & 0xff00 ) >> 8)) + +#define SPANS_COMMON(x1, w1, x2, w2) \ +(!(( (int)((x2) + (int)(w2)) <= (int)(x1)) || (int)((x2) >= (int)((x1) + (int)(w1))))) + +#define RECTS_INTERSECT(x, y, w, h, xx, yy, ww, hh) \ +((SPANS_COMMON((x), (w), (xx), (ww))) && (SPANS_COMMON((y), (h), (yy), (hh)))) + +#define RECTS_CLIP_TO_RECT(_x, _y, _w, _h, _cx, _cy, _cw, _ch) \ +{ \ + if (RECTS_INTERSECT(_x, _y, _w, _h, _cx, _cy, _cw, _ch)) \ + { \ + if ((int)_x < (int)(_cx)) \ + { \ + if ((int)_w + ((int)_x - (int)(_cx)) < 0) _w = 0; \ + else _w += ((int)_x - (int)(_cx)); \ + _x = (_cx); \ + } \ + if ((int)(_x + _w) > (int)((_cx) + (_cw))) \ + _w = (_cx) + (_cw) - _x; \ + if ((int)_y < (int)(_cy)) \ + { \ + if ((int)_h + ((int)_y - (int)(_cy)) < 0) _h = 0; \ + else _h += ((int)_y - (int)(_cy)); \ + _y = (_cy); \ + } \ + if ((int)(_y + _h) > (int)((_cy) + (_ch))) \ + _h = (_cy) + (_ch) - _y; \ + } \ + else \ + { \ + _w = 0; _h = 0; \ + } \ +} + + +#define INTERP_VAL(out, in1, in2, in3, in4, interp_x, interp_y) \ + { \ + int _v, _vv; \ + \ + _v = (256 - (interp_x)) * (in1); \ + if ((interp_x) > 0) _v += (interp_x) * (in2); \ + _v *= (256 - (interp_y)); \ + if ((interp_y) > 0) \ + { \ + _vv = (256 - (interp_x)) * (in3); \ + if ((interp_x) > 0) _vv += (interp_x) * (in4); \ + _vv *= (interp_y); \ + (out) = ((_v + _vv) >> 16); \ + } \ + else (out) = (_v >> 16); \ + } + +#define INTERP_2(in1, in2, interp, interp_inv) \ + ((in1 * interp_inv) + (in2 * interp)) >> 8 + + +#define CONVERT_LOOP_START_ROT_0() \ + src_ptr = src; \ + for (y = 0; y < h; y++) \ + { \ + for (x = 0; x < w; x++) \ + { + +#define CONVERT_LOOP_END_ROT_0() \ + dst_ptr++; \ + src_ptr++; \ + } \ + src_ptr += src_jump; \ + dst_ptr += dst_jump; \ + } + +#define CONVERT_LOOP_START_ROT_180() \ + src_ptr = src + (w - 1) + ((h - 1) * (w + src_jump)); \ + for (y = 0; y < h; y++) \ + { \ + for (x = 0; x < w; x++) \ + { + +#define CONVERT_LOOP_END_ROT_180() \ + dst_ptr++; \ + src_ptr--; \ + } \ + src_ptr = src + (w - 1) + ((h - y - 2) * (w + src_jump)); \ + dst_ptr += dst_jump; \ + } + +#define CONVERT_LOOP_START_ROT_270() \ + src_ptr = src + ((w - 1) * (h + src_jump)); \ + for (y = 0; y < h; y++) \ + { \ + for (x = 0; x < w; x++) \ + { + +#define CONVERT_LOOP_END_ROT_270() \ + dst_ptr++; \ + src_ptr -= (h + src_jump); \ + } \ + src_ptr = src + ((w - 1) * (h + src_jump)) + (y + 1); \ + dst_ptr += dst_jump; \ + } + +#define CONVERT_LOOP_START_ROT_90() \ + src_ptr = src + (h - 1); \ + for (y = 0; y < h; y++) \ + { \ + for (x = 0; x < w; x++) \ + { + +#define CONVERT_LOOP_END_ROT_90() \ + dst_ptr++; \ + src_ptr += (h + src_jump); \ + } \ + src_ptr = src + (h - 1) - y - 1; \ + dst_ptr += dst_jump; \ + } + +#define CONVERT_LOOP2_START_ROT_0() \ + src_ptr = src; \ + for (y = 0; y < h; y++) \ + { \ + for (x = 0; x < w; x++) \ + { + +#define CONVERT_LOOP2_INC_ROT_0() \ +src_ptr++; \ +x++; + +#define CONVERT_LOOP2_END_ROT_0() \ + dst_ptr+=2; \ + src_ptr++; \ + } \ + src_ptr += src_jump; \ + dst_ptr += dst_jump; \ + } + +#define CONVERT_LOOP2_START_ROT_180() \ + src_ptr = src + (w - 1) + ((h - 1) * (w + src_jump)); \ + for (y = 0; y < h; y++) \ + { \ + for (x = 0; x < w; x++) \ + { + +#define CONVERT_LOOP2_INC_ROT_180() \ +src_ptr--; \ +x++; + +#define CONVERT_LOOP2_END_ROT_180() \ + dst_ptr+=2; \ + src_ptr--; \ + } \ + src_ptr = src + (w - 1) + ((h - y - 2) * (w + src_jump)); \ + dst_ptr += dst_jump; \ + } + +#define CONVERT_LOOP2_START_ROT_270() \ + src_ptr = src + ((w - 1) * (h + src_jump)); \ + for (y = 0; y < h; y++) \ + { \ + for (x = 0; x < w; x++) \ + { + +#define CONVERT_LOOP2_INC_ROT_270() \ +src_ptr -= (h + src_jump); \ +x++; + +#define CONVERT_LOOP2_END_ROT_270() \ + dst_ptr+=2; \ + src_ptr -= (h + src_jump); \ + } \ + src_ptr = src + ((w - 1) * (h + src_jump)) + (y + 1); \ + dst_ptr += dst_jump; \ + } + +#define CONVERT_LOOP2_START_ROT_90() \ + src_ptr = src + (h - 1); \ + for (y = 0; y < h; y++) \ + { \ + for (x = 0; x < w; x++) \ + { + +#define CONVERT_LOOP2_INC_ROT_90() \ +src_ptr += (h + src_jump); \ +x++; + +#define CONVERT_LOOP2_END_ROT_90() \ + dst_ptr+=2; \ + src_ptr += (h + src_jump); \ + } \ + src_ptr = src + (h - 1) - y - 1; \ + dst_ptr += dst_jump; \ + } + +#endif diff --git a/src/libraries/love.h b/src/libraries/love.h new file mode 100644 index 0000000..5964cde --- /dev/null +++ b/src/libraries/love.h @@ -0,0 +1,198 @@ +#ifndef _LOVE_H_ +#define _LOVE_H_ + + + +/* + +What do we need as an internal world object format? + +Can't call it Things, that's taken already. + +"Stuffs" works though. B-) + +Love server needs to manage in world stuffs, and send changes to everyone. + +Extantz needs to manage what's shown in world, and edit that stuffs. + +Combining the data structures seems sane. Letting the love server +define those data structures also seems sane, hence this file. + + +Extantz needs - + what it looks like (Evas_3D stuff) + "link sets" + what is attached to what + mesh + vertices, triangles, ... + local position and orientation relative to parent + material + textures + colours, including alpha + light + shade mode + where it is + position, orientation + animation stuff + + +common + UUID + name & description + owner + position, orientation + "link sets" + + +love needs + UUID + name & description + owner + position, orientation + "link sets" + LL used a list of prims, we can do better I'm sure. + Though for the sake of this experimental version, just use an array of stuffs. + contents + scripts, cards, other stuffs, animations, sounds, textures, ... + content types + +*/ + + +/* Stuffs is a single "primitive" object, it can be - + single mesh object - NOTE: Should include a list of materials. + LL style prim, including tree, defined as a small bunch of data defining the type and parameters + LL style mesh "file" + single mesh file, collada, other mesh format + height field, for land, or water + LuaSL script + "notecard", just a text file, with no limits + animation, BVH, Alice's BVJ, or perhaps any other animation file format + sounds, MP3, other sound formats + textures, PNG, JPEG, JPEG2000, TIFF, GIF, other texture formats + other LL stuff + landmark + clothing + body part, shape, skin, hair, or eyes + gesture + calling card +*/ + +#include "evas_macros.h" +#include "evas_3d_utils.h" // TODO - Hopefully I can convince the authors to make this public. + +#include "Runnr.h" + + +typedef struct _vec4 +{ + float x; + float y; + float z; + float w; +} vec4; + +typedef struct _vec3 +{ + float x; + float y; + float z; +} vec3; + +typedef struct _vec2 +{ + float x; + float y; +} vec2; + + +typedef struct _material +{ + int face; + //type? + char texture[PATH_MAX]; + //colour + //alpha + //other stuff +} Material; + +typedef struct _mesh +{ + char fileName[PATH_MAX]; + //type + vec3 pos; + vec4 rot; + Eina_Inarray materials; // Material + Eina_Inarray parts; // Mesh +} Mesh; + +typedef struct _stuffs +{ + char UUID[32], *name, *description, owner[32]; + //type + union + { + Mesh *mesh; + script *scrip; // Not a typo, C++ is fussy about reusing names like this. + void *other; + } details; +} Stuffs; + + +typedef struct _loveStuffs +{ + Stuffs stuffs; + Eina_Inarray contents; // Stuffs +} LoveStuffs; + +typedef struct _extantzStuffs +{ + Stuffs stuffs; +// Evas_3D_Mesh *mesh; +// Evas_3D_Node *mesh_node; // Multiple Evas_3D_Mesh's can be in one Evas_3D_Node + Eina_Inarray *materials; // Evas_3D_Material + Eina_Inarray *textures; // Evas_3D_Texture +} ExtantzStuffs; + + +/* Data flow + +love server starts up + scans sim disk structure looking for scripts in stuffs + keep track of which script is in which stuffs + -> LuaSL compile script + -> LuaSL load this saved state + -> LuaSL run script + +Extantz client starts up + -> love login(name, password) + loads user details + <- love this is your user uuid + get sim details from lspace at this URL (or local disk directory file://) + -> lspace gimme the sim (or just pick up the index.omg file from disk) + <- lspace index.omg + figure out which mesh stuffs to load + -> lspace gimme(uuid) (or load it from disk) + <- lspace uuid.omg + figure out which mesh and texture files to load + -> lspace gimme this mesh file (or load it from disk) + <- lspace mesh file + -> lspace gimme this texture file (or load it from disk) + <- lspace texture file + + user clicks on in world stuffs + -> love touched(user uuid, stuffs.uuid) + looks up stuffs, loops through scripts + -> LuaSL script.uuid.touch_start() and the detected stuff + + user edits stuffs in world + -> love get contents(stuffs.uuid) + loads stuffs.omg from disk + loads stuffs.index.omg + <- love here's the list of contents Stuffs + -> love change this bit + changes that bit and stores on disk + send update nails commands to everyone/thing watching +*/ + +#endif diff --git a/src/libraries/winFang.h b/src/libraries/winFang.h index 7a84a7e..f2aebfd 100644 --- a/src/libraries/winFang.h +++ b/src/libraries/winFang.h @@ -2,9 +2,6 @@ #define _WINFANG_H_ -#include -#include -#include #include #include -- cgit v1.1