aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'src/libraries')
-rw-r--r--src/libraries/LumbrJack.c2
-rw-r--r--src/libraries/evas_3d_utils.h1557
-rw-r--r--src/libraries/evas_macros.h217
-rw-r--r--src/libraries/love.h198
-rw-r--r--src/libraries/winFang.h3
5 files changed, 1973 insertions, 4 deletions
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 @@
3*/ 3*/
4 4
5 5
6#include "LumbrJack.h"
7#include <unistd.h> 6#include <unistd.h>
7#include "LumbrJack.h"
8 8
9 9
10static char dateTime[DATE_TIME_LEN]; 10static 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 @@
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/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 @@
1#ifndef EVAS_MACROS_H
2#define EVAS_MACROS_H
3
4#undef ABS
5#define ABS(x) (((x) < 0) ? -(x) : (x))
6
7#undef SGN
8#define SGN(x) (((x) < 0) ? -1 : 1)
9
10#undef MIN
11#define MIN(x, y) (((x) < (y)) ? (x) : (y))
12
13#undef MAX
14#define MAX(x, y) (((x) > (y)) ? (x) : (y))
15
16#define SWAP32(x) (x) = \
17 ((((x) & 0x000000ff ) << 24) | \
18 (((x) & 0x0000ff00 ) << 8) | \
19 (((x) & 0x00ff0000 ) >> 8) | \
20 (((x) & 0xff000000 ) >> 24))
21
22#define SWAP16(x) (x) = \
23 ((((x) & 0x00ff ) << 8) | \
24 (((x) & 0xff00 ) >> 8))
25
26#define SPANS_COMMON(x1, w1, x2, w2) \
27(!(( (int)((x2) + (int)(w2)) <= (int)(x1)) || (int)((x2) >= (int)((x1) + (int)(w1)))))
28
29#define RECTS_INTERSECT(x, y, w, h, xx, yy, ww, hh) \
30((SPANS_COMMON((x), (w), (xx), (ww))) && (SPANS_COMMON((y), (h), (yy), (hh))))
31
32#define RECTS_CLIP_TO_RECT(_x, _y, _w, _h, _cx, _cy, _cw, _ch) \
33{ \
34 if (RECTS_INTERSECT(_x, _y, _w, _h, _cx, _cy, _cw, _ch)) \
35 { \
36 if ((int)_x < (int)(_cx)) \
37 { \
38 if ((int)_w + ((int)_x - (int)(_cx)) < 0) _w = 0; \
39 else _w += ((int)_x - (int)(_cx)); \
40 _x = (_cx); \
41 } \
42 if ((int)(_x + _w) > (int)((_cx) + (_cw))) \
43 _w = (_cx) + (_cw) - _x; \
44 if ((int)_y < (int)(_cy)) \
45 { \
46 if ((int)_h + ((int)_y - (int)(_cy)) < 0) _h = 0; \
47 else _h += ((int)_y - (int)(_cy)); \
48 _y = (_cy); \
49 } \
50 if ((int)(_y + _h) > (int)((_cy) + (_ch))) \
51 _h = (_cy) + (_ch) - _y; \
52 } \
53 else \
54 { \
55 _w = 0; _h = 0; \
56 } \
57}
58
59
60#define INTERP_VAL(out, in1, in2, in3, in4, interp_x, interp_y) \
61 { \
62 int _v, _vv; \
63 \
64 _v = (256 - (interp_x)) * (in1); \
65 if ((interp_x) > 0) _v += (interp_x) * (in2); \
66 _v *= (256 - (interp_y)); \
67 if ((interp_y) > 0) \
68 { \
69 _vv = (256 - (interp_x)) * (in3); \
70 if ((interp_x) > 0) _vv += (interp_x) * (in4); \
71 _vv *= (interp_y); \
72 (out) = ((_v + _vv) >> 16); \
73 } \
74 else (out) = (_v >> 16); \
75 }
76
77#define INTERP_2(in1, in2, interp, interp_inv) \
78 ((in1 * interp_inv) + (in2 * interp)) >> 8
79
80
81#define CONVERT_LOOP_START_ROT_0() \
82 src_ptr = src; \
83 for (y = 0; y < h; y++) \
84 { \
85 for (x = 0; x < w; x++) \
86 {
87
88#define CONVERT_LOOP_END_ROT_0() \
89 dst_ptr++; \
90 src_ptr++; \
91 } \
92 src_ptr += src_jump; \
93 dst_ptr += dst_jump; \
94 }
95
96#define CONVERT_LOOP_START_ROT_180() \
97 src_ptr = src + (w - 1) + ((h - 1) * (w + src_jump)); \
98 for (y = 0; y < h; y++) \
99 { \
100 for (x = 0; x < w; x++) \
101 {
102
103#define CONVERT_LOOP_END_ROT_180() \
104 dst_ptr++; \
105 src_ptr--; \
106 } \
107 src_ptr = src + (w - 1) + ((h - y - 2) * (w + src_jump)); \
108 dst_ptr += dst_jump; \
109 }
110
111#define CONVERT_LOOP_START_ROT_270() \
112 src_ptr = src + ((w - 1) * (h + src_jump)); \
113 for (y = 0; y < h; y++) \
114 { \
115 for (x = 0; x < w; x++) \
116 {
117
118#define CONVERT_LOOP_END_ROT_270() \
119 dst_ptr++; \
120 src_ptr -= (h + src_jump); \
121 } \
122 src_ptr = src + ((w - 1) * (h + src_jump)) + (y + 1); \
123 dst_ptr += dst_jump; \
124 }
125
126#define CONVERT_LOOP_START_ROT_90() \
127 src_ptr = src + (h - 1); \
128 for (y = 0; y < h; y++) \
129 { \
130 for (x = 0; x < w; x++) \
131 {
132
133#define CONVERT_LOOP_END_ROT_90() \
134 dst_ptr++; \
135 src_ptr += (h + src_jump); \
136 } \
137 src_ptr = src + (h - 1) - y - 1; \
138 dst_ptr += dst_jump; \
139 }
140
141#define CONVERT_LOOP2_START_ROT_0() \
142 src_ptr = src; \
143 for (y = 0; y < h; y++) \
144 { \
145 for (x = 0; x < w; x++) \
146 {
147
148#define CONVERT_LOOP2_INC_ROT_0() \
149src_ptr++; \
150x++;
151
152#define CONVERT_LOOP2_END_ROT_0() \
153 dst_ptr+=2; \
154 src_ptr++; \
155 } \
156 src_ptr += src_jump; \
157 dst_ptr += dst_jump; \
158 }
159
160#define CONVERT_LOOP2_START_ROT_180() \
161 src_ptr = src + (w - 1) + ((h - 1) * (w + src_jump)); \
162 for (y = 0; y < h; y++) \
163 { \
164 for (x = 0; x < w; x++) \
165 {
166
167#define CONVERT_LOOP2_INC_ROT_180() \
168src_ptr--; \
169x++;
170
171#define CONVERT_LOOP2_END_ROT_180() \
172 dst_ptr+=2; \
173 src_ptr--; \
174 } \
175 src_ptr = src + (w - 1) + ((h - y - 2) * (w + src_jump)); \
176 dst_ptr += dst_jump; \
177 }
178
179#define CONVERT_LOOP2_START_ROT_270() \
180 src_ptr = src + ((w - 1) * (h + src_jump)); \
181 for (y = 0; y < h; y++) \
182 { \
183 for (x = 0; x < w; x++) \
184 {
185
186#define CONVERT_LOOP2_INC_ROT_270() \
187src_ptr -= (h + src_jump); \
188x++;
189
190#define CONVERT_LOOP2_END_ROT_270() \
191 dst_ptr+=2; \
192 src_ptr -= (h + src_jump); \
193 } \
194 src_ptr = src + ((w - 1) * (h + src_jump)) + (y + 1); \
195 dst_ptr += dst_jump; \
196 }
197
198#define CONVERT_LOOP2_START_ROT_90() \
199 src_ptr = src + (h - 1); \
200 for (y = 0; y < h; y++) \
201 { \
202 for (x = 0; x < w; x++) \
203 {
204
205#define CONVERT_LOOP2_INC_ROT_90() \
206src_ptr += (h + src_jump); \
207x++;
208
209#define CONVERT_LOOP2_END_ROT_90() \
210 dst_ptr+=2; \
211 src_ptr += (h + src_jump); \
212 } \
213 src_ptr = src + (h - 1) - y - 1; \
214 dst_ptr += dst_jump; \
215 }
216
217#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 @@
1#ifndef _LOVE_H_
2#define _LOVE_H_
3
4
5
6/*
7
8What do we need as an internal world object format?
9
10Can't call it Things, that's taken already.
11
12"Stuffs" works though. B-)
13
14Love server needs to manage in world stuffs, and send changes to everyone.
15
16Extantz needs to manage what's shown in world, and edit that stuffs.
17
18Combining the data structures seems sane. Letting the love server
19define those data structures also seems sane, hence this file.
20
21
22Extantz needs -
23 what it looks like (Evas_3D stuff)
24 "link sets"
25 what is attached to what
26 mesh
27 vertices, triangles, ...
28 local position and orientation relative to parent
29 material
30 textures
31 colours, including alpha
32 light
33 shade mode
34 where it is
35 position, orientation
36 animation stuff
37
38
39common
40 UUID
41 name & description
42 owner
43 position, orientation
44 "link sets"
45
46
47love needs
48 UUID
49 name & description
50 owner
51 position, orientation
52 "link sets"
53 LL used a list of prims, we can do better I'm sure.
54 Though for the sake of this experimental version, just use an array of stuffs.
55 contents
56 scripts, cards, other stuffs, animations, sounds, textures, ...
57 content types
58
59*/
60
61
62/* Stuffs is a single "primitive" object, it can be -
63 single mesh object - NOTE: Should include a list of materials.
64 LL style prim, including tree, defined as a small bunch of data defining the type and parameters
65 LL style mesh "file"
66 single mesh file, collada, other mesh format
67 height field, for land, or water
68 LuaSL script
69 "notecard", just a text file, with no limits
70 animation, BVH, Alice's BVJ, or perhaps any other animation file format
71 sounds, MP3, other sound formats
72 textures, PNG, JPEG, JPEG2000, TIFF, GIF, other texture formats
73 other LL stuff
74 landmark
75 clothing
76 body part, shape, skin, hair, or eyes
77 gesture
78 calling card
79*/
80
81#include "evas_macros.h"
82#include "evas_3d_utils.h" // TODO - Hopefully I can convince the authors to make this public.
83
84#include "Runnr.h"
85
86
87typedef struct _vec4
88{
89 float x;
90 float y;
91 float z;
92 float w;
93} vec4;
94
95typedef struct _vec3
96{
97 float x;
98 float y;
99 float z;
100} vec3;
101
102typedef struct _vec2
103{
104 float x;
105 float y;
106} vec2;
107
108
109typedef struct _material
110{
111 int face;
112 //type?
113 char texture[PATH_MAX];
114 //colour
115 //alpha
116 //other stuff
117} Material;
118
119typedef struct _mesh
120{
121 char fileName[PATH_MAX];
122 //type
123 vec3 pos;
124 vec4 rot;
125 Eina_Inarray materials; // Material
126 Eina_Inarray parts; // Mesh
127} Mesh;
128
129typedef struct _stuffs
130{
131 char UUID[32], *name, *description, owner[32];
132 //type
133 union
134 {
135 Mesh *mesh;
136 script *scrip; // Not a typo, C++ is fussy about reusing names like this.
137 void *other;
138 } details;
139} Stuffs;
140
141
142typedef struct _loveStuffs
143{
144 Stuffs stuffs;
145 Eina_Inarray contents; // Stuffs
146} LoveStuffs;
147
148typedef struct _extantzStuffs
149{
150 Stuffs stuffs;
151// Evas_3D_Mesh *mesh;
152// Evas_3D_Node *mesh_node; // Multiple Evas_3D_Mesh's can be in one Evas_3D_Node
153 Eina_Inarray *materials; // Evas_3D_Material
154 Eina_Inarray *textures; // Evas_3D_Texture
155} ExtantzStuffs;
156
157
158/* Data flow
159
160love server starts up
161 scans sim disk structure looking for scripts in stuffs
162 keep track of which script is in which stuffs
163 -> LuaSL compile script
164 -> LuaSL load this saved state
165 -> LuaSL run script
166
167Extantz client starts up
168 -> love login(name, password)
169 loads user details
170 <- love this is your user uuid
171 get sim details from lspace at this URL (or local disk directory file://)
172 -> lspace gimme the sim (or just pick up the index.omg file from disk)
173 <- lspace index.omg
174 figure out which mesh stuffs to load
175 -> lspace gimme(uuid) (or load it from disk)
176 <- lspace uuid.omg
177 figure out which mesh and texture files to load
178 -> lspace gimme this mesh file (or load it from disk)
179 <- lspace mesh file
180 -> lspace gimme this texture file (or load it from disk)
181 <- lspace texture file
182
183 user clicks on in world stuffs
184 -> love touched(user uuid, stuffs.uuid)
185 looks up stuffs, loops through scripts
186 -> LuaSL script.uuid.touch_start() and the detected stuff
187
188 user edits stuffs in world
189 -> love get contents(stuffs.uuid)
190 loads stuffs.omg from disk
191 loads stuffs.index.omg
192 <- love here's the list of contents Stuffs
193 -> love change this bit
194 changes that bit and stores on disk
195 send update nails commands to everyone/thing watching
196*/
197
198#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 @@
2#define _WINFANG_H_ 2#define _WINFANG_H_
3 3
4 4
5#include <Eo.h>
6#include <Eina.h>
7#include <Evas.h>
8#include <Elementary.h> 5#include <Elementary.h>
9#include <EPhysics.h> 6#include <EPhysics.h>
10 7