Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / effects / inc / utils / FUiEffects_UtilsMatrix3.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 /**
19  * @file       FUiEffects_UtilsMatrix3.h
20  * @brief      The Matrix3 class
21  *
22  */
23
24 #ifndef _FUI_EFFECTS_INTERNAL_UTILS_MATRIX3_H_
25 #define _FUI_EFFECTS_INTERNAL_UTILS_MATRIX3_H_
26
27 #include "FUiEffects_UtilsAdapterFunctions.h"
28
29 namespace Tizen { namespace Ui { namespace Effects { namespace _Utils
30 {
31         template<class T> class _Vector3;
32         template<class T> class _Vector2;
33         template<class T> class Matrix2;
34         template<class T> class Quaternion;
35
36         template<class T> class Matrix3
37         {
38             private:
39                 typedef Matrix3<T> SelfType;
40
41             public:
42                 _Vector3<T> i;
43                 _Vector3<T> j;
44                 _Vector3<T> k;
45
46                 inline Matrix3();
47                 inline explicit Matrix3(const T& aValue);
48                 inline explicit Matrix3(const T* aValue);
49                 inline Matrix3(const SelfType& aOther);
50                 inline Matrix3(const _Vector3<T>& aI, const _Vector3<T>& aJ, const _Vector3<T>& aC);
51                 inline Matrix3(const _Vector2<T>& aI, const _Vector2<T>& aJ, const _Vector2<T>& aC);
52                 inline Matrix3(const T& a11, const T& a12, const T& a13,
53                                const T& a21, const T& a22, const T& a23,
54                                const T& a31, const T& a32, const T& a33);
55
56                 inline SelfType& operator=(const SelfType& aRhv);
57
58                 inline SelfType& set(const T& aValue);
59                 inline SelfType& set(const T* aValue);
60                 inline SelfType& set(const SelfType& aOther);
61                 inline SelfType& set(const _Vector3<T>& aI, const _Vector3<T>& aJ, const _Vector3<T>& aC);
62                 inline SelfType& set(const _Vector2<T>& aI, const _Vector2<T>& aJ, const _Vector2<T>& aC);
63                 inline SelfType& set(const T& a11, const T& a12, const T& a13,
64                                      const T& a21, const T& a22, const T& a23,
65                                      const T& a31, const T& a32, const T& a33);
66
67                 inline SelfType& identity();
68                 inline static const SelfType& getIdentity();
69                 inline bool isIdentity() const;
70
71                 inline SelfType operator-() const;
72                 inline SelfType& inverse();
73                 inline SelfType getInversed() const;
74                 inline SelfType& transpose();
75                 inline SelfType getTransposed() const;
76
77                 inline SelfType& operator+=(const SelfType& aRhv);
78                 inline SelfType& operator+=(const T& aRhv);
79                 inline SelfType& operator-=(const SelfType& aRhv);
80                 inline SelfType& operator-=(const T& aRhv);
81                 inline SelfType& operator*=(const SelfType& aRhv);
82                 inline SelfType& operator*=(const T& aRhv);
83                 inline SelfType& operator/=(const T& aRhv);
84                 inline SelfType GetMultipliedByMember(const SelfType& aRhv) const;
85                 static inline SelfType createMultipliedByMember(const SelfType& aLhv, const SelfType& aRhv);
86                 inline SelfType& multiplyByMember(const SelfType& aRhv);
87                 inline SelfType getDividedByMember(const SelfType& aRhv) const;
88                 static inline SelfType createDividedByMember(const SelfType& aLhv, const SelfType& aRhv);
89                 inline SelfType& divideByMember(const SelfType& aRhv);
90
91                 inline T* getPointer();
92                 inline const T* getPointer() const;
93                 inline T& get(unsigned int aRow, unsigned int aColumn);
94                 inline const T& get(unsigned int aRow, unsigned int aColumn) const;
95                 inline T& get(unsigned int aAbsIndex);
96                 inline const T& get(unsigned int aAbsIndex) const;
97                 inline SelfType& set(unsigned int aRow, unsigned int aColumn, const T& aValue);
98                 inline SelfType& set(unsigned int aAbsIndex, const T& aValue);
99                 inline _Vector3<T>& getRow(unsigned int aRow);
100                 inline const _Vector3<T>& getRow(unsigned int aRow) const;
101                 inline SelfType& setRow(unsigned int aRow, const _Vector3<T>& aValue);
102                 inline _Vector3<T> getColumn(unsigned int aColumn) const;
103                 inline SelfType& setColumn(unsigned int aColumn, const _Vector3<T>& aValue);
104                 inline T& operator()(unsigned int aRow, unsigned int aColumn);
105                 inline const T& operator()(unsigned int aRow, unsigned int aColumn) const;
106                 inline T& operator()(unsigned int aAbsIndex);
107                 inline const T& operator()(unsigned int aAbsIndex) const;
108                 inline T& operator[](unsigned int aAbsIndex);
109                 inline const T& operator[](unsigned int aAbsIndex) const;
110
111                 inline SelfType& lerp(const SelfType& aTo, const T& aCoeff);
112                 inline SelfType getLerped(const SelfType& aTo, const T& aCoeff) const;
113                 inline SelfType& makeLerped(const SelfType& aFrom, const SelfType& aTo, const T& aCoeff);
114                 static inline SelfType createLerped(const SelfType& aFrom, const SelfType& aTo, const T& aCoeff);
115                 inline SelfType& slerp(const SelfType& aTo, const T& aCoeff);
116                 inline SelfType getSlerped(const SelfType& aTo, const T& aCoeff) const;
117                 inline SelfType& makeSlerped(const SelfType& aFrom, const SelfType& aTo, const T& aCoeff);
118                 static inline SelfType createSlerped(const SelfType& aFrom, const SelfType& aTo, const T& aCoeff);
119
120                 inline T determinant() const;
121
122                 inline _Vector3<T>& applyTransform(_Vector3<T>& aVector) const;
123                 inline _Vector3<T> getAppliedTransform(const _Vector3<T>& aVector) const;
124                 inline _Vector3<T>& applyRotation(_Vector3<T>& aVector) const;
125                 inline _Vector3<T> getAppliedRotation(const _Vector3<T>& aVector) const;
126                 inline _Vector3<T>& applyTranslate(_Vector3<T>& aVector) const;
127                 inline _Vector3<T> getAppliedTranslate(const _Vector3<T>& aVector) const;
128
129                 inline _Vector2<T>& applyTransform(_Vector2<T>& aVector) const;
130                 inline _Vector2<T> getAppliedTransform(const _Vector2<T>& aVector) const;
131                 inline _Vector2<T>& applyRotation(_Vector2<T>& aVector) const;
132                 inline _Vector2<T> getAppliedRotation(const _Vector2<T>& aVector) const;
133                 inline _Vector2<T>& applyTranslate(_Vector2<T>& aVector) const;
134                 inline _Vector2<T> getAppliedTranslate(const _Vector2<T>& aVector) const;
135
136                 inline SelfType& setRotation(const T& aAngleRAD);
137                 inline SelfType& setRotation(const Matrix2<T>& aRotation);
138                 inline SelfType& setRotation(const Matrix3<T>& aRotation);
139                 inline SelfType& makeRotation(const T& aAngleRAD);
140                 inline SelfType& makeRotation(const Matrix2<T>& aRotation);
141                 inline SelfType& makeRotation(const Matrix3<T>& aRotation);
142                 inline SelfType& rotate(const T& aAngleRAD);
143                 inline SelfType& rotate(const Matrix2<T>& aRotation);
144                 inline SelfType& rotate(const Matrix3<T>& aRotation);
145                 static inline SelfType createRotation(const T& aAngleRAD);
146                 static inline SelfType createRotation(const Matrix2<T>& aRotation);
147                 static inline SelfType createRotation(const Matrix3<T>& aRotation);
148                 inline Matrix2<T> getRotation() const;
149                 inline T getRotationAngle() const;
150
151                 inline SelfType& makeScale(const T& aX, const T& aY);
152                 inline SelfType& makeScale(const _Vector2<T>& aScale);
153                 inline SelfType& setScale(const T& aX, const T& aY);
154                 inline SelfType& setScale(const _Vector2<T>& aScale);
155                 static inline SelfType createScale(const T& aX, const T& aY);
156                 static inline SelfType createScale(const _Vector2<T>& aScale);
157                 inline SelfType& scale(const T& aX, const T& aY);
158                 inline SelfType& scale(const _Vector2<T>& aScale);
159
160                 inline SelfType& setTranslation(const T& aX, const T& aY);
161                 inline SelfType& setTranslation(const _Vector2<T>& aTran);
162                 inline SelfType& makeTranslation(const T& aX, const T& aY);
163                 inline SelfType& makeTranslation(const _Vector2<T>& aTran);
164                 inline SelfType& translate(const T& aX, const T& aY);
165                 inline SelfType& translate(const _Vector2<T>& aTran);
166                 static inline SelfType createTranslation(const T& aX, const T& aY);
167                 static inline SelfType createTranslation(const _Vector2<T>& aTran);
168                 inline _Vector2<T> getTranslation() const;
169                 inline _Vector3<T> getFullTranslation() const;
170
171                 inline T magnitude() const;
172                 inline T magnitude_sqr() const;
173                 inline T trace() const;
174                 inline Matrix2<T> minorMatrix(int row, int column) const;
175                 inline SelfType& makeCross(const _Vector3<T>& aVector);
176                 static inline SelfType createCross(const _Vector3<T>& aVector);
177
178                 inline const SelfType& QR_Decomposition(SelfType& aQ, SelfType& aR) const;
179         };
180
181         typedef Matrix3<float> Mat3f;
182         typedef Matrix3<double> Mat3d;
183
184         template<class T> inline Matrix3<T> operator+(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv);
185         template<class T> inline Matrix3<T> operator+(const Matrix3<T>& aLhv, const T& aRhv);
186         template<class T> inline Matrix3<T> operator+(const T& aLhv, const Matrix3<T>& aRhv);
187         template<class T> inline Matrix3<T> operator-(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv);
188         template<class T> inline Matrix3<T> operator-(const Matrix3<T>& aLhv, const T& aRhv);
189         template<class T> inline Matrix3<T> operator-(const T& aLhv, const Matrix3<T>& aRhv);
190         template<class T> inline Matrix3<T> operator*(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv);
191         template<class T> inline Matrix3<T> operator*(const Matrix3<T>& aLhv, const T& aRhv);
192         template<class T> inline Matrix3<T> operator*(const T& aLhv, const Matrix3<T>& aRhv);
193         template<class T> inline _Vector3<T> operator*(const Matrix3<T>& aLhv, const _Vector3<T>& aRhv);
194         template<class T> inline _Vector3<T> operator*(const _Vector3<T>& aLhv, const Matrix3<T>& aRhv);
195         template<class T> inline _Vector2<T> operator*(const Matrix3<T>& aLhv, const _Vector2<T>& aRhv);
196         template<class T> inline _Vector2<T> operator*(const _Vector2<T>& aLhv, const Matrix3<T>& aRhv);
197         template<class T> inline Matrix3<T> operator/(const Matrix3<T>& aLhv, const T& aRhv);
198         template<class T> inline Matrix3<T> operator/(const T& aLhv, const Matrix3<T>& aRhv);
199         template<class T> inline bool operator==(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv);
200         template<class T> inline bool operator==(const T& aLhv, const Matrix3<T>& aRhv);
201         template<class T> inline bool operator==(const Matrix3<T>& aLhv, const T& aRhv);
202         template<class T> inline bool operator!=(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv);
203         template<class T> inline bool operator!=(const T& aLhv, const Matrix3<T>& aRhv);
204         template<class T> inline bool operator!=(const Matrix3<T>& aLhv, const T& aRhv);
205
206        template<class T> Matrix3<T>::Matrix3() {}
207
208        template<class T> Matrix3<T>::Matrix3(const T& aValue):
209        i(aValue), j(aValue), k(aValue) {}
210
211        template<class T> Matrix3<T>::Matrix3(const T* aValue):
212        i(aValue[0], aValue[1], aValue[2]), j(aValue[3], aValue[4], aValue[5]), k(aValue[6], aValue[7], aValue[8]) {}
213
214        template<class T> Matrix3<T>::Matrix3(const Matrix3<T>& aOther):
215        i(aOther.i), j(aOther.j), k(aOther.k) {}
216
217        template<class T> Matrix3<T>::Matrix3(const _Vector3<T>& aI, const _Vector3<T>& aJ, const _Vector3<T>& aK):
218        i(aI), j(aJ), k(aK) {}
219
220        template<class T> Matrix3<T>::Matrix3(const _Vector2<T>& aI, const _Vector2<T>& aJ, const _Vector2<T>& aK):
221        i(aI, T(0.0f)), j(aJ, T(0.0f)), k(aK, T(1.0f)) {}
222
223        template<class T> Matrix3<T>::Matrix3(const T& a11, const T& a12, const T& a13,
224            const T& a21, const T& a22, const T& a23,
225            const T& a31, const T& a32, const T& a33):
226        i(a11, a12, a13), j(a21, a22, a23), k(a31, a32, a33) {}
227
228
229        template<class T> Matrix3<T>& Matrix3<T>::operator=(const Matrix3<T>& aRhv)
230        {
231            i = aRhv.i;
232            j = aRhv.j;
233            k = aRhv.k;
234            return *this;
235        }
236
237        template<class T> Matrix3<T>& Matrix3<T>::set(const T& aValue)
238        {
239            i.set(aValue);
240            j.set(aValue);
241            k.set(aValue);
242            return *this;
243        }
244
245        template<class T> Matrix3<T>& Matrix3<T>::set(const T* aValue)
246        {
247            i.set(aValue[0], aValue[1], aValue[2]);
248            j.set(aValue[3], aValue[4], aValue[5]);
249            k.set(aValue[6], aValue[7], aValue[8]);
250            return *this;
251        }
252
253        template<class T> Matrix3<T>& Matrix3<T>::set(const Matrix3<T>& aOther)
254        {
255            i = aOther.i;
256            j = aOther.j;
257            k = aOther.k;
258            return *this;
259        }
260
261        template<class T> Matrix3<T>& Matrix3<T>::set(const _Vector3<T>& aI, const _Vector3<T>& aJ, const _Vector3<T>& aK)
262        {
263            i = aI;
264            j = aJ;
265            k = aK;
266            return *this;
267        }
268
269        template<class T> Matrix3<T>& Matrix3<T>::set(const _Vector2<T>& aI, const _Vector2<T>& aJ, const _Vector2<T>& aK)
270        {
271            i.set(aI, T(0.0f));
272            j.set(aJ, T(0.0f));
273            k.set(aK, T(1.0f));
274            return *this;
275        }
276
277        template<class T> Matrix3<T>& Matrix3<T>::set(const T& a11, const T& a12, const T& a13,
278            const T& a21, const T& a22, const T& a23,
279            const T& a31, const T& a32, const T& a33)
280        {
281            i.set(a11, a12, a13);
282            j.set(a21, a22, a23);
283            k.set(a31, a32, a33);
284            return *this;
285        }
286
287        template<class T> inline Matrix3<T>& Matrix3<T>::identity()
288        {
289            return operator=(getIdentity());
290        }
291
292        template<class T> inline const Matrix3<T>& Matrix3<T>::getIdentity()
293        {
294            static Matrix3<T> identityMatrix(
295                                             T(1.0f), T(0.0f), T(0.0f),
296                                             T(0.0f), T(1.0f), T(0.0f),
297                                             T(0.0f), T(0.0f), T(1.0f));
298            return identityMatrix;
299        }
300
301        template<class T> inline bool Matrix3<T>::isIdentity() const
302        {
303            return *this == getIdentity();
304        }
305
306        template<class T> inline Matrix3<T> Matrix3<T>::operator-() const
307        {
308            return Matrix3<T>(-i, -j, -k);
309        }
310
311        template<class T> inline Matrix3<T>& Matrix3<T>::inverse()
312        {
313            static const T t0(0.0f);
314            static const T t1(1.0f);
315
316            T s = determinant();
317            if(EffectsEqual(s, t0)) return *this;
318            T inv_det(t1 / s);
319            return set(  (j.y * k.z - k.y * j.z) * inv_det, -(i.y * k.z - k.y * i.z) * inv_det,  (i.y * j.z - j.y * i.z) * inv_det,
320                        -(j.x * k.z - k.x * j.z) * inv_det,  (i.x * k.z - k.x * i.z) * inv_det, -(i.x * j.z - j.x * i.z) * inv_det,
321                         (j.x * k.y - k.x * j.y) * inv_det, -(i.x * k.y - k.x * i.y) * inv_det,  (i.x * j.y - j.x * i.y) * inv_det);
322        }
323        template<class T> inline Matrix3<T> Matrix3<T>::getInversed() const
324        {
325            static const T t0(0.0f);
326            static const T t1(1.0f);
327
328            T s = determinant();
329            if(EffectsEqual(s, t0)) return *this;
330            T inv_det(t1 / s);
331            return Matrix3<T>(   (j.y * k.z - k.y * j.z) * inv_det, -(i.y * k.z - k.y * i.z) * inv_det,  (i.y * j.z - j.y * i.z) * inv_det,
332                                -(j.x * k.z - k.x * j.z) * inv_det,  (i.x * k.z - k.x * i.z) * inv_det, -(i.x * j.z - j.x * i.z) * inv_det,
333                                 (j.x * k.y - k.x * j.y) * inv_det, -(i.x * k.y - k.x * i.y) * inv_det,  (i.x * j.y - j.x * i.y) * inv_det);
334        }
335
336        template <class T> inline T Matrix3<T>::determinant() const
337        {
338            return
339                      i.x * (j.y * k.z - j.z * k.y)
340                    - i.y * (j.x * k.z - j.z * k.x)
341                    + i.z * (j.x * k.y - j.y * k.x);
342        }
343
344        template<class T> inline Matrix3<T>& Matrix3<T>::transpose()
345        {
346            EffectsSwap(i.y, j.x);
347            EffectsSwap(i.z, k.x);
348            EffectsSwap(j.z, k.y);
349            return *this;
350        }
351
352        template<class T> inline Matrix3<T> Matrix3<T>::getTransposed() const
353        {
354            return Matrix3<T>( i.x, j.x, k.x,
355                               i.y, j.y, k.y,
356                               i.z, j.z, k.z);
357        }
358
359        template<class T> inline T* Matrix3<T>::getPointer()
360        {
361            return i.getPointer();
362        }
363
364        template<class T> inline const T* Matrix3<T>::getPointer() const
365        {
366            return i.getPointer();
367        }
368
369        template<class T> inline T& Matrix3<T>::get(unsigned int aRow, unsigned int aColumn)
370        {
371            return operator()(aRow, aColumn);
372        }
373
374        template<class T> inline const T& Matrix3<T>::get(unsigned int aRow, unsigned int aColumn) const
375        {
376            return operator()(aRow, aColumn);
377        }
378
379        template<class T> inline T& Matrix3<T>::get(unsigned int aAbsIndex)
380        {
381            return operator()(aAbsIndex);
382        }
383
384        template<class T> inline const T& Matrix3<T>::get(unsigned int aAbsIndex) const
385        {
386            return operator()(aAbsIndex);
387        }
388
389        template<class T> inline _Vector3<T>& Matrix3<T>::getRow(unsigned int aRow)
390        {
391            switch(aRow)
392            {
393            case 1:
394                return j;
395            case 2:
396                return k;
397            }
398            return i;
399        }
400
401        template<class T> inline const _Vector3<T>& Matrix3<T>::getRow(unsigned int aRow) const
402        {
403            switch(aRow)
404            {
405            case 1:
406                return j;
407            case 2:
408                return k;
409            }
410            return i;
411        }
412
413        template<class T> inline _Vector3<T> Matrix3<T>::getColumn(unsigned int aColumn) const
414        {
415            switch(aColumn)
416            {
417            case 1:
418                return _Vector3<T>(i.y, j.y, k.y);
419            case 2:
420                return _Vector3<T>(i.z, j.z, k.z);
421            }
422
423            return _Vector3<T>(i.x, j.x, k.x);
424        }
425
426        template<class T> inline T& Matrix3<T>::operator()(unsigned int aRow, unsigned int aColumn)
427        {
428            return operator[]((aRow * 3) + aColumn);
429        }
430
431        template<class T> inline const T& Matrix3<T>::operator()(unsigned int aRow, unsigned int aColumn) const
432        {
433            return operator[]((aRow * 3) + aColumn);
434        }
435
436        template<class T> inline T& Matrix3<T>::operator()(unsigned int aAbsIndex)
437        {
438            return operator[](aAbsIndex);
439        }
440
441        template<class T> inline const T& Matrix3<T>::operator()(unsigned int aAbsIndex) const
442        {
443            return operator[](aAbsIndex);
444        }
445
446        template<class T> inline T& Matrix3<T>::operator[](unsigned int aAbsIndex)
447        {
448            return getPointer()[aAbsIndex];
449        }
450
451        template<class T> inline const T& Matrix3<T>::operator[](unsigned int aAbsIndex) const
452        {
453            return getPointer()[aAbsIndex];
454        }
455
456        template<class T> inline Matrix3<T>& Matrix3<T>::setColumn(unsigned int aColumn, const _Vector3<T>& aValue)
457        {
458            switch(aColumn)
459            {
460            case 0:
461                i.x = aValue.x;
462                j.x = aValue.y;
463                k.x = aValue.z;
464                break;
465            case 1:
466                i.y = aValue.x;
467                j.y = aValue.y;
468                k.y = aValue.z;
469                break;
470            case 2:
471                i.z = aValue.x;
472                j.z = aValue.y;
473                k.z = aValue.z;
474                break;
475            }
476
477            return *this;
478        }
479
480        template<class T> inline Matrix3<T>& Matrix3<T>::setRow(unsigned int aRow, const _Vector3<T>& aValue)
481        {
482            switch(aRow)
483            {
484            case 0:
485                i = aValue;
486                break;
487            case 1:
488                j = aValue;
489                break;
490            case 2:
491                k = aValue;
492                break;
493            }
494
495            return *this;
496        }
497
498        template<class T> inline Matrix3<T>& Matrix3<T>::set(unsigned int aRow, unsigned int aColumn, const T& aValue)
499        {
500            operator()(aRow, aColumn) = aValue;
501            return *this;
502        }
503
504        template<class T> inline Matrix3<T>& Matrix3<T>::set(unsigned int aAbsIndex, const T& aValue)
505        {
506            operator()(aAbsIndex) = aValue;
507            return *this;
508        }
509
510
511
512        template<class T> inline Matrix3<T>& Matrix3<T>::operator+=(const Matrix3<T>& aRhv)
513        {
514            i += aRhv.i;
515            j += aRhv.j;
516            k += aRhv.k;
517            return *this;
518        }
519        template<class T> inline Matrix3<T>& Matrix3<T>::operator+=(const T& aRhv)
520        {
521            i += aRhv;
522            j += aRhv;
523            k += aRhv;
524            return *this;
525        }
526        template<class T> inline Matrix3<T>& Matrix3<T>::operator-=(const Matrix3<T>& aRhv)
527        {
528            i -= aRhv.i;
529            j -= aRhv.j;
530            k -= aRhv.k;
531            return *this;
532        }
533        template<class T> inline Matrix3<T>& Matrix3<T>::operator-=(const T& aRhv)
534        {
535            i -= aRhv;
536            j -= aRhv;
537            k -= aRhv;
538            return *this;
539        }
540        template<class T> inline Matrix3<T>& Matrix3<T>::operator*=(const T& aRhv)
541        {
542            i *= aRhv;
543            j *= aRhv;
544            k *= aRhv;
545            return *this;
546        }
547
548        template<class T> inline Matrix3<T> Matrix3<T>::GetMultipliedByMember(const Matrix3<T>& aRhv) const
549        {
550            return Matrix3<T>(i * aRhv.i, j * aRhv.j, k * aRhv.k);
551        }
552
553        template<class T> inline Matrix3<T>& Matrix3<T>::multiplyByMember(const Matrix3<T>& aRhv)
554        {
555            i *= aRhv.i;
556            j *= aRhv.j;
557            k *= aRhv.k;
558            return *this;
559        }
560
561        template<class T> inline Matrix3<T> Matrix3<T>::createMultipliedByMember(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv)
562        {
563            return Matrix3<T>(aLhv.i * aRhv.i, aLhv.j * aRhv.j, aLhv.k * aRhv.k);
564        }
565
566        template<class T> inline Matrix3<T>& Matrix3<T>::operator*=(const Matrix3<T>& aRhv)
567        {
568            set(
569                i.x * aRhv.i.x + i.y * aRhv.j.x + i.z * aRhv.k.x,
570                i.x * aRhv.i.y + i.y * aRhv.j.y + i.z * aRhv.k.y,
571                i.x * aRhv.i.z + i.y * aRhv.j.z + i.z * aRhv.k.z,
572
573                j.x * aRhv.i.x + j.y * aRhv.j.x + j.z * aRhv.k.x,
574                j.x * aRhv.i.y + j.y * aRhv.j.y + j.z * aRhv.k.y,
575                j.x * aRhv.i.z + j.y * aRhv.j.z + j.z * aRhv.k.z,
576
577                k.x * aRhv.i.x + k.y * aRhv.j.x + k.z * aRhv.k.x,
578                k.x * aRhv.i.y + k.y * aRhv.j.y + k.z * aRhv.k.y,
579                k.x * aRhv.i.z + k.y * aRhv.j.z + k.z * aRhv.k.z);
580            return *this;
581        }
582
583        template<class T> inline Matrix3<T> Matrix3<T>::getDividedByMember(const Matrix3<T>& aRhv) const
584        {
585            return Matrix3<T>(i / aRhv.i, j / aRhv.j, k / aRhv.k);
586        }
587
588        template<class T> inline Matrix3<T>& Matrix3<T>::divideByMember(const Matrix3<T>& aRhv)
589        {
590            i /= aRhv.i;
591            j /= aRhv.j;
592            k /= aRhv.k;
593            return *this;
594        }
595        template<class T> inline Matrix3<T> Matrix3<T>::createDividedByMember(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv)
596        {
597            return Matrix3<T>(aLhv.i / aRhv.i, aLhv.j / aRhv.j, aLhv.k / aRhv.k);
598        }
599
600        template<class T> inline Matrix3<T>& Matrix3<T>::operator/=(const T& aRhv)
601        {
602            i /= aRhv;
603            j /= aRhv;
604            k /= aRhv;
605            return *this;
606        }
607
608
609
610        template<class T> inline _Vector3<T>& Matrix3<T>::applyTransform(_Vector3<T>& aVector) const
611        {
612            return aVector.set(
613                aVector.x * i.x + aVector.y * j.x + aVector.z * k.x,
614                aVector.x * i.y + aVector.y * j.y + aVector.z * k.y,
615                aVector.x * i.z + aVector.y * j.z + aVector.z * k.z);
616        }
617
618        template<class T> inline _Vector3<T> Matrix3<T>::getAppliedTransform(const _Vector3<T>& aVector) const
619        {
620            return _Vector3<T>(
621                aVector.x * i.x + aVector.y * j.x + aVector.z * k.x,
622                aVector.x * i.y + aVector.y * j.y + aVector.z * k.y,
623                aVector.x * i.z + aVector.y * j.z + aVector.z * k.z);
624        }
625
626        template<class T> inline _Vector3<T>& Matrix3<T>::applyRotation(_Vector3<T>& aVector) const
627        {
628            return aVector.set(
629                                aVector.x * i.x + aVector.y * j.x,
630                                aVector.x * i.y + aVector.y * j.y,
631                                aVector.z);
632        }
633
634        template<class T> inline _Vector3<T> Matrix3<T>::getAppliedRotation(const _Vector3<T>& aVector) const
635        {
636            return _Vector3<T>(
637                                aVector.x * i.x + aVector.y * j.x,
638                                aVector.x * i.y + aVector.y * j.y,
639                                aVector.z);
640        }
641
642        template<class T> inline _Vector3<T>& Matrix3<T>::applyTranslate(_Vector3<T>& aVector) const
643        {
644            return aVector.set(
645                                aVector.x + aVector.z * k.x,
646                                aVector.y + aVector.z * k.y,
647                                aVector.z);
648        }
649
650        template<class T> inline _Vector3<T> Matrix3<T>::getAppliedTranslate(const _Vector3<T>& aVector) const
651        {
652            return _Vector3<T>(
653                                aVector.x + aVector.z * k.x,
654                                aVector.y + aVector.z * k.y,
655                                aVector.z);
656        }
657
658        template<class T> inline _Vector2<T>& Matrix3<T>::applyTransform(_Vector2<T>& aVector) const
659        {
660            return aVector.set(
661                                aVector.x * i.x + aVector.y * j.x + k.x,
662                                aVector.x * i.y + aVector.y * j.y + k.y);
663        }
664
665        template<class T> inline _Vector2<T> Matrix3<T>::getAppliedTransform(const _Vector2<T>& aVector) const
666        {
667            return _Vector2<T>(
668                                aVector.x * i.x + aVector.y * j.x + k.x,
669                                aVector.x * i.y + aVector.y * j.y + k.y);
670        }
671
672        template<class T> inline _Vector2<T>& Matrix3<T>::applyRotation(_Vector2<T>& aVector) const
673        {
674            return aVector.set(
675                                aVector.x * i.x + aVector.y * j.x,
676                                aVector.x * i.y + aVector.y * j.y);
677        }
678
679        template<class T> inline _Vector2<T> Matrix3<T>::getAppliedRotation(const _Vector2<T>& aVector) const
680        {
681            return _Vector2<T>(
682                                aVector.x * i.x + aVector.y * j.x,
683                                aVector.x * i.y + aVector.y * j.y);
684        }
685
686        template<class T> inline _Vector2<T>& Matrix3<T>::applyTranslate(_Vector2<T>& aVector) const
687        {
688            return aVector.set(
689                                aVector.x + k.x,
690                                aVector.y + k.y);
691        }
692
693        template<class T> inline _Vector2<T> Matrix3<T>::getAppliedTranslate(const _Vector2<T>& aVector) const
694        {
695            return _Vector2<T>(
696                                aVector.x + k.x,
697                                aVector.y + k.y);
698        }
699
700        template<class T> inline Matrix3<T>& Matrix3<T>::setRotation(const T& aAngleRAD)
701        {
702            const T s = effects_sin(aAngleRAD);
703            const T c = effects_cos(aAngleRAD);
704            i.x = c;
705            i.y = s;
706            j.x = -s;
707            j.y = c;
708            return *this;
709        }
710        template<class T> inline Matrix3<T>& Matrix3<T>::setRotation(const Matrix2<T>& aRotation)
711        {
712            i.x = aRotation.i.x;
713            i.y = aRotation.i.y;
714            j.x = aRotation.j.x;
715            j.y = aRotation.j.y;
716            return *this;
717        }
718        template<class T> inline Matrix3<T>& Matrix3<T>::setRotation(const Matrix3<T>& aRotation)
719        {
720            i.x = aRotation.i.x;
721            i.y = aRotation.i.y;
722            j.x = aRotation.j.x;
723            j.y = aRotation.j.y;
724            return *this;
725        }
726        template<class T> inline Matrix3<T>& Matrix3<T>::makeRotation(const T& aAngleRAD)
727        {
728            identity();
729            return setRotation(aAngleRAD);
730        }
731        template<class T> inline Matrix3<T>& Matrix3<T>::makeRotation(const Matrix2<T>& aRotation)
732        {
733            identity();
734            return setRotation(aRotation);
735        }
736        template<class T> inline Matrix3<T>& Matrix3<T>::makeRotation(const Matrix3<T>& aRotation)
737        {
738            identity();
739            return setRotation(aRotation);
740        }
741        template<class T> inline Matrix3<T>& Matrix3<T>::rotate(const T& aAngleRAD)
742        {
743            const T s = effects_sin(aAngleRAD);
744            const T c = effects_cos(aAngleRAD);
745            const T ix = i.x * c - i.y * s;
746            const T iy = i.x * s + i.y * c;
747            const T jx = j.x * c - j.y * s;
748            const T jy = j.x * s + j.y * c;
749            i.x = ix;
750            i.y = iy;
751            j.x = jx;
752            j.y = jy;
753            return *this;
754        }
755        template<class T> inline Matrix3<T>& Matrix3<T>::rotate(const Matrix2<T>& aRotation)
756        {
757            const T ix = i.x * aRotation.i.x + i.y * aRotation.j.x;
758            const T iy = i.x * aRotation.i.y + i.y * aRotation.j.y;
759            const T jx = j.x * aRotation.i.x + j.y * aRotation.j.x;
760            const T jy = j.x * aRotation.i.y + j.y * aRotation.j.y;
761            i.x = ix;
762            i.y = iy;
763            j.x = jx;
764            j.y = jy;
765            return *this;
766        }
767        template<class T> inline Matrix3<T>& Matrix3<T>::rotate(const Matrix3<T>& aRotation)
768        {
769            const T ix = i.x * aRotation.i.x + i.y * aRotation.j.x;
770            const T iy = i.x * aRotation.i.y + i.y * aRotation.j.y;
771            const T jx = j.x * aRotation.i.x + j.y * aRotation.j.x;
772            const T jy = j.x * aRotation.i.y + j.y * aRotation.j.y;
773            i.x = ix;
774            i.y = iy;
775            j.x = jx;
776            j.y = jy;
777            return *this;
778        }
779        template<class T> inline Matrix3<T> Matrix3<T>::createRotation(const T& aAngleRAD)
780        {
781            return Matrix3<T>().makeRotation(aAngleRAD);
782        }
783        template<class T> inline Matrix3<T> Matrix3<T>::createRotation(const Matrix2<T>& aRotation)
784        {
785            return Matrix3<T>().makeRotation(aRotation);
786        }
787        template<class T> inline Matrix3<T> Matrix3<T>::createRotation(const Matrix3<T>& aRotation)
788        {
789            return Matrix3<T>().makeRotation(aRotation);
790        }
791        template<class T> inline Matrix2<T> Matrix3<T>::getRotation() const
792        {
793            return Matrix2<T>(i.x, i.y, j.x, j.y);
794        }
795        template<class T> inline T Matrix3<T>::getRotationAngle() const
796        {
797            static const T t0(0.0f);
798            static const T t1(1.0f);
799
800            static const _Vector2<T> orig_vector(t1, t0);
801            static const _Vector2<T> orig_vector_cross(t0, t1);
802
803            _Vector2<T> rotated(getAppliedRotation(orig_vector).normalize());
804            const T angleCos = effects_clamp(rotated.dot(orig_vector), -t1, t1);
805            const T angleCosCross = effects_clamp(rotated.dot(orig_vector_cross), -t1, t1);
806
807            if(angleCosCross > t0)
808                return effects_acos(angleCos);
809            return -effects_acos(angleCos);
810        }
811
812        template<class T> inline Matrix3<T>& Matrix3<T>::makeScale(const T& aX, const T& aY)
813        {
814            identity();
815            return setScale(aX, aY);
816        }
817        template<class T> inline Matrix3<T>& Matrix3<T>::makeScale(const _Vector2<T>& aScale)
818        {
819            return makeScale(aScale.x, aScale.y);
820        }
821        template<class T> inline Matrix3<T> Matrix3<T>::createScale(const T& aX, const T& aY)
822        {
823            return Matrix3<T>().makeScale(aX, aY);
824        }
825        template<class T> inline Matrix3<T> Matrix3<T>::createScale(const _Vector2<T>& aScale)
826        {
827            return Matrix3<T>().makeScale(aScale);
828        }
829        template<class T> inline Matrix3<T>& Matrix3<T>::setScale(const T& aX, const T& aY)
830        {
831            i.x = aX;
832            j.y = aY;
833
834            i.y = j.x = T(0.0f);
835            return *this;
836        }
837        template<class T> inline Matrix3<T>& Matrix3<T>::setScale(const _Vector2<T>& aScale)
838        {
839            return setScale(aScale.x, aScale.y);
840        }
841        template<class T> inline Matrix3<T>& Matrix3<T>::scale(const T& aX, const T& aY)
842        {
843            i.x *= aX; i.y *= aY;
844            j.x *= aX; j.y *= aY;
845
846            return *this;
847        }
848        template<class T> inline Matrix3<T>& Matrix3<T>::scale(const _Vector2<T>& aScale)
849        {
850            return scale(aScale.x, aScale.y);
851        }
852
853        template<class T> inline Matrix3<T>& Matrix3<T>::setTranslation(const T& aX, const T& aY)
854        {
855            k.x = aX;
856            k.y = aY;
857            return *this;
858        }
859        template<class T> inline Matrix3<T>& Matrix3<T>::setTranslation(const _Vector2<T>& aTran)
860        {
861            return setTranslation(aTran.x, aTran.y);
862        }
863        template<class T> inline Matrix3<T>& Matrix3<T>::makeTranslation(const T& aX, const T& aY)
864        {
865            identity();
866            return setTranslation(aX, aY);
867        }
868        template<class T> inline Matrix3<T>& Matrix3<T>::makeTranslation(const _Vector2<T>& aTran)
869        {
870            return makeTranslation(aTran.x, aTran.y);
871        }
872        template<class T> inline Matrix3<T> Matrix3<T>::createTranslation(const T& aX, const T& aY)
873        {
874            return Matrix3<T>().makeTranslation(aX, aY);
875        }
876        template<class T> inline Matrix3<T> Matrix3<T>::createTranslation(const _Vector2<T>& aTran)
877        {
878            return Matrix3<T>().makeTranslation(aTran);
879        }
880        template<class T> inline Matrix3<T>& Matrix3<T>::translate(const T& aX, const T& aY)
881        {
882            k.x += aX;
883            k.y += aY;
884            return *this;
885        }
886        template<class T> inline Matrix3<T>& Matrix3<T>::translate(const _Vector2<T>& aTran)
887        {
888            return translate(aTran.x, aTran.y);
889        }
890        template<class T> inline _Vector2<T> Matrix3<T>::getTranslation() const
891        {
892            return k.swizzle(0, 1);
893        }
894        template<class T> inline _Vector3<T> Matrix3<T>::getFullTranslation() const
895        {
896            return k;
897        }
898
899        template<class T> inline Matrix3<T>& Matrix3<T>::lerp(const Matrix3<T>& aTo, const T& aCoeff)
900        {
901            i.lerp(aTo.i, aCoeff);
902            j.lerp(aTo.j, aCoeff);
903            k.lerp(aTo.k, aCoeff);
904            return *this;
905        }
906
907        template<class T> inline Matrix3<T> Matrix3<T>::getLerped(const Matrix3<T>& aTo, const T& aCoeff) const
908        {
909            Matrix3<T> result(i.getLerped(aTo.i, aCoeff),
910                j.getLerped(aTo.j, aCoeff),
911                k.getLerped(aTo.k, aCoeff));
912            return result;
913        }
914
915        template<class T> inline Matrix3<T>& Matrix3<T>::makeLerped(const Matrix3<T>& aFrom, const Matrix3<T>& aTo, const T& aCoeff)
916        {
917            i.makeLerped(aFrom.i, aTo.i, aCoeff);
918            j.makeLerped(aFrom.j, aTo.j, aCoeff);
919            k.makeLerped(aFrom.k, aTo.k, aCoeff);
920            return *this;
921        }
922        template<class T> inline Matrix3<T> Matrix3<T>::createLerped(const Matrix3<T>& aFrom, const Matrix3<T>& aTo, const T& aCoeff)
923        {
924            return Matrix3<T>().makeLerped(aFrom, aTo, aCoeff);
925        }
926
927        template<class T> inline Matrix3<T>& Matrix3<T>::slerp(const Matrix3<T>& aTo, const T& aCoeff)
928        {
929            setRotation(effects_lerp(getRotationAngle(), aTo.getRotationAngle(), aCoeff));
930            k.lerp(aTo.k, aCoeff);
931            return *this;
932        }
933
934        template<class T> inline Matrix3<T> Matrix3<T>::getSlerped(const Matrix3<T>& aTo, const T& aCoeff) const
935        {
936            Matrix3 result;
937            result.makeRotation(effects_lerp(getRotationAngle(), aTo.getRotationAngle(), aCoeff));
938            result.k = k.getLerped(aTo.k, aCoeff);
939            return result;
940        }
941
942        template<class T> inline Matrix3<T>& Matrix3<T>::makeSlerped(const Matrix3<T>& aFrom, const Matrix3<T>& aTo, const T& aCoeff)
943        {
944            makeRotation(effects_lerp(aFrom.getRotationAngle(), aTo.getRotationAngle(), aCoeff));
945            k.makeLerped(aFrom.k, aTo.k, aCoeff);
946            return *this;
947        }
948
949        template<class T> inline Matrix3<T> Matrix3<T>::createSlerped(const Matrix3<T>& aFrom, const Matrix3<T>& aTo, const T& aCoeff)
950        {
951            return Matrix3<T>().makeSlerped(aFrom, aTo, aCoeff);
952        }
953
954        template<class T> inline T Matrix3<T>::magnitude_sqr() const
955        {
956            return i.dot(i) + j.dot(j) + k.dot(k);
957        }
958        template<class T> inline T Matrix3<T>::magnitude() const
959        {
960            return effects_sqrt(magnitude_sqr());
961        }
962        template<class T> inline T Matrix3<T>::trace() const
963        {
964            return i.x + j.y + k.z;
965        }
966        template<class T> inline Matrix2<T> Matrix3<T>::minorMatrix(int row, int column) const
967        {
968            Matrix2<T> result;
969
970            int row_counter = 0;
971            int column_counter = 0;
972            for(int current_row = 0; 3 > current_row; ++current_row)
973            {
974                if(current_row == row)
975                    continue;
976
977                column_counter = 0;
978                for(int current_column = 0; 3 > current_column; ++current_column)
979                {
980                    if(current_column == column)
981                        continue;
982
983                    result(row_counter, column_counter) = this->operator()(current_row, current_column);
984                    ++column_counter;
985                }
986                ++row_counter;
987            }
988            return result;
989        }
990        template<class T> inline Matrix3<T>& Matrix3<T>::makeCross(const _Vector3<T>& aVector)
991        {
992            static const T t0(0.0f);
993
994            return set( t0,        -aVector.z,  aVector.y,
995                        aVector.z,  t0,        -aVector.x,
996                       -aVector.y,  aVector.x,  t0);
997        }
998        template<class T> inline Matrix3<T> Matrix3<T>::createCross(const _Vector3<T>& aVector)
999        {
1000            return Matrix3<T>().makeCross(aVector);
1001        }
1002
1003        template<class T> inline const Matrix3<T>& Matrix3<T>::QR_Decomposition(Matrix3<T>& aQ, Matrix3<T>& aR) const
1004        {
1005            aR.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
1006
1007            aQ = *this;
1008
1009            for (int k = 0; k < 3; ++k)
1010            {
1011                for (int i = 0; i < k; ++i)
1012                {
1013                    _Vector3<T> v1 = aQ.getColumn(i);
1014                    _Vector3<T> v2 = aQ.getColumn(k);
1015                    aR(i, k) = v1.dot(v2);
1016
1017                    _Vector3<T> v3 = aR(i, k) * v1;
1018                    _Vector3<T> v4 = v2 - v3;
1019                    aQ.setColumn(k, v4);
1020                }
1021
1022                _Vector3<T> qv1 = aQ.getColumn(k);
1023                aR(k, k) = qv1.length();
1024
1025                _Vector3<T> qv2 = qv1 / aR(k, k);
1026                aQ.setColumn(k, qv2);
1027            }
1028
1029            return *this;
1030        }
1031
1032        template<class T> inline bool isEqual(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv, const T& aEpsilon = effects_epsilon<T>::epsilon())
1033        {
1034            return isEqual(aLhv.i, aRhv.i, aEpsilon) && isEqual(aLhv.j, aRhv.j, aEpsilon) && isEqual(aLhv.k, aRhv.k, aEpsilon);
1035        }
1036        template<class T> inline Matrix3<T> operator+(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv)
1037        {
1038            return Matrix3<T>(aLhv.i + aRhv.i, aLhv.j + aRhv.j, aLhv.k + aRhv.k);
1039        }
1040        template<class T> inline Matrix3<T> operator+(const Matrix3<T>& aLhv, const T& aRhv)
1041        {
1042            return Matrix3<T>(aLhv.i + aRhv, aLhv.j + aRhv, aLhv.k + aRhv);
1043        }
1044        template<class T> inline Matrix3<T> operator+(const T& aLhv, const Matrix3<T>& aRhv)
1045        {
1046            return Matrix3<T>(aLhv + aRhv.i, aLhv + aRhv.j, aLhv + aRhv.k);
1047        }
1048        template<class T> inline Matrix3<T> operator-(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv)
1049        {
1050            return Matrix3<T>(aLhv.i - aRhv.i, aLhv.j - aRhv.j, aLhv.k - aRhv.k);
1051        }
1052        template<class T> inline Matrix3<T> operator-(const Matrix3<T>& aLhv, const T& aRhv)
1053        {
1054            return Matrix3<T>(aLhv.i - aRhv, aLhv.j - aRhv, aLhv.k - aRhv);
1055        }
1056        template<class T> inline Matrix3<T> operator-(const T& aLhv, const Matrix3<T>& aRhv)
1057        {
1058            return Matrix3<T>(aLhv - aRhv.i, aLhv - aRhv.j, aLhv - aRhv.k);
1059        }
1060        template<class T> inline Matrix3<T> operator*(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv)
1061        {
1062            return Matrix3<T>(
1063                aLhv.i.x * aRhv.i.x + aLhv.i.y * aRhv.j.x + aLhv.i.z * aRhv.k.x,
1064                aLhv.i.x * aRhv.i.y + aLhv.i.y * aRhv.j.y + aLhv.i.z * aRhv.k.y,
1065                aLhv.i.x * aRhv.i.z + aLhv.i.y * aRhv.j.z + aLhv.i.z * aRhv.k.z,
1066
1067                aLhv.j.x * aRhv.i.x + aLhv.j.y * aRhv.j.x + aLhv.j.z * aRhv.k.x,
1068                aLhv.j.x * aRhv.i.y + aLhv.j.y * aRhv.j.y + aLhv.j.z * aRhv.k.y,
1069                aLhv.j.x * aRhv.i.z + aLhv.j.y * aRhv.j.z + aLhv.j.z * aRhv.k.z,
1070
1071                aLhv.k.x * aRhv.i.x + aLhv.k.y * aRhv.j.x + aLhv.k.z * aRhv.k.x,
1072                aLhv.k.x * aRhv.i.y + aLhv.k.y * aRhv.j.y + aLhv.k.z * aRhv.k.y,
1073                aLhv.k.x * aRhv.i.z + aLhv.k.y * aRhv.j.z + aLhv.k.z * aRhv.k.z);
1074        }
1075        template<class T> inline Matrix3<T> operator*(const Matrix3<T>& aLhv, const T& aRhv)
1076        {
1077            return Matrix3<T>(aLhv.i * aRhv, aLhv.j * aRhv, aLhv.k * aRhv);
1078        }
1079        template<class T> inline Matrix3<T> operator*(const T& aLhv, const Matrix3<T>& aRhv)
1080        {
1081            return Matrix3<T>(aLhv * aRhv.i, aLhv * aRhv.j, aLhv * aRhv.k);
1082        }
1083        template<class T> inline _Vector3<T> operator*(const _Vector3<T>& aLhv, const Matrix3<T>& aRhv)
1084        {
1085            return aRhv.getAppliedTransform(aLhv);
1086        }
1087        template<class T> inline _Vector3<T> operator*(const Matrix3<T>& aLhv, const _Vector3<T>& aRhv)
1088        {
1089            return _Vector3<T>(  aLhv.i.x * aRhv.x + aLhv.i.y * aRhv.y + aLhv.i.z * aRhv.z,
1090                aLhv.j.x * aRhv.x + aLhv.j.y * aRhv.y + aLhv.j.z * aRhv.z,
1091                aLhv.k.x * aRhv.x + aLhv.k.y * aRhv.y + aLhv.k.z * aRhv.z);
1092        }
1093        template<class T> inline _Vector2<T> operator*(const _Vector2<T>& aLhv, const Matrix3<T>& aRhv)
1094        {
1095            return aRhv.getAppliedTransform(aLhv);
1096        }
1097        template<class T> inline _Vector2<T> operator*(const Matrix3<T>& aLhv, const _Vector2<T>& aRhv)
1098        {
1099            return _Vector2<T>(  aLhv.i.x * aRhv.x + aLhv.i.y * aRhv.y + aLhv.i.z,
1100                aLhv.j.x * aRhv.x + aLhv.j.y * aRhv.y + aLhv.j.z);
1101        }
1102        template<class T> inline Matrix3<T> operator/(const Matrix3<T>& aLhv, const T& aRhv)
1103        {
1104            return Matrix3<T>(aLhv.i / aRhv, aLhv.j / aRhv, aLhv.k / aRhv);
1105        }
1106        template<class T> inline Matrix3<T> operator/(const T& aLhv, const Matrix3<T>& aRhv)
1107        {
1108            return Matrix3<T>(aLhv / aRhv.i, aLhv / aRhv.j, aLhv / aRhv.k);
1109        }
1110        template<class T> inline bool operator==(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv)
1111        {
1112            return aLhv.i == aRhv.i && aLhv.j == aRhv.j && aLhv.k == aRhv.k;
1113        }
1114        template<class T> inline bool operator==(const Matrix3<T>& aLhv, const T& aRhv)
1115        {
1116            return aLhv.i == aRhv && aLhv.j == aRhv && aLhv.k == aRhv;
1117        }
1118        template<class T> inline bool operator==(const T& aLhv, const Matrix3<T>& aRhv)
1119        {
1120            return aLhv == aRhv.i && aLhv == aRhv.j && aLhv == aRhv.k;
1121        }
1122        template<class T> inline bool operator!=(const Matrix3<T>& aLhv, const Matrix3<T>& aRhv)
1123        {
1124            return !(aLhv == aRhv);
1125        }
1126        template<class T> inline bool operator!=(const Matrix3<T>& aLhv, const T& aRhv)
1127        {
1128            return !(aLhv == aRhv);
1129        }
1130        template<class T> inline bool operator!=(const T& aLhv, const Matrix3<T>& aRhv)
1131        {
1132            return !(aLhv == aRhv);
1133        }
1134 } } } } //Tizen::Ui::Effects::_Utils
1135
1136 #endif //_FUI_EFFECTS_INTERNAL_UTILS_MATRIX3_H_