Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / effects / inc / utils / FUiEffects_UtilsMatrix4.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_UtilsMatrix4.h
20  * @brief      The Matrix4 class
21  *
22  */
23
24 #ifndef _FUI_EFFECTS_INTERNAL_UTILS_MATRIX4_H_
25 #define _FUI_EFFECTS_INTERNAL_UTILS_MATRIX4_H_
26
27 #include "FUiEffects_UtilsAdapterFunctions.h"
28
29 namespace Tizen { namespace Ui { namespace Effects { namespace _Utils
30 {
31         template<class T> class Vector4;
32         template<class T> class _Vector3;
33         template<class T> class Matrix3;
34         template<class T> class Quaternion;
35
36         template<class T> class Matrix4
37         {
38             private:
39                 typedef Matrix4<T> SelfType;
40
41             public:
42                 Vector4<T> i;
43                 Vector4<T> j;
44                 Vector4<T> k;
45                 Vector4<T> c;
46
47                 inline Matrix4();
48                 inline explicit Matrix4(const T& aValue);
49                 inline explicit Matrix4(const T* aValues);
50                 inline Matrix4(const SelfType& aOther);
51                 inline Matrix4(const Vector4<T>& aI, const Vector4<T>& aJ,
52                                const Vector4<T>& aK, const Vector4<T>& aC);
53                 inline Matrix4(const _Vector3<T>& aI, const _Vector3<T>& aJ,
54                                const _Vector3<T>& aK, const _Vector3<T>& aC);
55                 inline Matrix4(const T& a11, const T& a12, const T& a13, const T& a14,
56                                const T& a21, const T& a22, const T& a23, const T& a24,
57                                const T& a31, const T& a32, const T& a33, const T& a34,
58                                const T& a41, const T& a42, const T& a43, const T& a44);
59
60                 inline SelfType& operator=(const SelfType& aRhv);
61
62                 inline SelfType& set(const T& aValue);
63                 inline SelfType& set(const T* aValues);
64                 inline SelfType& set(const SelfType& aOther);
65                 inline SelfType& set(const Vector4<T>& aI, const Vector4<T>& aJ,
66                                      const Vector4<T>& aK, const Vector4<T>& aC);
67                 inline SelfType& set(const _Vector3<T>& aI, const _Vector3<T>& aJ,
68                                      const _Vector3<T>& aK, const _Vector3<T>& aC);
69                 inline SelfType& set(const T& a11, const T& a12, const T& a13, const T& a14,
70                                      const T& a21, const T& a22, const T& a23, const T& a24,
71                                      const T& a31, const T& a32, const T& a33, const T& a34,
72                                      const T& a41, const T& a42, const T& a43, const T& a44);
73
74                 inline SelfType& identity();
75                 inline static const SelfType& getIdentity();
76                 inline bool isIdentity() const;
77
78                 inline SelfType operator-() const;
79                 inline SelfType& inverse();
80                 inline SelfType getInversed() const;
81                 inline SelfType& transpose();
82                 inline SelfType getTransposed() const;
83
84                 inline SelfType& operator+=(const SelfType& aRhv);
85                 inline SelfType& operator+=(const T& aRhv);
86                 inline SelfType& operator-=(const SelfType& aRhv);
87                 inline SelfType& operator-=(const T& aRhv);
88                 inline SelfType& operator*=(const SelfType& aRhv);
89                 inline SelfType& operator*=(const T& aRhv);
90                 inline SelfType& operator/=(const T& aRhv);
91                 inline SelfType GetMultipliedByMember(const SelfType& aRhv) const;
92                 inline SelfType& multiplyByMember(const SelfType& aRhv);
93                 static inline SelfType createMultipliedByMember(const SelfType& aLhv, const SelfType& aRhv);
94                 inline SelfType getDividedByMember(const SelfType& aRhv) const;
95                 inline SelfType& divideByMember(const SelfType& aRhv);
96                 static inline SelfType createDividedByMember(const SelfType& aLhv, const SelfType& aRhv);
97
98                 inline T* getPointer();
99                 inline const T* getPointer() const;
100                 inline T& get(unsigned int aRow, unsigned int aColumn);
101                 inline const T& get(unsigned int aRow, unsigned int aColumn) const;
102                 inline T& get(unsigned int aAbsIndex);
103                 inline const T& get(unsigned int aAbsIndex) const;
104                 inline SelfType& set(unsigned int aRow, unsigned int aColumn, const T& aValue);
105                 inline SelfType& set(unsigned int aAbsIndex, const T& aValue);
106                 inline Vector4<T>& getRow(unsigned int aRow);
107                 inline const Vector4<T>& getRow(unsigned int aRow) const;
108                 inline SelfType& setRow(unsigned int aRow, const Vector4<T>& aValue);
109                 inline Vector4<T> getColumn(unsigned int aColumn) const;
110                 inline SelfType& setColumn(unsigned int aColumn, const Vector4<T>& aValue);
111                 inline T& operator()(unsigned int aRow, unsigned int aColumn);
112                 inline const T& operator()(unsigned int aRow, unsigned int aColumn) const;
113                 inline T& operator()(unsigned int aAbsIndex);
114                 inline const T& operator()(unsigned int aAbsIndex) const;
115                 inline T& operator[](unsigned int aAbsIndex);
116                 inline const T& operator[](unsigned int aAbsIndex) const;
117
118                 inline SelfType& lerp(const SelfType& aTo, const T& aCoeff);
119                 inline SelfType getLerped(const SelfType& aTo, const T& aCoeff) const;
120                 inline SelfType& makeLerped(const SelfType& aFrom, const SelfType& aTo, const T& aCoeff);
121                 static inline SelfType createLerped(const SelfType& aFrom, const SelfType& aTo, const T& aCoeff);
122                 inline SelfType& slerp(const SelfType& aTo, const T& aCoeff);
123                 inline SelfType getSlerped(const SelfType& aTo, const T& aCoeff) const;
124                 inline SelfType& makeSlerped(const SelfType& aFrom, const SelfType& aTo, const T& aCoeff);
125                 static inline SelfType createSlerped(const SelfType& aFrom, const SelfType& aTo, const T& aCoeff);
126
127                 inline T determinant() const;
128
129                 inline Vector4<T>& applyTransform(Vector4<T>& aVector) const;
130                 inline Vector4<T> getAppliedTransform(const Vector4<T>& aVector) const;
131                 inline Vector4<T>& applyRotation(Vector4<T>& aVector) const;
132                 inline Vector4<T> getAppliedRotation(const Vector4<T>& aVector) const;
133                 inline Vector4<T>& applyTranslate(Vector4<T>& aVector) const;
134                 inline Vector4<T> getAppliedTranslate(const Vector4<T>& aVector) const;
135
136                 inline _Vector3<T>& applyTransform(_Vector3<T>& aVector) const;
137                 inline _Vector3<T> getAppliedTransform(const _Vector3<T>& aVector) const;
138                 inline _Vector3<T>& applyRotation(_Vector3<T>& aVector) const;
139                 inline _Vector3<T> getAppliedRotation(const _Vector3<T>& aVector) const;
140                 inline _Vector3<T>& applyTranslate(_Vector3<T>& aVector) const;
141                 inline _Vector3<T> getAppliedTranslate(const _Vector3<T>& aVector) const;
142
143                 inline Quaternion<T>& applyRotation(Quaternion<T>& aQuaternion) const;
144                 inline Quaternion<T> getAppliedRotation(const Quaternion<T>& aQuaternion) const;
145
146                 inline SelfType& setRotation(const T& aXAngleRAD, const T& aYAngleRAD, const T& aZAngleRAD, RotationOrder3 aOrder = ROTATION_XYZ);
147                 inline SelfType& setRotation(const _Vector3<T>& aAnglesRAD, RotationOrder3 aOrder = ROTATION_XYZ);
148                 inline SelfType& setRotationX(const T& aAngleRAD);
149                 inline SelfType& setRotationY(const T& aAngleRAD);
150                 inline SelfType& setRotationZ(const T& aAngleRAD);
151                 inline SelfType& setRotationAxis(const _Vector3<T>& aAxis, const T& aAngleRAD);
152                 inline SelfType& setRotationAxis(const T& aXAxis, const T& aYAxis, const T& aZAxis, const T& aAngleRAD);
153                 inline SelfType& setRotation(const Quaternion<T>& aRotation);
154                 inline SelfType& setRotation(const Matrix3<T>& aRotation);
155                 inline SelfType& makeRotation(const T& aXAngleRAD, const T& aYAngleRAD, const T& aZAngleRAD, RotationOrder3 aOrder = ROTATION_XYZ);
156                 inline SelfType& makeRotation(const _Vector3<T>& aAnglesRAD, RotationOrder3 aOrder = ROTATION_XYZ);
157                 inline SelfType& makeRotationX(const T& aAngleRAD);
158                 inline SelfType& makeRotationY(const T& aAngleRAD);
159                 inline SelfType& makeRotationZ(const T& aAngleRAD);
160                 inline SelfType& makeRotationAxis(const _Vector3<T>& aAxis, const T& aAngleRAD);
161                 inline SelfType& makeRotationAxis(const T& aXAxis, const T& aYAxis, const T& aZAxis, const T& aAngleRAD);
162                 inline SelfType& makeRotation(const Quaternion<T>& aRotation);
163                 inline SelfType& makeRotation(const Matrix3<T>& aRotation);
164                 inline SelfType& rotate(const T& aXAngleRAD, const T& aYAngleRAD, const T& aZAngleRAD, RotationOrder3 aOrder = ROTATION_XYZ);
165                 inline SelfType& rotate(const _Vector3<T>& aAnglesRAD, RotationOrder3 aOrder3 = ROTATION_XYZ);
166                 inline SelfType& rotateX(const T& aAngleRAD);
167                 inline SelfType& rotateY(const T& aAngleRAD);
168                 inline SelfType& rotateZ(const T& aAngleRAD);
169                 inline SelfType& rotateAxis(const _Vector3<T>& aAxis, const T& aAngleRAD);
170                 inline SelfType& rotateAxis(const T& aXAxis, const T& aYAxis, const T& aZAxis, const T& aAngleRAD);
171                 inline SelfType& rotate(const Quaternion<T>& aRotation);
172                 inline SelfType& rotate(const Matrix3<T>& aRotation);
173                 inline SelfType& rotate(const Matrix4<T>& aRotation);
174                 static inline SelfType createRotation(const T& aXAngleRAD, const T& aYAngleRAD, const T& aZAngleRAD, RotationOrder3 aOrder = ROTATION_XYZ);
175                 static inline SelfType createRotation(const _Vector3<T>& aAnglesRAD, RotationOrder3 aOrder = ROTATION_XYZ);
176                 static inline SelfType createRotationX(const T& aAngleRAD);
177                 static inline SelfType createRotationY(const T& aAngleRAD);
178                 static inline SelfType createRotationZ(const T& aAngleRAD);
179                 static inline SelfType createRotationAxis(const _Vector3<T>& aAxis, const T& aAngleRAD);
180                 static inline SelfType createRotationAxis(const T& aXAxis, const T& aYAxis, const T& aZAxis, const T& aAngleRAD);
181                 static inline SelfType createRotation(const Quaternion<T>& aRotation);
182                 static inline SelfType createRotation(const Matrix3<T>& aRotation);
183                 inline const SelfType& getRotationAngles(T& aXAngleRAD, T& aYAngeRAD, T& aZAngleRAD, unsigned int aSolutionNumber = 1) const;
184                 inline Quaternion<T> getQuaternion() const;
185                 inline Quaternion<T>& getQuaternion(Quaternion<T>& aRotation) const;
186                 inline Matrix3<T> getRotation() const;
187                 inline Matrix3<T>& getRotation(Matrix3<T>& aRotation) const;
188
189                 inline SelfType& makeScale(const T& aX, const T& aY, const T& aZ);
190                 inline SelfType& makeScale(const _Vector3<T>& aScale);
191                 inline SelfType& setScale(const T& aX, const T& aY, const T& aZ);
192                 inline SelfType& setScale(const _Vector3<T>& aScale);
193                 static inline SelfType createScale(const T& aX, const T& aY, const T& aZ);
194                 static inline SelfType createScale(const _Vector3<T>& aScale);
195                 inline SelfType& scale(const T& aX, const T& aY, const T& aZ);
196                 inline SelfType& scale(const _Vector3<T>& aScale);
197
198                 inline SelfType& setTranslation(const T& aX, const T& aY, const T& aZ);
199                 inline SelfType& setTranslation(const _Vector3<T>& aTran);
200                 inline SelfType& makeTranslation(const T& aX, const T& aY, const T& aZ);
201                 inline SelfType& makeTranslation(const _Vector3<T>& aTran);
202                 inline SelfType& translate(const T& aX, const T& aY, const T& aZ);
203                 inline SelfType& translate(const _Vector3<T>& aTran);
204                 static inline SelfType createTranslation(const T& aX, const T& aY, const T& aZ);
205                 static inline SelfType createTranslation(const _Vector3<T>& aTran);
206                 inline _Vector3<T> getTranslation() const;
207                 inline Vector4<T> getFullTranslation() const;
208
209                 inline SelfType& makeLookAtLH(const _Vector3<T>& aEye, const _Vector3<T>& aAt, const _Vector3<T>& aUp);
210                 inline SelfType& makeLookAtRH(const _Vector3<T>& aEye, const _Vector3<T>& aAt, const _Vector3<T>& aUp);
211                 inline SelfType& makeOrthoRH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar);
212                 inline SelfType& makeOrthoLH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar);
213                 inline SelfType& makeOrthoRH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar);
214                 inline SelfType& makeOrthoLH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar);
215                 inline SelfType& makePerspectiveLH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar);
216                 inline SelfType& makePerspectiveRH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar);
217                 inline SelfType& makePerspectiveLH(const T& aWidth, const T& aHeight, const T& aZnear, const T& aZFar);
218                 inline SelfType& makePerspectiveRH(const T& aWidth, const T& aHeight, const T& aZnear, const T& aZFar);
219                 inline SelfType& makePerspectiveFovLH(const T& aFovY, const T& aAspect, const T& aZnear, const T& aZFar);
220                 inline SelfType& makePerspectiveFovRH(const T& aFovY, const T& aAspect, const T& aZnear, const T& aZFar);
221                 static inline SelfType createLookAtLH(const _Vector3<T>& aEye, const _Vector3<T>& aAt, const _Vector3<T>& aUp);
222                 static inline SelfType createLookAtRH(const _Vector3<T>& aEye, const _Vector3<T>& aAt, const _Vector3<T>& aUp);
223                 static inline SelfType createOrthoRH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar);
224                 static inline SelfType createOrthoLH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar);
225                 static inline SelfType createOrthoRH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar);
226                 static inline SelfType createOrthoLH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar);
227                 static inline SelfType createPerspectiveLH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar);
228                 static inline SelfType createPerspectiveRH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar);
229                 static inline SelfType createPerspectiveLH(const T& aWidth, const T& aHeight, const T& aZnear, const T& aZFar);
230                 static inline SelfType createPerspectiveRH(const T& aWidth, const T& aHeight, const T& aZnear, const T& aZFar);
231                 static inline SelfType createPerspectiveFovLH(const T& aFovY, const T& aAspect, const T& aZnear, const T& aZFar);
232                 static inline SelfType createPerspectiveFovRH(const T& aFovY, const T& aAspect, const T& aZnear, const T& aZFar);
233
234                 inline bool getOrthoParamsRH(T& aLeft, T& aRight, T& aTop, T& aBottom, T& aZNear, T& aZFar) const;
235                 inline bool getPerspectiveParamsRH(T& aLeft, T& aRight, T& aTop, T& aBottom, T& aZNear, T& aZFar) const;
236                 inline bool getPerspectiveParamsRH(T& aFovY, T& aAspect, T& aZNear, T& aZFar) const;
237                 inline bool getViewParams(_Vector3<T>& aPosition, _Vector3<T>& aDirection, _Vector3<T>& aUp, _Vector3<T>& aRight) const;
238         };
239
240         typedef Matrix4<float> Mat4f;
241         typedef Matrix4<double> Mat4d;
242
243         template<class T> inline Matrix4<T> operator+(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv);
244         template<class T> inline Matrix4<T> operator+(const Matrix4<T>& aLhv, const T& aRhv);
245         template<class T> inline Matrix4<T> operator+(const T& aLhv, const Matrix4<T>& aRhv);
246         template<class T> inline Matrix4<T> operator-(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv);
247         template<class T> inline Matrix4<T> operator-(const Matrix4<T>& aLhv, const T& aRhv);
248         template<class T> inline Matrix4<T> operator-(const T& aLhv, const Matrix4<T>& aRhv);
249         template<class T> inline Matrix4<T> operator*(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv);
250         template<class T> inline Matrix4<T> operator*(const Matrix4<T>& aLhv, const T& aRhv);
251         template<class T> inline Matrix4<T> operator*(const T& aLhv, const Matrix4<T>& aRhv);
252         template<class T> inline Vector4<T> operator*(const Matrix4<T>& aLhv, const Vector4<T>& aRhv);
253         template<class T> inline Vector4<T> operator*(const Vector4<T>& aLhv, const Matrix4<T>& aRhv);
254         template<class T> inline _Vector3<T> operator*(const Matrix4<T>& aLhv, const _Vector3<T>& aRhv);
255         template<class T> inline _Vector3<T> operator*(const _Vector3<T>& aLhv, const Matrix4<T>& aRhv);
256         template<class T> inline Matrix4<T> operator/(const Matrix4<T>& aLhv, const T& aRhv);
257         template<class T> inline Matrix4<T> operator/(const T& aLhv, const Matrix4<T>& aRhv);
258         template<class T> inline bool operator==(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv);
259         template<class T> inline bool operator==(const Matrix4<T>& aLhv, const T& aRhv);
260         template<class T> inline bool operator==(const T& aLhv, const Matrix4<T>& aRhv);
261         template<class T> inline bool operator!=(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv);
262         template<class T> inline bool operator!=(const Matrix4<T>& aLhv, const T& aRhv);
263         template<class T> inline bool operator!=(const T& aLhv, const Matrix4<T>& aRhv);
264
265         template<class T> inline Matrix4<T>::Matrix4() {}
266
267         template<class T> inline Matrix4<T>::Matrix4(const T& aValue):
268             i(aValue), j(aValue), k(aValue), c(aValue) {}
269
270         template<class T> inline Matrix4<T>::Matrix4(const T* aValues):
271             i(aValues[0], aValues[1], aValues[2], aValues[3]),
272             j(aValues[4], aValues[5], aValues[6], aValues[7]),
273             k(aValues[8], aValues[9], aValues[10], aValues[11]),
274             c(aValues[12], aValues[13], aValues[14], aValues[15]) {}
275
276         template<class T> inline Matrix4<T>::Matrix4(const Matrix4<T>& aOther):
277             i(aOther.i), j(aOther.j), k(aOther.k), c(aOther.c) {}
278
279         template<class T> inline Matrix4<T>::Matrix4(const Vector4<T>& aI, const Vector4<T>& aJ, const Vector4<T>& aK, const Vector4<T>& aC):
280             i(aI), j(aJ), k(aK), c(aC) {}
281
282         template<class T> inline Matrix4<T>::Matrix4(const _Vector3<T>& aI, const _Vector3<T>& aJ, const _Vector3<T>& aK, const _Vector3<T>& aC):
283             i(aI, T(0.0f)), j(aJ, T(0.0f)), k(aK, T(0.0f)), c(aC, T(1.0f)) {}
284
285         template<class T> inline Matrix4<T>::Matrix4(const T& a11, const T& a12, const T& a13, const T& a14,
286                                               const T& a21, const T& a22, const T& a23, const T& a24,
287                                               const T& a31, const T& a32, const T& a33, const T& a34,
288                                               const T& a41, const T& a42, const T& a43, const T& a44):
289             i(a11, a12, a13, a14), j(a21, a22, a23, a24), k(a31, a32, a33, a34), c(a41, a42, a43, a44) {}
290
291         template<class T> inline Matrix4<T>& Matrix4<T>::operator=(const Matrix4<T>& aRhv)
292         {
293             i = aRhv.i;
294             j = aRhv.j;
295             k = aRhv.k;
296             c = aRhv.c;
297             return *this;
298         }
299
300         template<class T> inline Matrix4<T>& Matrix4<T>::set(const T& aValue)
301         {
302             i.set(aValue);
303             j.set(aValue);
304             k.set(aValue);
305             c.set(aValue);
306             return *this;
307         }
308
309         template<class T> inline Matrix4<T>& Matrix4<T>::set(const T* aValues)
310         {
311             i.set(aValues[0], aValues[1], aValues[2], aValues[3]);
312             j.set(aValues[4], aValues[5], aValues[6], aValues[7]);
313             k.set(aValues[8], aValues[9], aValues[10], aValues[11]);
314             c.set(aValues[12], aValues[13], aValues[14], aValues[15]);
315             return *this;
316         }
317
318         template<class T> inline Matrix4<T>& Matrix4<T>::set(const Matrix4<T>& aOther)
319         {
320             i = aOther.i;
321             j = aOther.j;
322             k = aOther.k;
323             c = aOther.c;
324             return *this;
325         }
326
327         template<class T> inline Matrix4<T>& Matrix4<T>::set(const Vector4<T>& aI, const Vector4<T>& aJ,
328                                                       const Vector4<T>& aK, const Vector4<T>& aC)
329         {
330             i = aI;
331             j = aJ;
332             k = aK;
333             c = aC;
334             return *this;
335         }
336
337         template<class T> inline Matrix4<T>& Matrix4<T>::set(const _Vector3<T>& aI, const _Vector3<T>& aJ,
338                                                       const _Vector3<T>& aK, const _Vector3<T>& aC)
339         {
340             i.set(aI, T(0.0f));
341             j.set(aJ, T(0.0f));
342             k.set(aK, T(0.0f));
343             c.set(aC, T(1.0f));
344             return *this;
345         }
346
347         template<class T> inline Matrix4<T>& Matrix4<T>::set(const T& a11, const T& a12, const T& a13, const T& a14,
348                                                       const T& a21, const T& a22, const T& a23, const T& a24,
349                                                       const T& a31, const T& a32, const T& a33, const T& a34,
350                                                       const T& a41, const T& a42, const T& a43, const T& a44)
351         {
352             i.set(a11, a12, a13, a14);
353             j.set(a21, a22, a23, a24);
354             k.set(a31, a32, a33, a34);
355             c.set(a41, a42, a43, a44);
356             return *this;
357         }
358
359         template<class T> inline Matrix4<T>& Matrix4<T>::identity()
360         {
361             return operator=(getIdentity());
362         }
363
364         template<class T> inline const Matrix4<T>& Matrix4<T>::getIdentity()
365         {
366             static Matrix4<T> identityMatrix(
367                 T(1.0f), T(0.0f), T(0.0f), T(0.0f),
368                 T(0.0f), T(1.0f), T(0.0f), T(0.0f),
369                 T(0.0f), T(0.0f), T(1.0f), T(0.0f),
370                 T(0.0f), T(0.0f), T(0.0f), T(1.0f));
371             return identityMatrix;
372         }
373
374         template<class T> inline Matrix4<T> Matrix4<T>::operator-() const
375         {
376             return Matrix4<T>(-i, -j, -k, -c);
377         }
378
379         template<class T> inline Matrix4<T>& Matrix4<T>::inverse()
380         {
381             static const T t0(0.0f);
382
383                     T s = determinant();
384                     if(EffectsEqual(s, t0)) return *this;
385                     set(
386                 (j.y*(k.z*c.w - k.w*c.z) + j.z*(k.w*c.y - k.y*c.w) + j.w*(k.y*c.z - k.z*c.y)) / s,
387                     (k.y*(i.z*c.w - i.w*c.z) + k.z*(i.w*c.y - i.y*c.w) + k.w*(i.y*c.z - i.z*c.y)) / s,
388                     (c.y*(i.z*j.w - i.w*j.z) + c.z*(i.w*j.y - i.y*j.w) + c.w*(i.y*j.z - i.z*j.y)) / s,
389                     (i.y*(j.w*k.z - j.z*k.w) + i.z*(j.y*k.w - j.w*k.y) + i.w*(j.z*k.y - j.y*k.z)) / s,
390                     (j.z*(k.x*c.w - k.w*c.x) + j.w*(k.z*c.x - k.x*c.z) + j.x*(k.w*c.z - k.z*c.w)) / s,
391                     (k.z*(i.x*c.w - i.w*c.x) + k.w*(i.z*c.x - i.x*c.z) + k.x*(i.w*c.z - i.z*c.w)) / s,
392                     (c.z*(i.x*j.w - i.w*j.x) + c.w*(i.z*j.x - i.x*j.z) + c.x*(i.w*j.z - i.z*j.w)) / s,
393                     (i.z*(j.w*k.x - j.x*k.w) + i.w*(j.x*k.z - j.z*k.x) + i.x*(j.z*k.w - j.w*k.z)) / s,
394                     (j.w*(k.x*c.y - k.y*c.x) + j.x*(k.y*c.w - k.w*c.y) + j.y*(k.w*c.x - k.x*c.w)) / s,
395                     (k.w*(i.x*c.y - i.y*c.x) + k.x*(i.y*c.w - i.w*c.y) + k.y*(i.w*c.x - i.x*c.w)) / s,
396                     (c.w*(i.x*j.y - i.y*j.x) + c.x*(i.y*j.w - i.w*j.y) + c.y*(i.w*j.x - i.x*j.w)) / s,
397                     (i.w*(j.y*k.x - j.x*k.y) + i.x*(j.w*k.y - j.y*k.w) + i.y*(j.x*k.w - j.w*k.x)) / s,
398                     (j.x*(k.z*c.y - k.y*c.z) + j.y*(k.x*c.z - k.z*c.x) + j.z*(k.y*c.x - k.x*c.y)) / s,
399                     (k.x*(i.z*c.y - i.y*c.z) + k.y*(i.x*c.z - i.z*c.x) + k.z*(i.y*c.x - i.x*c.y)) / s,
400                     (c.x*(i.z*j.y - i.y*j.z) + c.y*(i.x*j.z - i.z*j.x) + c.z*(i.y*j.x - i.x*j.y)) / s,
401                     (i.x*(j.y*k.z - j.z*k.y) + i.y*(j.z*k.x - j.x*k.z) + i.z*(j.x*k.y - j.y*k.x)) / s);
402             return *this;
403         }
404
405         template<class T> inline Matrix4<T> Matrix4<T>::getInversed() const
406         {
407             static const T t0(0.0f);
408
409             T s = determinant();
410             if(EffectsEqual(s, t0)) return *this;
411                     Matrix4 inverted(
412                         (j.y*(k.z*c.w - k.w*c.z) + j.z*(k.w*c.y - k.y*c.w) + j.w*(k.y*c.z - k.z*c.y)) / s,
413                                 (k.y*(i.z*c.w - i.w*c.z) + k.z*(i.w*c.y - i.y*c.w) + k.w*(i.y*c.z - i.z*c.y)) / s,
414                                     (c.y*(i.z*j.w - i.w*j.z) + c.z*(i.w*j.y - i.y*j.w) + c.w*(i.y*j.z - i.z*j.y)) / s,
415                                     (i.y*(j.w*k.z - j.z*k.w) + i.z*(j.y*k.w - j.w*k.y) + i.w*(j.z*k.y - j.y*k.z)) / s,
416                                     (j.z*(k.x*c.w - k.w*c.x) + j.w*(k.z*c.x - k.x*c.z) + j.x*(k.w*c.z - k.z*c.w)) / s,
417                                     (k.z*(i.x*c.w - i.w*c.x) + k.w*(i.z*c.x - i.x*c.z) + k.x*(i.w*c.z - i.z*c.w)) / s,
418                                     (c.z*(i.x*j.w - i.w*j.x) + c.w*(i.z*j.x - i.x*j.z) + c.x*(i.w*j.z - i.z*j.w)) / s,
419                                     (i.z*(j.w*k.x - j.x*k.w) + i.w*(j.x*k.z - j.z*k.x) + i.x*(j.z*k.w - j.w*k.z)) / s,
420                                     (j.w*(k.x*c.y - k.y*c.x) + j.x*(k.y*c.w - k.w*c.y) + j.y*(k.w*c.x - k.x*c.w)) / s,
421                                     (k.w*(i.x*c.y - i.y*c.x) + k.x*(i.y*c.w - i.w*c.y) + k.y*(i.w*c.x - i.x*c.w)) / s,
422                                     (c.w*(i.x*j.y - i.y*j.x) + c.x*(i.y*j.w - i.w*j.y) + c.y*(i.w*j.x - i.x*j.w)) / s,
423                                     (i.w*(j.y*k.x - j.x*k.y) + i.x*(j.w*k.y - j.y*k.w) + i.y*(j.x*k.w - j.w*k.x)) / s,
424                                     (j.x*(k.z*c.y - k.y*c.z) + j.y*(k.x*c.z - k.z*c.x) + j.z*(k.y*c.x - k.x*c.y)) / s,
425                                     (k.x*(i.z*c.y - i.y*c.z) + k.y*(i.x*c.z - i.z*c.x) + k.z*(i.y*c.x - i.x*c.y)) / s,
426                                     (c.x*(i.z*j.y - i.y*j.z) + c.y*(i.x*j.z - i.z*j.x) + c.z*(i.y*j.x - i.x*j.y)) / s,
427                                     (i.x*(j.y*k.z - j.z*k.y) + i.y*(j.z*k.x - j.x*k.z) + i.z*(j.x*k.y - j.y*k.x)) / s);
428             return inverted;
429         }
430
431         template<class T> inline Matrix4<T>& Matrix4<T>::transpose()
432         {
433             EffectsSwap(i.y, j.x);
434             EffectsSwap(i.z, k.x);
435             EffectsSwap(i.w, c.x);
436             EffectsSwap(j.z, k.y);
437             EffectsSwap(j.w, c.y);
438             EffectsSwap(k.w, c.z);
439             return *this;
440         }
441
442         template<class T> inline Matrix4<T> Matrix4<T>::getTransposed() const
443         {
444             Matrix4 transposed(i.x, j.x, k.x, c.x,
445                 i.y, j.y, k.y, c.y,
446                 i.z, j.z, k.z, c.z,
447                 i.w, j.w, k.w, c.w);
448
449             return transposed;
450         }
451
452         template<class T> inline Matrix4<T>& Matrix4<T>::operator+=(const Matrix4<T>& aRhv)
453         {
454             i += aRhv.i;
455             j += aRhv.j;
456             k += aRhv.k;
457             c += aRhv.c;
458             return *this;
459         }
460         template<class T> inline Matrix4<T>& Matrix4<T>::operator+=(const T& aRhv)
461         {
462             i += aRhv;
463             j += aRhv;
464             k += aRhv;
465             c += aRhv;
466             return *this;
467         }
468         template<class T> inline Matrix4<T>& Matrix4<T>::operator-=(const Matrix4<T>& aRhv)
469         {
470             i -= aRhv.i;
471             j -= aRhv.j;
472             k -= aRhv.k;
473             c -= aRhv.c;
474             return *this;
475         }
476         template<class T> inline Matrix4<T>& Matrix4<T>::operator-=(const T& aRhv)
477         {
478             i -= aRhv;
479             j -= aRhv;
480             k -= aRhv;
481             c -= aRhv;
482             return *this;
483         }
484         template<class T> inline Matrix4<T>& Matrix4<T>::operator*=(const T& aRhv)
485         {
486             i *= aRhv;
487             j *= aRhv;
488             k *= aRhv;
489             c *= aRhv;
490             return *this;
491         }
492
493         template<class T> inline Matrix4<T> Matrix4<T>::GetMultipliedByMember(const Matrix4<T>& aRhv) const
494         {
495             return Matrix4<T>(i * aRhv.i, j * aRhv.j, k * aRhv.k, c * aRhv.c);
496         }
497
498         template<class T> inline Matrix4<T>& Matrix4<T>::multiplyByMember(const Matrix4<T>& aRhv)
499         {
500             i *= aRhv.i;
501             j *= aRhv.j;
502             k *= aRhv.k;
503             c *= aRhv.c;
504             return *this;
505         }
506
507         template<class T> inline Matrix4<T> Matrix4<T>::createMultipliedByMember(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv)
508         {
509             return Matrix4<T>(aLhv.i * aRhv.i, aLhv.j * aRhv.j, aLhv.k * aRhv.k, aLhv.c * aRhv.c);
510         }
511
512         template<class T> inline Matrix4<T>& Matrix4<T>::operator*=(const Matrix4<T>& aRhv)
513         {
514             set(
515                 i.x * aRhv.i.x + i.y * aRhv.j.x + i.z * aRhv.k.x + i.w * aRhv.c.x,
516                 i.x * aRhv.i.y + i.y * aRhv.j.y + i.z * aRhv.k.y + i.w * aRhv.c.y,
517                 i.x * aRhv.i.z + i.y * aRhv.j.z + i.z * aRhv.k.z + i.w * aRhv.c.z,
518                 i.x * aRhv.i.w + i.y * aRhv.j.w + i.z * aRhv.k.w + i.w * aRhv.c.w,
519
520                 j.x * aRhv.i.x + j.y * aRhv.j.x + j.z * aRhv.k.x + j.w * aRhv.c.x,
521                 j.x * aRhv.i.y + j.y * aRhv.j.y + j.z * aRhv.k.y + j.w * aRhv.c.y,
522                 j.x * aRhv.i.z + j.y * aRhv.j.z + j.z * aRhv.k.z + j.w * aRhv.c.z,
523                 j.x * aRhv.i.w + j.y * aRhv.j.w + j.z * aRhv.k.w + j.w * aRhv.c.w,
524
525                 k.x * aRhv.i.x + k.y * aRhv.j.x + k.z * aRhv.k.x + k.w * aRhv.c.x,
526                 k.x * aRhv.i.y + k.y * aRhv.j.y + k.z * aRhv.k.y + k.w * aRhv.c.y,
527                 k.x * aRhv.i.z + k.y * aRhv.j.z + k.z * aRhv.k.z + k.w * aRhv.c.z,
528                 k.x * aRhv.i.w + k.y * aRhv.j.w + k.z * aRhv.k.w + k.w * aRhv.c.w,
529
530                 c.x * aRhv.i.x + c.y * aRhv.j.x + c.z * aRhv.k.x + c.w * aRhv.c.x,
531                 c.x * aRhv.i.y + c.y * aRhv.j.y + c.z * aRhv.k.y + c.w * aRhv.c.y,
532                 c.x * aRhv.i.z + c.y * aRhv.j.z + c.z * aRhv.k.z + c.w * aRhv.c.z,
533                 c.x * aRhv.i.w + c.y * aRhv.j.w + c.z * aRhv.k.w + c.w * aRhv.c.w);
534             return *this;
535         }
536
537         template<class T> inline Matrix4<T> Matrix4<T>::getDividedByMember(const Matrix4<T>& aRhv) const
538         {
539             return Matrix4<T>(i / aRhv.i, j / aRhv.j, k / aRhv.k, c / aRhv.c);
540         }
541
542         template<class T> inline Matrix4<T>& Matrix4<T>::divideByMember(const Matrix4<T>& aRhv)
543         {
544             i /= aRhv.i;
545             j /= aRhv.j;
546             k /= aRhv.k;
547             c /= aRhv.c;
548             return *this;
549         }
550         template<class T> inline Matrix4<T> Matrix4<T>::createDividedByMember(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv)
551         {
552             return Matrix4<T>(aLhv.i / aRhv.i, aLhv.j / aRhv.j, aLhv.k / aRhv.k, aLhv.c / aRhv.c);
553         }
554
555         template<class T> inline Matrix4<T>& Matrix4<T>::operator/=(const T& aRhv)
556         {
557             i /= aRhv;
558             j /= aRhv;
559             k /= aRhv;
560             c /= aRhv;
561             return *this;
562         }
563
564         template<class T> inline bool Matrix4<T>::isIdentity() const
565         {
566             return *this == getIdentity();
567         }
568
569         template<class T> inline T* Matrix4<T>::getPointer()
570         {
571             return i.getPointer();
572         }
573
574         template<class T> inline const T* Matrix4<T>::getPointer() const
575         {
576             return i.getPointer();
577         }
578
579         template<class T> inline T& Matrix4<T>::get(unsigned int aRow, unsigned int aColumn)
580         {
581             return operator()(aRow, aColumn);
582         }
583
584         template<class T> inline const T& Matrix4<T>::get(unsigned int aRow, unsigned int aColumn) const
585         {
586             return operator()(aRow, aColumn);
587         }
588
589         template<class T> inline T& Matrix4<T>::get(unsigned int aAbsIndex)
590         {
591             return operator()(aAbsIndex);
592         }
593
594         template<class T> inline const T& Matrix4<T>::get(unsigned int aAbsIndex) const
595         {
596             return operator()(aAbsIndex);
597         }
598
599         template<class T> inline Vector4<T>& Matrix4<T>::getRow(unsigned int aRow)
600         {
601             switch(aRow)
602             {
603             case 1:
604                 return j;
605             case 2:
606                 return k;
607             case 3:
608                 return c;
609             }
610             return i;
611         }
612
613         template<class T> inline const Vector4<T>& Matrix4<T>::getRow(unsigned int aRow) const
614         {
615             switch(aRow)
616             {
617             case 1:
618                 return j;
619             case 2:
620                 return k;
621             case 3:
622                 return c;
623             }
624             return i;
625         }
626
627         template<class T> inline Vector4<T> Matrix4<T>::getColumn(unsigned int aColumn) const
628         {
629             switch(aColumn)
630             {
631             case 1:
632                 return Vector4<T>(i.y, j.y, k.y, c.y);
633             case 2:
634                 return Vector4<T>(i.z, j.z, k.z, c.z);
635             case 3:
636                 return Vector4<T>(i.w, j.w, k.w, c.w);
637             }
638
639             return Vector4<T>(i.x, j.x, k.x, c.x);
640         }
641
642         template<class T> inline T& Matrix4<T>::operator()(unsigned int aRow, unsigned int aColumn)
643         {
644             return operator[]((aRow << 2) + aColumn);
645         }
646
647         template<class T> inline const T& Matrix4<T>::operator()(unsigned int aRow, unsigned int aColumn) const
648         {
649             return operator[]((aRow << 2) + aColumn);
650         }
651
652         template<class T> inline T& Matrix4<T>::operator()(unsigned int aAbsIndex)
653         {
654             return operator[](aAbsIndex);
655         }
656
657         template<class T> inline const T& Matrix4<T>::operator()(unsigned int aAbsIndex) const
658         {
659             return operator[](aAbsIndex);
660         }
661
662         template<class T> inline T& Matrix4<T>::operator[](unsigned int aAbsIndex)
663         {
664             return getPointer()[aAbsIndex];
665         }
666
667         template<class T> inline const T& Matrix4<T>::operator[](unsigned int aAbsIndex) const
668         {
669             return getPointer()[aAbsIndex];
670         }
671
672         template<class T> inline Matrix4<T>& Matrix4<T>::setColumn(unsigned int aColumn, const Vector4<T>& aValue)
673         {
674             switch(aColumn)
675             {
676             case 0:
677                 i.x = aValue.x;
678                 j.x = aValue.y;
679                 k.x = aValue.z;
680                 c.x = aValue.w;
681                 break;
682             case 1:
683                 i.y = aValue.x;
684                 j.y = aValue.y;
685                 k.y = aValue.z;
686                 c.y = aValue.w;
687                 break;
688             case 2:
689                 i.z = aValue.x;
690                 j.z = aValue.y;
691                 k.z = aValue.z;
692                 c.z = aValue.w;
693                 break;
694             case 3:
695                 i.w = aValue.x;
696                 j.w = aValue.y;
697                 k.w = aValue.z;
698                 c.w = aValue.w;
699                 break;
700             }
701
702             return *this;
703         }
704
705         template<class T> inline Matrix4<T>& Matrix4<T>::setRow(unsigned int aRow, const Vector4<T>& aValue)
706         {
707             switch(aRow)
708             {
709             case 0:
710                 i = aValue;
711                 break;
712             case 1:
713                 j = aValue;
714                 break;
715             case 2:
716                 k = aValue;
717                 break;
718             case 3:
719                 c = aValue;
720                 break;
721             }
722
723             return *this;
724         }
725
726         template<class T> inline Matrix4<T>& Matrix4<T>::set(unsigned int aRow, unsigned int aColumn, const T& aValue)
727         {
728             operator()(aRow, aColumn) = aValue;
729             return *this;
730         }
731
732         template<class T> inline Matrix4<T>& Matrix4<T>::set(unsigned int aAbsIndex, const T& aValue)
733         {
734             operator()(aAbsIndex) = aValue;
735             return *this;
736         }
737
738         template<class T> inline Matrix4<T>& Matrix4<T>::lerp(const Matrix4<T>& aTo, const T& aCoeff)
739         {
740             i.lerp(aTo.i, aCoeff);
741             j.lerp(aTo.j, aCoeff);
742             k.lerp(aTo.k, aCoeff);
743             c.lerp(aTo.c, aCoeff);
744             return *this;
745         }
746
747         template<class T> inline Matrix4<T> Matrix4<T>::getLerped(const Matrix4<T>& aTo, const T& aCoeff) const
748         {
749             Matrix4<T> result(i.getLerped(aTo.i, aCoeff),
750                               j.getLerped(aTo.j, aCoeff),
751                               k.getLerped(aTo.k, aCoeff),
752                               c.getLerped(aTo.c, aCoeff));
753             return result;
754         }
755
756         template<class T> inline Matrix4<T>& Matrix4<T>::makeLerped(const Matrix4<T>& aFrom, const Matrix4<T>& aTo, const T& aCoeff)
757         {
758             i.makeLerped(aFrom.i, aTo.i, aCoeff);
759             j.makeLerped(aFrom.j, aTo.j, aCoeff);
760             k.makeLerped(aFrom.k, aTo.k, aCoeff);
761             c.makeLerped(aFrom.c, aTo.c, aCoeff);
762             return *this;
763         }
764         template<class T> inline Matrix4<T> Matrix4<T>::createLerped(const Matrix4<T>& aFrom, const Matrix4<T>& aTo, const T& aCoeff)
765         {
766             return Matrix4<T>().makeLerped(aFrom, aTo, aCoeff);
767         }
768
769         template<class T> inline Matrix4<T>& Matrix4<T>::slerp(const Matrix4<T>& aTo, const T& aCoeff)
770         {
771             setRotation(getQuaternion().slerp(aTo.getQuaternion(), aCoeff));
772             c.lerp(aTo.c, aCoeff);
773             return *this;
774         }
775
776         template<class T> inline Matrix4<T> Matrix4<T>::getSlerped(const Matrix4<T>& aTo, const T& aCoeff) const
777         {
778             Matrix4 result;
779             result.makeRotation(getQuaternion().slerp(aTo.getQuaternion(), aCoeff));
780             result.c = c.getLerped(aTo.c, aCoeff);
781             return result;
782         }
783
784         template<class T> inline Matrix4<T>& Matrix4<T>::makeSlerped(const Matrix4<T>& aFrom, const Matrix4<T>& aTo, const T& aCoeff)
785         {
786             makeRotation(aFrom.getQuaternion().slerp(aTo.getQuaternion(), aCoeff));
787             c.makeLerped(aFrom.c, aTo.c, aCoeff);
788             return *this;
789         }
790
791         template<class T> inline Matrix4<T> Matrix4<T>::createSlerped(const Matrix4<T>& aFrom, const Matrix4<T>& aTo, const T& aCoeff)
792         {
793             return Matrix4<T>().makeSlerped(aFrom, aTo, aCoeff);
794         }
795
796         template<class T> inline T Matrix4<T>::determinant() const
797         {
798             return  (i.x * j.y - i.y * j.x) * (k.z * c.w - k.w * c.z)-
799                     (i.x * j.z - i.z * j.x) * (k.y * c.w - k.w * c.y)+
800                     (i.x * j.w - i.w * j.x) * (k.y * c.z - k.z * c.y)+
801                     (i.y * j.z - i.z * j.y) * (k.x * c.w - k.w * c.x)-
802                     (i.y * j.w - i.w * j.y) * (k.x * c.z - k.z * c.x)+
803                     (i.z * j.w - i.w * j.z) * (k.x * c.y - k.y * c.x);
804         }
805
806         template<class T> inline Vector4<T>& Matrix4<T>::applyTransform(Vector4<T>& aVector) const
807         {
808             return aVector.set(
809                                 aVector.x * i.x + aVector.y * j.x + aVector.z * k.x + aVector.w * c.x,
810                                 aVector.x * i.y + aVector.y * j.y + aVector.z * k.y + aVector.w * c.y,
811                                 aVector.x * i.z + aVector.y * j.z + aVector.z * k.z + aVector.w * c.z,
812                                 aVector.x * i.w + aVector.y * j.w + aVector.z * k.w + aVector.w * c.w);
813         }
814
815         template<class T> inline Vector4<T> Matrix4<T>::getAppliedTransform(const Vector4<T>& aVector) const
816         {
817             return Vector4<T>(
818                                 aVector.x * i.x + aVector.y * j.x + aVector.z * k.x + aVector.w * c.x,
819                                 aVector.x * i.y + aVector.y * j.y + aVector.z * k.y + aVector.w * c.y,
820                                 aVector.x * i.z + aVector.y * j.z + aVector.z * k.z + aVector.w * c.z,
821                                 aVector.x * i.w + aVector.y * j.w + aVector.z * k.w + aVector.w * c.w);
822         }
823
824         template<class T> inline Vector4<T>& Matrix4<T>::applyRotation(Vector4<T>& aVector) const
825         {
826             return aVector.set(
827                                 aVector.x * i.x + aVector.y * j.x + aVector.z * k.x,
828                                 aVector.x * i.y + aVector.y * j.y + aVector.z * k.y,
829                                 aVector.x * i.z + aVector.y * j.z + aVector.z * k.z,
830                                 aVector.w);
831         }
832
833         template<class T> inline Vector4<T> Matrix4<T>::getAppliedRotation(const Vector4<T>& aVector) const
834         {
835             return Vector4<T>(
836                                 aVector.x * i.x + aVector.y * j.x + aVector.z * k.x,
837                                 aVector.x * i.y + aVector.y * j.y + aVector.z * k.y,
838                                 aVector.x * i.z + aVector.y * j.z + aVector.z * k.z,
839                                 aVector.w);
840         }
841
842         template<class T> inline Vector4<T>& Matrix4<T>::applyTranslate(Vector4<T>& aVector) const
843         {
844             return aVector.set(
845                                 aVector.x + aVector.w * c.x,
846                                 aVector.y + aVector.w * c.y,
847                                 aVector.z + aVector.w * c.z,
848                                 aVector.w);
849         }
850
851         template<class T> inline Vector4<T> Matrix4<T>::getAppliedTranslate(const Vector4<T>& aVector) const
852         {
853             return Vector4<T>(
854                                 aVector.x + aVector.w * c.x,
855                                 aVector.y + aVector.w * c.y,
856                                 aVector.z + aVector.w * c.z,
857                                 aVector.w);
858         }
859
860         template<class T> inline _Vector3<T>& Matrix4<T>::applyTransform(_Vector3<T>& aVector) const
861         {
862             return aVector.set(
863                                 aVector.x * i.x + aVector.y * j.x + aVector.z * k.x + c.x,
864                                 aVector.x * i.y + aVector.y * j.y + aVector.z * k.y + c.y,
865                                 aVector.x * i.z + aVector.y * j.z + aVector.z * k.z + c.z);
866         }
867
868         template<class T> inline _Vector3<T> Matrix4<T>::getAppliedTransform(const _Vector3<T>& aVector) const
869         {
870             return _Vector3<T>(
871                                 aVector.x * i.x + aVector.y * j.x + aVector.z * k.x + c.x,
872                                 aVector.x * i.y + aVector.y * j.y + aVector.z * k.y + c.y,
873                                 aVector.x * i.z + aVector.y * j.z + aVector.z * k.z + c.z);
874         }
875
876         template<class T> inline _Vector3<T>& Matrix4<T>::applyRotation(_Vector3<T>& aVector) const
877         {
878             return aVector.set(
879                                 aVector.x * i.x + aVector.y * j.x + aVector.z * k.x,
880                                 aVector.x * i.y + aVector.y * j.y + aVector.z * k.y,
881                                 aVector.x * i.z + aVector.y * j.z + aVector.z * k.z);
882         }
883
884         template<class T> inline _Vector3<T> Matrix4<T>::getAppliedRotation(const _Vector3<T>& aVector) const
885         {
886             return _Vector3<T>(
887                                 aVector.x * i.x + aVector.y * j.x + aVector.z * k.x,
888                                 aVector.x * i.y + aVector.y * j.y + aVector.z * k.y,
889                                 aVector.x * i.z + aVector.y * j.z + aVector.z * k.z);
890         }
891
892         template<class T> inline _Vector3<T>& Matrix4<T>::applyTranslate(_Vector3<T>& aVector) const
893         {
894             return aVector.set(
895                                 aVector.x + c.x,
896                                 aVector.y + c.y,
897                                 aVector.z + c.z);
898         }
899
900         template<class T> inline _Vector3<T> Matrix4<T>::getAppliedTranslate(const _Vector3<T>& aVector) const
901         {
902             return _Vector3<T>(
903                                 aVector.x + c.x,
904                                 aVector.y + c.y,
905                                 aVector.z + c.z);
906         }
907
908         template<class T> inline Quaternion<T>& Matrix4<T>::applyRotation(Quaternion<T>& aQuaternion) const
909         {
910
911             return aQuaternion.set(getQuaternion() * aQuaternion);
912         }
913
914         template<class T> inline Quaternion<T> Matrix4<T>::getAppliedRotation(const Quaternion<T>& aQuaternion) const
915         {
916             return getQuaternion() * aQuaternion;
917         }
918
919         template<class T> inline Matrix4<T>& Matrix4<T>::setRotation(const T& aXAngleRAD, const T& aYAngleRAD, const T& aZAngleRAD, RotationOrder3 aOrder)
920         {
921             Matrix4<T> result;
922             result.makeRotation(aXAngleRAD, aYAngleRAD, aZAngleRAD, aOrder);
923
924             i.x = result.i.x; i.y = result.i.y; i.z = result.i.z;
925             j.x = result.j.x; j.y = result.j.y; j.z = result.j.z;
926             k.x = result.k.x; k.y = result.k.y; k.z = result.k.z;
927             return *this;
928         }
929
930         template<class T> inline Matrix4<T>& Matrix4<T>::setRotation(const _Vector3<T>& aAnglesRAD, RotationOrder3 aOrder)
931         {
932             return setRotation(aAnglesRAD.x, aAnglesRAD.y, aAnglesRAD.z, aOrder);
933         }
934
935         template<class T> inline Matrix4<T>& Matrix4<T>::setRotationX(const T& aAngleRAD)
936         {
937                 const T c = effects_cos(aAngleRAD);
938                     const T s = effects_sin(aAngleRAD);
939             i.x = T(1.0f);
940             i.y = i.z = j.x = k.x = T(0.0f);
941                     j.y = c;
942             j.z = s;
943                     k.y = -s;
944             k.z = c;
945             return *this;
946         }
947
948         template<class T> inline Matrix4<T>& Matrix4<T>::setRotationY(const T& aAngleRAD)
949         {
950                 const T c = effects_cos(aAngleRAD);
951                     const T s = effects_sin(aAngleRAD);
952             j.y = T(1.0f);
953             i.y = j.x = j.z = k.y = T(0.0f);
954                     i.x = c;
955             i.z = -s;
956                     k.x = s;
957             k.z = c;
958             return *this;
959         }
960
961         template<class T> inline Matrix4<T>& Matrix4<T>::setRotationZ(const T& aAngleRAD)
962         {
963                     const T c = effects_cos(aAngleRAD);
964                     const T s = effects_sin(aAngleRAD);
965             k.z = T(1.0f);
966             i.z = j.z = k.x = k.y = T(0.0f);
967                     i.x = c;
968             i.y = s;
969                     j.x = -s;
970             j.y = c;
971             return *this;
972         }
973
974         template<class T> inline Matrix4<T>& Matrix4<T>::setRotationAxis(const _Vector3<T>& aAxis, const T& aAngleRAD)
975         {
976             return setRotationAxis(aAxis.x, aAxis.y, aAxis.z, aAngleRAD);
977         }
978
979         template<class T> inline Matrix4<T>& Matrix4<T>::setRotationAxis(const T& aXAxis, const T& aYAxis, const T& aZAxis, const T& aAngleRAD)
980         {
981             Matrix4<T> result;
982             result.makeRotationAxis(aXAxis, aYAxis, aZAxis, aAngleRAD);
983
984             i.x = result.i.x; i.y = result.i.y; i.z = result.i.z;
985             j.x = result.j.x; j.y = result.j.y; j.z = result.j.z;
986             k.x = result.k.x; k.y = result.k.y; k.z = result.k.z;
987             return *this;
988         }
989
990         template<class T> inline Matrix4<T>& Matrix4<T>::setRotation(const Quaternion<T>& aRotation)
991         {
992             T wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
993             T s  = T(2.0f) / aRotation.lengthSqr();  // 4 mul 3 add 1 div
994             x2 = aRotation.x * s;    y2 = aRotation.y * s;    z2 = aRotation.z * s;
995             xx = aRotation.x * x2;   xy = aRotation.x * y2;   xz = aRotation.x * z2;
996             yy = aRotation.y * y2;   yz = aRotation.y * z2;   zz = aRotation.z * z2;
997             wx = aRotation.w * x2;   wy = aRotation.w * y2;   wz = aRotation.w * z2;
998
999             const T t1(1.0f);
1000             i.x = t1 - (yy + zz);
1001             j.x = xy - wz;
1002             k.x = xz + wy;
1003
1004             i.y = xy + wz;
1005             j.y = t1 - (xx + zz);
1006             k.y = yz - wx;
1007
1008             i.z = xz - wy;
1009             j.z = yz + wx;
1010             k.z = t1 - (xx + yy);
1011             return *this;
1012         }
1013
1014         template<class T> inline Matrix4<T>& Matrix4<T>::setRotation(const Matrix3<T>& aRotation)
1015         {
1016             i.x = aRotation.i.x; i.y = aRotation.i.y; i.z = aRotation.i.z;
1017             j.x = aRotation.j.x; j.y = aRotation.j.y; j.z = aRotation.j.z;
1018             k.x = aRotation.k.x; k.y = aRotation.k.y; k.z = aRotation.k.z;
1019             return *this;
1020         }
1021
1022         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotation(const T& aXAngleRAD, const T& aYAngleRAD, const T& aZAngleRAD, RotationOrder3 aOrder)
1023         {
1024             switch(aOrder)
1025             {
1026             case ROTATION_XYZ:
1027                 makeRotationX(aXAngleRAD);
1028                 rotateY(aYAngleRAD);
1029                 rotateZ(aZAngleRAD);
1030                 break;
1031             case ROTATION_XZY:
1032                 makeRotationX(aXAngleRAD);
1033                 rotateZ(aZAngleRAD);
1034                 rotateY(aYAngleRAD);
1035                 break;
1036             case ROTATION_YXZ:
1037                 makeRotationY(aYAngleRAD);
1038                 rotateX(aXAngleRAD);
1039                 rotateZ(aZAngleRAD);
1040                 break;
1041             case ROTATION_YZX:
1042                 makeRotationY(aYAngleRAD);
1043                 rotateZ(aZAngleRAD);
1044                 rotateX(aXAngleRAD);
1045                 break;
1046             case ROTATION_ZXY:
1047                 makeRotationZ(aZAngleRAD);
1048                 rotateX(aXAngleRAD);
1049                 rotateY(aYAngleRAD);
1050                 break;
1051             case ROTATION_ZYX:
1052                 makeRotationZ(aZAngleRAD);
1053                 rotateY(aYAngleRAD);
1054                 rotateX(aXAngleRAD);
1055                 break;
1056             default:
1057                 break;
1058             }
1059             return *this;
1060         }
1061
1062         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotation(const _Vector3<T>& aAnglesRAD, RotationOrder3 aOrder)
1063         {
1064             return makeRotation(aAnglesRAD.x, aAnglesRAD.y, aAnglesRAD.z, aOrder);
1065         }
1066
1067         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotationX(const T& aAngleRAD)
1068         {
1069             identity();
1070                 const T c = effects_cos(aAngleRAD);
1071                     const T s = effects_sin(aAngleRAD);
1072                     j.y = c;
1073             j.z = s;
1074                     k.y = -s;
1075             k.z = c;
1076             return *this;
1077         }
1078
1079         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotationY(const T& aAngleRAD)
1080         {
1081                     identity();
1082                 const T c = effects_cos(aAngleRAD);
1083                     const T s = effects_sin(aAngleRAD);
1084                     i.x = c;
1085             i.z = -s;
1086                     k.x = s;
1087             k.z = c;
1088             return *this;
1089         }
1090
1091         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotationZ(const T& aAngleRAD)
1092         {
1093                     identity();
1094                     const T c = effects_cos(aAngleRAD);
1095                     const T s = effects_sin(aAngleRAD);
1096                     i.x = c;
1097             i.y = s;
1098                     j.x = -s;
1099             j.y = c;
1100             return *this;
1101         }
1102
1103         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotationAxis(const _Vector3<T>& aAxis, const T& aAngleRAD)
1104         {
1105             return makeRotationAxis(aAxis.x, aAxis.y, aAxis.z, aAngleRAD);
1106         }
1107
1108         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotationAxis(const T& aXAxis, const T& aYAxis, const T& aZAxis, const T& aAngleRAD)
1109         {
1110             static const T t1(1.0f);
1111
1112                 _Vector3<T> v(aXAxis, aYAxis, aZAxis);
1113             v.normalize();
1114                 const T sa = effects_sin(aAngleRAD);
1115             const T ca = effects_cos(aAngleRAD);
1116             const T inv_ca = t1 - ca;
1117
1118
1119                 identity();
1120
1121                 i.x = ca + inv_ca * v.x * v.x;
1122                 i.y = inv_ca * v.x * v.y - sa * v.z;
1123                 i.z = inv_ca * v.z * v.x + sa * v.y;
1124                 j.x = inv_ca * v.x * v.y + sa * v.z;
1125                 j.y = ca + inv_ca * v.y * v.y;
1126                 j.z = inv_ca * v.y * v.z - sa * v.x;
1127                 k.x = inv_ca * v.z * v.x - sa * v.y;
1128                 k.y = inv_ca * v.y * v.z + sa * v.x;
1129                 k.z = ca + inv_ca * v.z * v.z;
1130
1131             return *this;
1132         }
1133
1134         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotation(const Quaternion<T>& aRotation)
1135         {
1136             identity();
1137             return setRotation(aRotation);
1138         }
1139
1140         template<class T> inline Matrix4<T>& Matrix4<T>::makeRotation(const Matrix3<T>& aRotation)
1141         {
1142             identity();
1143             return setRotation(aRotation);
1144         }
1145
1146         template<class T> inline Matrix4<T> Matrix4<T>::createRotation(const T& aXAngleRAD, const T& aYAngleRAD, const T& aZAngleRAD, RotationOrder3 aOrder)
1147         {
1148             return Matrix4<T>().makeRotation(aXAngleRAD, aYAngleRAD, aZAngleRAD, aOrder);
1149         }
1150
1151         template<class T> inline Matrix4<T> Matrix4<T>::createRotation(const _Vector3<T>& aAnglesRAD, RotationOrder3 aOrder)
1152         {
1153             return Matrix4<T>().makeRotation(aAnglesRAD, aOrder);
1154         }
1155
1156         template<class T> inline Matrix4<T> Matrix4<T>::createRotationX(const T& aAngleRAD)
1157         {
1158             return Matrix4<T>().makeRotationX(aAngleRAD);
1159         }
1160
1161         template<class T> inline Matrix4<T> Matrix4<T>::createRotationY(const T& aAngleRAD)
1162         {
1163             return Matrix4<T>().makeRotationY(aAngleRAD);
1164         }
1165
1166         template<class T> inline Matrix4<T> Matrix4<T>::createRotationZ(const T& aAngleRAD)
1167         {
1168             return Matrix4<T>().makeRotationZ(aAngleRAD);
1169         }
1170
1171         template<class T> inline Matrix4<T> Matrix4<T>::createRotationAxis(const _Vector3<T>& aAxis, const T& aAngleRAD)
1172         {
1173             return Matrix4<T>().makeRotationAxis(aAxis, aAngleRAD);
1174         }
1175
1176         template<class T> inline Matrix4<T> Matrix4<T>::createRotationAxis(const T& aXAxis, const T& aYAxis, const T& aZAxis, const T& aAngleRAD)
1177         {
1178             return Matrix4<T>().makeRotationAxis(aXAxis, aYAxis, aZAxis, aAngleRAD);
1179         }
1180
1181         template<class T> inline Matrix4<T> Matrix4<T>::createRotation(const Quaternion<T>& aRotation)
1182         {
1183             return Matrix4<T>().makeRotation(aRotation);
1184         }
1185
1186         template<class T> inline Matrix4<T> Matrix4<T>::createRotation(const Matrix3<T>& aRotation)
1187         {
1188             return Matrix4<T>().makeRotation(aRotation);
1189         }
1190
1191         template<class T> inline Matrix4<T>& Matrix4<T>::rotate(const T& aXAngleRAD, const T& aYAngleRAD, const T& aZAngleRAD, RotationOrder3 aOrder)
1192         {
1193             return rotate(Matrix4<T>().makeRotation(aXAngleRAD, aYAngleRAD, aZAngleRAD, aOrder));
1194         }
1195         template<class T> inline Matrix4<T>& Matrix4<T>::rotate(const _Vector3<T>& aAnglesRAD, RotationOrder3 aOrder3)
1196         {
1197             return rotate(Matrix4<T>().makeRotation(aAnglesRAD, aOrder3));
1198         }
1199         template<class T> inline Matrix4<T>& Matrix4<T>::rotateX(const T& aAngleRAD)
1200         {
1201             return rotate(Matrix4<T>().makeRotationX(aAngleRAD));
1202         }
1203         template<class T> inline Matrix4<T>& Matrix4<T>::rotateY(const T& aAngleRAD)
1204         {
1205             return rotate(Matrix4<T>().makeRotationY(aAngleRAD));
1206         }
1207         template<class T> inline Matrix4<T>& Matrix4<T>::rotateZ(const T& aAngleRAD)
1208         {
1209             return rotate(Matrix4<T>().makeRotationZ(aAngleRAD));
1210         }
1211         template<class T> inline Matrix4<T>& Matrix4<T>::rotateAxis(const _Vector3<T>& aAxis, const T& aAngleRAD)
1212         {
1213             return rotate(Matrix4<T>().makeRotationAxis(aAxis, aAngleRAD));
1214         }
1215         template<class T> inline Matrix4<T>& Matrix4<T>::rotateAxis(const T& aXAxis, const T& aYAxis, const T& aZAxis, const T& aAngleRAD)
1216         {
1217             return rotate(Matrix4<T>().makeRotationAxis(aXAxis, aYAxis, aZAxis, aAngleRAD));
1218         }
1219         template<class T> inline Matrix4<T>& Matrix4<T>::rotate(const Quaternion<T>& aRotation)
1220         {
1221             return rotate(Matrix4<T>().makeRotation(aRotation));
1222         }
1223         template<class T> inline Matrix4<T>& Matrix4<T>::rotate(const Matrix3<T>& aRotation)
1224         {
1225                         const T _11 = i.x * aRotation.i.x + i.y * aRotation.j.x + i.z * aRotation.k.x;
1226                         const T _12 = i.x * aRotation.i.y + i.y * aRotation.j.y + i.z * aRotation.k.y;
1227                         const T _13 = i.x * aRotation.i.z + i.y * aRotation.j.z + i.z * aRotation.k.z;
1228
1229                         const T _21 = j.x * aRotation.i.x + j.y * aRotation.j.x + j.z * aRotation.k.x;
1230                         const T _22 = j.x * aRotation.i.y + j.y * aRotation.j.y + j.z * aRotation.k.y;
1231                         const T _23 = j.x * aRotation.i.z + j.y * aRotation.j.z + j.z * aRotation.k.z;
1232
1233                         const T _31 = k.x * aRotation.i.x + k.y * aRotation.j.x + k.z * aRotation.k.x;
1234                         const T _32 = k.x * aRotation.i.y + k.y * aRotation.j.y + k.z * aRotation.k.y;
1235                         const T _33 = k.x * aRotation.i.z + k.y * aRotation.j.z + k.z * aRotation.k.z;
1236
1237             i.x = _11; i.y = _12; i.z = _13;
1238             j.x = _21; j.y = _22; j.z = _23;
1239             k.x = _31; k.y = _32; k.z = _33;
1240
1241             return *this;
1242         }
1243         template<class T> inline Matrix4<T>& Matrix4<T>::rotate(const Matrix4<T>& aRotation)
1244         {
1245                         const T _11 = i.x * aRotation.i.x + i.y * aRotation.j.x + i.z * aRotation.k.x;
1246                         const T _12 = i.x * aRotation.i.y + i.y * aRotation.j.y + i.z * aRotation.k.y;
1247                         const T _13 = i.x * aRotation.i.z + i.y * aRotation.j.z + i.z * aRotation.k.z;
1248
1249                         const T _21 = j.x * aRotation.i.x + j.y * aRotation.j.x + j.z * aRotation.k.x;
1250                         const T _22 = j.x * aRotation.i.y + j.y * aRotation.j.y + j.z * aRotation.k.y;
1251                         const T _23 = j.x * aRotation.i.z + j.y * aRotation.j.z + j.z * aRotation.k.z;
1252
1253                         const T _31 = k.x * aRotation.i.x + k.y * aRotation.j.x + k.z * aRotation.k.x;
1254                         const T _32 = k.x * aRotation.i.y + k.y * aRotation.j.y + k.z * aRotation.k.y;
1255                         const T _33 = k.x * aRotation.i.z + k.y * aRotation.j.z + k.z * aRotation.k.z;
1256
1257             i.x = _11; i.y = _12; i.z = _13;
1258             j.x = _21; j.y = _22; j.z = _23;
1259             k.x = _31; k.y = _32; k.z = _33;
1260
1261             return *this;
1262         }
1263         template<class T> inline const Matrix4<T>& Matrix4<T>::getRotationAngles(T& aXAngleRAD, T& aYAngeRAD, T& aZAngleRAD, unsigned int aSolutionNumber) const
1264         {
1265             static const T t0(0.0f);
1266             static const T t2(2.0f);
1267             static const T pi(fPI);
1268
1269             T& yaw = aZAngleRAD;
1270             T& pitch = aYAngeRAD;
1271             T& roll = aXAngleRAD;
1272
1273             struct Euler
1274             {
1275                 T yaw;
1276                 T pitch;
1277                 T roll;
1278             };
1279
1280             Euler euler_out;
1281             Euler euler_out2; //second solution
1282
1283             // Check that pitch is not at a singularity
1284             if(EffectsAbs(k.x) >= T(1.0f))
1285             {
1286                 euler_out.yaw = t0;
1287                 euler_out2.yaw = t0;
1288
1289                 // From difference of angles formula
1290                 T delta = effects_atan2(i.x, i.z);
1291                 if (k.x > 0)  //gimbal locked up
1292                 {
1293                     euler_out.pitch = pi / t2;
1294                     euler_out2.pitch = pi / t2;
1295                     euler_out.roll = euler_out.pitch + delta;
1296                     euler_out2.roll = euler_out.pitch + delta;
1297                 }
1298                 else // gimbal locked down
1299                 {
1300                     euler_out.pitch = -pi / t2;
1301                     euler_out2.pitch = -pi / t2;
1302                     euler_out.roll = -euler_out.pitch + delta;
1303                     euler_out2.roll = -euler_out.pitch + delta;
1304                 }
1305             }
1306             else
1307             {
1308                 euler_out.pitch = - effects_asin(k.x);
1309                 euler_out2.pitch = pi - euler_out.pitch;
1310
1311                 euler_out.roll = effects_atan2(k.y / effects_cos(euler_out.pitch), k.z / effects_cos(euler_out.pitch));
1312
1313                 euler_out2.roll = effects_atan2(k.y / effects_cos(euler_out2.pitch), k.z / effects_cos(euler_out2.pitch));
1314
1315                 euler_out.yaw = effects_atan2(j.x / effects_cos(euler_out.pitch), i.x / effects_cos(euler_out.pitch));
1316
1317                 euler_out2.yaw = effects_atan2(j.x / effects_cos(euler_out2.pitch), i.x / effects_cos(euler_out2.pitch));
1318             }
1319
1320             if (aSolutionNumber == 1)
1321             {
1322                 yaw = euler_out.yaw;
1323                 pitch = euler_out.pitch;
1324                 roll = euler_out.roll;
1325             }
1326             else
1327             {
1328                 yaw = euler_out2.yaw;
1329                 pitch = euler_out2.pitch;
1330                 roll = euler_out2.roll;
1331             }
1332             return *this;
1333         }
1334         template<class T> inline Quaternion<T>& Matrix4<T>::getQuaternion(Quaternion<T>& aRotation) const
1335         {
1336             static const T t0(0.0f);
1337             static const T thalf(0.5f);
1338             static const T t1(1.0f);
1339
1340             Quaternion<T>& result = aRotation;
1341
1342             T tr = i.x + j.y + k.z; // trace of martix
1343             if(tr > t0)
1344             {     // if trace positive than "w" is biggest component
1345                 result.set(j.z - k.y, k.x - i.z, i.y - j.x, tr + t1);
1346                 result *= (T(0.5f) / effects_sqrt(result.w));     // "w" contain the "norm * 4"
1347
1348             }
1349             else                 // Some of vector components is bigger
1350             {
1351                 if((i.x > j.y) && (i.x > k.z))
1352                 {
1353                     result.set(t1 + i.x - j.y - k.z, j.x + i.y, k.x + i.z, j.z - k.y);
1354                     result *= (thalf / effects_sqrt(result.x));
1355
1356                 }
1357                 else
1358                 {
1359                     if(j.y > k.z)
1360                     {
1361                         result.set(j.x + i.y, t1 + j.y - i.x - k.z, k.y + j.z, k.x - i.z);
1362                         result *= (thalf / effects_sqrt(result.x));
1363
1364                     }
1365                     else
1366                     {
1367                         result.set(k.x + i.z, k.y + j.z, t1 + k.z - i.x - j.y, i.y - j.x);
1368                         result *= (thalf / effects_sqrt(result.z));
1369
1370                     }
1371                 }
1372             }
1373             return result.normalize();
1374         }
1375         template<class T> inline Quaternion<T> Matrix4<T>::getQuaternion() const
1376         {
1377             Quaternion<T> result;
1378             return getQuaternion(result);
1379         }
1380         template<class T> inline Matrix3<T> Matrix4<T>::getRotation() const
1381         {
1382             return Matrix3<T>(i.x, i.y, i.z,
1383                               j.x, j.y, j.z,
1384                               k.x, k.y, k.z);
1385         }
1386
1387         template<class T> inline Matrix4<T>& Matrix4<T>::makeScale(const T& aX, const T& aY, const T& aZ)
1388         {
1389             identity();
1390             return setScale(aX, aY, aZ);
1391         }
1392         template<class T> inline Matrix4<T>& Matrix4<T>::makeScale(const _Vector3<T>& aScale)
1393         {
1394             return makeScale(aScale.x, aScale.y, aScale.z);
1395         }
1396         template<class T> inline Matrix4<T> Matrix4<T>::createScale(const T& aX, const T& aY, const T& aZ)
1397         {
1398             return Matrix4<T>().makeScale(aX, aY, aZ);
1399         }
1400         template<class T> inline Matrix4<T> Matrix4<T>::createScale(const _Vector3<T>& aScale)
1401         {
1402             return Matrix4<T>().makeScale(aScale);
1403         }
1404         template<class T> inline Matrix4<T>& Matrix4<T>::setScale(const T& aX, const T& aY, const T& aZ)
1405         {
1406             i.x = aX;
1407             j.y = aY;
1408             k.z = aZ;
1409
1410             i.y = i.z = j.x = j.z = k.x = k.y = T(0.0f);
1411             return *this;
1412         }
1413         template<class T> inline Matrix4<T>& Matrix4<T>::setScale(const _Vector3<T>& aScale)
1414         {
1415             return setScale(aScale.x, aScale.y, aScale.z);
1416         }
1417         template<class T> inline Matrix4<T>& Matrix4<T>::scale(const T& aX, const T& aY, const T& aZ)
1418         {
1419             i.x *= aX; i.y *= aY; i.z *= aZ;
1420             j.x *= aX; j.y *= aY; j.z *= aZ;
1421             k.x *= aX; k.y *= aY; k.z *= aZ;
1422
1423             return *this;
1424         }
1425         template<class T> inline Matrix4<T>& Matrix4<T>::scale(const _Vector3<T>& aScale)
1426         {
1427             return scale(aScale.x, aScale.y, aScale.z);
1428         }
1429
1430         template<class T> inline Matrix4<T>& Matrix4<T>::setTranslation(const T& aX, const T& aY, const T& aZ)
1431         {
1432             c.x = aX;
1433             c.y = aY;
1434             c.z = aZ;
1435             return *this;
1436         }
1437         template<class T> inline Matrix4<T>& Matrix4<T>::setTranslation(const _Vector3<T>& aTran)
1438         {
1439             return setTranslation(aTran.x, aTran.y, aTran.z);
1440         }
1441         template<class T> inline Matrix4<T>& Matrix4<T>::makeTranslation(const T& aX, const T& aY, const T& aZ)
1442         {
1443             identity();
1444             return setTranslation(aX, aY, aZ);
1445         }
1446         template<class T> inline Matrix4<T>& Matrix4<T>::makeTranslation(const _Vector3<T>& aTran)
1447         {
1448             return makeTranslation(aTran.x, aTran.y, aTran.z);
1449         }
1450         template<class T> inline Matrix4<T> Matrix4<T>::createTranslation(const T& aX, const T& aY, const T& aZ)
1451         {
1452             return Matrix4<T>().makeTranslation(aX, aY, aZ);
1453         }
1454         template<class T> inline Matrix4<T> Matrix4<T>::createTranslation(const _Vector3<T>& aTran)
1455         {
1456             return Matrix4<T>().makeTranslation(aTran);
1457         }
1458         template<class T> inline Matrix4<T>& Matrix4<T>::translate(const T& aX, const T& aY, const T& aZ)
1459         {
1460             c.x += aX;
1461             c.y += aY;
1462             c.z += aZ;
1463             return *this;
1464         }
1465         template<class T> inline Matrix4<T>& Matrix4<T>::translate(const _Vector3<T>& aTran)
1466         {
1467             return translate(aTran.x, aTran.y, aTran.z);
1468         }
1469         template<class T> inline _Vector3<T> Matrix4<T>::getTranslation() const
1470         {
1471             return c.swizzle(0, 1, 2);
1472         }
1473         template<class T> inline Vector4<T> Matrix4<T>::getFullTranslation() const
1474         {
1475             return c;
1476         }
1477
1478         template<class T> inline Matrix4<T>& Matrix4<T>::makeLookAtLH(const _Vector3<T>& aEye, const _Vector3<T>& aAt, const _Vector3<T>& aUp)
1479         {
1480             static const T t0(0.0f);
1481             static const T t1(1.0f);
1482
1483             _Vector3<T> z((aAt - aEye).normalize());
1484             _Vector3<T> x; x.makeCrossed(aUp, z).normalize();
1485             _Vector3<T> y; y.makeCrossed(z, x);
1486
1487             i.x = x.x; i.y = y.x; i.z = z.x; i.w = t0;
1488             j.x = x.y; j.y = y.y; j.z = z.y; j.w = t0;
1489             k.x = x.z; k.y = y.z; k.z = z.z; k.w = t0;
1490             c.x = -x.dot(aEye);
1491             c.y = -y.dot(aEye);
1492             c.z = -z.dot(aEye);
1493             c.w = t1;
1494             return *this;
1495         }
1496         template<class T> inline Matrix4<T>& Matrix4<T>::makeLookAtRH(const _Vector3<T>& aEye, const _Vector3<T>& aAt, const _Vector3<T>& aUp)
1497         {
1498             static const T t0(0.0f);
1499             static const T t1(1.0f);
1500
1501             _Vector3<T> z((aEye - aAt).normalize());
1502             _Vector3<T> x; x.makeCrossed(aUp, z).normalize();
1503             _Vector3<T> y; y.makeCrossed(z, x);
1504
1505             i.x = x.x; i.y = y.x; i.z = z.x; i.w = t0;
1506             j.x = x.y; j.y = y.y; j.z = z.y; j.w = t0;
1507             k.x = x.z; k.y = y.z; k.z = z.z; k.w = t0;
1508             c.x = -x.dot(aEye);
1509             c.y = -y.dot(aEye);
1510             c.z = -z.dot(aEye);
1511             c.w = t1;
1512             return *this;
1513         }
1514         template<class T> inline Matrix4<T>& Matrix4<T>::makeOrthoRH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar)
1515         {
1516             static const T t2(2.0f);
1517
1518             identity();
1519             i.x = t2 / aWidth;
1520             j.y = t2 / aHeight;
1521             k.z = t2 / (aZNear - aZFar);
1522             c.z = (aZFar + aZNear) / (aZNear - aZFar);
1523             return *this;
1524         }
1525         template<class T> inline Matrix4<T>& Matrix4<T>::makeOrthoLH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar)
1526         {
1527             makeOrthoRH(aWidth, aHeight, aZNear, aZFar);
1528             k.z = -k.z;
1529             return *this;
1530         }
1531         template<class T> inline Matrix4<T>& Matrix4<T>::makeOrthoRH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar)
1532         {
1533             static const T t2(2.0f);
1534
1535             identity();
1536
1537             i.x = t2 / (aRight - aLeft);
1538             j.y = t2 / (aTop - aBottom);
1539             k.z = t2 / (aZNear - aZFar);
1540
1541             c.x = (aLeft + aRight) / (aLeft - aRight);
1542             c.y = (aTop + aBottom) / (aBottom - aTop);
1543             c.z = (aZFar + aZNear) / (aZNear - aZFar);
1544
1545             return *this;
1546         }
1547         template<class T> inline Matrix4<T>& Matrix4<T>::makeOrthoLH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar)
1548         {
1549             makeOrthoRH(aLeft, aRight, aTop, aBottom, aZNear, aZFar);
1550             k.z = -k.z;
1551             return *this;
1552         }
1553         template<class T> inline Matrix4<T>& Matrix4<T>::makePerspectiveLH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar)
1554         {
1555             makePerspectiveRH(aLeft, aRight, aTop, aBottom, aZNear, aZFar);
1556             k.z = -k.z;
1557             return *this;
1558         }
1559         template<class T> inline Matrix4<T>& Matrix4<T>::makePerspectiveRH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar)
1560         {
1561             static const T t0(0.0f);
1562             static const T t1(1.0f);
1563             static const T t2(2.0f);
1564
1565             identity();
1566             i.x = t2 * aZNear / (aRight - aLeft);
1567             j.y = t2 * aZNear / (aTop - aBottom);
1568             k.z = (aZFar + aZNear) / (aZNear - aZFar);
1569             c.w = t0;
1570
1571             k.w = -t1;
1572             k.x = (aLeft + aRight) / (aRight - aLeft);
1573             k.y = (aTop + aBottom) / (aTop - aBottom);
1574             c.z = t2 * aZNear * aZFar / (aZNear - aZFar);
1575
1576             return *this;
1577         }
1578         template<class T> inline Matrix4<T>& Matrix4<T>::makePerspectiveLH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar)
1579         {
1580             makePerspectiveRH(aWidth, aHeight, aZNear, aZFar);
1581             k.z = -k.z;
1582             return *this;
1583         }
1584         template<class T> inline Matrix4<T>& Matrix4<T>::makePerspectiveRH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar)
1585         {
1586             static const T t0(0.0f);
1587             static const T t1(1.0f);
1588             static const T t2(2.0f);
1589
1590             identity();
1591             i.x = t2 * aZNear / aWidth;
1592             j.y = t2 * aZNear / aHeight;
1593             k.z = (aZFar + aZNear) / (aZNear - aZFar);
1594             c.z = t2 * aZNear * aZFar / (aZNear - aZFar);
1595             k.w = -t1;
1596             c.w = t0;
1597             return *this;
1598         }
1599         template<class T> inline Matrix4<T>& Matrix4<T>::makePerspectiveFovLH(const T& aFovY, const T& aAspect, const T& aZNear, const T& aZFar)
1600         {
1601             makePerspectiveFovRH(aFovY, aAspect, aZNear, aZFar);
1602             k.z = -k.z;
1603             return *this;
1604         }
1605         template<class T> inline Matrix4<T>& Matrix4<T>::makePerspectiveFovRH(const T& aFovY, const T& aAspect, const T& aZNear, const T& aZFar)
1606         {
1607             static const T t0(0.0f);
1608             static const T t1(1.0f);
1609             static const T t2(2.0f);
1610
1611             identity();
1612             j.y = t1 / tan(aFovY / t2);
1613             i.x = j.y / aAspect;
1614             k.z = (aZFar + aZNear) / (aZNear - aZFar);
1615             k.w = -t1;
1616             c.z = t2 * (aZNear * aZFar / (aZNear - aZFar));
1617             c.w = t0;
1618             return *this;
1619         }
1620
1621         template<class T> inline Matrix4<T> Matrix4<T>::createLookAtLH(const _Vector3<T>& aEye, const _Vector3<T>& aAt, const _Vector3<T>& aUp)
1622         {
1623             return Matrix4<T>().makeLookAtLH(aEye, aAt, aUp);
1624         }
1625         template<class T> inline Matrix4<T> Matrix4<T>::createLookAtRH(const _Vector3<T>& aEye, const _Vector3<T>& aAt, const _Vector3<T>& aUp)
1626         {
1627             return Matrix4<T>().makeLookAtRH(aEye, aAt, aUp);
1628         }
1629         template<class T> inline Matrix4<T> Matrix4<T>::createOrthoRH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar)
1630         {
1631             return Matrix4<T>().makeOrthoRH(aWidth, aHeight, aZNear, aZFar);
1632         }
1633         template<class T> inline Matrix4<T> Matrix4<T>::createOrthoLH(const T& aWidth, const T& aHeight, const T& aZNear, const T& aZFar)
1634         {
1635             return Matrix4<T>().makeOrthoLH(aWidth, aHeight, aZNear, aZFar);
1636         }
1637         template<class T> inline Matrix4<T> Matrix4<T>::createOrthoRH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar)
1638         {
1639             return Matrix4<T>().makeOrthoRH(aLeft, aRight, aTop, aBottom, aZNear, aZFar);
1640         }
1641         template<class T> inline Matrix4<T> Matrix4<T>::createOrthoLH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar)
1642         {
1643             return Matrix4<T>().makeOrthoLH(aLeft, aRight, aTop, aBottom, aZNear, aZFar);
1644         }
1645         template<class T> inline Matrix4<T> Matrix4<T>::createPerspectiveLH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar)
1646         {
1647             return Matrix4<T>().makePerspectiveLH(aLeft, aRight, aTop, aBottom, aZNear, aZFar);
1648         }
1649         template<class T> inline Matrix4<T> Matrix4<T>::createPerspectiveRH(const T& aLeft, const T& aRight, const T& aTop, const T& aBottom, const T& aZNear, const T& aZFar)
1650         {
1651             return Matrix4<T>().makePerspectiveRH(aLeft, aRight, aTop, aBottom, aZNear, aZFar);
1652         }
1653         template<class T> inline Matrix4<T> Matrix4<T>::createPerspectiveLH(const T& aWidth, const T& aHeight, const T& aZnear, const T& aZFar)
1654         {
1655             return Matrix4<T>().makePerspectiveLH(aWidth, aHeight, aZnear, aZFar);
1656         }
1657         template<class T> inline Matrix4<T> Matrix4<T>::createPerspectiveRH(const T& aWidth, const T& aHeight, const T& aZnear, const T& aZFar)
1658         {
1659             return Matrix4<T>().makePerspectiveRH(aWidth, aHeight, aZnear, aZFar);
1660         }
1661         template<class T> inline Matrix4<T> Matrix4<T>::createPerspectiveFovLH(const T& aFovY, const T& aAspect, const T& aZnear, const T& aZFar)
1662         {
1663             return Matrix4<T>().makePerspectiveFovLH(aFovY, aAspect, aZnear, aZFar);
1664         }
1665         template<class T> inline Matrix4<T> Matrix4<T>::createPerspectiveFovRH(const T& aFovY, const T& aAspect, const T& aZnear, const T& aZFar)
1666         {
1667             return Matrix4<T>().makePerspectiveFovRH(aFovY, aAspect, aZnear, aZFar);
1668         }
1669
1670         template<class T> inline bool Matrix4<T>::getOrthoParamsRH(T& aLeft, T& aRight, T& aTop, T& aBottom, T& aZNear, T& aZFar) const
1671         {
1672             static const T t1(1.0f);
1673
1674             aZNear = (c.z + t1) / k.z;
1675             aZFar = (c.z - t1) / k.z;
1676
1677             aLeft = -(t1 + c.x) / i.x;
1678             aRight = (t1 - c.x) / i.x;
1679
1680             aBottom = -(t1 + c.y) / j.y;
1681             aTop = (t1 - c.y) / j.y;
1682
1683             return true;
1684         }
1685         template<class T> inline bool Matrix4<T>::getPerspectiveParamsRH(T& aLeft, T& aRight, T& aTop, T& aBottom, T& aZNear, T& aZFar) const
1686         {
1687             static const T t1(1.0f);
1688
1689             aZNear = c.z / (k.z - t1);
1690             aZFar = c.z / (t1 + k.z);
1691
1692             aLeft = aZNear * (k.x - t1) / i.x;
1693             aRight = aZNear * (t1 + k.x) / i.x;
1694
1695             aTop = aZNear * (t1 + k.y) / j.y;
1696             aBottom = aZNear * (k.y - t1) / j.y;
1697
1698             return true;
1699         }
1700         template<class T> inline bool Matrix4<T>::getPerspectiveParamsRH(T& aFovY, T& aAspect, T& aZNear, T& aZFar) const
1701         {
1702             T left, right, bottom, top;
1703             bool result = getPerspectiveParamsRH(left, right, top, bottom, aZNear, aZFar);
1704             if(result)
1705             {
1706                 T height = top - bottom;
1707                 T width = right - left;
1708                 aAspect = width / height;
1709                 aFovY = T(2.0f) * effects_atan(height / aZNear * T(0.5f));
1710             }
1711             return result;
1712         }
1713         template<class T> inline bool Matrix4<T>::getViewParams(_Vector3<T>& aPosition, _Vector3<T>& aDirection, _Vector3<T>& aUp, _Vector3<T>& aRight) const
1714         {
1715             aRight.set(i.x, j.x, k.x);
1716             aUp.set(i.y, j.y, k.y);
1717             aDirection.set(-i.z, -j.z, -k.z);
1718             aPosition = aDirection * c.z - aRight * c.x - aUp * c.y;
1719             return true;
1720         }
1721
1722         template<class T> inline bool isEqual(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv, const T& aEpsilon = effects_epsilon<T>::epsilon())
1723         {
1724             return isEqual(aLhv.i, aRhv.i, aEpsilon) && isEqual(aLhv.j, aRhv.j, aEpsilon) && isEqual(aLhv.k, aRhv.k, aEpsilon) && isEqual(aLhv.c, aRhv.c, aEpsilon);
1725         }
1726         template<class T> inline Matrix4<T> operator+(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv)
1727         {
1728             return Matrix4<T>(aLhv.i + aRhv.i, aLhv.j + aRhv.j, aLhv.k + aRhv.k, aLhv.c + aRhv.c);
1729         }
1730         template<class T> inline Matrix4<T> operator+(const Matrix4<T>& aLhv, const T& aRhv)
1731         {
1732             return Matrix4<T>(aLhv.i + aRhv, aLhv.j + aRhv, aLhv.k + aRhv, aLhv.c + aRhv);
1733         }
1734         template<class T> inline Matrix4<T> operator+(const T& aLhv, const Matrix4<T>& aRhv)
1735         {
1736             return Matrix4<T>(aLhv + aRhv.i, aLhv + aRhv.j, aLhv + aRhv.k, aLhv + aRhv.c);
1737         }
1738         template<class T> inline Matrix4<T> operator-(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv)
1739         {
1740             return Matrix4<T>(aLhv.i - aRhv.i, aLhv.j - aRhv.j, aLhv.k - aRhv.k, aLhv.c - aRhv.c);
1741         }
1742         template<class T> inline Matrix4<T> operator-(const Matrix4<T>& aLhv, const T& aRhv)
1743         {
1744             return Matrix4<T>(aLhv.i - aRhv, aLhv.j - aRhv, aLhv.k - aRhv, aLhv.c - aRhv);
1745         }
1746         template<class T> inline Matrix4<T> operator-(const T& aLhv, const Matrix4<T>& aRhv)
1747         {
1748             return Matrix4<T>(aLhv - aRhv.i, aLhv - aRhv.j, aLhv - aRhv.k, aLhv - aRhv.c);
1749         }
1750         template<class T> inline Matrix4<T> operator*(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv)
1751         {
1752             return Matrix4<T>(
1753                 aLhv.i.x * aRhv.i.x + aLhv.i.y * aRhv.j.x + aLhv.i.z * aRhv.k.x + aLhv.i.w * aRhv.c.x,
1754                 aLhv.i.x * aRhv.i.y + aLhv.i.y * aRhv.j.y + aLhv.i.z * aRhv.k.y + aLhv.i.w * aRhv.c.y,
1755                 aLhv.i.x * aRhv.i.z + aLhv.i.y * aRhv.j.z + aLhv.i.z * aRhv.k.z + aLhv.i.w * aRhv.c.z,
1756                 aLhv.i.x * aRhv.i.w + aLhv.i.y * aRhv.j.w + aLhv.i.z * aRhv.k.w + aLhv.i.w * aRhv.c.w,
1757
1758                 aLhv.j.x * aRhv.i.x + aLhv.j.y * aRhv.j.x + aLhv.j.z * aRhv.k.x + aLhv.j.w * aRhv.c.x,
1759                 aLhv.j.x * aRhv.i.y + aLhv.j.y * aRhv.j.y + aLhv.j.z * aRhv.k.y + aLhv.j.w * aRhv.c.y,
1760                 aLhv.j.x * aRhv.i.z + aLhv.j.y * aRhv.j.z + aLhv.j.z * aRhv.k.z + aLhv.j.w * aRhv.c.z,
1761                 aLhv.j.x * aRhv.i.w + aLhv.j.y * aRhv.j.w + aLhv.j.z * aRhv.k.w + aLhv.j.w * aRhv.c.w,
1762
1763                 aLhv.k.x * aRhv.i.x + aLhv.k.y * aRhv.j.x + aLhv.k.z * aRhv.k.x + aLhv.k.w * aRhv.c.x,
1764                 aLhv.k.x * aRhv.i.y + aLhv.k.y * aRhv.j.y + aLhv.k.z * aRhv.k.y + aLhv.k.w * aRhv.c.y,
1765                 aLhv.k.x * aRhv.i.z + aLhv.k.y * aRhv.j.z + aLhv.k.z * aRhv.k.z + aLhv.k.w * aRhv.c.z,
1766                 aLhv.k.x * aRhv.i.w + aLhv.k.y * aRhv.j.w + aLhv.k.z * aRhv.k.w + aLhv.k.w * aRhv.c.w,
1767
1768                 aLhv.c.x * aRhv.i.x + aLhv.c.y * aRhv.j.x + aLhv.c.z * aRhv.k.x + aLhv.c.w * aRhv.c.x,
1769                 aLhv.c.x * aRhv.i.y + aLhv.c.y * aRhv.j.y + aLhv.c.z * aRhv.k.y + aLhv.c.w * aRhv.c.y,
1770                 aLhv.c.x * aRhv.i.z + aLhv.c.y * aRhv.j.z + aLhv.c.z * aRhv.k.z + aLhv.c.w * aRhv.c.z,
1771                 aLhv.c.x * aRhv.i.w + aLhv.c.y * aRhv.j.w + aLhv.c.z * aRhv.k.w + aLhv.c.w * aRhv.c.w);
1772         }
1773         template<class T> inline Matrix4<T> operator*(const Matrix4<T>& aLhv, const T& aRhv)
1774         {
1775             return Matrix4<T>(aLhv.i * aRhv, aLhv.j * aRhv, aLhv.k * aRhv, aLhv.c * aRhv);
1776         }
1777         template<class T> inline Matrix4<T> operator*(const T& aLhv, const Matrix4<T>& aRhv)
1778         {
1779             return Matrix4<T>(aLhv * aRhv.i, aLhv * aRhv.j, aLhv * aRhv.k, aLhv * aRhv.c);
1780         }
1781         template<class T> inline Vector4<T> operator*(const Matrix4<T>& aLhv, const Vector4<T>& aRhv)
1782         {
1783             return Vector4<T>(aLhv.i.dot(aRhv), aLhv.j.dot(aRhv), aLhv.k.dot(aRhv), aLhv.c.dot(aRhv));
1784         }
1785         template<class T> inline Vector4<T> operator*(const Vector4<T>& aLhv, const Matrix4<T>& aRhv)
1786         {
1787             return aRhv.getAppliedTransform(aLhv);
1788         }
1789         template<class T> inline _Vector3<T> operator*(const _Vector3<T>& aLhv, const Matrix4<T>& aRhv)
1790         {
1791             return aRhv.getAppliedTransform(aLhv);
1792         }
1793         template<class T> inline _Vector3<T> operator*(const Matrix4<T>& aLhv, const _Vector3<T>& aRhv)
1794         {
1795             return _Vector3<T>(  aLhv.i.x * aRhv.x + aLhv.i.y * aRhv.y + aLhv.i.z * aRhv.z + aLhv.i.w,
1796                 aLhv.j.x * aRhv.x + aLhv.j.y * aRhv.y + aLhv.j.z * aRhv.z + aLhv.j.w,
1797                 aLhv.k.x * aRhv.x + aLhv.k.y * aRhv.y + aLhv.k.z * aRhv.z + aLhv.k.w);
1798         }
1799         template<class T> inline Matrix4<T> operator/(const Matrix4<T>& aLhv, const T& aRhv)
1800         {
1801             return Matrix4<T>(aLhv.i / aRhv, aLhv.j / aRhv, aLhv.k / aRhv, aLhv.c / aRhv);
1802         }
1803         template<class T> inline Matrix4<T> operator/(const T& aLhv, const Matrix4<T>& aRhv)
1804         {
1805             return Matrix4<T>(aLhv / aRhv.i, aLhv / aRhv.j, aLhv / aRhv.k, aLhv / aRhv.c);
1806         }
1807         template<class T> inline bool operator==(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv)
1808         {
1809             return aLhv.i == aRhv.i && aLhv.j == aRhv.j && aLhv.k == aRhv.k && aLhv.c == aRhv.c;
1810         }
1811         template<class T> inline bool operator==(const Matrix4<T>& aLhv, const T& aRhv)
1812         {
1813             return aLhv.i == aRhv && aLhv.j == aRhv && aLhv.k == aRhv && aLhv.c == aRhv;
1814         }
1815         template<class T> inline bool operator==(const T& aLhv, const Matrix4<T>& aRhv)
1816         {
1817             return aLhv == aRhv.i && aLhv == aRhv.j && aLhv == aRhv.k && aLhv == aRhv.c;
1818         }
1819         template<class T> inline bool operator!=(const Matrix4<T>& aLhv, const Matrix4<T>& aRhv)
1820         {
1821             return !(aLhv == aRhv);
1822         }
1823         template<class T> inline bool operator!=(const Matrix4<T>& aLhv, const T& aRhv)
1824         {
1825             return !(aLhv == aRhv);
1826         }
1827         template<class T> inline bool operator!=(const T& aLhv, const Matrix4<T>& aRhv)
1828         {
1829             return !(aLhv == aRhv);
1830         }
1831 } } } } //Tizen::Ui::Effects::_Utils
1832
1833 #endif //_FUI_EFFECTS_INTERNAL_UTILS_MATRIX4_H_