Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / effects / inc / utils / FUiEffects_UtilsLuaMat4.h
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file        FUiEffects_UtilsLuaMat4.h
19  * @brief       This file contains a definition of LuaMat4 class template
20  *
21  */
22
23 #ifndef _FUI_EFFECTS_INTERNAL_UTILS_LUA_MAT4_H_
24 #define _FUI_EFFECTS_INTERNAL_UTILS_LUA_MAT4_H_
25
26 namespace Tizen { namespace Ui { namespace Effects { namespace _Utils
27 {
28
29 template<class T> class Matrix4;
30
31 /**
32  * @template class              LuaMat4
33  * @brief                               This class is needed for model matrix manipulations
34  *                                              from scripts such as rotation, scale, translate and set identity matrix
35  */
36
37 template<class T>
38 class LuaMat4
39 {
40 public:
41         /**
42          * @brief               LuaMat4 class default constructor
43          */
44         inline LuaMat4(void);
45
46         /**
47          * @brief               LuaMat4 class copy constructor
48          */
49         inline LuaMat4(const LuaMat4<T>& rhs);
50
51         /**
52          * @brief               LuaMat4 class constructor by elements
53          */
54         inline LuaMat4(T m0,  T m1,  T m2,  T m3,
55                                    T m4,  T m5,  T m6,  T m7,
56                                    T m8,  T m9,  T m10, T m11,
57                                    T m12, T m13, T m14, T m15);
58
59         /**
60          * @brief               LuaMat4 class constructor by one element
61          */
62         inline LuaMat4(T m);
63
64         /**
65          * @brief               LuaMat4 class adaptive constructor from class Matrix4
66          */
67         inline LuaMat4(const Matrix4<T> &mat4);
68
69         /**
70          * @brief               Sets identity matrix
71          */
72         inline void SetIdentity(void);
73
74         /**
75          * @brief               Translates model matrix by values X0, Y0 and Z0 relative to the axes
76          */
77         inline void Translate(T x0, T y0, T z0);
78
79         /**
80          * @brief               Scales model matrix by the factors ax, ay, az relative to the axes
81          * @remark              The coordinates of point (0,0,0) do not change
82          */
83         inline bool Scale(T ax, T ay, T az);
84
85         /**
86          * @brief               Scales model matrix by the factors ax, ay, az relative to the axes
87          * @remark              The coordinates of point (x0, y0, z0) do not change
88          */
89         inline bool Scale(T ax, T ay, T az, T x0, T y0, T z0);
90
91         /**
92          * @brief               Rotates model matrix by the Angle around axis Z
93          *                              drawn from the point (0,0,0) in global coordinates
94          */
95         inline void RotateAroundAxisZ(T angle);
96
97         /**
98          * @brief               Rotates model matrix by the Angle around axis Z
99          *                              drawn from the point (x0, y0, z0) in global coordinates
100          */
101         inline void RotateAroundAxisZ(T angle, T x0, T y0, T z0);
102
103         /**
104          * @brief               Rotates model matrix by the Angle around axis X
105          *                              drawn from the point (0, 0, 0) in global coordinates
106          */
107         inline void RotateAroundAxisX(T angle);
108
109         /**
110          * @brief               Rotates model matrix by the Angle around axis X
111          *                              drawn from the point (x0, y0, z0) in global coordinates
112          */
113         inline void RotateAroundAxisX(T angle, T x0, T y0, T z0);
114
115         /**
116          * @brief               Rotates model matrix by the Angle around axis Y
117          *                              drawn from the point (0, 0, 0) in global coordinates
118          */
119         inline void RotateAroundAxisY(T angle);
120
121         /**
122          * @brief               Rotates model matrix by the Angle around axis Y
123          *                              drawn from the point (x0,y0,z0) in global coordinates
124          */
125         inline void RotateAroundAxisY(T angle, T x0, T y0, T z0);
126
127         /**
128          * @brief               Rotates model matrix by the Angle around axis with coordinates Ax, Ay, Az
129          *                              drawn from the point (0,0,0) in global coordinates
130          */
131         inline bool RotateAroundAxisArbitrary(T angle, T ax, T ay, T az);
132
133         /**
134          * @brief               Rotates model matrix by the Angle around axis with coordinates Ax, Ay, Az
135          *                              drawn from the point (x0, y0, z0) in global coordinates
136          */
137         inline bool RotateAroundAxisArbitrary(T angle, T ax, T ay, T az, T x0, T y0, T z0);
138
139         /**
140          * @brief               Overloading multiplication operator of two matrix as class LuaMat4 instances
141          */
142         inline LuaMat4<T> operator*(const LuaMat4<T> &mul) const;
143
144         /**
145          * @brief               Overloading multiplication operator of matrix and number
146          */
147         inline LuaMat4<T> operator*(T mul) const;
148
149         /**
150          * @brief               Overloading addition operator of two matrix
151          */
152         inline LuaMat4<T> operator+(const LuaMat4<T> &add) const;
153
154         /**
155          * @brief               Overloading subtraction operator of two matrix
156          */
157         inline LuaMat4<T> operator-(const LuaMat4<T> &sub) const;
158
159         /**
160          * @brief               Overloading the unary minus operator
161          */
162         inline LuaMat4<T> operator-(void)const;
163
164         /**
165          * @brief               Overloading the assignment operator
166          */
167         inline LuaMat4<T> &operator=(const LuaMat4<T> &orig);
168
169         /**
170          * @brief               Casts LuaMat4 class instance to type Matrix4
171          */
172         inline operator Matrix4<T>(void)const;
173
174 protected:
175
176 private:
177
178
179 public:
180
181 protected:
182
183 private:
184
185         T __m[16];      /**< the matrix 4*4 as one dimensional array of type T */
186
187 }; // LuaMat4
188
189 typedef LuaMat4<float> LuaMatrix4;
190
191 } } } } // Tizen::Ui::Effects::_Utils
192
193
194 #include <string.h>
195 #include <limits>
196
197 namespace Tizen { namespace Ui { namespace Effects { namespace _Utils
198 {
199
200
201 template<class T> inline
202 LuaMat4<T>::LuaMat4(void)
203 {
204         SetIdentity();
205 }
206
207 template<class T> inline
208 LuaMat4<T>::LuaMat4(T m)
209 {
210         for (int i = 0; i < 16; ++i)
211         {
212                 __m[i] = m;
213         }
214 }
215
216 template<class T> inline
217 LuaMat4<T>::LuaMat4(const LuaMat4<T> &rhs)
218 {
219         memcpy(this->__m, rhs.__m, 16 * sizeof(T));
220 }
221
222 template<class T> inline
223 LuaMat4<T>::LuaMat4(const Matrix4<T> &mat4)
224 {
225         memcpy( __m,     &mat4.i, 4 * sizeof(T));
226         memcpy(&__m[4],  &mat4.j, 4 * sizeof(T));
227         memcpy(&__m[8],  &mat4.k, 4 * sizeof(T));
228         memcpy(&__m[12], &mat4.c, 4 * sizeof(T));
229 }
230
231 template<class T> inline
232 LuaMat4<T>::LuaMat4(T m0,  T m1,  T m2,  T m3,
233                                         T m4,  T m5,  T m6,  T m7,
234                                         T m8,  T m9,  T m10, T m11,
235                                         T m12, T m13, T m14, T m15)
236 {
237         T* pm = __m;
238         *(pm++) = m0;
239         *(pm++) = m1;
240         *(pm++) = m2;
241         *(pm++) = m3;
242         *(pm++) = m4;
243         *(pm++) = m5;
244         *(pm++) = m6;
245         *(pm++) = m7;
246         *(pm++) = m8;
247         *(pm++) = m9;
248         *(pm++) = m10;
249         *(pm++) = m11;
250         *(pm++) = m12;
251         *(pm++) = m13;
252         *(pm++) = m14;
253         *(pm++) = m15;
254 }
255
256 template<class T> inline void
257 LuaMat4<T>::SetIdentity(void)
258 {
259         memset(__m, 0, 16 * sizeof(T));
260
261         T one = static_cast<T>(1);
262         __m[0] = one;
263         __m[5] = one;
264         __m[10] = one;
265         __m[15] = one;
266
267         return;
268 }
269
270 template<class T> inline void
271 LuaMat4<T>::Translate(T x0, T y0, T z0)
272 {
273         T* pnt0 = __m;
274         T* pnt3Init = &(__m[12]);
275         T* pnt3 = pnt3Init;
276
277         const T* pArg[3] = {&x0, &y0, &z0};
278         const  T** p = pArg;
279         for (short i = 0, j = 0; i < 12; ++i, ++j)
280         {
281                 if (j == 4)
282                 {
283                         j = 0;
284                         p++;
285                         pnt3 = pnt3Init;
286                 }
287                 *pnt0 += *(pnt3++) * (**p);
288                 pnt0++;
289         }
290
291         return;
292 }
293
294 template<class T> inline bool
295 LuaMat4<T>::Scale(T aX, T aY, T aZ)
296 {
297         T epsilon = std::numeric_limits<T>::epsilon();
298         if (aX <= -epsilon || aY <= -epsilon || aZ <= -epsilon)
299         {
300                 return false;
301         }
302
303         T *pnt0 = __m;
304         const T* pArg[3] = {&aX, &aY, &aZ};
305         const T** p = pArg;
306         for (short i = 0, j = 0; i < 12; ++i, ++j)
307         {
308                 if (j == 4)
309                 {
310                         j = 0;
311                         ++p;
312                 }
313                 *pnt0 *= (**p);
314                 pnt0++;
315         }
316
317         return true;
318 }
319
320 template<class T> inline bool
321 LuaMat4<T>::Scale(T aX, T aY, T aZ, T x0, T y0, T z0)
322 {
323         Translate(-x0, -y0, -z0);
324         bool res = Scale(aX, aY, aZ);
325         Translate(x0, y0, z0);
326
327         return res;
328 }
329
330 template<class T> inline void
331 LuaMat4<T>::RotateAroundAxisZ(T angle)
332 {
333         // ---- for case T==float ----------
334         float coi = cosf(angle);
335         float sii = sinf(angle);
336         //----------------------------------
337         float co = coi;
338         float si = sii;
339
340         T* pnt1Init = __m;
341         T* pnt2Init = &(__m[4]);
342         T* pnt1 = pnt1Init;
343         T* pnt2 = pnt2Init;
344         T mTemp[8];
345         T* pMTemp = mTemp;
346         for (short i = 0, j = 0; i < 8; ++i, ++j)
347         {
348                 if (j == 4)
349                 {
350                         j = 0;
351                         co = -sii;
352                         si = coi;
353                         pnt1 = pnt1Init;
354                         pnt2 = pnt2Init;
355                 }
356                 *pMTemp = (*(pnt1++) * co + *(pnt2++) * si);
357                 pMTemp++;
358         }
359         memcpy(__m, mTemp, 8 * sizeof(T));
360
361         return;
362 }
363
364 template<class T> inline void
365 LuaMat4<T>::RotateAroundAxisZ(T angle, T x0, T y0, T z0)
366 {
367         Translate(-x0, -y0, -z0);
368         RotateAroundAxisZ(angle);
369         Translate(x0, y0, z0);
370
371         return;
372 }
373
374 template<class T> inline void
375 LuaMat4<T>::RotateAroundAxisX(T angle)
376 {
377         // ---- for case T==float ----------
378         float coi = cosf(angle);
379         float sii = sinf(angle);
380         //----------------------------------
381         float co = coi;
382         float si = -sii;
383
384         T* pnt1Init = &(__m[4]);
385         T* pnt2Init = &(__m[8]);
386         T* pnt1 = pnt1Init;
387         T* pnt2 = pnt2Init;
388         T mTemp[8];
389         T* pMTemp = mTemp;
390         for (short i = 0, j = 0; i < 8; ++i, ++j)
391         {
392                 if (j == 4)
393                 {
394                         j = 0;
395                         co = sii;
396                         si = coi;
397                         pnt1 = pnt1Init;
398                         pnt2 = pnt2Init;
399                 }
400                 *pMTemp = (*(pnt1++) * co + *(pnt2++) * si);
401                 pMTemp++;
402         }
403         memcpy(&(__m[4]), mTemp, 8 * sizeof(T));
404
405         return;
406 }
407
408 template<class T> inline void
409 LuaMat4<T>::RotateAroundAxisX(T angle, T x0, T y0, T z0)
410 {
411         Translate(-x0, -y0, -z0);
412         RotateAroundAxisX(angle);
413         Translate(x0, y0, z0);
414
415         return;
416 }
417
418 template<class T> inline void
419 LuaMat4<T>::RotateAroundAxisY(T angle)
420 {
421         // ---- for case T==float ----------
422         float coi = cosf(angle);
423         float sii = sinf(angle);
424         //----------------------------------
425         float co = coi;
426         float si = sii;
427
428         T* pnt1Init = __m;
429         T* pnt2Init = &(__m[8]);
430         T* pnt1 = pnt1Init;
431         T* pnt2 = pnt2Init;
432         T mTemp[8];
433         T* pMTemp = mTemp;
434         for (short i = 0, j = 0; i < 8; ++i, ++j)
435         {
436                 if (j == 4)
437                 {
438                         j = 0;
439                         co = -sii;
440                         si = coi;
441                         pnt1 = pnt1Init;
442                         pnt2 = pnt2Init;
443                 }
444                 *pMTemp = (*(pnt1++) * co + *(pnt2++) * si);
445                 pMTemp++;
446         }
447         memcpy(__m, mTemp, 4 * sizeof(T));
448         memcpy(&(__m[8]), &(mTemp[4]), 4 * sizeof(T));
449
450         return;
451 }
452
453 template<class T> inline void
454 LuaMat4<T>::RotateAroundAxisY(T angle, T x0, T y0, T z0)
455 {
456         Translate(-x0, -y0, -z0);
457         RotateAroundAxisY(angle);
458         Translate(x0, y0, z0);
459
460         return;
461 }
462
463 template<class T> inline bool
464 LuaMat4<T>::RotateAroundAxisArbitrary(T angle, T ax, T ay, T az)
465 {
466         // ---- for case T==float -------------------------------------
467         float c = cosf(angle);
468         float s = sinf(angle);
469
470         T len = sqrtf(ax * ax + ay * ay + az * az);
471         if (fabsf(len) <= std::numeric_limits<T>::epsilon())
472         {
473                 return false;
474         }
475         //-------------------------------------------------------------
476         T axn = ax / len;
477         T ayn = ay / len;
478         T azn = az / len;
479
480         LuaMat4<T> res(c + (1 - c) * axn * axn,         (1 - c) * axn * ayn - s * azn,          (1 - c) * axn * azn + s * ayn,          0,
481                                    (1 - c) * ayn * axn + s * azn,   c + (1 - c) * ayn * ayn,                    (1 - c) * ayn * azn - s * axn,          0,
482                                    (1 - c) * azn * axn - s * ayn,   (1 - c) * azn * ayn + s * axn,      c + (1 - c) * azn * azn,                0,
483                                    0,                                                           0,                                                              0,                                                              1);
484
485         *this = res * (*this);
486         return true;
487 }
488
489 template<class T> inline bool
490 LuaMat4<T>::RotateAroundAxisArbitrary(T angle, T ax, T ay, T az, T x0, T y0, T z0)
491 {
492         Translate(-x0, -y0, -z0);
493         bool res = RotateAroundAxisArbitrary(angle, ax, ay, az);
494         Translate(x0, y0, z0);
495
496         return res;
497 }
498
499 template<class T> inline LuaMat4<T>
500 LuaMat4<T>::operator*(const LuaMat4<T> &rhs) const
501 {
502         LuaMat4<T> res;
503         memset(res.__m, 0, 16 * sizeof(T));
504         const T* pThis = __m;
505         const T* pThisC;
506         const T* pMul = rhs.__m;
507         const T* pMulC;
508         T *pRes = res.__m;
509         short i, j, k;
510         for (k = 0; k < 4; ++k)
511         {
512                 for (j = 0; j < 4; ++j)
513                 {
514                         pThisC = pThis;
515                         pMulC = pMul;
516                         for (i = 0; i < 4; ++i)
517                         {
518                                 *pRes += *(pThisC++) * (*pMulC);
519                                 pMulC += 4;
520                         }
521                         pRes++;
522                         pMul++;
523                 }
524                 pThis += 4;
525                 pMul = rhs.__m;
526         }
527
528         return res;
529 }
530
531 template<class T> inline LuaMat4<T>
532 LuaMat4<T>::operator*(T rhs)const
533 {
534         LuaMat4<T> res(*this);
535         T *pRes = res.__m;
536
537         for (short i = 0; i < 15; ++i, ++pRes)
538         {
539                 *pRes *= rhs;
540         }
541
542         return res;
543 }
544
545 template<class T> inline LuaMat4<T>
546 LuaMat4<T>::operator+(const LuaMat4<T> &rhs)const
547 {
548         LuaMat4<T> res;
549         memset(res.__m, 0, 16*sizeof(T));
550         T *pRes = res.__m;
551         const T* pAdd1 = __m;
552         const T* pAdd2 = rhs.__m;
553
554         for (short i = 0; i < 15; ++i, ++pRes)
555         {
556                 *pRes = *(pAdd1++) + *(pAdd2++);
557         }
558
559         return res;
560 }
561
562 template<class T> inline LuaMat4<T>
563 LuaMat4<T>::operator-(void)const
564 {
565         LuaMat4<T> res(*this);
566         T *pRes = res.__m;
567
568         for (short i = 0; i < 15; ++i, ++pRes)
569         {
570                 *pRes = -(*pRes);
571         }
572
573         return res;
574 }
575
576 template<class T> inline LuaMat4<T>
577 LuaMat4<T>::operator-(const LuaMat4<T> &rhs)const
578 {
579         return *this + (-rhs);
580 }
581
582 template<class T> inline LuaMat4<T> &
583 LuaMat4<T>::operator=(const LuaMat4<T> &rhs)
584 {
585         memcpy(__m, rhs.__m, 16 * sizeof(T));
586         return *this;
587 }
588
589 template<class T> inline
590 LuaMat4<T>::operator Matrix4<T>(void)const
591 {
592         Matrix4<T> res(__m[0],  __m[1],  __m[2],  __m[3],
593                                    __m[4],  __m[5],  __m[6],  __m[7],
594                                    __m[8],  __m[9],  __m[10], __m[11],
595                                    __m[12], __m[13], __m[14], __m[15]);
596
597         return res;
598 }
599
600
601 } } } } // Tizen::Ui::Effects::_Utils
602
603 #endif //_FUI_EFFECTS_INTERNAL_UTILS_LUA_MAT4_H_