diff options
Diffstat (limited to '')
-rw-r--r-- | src/libraries/evas_3d_utils.h | 1557 | ||||
-rw-r--r-- | src/libraries/love.h | 1 |
2 files changed, 0 insertions, 1558 deletions
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 | |||
10 | typedef struct _Evas_Color Evas_Color; | ||
11 | typedef struct _Evas_Vec2 Evas_Vec2; | ||
12 | typedef struct _Evas_Vec3 Evas_Vec3; | ||
13 | typedef struct _Evas_Vec4 Evas_Vec4; | ||
14 | typedef struct _Evas_Mat2 Evas_Mat2; | ||
15 | typedef struct _Evas_Mat3 Evas_Mat3; | ||
16 | typedef struct _Evas_Mat4 Evas_Mat4; | ||
17 | typedef struct _Evas_Box2 Evas_Box2; | ||
18 | typedef struct _Evas_Box3 Evas_Box3; | ||
19 | typedef struct _Evas_Triangle3 Evas_Triangle3; | ||
20 | typedef struct _Evas_Ray3 Evas_Ray3; | ||
21 | |||
22 | struct _Evas_Color | ||
23 | { | ||
24 | Evas_Real r; | ||
25 | Evas_Real g; | ||
26 | Evas_Real b; | ||
27 | Evas_Real a; | ||
28 | }; | ||
29 | |||
30 | struct _Evas_Vec2 | ||
31 | { | ||
32 | Evas_Real x; | ||
33 | Evas_Real y; | ||
34 | }; | ||
35 | |||
36 | struct _Evas_Vec3 | ||
37 | { | ||
38 | Evas_Real x; | ||
39 | Evas_Real y; | ||
40 | Evas_Real z; | ||
41 | }; | ||
42 | |||
43 | struct _Evas_Vec4 | ||
44 | { | ||
45 | Evas_Real x; | ||
46 | Evas_Real y; | ||
47 | Evas_Real z; | ||
48 | Evas_Real w; | ||
49 | }; | ||
50 | |||
51 | struct _Evas_Mat2 | ||
52 | { | ||
53 | Evas_Real m[4]; | ||
54 | int flags; | ||
55 | }; | ||
56 | |||
57 | struct _Evas_Mat3 | ||
58 | { | ||
59 | Evas_Real m[9]; | ||
60 | int flags; | ||
61 | }; | ||
62 | |||
63 | struct _Evas_Mat4 | ||
64 | { | ||
65 | Evas_Real m[16]; | ||
66 | int flags; | ||
67 | }; | ||
68 | |||
69 | struct _Evas_Box2 | ||
70 | { | ||
71 | Evas_Vec2 p0; | ||
72 | Evas_Vec2 p1; | ||
73 | }; | ||
74 | |||
75 | struct _Evas_Box3 | ||
76 | { | ||
77 | Evas_Vec3 p0; | ||
78 | Evas_Vec3 p1; | ||
79 | }; | ||
80 | |||
81 | struct _Evas_Triangle3 | ||
82 | { | ||
83 | Evas_Vec3 p0; | ||
84 | Evas_Vec3 p1; | ||
85 | Evas_Vec3 p2; | ||
86 | }; | ||
87 | |||
88 | struct _Evas_Ray3 | ||
89 | { | ||
90 | Evas_Vec3 org; | ||
91 | Evas_Vec3 dir; | ||
92 | }; | ||
93 | |||
94 | /* 2D vector */ | ||
95 | static inline void | ||
96 | evas_vec2_set(Evas_Vec2 *dst, Evas_Real x, Evas_Real y) | ||
97 | { | ||
98 | dst->x = x; | ||
99 | dst->y = y; | ||
100 | } | ||
101 | |||
102 | static inline void | ||
103 | evas_vec2_array_set(Evas_Vec2 *dst, const Evas_Real *v) | ||
104 | { | ||
105 | dst->x = v[0]; | ||
106 | dst->y = v[1]; | ||
107 | } | ||
108 | |||
109 | static inline void | ||
110 | evas_vec2_copy(Evas_Vec2 *dst, const Evas_Vec2 *src) | ||
111 | { | ||
112 | dst->x = src->x; | ||
113 | dst->y = src->y; | ||
114 | } | ||
115 | |||
116 | static inline void | ||
117 | evas_vec2_negate(Evas_Vec2 *out, const Evas_Vec2 *v) | ||
118 | { | ||
119 | out->x = -v->x; | ||
120 | out->y = -v->y; | ||
121 | } | ||
122 | |||
123 | static inline void | ||
124 | evas_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 | |||
130 | static inline void | ||
131 | evas_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 | |||
137 | static inline void | ||
138 | evas_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 | |||
144 | static inline Evas_Real | ||
145 | evas_vec2_dot_product(const Evas_Vec2 *a, const Evas_Vec2 *b) | ||
146 | { | ||
147 | return (a->x * b->x) + (a->y * b->y); | ||
148 | } | ||
149 | |||
150 | static inline Evas_Real | ||
151 | evas_vec2_length_get(const Evas_Vec2 *v) | ||
152 | { | ||
153 | return (Evas_Real)sqrt((double)((v->x * v->x) + (v->y * v->y))); | ||
154 | } | ||
155 | |||
156 | static inline Evas_Real | ||
157 | evas_vec2_length_square_get(const Evas_Vec2 *v) | ||
158 | { | ||
159 | return (v->x * v->x) + (v->y * v->y); | ||
160 | } | ||
161 | |||
162 | static inline Evas_Real | ||
163 | evas_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 | |||
171 | static inline Evas_Real | ||
172 | evas_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 | |||
180 | static inline void | ||
181 | evas_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 | |||
187 | static inline void | ||
188 | evas_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 | |||
198 | static inline void | ||
199 | evas_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 | |||
209 | static inline void | ||
210 | evas_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 */ | ||
221 | static inline void | ||
222 | evas_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 | |||
229 | static inline void | ||
230 | evas_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 | |||
237 | static inline void | ||
238 | evas_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 | |||
245 | static inline void | ||
246 | evas_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 | |||
253 | static inline void | ||
254 | evas_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 | |||
261 | static inline void | ||
262 | evas_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 | |||
269 | static inline void | ||
270 | evas_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 | |||
277 | static inline void | ||
278 | evas_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 | |||
285 | static inline Evas_Real | ||
286 | evas_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 | |||
291 | static inline void | ||
292 | evas_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 | |||
303 | static inline Evas_Real | ||
304 | evas_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 | |||
309 | static inline Evas_Real | ||
310 | evas_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 | |||
315 | static inline Evas_Real | ||
316 | evas_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 | |||
324 | static inline Evas_Real | ||
325 | evas_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 | |||
333 | static inline void | ||
334 | evas_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 | |||
340 | static inline void | ||
341 | evas_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 | |||
358 | static inline void | ||
359 | evas_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 | |||
377 | static inline void | ||
378 | evas_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 | |||
395 | static inline void | ||
396 | evas_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 */ | ||
415 | static inline void | ||
416 | evas_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 | |||
424 | static inline void | ||
425 | evas_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 | |||
433 | static inline void | ||
434 | evas_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 | |||
442 | static inline void | ||
443 | evas_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 | |||
456 | static inline void | ||
457 | evas_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 | |||
465 | static inline void | ||
466 | evas_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 | |||
474 | static inline void | ||
475 | evas_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 | |||
483 | static inline void | ||
484 | evas_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 | |||
492 | static inline void | ||
493 | evas_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 | |||
501 | static inline Evas_Real | ||
502 | evas_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 | |||
508 | static inline Evas_Real | ||
509 | evas_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 | |||
514 | static inline Evas_Real | ||
515 | evas_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 | |||
523 | static inline Evas_Real | ||
524 | evas_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 | |||
532 | static inline void | ||
533 | evas_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 | |||
539 | static inline void | ||
540 | evas_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 | |||
558 | static inline void | ||
559 | evas_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 | |||
569 | static inline void | ||
570 | evas_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 | |||
578 | static inline void | ||
579 | evas_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 | |||
587 | static inline void | ||
588 | evas_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 */ | ||
597 | static inline void | ||
598 | evas_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 | |||
623 | static inline void | ||
624 | evas_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 | |||
630 | static inline void | ||
631 | evas_mat4_copy(Evas_Mat4 *dst, const Evas_Mat4 *src) | ||
632 | { | ||
633 | memcpy(dst, src, sizeof(Evas_Mat4)); | ||
634 | } | ||
635 | |||
636 | static inline void | ||
637 | evas_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 | |||
679 | static inline void | ||
680 | evas_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 | |||
696 | static inline void | ||
697 | evas_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 | |||
734 | static inline void | ||
735 | evas_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 | |||
767 | static inline void | ||
768 | evas_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 | |||
799 | static inline void | ||
800 | evas_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 | |||
950 | static inline void | ||
951 | evas_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 | |||
966 | static inline void | ||
967 | evas_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 */ | ||
1000 | static inline void | ||
1001 | evas_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 | |||
1016 | static inline void | ||
1017 | evas_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 | |||
1023 | static inline void | ||
1024 | evas_mat3_copy(Evas_Mat3 *dst, const Evas_Mat3 *src) | ||
1025 | { | ||
1026 | memcpy(dst, src, sizeof(Evas_Mat3)); | ||
1027 | } | ||
1028 | |||
1029 | static inline void | ||
1030 | evas_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 | |||
1063 | static inline void | ||
1064 | evas_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 | |||
1079 | static inline void | ||
1080 | evas_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 | |||
1122 | static inline void | ||
1123 | evas_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 */ | ||
1139 | static inline void | ||
1140 | evas_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 | |||
1150 | static inline void | ||
1151 | evas_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 | |||
1157 | static inline void | ||
1158 | evas_mat2_copy(Evas_Mat2 *dst, const Evas_Mat2 *src) | ||
1159 | { | ||
1160 | memcpy(dst, src, sizeof(Evas_Mat2)); | ||
1161 | } | ||
1162 | |||
1163 | static inline void | ||
1164 | evas_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 | |||
1191 | static inline void | ||
1192 | evas_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 | |||
1207 | static inline void | ||
1208 | evas_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 | |||
1235 | static inline void | ||
1236 | evas_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 | |||
1251 | static inline void | ||
1252 | evas_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 | |||
1261 | static inline void | ||
1262 | evas_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 | |||
1273 | static inline void | ||
1274 | evas_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 | |||
1280 | static inline void | ||
1281 | evas_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 | |||
1287 | static inline void | ||
1288 | evas_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 | |||
1294 | static inline void | ||
1295 | evas_box3_transform(Evas_Box3 *out EINA_UNUSED, const Evas_Box3 *box EINA_UNUSED, const Evas_Mat4 *mat EINA_UNUSED) | ||
1296 | { | ||
1297 | /* TODO: */ | ||
1298 | } | ||
1299 | |||
1300 | static inline void | ||
1301 | evas_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 | |||
1313 | static inline void | ||
1314 | evas_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 | |||
1332 | static inline void | ||
1333 | evas_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 | |||
1345 | static inline void | ||
1346 | evas_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 | |||
1367 | static inline void | ||
1368 | evas_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 | |||
1404 | static inline void | ||
1405 | evas_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 | |||
1433 | static inline void | ||
1434 | evas_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 | |||
1478 | static inline void | ||
1479 | evas_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 | |||
1487 | static inline void | ||
1488 | evas_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 | |||
1496 | static inline void | ||
1497 | evas_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 | |||
1539 | static inline Eina_Bool | ||
1540 | evas_box3_ray3_intersect(const Evas_Box3 *box EINA_UNUSED, const Evas_Ray3 *ray EINA_UNUSED) | ||
1541 | { | ||
1542 | /* TODO: */ | ||
1543 | return EINA_TRUE; | ||
1544 | } | ||
1545 | |||
1546 | static inline Evas_Real | ||
1547 | evas_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 | ||