aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-02-06 13:12:39 +1000
committerDavid Walter Seikel2016-02-06 13:12:39 +1000
commited42be570bb7e6bd803c864ed56caa1e035fb9d0 (patch)
tree1302e1b8fb726e9f1429507bc38c3f0dcdfb12d5
parentMove return() to the hashed commands. (diff)
downloadSledjHamr-ed42be570bb7e6bd803c864ed56caa1e035fb9d0.zip
SledjHamr-ed42be570bb7e6bd803c864ed56caa1e035fb9d0.tar.gz
SledjHamr-ed42be570bb7e6bd803c864ed56caa1e035fb9d0.tar.bz2
SledjHamr-ed42be570bb7e6bd803c864ed56caa1e035fb9d0.tar.xz
Switch to eina_quaternion, instead of the copy pasted, coz it's hidden, evas_vec3 stuff.
-rw-r--r--src/extantz/camera.c71
-rw-r--r--src/libraries/evas_3d_utils.h1557
-rw-r--r--src/libraries/love.h1
3 files changed, 25 insertions, 1604 deletions
diff --git a/src/extantz/camera.c b/src/extantz/camera.c
index 123285c..9a28b15 100644
--- a/src/extantz/camera.c
+++ b/src/extantz/camera.c
@@ -1,15 +1,19 @@
1#include "extantz.h" 1#include "extantz.h"
2 2
3 3
4static inline void evas_euler_to_quaternion(Evas_Vec4 *out, Evas_Vec3 *in) 4
5#define DEGREE_TO_RADIAN(x) (((x) * M_PI) / 180.0)
6
7
8static inline void euler_to_quaternion(Eina_Quaternion *out, Evas_Real x, Evas_Real y, Evas_Real z)
5{ 9{
6 // Assuming the angles are in radians. 10 // Assuming the angles are in radians.
7 Evas_Real c1 = cos(in->y / 2.0); // heading (yaw/spin) .. y 11 Evas_Real c1 = cos(y / 2.0); // heading (yaw/spin) .. y
8 Evas_Real s1 = sin(in->y / 2.0); 12 Evas_Real s1 = sin(y / 2.0);
9 Evas_Real c2 = cos(in->z / 2.0); // attitude (pitch) .. x 13 Evas_Real c2 = cos(z / 2.0); // attitude (pitch) .. x
10 Evas_Real s2 = sin(in->z / 2.0); 14 Evas_Real s2 = sin(z / 2.0);
11 Evas_Real c3 = cos(in->x / 2.0); // bank (roll) .. z 15 Evas_Real c3 = cos(x / 2.0); // bank (roll) .. z
12 Evas_Real s3 = sin(in->x / 2.0); 16 Evas_Real s3 = sin(x / 2.0);
13 Evas_Real c1c2 = c1 * c2; 17 Evas_Real c1c2 = c1 * c2;
14 Evas_Real s1s2 = s1 * s2; 18 Evas_Real s1s2 = s1 * s2;
15 19
@@ -19,52 +23,27 @@ static inline void evas_euler_to_quaternion(Evas_Vec4 *out, Evas_Vec3 *in)
19 out->z =c1 * s2 * c3 - s1 * c2 * s3; 23 out->z =c1 * s2 * c3 - s1 * c2 * s3;
20} 24}
21 25
22static inline void evas_quaternion_normalise(Evas_Vec4 *in)
23{
24 Evas_Real n = sqrt(in->x * in->x + in->y * in->y + in->z * in->z + in->w * in->w);
25 in->x /= n;
26 in->y /= n;
27 in->z /= n;
28 in->w /= n;
29}
30
31static inline void evas_quaternion_multiply(Evas_Vec4 *out, const Evas_Vec4 *q1, const Evas_Vec4 *q2)
32{
33 out->x = q1->x * q2->w + q1->y * q2->z - q1->z * q2->y + q1->w * q2->x;
34 out->y = -q1->x * q2->z + q1->y * q2->w + q1->z * q2->x + q1->w * q2->y;
35 out->z = q1->x * q2->y - q1->y * q2->x + q1->z * q2->w + q1->w * q2->z;
36 out->w = -q1->x * q2->x - q1->y * q2->y - q1->z * q2->z + q1->w * q2->w;
37}
38
39static inline void evas_quaternion_conjugate(Evas_Vec4 *in)
40{
41 in->x = -in->x;
42 in->y = -in->y;
43 in->z = -in->z;
44 in->w = in->w;
45}
46 26
47Eina_Bool animateCamera(Scene_Data *scene) 27Eina_Bool animateCamera(Scene_Data *scene)
48{ 28{
49 Evas_Vec3 pos, rotate; 29 Eina_Quaternion rotate, orient, result, move;
50 Evas_Vec4 orient, rotateQ, result, move; 30 Evas_Real x, y, z;
51 31
52 evas_vec3_set(&rotate, DEGREE_TO_RADIAN(scene->move->r), DEGREE_TO_RADIAN(scene->move->s), DEGREE_TO_RADIAN(scene->move->p));
53 eo_do(scene->camera_node, evas_canvas3d_node_orientation_get(EVAS_CANVAS3D_SPACE_PARENT, &orient.x, &orient.y, &orient.z, &orient.w)); 32 eo_do(scene->camera_node, evas_canvas3d_node_orientation_get(EVAS_CANVAS3D_SPACE_PARENT, &orient.x, &orient.y, &orient.z, &orient.w));
54 evas_euler_to_quaternion(&rotateQ, &rotate); 33 euler_to_quaternion(&rotate, DEGREE_TO_RADIAN(scene->move->r), DEGREE_TO_RADIAN(scene->move->s), DEGREE_TO_RADIAN(scene->move->p));
55 evas_quaternion_multiply(&result, &orient, &rotateQ); 34 eina_quaternion_mul(&result, &orient, &rotate);
56 evas_quaternion_normalise(&result); 35 eina_quaternion_normalized(&result, &result);
57 eo_do(scene->camera_node, evas_canvas3d_node_orientation_set(result.x, result.y, result.z, result.w)); 36 eo_do(scene->camera_node, evas_canvas3d_node_orientation_set(result.x, result.y, result.z, result.w));
58 37
59 evas_vec4_set(&move, scene->move->x, scene->move->y, scene->move->z, 0); 38 eina_quaternion_set(&move, scene->move->x, scene->move->y, scene->move->z, 0);
60 eo_do(scene->camera_node, evas_canvas3d_node_position_get(EVAS_CANVAS3D_SPACE_PARENT, &pos.x, &pos.y, &pos.z)); 39 eo_do(scene->camera_node, evas_canvas3d_node_position_get(EVAS_CANVAS3D_SPACE_PARENT, &x, &y, &z));
61 evas_quaternion_multiply(&rotateQ, &result, &move); 40 eina_quaternion_mul(&rotate, &result, &move);
62 evas_quaternion_conjugate(&result); 41 eina_quaternion_conjugate(&result, &result);
63 evas_quaternion_multiply(&move, &rotateQ, &result); 42 eina_quaternion_mul(&move, &rotate, &result);
64 pos.x += move.x; 43 x += move.x;
65 pos.y += move.y; 44 y += move.y;
66 pos.z += move.z; 45 z += move.z;
67 eo_do(scene->camera_node, evas_canvas3d_node_position_set(pos.x, pos.y, pos.z)); 46 eo_do(scene->camera_node, evas_canvas3d_node_position_set(x, y, z));
68 47
69 return EINA_TRUE; 48 return EINA_TRUE;
70} 49}
diff --git a/src/libraries/evas_3d_utils.h b/src/libraries/evas_3d_utils.h
deleted file mode 100644
index 8adc322..0000000
--- a/src/libraries/evas_3d_utils.h
+++ /dev/null
@@ -1,1557 +0,0 @@
1//#ifndef EVAS_PRIVATE_H
2//# error You shall not include this header directly
3//#endif
4
5#include <math.h>
6
7#define DEGREE_TO_RADIAN(x) (((x) * M_PI) / 180.0)
8#define EVAS_MATRIX_IS_IDENTITY 0x00000001
9
10typedef struct _Evas_Color Evas_Color;
11typedef struct _Evas_Vec2 Evas_Vec2;
12typedef struct _Evas_Vec3 Evas_Vec3;
13typedef struct _Evas_Vec4 Evas_Vec4;
14typedef struct _Evas_Mat2 Evas_Mat2;
15typedef struct _Evas_Mat3 Evas_Mat3;
16typedef struct _Evas_Mat4 Evas_Mat4;
17typedef struct _Evas_Box2 Evas_Box2;
18typedef struct _Evas_Box3 Evas_Box3;
19typedef struct _Evas_Triangle3 Evas_Triangle3;
20typedef struct _Evas_Ray3 Evas_Ray3;
21
22struct _Evas_Color
23{
24 Evas_Real r;
25 Evas_Real g;
26 Evas_Real b;
27 Evas_Real a;
28};
29
30struct _Evas_Vec2
31{
32 Evas_Real x;
33 Evas_Real y;
34};
35
36struct _Evas_Vec3
37{
38 Evas_Real x;
39 Evas_Real y;
40 Evas_Real z;
41};
42
43struct _Evas_Vec4
44{
45 Evas_Real x;
46 Evas_Real y;
47 Evas_Real z;
48 Evas_Real w;
49};
50
51struct _Evas_Mat2
52{
53 Evas_Real m[4];
54 int flags;
55};
56
57struct _Evas_Mat3
58{
59 Evas_Real m[9];
60 int flags;
61};
62
63struct _Evas_Mat4
64{
65 Evas_Real m[16];
66 int flags;
67};
68
69struct _Evas_Box2
70{
71 Evas_Vec2 p0;
72 Evas_Vec2 p1;
73};
74
75struct _Evas_Box3
76{
77 Evas_Vec3 p0;
78 Evas_Vec3 p1;
79};
80
81struct _Evas_Triangle3
82{
83 Evas_Vec3 p0;
84 Evas_Vec3 p1;
85 Evas_Vec3 p2;
86};
87
88struct _Evas_Ray3
89{
90 Evas_Vec3 org;
91 Evas_Vec3 dir;
92};
93
94/* 2D vector */
95static inline void
96evas_vec2_set(Evas_Vec2 *dst, Evas_Real x, Evas_Real y)
97{
98 dst->x = x;
99 dst->y = y;
100}
101
102static inline void
103evas_vec2_array_set(Evas_Vec2 *dst, const Evas_Real *v)
104{
105 dst->x = v[0];
106 dst->y = v[1];
107}
108
109static inline void
110evas_vec2_copy(Evas_Vec2 *dst, const Evas_Vec2 *src)
111{
112 dst->x = src->x;
113 dst->y = src->y;
114}
115
116static inline void
117evas_vec2_negate(Evas_Vec2 *out, const Evas_Vec2 *v)
118{
119 out->x = -v->x;
120 out->y = -v->y;
121}
122
123static inline void
124evas_vec2_add(Evas_Vec2 *out, const Evas_Vec2 *a, const Evas_Vec2 *b)
125{
126 out->x = a->x + b->x;
127 out->y = a->y + b->y;
128}
129
130static inline void
131evas_vec2_subtract(Evas_Vec2 *out, const Evas_Vec2 *a, const Evas_Vec2 *b)
132{
133 out->x = a->x - b->x;
134 out->y = a->y - b->y;
135}
136
137static inline void
138evas_vec2_scale(Evas_Vec2 *out, const Evas_Vec2 *v, Evas_Real scale)
139{
140 out->x = scale * v->x;
141 out->y = scale * v->y;
142}
143
144static inline Evas_Real
145evas_vec2_dot_product(const Evas_Vec2 *a, const Evas_Vec2 *b)
146{
147 return (a->x * b->x) + (a->y * b->y);
148}
149
150static inline Evas_Real
151evas_vec2_length_get(const Evas_Vec2 *v)
152{
153 return (Evas_Real)sqrt((double)((v->x * v->x) + (v->y * v->y)));
154}
155
156static inline Evas_Real
157evas_vec2_length_square_get(const Evas_Vec2 *v)
158{
159 return (v->x * v->x) + (v->y * v->y);
160}
161
162static inline Evas_Real
163evas_vec2_distance_get(const Evas_Vec2 *a, const Evas_Vec2 *b)
164{
165 Evas_Vec2 v;
166
167 evas_vec2_subtract(&v, a, b);
168 return evas_vec2_length_get(&v);
169}
170
171static inline Evas_Real
172evas_vec2_distance_square_get(const Evas_Vec2 *a, const Evas_Vec2 *b)
173{
174 Evas_Vec2 v;
175
176 evas_vec2_subtract(&v, a, b);
177 return evas_vec2_length_square_get(&v);
178}
179
180static inline void
181evas_vec2_normalize(Evas_Vec2 *out, const Evas_Vec2 *v)
182{
183 /* Assume "v" is not a zero vector */
184 evas_vec2_scale(out, v, 1.0 / evas_vec2_length_get(v));
185}
186
187static inline void
188evas_vec2_transform(Evas_Vec2 *out, const Evas_Mat2 *m, const Evas_Vec2 *v)
189{
190 Evas_Vec2 tmp;
191
192 tmp.x = (m->m[0] * v->x) + (m->m[2] * v->y);
193 tmp.y = (m->m[1] * v->x) + (m->m[3] * v->y);
194
195 evas_vec2_copy(out, &tmp);
196}
197
198static inline void
199evas_vec2_homogeneous_position_transform(Evas_Vec2 *out, const Evas_Mat3 *m, const Evas_Vec2 *v)
200{
201 Evas_Vec2 tmp;
202
203 tmp.x = (m->m[0] * v->x) + (m->m[3] * v->y) + m->m[6];
204 tmp.y = (m->m[1] * v->x) + (m->m[4] * v->y) + m->m[7];
205
206 evas_vec2_scale(out, &tmp, 1.0 / ((m->m[2] * v->x) + (m->m[5] * v->y) + m->m[8]));
207}
208
209static inline void
210evas_vec2_homogeneous_direction_transform(Evas_Vec2 *out, const Evas_Mat3 *m, const Evas_Vec2 *v)
211{
212 Evas_Vec2 tmp;
213
214 tmp.x = (m->m[0] * v->x) + (m->m[3] * v->y);
215 tmp.y = (m->m[1] * v->x) + (m->m[4] * v->y);
216
217 evas_vec2_copy(out, &tmp);
218}
219
220/* 3D vector */
221static inline void
222evas_vec3_set(Evas_Vec3 *dst, Evas_Real x, Evas_Real y, Evas_Real z)
223{
224 dst->x = x;
225 dst->y = y;
226 dst->z = z;
227}
228
229static inline void
230evas_vec3_array_set(Evas_Vec3 *dst, const Evas_Real *v)
231{
232 dst->x = v[0];
233 dst->y = v[1];
234 dst->z = v[2];
235}
236
237static inline void
238evas_vec3_copy(Evas_Vec3 *dst, const Evas_Vec3 *src)
239{
240 dst->x = src->x;
241 dst->y = src->y;
242 dst->z = src->z;
243}
244
245static inline void
246evas_vec3_negate(Evas_Vec3 *out, const Evas_Vec3 *v)
247{
248 out->x = -v->x;
249 out->y = -v->y;
250 out->z = -v->z;
251}
252
253static inline void
254evas_vec3_add(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b)
255{
256 out->x = a->x + b->x;
257 out->y = a->y + b->y;
258 out->z = a->z + b->z;
259}
260
261static inline void
262evas_vec3_subtract(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b)
263{
264 out->x = a->x - b->x;
265 out->y = a->y - b->y;
266 out->z = a->z - b->z;
267}
268
269static inline void
270evas_vec3_scale(Evas_Vec3 *out, const Evas_Vec3 *v, Evas_Real scale)
271{
272 out->x = scale * v->x;
273 out->y = scale * v->y;
274 out->z = scale * v->z;
275}
276
277static inline void
278evas_vec3_multiply(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b)
279{
280 out->x = a->x * b->x;
281 out->y = a->y * b->y;
282 out->z = a->z * b->z;
283}
284
285static inline Evas_Real
286evas_vec3_dot_product(const Evas_Vec3 *a, const Evas_Vec3 *b)
287{
288 return (a->x * b->x) + (a->y * b->y) + (a->z * b->z);
289}
290
291static inline void
292evas_vec3_cross_product(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b)
293{
294 Evas_Vec3 tmp;
295
296 tmp.x = a->y * b->z - a->z * b->y;
297 tmp.y = a->z * b->x - a->x * b->z;
298 tmp.z = a->x * b->y - a->y * b->x;
299
300 evas_vec3_copy(out, &tmp);
301}
302
303static inline Evas_Real
304evas_vec3_length_get(const Evas_Vec3 *v)
305{
306 return (Evas_Real)sqrt((double)((v->x * v->x) + (v->y * v->y) + (v->z * v->z)));
307}
308
309static inline Evas_Real
310evas_vec3_length_square_get(const Evas_Vec3 *v)
311{
312 return (v->x * v->x) + (v->y * v->y) + (v->z * v->z);
313}
314
315static inline Evas_Real
316evas_vec3_distance_get(const Evas_Vec3 *a, const Evas_Vec3 *b)
317{
318 Evas_Vec3 v;
319
320 evas_vec3_subtract(&v, a, b);
321 return evas_vec3_length_get(&v);
322}
323
324static inline Evas_Real
325evas_vec3_distance_square_get(const Evas_Vec3 *a, const Evas_Vec3 *b)
326{
327 Evas_Vec3 v;
328
329 evas_vec3_subtract(&v, a, b);
330 return evas_vec3_length_square_get(&v);
331}
332
333static inline void
334evas_vec3_normalize(Evas_Vec3 *out, const Evas_Vec3 *v)
335{
336 /* Assume "v" is not a zero vector */
337 evas_vec3_scale(out, v, 1.0 / evas_vec3_length_get(v));
338}
339
340static inline void
341evas_vec3_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Mat3 *m)
342{
343 Evas_Vec3 tmp;
344
345 if (m->flags & EVAS_MATRIX_IS_IDENTITY)
346 {
347 evas_vec3_copy(out, v);
348 return;
349 }
350
351 tmp.x = (m->m[0] * v->x) + (m->m[3] * v->y) + (m->m[6] * v->z);
352 tmp.y = (m->m[1] * v->x) + (m->m[4] * v->y) + (m->m[7] * v->z);
353 tmp.z = (m->m[2] * v->x) + (m->m[5] * v->y) + (m->m[8] * v->z);
354
355 evas_vec3_copy(out, &tmp);
356}
357
358static inline void
359evas_vec3_homogeneous_position_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Mat4 *m)
360{
361 Evas_Vec3 tmp;
362
363 if (m->flags & EVAS_MATRIX_IS_IDENTITY)
364 {
365 evas_vec3_copy(out, v);
366 return;
367 }
368
369 tmp.x = (m->m[0] * v->x) + (m->m[4] * v->y) + (m->m[8] * v->z) + m->m[12];
370 tmp.y = (m->m[1] * v->x) + (m->m[5] * v->y) + (m->m[9] * v->z) + m->m[13];
371 tmp.z = (m->m[2] * v->x) + (m->m[6] * v->y) + (m->m[10] * v->z) + m->m[14];
372
373 evas_vec3_scale(out, &tmp,
374 1.0 / ((m->m[3] * v->x) + (m->m[7] * v->y) + (m->m[11] * v->z) + m->m[15]));
375}
376
377static inline void
378evas_vec3_homogeneous_direction_transform(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Mat4 *m)
379{
380 Evas_Vec3 tmp;
381
382 if (m->flags & EVAS_MATRIX_IS_IDENTITY)
383 {
384 evas_vec3_copy(out, v);
385 return;
386 }
387
388 tmp.x = (m->m[0] * v->x) + (m->m[4] * v->y) + (m->m[8] * v->z);
389 tmp.y = (m->m[1] * v->x) + (m->m[5] * v->y) + (m->m[9] * v->z);
390 tmp.z = (m->m[2] * v->x) + (m->m[6] * v->y) + (m->m[10] * v->z);
391
392 evas_vec3_copy(out, &tmp);
393}
394
395static inline void
396evas_vec3_quaternion_rotate(Evas_Vec3 *out, const Evas_Vec3 *v, const Evas_Vec4 *q)
397{
398 Evas_Vec3 uv, uuv;
399 Evas_Vec3 axis;
400
401 evas_vec3_set(&axis, q->x, q->y, q->z);
402
403 evas_vec3_cross_product(&uv, &axis, v);
404 evas_vec3_cross_product(&uuv, &axis, &uv);
405
406 evas_vec3_scale(&uv, &uv, 2.0 * q->w);
407 evas_vec3_scale(&uuv, &uuv, 2.0);
408
409 out->x = v->x + uv.x + uuv.x;
410 out->y = v->y + uv.y + uuv.y;
411 out->z = v->z + uv.z + uuv.z;
412}
413
414/* 4D vector */
415static inline void
416evas_vec4_set(Evas_Vec4 *dst, Evas_Real x, Evas_Real y, Evas_Real z, Evas_Real w)
417{
418 dst->x = x;
419 dst->y = y;
420 dst->z = z;
421 dst->w = w;
422}
423
424static inline void
425evas_vec4_array_set(Evas_Vec4 *dst, const Evas_Real *v)
426{
427 dst->x = v[0];
428 dst->y = v[1];
429 dst->z = v[2];
430 dst->w = v[3];
431}
432
433static inline void
434evas_vec4_copy(Evas_Vec4 *dst, const Evas_Vec4 *src)
435{
436 dst->x = src->x;
437 dst->y = src->y;
438 dst->z = src->z;
439 dst->w = src->w;
440}
441
442static inline void
443evas_vec4_homogeneous_regulate(Evas_Vec4 *out, const Evas_Vec4 *v)
444{
445 if (v->w != 0.0)
446 {
447 Evas_Real scale = 1.0 / v->w;
448
449 out->x = v->x * scale;
450 out->y = v->y * scale;
451 out->z = v->z * scale;
452 out->w = 1.0;
453 }
454}
455
456static inline void
457evas_vec4_negate(Evas_Vec4 *out, const Evas_Vec4 *v)
458{
459 out->x = -v->x;
460 out->y = -v->y;
461 out->z = -v->z;
462 out->w = -v->w;
463}
464
465static inline void
466evas_vec4_add(Evas_Vec4 *out, const Evas_Vec4 *a, const Evas_Vec4 *b)
467{
468 out->x = a->x + b->x;
469 out->y = a->y + b->y;
470 out->z = a->z + b->z;
471 out->w = a->w + b->w;
472}
473
474static inline void
475evas_vec4_subtract(Evas_Vec4 *out, const Evas_Vec4 *a, const Evas_Vec4 *b)
476{
477 out->x = a->x - b->x;
478 out->y = a->y - b->y;
479 out->z = a->z - b->z;
480 out->w = a->w - b->w;
481}
482
483static inline void
484evas_vec4_scale(Evas_Vec4 *out, const Evas_Vec4 *v, Evas_Real scale)
485{
486 out->x = scale * v->x;
487 out->y = scale * v->y;
488 out->z = scale * v->z;
489 out->w = scale * v->w;
490}
491
492static inline void
493evas_vec4_multiply(Evas_Vec4 *out, const Evas_Vec4 *a, const Evas_Vec4 *b)
494{
495 out->x = a->x * b->x;
496 out->y = a->y * b->y;
497 out->z = a->z * b->z;
498 out->w = a->w * b->w;
499}
500
501static inline Evas_Real
502evas_vec4_length_get(const Evas_Vec4 *v)
503{
504 return (Evas_Real)sqrt((double)((v->x * v->x) + (v->y * v->y) +
505 (v->z * v->z) + (v->w + v->w)));
506}
507
508static inline Evas_Real
509evas_vec4_length_square_get(const Evas_Vec4 *v)
510{
511 return (v->x * v->x) + (v->y * v->y) + (v->z * v->z) + (v->w * v->w);
512}
513
514static inline Evas_Real
515evas_vec4_distance_get(const Evas_Vec4 *a, const Evas_Vec4 *b)
516{
517 Evas_Vec4 v;
518
519 evas_vec4_subtract(&v, a, b);
520 return evas_vec4_length_get(&v);
521}
522
523static inline Evas_Real
524evas_vec4_distance_square_get(const Evas_Vec4 *a, const Evas_Vec4 *b)
525{
526 Evas_Vec4 v;
527
528 evas_vec4_subtract(&v, a, b);
529 return evas_vec4_length_square_get(&v);
530}
531
532static inline void
533evas_vec4_normalize(Evas_Vec4 *out, const Evas_Vec4 *v)
534{
535 /* Assume "v" is not a zero vector */
536 evas_vec4_scale(out, v, 1.0 / evas_vec4_length_get(v));
537}
538
539static inline void
540evas_vec4_transform(Evas_Vec4 *out, const Evas_Vec4 *v, const Evas_Mat4 *m)
541{
542 Evas_Vec4 tmp;
543
544 if (m->flags & EVAS_MATRIX_IS_IDENTITY)
545 {
546 evas_vec4_copy(out, v);
547 return;
548 }
549
550 tmp.x = (m->m[0] * v->x) + (m->m[4] * v->y) + (m->m[ 8] * v->z) + (m->m[12] * v->w);
551 tmp.y = (m->m[1] * v->x) + (m->m[5] * v->y) + (m->m[ 9] * v->z) + (m->m[13] * v->w);
552 tmp.z = (m->m[2] * v->x) + (m->m[6] * v->y) + (m->m[10] * v->z) + (m->m[14] * v->w);
553 tmp.w = (m->m[3] * v->x) + (m->m[7] * v->y) + (m->m[11] * v->z) + (m->m[15] * v->w);
554
555 evas_vec4_copy(out, &tmp);
556}
557
558static inline void
559evas_vec3_homogeneous_position_set(Evas_Vec3 *out, const Evas_Vec4 *v)
560{
561 /* Assume "v" is a positional vector. (v->w != 0.0) */
562 Evas_Real h = 1.0 / v->w;
563
564 out->x = v->x * h;
565 out->y = v->y * h;
566 out->z = v->z * h;
567}
568
569static inline void
570evas_vec3_homogeneous_direction_set(Evas_Vec3 *out, const Evas_Vec4 *v)
571{
572 /* Assume "v" is a directional vector. (v->w == 0.0) */
573 out->x = v->x;
574 out->y = v->y;
575 out->z = v->z;
576}
577
578static inline void
579evas_vec4_homogeneous_position_set(Evas_Vec4 *out, const Evas_Vec3 *v)
580{
581 out->x = v->x;
582 out->y = v->y;
583 out->z = v->z;
584 out->w = 1.0;
585}
586
587static inline void
588evas_vec4_homogeneous_direction_set(Evas_Vec4 *out, const Evas_Vec3 *v)
589{
590 out->x = v->x;
591 out->y = v->y;
592 out->z = v->z;
593 out->w = 0.0;
594}
595
596/* 4x4 matrix */
597static inline void
598evas_mat4_identity_set(Evas_Mat4 *m)
599{
600 m->m[0] = 1.0;
601 m->m[1] = 0.0;
602 m->m[2] = 0.0;
603 m->m[3] = 0.0;
604
605 m->m[4] = 0.0;
606 m->m[5] = 1.0;
607 m->m[6] = 0.0;
608 m->m[7] = 0.0;
609
610 m->m[8] = 0.0;
611 m->m[9] = 0.0;
612 m->m[10] = 1.0;
613 m->m[11] = 0.0;
614
615 m->m[12] = 0.0;
616 m->m[13] = 0.0;
617 m->m[14] = 0.0;
618 m->m[15] = 1.0;
619
620 m->flags = EVAS_MATRIX_IS_IDENTITY;
621}
622
623static inline void
624evas_mat4_array_set(Evas_Mat4 *m, const Evas_Real *v)
625{
626 memcpy(&m->m[0], v, sizeof(Evas_Real) * 16);
627 m->flags = 0;
628}
629
630static inline void
631evas_mat4_copy(Evas_Mat4 *dst, const Evas_Mat4 *src)
632{
633 memcpy(dst, src, sizeof(Evas_Mat4));
634}
635
636static inline void
637evas_mat4_nocheck_multiply(Evas_Mat4 *out, const Evas_Mat4 *mat_a,
638 const Evas_Mat4 *mat_b)
639{
640 Evas_Real *d = out->m;
641 const Evas_Real *a = mat_a->m;
642 const Evas_Real *b = mat_b->m;
643
644 if (mat_a->flags & EVAS_MATRIX_IS_IDENTITY)
645 {
646 evas_mat4_copy(out, mat_b);
647 return;
648 }
649
650 if (mat_b->flags & EVAS_MATRIX_IS_IDENTITY)
651 {
652 evas_mat4_copy(out, mat_a);
653 return;
654 }
655
656 d[ 0] = a[ 0] * b[ 0] + a[ 4] * b[ 1] + a[ 8] * b[ 2] + a[12] * b [3];
657 d[ 4] = a[ 0] * b[ 4] + a[ 4] * b[ 5] + a[ 8] * b[ 6] + a[12] * b [7];
658 d[ 8] = a[ 0] * b[ 8] + a[ 4] * b[ 9] + a[ 8] * b[10] + a[12] * b[11];
659 d[12] = a[ 0] * b[12] + a[ 4] * b[13] + a[ 8] * b[14] + a[12] * b[15];
660
661 d[ 1] = a[ 1] * b[ 0] + a[ 5] * b[ 1] + a[ 9] * b[ 2] + a[13] * b [3];
662 d[ 5] = a[ 1] * b[ 4] + a[ 5] * b[ 5] + a[ 9] * b[ 6] + a[13] * b [7];
663 d[ 9] = a[ 1] * b[ 8] + a[ 5] * b[ 9] + a[ 9] * b[10] + a[13] * b[11];
664 d[13] = a[ 1] * b[12] + a[ 5] * b[13] + a[ 9] * b[14] + a[13] * b[15];
665
666 d[ 2] = a[ 2] * b[ 0] + a[ 6] * b[ 1] + a[10] * b[ 2] + a[14] * b [3];
667 d[ 6] = a[ 2] * b[ 4] + a[ 6] * b[ 5] + a[10] * b[ 6] + a[14] * b [7];
668 d[10] = a[ 2] * b[ 8] + a[ 6] * b[ 9] + a[10] * b[10] + a[14] * b[11];
669 d[14] = a[ 2] * b[12] + a[ 6] * b[13] + a[10] * b[14] + a[14] * b[15];
670
671 d[ 3] = a[ 3] * b[ 0] + a[ 7] * b[ 1] + a[11] * b[ 2] + a[15] * b [3];
672 d[ 7] = a[ 3] * b[ 4] + a[ 7] * b[ 5] + a[11] * b[ 6] + a[15] * b [7];
673 d[11] = a[ 3] * b[ 8] + a[ 7] * b[ 9] + a[11] * b[10] + a[15] * b[11];
674 d[15] = a[ 3] * b[12] + a[ 7] * b[13] + a[11] * b[14] + a[15] * b[15];
675
676 out->flags = 0;
677}
678
679static inline void
680evas_mat4_multiply(Evas_Mat4 *out, const Evas_Mat4 *mat_a,
681 const Evas_Mat4 *mat_b)
682{
683 if (out != mat_a && out != mat_b)
684 {
685 evas_mat4_nocheck_multiply(out, mat_a, mat_b);
686 }
687 else
688 {
689 Evas_Mat4 result;
690
691 evas_mat4_nocheck_multiply(&result, mat_a, mat_b);
692 evas_mat4_copy(out, &result);
693 }
694}
695
696static inline void
697evas_mat4_look_at_set(Evas_Mat4 *m,
698 const Evas_Vec3 *pos, const Evas_Vec3 *center, const Evas_Vec3 *up)
699{
700 Evas_Vec3 x, y, z;
701
702 evas_vec3_subtract(&z, pos, center);
703 evas_vec3_normalize(&z, &z);
704
705 evas_vec3_cross_product(&x, up, &z);
706 evas_vec3_normalize(&x, &x);
707
708 evas_vec3_cross_product(&y, &z, &x);
709 evas_vec3_normalize(&y, &y);
710
711 m->m[ 0] = x.x;
712 m->m[ 1] = y.x;
713 m->m[ 2] = z.x;
714 m->m[ 3] = 0.0;
715
716 m->m[ 4] = x.y;
717 m->m[ 5] = y.y;
718 m->m[ 6] = z.y;
719 m->m[ 7] = 0.0;
720
721 m->m[ 8] = x.z;
722 m->m[ 9] = y.z;
723 m->m[10] = z.z;
724 m->m[11] = 0.0;
725
726 m->m[12] = -evas_vec3_dot_product(&x, pos);
727 m->m[13] = -evas_vec3_dot_product(&y, pos);
728 m->m[14] = -evas_vec3_dot_product(&z, pos);
729 m->m[15] = 1.0;
730
731 m->flags = 0;
732}
733
734static inline void
735evas_mat4_frustum_set(Evas_Mat4 *m,
736 Evas_Real left, Evas_Real right, Evas_Real bottom, Evas_Real top,
737 Evas_Real dnear, Evas_Real dfar)
738{
739 Evas_Real w = right - left;
740 Evas_Real h = top - bottom;
741 Evas_Real depth = dnear - dfar;
742 Evas_Real near_2 = 2.0f * dnear;
743
744 m->m[ 0] = near_2 / w;
745 m->m[ 1] = 0.0f;
746 m->m[ 2] = 0.0f;
747 m->m[ 3] = 0.0f;
748
749 m->m[ 4] = 0.0f;
750 m->m[ 5] = near_2 / h;
751 m->m[ 6] = 0.0f;
752 m->m[ 7] = 0.0f;
753
754 m->m[ 8] = (right + left) / w;
755 m->m[ 9] = (top + bottom) / h;
756 m->m[10] = (dfar + dnear) / depth;
757 m->m[11] = -1.0f;
758
759 m->m[12] = 0.0f;
760 m->m[13] = 0.0f;
761 m->m[14] = near_2 * dfar / depth;
762 m->m[15] = 0.0f;
763
764 m->flags = 0;
765}
766
767static inline void
768evas_mat4_ortho_set(Evas_Mat4 *m,
769 Evas_Real left, Evas_Real right, Evas_Real bottom, Evas_Real top,
770 Evas_Real dnear, Evas_Real dfar)
771{
772 Evas_Real w = right - left;
773 Evas_Real h = top - bottom;
774 Evas_Real depth = dnear - dfar;
775
776 m->m[ 0] = 2.0f / w;
777 m->m[ 1] = 0.0f;
778 m->m[ 2] = 0.0f;
779 m->m[ 3] = 0.0f;
780
781 m->m[ 4] = 0.0f;
782 m->m[ 5] = 2.0f / h;
783 m->m[ 6] = 0.0f;
784 m->m[ 7] = 0.0f;
785
786 m->m[ 8] = 0.0f;
787 m->m[ 9] = 0.0f;
788 m->m[10] = 2.0f / depth;
789 m->m[11] = 0.0f;
790
791 m->m[12] = -(right + left) / w;
792 m->m[13] = -(top + bottom) / h;
793 m->m[14] = (dfar + dnear) / depth;
794 m->m[15] = 1.0f;
795
796 m->flags = 0;
797}
798
799static inline void
800evas_mat4_nocheck_inverse(Evas_Mat4 *out, const Evas_Mat4 *mat)
801{
802 Evas_Real *d = out->m;
803 const Evas_Real *m = mat->m;
804 Evas_Real det;
805
806 if (mat->flags & EVAS_MATRIX_IS_IDENTITY)
807 {
808 evas_mat4_copy(out, mat);
809 return;
810 }
811
812 d[ 0] = m[ 5] * m[10] * m[15] -
813 m[ 5] * m[11] * m[14] -
814 m[ 9] * m[ 6] * m[15] +
815 m[ 9] * m[ 7] * m[14] +
816 m[13] * m[ 6] * m[11] -
817 m[13] * m[ 7] * m[10];
818
819 d[ 4] = -m[ 4] * m[10] * m[15] +
820 m[ 4] * m[11] * m[14] +
821 m[ 8] * m[ 6] * m[15] -
822 m[ 8] * m[ 7] * m[14] -
823 m[12] * m[ 6] * m[11] +
824 m[12] * m[ 7] * m[10];
825
826 d[ 8] = m[ 4] * m[ 9] * m[15] -
827 m[ 4] * m[11] * m[13] -
828 m[ 8] * m[ 5] * m[15] +
829 m[ 8] * m[ 7] * m[13] +
830 m[12] * m[ 5] * m[11] -
831 m[12] * m[ 7] * m[ 9];
832
833 d[12] = -m[ 4] * m[ 9] * m[14] +
834 m[ 4] * m[10] * m[13] +
835 m[ 8] * m[ 5] * m[14] -
836 m[ 8] * m[ 6] * m[13] -
837 m[12] * m[ 5] * m[10] +
838 m[12] * m[ 6] * m[ 9];
839
840 d[ 1] = -m[ 1] * m[10] * m[15] +
841 m[ 1] * m[11] * m[14] +
842 m[ 9] * m[ 2] * m[15] -
843 m[ 9] * m[ 3] * m[14] -
844 m[13] * m[ 2] * m[11] +
845 m[13] * m[ 3] * m[10];
846
847 d[ 5] = m[ 0] * m[10] * m[15] -
848 m[ 0] * m[11] * m[14] -
849 m[ 8] * m[ 2] * m[15] +
850 m[ 8] * m[ 3] * m[14] +
851 m[12] * m[ 2] * m[11] -
852 m[12] * m[ 3] * m[10];
853
854 d[ 9] = -m[ 0] * m[ 9] * m[15] +
855 m[ 0] * m[11] * m[13] +
856 m[ 8] * m[ 1] * m[15] -
857 m[ 8] * m[ 3] * m[13] -
858 m[12] * m[ 1] * m[11] +
859 m[12] * m[ 3] * m[ 9];
860
861 d[13] = m[ 0] * m[ 9] * m[14] -
862 m[ 0] * m[10] * m[13] -
863 m[ 8] * m[ 1] * m[14] +
864 m[ 8] * m[ 2] * m[13] +
865 m[12] * m[ 1] * m[10] -
866 m[12] * m[ 2] * m[ 9];
867
868 d[ 2] = m[ 1] * m[ 6] * m[15] -
869 m[ 1] * m[ 7] * m[14] -
870 m[ 5] * m[ 2] * m[15] +
871 m[ 5] * m[ 3] * m[14] +
872 m[13] * m[ 2] * m[ 7] -
873 m[13] * m[ 3] * m[ 6];
874
875 d[ 6] = -m[ 0] * m[ 6] * m[15] +
876 m[ 0] * m[ 7] * m[14] +
877 m[ 4] * m[ 2] * m[15] -
878 m[ 4] * m[ 3] * m[14] -
879 m[12] * m[ 2] * m[ 7] +
880 m[12] * m[ 3] * m[ 6];
881
882 d[10] = m[ 0] * m[ 5] * m[15] -
883 m[ 0] * m[ 7] * m[13] -
884 m[ 4] * m[ 1] * m[15] +
885 m[ 4] * m[ 3] * m[13] +
886 m[12] * m[ 1] * m[ 7] -
887 m[12] * m[ 3] * m[ 5];
888
889 d[14] = -m[ 0] * m[ 5] * m[14] +
890 m[ 0] * m[ 6] * m[13] +
891 m[ 4] * m[ 1] * m[14] -
892 m[ 4] * m[ 2] * m[13] -
893 m[12] * m[ 1] * m[ 6] +
894 m[12] * m[ 2] * m[ 5];
895
896 d[ 3] = -m[ 1] * m[ 6] * m[11] +
897 m[ 1] * m[ 7] * m[10] +
898 m[ 5] * m[ 2] * m[11] -
899 m[ 5] * m[ 3] * m[10] -
900 m[ 9] * m[ 2] * m[ 7] +
901 m[ 9] * m[ 3] * m[ 6];
902
903 d[ 7] = m[ 0] * m[ 6] * m[11] -
904 m[ 0] * m[ 7] * m[10] -
905 m[ 4] * m[ 2] * m[11] +
906 m[ 4] * m[ 3] * m[10] +
907 m[ 8] * m[ 2] * m[ 7] -
908 m[ 8] * m[ 3] * m[ 6];
909
910 d[11] = -m[ 0] * m[ 5] * m[11] +
911 m[ 0] * m[ 7] * m[ 9] +
912 m[ 4] * m[ 1] * m[11] -
913 m[ 4] * m[ 3] * m[ 9] -
914 m[ 8] * m[ 1] * m[ 7] +
915 m[ 8] * m[ 3] * m[ 5];
916
917 d[15] = m[ 0] * m[ 5] * m[10] -
918 m[ 0] * m[ 6] * m[ 9] -
919 m[ 4] * m[ 1] * m[10] +
920 m[ 4] * m[ 2] * m[ 9] +
921 m[ 8] * m[ 1] * m[ 6] -
922 m[ 8] * m[ 2] * m[ 5];
923
924 det = m[0] * d[0] + m[1] * d[4] + m[2] * d[8] + m[3] * d[12];
925
926 if (det == 0.0) return;
927
928 det = 1.0 / det;
929
930 d[ 0] *= det;
931 d[ 1] *= det;
932 d[ 2] *= det;
933 d[ 3] *= det;
934 d[ 4] *= det;
935 d[ 5] *= det;
936 d[ 6] *= det;
937 d[ 7] *= det;
938 d[ 8] *= det;
939 d[ 9] *= det;
940 d[10] *= det;
941 d[11] *= det;
942 d[12] *= det;
943 d[13] *= det;
944 d[14] *= det;
945 d[15] *= det;
946
947 out->flags = 0;
948}
949
950static inline void
951evas_mat4_inverse(Evas_Mat4 *out, const Evas_Mat4 *mat)
952{
953 if (out != mat)
954 {
955 evas_mat4_nocheck_inverse(out, mat);
956 }
957 else
958 {
959 Evas_Mat4 tmp;
960
961 evas_mat4_nocheck_inverse(&tmp, mat);
962 evas_mat4_copy(out, &tmp);
963 }
964}
965
966static inline void
967evas_normal_matrix_get(Evas_Mat3 *out, const Evas_Mat4 *m)
968{
969 /* Normal matrix is a transposed matirx of inversed modelview.
970 * And we need only upper-left 3x3 terms to work with. */
971
972 Evas_Real det;
973 Evas_Real a = m->m[0];
974 Evas_Real b = m->m[4];
975 Evas_Real c = m->m[8];
976 Evas_Real d = m->m[1];
977 Evas_Real e = m->m[5];
978 Evas_Real f = m->m[9];
979 Evas_Real g = m->m[2];
980 Evas_Real h = m->m[6];
981 Evas_Real i = m->m[10];
982
983 det = a * e * i + b * f * g + c * d * h - g * e * c - h * f * a - i * d * b;
984 det = 1.0 / det;
985
986 out->m[0] = (e * i - f * h) * det;
987 out->m[1] = (h * c - i * b) * det;
988 out->m[2] = (b * f - c * e) * det;
989 out->m[3] = (g * f - d * i) * det;
990 out->m[4] = (a * i - g * c) * det;
991 out->m[5] = (d * c - a * f) * det;
992 out->m[6] = (d * h - g * e) * det;
993 out->m[7] = (g * b - a * h) * det;
994 out->m[8] = (a * e - d * b) * det;
995
996 out->flags = 0;
997}
998
999/* 3x3 matrix */
1000static inline void
1001evas_mat3_identity_set(Evas_Mat3 *m)
1002{
1003 m->m[0] = 1.0;
1004 m->m[1] = 0.0;
1005 m->m[2] = 0.0;
1006 m->m[3] = 0.0;
1007 m->m[4] = 1.0;
1008 m->m[5] = 0.0;
1009 m->m[6] = 0.0;
1010 m->m[7] = 0.0;
1011 m->m[8] = 1.0;
1012
1013 m->flags = EVAS_MATRIX_IS_IDENTITY;
1014}
1015
1016static inline void
1017evas_mat3_array_set(Evas_Mat3 *m, const Evas_Real *v)
1018{
1019 memcpy(&m->m[0], v, sizeof(Evas_Real) * 9);
1020 m->flags = 0;
1021}
1022
1023static inline void
1024evas_mat3_copy(Evas_Mat3 *dst, const Evas_Mat3 *src)
1025{
1026 memcpy(dst, src, sizeof(Evas_Mat3));
1027}
1028
1029static inline void
1030evas_mat3_nocheck_multiply(Evas_Mat3 *out, const Evas_Mat3 *mat_a, const Evas_Mat3 *mat_b)
1031{
1032 Evas_Real *d = out->m;
1033 const Evas_Real *a = mat_a->m;
1034 const Evas_Real *b = mat_b->m;
1035
1036 if (mat_a->flags & EVAS_MATRIX_IS_IDENTITY)
1037 {
1038 evas_mat3_copy(out, mat_b);
1039 return;
1040 }
1041
1042 if (mat_b->flags & EVAS_MATRIX_IS_IDENTITY)
1043 {
1044 evas_mat3_copy(out, mat_a);
1045 return;
1046 }
1047
1048 d[0] = a[0] * b[0] + a[3] * b[1] + a[6] * b[2];
1049 d[3] = a[0] * b[3] + a[3] * b[4] + a[6] * b[5];
1050 d[6] = a[0] * b[6] + a[3] * b[7] + a[6] * b[8];
1051
1052 d[1] = a[1] * b[0] + a[4] * b[1] + a[7] * b[2];
1053 d[4] = a[1] * b[3] + a[4] * b[4] + a[7] * b[5];
1054 d[7] = a[1] * b[6] + a[4] * b[7] + a[7] * b[8];
1055
1056 d[2] = a[2] * b[0] + a[5] * b[1] + a[8] * b[2];
1057 d[5] = a[2] * b[3] + a[5] * b[4] + a[8] * b[5];
1058 d[8] = a[2] * b[6] + a[5] * b[7] + a[8] * b[8];
1059
1060 out->flags = 0;
1061}
1062
1063static inline void
1064evas_mat3_multiply(Evas_Mat3 *out, const Evas_Mat3 *mat_a, const Evas_Mat3 *mat_b)
1065{
1066 if (out != mat_a && out != mat_b)
1067 {
1068 evas_mat3_nocheck_multiply(out, mat_a, mat_b);
1069 }
1070 else
1071 {
1072 Evas_Mat3 tmp;
1073
1074 evas_mat3_nocheck_multiply(&tmp, mat_a, mat_b);
1075 evas_mat3_copy(out, &tmp);
1076 }
1077}
1078
1079static inline void
1080evas_mat3_nocheck_inverse(Evas_Mat3 *out, const Evas_Mat3 *mat)
1081{
1082 Evas_Real *d = &out->m[0];
1083 const Evas_Real *m = &mat->m[0];
1084 Evas_Real det;
1085
1086 if (mat->flags & EVAS_MATRIX_IS_IDENTITY)
1087 {
1088 evas_mat3_copy(out, mat);
1089 return;
1090 }
1091
1092 d[0] = m[4] * m[8] - m[7] * m[5];
1093 d[1] = m[7] * m[2] - m[1] * m[8];
1094 d[2] = m[1] * m[5] - m[4] * m[2];
1095 d[3] = m[6] * m[5] - m[3] * m[8];
1096 d[4] = m[0] * m[8] - m[6] * m[2];
1097 d[5] = m[3] * m[2] - m[0] * m[5];
1098 d[6] = m[3] * m[7] - m[6] * m[4];
1099 d[7] = m[6] * m[1] - m[0] * m[7];
1100 d[8] = m[0] * m[4] - m[3] * m[1];
1101
1102 det = m[0] * d[0] + m[1] * d[3] + m[2] * d[6];
1103
1104 if (det == 0.0)
1105 return;
1106
1107 det = 1.0 / det;
1108
1109 d[0] *= det;
1110 d[1] *= det;
1111 d[2] *= det;
1112 d[3] *= det;
1113 d[4] *= det;
1114 d[5] *= det;
1115 d[6] *= det;
1116 d[7] *= det;
1117 d[8] *= det;
1118
1119 out->flags = 0;
1120}
1121
1122static inline void
1123evas_mat3_invserse(Evas_Mat3 *out, const Evas_Mat3 *mat)
1124{
1125 if (out != mat)
1126 {
1127 evas_mat3_nocheck_inverse(out, mat);
1128 }
1129 else
1130 {
1131 Evas_Mat3 tmp;
1132
1133 evas_mat3_nocheck_inverse(&tmp, mat);
1134 evas_mat3_copy(out, &tmp);
1135 }
1136}
1137
1138/* 2x2 matrix */
1139static inline void
1140evas_mat2_identity_set(Evas_Mat2 *m)
1141{
1142 m->m[0] = 1.0;
1143 m->m[1] = 0.0;
1144 m->m[2] = 0.0;
1145 m->m[3] = 1.0;
1146
1147 m->flags = EVAS_MATRIX_IS_IDENTITY;
1148}
1149
1150static inline void
1151evas_mat2_array_set(Evas_Mat2 *m, const Evas_Real *v)
1152{
1153 memcpy(&m->m[0], v, sizeof(Evas_Real) * 4);
1154 m->flags = 0;
1155}
1156
1157static inline void
1158evas_mat2_copy(Evas_Mat2 *dst, const Evas_Mat2 *src)
1159{
1160 memcpy(dst, src, sizeof(Evas_Mat2));
1161}
1162
1163static inline void
1164evas_mat2_nocheck_multiply(Evas_Mat2 *out, const Evas_Mat2 *mat_a, const Evas_Mat2 *mat_b)
1165{
1166 Evas_Real *d = &out->m[0];
1167 const Evas_Real *a = &mat_a->m[0];
1168 const Evas_Real *b = &mat_b->m[0];
1169
1170 if (mat_a->flags & EVAS_MATRIX_IS_IDENTITY)
1171 {
1172 evas_mat2_copy(out, mat_b);
1173 return;
1174 }
1175
1176 if (mat_b->flags & EVAS_MATRIX_IS_IDENTITY)
1177 {
1178 evas_mat2_copy(out, mat_a);
1179 return;
1180 }
1181
1182 d[0] = a[0] * b[0] + a[2] * b[1];
1183 d[2] = a[0] * b[2] + a[2] * b[3];
1184
1185 d[1] = a[1] * b[0] + a[3] * b[1];
1186 d[3] = a[1] * b[2] + a[3] * b[3];
1187
1188 out->flags = 0;
1189}
1190
1191static inline void
1192evas_mat2_multiply(Evas_Mat2 *out, const Evas_Mat2 *mat_a, const Evas_Mat2 *mat_b)
1193{
1194 if (out != mat_a && out != mat_b)
1195 {
1196 evas_mat2_nocheck_multiply(out, mat_a, mat_b);
1197 }
1198 else
1199 {
1200 Evas_Mat2 tmp;
1201
1202 evas_mat2_nocheck_multiply(&tmp, mat_a, mat_b);
1203 evas_mat2_copy(out, &tmp);
1204 }
1205}
1206
1207static inline void
1208evas_mat2_nocheck_inverse(Evas_Mat2 *out, const Evas_Mat2 *mat)
1209{
1210 Evas_Real *d = &out->m[0];
1211 const Evas_Real *m = &mat->m[0];
1212 Evas_Real det;
1213
1214 if (mat->flags & EVAS_MATRIX_IS_IDENTITY)
1215 {
1216 evas_mat2_copy(out, mat);
1217 return;
1218 }
1219
1220 det = m[0] * m[3] - m[2] * m[1];
1221
1222 if (det == 0.0)
1223 return;
1224
1225 det = 1.0 / det;
1226
1227 d[0] = m[3] * det;
1228 d[1] = -m[1] * det;
1229 d[2] = -m[2] * det;
1230 d[3] = m[0] * det;
1231
1232 out->flags = 0;
1233}
1234
1235static inline void
1236evas_mat2_invserse(Evas_Mat2 *out, const Evas_Mat2 *mat)
1237{
1238 if (out != mat)
1239 {
1240 evas_mat2_nocheck_inverse(out, mat);
1241 }
1242 else
1243 {
1244 Evas_Mat2 tmp;
1245
1246 evas_mat2_nocheck_inverse(&tmp, mat);
1247 evas_mat2_copy(out, &tmp);
1248 }
1249}
1250
1251static inline void
1252evas_box2_set(Evas_Box2 *box, Evas_Real x0, Evas_Real y0, Evas_Real x1,
1253 Evas_Real y1)
1254{
1255 box->p0.x = x0;
1256 box->p0.y = y0;
1257 box->p1.x = x1;
1258 box->p1.y = y1;
1259}
1260
1261static inline void
1262evas_box3_set(Evas_Box3 *box, Evas_Real x0, Evas_Real y0, Evas_Real z0,
1263 Evas_Real x1, Evas_Real y1, Evas_Real z1)
1264{
1265 box->p0.x = x0;
1266 box->p0.y = y0;
1267 box->p0.z = z0;
1268 box->p1.x = x1;
1269 box->p1.y = y1;
1270 box->p1.z = z1;
1271}
1272
1273static inline void
1274evas_box3_empty_set(Evas_Box3 *box)
1275{
1276 evas_vec3_set(&box->p0, 0.0, 0.0, 0.0);
1277 evas_vec3_set(&box->p1, 0.0, 0.0, 0.0);
1278}
1279
1280static inline void
1281evas_box3_copy(Evas_Box3 *dst, const Evas_Box3 *src)
1282{
1283 evas_vec3_copy(&dst->p0, &src->p0);
1284 evas_vec3_copy(&dst->p1, &src->p1);
1285}
1286
1287static inline void
1288evas_box3_union(Evas_Box3 *out, const Evas_Box3 *a, const Evas_Box3 *b)
1289{
1290 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));
1291 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));
1292}
1293
1294static inline void
1295evas_box3_transform(Evas_Box3 *out EINA_UNUSED, const Evas_Box3 *box EINA_UNUSED, const Evas_Mat4 *mat EINA_UNUSED)
1296{
1297 /* TODO: */
1298}
1299
1300static inline void
1301evas_mat4_position_get(const Evas_Mat4 *matrix, Evas_Vec4 *position)
1302{
1303 Evas_Vec4 pos;
1304
1305 pos.x = 0.0;
1306 pos.y = 0.0;
1307 pos.z = 0.0;
1308 pos.w = 1.0;
1309
1310 evas_vec4_transform(position, &pos, matrix);
1311}
1312
1313static inline void
1314evas_mat4_direction_get(const Evas_Mat4 *matrix, Evas_Vec3 *direction)
1315{
1316 /* TODO: Check correctness. */
1317
1318 Evas_Vec4 dir;
1319
1320 dir.x = 0.0;
1321 dir.y = 0.0;
1322 dir.z = 1.0;
1323 dir.w = 1.0;
1324
1325 evas_vec4_transform(&dir, &dir, matrix);
1326
1327 direction->x = dir.x;
1328 direction->y = dir.y;
1329 direction->z = dir.z;
1330}
1331
1332static inline void
1333evas_vec4_quaternion_multiply(Evas_Vec4 *out, const Evas_Vec4 *a, const Evas_Vec4 *b)
1334{
1335 Evas_Vec4 r;
1336
1337 r.x = (a->w * b->x) + (a->x * b->w) + (a->y * b->z) - (a->z * b->y);
1338 r.y = (a->w * b->y) - (a->x * b->z) + (a->y * b->w) + (a->z * b->x);
1339 r.z = (a->w * b->z) + (a->x * b->y) - (a->y * b->x) + (a->z * b->w);
1340 r.w = (a->w * b->w) - (a->x * b->x) - (a->y * b->y) - (a->z * b->z);
1341
1342 *out = r;
1343}
1344
1345static inline void
1346evas_vec4_quaternion_inverse(Evas_Vec4 *out, const Evas_Vec4 *q)
1347{
1348 Evas_Real norm = (q->x * q->x) + (q->y * q->y) + (q->z * q->z) + (q->w * q->w);
1349
1350 if (norm > 0.0)
1351 {
1352 Evas_Real inv_norm = 1.0 / norm;
1353 out->x = -q->x * inv_norm;
1354 out->y = -q->y * inv_norm;
1355 out->z = -q->z * inv_norm;
1356 out->w = q->w * inv_norm;
1357 }
1358 else
1359 {
1360 out->x = 0.0;
1361 out->y = 0.0;
1362 out->z = 0.0;
1363 out->w = 0.0;
1364 }
1365}
1366
1367static inline void
1368evas_vec4_quaternion_rotation_matrix_get(const Evas_Vec4 *q, Evas_Mat3 *mat)
1369{
1370 Evas_Real x, y, z;
1371 Evas_Real xx, xy, xz;
1372 Evas_Real yy, yz;
1373 Evas_Real zz;
1374 Evas_Real wx, wy, wz;
1375
1376 x = 2.0 * q->x;
1377 y = 2.0 * q->y;
1378 z = 2.0 * q->z;
1379
1380 xx = q->x * x;
1381 xy = q->x * y;
1382 xz = q->x * z;
1383
1384 yy = q->y * y;
1385 yz = q->y * z;
1386
1387 zz = q->z * z;
1388
1389 wx = q->w * x;
1390 wy = q->w * y;
1391 wz = q->w * z;
1392
1393 mat->m[0] = 1.0 - yy - zz;
1394 mat->m[1] = xy + wz;
1395 mat->m[2] = xz - wy;
1396 mat->m[3] = xy - wz;
1397 mat->m[4] = 1.0 - xx - zz;
1398 mat->m[5] = yz + wx;
1399 mat->m[6] = xz + wy;
1400 mat->m[7] = yz - wx;
1401 mat->m[8] = 1.0 - xx - yy;
1402}
1403
1404static inline void
1405evas_mat4_build(Evas_Mat4 *out,
1406 const Evas_Vec3 *position, const Evas_Vec4 *orientation, const Evas_Vec3 *scale)
1407{
1408 Evas_Mat3 rot;
1409
1410 evas_vec4_quaternion_rotation_matrix_get(orientation, &rot);
1411
1412 out->m[ 0] = scale->x * rot.m[0];
1413 out->m[ 1] = scale->x * rot.m[1];
1414 out->m[ 2] = scale->x * rot.m[2];
1415 out->m[ 3] = 0.0;
1416
1417 out->m[ 4] = scale->y * rot.m[3];
1418 out->m[ 5] = scale->y * rot.m[4];
1419 out->m[ 6] = scale->y * rot.m[5];
1420 out->m[ 7] = 0.0;
1421
1422 out->m[ 8] = scale->z * rot.m[6];
1423 out->m[ 9] = scale->z * rot.m[7];
1424 out->m[10] = scale->z * rot.m[8];
1425 out->m[11] = 0.0;
1426
1427 out->m[12] = position->x;
1428 out->m[13] = position->y;
1429 out->m[14] = position->z;
1430 out->m[15] = 1.0;
1431}
1432
1433static inline void
1434evas_mat4_inverse_build(Evas_Mat4 *out, const Evas_Vec3 *position,
1435 const Evas_Vec4 *orientation, const Evas_Vec3 *scale)
1436{
1437 Evas_Vec4 inv_rotation;
1438 Evas_Vec3 inv_scale;
1439 Evas_Vec3 inv_translate;
1440
1441 Evas_Mat3 rot;
1442
1443 /* Inverse scale. */
1444 evas_vec3_set(&inv_scale, 1.0 / scale->x, 1.0 / scale->y, 1.0 / scale->z);
1445
1446 /* Inverse rotation. */
1447 evas_vec4_quaternion_inverse(&inv_rotation, orientation);
1448
1449 /* Inverse translation. */
1450 evas_vec3_negate(&inv_translate, position);
1451 evas_vec3_quaternion_rotate(&inv_translate, &inv_translate, &inv_rotation);
1452 evas_vec3_multiply(&inv_translate, &inv_translate, &inv_scale);
1453
1454 /* Get 3x3 rotation matrix. */
1455 evas_vec4_quaternion_rotation_matrix_get(&inv_rotation, &rot);
1456
1457 out->m[ 0] = inv_scale.x * rot.m[0];
1458 out->m[ 1] = inv_scale.y * rot.m[1];
1459 out->m[ 2] = inv_scale.z * rot.m[2];
1460 out->m[ 3] = 0.0;
1461
1462 out->m[ 4] = inv_scale.x * rot.m[3];
1463 out->m[ 5] = inv_scale.y * rot.m[4];
1464 out->m[ 6] = inv_scale.z * rot.m[5];
1465 out->m[ 7] = 0.0;
1466
1467 out->m[ 8] = inv_scale.x * rot.m[6];
1468 out->m[ 9] = inv_scale.y * rot.m[7];
1469 out->m[10] = inv_scale.z * rot.m[8];
1470 out->m[11] = 0.0;
1471
1472 out->m[12] = inv_translate.x;
1473 out->m[13] = inv_translate.y;
1474 out->m[14] = inv_translate.z;
1475 out->m[15] = 1.0;
1476}
1477
1478static inline void
1479evas_color_set(Evas_Color *color, Evas_Real r, Evas_Real g, Evas_Real b, Evas_Real a)
1480{
1481 color->r = r;
1482 color->g = g;
1483 color->b = b;
1484 color->a = a;
1485}
1486
1487static inline void
1488evas_color_blend(Evas_Color *dst, const Evas_Color *c0, const Evas_Color *c1, Evas_Real w)
1489{
1490 dst->r = c0->r * w + c1->r * (1.0 - w);
1491 dst->g = c0->g * w + c1->g * (1.0 - w);
1492 dst->b = c0->b * w + c1->b * (1.0 - w);
1493 dst->a = c0->a * w + c1->a * (1.0 - w);
1494}
1495
1496static inline void
1497evas_ray3_init(Evas_Ray3 *ray, Evas_Real x, Evas_Real y, const Evas_Mat4 *mvp)
1498{
1499 Evas_Mat4 mat;
1500 Evas_Vec4 dnear, dfar;
1501
1502 memset(&mat, 0, sizeof (mat));
1503
1504 /* Get the matrix which transforms from normalized device coordinate to
1505 modeling coodrinate. */
1506 evas_mat4_inverse(&mat, mvp);
1507
1508 /* Transform near point. */
1509 dnear.x = x;
1510 dnear.y = y;
1511 dnear.z = -1.0;
1512 dnear.w = 1.0;
1513
1514 evas_vec4_transform(&dnear, &dnear, &mat);
1515
1516 dnear.w = 1.0 / dnear.w;
1517 dnear.x *= dnear.w;
1518 dnear.y *= dnear.w;
1519 dnear.z *= dnear.w;
1520
1521 evas_vec3_set(&ray->org, dnear.x, dnear.y, dnear.z);
1522
1523 /* Transform far point. */
1524 dfar.x = x;
1525 dfar.y = y;
1526 dfar.z = 1.0;
1527 dfar.w = 1.0;
1528
1529 evas_vec4_transform(&dfar, &dfar, &mat);
1530
1531 dfar.w = 1.0 / dfar.w;
1532 dfar.x *= dfar.w;
1533 dfar.y *= dfar.w;
1534 dfar.z *= dfar.w;
1535
1536 evas_vec3_set(&ray->dir, dfar.x - dnear.x, dfar.y - dnear.y, dfar.z - dnear.z);
1537}
1538
1539static inline Eina_Bool
1540evas_box3_ray3_intersect(const Evas_Box3 *box EINA_UNUSED, const Evas_Ray3 *ray EINA_UNUSED)
1541{
1542 /* TODO: */
1543 return EINA_TRUE;
1544}
1545
1546static inline Evas_Real
1547evas_reciprocal_sqrt(Evas_Real x)
1548{
1549 union {
1550 float f;
1551 long i;
1552 } u;
1553
1554 u.f = x;
1555 u.i = 0x5f3759df - (u.i >> 1);
1556 return u.f * (1.5f - u.f * u.f * x * 0.5f);
1557}
diff --git a/src/libraries/love.h b/src/libraries/love.h
index be82758..1de8032 100644
--- a/src/libraries/love.h
+++ b/src/libraries/love.h
@@ -79,7 +79,6 @@ love needs
79*/ 79*/
80 80
81#include "evas_macros.h" 81#include "evas_macros.h"
82#include "evas_3d_utils.h" // TODO - Hopefully I can convince the authors to make this public.
83 82
84#include "Runnr.h" 83#include "Runnr.h"
85 84