Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / effects / inc / renderer / math / FUiEffects_RendererMathMatrix.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_RendererMathMatrix.h
20  * @brief      The Matrix class
21  *
22  */
23
24 #ifndef _FUI_EFFECTS_INTERNAL_RENDERER_MATH_MATRIX_H_
25 #define _FUI_EFFECTS_INTERNAL_RENDERER_MATH_MATRIX_H_
26
27 #include <renderer/math/FUiEffects_RendererMathVector.h>
28 #include <renderer/math/FUiEffects_RendererMathMatrix1Traits.h>
29 #include <renderer/math/FUiEffects_RendererMathMatrix2Traits.h>
30 #include <renderer/math/FUiEffects_RendererMathMatrix3Traits.h>
31 #include <renderer/math/FUiEffects_RendererMathCommon.h>
32 #include <renderer/math/FUiEffects_RendererMathAdapterFunctions.h>
33 #include <renderer/system/FUiEffects_RendererSystemStaticAssert.h>
34
35 namespace Tizen { namespace Ui { namespace Effects { namespace _Renderer { namespace Math
36 {
37 template<typename T, int Dimension>
38 class Matrix :
39         public MatrixTraits<T, Dimension>
40 {
41 public:
42         typedef Matrix<T, Dimension> MatrixType;
43         typedef Vector<T, Dimension> VectorType;
44         typedef MatrixTraitsBase<T, Dimension> MatrixTraitsBaseType;
45         typedef typename MatrixTraitsBaseType::TypeReference TypeReference;
46
47         using MatrixTraitsBaseType::data;
48         using MatrixTraits<T, Dimension>::Set;
49         using MatrixTraits<T, Dimension>::CreateScale;
50         using MatrixTraits<T, Dimension>::MakeScale;
51         using MatrixTraits<T, Dimension>::Scale;
52         using MatrixTraits<T, Dimension>::SetScale;
53         using MatrixTraits<T, Dimension>::ApplyTransform;
54         using MatrixTraits<T, Dimension>::GetAppliedTransform;
55
56         inline Matrix(void);
57         inline explicit Matrix(const TypeReference value);
58         inline Matrix(const TypeReference a11, const TypeReference a12,
59                                   const TypeReference a21, const TypeReference a22);
60
61         inline Matrix(const TypeReference a11, const TypeReference a12, const TypeReference a13,
62                                   const TypeReference a21, const TypeReference a22, const TypeReference a23,
63                                   const TypeReference a31, const TypeReference a32, const TypeReference a33);
64
65         inline Matrix(const TypeReference a11, const TypeReference a12, const TypeReference a13, const TypeReference a14,
66                                   const TypeReference a21, const TypeReference a22, const TypeReference a23, const TypeReference a24,
67                                   const TypeReference a31, const TypeReference a32, const TypeReference a33, const TypeReference a34,
68                                   const TypeReference a41, const TypeReference a42, const TypeReference a43, const TypeReference a44);
69
70         inline Matrix(const VectorType& i, const VectorType& j);
71         inline Matrix(const VectorType& i, const VectorType& j, const VectorType& k);
72         inline Matrix(const VectorType& i, const VectorType& j, const VectorType& k, const VectorType& c);
73
74         inline Matrix(const MatrixType& other);
75
76         inline MatrixType& operator = (const MatrixType& rhv);
77
78         inline MatrixType& Set(const MatrixType& other);
79         inline MatrixType& Set(const TypeReference value);
80
81         inline MatrixType& FillFromArray(const T* pArray);
82         static inline MatrixType MakeFromArray(const T* pArray);
83
84         inline MatrixType& Identity(void);
85         inline bool IsIdentity(void) const;
86
87         inline MatrixType operator-(void) const;
88         inline MatrixType& Inverse(void);
89         inline MatrixType GetInversed(void) const;
90
91         inline MatrixType& Transpose(void);
92         inline MatrixType GetTransposed(void) const;
93
94         inline MatrixType& operator+=(const MatrixType& rhv);
95         inline MatrixType& operator+=(const TypeReference rhv);
96         inline MatrixType& operator-=(const MatrixType& rhv);
97         inline MatrixType& operator-=(const TypeReference rhv);
98         inline MatrixType& operator*=(const MatrixType& rhv);
99         inline MatrixType& operator*=(const TypeReference rhv);
100         inline MatrixType& operator/=(const TypeReference rhv);
101         inline MatrixType GetMultipliedByMember(const MatrixType& rhv) const;
102         inline MatrixType& MultiplyByMember(const MatrixType& rhv);
103         static inline MatrixType CreateMultipliedByMember(const MatrixType& lhv, const MatrixType& rhv);
104         inline MatrixType GetDividedByMember(const MatrixType& rhv) const;
105         inline MatrixType& DivideByMember(const MatrixType& rhv);
106         static inline MatrixType CreateDividedByMember(const MatrixType& lhv, const MatrixType& rhv);
107
108         inline T* GetPointer(void);
109         inline const T* GetPointer(void) const;
110         inline TypeReference Get(unsigned int row, unsigned int column);
111         inline const TypeReference Get(unsigned int row, unsigned int column) const;
112         inline TypeReference Get(unsigned int absIndex);
113         inline const TypeReference Get(unsigned int absIndex) const;
114         inline MatrixType& Set(unsigned int row, unsigned int column, const TypeReference value);
115         inline MatrixType& Set(unsigned int absIndex, const TypeReference value);
116         inline VectorType GetColumn(unsigned int column) const;
117         inline MatrixType& SetColumn(unsigned int column, const VectorType& value);
118         inline VectorType& GetRow(unsigned int row);
119         inline const VectorType& GetRow(unsigned int row) const;
120         inline MatrixType& SetRow(unsigned int row, const VectorType& value);
121         inline TypeReference operator()(unsigned int row, unsigned int column);
122         inline const TypeReference operator()(unsigned int row, unsigned int column) const;
123         inline TypeReference operator()(unsigned int absIndex);
124         inline const TypeReference operator()(unsigned int absIndex) const;
125         inline TypeReference operator[](unsigned int absIndex);
126         inline const TypeReference operator[](unsigned int absIndex) const;
127
128         inline MatrixType& Lerp(const MatrixType& to, const TypeReference coeff);
129         inline MatrixType GetLerped(const MatrixType& to, const TypeReference coeff) const;
130         inline MatrixType& MakeLerped(const MatrixType& from, const MatrixType& to, const TypeReference coeff);
131         static inline MatrixType CreateLerped(const MatrixType& from, const MatrixType& to, const TypeReference coeff);
132
133         inline TypeReference Magnitude(void) const;
134         inline TypeReference MagnitudeSqr(void) const;
135         inline TypeReference Trace(void) const;
136         inline Matrix<T, (Dimension == 1 ? Dimension : Dimension - 1)> MinorMatrix(unsigned int row, unsigned int column) const;
137
138         inline TypeReference Determinant(void) const;
139
140         inline VectorType& ApplyTransform(VectorType& vector) const;
141         inline VectorType GetAppliedTransform(const VectorType& vector) const;
142
143         template<int VectorDimension>
144         inline MatrixType& MakeScale(const Vector<T, VectorDimension>& scale);
145         template<int VectorDimension>
146         inline MatrixType& SetScale(const Vector<T, VectorDimension>& scale);
147         template<int VectorDimension>
148         static inline MatrixType CreateScale(const Vector<T, VectorDimension>& scale);
149         template<int VectorDimension>
150         inline MatrixType& Scale(const Vector<T, VectorDimension>& scale);
151
152         inline bool IsEqual(const Matrix<T, Dimension>& rhv, const TypeReference epsilon = EffectsEpsilon<T>::epsilon()) const;
153 };
154
155 template<typename T, int Dimension>
156 inline bool IsEqual(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv, const typename Matrix<T, Dimension>::TypeReference epsilon);
157 template<typename T, int Dimension> inline Matrix<T, Dimension> operator+(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv);
158 template<typename T, int Dimension> inline Matrix<T, Dimension> operator+(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv);
159 template<typename T, int Dimension> inline Matrix<T, Dimension> operator+(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv);
160 template<typename T, int Dimension> inline Matrix<T, Dimension> operator-(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv);
161 template<typename T, int Dimension> inline Matrix<T, Dimension> operator-(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv);
162 template<typename T, int Dimension> inline Matrix<T, Dimension> operator-(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv);
163 template<typename T, int Dimension> inline Matrix<T, Dimension> operator*(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv);
164 template<typename T, int Dimension> inline Matrix<T, Dimension> operator*(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv);
165 template<typename T, int Dimension> inline Matrix<T, Dimension> operator*(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv);
166 template<typename T, int Dimension> inline Vector<T, Dimension> operator*(const Matrix<T, Dimension>& lhv, const Vector<T, Dimension>& rhv);
167 template<typename T, int Dimension> inline Vector<T, Dimension> operator*(const Vector<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv);
168 template<typename T, int Dimension> inline Vector<T, Dimension - 1> operator*(const Matrix<T, Dimension>& lhv, const Vector<T, Dimension - 1>& rhv);
169 template<typename T, int Dimension> inline Vector<T, Dimension - 1> operator*(const Vector<T, Dimension - 1>& lhv, const Matrix<T, Dimension>& rhv);
170 template<typename T, int Dimension> inline Matrix<T, Dimension> operator/(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv);
171 template<typename T, int Dimension> inline Matrix<T, Dimension> operator/(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv);
172 template<typename T, int Dimension> inline bool operator==(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv);
173 template<typename T, int Dimension> inline bool operator==(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv);
174 template<typename T, int Dimension> inline bool operator==(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv);
175 template<typename T, int Dimension> inline bool operator!=(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv);
176 template<typename T, int Dimension> inline bool operator!=(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv);
177 template<typename T, int Dimension> inline bool operator!=(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv);
178
179 typedef Matrix<float, 1> Matrix1f;
180 typedef Matrix<double, 1> Matrix1d;
181 typedef Matrix<float, 2> Matrix2f;
182 typedef Matrix<double, 2> Matrix2d;
183 typedef Matrix<float, 3> Matrix3f;
184 typedef Matrix<double, 3> Matrix3d;
185 typedef Matrix<float, 4> Matrix4f;
186 typedef Matrix<double, 4> Matrix4d;
187
188 template<typename T, int Dimension>
189 Matrix<T, Dimension>::Matrix(void)
190 {
191
192 }
193
194 template<typename T, int Dimension>
195 Matrix<T, Dimension>::Matrix(const TypeReference value)
196 {
197         for (int i = 0; i < Dimension; i++)
198         {
199                 data[i] = VectorType(value);
200         }
201 }
202
203 template<typename T, int Dimension>
204 Matrix<T, Dimension>::Matrix(const TypeReference a11, const TypeReference a12,
205                                                          const TypeReference a21, const TypeReference a22)
206 {
207         EffectsStaticAssert(Dimension == 2);
208
209         data[0].Set(a11, a12);
210         data[1].Set(a21, a22);
211 }
212
213 template<typename T, int Dimension>
214 Matrix<T, Dimension>::Matrix(const TypeReference a11, const TypeReference a12, const TypeReference a13,
215                                                          const TypeReference a21, const TypeReference a22, const TypeReference a23,
216                                                          const TypeReference a31, const TypeReference a32, const TypeReference a33)
217 {
218         EffectsStaticAssert(Dimension == 3);
219
220         data[0].Set(a11, a12, a13);
221         data[1].Set(a21, a22, a23);
222         data[2].Set(a31, a32, a33);
223 }
224
225 template<typename T, int Dimension>
226 Matrix<T, Dimension>::Matrix(const TypeReference a11, const TypeReference a12, const TypeReference a13, const TypeReference a14,
227                                                          const TypeReference a21, const TypeReference a22, const TypeReference a23, const TypeReference a24,
228                                                          const TypeReference a31, const TypeReference a32, const TypeReference a33, const TypeReference a34,
229                                                          const TypeReference a41, const TypeReference a42, const TypeReference a43, const TypeReference a44)
230 {
231         EffectsStaticAssert(Dimension == 4);
232
233         data[0].Set(a11, a12, a13, a14);
234         data[1].Set(a21, a22, a23, a24);
235         data[2].Set(a31, a32, a33, a34);
236         data[3].Set(a41, a42, a43, a44);
237 }
238
239 template<typename T, int Dimension>
240 Matrix<T, Dimension>::Matrix(const VectorType& i, const VectorType& j)
241 {
242         EffectsStaticAssert(Dimension == 2);
243         data[0] = i;
244         data[1] = j;
245 }
246
247 template<typename T, int Dimension>
248 Matrix<T, Dimension>::Matrix(const VectorType& i, const VectorType& j, const VectorType& k)
249 {
250         EffectsStaticAssert(Dimension == 3);
251         data[0] = i;
252         data[1] = j;
253         data[2] = k;
254 }
255
256 template<typename T, int Dimension>
257 Matrix<T, Dimension>::Matrix(const VectorType& i, const VectorType& j, const VectorType& k, const VectorType& c)
258 {
259         EffectsStaticAssert(Dimension == 4);
260
261         data[0] = i;
262         data[1] = j;
263         data[2] = k;
264         data[3] = c;
265 }
266
267 template<typename T, int Dimension>
268 Matrix<T, Dimension>::Matrix(const MatrixType& other)
269 {
270         for (int i = 0; i < Dimension; i++)
271         {
272                 data[i] = other.data[i];
273         }
274 }
275
276 template<typename T, int Dimension>
277 Matrix<T, Dimension>& Matrix<T, Dimension>::operator=(const MatrixType& rhv)
278 {
279         for (int i = 0; i < Dimension; i++)
280         {
281                 data[i] = rhv.data[i];
282         }
283         return *this;
284 }
285
286 template<typename T, int Dimension>
287 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Set(const MatrixType& other)
288 {
289         for (int i = 0; i < Dimension; i++)
290         {
291                 data[i] = other.data[i];
292         }
293         return *this;
294 }
295
296 template<typename T, int Dimension>
297 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Set(const TypeReference value)
298 {
299         for (int i = 0; i < Dimension; i++)
300         {
301                 data[i] = VectorType(value);
302         }
303         return *this;
304 }
305
306 template<typename T, int Dimension>
307 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::FillFromArray(const T* pValue)
308 {
309         for (int i = 0; i < Dimension; i++)
310         {
311                 data[i] = VectorType::MakeFromArray(&pValue[Dimension * i]);
312         }
313
314         return *this;
315 }
316
317 template<typename T, int Dimension>
318 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::MakeFromArray(const T* pValue)
319 {
320         MatrixType result;
321         result.FillFromArray(pValue);
322         return result;
323 }
324
325 template<typename T, int Dimension>
326 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Identity(void)
327 {
328         *this = MatrixType::GetIdentity();
329         return *this;
330 }
331
332 template<typename T, int Dimension>
333 bool Matrix<T, Dimension>::IsIdentity(void) const
334 {
335         return *this == MatrixType::GetIdentity();
336 }
337
338 template<typename T, int Dimension>
339 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::operator-(void) const
340 {
341         MatrixType result;
342         for (int i = 0; i < Dimension; ++i)
343         {
344                 result.data[i] = -data[i];
345         }
346         return result;
347 }
348
349 template<typename T, int Dimension>
350 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Inverse(void)
351 {
352         static const T t0(0.0f);
353         static const T t1(1.0f);
354
355         T det = Determinant();
356         if (EffectsEqual(det, t0)) return *this;
357
358         det = t1 / det;
359         MatrixType result;
360         for (int i = 0; i < Dimension; ++i)
361         {
362                 for (int j = 0; j < Dimension; ++j)
363                 {
364                         result.data[i].data[j] = ((i+j) % 2 == 0 ? 1 : -1) * det * MinorMatrix(j, i).Determinant();
365                 }
366         }
367         return *this = result;
368 }
369
370 template<typename T, int Dimension>
371 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::GetInversed(void) const
372 {
373         MatrixType result(*this);
374         return result.Inverse();
375 }
376
377 template<typename T, int Dimension>
378 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Transpose(void)
379 {
380         for (int i = 0; i < Dimension; ++i)
381         {
382                 for (int j = i + 1;  j < Dimension; ++j)
383                 {
384                         EffectsSwap(data[j].data[i], data[i].data[j]);
385                 }
386         }
387         return *this;
388 }
389
390 template<typename T, int Dimension>
391 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::GetTransposed(void) const
392 {
393         MatrixType trasposed = *this;
394         return trasposed.Transpose();
395 }
396
397 template<typename T, int Dimension>
398 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::operator+=(const MatrixType& rhv)
399 {
400         for (int i = 0; i < Dimension; ++i)
401         {
402                 data[i] += rhv.data[i];
403         }
404         return *this;
405 }
406
407 template<typename T, int Dimension>
408 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::operator+=(const TypeReference rhv)
409 {
410         for (int i = 0; i < Dimension; ++i)
411         {
412                 data[i] += rhv;
413         }
414         return *this;
415 }
416
417 template<typename T, int Dimension>
418 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::operator-=(const MatrixType& rhv)
419 {
420         for (int i = 0; i < Dimension; ++i)
421         {
422                 data[i] -= rhv.data[i];
423         }
424         return *this;
425 }
426
427 template<typename T, int Dimension>
428 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::operator-=(const TypeReference rhv)
429 {
430         for (int i = 0; i < Dimension; ++i)
431         {
432                 data[i] -= rhv;
433         }
434         return *this;
435 }
436
437 template<typename T, int Dimension>
438 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::operator*=(const MatrixType& rhv)
439 {
440         MatrixType result(T(0.0f));
441         for (int i = 0; i < Dimension; ++i)
442         {
443                 for (int j = 0; j < Dimension; ++j)
444                 {
445                         for (int k = 0; k < Dimension; ++k)
446                                 result.data[i].data[j] += data[i].data[k] * rhv.data[k].data[j];
447                 }
448         }
449         *this = result;
450         return *this;
451 }
452
453 template<typename T, int Dimension>
454 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::operator*=(const TypeReference rhv)
455 {
456         for (int i = 0; i < Dimension; ++i)
457         {
458                 data[i] *= rhv;
459         }
460         return *this;
461 }
462
463 template<typename T, int Dimension>
464 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::operator/=(const TypeReference rhv)
465 {
466         for (int i = 0; i < Dimension; ++i)
467         {
468                 data[i] /= rhv;
469         }
470         return *this;
471 }
472
473 template<typename T, int Dimension>
474 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::GetMultipliedByMember(const MatrixType& rhv) const
475 {
476         MatrixType result;
477         for (int i = 0; i < Dimension; ++i)
478         {
479                 result.data[i].Set(data[i] * rhv.data[i]);
480         }
481         return result;
482 }
483
484 template<typename T, int Dimension>
485 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::MultiplyByMember(const MatrixType& rhv)
486 {
487         for (int i = 0; i < Dimension; ++i)
488         {
489                 data[i] = data[i] * rhv.data[i];
490         }
491         return *this;
492 }
493
494 template<typename T, int Dimension>
495 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::CreateMultipliedByMember(const MatrixType& lhv, const MatrixType& rhv)
496 {
497         MatrixType temp(lhv);
498         temp.MultiplyByMember(rhv);
499         return temp;
500 }
501
502 template<typename T, int Dimension>
503 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::GetDividedByMember(const MatrixType& rhv) const
504 {
505         MatrixType result;
506         for (int i = 0; i < Dimension; ++i)
507         {
508                 result.data[i].Set(data[i] / rhv.data[i]);
509         }
510         return result;
511 }
512
513 template<typename T, int Dimension>
514 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::DivideByMember(const MatrixType& rhv)
515 {
516         for (int i = 0; i < Dimension; ++i)
517         {
518                 data[i] = data[i] / rhv.data[i];
519         }
520         return *this;
521 }
522
523 template<typename T, int Dimension>
524 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::CreateDividedByMember(const MatrixType& lhv, const MatrixType& rhv)
525 {
526         MatrixType temp(lhv);
527         temp.DivideByMember(rhv);
528         return temp;
529 }
530
531 template<typename T, int Dimension>
532 T* Matrix<T, Dimension>::GetPointer(void)
533 {
534         return data[0].GetPointer();
535 }
536
537 template<typename T, int Dimension>
538 const T* Matrix<T, Dimension>::GetPointer(void) const
539 {
540         return data[0].GetPointer();
541 }
542
543 template<typename T, int Dimension>
544 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::Get(unsigned int row, unsigned int column)
545 {
546         return operator()(row, column);
547 }
548
549 template<typename T, int Dimension>
550 const typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::Get(unsigned int row, unsigned int column) const
551 {
552         return operator()(row, column);
553 }
554
555 template<typename T, int Dimension>
556 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::Get(unsigned int absIndex)
557 {
558         return operator()(absIndex);
559 }
560
561 template<typename T, int Dimension>
562 const typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::Get(unsigned int absIndex) const
563 {
564         return operator()(absIndex);
565 }
566
567 template<typename T, int Dimension>
568 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Set(unsigned int row, unsigned int column, const TypeReference value)
569 {
570         data[row].data[column] = value;
571         return *this;
572 }
573
574 template<typename T, int Dimension>
575 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Set(unsigned int absIndex, const TypeReference value)
576 {
577         data[absIndex / Dimension].data[absIndex % Dimension] = value;
578         return *this;
579 }
580
581 template<typename T, int Dimension>
582 typename Matrix<T, Dimension>::VectorType Matrix<T, Dimension>::GetColumn(unsigned int column) const
583 {
584         VectorType result;
585         for (int i = 0; i < Dimension; ++i)
586         {
587                 result.data[i] = data[i].data[column];
588         }
589         return result;
590 }
591
592 template<typename T, int Dimension>
593 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::SetColumn(unsigned int column, const VectorType& value)
594 {
595         for (int i = 0; i < Dimension; ++i)
596         {
597                 data[i].data[column] = value.data[i];
598         }
599
600         return *this;
601 }
602
603 template<typename T, int Dimension>
604 typename Matrix<T, Dimension>::VectorType& Matrix<T, Dimension>::GetRow(unsigned int row)
605 {
606         return data[row];
607 }
608
609 template<typename T, int Dimension>
610 const typename Matrix<T, Dimension>::VectorType& Matrix<T, Dimension>::GetRow(unsigned int row) const
611 {
612         return data[row];
613 }
614
615 template<typename T, int Dimension>
616 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::SetRow(unsigned int row, const VectorType& value)
617 {
618         data[row] = value;
619         return *this;
620 }
621
622 template<typename T, int Dimension>
623 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::operator()(unsigned int row, unsigned int column)
624 {
625         return data[row].data[column];
626 }
627
628 template<typename T, int Dimension>
629 const typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::operator()(unsigned int row, unsigned int column) const
630 {
631         return data[row].data[column];
632 }
633
634 template<typename T, int Dimension>
635 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::operator()(unsigned int absIndex)
636 {
637         return operator[](absIndex);
638 }
639
640 template<typename T, int Dimension>
641 const typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::operator()(unsigned int absIndex) const
642 {
643         return operator[](absIndex);
644 }
645
646 template<typename T, int Dimension>
647 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::operator[](unsigned int absIndex)
648 {
649         return data[absIndex / Dimension].data[absIndex % Dimension];
650 }
651
652 template<typename T, int Dimension>
653 const typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::operator[](unsigned int absIndex) const
654 {
655         return data[absIndex / Dimension].data[absIndex % Dimension];
656 }
657
658 template<typename T, int Dimension>
659 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Lerp(const MatrixType& to, const TypeReference coeff)
660 {
661         for (int i = 0; i < Dimension; ++i)
662         {
663                 data[i].Lerp(to.data[i], coeff);
664         }
665         return *this;
666 }
667
668 template<typename T, int Dimension>
669 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::GetLerped(const MatrixType& to, const TypeReference coeff) const
670 {
671         MatrixType result;
672         for (int i = 0; i < Dimension; ++i)
673         {
674                 result.data[i] = data[i].GetLerped(to.data[i], coeff);
675         }
676         return result;
677 }
678
679 template<typename T, int Dimension>
680 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::MakeLerped(const MatrixType& from, const MatrixType& to, const TypeReference coeff)
681 {
682         for (int i = 0; i < Dimension; ++i)
683         {
684                 data[i] = VectorType().MakeLerped(from.data[i], to.data[i], coeff);
685         }
686         return *this;
687 }
688
689 template<typename T, int Dimension>
690 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::CreateLerped(const MatrixType& from, const MatrixType& to, const TypeReference coeff)
691 {
692         MatrixType result;
693         for (int i = 0; i < Dimension; ++i)
694         {
695                 result.data[i] = VectorType().MakeLerped(from.data[i], to.data[i], coeff);
696         }
697         return result;
698 }
699
700 template<typename T, int Dimension>
701 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::Magnitude(void) const
702 {
703         return effects_sqrt(MagnitudeSqr());
704 }
705
706 template<typename T, int Dimension>
707 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::MagnitudeSqr(void) const
708 {
709         T result = T(0.0f);
710         for (int i = 0; i < Dimension; ++i)
711         {
712                 result += data[i].dot(data[i]);
713         }
714         return result;
715 }
716
717 template<typename T, int Dimension>
718 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::Trace(void) const
719 {
720         T result = T(0.0f);
721         for (int i = 0; i < Dimension; ++i)
722         {
723                 result += data[i].data[i];
724         }
725         return result;
726 }
727
728 template<typename T, int Dimension>
729 Matrix<T, (Dimension == 1 ? Dimension : Dimension - 1)> Matrix<T, Dimension>::MinorMatrix(unsigned int row, unsigned int column) const
730 {
731         Matrix<T, (Dimension == 1 ? Dimension : Dimension - 1)> result;
732
733         int columnCounter = 0;
734         for (unsigned int i = 0; i < Dimension; ++i)
735         {
736                 if (i != column)
737                 {
738                         int rowCounter = 0;
739                         for (unsigned int j = 0; j < Dimension; ++j)
740                         {
741                                 if (j != row)
742                                 {
743                                         result.data[rowCounter].data[columnCounter] = data[j].data[i];
744                                         ++rowCounter;
745                                 }
746                         }
747                         ++columnCounter;
748                 }
749         }
750         return result;
751 }
752
753 template<typename T, int Dimension>
754 typename Matrix<T, Dimension>::TypeReference Matrix<T, Dimension>::Determinant(void) const
755 {
756         if (Dimension == 1)
757         {
758                 return data[0].data[0];
759         }
760
761         T result = T(0.0f);
762         for (int i = 0; i < Dimension; ++i)
763         {
764                 result += (i % 2 == 0 ? 1 : -1) * data[i].data[0] * MinorMatrix(i, 0).Determinant();
765         }
766         return result;
767 }
768
769 template<typename T, int Dimension>
770 typename Matrix<T, Dimension>::VectorType& Matrix<T, Dimension>::ApplyTransform(VectorType& vector) const
771 {
772         VectorType temp(vector);
773         for (int i = 0; i < Dimension; ++i)
774         {
775                 vector.data[i] = data[i].dot(temp);
776         }
777         return vector;
778 }
779
780 template<typename T, int Dimension>
781 typename Matrix<T, Dimension>::VectorType Matrix<T, Dimension>::GetAppliedTransform(const VectorType& vector) const
782 {
783         VectorType result(vector);
784         return ApplyTransform(result);
785 }
786
787 template<typename T, int Dimension>
788 template<int VectorDimension>
789 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::MakeScale(const Vector<T, VectorDimension>& scale)
790 {
791         Identity();
792         for (int i = 0; i < VectorDimension; ++i)
793         {
794                 if (i < Dimension)
795                 {
796                         data[i].data[i] = scale.data[i];
797                 }
798         }
799         return *this;
800 };
801
802 template<typename T, int Dimension>
803 template<int VectorDimension>
804 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::SetScale(const Vector<T, VectorDimension>& scale)
805 {
806         for (int i = 0; i < VectorDimension; ++i)
807         {
808                 for (int j = 0; j < VectorDimension; ++j)
809                 {
810                         if (i < Dimension && j < Dimension)
811                         {
812                                 if (i == j)
813                                         data[i].data[i] = scale.data[i];
814                                 else
815                                         data[i].data[j] = T(0.0f);
816                         }
817                 }
818         }
819         return *this;
820 };
821
822 template<typename T, int Dimension>
823 template<int VectorDimension>
824 typename Matrix<T, Dimension>::MatrixType Matrix<T, Dimension>::CreateScale(const Vector<T, VectorDimension>& scale)
825 {
826         return MatrixType().MakeScale(scale);
827 };
828
829 template<typename T, int Dimension>
830 template<int VectorDimension>
831 typename Matrix<T, Dimension>::MatrixType& Matrix<T, Dimension>::Scale(const Vector<T, VectorDimension>& scale)
832 {
833         for (int i = 0; i < VectorDimension; ++i)
834         {
835                 for (int j = 0; j < VectorDimension;  ++j)
836                 {
837                         if (i < Dimension && j < Dimension)
838                         {
839                                 data[i].data[j] *= scale.data[i];
840                         }
841                 }
842         }
843         return *this;
844 };
845
846 template<typename T, int Dimension>
847 bool Matrix<T, Dimension>::IsEqual(const MatrixType& rhv, const TypeReference epsilon) const
848 {
849         for (int i = 0; i < Dimension; ++i)
850         {
851                 if (!data[i].IsEqual(rhv.data[i], epsilon))
852                 {
853                         return false;
854                 }
855         }
856         return true;
857 }
858
859 template<typename T, int Dimension>
860 bool IsEqual(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv, const typename Matrix<T, Dimension>::TypeReference epsilon)
861 {
862         return lhv.IsEqual(rhv, epsilon);
863 }
864
865 template<typename T, int Dimension>
866 Matrix<T, Dimension> operator+(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv)
867 {
868         Matrix<T, Dimension> result;
869         for (int i = 0; i < Dimension; ++i)
870         {
871                 result.data[i] = lhv.data[i] + rhv.data[i];
872         }
873
874         return result;
875 }
876
877 template<typename T, int Dimension>
878 Matrix<T, Dimension> operator+(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv)
879 {
880         Matrix<T, Dimension> result;
881         for (int i = 0; i < Dimension; ++i)
882         {
883                 result.data[i] = lhv.data[i] + rhv;
884         }
885
886         return result;
887 }
888
889 template<typename T, int Dimension>
890 Matrix<T, Dimension> operator+(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv)
891 {
892         Matrix<T, Dimension> result;
893         for (int i = 0; i < Dimension; ++i)
894         {
895                 result.data[i] = lhv + rhv.data[i];
896         }
897
898         return result;
899 }
900
901 template<typename T, int Dimension>
902 Matrix<T, Dimension> operator-(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv)
903 {
904         Matrix<T, Dimension> result;
905         for (int i = 0; i < Dimension; ++i)
906         {
907                 result.data[i] = lhv.data[i] - rhv.data[i];
908         }
909
910         return result;
911 }
912
913 template<typename T, int Dimension> Matrix<T, Dimension> operator-(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv)
914 {
915         Matrix<T, Dimension> result;
916         for (int i = 0; i < Dimension; ++i)
917         {
918                 result.data[i] = lhv.data[i] - rhv;
919         }
920
921         return result;
922 }
923
924 template<typename T, int Dimension>
925 Matrix<T, Dimension> operator-(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv)
926 {
927         Matrix<T, Dimension> result;
928         for (int i = 0; i < Dimension; ++i)
929         {
930                 result.data[i] = lhv - rhv.data[i];
931         }
932
933         return result;
934 }
935
936 template<typename T, int Dimension>
937 Matrix<T, Dimension> operator*(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv)
938 {
939         Matrix<T, Dimension> result(lhv);
940         return result *= rhv;
941 }
942
943 template<typename T, int Dimension>
944 Matrix<T, Dimension> operator*(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv)
945 {
946         Matrix<T, Dimension> result(lhv);
947         return result *= rhv;
948 }
949
950 template<typename T, int Dimension>
951 Matrix<T, Dimension> operator*(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv)
952 {
953         Matrix<T, Dimension> result(rhv);
954         return result *= lhv;
955 }
956
957 template<typename T, int Dimension>
958 Vector<T, Dimension> operator*(const Matrix<T, Dimension>& lhv, const Vector<T, Dimension>& rhv)
959 {
960         Vector<T, Dimension> result;
961         for (int i = 0; i < Dimension; ++i)
962         {
963                 result.data[i] = lhv.data[i].dot(rhv);
964         }
965
966         return result;
967 }
968
969 template<typename T, int Dimension>
970 Vector<T, Dimension> operator*(const Vector<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv)
971 {
972         Vector<T, Dimension> temp;
973         for (int i = 0; i < Dimension; ++i)
974         {
975                 temp.data[i] = rhv.GetColumn(i).Dot(lhv);
976         }
977         return temp;
978 }
979
980 template<typename T, int Dimension>
981 Vector<T, Dimension - 1> operator*(const Matrix<T, Dimension>& lhv, const Vector<T, Dimension - 1>& rhv)
982 {
983         Matrix<T, Dimension - 1> minor = lhv.MinorMatrix(Dimension - 1, Dimension - 1);
984         Vector<T, Dimension - 1> result = minor * rhv;
985         for (int i = 0; i < Dimension - 1; ++i)
986         {
987                 result.data[i] += lhv.data[i].data[Dimension - 1];
988         }
989
990         return result;
991 }
992
993 template<typename T, int Dimension>
994 Vector<T, Dimension - 1> operator*(const Vector<T, Dimension - 1>& lhv, const Matrix<T, Dimension>& rhv)
995 {
996         Matrix<T, Dimension - 1> minor = rhv.MinorMatrix(Dimension - 1, Dimension - 1);
997         Vector<T, Dimension - 1> result = lhv * minor;
998         for (int i = 0; i < Dimension - 1; ++i)
999         {
1000                 result.data[i] += rhv.data[i].data[Dimension - 1];
1001         }
1002         return result;
1003 }
1004
1005 template<typename T, int Dimension>
1006 Matrix<T, Dimension> operator/(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv)
1007 {
1008         Matrix<T, Dimension> result;
1009         for (int i = 0; i < Dimension; ++i)
1010         {
1011                 result.data[i] = lhv.data[i] / rhv;
1012         }
1013
1014         return result;
1015 }
1016
1017 template<typename T, int Dimension>
1018 Matrix<T, Dimension> operator/(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv)
1019 {
1020         Matrix<T, Dimension> result;
1021         for (int i = 0; i < Dimension; ++i)
1022         {
1023                 result.data[i] = lhv / rhv.data[i];
1024         }
1025
1026         return result;
1027 }
1028
1029 template<typename T, int Dimension>
1030 bool operator==(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv)
1031 {
1032         for (int i = 0; i < Dimension; ++i)
1033         {
1034                 if (lhv.data[i] != rhv.data[i])
1035                 {
1036                         return false;
1037                 }
1038         }
1039         return true;
1040 }
1041
1042 template<typename T, int Dimension>
1043 bool operator==(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv)
1044 {
1045         for (int i = 0; i < Dimension; ++i)
1046         {
1047                 if (lhv.data[i] != rhv)
1048                 {
1049                         return false;
1050                 }
1051         }
1052         return true;
1053 }
1054
1055 template<typename T, int Dimension>
1056 bool operator==(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv)
1057 {
1058         for (int i = 0; i < Dimension; ++i)
1059         {
1060                 if (lhv != rhv.data[i])
1061                 {
1062                         return false;
1063                 }
1064         }
1065         return true;
1066 }
1067
1068 template<typename T, int Dimension>
1069 bool operator!=(const Matrix<T, Dimension>& lhv, const Matrix<T, Dimension>& rhv)
1070 {
1071         return !(lhv == rhv);
1072 }
1073
1074 template<typename T, int Dimension>
1075 bool operator!=(const Matrix<T, Dimension>& lhv, const typename Matrix<T, Dimension>::TypeReference rhv)
1076 {
1077         return !(lhv == rhv);
1078 }
1079
1080 template<typename T, int Dimension>
1081 bool operator!=(const typename Matrix<T, Dimension>::TypeReference lhv, const Matrix<T, Dimension>& rhv)
1082 {
1083         return !(lhv == rhv);
1084 }
1085
1086 }}}}} //Tizen::Ui::Effects::_Renderer::Math
1087
1088 #endif //_FUI_EFFECTS_INTERNAL_RENDERER_MATH_MATRIX_H_