Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / effects / inc / renderer / math / FUiEffects_RendererMathMatrixTraits.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_RendererMathMatrixTraits.h
20  * @brief      The MatrixTraits class
21  *
22  */
23
24 #ifndef _FUI_EFFECTS_INTERNAL_RENDERER_MATH_MATRIX_TRAITS_H_
25 #define _FUI_EFFECTS_INTERNAL_RENDERER_MATH_MATRIX_TRAITS_H_
26
27 #include <renderer/math/FUiEffects_RendererMathMatrixTraitsBase.h>
28 #include <renderer/math/FUiEffects_RendererMathCommon.h>
29 #include <renderer/math/FUiEffects_RendererMathAdapterFunctions.h>
30
31 namespace Tizen { namespace Ui { namespace Effects { namespace _Renderer { namespace Math
32 {
33
34 template<typename T, int Dimension>
35 class Vector;
36 template<typename T>
37 class Quaternion;
38
39 template<typename T, int Dimension>
40 class MatrixTraits :
41         public MatrixTraitsBase<T, Dimension>
42 {
43 public:
44         typedef Matrix<T, Dimension> MatrixType;
45         typedef Vector<T, Dimension> VectorType;
46         typedef Vector<T, 3> Vector3;
47         typedef Matrix<T, 3> Matrix3;
48         typedef Matrix<T, 2> Matrix2;
49
50         typedef MatrixTraitsBase<T, Dimension> MatrixTraitsBaseType;
51         typedef typename MatrixTraitsBaseType::TypeReference TypeReference;
52
53         using MatrixTraitsBaseType::data;
54
55         inline VectorType& I(void);
56         inline const VectorType& I(void) const;
57
58         inline VectorType& J(void);
59         inline const VectorType& J(void) const;
60
61         inline VectorType& K(void);
62         inline const VectorType& K(void) const;
63
64         inline VectorType& C(void);
65         inline const VectorType& C(void) const;
66
67         inline MatrixType& Set(const VectorType& i, const VectorType& j, const VectorType& k, const VectorType& c);
68         inline MatrixType& Set(const TypeReference a11, const TypeReference a12, const TypeReference a13, const TypeReference a14,
69                                                    const TypeReference a21, const TypeReference a22, const TypeReference a23, const TypeReference a24,
70                                                    const TypeReference a31, const TypeReference a32, const TypeReference a33, const TypeReference a34,
71                                                    const TypeReference a41, const TypeReference a42, const TypeReference a43, const TypeReference a44);
72
73         inline static const MatrixType& GetIdentity(void);
74
75         inline MatrixType& Slerp(const MatrixType& to, const TypeReference coeff);
76         inline MatrixType GetSlerped(const MatrixType& to, const TypeReference coeff) const;
77         inline MatrixType& MakeSlerped(const MatrixType& from, const MatrixType& to, const TypeReference coeff);
78         static inline MatrixType CreateSlerped(const MatrixType& from, const MatrixType& to, const TypeReference coeff);
79
80         inline VectorType& ApplyRotation(VectorType& vector) const;
81         inline VectorType GetAppliedRotation(const VectorType& vector) const;
82         inline VectorType& ApplyTranslate(VectorType& vector) const;
83         inline VectorType GetAppliedTranslate(const VectorType& vector) const;
84
85         inline Vector3& ApplyTransform(Vector3& vector) const;
86         inline Vector3 GetAppliedTransform(const Vector3& vector) const;
87         inline Vector3& ApplyRotation(Vector3& vector) const;
88         inline Vector3 GetAppliedRotation(const Vector3& vector) const;
89         inline Vector3& ApplyTranslate(Vector3& vector) const;
90         inline Vector3 GetAppliedTranslate(const Vector3& vector) const;
91
92         inline Quaternion<T>& ApplyRotation(Quaternion<T>& quaternion) const;
93         inline Quaternion<T> GetAppliedRotation(const Quaternion<T>& quaternion) const;
94
95         inline MatrixType& SetRotation(const TypeReference xAngleRad, const TypeReference yAngleRad, const TypeReference zAngleRad, RotationOrder3 order = ROTATION_XYZ);
96         inline MatrixType& SetRotation(const Vector3& anglesRad, RotationOrder3 order = ROTATION_XYZ);
97         inline MatrixType& SetRotationX(const TypeReference angleRad);
98         inline MatrixType& SetRotationY(const TypeReference angleRad);
99         inline MatrixType& SetRotationZ(const TypeReference angleRad);
100         inline MatrixType& SetRotationAxis(const Vector3& axis, const TypeReference angleRad);
101         inline MatrixType& SetRotationAxis(const TypeReference xAxis, const TypeReference yAxis, const TypeReference zAxis, const TypeReference angleRad);
102         inline MatrixType& SetRotation(const Quaternion<T>& rotation);
103         inline MatrixType& SetRotation(const Matrix3& rotation);
104         inline MatrixType& MakeRotation(const TypeReference xAngleRad, const TypeReference yAngleRad, const TypeReference zAngleRad, RotationOrder3 order = ROTATION_XYZ);
105         inline MatrixType& MakeRotation(const Vector3& anglesRad, RotationOrder3 order = ROTATION_XYZ);
106         inline MatrixType& MakeRotationX(const TypeReference angleRad);
107         inline MatrixType& MakeRotationY(const TypeReference angleRad);
108         inline MatrixType& MakeRotationZ(const TypeReference angleRad);
109         inline MatrixType& MakeRotationAxis(const Vector3& axis, const TypeReference angleRad);
110         inline MatrixType& MakeRotationAxis(const TypeReference xAxis, const TypeReference yAxis, const TypeReference zAxis, const TypeReference angleRad);
111         inline MatrixType& MakeRotation(const Quaternion<T>& rotation);
112         inline MatrixType& MakeRotation(const Matrix3& rotation);
113         inline MatrixType& Rotate(const TypeReference xAngleRad, const TypeReference yAngleRad, const TypeReference zAngleRad, RotationOrder3 order = ROTATION_XYZ);
114         inline MatrixType& Rotate(const Vector3& anglesRad, RotationOrder3 order3 = ROTATION_XYZ);
115         inline MatrixType& RotateX(const TypeReference angleRad);
116         inline MatrixType& RotateY(const TypeReference angleRad);
117         inline MatrixType& RotateZ(const TypeReference angleRad);
118         inline MatrixType& RotateAxis(const Vector3& axis, const TypeReference angleRad);
119         inline MatrixType& RotateAxis(const TypeReference xAxis, const TypeReference yAxis, const TypeReference zAxis, const TypeReference angleRad);
120         inline MatrixType& Rotate(const Quaternion<T>& rotation);
121         inline MatrixType& Rotate(const Matrix3& rotation);
122         inline MatrixType& Rotate(const MatrixType& rotation);
123         static inline MatrixType CreateRotation(const TypeReference xAngleRad, const TypeReference yAngleRad, const TypeReference zAngleRad, RotationOrder3 order = ROTATION_XYZ);
124         static inline MatrixType CreateRotation(const Vector3& anglesRad, RotationOrder3 order = ROTATION_XYZ);
125         static inline MatrixType CreateRotationX(const TypeReference angleRad);
126         static inline MatrixType CreateRotationY(const TypeReference angleRad);
127         static inline MatrixType CreateRotationZ(const TypeReference angleRad);
128         static inline MatrixType CreateRotationAxis(const Vector3& axis, const TypeReference angleRad);
129         static inline MatrixType CreateRotationAxis(const TypeReference xAxis, const TypeReference yAxis, const TypeReference zAxis, const TypeReference angleRad);
130         static inline MatrixType CreateRotation(const Quaternion<T>& rotation);
131         static inline MatrixType CreateRotation(const Matrix3& rotation);
132         inline MatrixType& GetRotationAngles(T& xAngleRad, T& yAngeRad, T& zAngleRad, unsigned int solutionNumber = 1);
133         inline Quaternion<T> GetQuaternion(void) const;
134         inline Quaternion<T>& GetQuaternion(Quaternion<T>& rotation) const;
135         inline Matrix3 GetRotation(void) const;
136         inline Matrix3& GetRotation(Matrix3& rotation) const;
137
138         inline MatrixType& MakeScale(const TypeReference x, const TypeReference y, const TypeReference z);
139         inline MatrixType& SetScale(const TypeReference x, const TypeReference y, const TypeReference z);
140         static inline MatrixType CreateScale(const TypeReference x, const TypeReference y, const TypeReference z);
141         inline MatrixType& Scale(const TypeReference x, const TypeReference y, const TypeReference z);
142
143         inline MatrixType& SetTranslation(const TypeReference x, const TypeReference y, const TypeReference z);
144         inline MatrixType& SetTranslation(const Vector3& tran);
145         inline MatrixType& MakeTranslation(const TypeReference x, const TypeReference y, const TypeReference z);
146         inline MatrixType& MakeTranslation(const Vector3& tran);
147         inline MatrixType& Translate(const TypeReference x, const TypeReference y, const TypeReference z);
148         inline MatrixType& Translate(const Vector3& tran);
149         static inline MatrixType CreateTranslation(const TypeReference x, const TypeReference y, const TypeReference z);
150         static inline MatrixType CreateTranslation(const Vector3& tran);
151         inline Vector3 GetTranslation(void) const;
152         inline VectorType GetFullTranslation(void) const;
153
154         inline MatrixType& MakeLookAtLH(const Vector3& eye, const Vector3& at, const Vector3& up);
155         inline MatrixType& MakeLookAtRH(const Vector3& eye, const Vector3& at, const Vector3& up);
156         inline MatrixType& MakeOrthoRH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar);
157         inline MatrixType& MakeOrthoLH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar);
158         inline MatrixType& MakeOrthoRH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar);
159         inline MatrixType& MakeOrthoLH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar);
160         inline MatrixType& MakePerspectiveLH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar);
161         inline MatrixType& MakePerspectiveRH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar);
162         inline MatrixType& MakePerspectiveLH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar);
163         inline MatrixType& MakePerspectiveRH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar);
164         inline MatrixType& MakePerspectiveFovLH(const TypeReference fovY, const TypeReference aspect, const TypeReference zNear, const TypeReference zFar);
165         inline MatrixType& MakePerspectiveFovRH(const TypeReference fovY, const TypeReference aspect, const TypeReference zNear, const TypeReference zFar);
166         static inline MatrixType CreateLookAtLH(const Vector3& eye, const Vector3& at, const Vector3& up);
167         static inline MatrixType CreateLookAtRH(const Vector3& eye, const Vector3& at, const Vector3& up);
168         static inline MatrixType CreateOrthoRH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar);
169         static inline MatrixType CreateOrthoLH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar);
170         static inline MatrixType CreateOrthoRH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar);
171         static inline MatrixType CreateOrthoLH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar);
172         static inline MatrixType CreatePerspectiveLH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar);
173         static inline MatrixType CreatePerspectiveRH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar);
174         static inline MatrixType CreatePerspectiveLH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar);
175         static inline MatrixType CreatePerspectiveRH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar);
176         static inline MatrixType CreatePerspectiveFovLH(const TypeReference fovY, const TypeReference aspect, const TypeReference zNear, const TypeReference zFar);
177         static inline MatrixType CreatePerspectiveFovRH(const TypeReference fovY, const TypeReference aspect, const TypeReference zNear, const TypeReference zFar);
178
179         inline bool GetOrthoParamsRH(T& left, T& right, T& top, T& bottom, T& zNear, T& zFar) const;
180         inline bool GetPerspectiveParamsRH(T& left, T& right, T& top, T& bottom, T& zNear, T& zFar) const;
181         inline bool GetPerspectiveParamsRH(T& fovY, T& aspect, T& zNear, T& zFar) const;
182         inline bool GetViewParams(Vector3& position, Vector3& direction, Vector3& up, Vector3& right) const;
183 };
184
185 template<typename T, int Dimension>
186 typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::I(void)
187 {
188         return data[0];
189 }
190
191 template<typename T, int Dimension>
192 const typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::I(void) const
193 {
194         return data[0];
195 }
196
197 template<typename T, int Dimension>
198 typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::J(void)
199 {
200         return data[1];
201 }
202
203 template<typename T, int Dimension>
204 const typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::J(void) const
205 {
206         return data[1];
207 }
208
209 template<typename T, int Dimension>
210 typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::K(void)
211 {
212         return data[2];
213 }
214
215 template<typename T, int Dimension>
216 const typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::K(void) const
217 {
218         return data[2];
219 }
220
221 template<typename T, int Dimension>
222 typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::C(void)
223 {
224         return data[3];
225 }
226
227 template<typename T, int Dimension>
228 const typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::C(void) const
229 {
230         return data[3];
231 }
232
233 template<typename T, int Dimension>
234 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Set(const VectorType& i, const VectorType& j, const VectorType& k, const VectorType& c)
235 {
236         data[0] = i;
237         data[1] = j;
238         data[2] = k;
239         data[3] = c;
240         return *(static_cast<MatrixType*>(this));
241 }
242
243 template<typename T, int Dimension>
244 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Set(const TypeReference a11, const TypeReference a12, const TypeReference a13, const TypeReference a14,
245                                                                                                                                                                  const TypeReference a21, const TypeReference a22, const TypeReference a23, const TypeReference a24,
246                                                                                                                                                                  const TypeReference a31, const TypeReference a32, const TypeReference a33, const TypeReference a34,
247                                                                                                                                                                  const TypeReference a41, const TypeReference a42, const TypeReference a43, const TypeReference a44)
248 {
249         data[0].Set(a11, a12, a13, a14);
250         data[1].Set(a21, a22, a23, a24);
251         data[2].Set(a31, a32, a33, a34);
252         data[3].Set(a41, a42, a43, a44);
253         return *(static_cast<MatrixType*>(this));
254 }
255
256 template<typename T, int Dimension>
257 const typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::GetIdentity(void)
258 {
259         static const MatrixType identityMatrix = MatrixType(T(1.0f), T(0.0f), T(0.0f), T(0.0f),
260                                                                                                   T(0.0f), T(1.0f), T(0.0f), T(0.0f),
261                                                                                                   T(0.0f), T(0.0f), T(1.0f), T(0.0f),
262                                                                                                   T(0.0f), T(0.0f), T(0.0f), T(1.0f));
263         return identityMatrix;
264 }
265
266 template<typename T, int Dimension>
267 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Slerp(const MatrixType& to, const TypeReference coeff)
268 {
269         SetRotation(GetQuaternion().Slerp(to.GetQuaternion(), coeff));
270
271         VectorType column = VectorType(data[0].data[3], data[1].data[3], data[2].data[3], data[3].data[3]);
272         column.lerp(VectorType(to.data[0].data[3], to.data[1].data[3], to.data[2].data[3], to.data[3].data[3]), coeff);
273         data[0].data[3] = column.data[0];
274         data[1].data[3] = column.data[1];
275         data[2].data[3] = column.data[2];
276         data[3].data[3] = column.data[3];
277
278         return *(static_cast<MatrixType*>(this));
279 }
280
281 template<typename T, int Dimension>
282 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::GetSlerped(const MatrixType& to, const TypeReference coeff) const
283 {
284         MatrixType result;
285         result.MakeRotation(GetQuaternion().Slerp(to.GetQuaternion(), coeff));
286
287         VectorType column = VectorType(data[0].data[3], data[1].data[3], data[2].data[3], data[3].data[3]);
288         column.lerp(VectorType(to.data[0].data[3], to.data[1].data[3], to.data[2].data[3], to.data[3].data[3]), coeff);
289         result.data[0].data[3] = column.data[0];
290         result.data[1].data[3] = column.data[1];
291         result.data[2].data[3] = column.data[2];
292         result.data[3].data[3] = column.data[3];
293
294         return result;
295 }
296
297 template<typename T, int Dimension>
298 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeSlerped(const MatrixType& from, const MatrixType& to, const TypeReference coeff)
299 {
300         *this = from;
301         Slerp(to, coeff);
302         return *(static_cast<MatrixType*>(this));
303 }
304
305 template<typename T, int Dimension>
306 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateSlerped(const MatrixType& from, const MatrixType& to, const TypeReference coeff)
307 {
308         return MatrixType().MakeSlerped(from, to, coeff);
309 }
310
311 template<typename T, int Dimension>
312 typename MatrixTraits<T, Dimension>::VectorType&  MatrixTraits<T, Dimension>::ApplyRotation(VectorType& vector) const
313 {
314         return vector.Set(vector.data[0] * data[0].data[0] + vector.data[1] * data[0].data[1] + vector.data[2] * data[0].data[2],
315                                            vector.data[0] * data[1].data[0] + vector.data[1] * data[1].data[1] + vector.data[2] * data[1].data[2],
316                                            vector.data[0] * data[2].data[0] + vector.data[1] * data[2].data[1] + vector.data[2] * data[2].data[2],
317                                            vector.data[3]);
318 }
319
320 template<typename T, int Dimension>
321 typename MatrixTraits<T, Dimension>::VectorType MatrixTraits<T, Dimension>::GetAppliedRotation(const VectorType& vector) const
322 {
323         return VectorType(vector.data[0] * data[0].data[0] + vector.data[1] * data[0].data[1] + vector.data[2] * data[0].data[2],
324                 vector.data[0] * data[1].data[0] + vector.data[1] * data[1].data[1] + vector.data[2] * data[1].data[2],
325                 vector.data[0] * data[2].data[0] + vector.data[1] * data[2].data[1] + vector.data[2] * data[2].data[2],
326                 vector.data[3]);
327 }
328
329 template<typename T, int Dimension>
330 typename MatrixTraits<T, Dimension>::VectorType& MatrixTraits<T, Dimension>::ApplyTranslate(VectorType& vector) const
331 {
332         return vector.Set(vector.data[0] + vector.data[3] * data[3].data[0],
333                                            vector.data[1] + vector.data[3] * data[3].data[1],
334                                            vector.data[2] + vector.data[3] * data[3].data[2],
335                                            vector.data[3]);
336 }
337
338 template<typename T, int Dimension>
339 typename MatrixTraits<T, Dimension>::VectorType MatrixTraits<T, Dimension>::GetAppliedTranslate(const VectorType& vector) const
340 {
341         return VectorType(vector.data[0] + vector.data[3] * data[3].data[0],
342                 vector.data[1] + vector.data[3] * data[3].data[1],
343                 vector.data[2] + vector.data[3] * data[3].data[2],
344                 vector.data[3]);
345 }
346
347 template<typename T, int Dimension>
348 typename MatrixTraits<T, Dimension>::Vector3& MatrixTraits<T, Dimension>::ApplyTransform(Vector3& vector) const
349 {
350         return vector.Set(vector.data[0] * data[0].data[0] + vector.data[1] * data[0].data[1] + vector.data[2] * data[0].data[2] + data[0].data[3],
351                                            vector.data[0] * data[1].data[0] + vector.data[1] * data[1].data[1] + vector.data[2] * data[1].data[2] + data[1].data[3],
352                                            vector.data[0] * data[2].data[0] + vector.data[1] * data[2].data[1] + vector.data[2] * data[2].data[2] + data[2].data[3]);
353 }
354
355 template<typename T, int Dimension>
356 typename MatrixTraits<T, Dimension>::Vector3 MatrixTraits<T, Dimension>::GetAppliedTransform(const Vector3& vector) const
357 {
358         return Vector3().Set(vector.data[0] * data[0].data[0] + vector.data[1] * data[0].data[1] + vector.data[2] * data[0].data[2] + data[0].data[3],
359                                                  vector.data[0] * data[1].data[0] + vector.data[1] * data[1].data[1] + vector.data[2] * data[1].data[2] + data[1].data[3],
360                                                  vector.data[0] * data[2].data[0] + vector.data[1] * data[2].data[1] + vector.data[2] * data[2].data[2] + data[2].data[3]);
361 }
362
363 template<typename T, int Dimension>
364 typename MatrixTraits<T, Dimension>::Vector3& MatrixTraits<T, Dimension>::ApplyRotation(Vector3& vector) const
365 {
366         return vector.Set(vector.data[0] * data[0].data[0] + vector.data[1] * data[0].data[1] + vector.data[2] * data[0].data[2],
367                 vector.data[0] * data[1].data[0] + vector.data[1] * data[1].data[1] + vector.data[2] * data[1].data[2],
368                 vector.data[0] * data[2].data[0] + vector.data[1] * data[2].data[1] + vector.data[2] * data[2].data[2]);
369 }
370
371 template<typename T, int Dimension>
372 typename MatrixTraits<T, Dimension>::Vector3 MatrixTraits<T, Dimension>::GetAppliedRotation(const Vector3& vector) const
373 {
374         return Vector3().Set(vector.data[0] * data[0].data[0] + vector.data[1] * data[0].data[1] + vector.data[2] * data[0].data[2],
375                 vector.data[0] * data[1].data[0] + vector.data[1] * data[1].data[1] + vector.data[2] * data[1].data[2],
376                 vector.data[0] * data[2].data[0] + vector.data[1] * data[2].data[1] + vector.data[2] * data[2].data[2]);
377 }
378
379 template<typename T, int Dimension>
380 typename MatrixTraits<T, Dimension>::Vector3& MatrixTraits<T, Dimension>::ApplyTranslate(Vector3& vector) const
381 {
382         return vector.Set(vector.data[0] + data[0].data[3],
383                                            vector.data[1] + data[1].data[3],
384                                            vector.data[2] + data[2].data[3]);
385 }
386
387 template<typename T, int Dimension>
388 typename MatrixTraits<T, Dimension>::Vector3 MatrixTraits<T, Dimension>::GetAppliedTranslate(const Vector3& vector) const
389 {
390         return Vector3(vector.data[0] + data[0].data[3],
391                 vector.data[1] + data[1].data[3],
392                 vector.data[2] + data[2].data[3]);
393 }
394
395 template<typename T, int Dimension>
396 Quaternion<T>& MatrixTraits<T, Dimension>::ApplyRotation(Quaternion<T>& quaternion) const
397 {
398         return quaternion.Set(GetQuaternion() * quaternion);
399 }
400
401 template<typename T, int Dimension>
402 Quaternion<T> MatrixTraits<T, Dimension>::GetAppliedRotation(const Quaternion<T>& quaternion) const
403 {
404         return GetQuaternion() * quaternion;
405 }
406
407 template<typename T, int Dimension>
408 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotation(const TypeReference xAngleRad, const TypeReference yAngleRad, const TypeReference zAngleRad, RotationOrder3 order)
409 {
410         MatrixType result;
411         result.MakeRotation(xAngleRad, yAngleRad, zAngleRad, order);
412         data[0].data[0] = result.data[0].data[0];
413         data[0].data[1] = result.data[0].data[1];
414         data[0].data[2] = result.data[0].data[2];
415         data[1].data[0] = result.data[1].data[0];
416         data[1].data[1] = result.data[1].data[1];
417         data[1].data[2] = result.data[1].data[2];
418         data[2].data[0] = result.data[2].data[0];
419         data[2].data[1] = result.data[2].data[1];
420         data[2].data[2] = result.data[2].data[2];
421
422         return *(static_cast<MatrixType*>(this));
423 }
424
425 template<typename T, int Dimension>
426 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotation(const Vector3& anglesRad, RotationOrder3 order)
427 {
428         return SetRotation(anglesRad.data[0], anglesRad.data[1], anglesRad.data[2], order);
429 }
430
431 template<typename T, int Dimension>
432 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotationX(const TypeReference angleRad)
433 {
434         const T c = effects_cos(angleRad);
435         const T s = effects_sin(angleRad);
436         data[0].data[0] = T(1.0f);
437         data[0].data[1] = data[0].data[2] = data[1].data[0] = data[2].data[0] = T(0.0f);
438         data[1].data[1] = c;
439         data[1].data[2] = -s;
440         data[2].data[1] = s;
441         data[2].data[2] = c;
442         return *(static_cast<MatrixType*>(this));
443 }
444
445 template<typename T, int Dimension>
446 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotationY(const TypeReference angleRad)
447 {
448         const T c = effects_cos(angleRad);
449         const T s = effects_sin(angleRad);
450         data[1].data[1] = T(1.0f);
451         data[0].data[1] = data[1].data[0] = data[1].data[2] = data[2].data[1] = T(0.0f);
452         data[0].data[0] = c;
453         data[0].data[2] = s;
454         data[2].data[0] = -s;
455         data[2].data[2] = c;
456         return *(static_cast<MatrixType*>(this));
457 }
458
459 template<typename T, int Dimension>
460 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotationZ(const TypeReference angleRad)
461 {
462         const T c = effects_cos(angleRad);
463         const T s = effects_sin(angleRad);
464         data[2].data[2] = T(1.0f);
465         data[0].data[2] = data[2].data[0] = data[1].data[2] = data[2].data[1] = T(0.0f);
466         data[0].data[0] = c;
467         data[0].data[1] = -s;
468         data[1].data[0] = s;
469         data[1].data[1] = c;
470         return *(static_cast<MatrixType*>(this));
471 }
472
473 template<typename T, int Dimension>
474 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotationAxis(const Vector3& axis, const TypeReference angleRad)
475 {
476         return SetRotationAxis(axis.data[0], axis.data[1], axis.data[2], angleRad);
477 }
478
479 template<typename T, int Dimension>
480 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotationAxis(const TypeReference xAxis, const TypeReference yAxis, const TypeReference zAxis, const TypeReference angleRad)
481 {
482         MatrixType result;
483         result.MakeRotationAxis(xAxis, yAxis, zAxis, angleRad);
484         data[0].data[0] = result.data[0].data[0];
485         data[0].data[1] = result.data[0].data[1];
486         data[0].data[2] = result.data[0].data[2];
487         data[1].data[0] = result.data[1].data[0];
488         data[1].data[1] = result.data[1].data[1];
489         data[1].data[2] = result.data[1].data[2];
490         data[2].data[0] = result.data[2].data[0];
491         data[2].data[1] = result.data[2].data[1];
492         data[2].data[2] = result.data[2].data[2];
493
494         return *(static_cast<MatrixType*>(this));
495 }
496
497 template<typename T, int Dimension>
498 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotation(const Quaternion<T>& rotation)
499 {
500         T wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
501         T s = T(2.0f) / rotation.lengthSqr();  // 4 mul 3 add 1 div
502         x2 = rotation.x * s;
503         y2 = rotation.y * s;
504         z2 = rotation.z * s;
505         xx = rotation.x * x2;
506         xy = rotation.x * y2;
507         xz = rotation.x * z2;
508         yy = rotation.y * y2;
509         yz = rotation.y * z2;
510         zz = rotation.z * z2;
511         wx = rotation.w * x2;
512         wy = rotation.w * y2;
513         wz = rotation.w * z2;
514
515         const T t1(1.0f);
516         data[0].data[0] = t1 - (yy + zz);
517         data[0].data[1] = xy - wz;
518         data[0].data[2] = xz + wy;
519
520         data[1].data[0] = xy + wz;
521         data[1].data[1] = t1 - (xx + zz);
522         data[1].data[2] = yz - wx;
523
524         data[2].data[0] = xz - wy;
525         data[2].data[1] = yz + wx;
526         data[2].data[2] = t1 - (xx + yy);
527         return *(static_cast<MatrixType*>(this));
528 }
529
530 template<typename T, int Dimension>
531 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetRotation(const Matrix3& rotation)
532 {
533         data[0].data[0] = rotation.data[0].data[0];
534         data[0].data[1] = rotation.data[0].data[1];
535         data[0].data[2] = rotation.data[0].data[2];
536         data[1].data[0] = rotation.data[1].data[0];
537         data[1].data[1] = rotation.data[1].data[1];
538         data[1].data[2] = rotation.data[1].data[2];
539         data[2].data[0] = rotation.data[2].data[0];
540         data[2].data[1] = rotation.data[2].data[1];
541         data[2].data[2] = rotation.data[2].data[2];
542
543         return *(static_cast<MatrixType*>(this));
544 }
545
546 template<typename T, int Dimension>
547 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotation(const TypeReference xAngleRad, const TypeReference yAngleRad, const TypeReference zAngleRad, RotationOrder3 order)
548 {
549         switch (order)
550         {
551         case ROTATION_XYZ:
552                 MakeRotationX(xAngleRad);
553                 RotateY(yAngleRad);
554                 RotateZ(zAngleRad);
555                 break;
556         case ROTATION_XZY:
557                 MakeRotationX(xAngleRad);
558                 RotateZ(zAngleRad);
559                 RotateY(yAngleRad);
560                 break;
561         case ROTATION_YXZ:
562                 MakeRotationY(yAngleRad);
563                 RotateX(xAngleRad);
564                 RotateZ(zAngleRad);
565                 break;
566         case ROTATION_YZX:
567                 MakeRotationY(yAngleRad);
568                 RotateZ(zAngleRad);
569                 RotateX(xAngleRad);
570                 break;
571         case ROTATION_ZXY:
572                 MakeRotationZ(zAngleRad);
573                 RotateX(xAngleRad);
574                 RotateY(yAngleRad);
575                 break;
576         case ROTATION_ZYX:
577                 MakeRotationZ(zAngleRad);
578                 RotateY(yAngleRad);
579                 RotateX(xAngleRad);
580                 break;
581         default:
582                 break;
583         };
584
585         return *(static_cast<MatrixType*>(this));
586 }
587
588 template<typename T, int Dimension>
589 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotation(const Vector3& anglesRad, RotationOrder3 order)
590 {
591         return MakeRotation(anglesRad.data[0], anglesRad.data[1], anglesRad.data[2], order);
592 }
593
594 template<typename T, int Dimension>
595 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotationX(const TypeReference angleRad)
596 {
597         *this = GetIdentity();
598         const T c = effects_cos(angleRad);
599         const T s = effects_sin(angleRad);
600         data[1].data[1] = c;
601         data[1].data[2] = -s;
602         data[2].data[1] = s;
603         data[2].data[2] = c;
604         return *(static_cast<MatrixType*>(this));
605 }
606
607 template<typename T, int Dimension>
608 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotationY(const TypeReference angleRad)
609 {
610         *this = GetIdentity();
611         const T c = effects_cos(angleRad);
612         const T s = effects_sin(angleRad);
613         data[0].data[0] = c;
614         data[0].data[2] = s;
615         data[2].data[0] = -s;
616         data[2].data[2] = c;
617         return *(static_cast<MatrixType*>(this));
618 }
619
620 template<typename T, int Dimension>
621 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotationZ(const TypeReference angleRad)
622 {
623         *this = GetIdentity();
624         const T c = effects_cos(angleRad);
625         const T s = effects_sin(angleRad);
626         data[0].data[0] = c;
627         data[0].data[1] = -s;
628         data[1].data[0] = s;
629         data[1].data[1] = c;
630         return *(static_cast<MatrixType*>(this));
631 }
632
633 template<typename T, int Dimension>
634 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotationAxis(const Vector3& axis, const TypeReference angleRad)
635 {
636         return MakeRotationAxis(axis.data[0], axis.data[1], axis.data[2], angleRad);
637 }
638
639 template<typename T, int Dimension>
640 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotationAxis(const TypeReference xAxis, const TypeReference yAxis, const TypeReference zAxis, const TypeReference angleRad)
641 {
642         static const T t1(1.0f);
643
644         Vector3 v = Vector3(xAxis, yAxis, zAxis);
645         v.normalize();
646         const T sa = effects_sin(angleRad);
647         const T ca = effects_cos(angleRad);
648         const T inv_ca = t1 - ca;
649
650         *this = GetIdentity();
651
652         data[0].data[0] = ca + inv_ca * v.x() * v.x();
653         data[0].data[1] = inv_ca * v.x() * v.y() - sa * v.z();
654         data[0].data[2] = inv_ca * v.z() * v.x() + sa * v.y();
655
656         data[1].data[0] = inv_ca * v.x()* v.y()+ sa * v.z();
657         data[1].data[1] = ca + inv_ca * v.y()* v.y();
658         data[1].data[2] = inv_ca * v.y()* v.z()- sa * v.x();
659
660         data[2].data[0] = inv_ca * v.z()* v.x()- sa * v.y();
661         data[2].data[1] = inv_ca * v.y()* v.z()+ sa * v.x();
662         data[2].data[2] = ca + inv_ca * v.z()* v.z();
663
664         return *(static_cast<MatrixType*>(this));
665 }
666
667 template<typename T, int Dimension>
668 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotation(const Quaternion<T>& rotation)
669 {
670         *this = GetIdentity();
671         return SetRotation(rotation);
672 }
673
674 template<typename T, int Dimension>
675 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeRotation(const Matrix3& rotation)
676 {
677         *this = GetIdentity();
678         return SetRotation(rotation);
679 }
680
681 template<typename T, int Dimension>
682 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Rotate(const TypeReference xAngleRad, const TypeReference yAngleRad, const TypeReference zAngleRad, RotationOrder3 order)
683 {
684         return Rotate(MatrixType().MakeRotation(xAngleRad, yAngleRad, zAngleRad, order));
685 }
686
687 template<typename T, int Dimension>
688 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Rotate(const Vector3& anglesRad, RotationOrder3 order3)
689 {
690         return Rotate(MatrixType().MakeRotation(anglesRad, order3));
691 }
692
693 template<typename T, int Dimension>
694 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::RotateX(const TypeReference angleRad)
695 {
696         return Rotate(MatrixType().MakeRotationX(angleRad));
697 }
698
699 template<typename T, int Dimension>
700 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::RotateY(const TypeReference angleRad)
701 {
702         return Rotate(MatrixType().MakeRotationY(angleRad));
703 }
704
705 template<typename T, int Dimension>
706 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::RotateZ(const TypeReference angleRad)
707 {
708         return Rotate(MatrixType().MakeRotationZ(angleRad));
709 }
710
711 template<typename T, int Dimension>
712 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::RotateAxis(const Vector3& axis, const TypeReference angleRad)
713 {
714         return Rotate(MatrixType().MakeRotationAxis(axis, angleRad));
715 }
716
717 template<typename T, int Dimension>
718 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::RotateAxis(const TypeReference xAxis, const TypeReference yAxis, const TypeReference zAxis, const TypeReference angleRad)
719 {
720         return Rotate(MatrixType().MakeRotationAxis(xAxis, yAxis, zAxis, angleRad));
721 }
722
723 template<typename T, int Dimension>
724 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Rotate(const Quaternion<T>& rotation)
725 {
726         return Rotate(MatrixType().MakeRotation(rotation));
727 }
728
729 template<typename T, int Dimension>
730 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Rotate(const Matrix3& rotation)
731 {
732         const T _11 = rotation.data[0].data[0] * data[0].data[0] + rotation.data[0].data[1] * data[1].data[0] + rotation.data[0].data[2] * data[2].data[0];
733         const T _12 = rotation.data[0].data[0] * data[0].data[1] + rotation.data[0].data[1] * data[1].data[1] + rotation.data[0].data[2] * data[2].data[1];
734         const T _13 = rotation.data[0].data[0] * data[0].data[2] + rotation.data[0].data[1] * data[1].data[2] + rotation.data[0].data[2] * data[2].data[2];
735
736         const T _21 = rotation.data[1].data[0] * data[0].data[0] + rotation.data[1].data[1] * data[1].data[0] + rotation.data[1].data[2] * data[2].data[0];
737         const T _22 = rotation.data[1].data[0] * data[0].data[1] + rotation.data[1].data[1] * data[1].data[1] + rotation.data[1].data[2] * data[2].data[1];
738         const T _23 = rotation.data[1].data[0] * data[0].data[2] + rotation.data[1].data[1] * data[1].data[2] + rotation.data[1].data[2] * data[2].data[2];
739
740         const T _31 = rotation.data[2].data[0] * data[0].data[0] + rotation.data[2].data[1] * data[1].data[0] + rotation.data[2].data[2] * data[2].data[0];
741         const T _32 = rotation.data[2].data[0] * data[0].data[1] + rotation.data[2].data[1] * data[1].data[1] + rotation.data[2].data[2] * data[2].data[1];
742         const T _33 = rotation.data[2].data[0] * data[0].data[2] + rotation.data[2].data[1] * data[1].data[2] + rotation.data[2].data[2] * data[2].data[2];
743
744         data[0].data[0] = _11;
745         data[0].data[1] = _12;
746         data[0].data[2] = _13;
747         data[1].data[0] = _21;
748         data[1].data[1] = _22;
749         data[1].data[2] = _23;
750         data[2].data[0] = _31;
751         data[2].data[1] = _32;
752         data[2].data[2] = _33;
753
754         return *(static_cast<MatrixType*>(this));
755 }
756
757 template<typename T, int Dimension>
758 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Rotate(const MatrixType& rotation)
759 {
760         const T _11 = rotation.data[0].data[0] * data[0].data[0] + rotation.data[0].data[1] * data[1].data[0] + rotation.data[0].data[2] * data[2].data[0];
761         const T _12 = rotation.data[0].data[0] * data[0].data[1] + rotation.data[0].data[1] * data[1].data[1] + rotation.data[0].data[2] * data[2].data[1];
762         const T _13 = rotation.data[0].data[0] * data[0].data[2] + rotation.data[0].data[1] * data[1].data[2] + rotation.data[0].data[2] * data[2].data[2];
763
764         const T _21 = rotation.data[1].data[0] * data[0].data[0] + rotation.data[1].data[1] * data[1].data[0] + rotation.data[1].data[2] * data[2].data[0];
765         const T _22 = rotation.data[1].data[0] * data[0].data[1] + rotation.data[1].data[1] * data[1].data[1] + rotation.data[1].data[2] * data[2].data[1];
766         const T _23 = rotation.data[1].data[0] * data[0].data[2] + rotation.data[1].data[1] * data[1].data[2] + rotation.data[1].data[2] * data[2].data[2];
767
768         const T _31 = rotation.data[2].data[0] * data[0].data[0] + rotation.data[2].data[1] * data[1].data[0] + rotation.data[2].data[2] * data[2].data[0];
769         const T _32 = rotation.data[2].data[0] * data[0].data[1] + rotation.data[2].data[1] * data[1].data[1] + rotation.data[2].data[2] * data[2].data[1];
770         const T _33 = rotation.data[2].data[0] * data[0].data[2] + rotation.data[2].data[1] * data[1].data[2] + rotation.data[2].data[2] * data[2].data[2];
771
772         data[0].data[0] = _11;
773         data[0].data[1] = _12;
774         data[0].data[2] = _13;
775         data[1].data[0] = _21;
776         data[1].data[1] = _22;
777         data[1].data[2] = _23;
778         data[2].data[0] = _31;
779         data[2].data[1] = _32;
780         data[2].data[2] = _33;
781
782         return *(static_cast<MatrixType*>(this));
783 }
784
785 template<typename T, int Dimension>
786 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotation(const TypeReference xAngleRad, const TypeReference yAngleRad, const TypeReference zAngleRad, RotationOrder3 order)
787 {
788         return MatrixType().MakeRotation(xAngleRad, yAngleRad, zAngleRad, order);
789 }
790
791 template<typename T, int Dimension>
792 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotation(const Vector3& anglesRad, RotationOrder3 order)
793 {
794         return MatrixType().MakeRotation(anglesRad, order);
795 }
796
797 template<typename T, int Dimension>
798 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotationX(const TypeReference angleRad)
799 {
800         return MatrixType().MakeRotationX(angleRad);
801 }
802
803 template<typename T, int Dimension>
804 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotationY(const TypeReference angleRad)
805 {
806         return MatrixType().MakeRotationY(angleRad);
807 }
808
809 template<typename T, int Dimension>
810 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotationZ(const TypeReference angleRad)
811 {
812         return MatrixType().MakeRotationZ(angleRad);
813 }
814
815 template<typename T, int Dimension>
816 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotationAxis(const Vector3& axis, const TypeReference angleRad)
817 {
818         return MatrixType().MakeRotationAxis(axis, angleRad);
819 }
820
821 template<typename T, int Dimension>
822 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotationAxis(const TypeReference xAxis, const TypeReference yAxis, const TypeReference zAxis, const TypeReference angleRad)
823 {
824         return MatrixType().MakeRotationAxis(xAxis, yAxis, zAxis, angleRad);
825 }
826
827 template<typename T, int Dimension>
828 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotation(const Quaternion<T>& rotation)
829 {
830         return MatrixType().MakeRotation(rotation);
831 }
832
833 template<typename T, int Dimension>
834 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateRotation(const Matrix3& rotation)
835 {
836         return MatrixType().MakeRotation(rotation);
837 }
838
839 template<typename T, int Dimension>
840 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::GetRotationAngles(T& xAngleRad, T& yAngeRad, T& zAngleRad, unsigned int solutionNumber)
841 {
842         static const T t0(0.0f);
843         static const T t2(2.0f);
844         static const T pi(F_PI);
845
846         T& yaw = zAngleRad;
847         T& pitch = yAngeRad;
848         T& roll = xAngleRad;
849
850         struct Euler
851         {
852                 T yaw;
853                 T pitch;
854                 T roll;
855         };
856
857         Euler euler_out;
858         Euler euler_out2; //second solution
859
860         // Check that pitch is not at a singularity
861         if (EffectsAbs<float>(data[0].data[2]) >= T(1.0f))
862         {
863                 euler_out.yaw = t0;
864                 euler_out2.yaw = t0;
865
866                 // From difference of angles formula
867                 T delta = effects_atan2(data[0].data[0], data[2].data[0]);
868                 if (data[0].data[2] > 0)  //gimbal locked up
869                 {
870                         euler_out.pitch = pi / t2;
871                         euler_out2.pitch = pi / t2;
872                         euler_out.roll = euler_out.pitch + delta;
873                         euler_out2.roll = euler_out.pitch + delta;
874                 }
875                 else // gimbal locked down
876                 {
877                         euler_out.pitch = -pi / t2;
878                         euler_out2.pitch = -pi / t2;
879                         euler_out.roll = -euler_out.pitch + delta;
880                         euler_out2.roll = -euler_out.pitch + delta;
881                 }
882         }
883         else
884         {
885                 euler_out.pitch = - effects_asin(data[0].data[2]);
886                 euler_out2.pitch = pi - euler_out.pitch;
887
888                 euler_out.roll = effects_atan2(data[1].data[2] / effects_cos(euler_out.pitch), data[2].data[2] / effects_cos(euler_out.pitch));
889
890                 euler_out2.roll = effects_atan2(data[1].data[2] / effects_cos(euler_out2.pitch), data[2].data[2] / effects_cos(euler_out2.pitch));
891
892                 euler_out.yaw = effects_atan2(data[0].data[1] / effects_cos(euler_out.pitch), data[0].data[0] / effects_cos(euler_out.pitch));
893
894                 euler_out2.yaw = effects_atan2(data[0].data[1] / effects_cos(euler_out2.pitch), data[0].data[0] / effects_cos(euler_out2.pitch));
895         }
896
897         if (solutionNumber == 1)
898         {
899                 yaw = euler_out.yaw;
900                 pitch = euler_out.pitch;
901                 roll = euler_out.roll;
902         }
903         else
904         {
905                 yaw = euler_out2.yaw;
906                 pitch = euler_out2.pitch;
907                 roll = euler_out2.roll;
908         }
909
910         return *(static_cast<MatrixType*>(this));
911 }
912
913 template<typename T, int Dimension>
914 Quaternion<T> MatrixTraits<T, Dimension>::GetQuaternion(void) const
915 {
916         Quaternion<T> result;
917         return GetQuaternion(result);
918 }
919
920 template<typename T, int Dimension>
921 Quaternion<T>& MatrixTraits<T, Dimension>::GetQuaternion(Quaternion<T>& rotation) const
922 {
923         static const T t0(0.0f);
924         static const T thalf(0.5f);
925         static const T t1(1.0f);
926
927         Quaternion<T>& result = rotation;
928
929         T tr = data[0].data[0] + data[1].data[1] + data[2].data[2]; // trace of martix
930         if (tr > t0)
931         {   // if trace positive than "w" is biggest component
932                 result.Set(data[2].data[1] - data[1].data[2], data[0].data[2] - data[2].data[0], data[1].data[0] - data[0].data[1], tr + t1);
933                 result *= (thalf / effects_sqrt(result.w));     // "w" contain the "norm * 4"
934
935         }
936         else                 // Some of vector components is bigger
937         {
938                 if ((data[0].data[0] > data[1].data[1]) && (data[0].data[0] > data[2].data[2]))
939                 {
940                         result.Set(t1 + data[0].data[0] - data[1].data[1] - data[2].data[2], data[0].data[1] + data[1].data[0], data[0].data[2] + data[2].data[0], data[2].data[1] - data[1].data[2]);
941                         result *= (thalf / effects_sqrt(result.x));
942
943                 }
944                 else
945                 {
946                         if (data[1].data[1] > data[2].data[2])
947                         {
948                                 result.Set(data[0].data[1] + data[1].data[0], t1 + data[1].data[1] - data[0].data[0] - data[2].data[2], data[1].data[2] + data[2].data[1], data[0].data[2] - data[2].data[0]);
949                                 result *= (thalf / effects_sqrt(result.y));
950
951                         }
952                         else
953                         {
954                                 result.Set(data[0].data[2] + data[2].data[0], data[1].data[2] + data[2].data[1], t1 + data[2].data[2] - data[0].data[0] - data[1].data[1], data[1].data[0] - data[0].data[1]);
955                                 result *= (thalf / effects_sqrt(result.z));
956
957                         }
958                 }
959         }
960
961         return result.normalize();
962 }
963
964 template<typename T, int Dimension>
965 typename MatrixTraits<T, Dimension>::Matrix3 MatrixTraits<T, Dimension>::GetRotation(void) const
966 {
967         return Matrix3(data[0].data[0], data[0].data[1], data[0].data[2],
968                                           data[1].data[0], data[1].data[1], data[1].data[2],
969                                           data[2].data[0], data[2].data[1], data[2].data[2]);
970 }
971
972 template<typename T, int Dimension>
973 typename MatrixTraits<T, Dimension>::Matrix3& MatrixTraits<T, Dimension>::GetRotation(Matrix3& rotation) const
974 {
975         return rotation = GetRotation();
976 }
977
978 template<typename T, int Dimension>
979 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeScale(const TypeReference x, const TypeReference y, const TypeReference z)
980 {
981         *this = GetIdentity();
982         return SetScale(x, y, z);
983 }
984
985 template<typename T, int Dimension>
986 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetScale(const TypeReference x, const TypeReference y, const TypeReference z)
987 {
988         data[0].data[0] = x;
989         data[1].data[1] = y;
990         data[2].data[2] = z;
991
992         data[0].data[1] = data[0].data[2] = data[1].data[0] = data[1].data[2] = data[2].data[0] = data[2].data[1] = T(0.0f);
993         return *(static_cast<MatrixType*>(this));
994 }
995
996 template<typename T, int Dimension>
997 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateScale(const TypeReference x, const TypeReference y, const TypeReference z)
998 {
999         return MatrixType().MakeScale(x, y, z);
1000 }
1001
1002 template<typename T, int Dimension>
1003 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Scale(const TypeReference x, const TypeReference y, const TypeReference z)
1004 {
1005         data[0].data[0] *= x;
1006         data[1].data[0] *= y;
1007         data[2].data[0] *= z;
1008         data[0].data[1] *= x;
1009         data[1].data[1] *= y;
1010         data[2].data[1] *= z;
1011         data[0].data[2] *= x;
1012         data[1].data[2] *= y;
1013         data[2].data[2] *= z;
1014
1015         return *(static_cast<MatrixType*>(this));
1016 }
1017
1018 template<typename T, int Dimension>
1019 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetTranslation(const TypeReference x, const TypeReference y, const TypeReference z)
1020 {
1021         data[0].data[3] = x;
1022         data[1].data[3] = y;
1023         data[2].data[3] = z;
1024         return *(static_cast<MatrixType*>(this));
1025 }
1026
1027 template<typename T, int Dimension>
1028 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::SetTranslation(const Vector3& tran)
1029 {
1030         return SetTranslation(tran.data[0], tran.data[1], tran.data[2]);
1031 }
1032
1033 template<typename T, int Dimension>
1034 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeTranslation(const TypeReference x, const TypeReference y, const TypeReference z)
1035 {
1036         *this = GetIdentity();
1037         return SetTranslation(x, y, z);
1038 }
1039
1040 template<typename T, int Dimension>
1041 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeTranslation(const Vector3& tran)
1042 {
1043         return MakeTranslation(tran.data[0], tran.data[1], tran.data[2]);
1044 }
1045
1046 template<typename T, int Dimension>
1047 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Translate(const TypeReference x, const TypeReference y, const TypeReference z)
1048 {
1049         data[0].data[3] += x;
1050         data[1].data[3] += y;
1051         data[2].data[3] += z;
1052         return *(static_cast<MatrixType*>(this));
1053 }
1054
1055 template<typename T, int Dimension>
1056 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::Translate(const Vector3& tran)
1057 {
1058         return Translate(tran.data[0], tran.data[1], tran.data[2]);
1059 }
1060
1061 template<typename T, int Dimension>
1062 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateTranslation(const TypeReference x, const TypeReference y, const TypeReference z)
1063 {
1064         return MatrixType().MakeTranslation(x, y, z);
1065 }
1066
1067 template<typename T, int Dimension>
1068 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateTranslation(const Vector3& tran)
1069 {
1070         return MatrixType().MakeTranslation(tran);
1071 }
1072
1073 template<typename T, int Dimension>
1074 typename MatrixTraits<T, Dimension>::Vector3 MatrixTraits<T, Dimension>::GetTranslation(void) const
1075 {
1076         return Vector3().Set(data[0].data[3], data[1].data[3], data[2].data[3]);
1077 }
1078
1079 template<typename T, int Dimension>
1080 typename MatrixTraits<T, Dimension>::VectorType MatrixTraits<T, Dimension>::GetFullTranslation(void) const
1081 {
1082         return VectorType().Set(data[0].data[3], data[1].data[3], data[2].data[3], data[3].data[3]);
1083 }
1084
1085 template<typename T, int Dimension>
1086 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeLookAtLH(const Vector3& eye, const Vector3& at, const Vector3& up)
1087 {
1088         static const T t0(0.0f);
1089         static const T t1(1.0f);
1090
1091         Vector3 z((at - eye).normalize());
1092         Vector3 x;
1093         x.makeCrossed(up, z).normalize();
1094         Vector3 y;
1095         y.makeCrossed(z, x);
1096
1097         data[0].data[0] = x.x();
1098         data[1].data[0] = y.x();
1099         data[2].data[0] = z.x();
1100         data[3].data[0] = t0;
1101         data[0].data[1] = x.y();
1102         data[1].data[1] = y.y();
1103         data[2].data[1] = z.y();
1104         data[3].data[1] = t0;
1105         data[0].data[2] = x.z();
1106         data[1].data[2] = y.z();
1107         data[2].data[2] = z.z();
1108         data[3].data[2] = t0;
1109
1110         data[0].data[3] = -x.dot(eye);
1111         data[1].data[3] = -y.dot(eye);
1112         data[2].data[3] = -z.dot(eye);
1113         data[3].data[3] = t1;
1114
1115         return *(static_cast<MatrixType*>(this));
1116 }
1117
1118 template<typename T, int Dimension>
1119 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeLookAtRH(const Vector3& eye, const Vector3& at, const Vector3& up)
1120 {
1121         static const T t0(0.0f);
1122         static const T t1(1.0f);
1123
1124         Vector3 z((eye - at).normalize());
1125         Vector3 x;
1126         x.makeCrossed(up, z).normalize();
1127         Vector3 y;
1128         y.makeCrossed(z, x);
1129
1130         data[0].data[0] = x.x();
1131         data[1].data[0] = y.x();
1132         data[2].data[0] = z.x();
1133         data[3].data[0] = t0;
1134         data[0].data[1] = x.y();
1135         data[1].data[1] = y.y();
1136         data[2].data[1] = z.y();
1137         data[3].data[1] = t0;
1138         data[0].data[2] = x.z();
1139         data[1].data[2] = y.z();
1140         data[2].data[2] = z.z();
1141         data[3].data[2] = t0;
1142
1143         data[0].data[3] = -x.dot(eye);
1144         data[1].data[3] = -y.dot(eye);
1145         data[2].data[3] = -z.dot(eye);
1146         data[3].data[3] = t1;
1147
1148         return *(static_cast<MatrixType*>(this));
1149 }
1150
1151 template<typename T, int Dimension>
1152 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeOrthoRH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar)
1153 {
1154         static const T t2(2.0f);
1155
1156         *this = GetIdentity();
1157         data[0].data[0] = t2 / width;
1158         data[1].data[1] = t2 / height;
1159         data[2].data[2] = t2 / (zNear - zFar);
1160         data[2].data[3] = (zFar + zNear) / (zNear - zFar);
1161         return *(static_cast<MatrixType*>(this));
1162 }
1163
1164 template<typename T, int Dimension>
1165 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeOrthoLH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar)
1166 {
1167         MakeOrthoRH(width, height, zNear, zFar);
1168         data[2].data[2] = -data[2].data[2];
1169         return *(static_cast<MatrixType*>(this));
1170 }
1171
1172 template<typename T, int Dimension>
1173 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeOrthoRH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar)
1174 {
1175         static const T t2(2.0f);
1176
1177         *this = GetIdentity();
1178
1179         data[0].data[0] = t2 / (right - left);
1180         data[1].data[1] = t2 / (top - bottom);
1181         data[2].data[2] = t2 / (zNear - zFar);
1182
1183         data[0].data[3] = (left + right) / (left - right);
1184         data[1].data[3] = (top + bottom) / (bottom - top);
1185         data[2].data[3] = (zFar + zNear) / (zNear - zFar);
1186
1187         return *(static_cast<MatrixType*>(this));
1188 }
1189
1190 template<typename T, int Dimension>
1191 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakeOrthoLH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar)
1192 {
1193         MakeOrthoRH(left, right, top, bottom, zNear, zFar);
1194         data[2].data[2] = -data[2].data[2];
1195         return *(static_cast<MatrixType*>(this));
1196 }
1197
1198 template<typename T, int Dimension>
1199 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakePerspectiveLH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar)
1200 {
1201         MakePerspectiveRH(left, right, top, bottom, zNear, zFar);
1202         data[2].data[2] = -data[2].data[2];
1203         return *(static_cast<MatrixType*>(this));
1204 }
1205
1206 template<typename T, int Dimension>
1207 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakePerspectiveRH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar)
1208 {
1209         static const T t0(0.0f);
1210         static const T t1(1.0f);
1211         static const T t2(2.0f);
1212
1213         *this = GetIdentity();
1214         data[0].data[0] = t2 * zNear / (right - left);
1215         data[1].data[1] = t2 * zNear / (top - bottom);
1216         data[2].data[2] = (zFar + zNear) / (zNear - zFar);
1217         data[3].data[3] = t0;
1218
1219         data[3].data[2] = -t1;
1220         data[0].data[2] = (left + right) / (right - left);
1221         data[1].data[2] = (top + bottom) / (top - bottom);
1222         data[2].data[3] = t2 * zNear * zFar / (zNear - zFar);
1223
1224         return *(static_cast<MatrixType*>(this));
1225 }
1226
1227 template<typename T, int Dimension>
1228 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakePerspectiveLH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar)
1229 {
1230         MakePerspectiveRH(width, height, zNear, zFar);
1231         data[2].data[2] = -data[2].data[2];
1232         return *(static_cast<MatrixType*>(this));
1233 }
1234
1235 template<typename T, int Dimension>
1236 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakePerspectiveRH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar)
1237 {
1238         static const T t0(0.0f);
1239         static const T t1(1.0f);
1240         static const T t2(2.0f);
1241
1242         *this = GetIdentity();
1243         data[0].data[0] = t2 * zNear / width;
1244         data[1].data[1] = t2 * zNear / height;
1245         data[2].data[2] = (zFar + zNear) / (zNear - zFar);
1246
1247         data[2].data[3] = t2 * zNear * zFar / (zNear - zFar);
1248         data[3].data[2] = -t1;
1249         data[3].data[3] = t0;
1250         return *(static_cast<MatrixType*>(this));
1251 }
1252
1253 template<typename T, int Dimension>
1254 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakePerspectiveFovLH(const TypeReference fovY, const TypeReference aspect, const TypeReference zNear, const TypeReference zFar)
1255 {
1256         MakePerspectiveFovRH(fovY, aspect, zNear, zFar);
1257         data[2].data[2] = -data[2].data[2];
1258         return *(static_cast<MatrixType*>(this));
1259 }
1260
1261 template<typename T, int Dimension>
1262 typename MatrixTraits<T, Dimension>::MatrixType& MatrixTraits<T, Dimension>::MakePerspectiveFovRH(const TypeReference fovY, const TypeReference aspect, const TypeReference zNear, const TypeReference zFar)
1263 {
1264         static const T t0(0.0f);
1265         static const T t1(1.0f);
1266         static const T t2(2.0f);
1267
1268         *this = GetIdentity();
1269         data[1].data[1] = t1 / tan(fovY / t2);
1270         data[0].data[0] = data[1].data[1] / aspect;
1271         data[2].data[2] = (zFar + zNear) / (zNear - zFar);
1272
1273         data[3].data[2] = -t1;
1274         data[2].data[3] = t2 * (zNear * zFar / (zNear - zFar));
1275         data[3].data[3] = t0;
1276         return *(static_cast<MatrixType*>(this));
1277 }
1278
1279 template<typename T, int Dimension>
1280 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateLookAtLH(const Vector3& eye, const Vector3& at, const Vector3& up)
1281 {
1282         return MatrixType().MakeLookAtLH(eye, at, up);
1283 }
1284
1285 template<typename T, int Dimension>
1286 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateLookAtRH(const Vector3& eye, const Vector3& at, const Vector3& up)
1287 {
1288         return MatrixType().MakeLookAtRH(eye, at, up);
1289 }
1290
1291 template<typename T, int Dimension>
1292 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateOrthoRH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar)
1293 {
1294         return MatrixType().MakeOrthoRH(width, height, zNear, zFar);
1295 }
1296
1297 template<typename T, int Dimension>
1298 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateOrthoLH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar)
1299 {
1300         return MatrixType().MakeOrthoLH(width, height, zNear, zFar);
1301 }
1302
1303 template<typename T, int Dimension>
1304 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateOrthoRH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar)
1305 {
1306         return MatrixType().MakeOrthoRH(left, right, top, bottom, zNear, zFar);
1307 }
1308
1309 template<typename T, int Dimension>
1310 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreateOrthoLH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar)
1311 {
1312         return MatrixType().MakeOrthoLH(left, right, top, bottom, zNear, zFar);
1313 }
1314
1315 template<typename T, int Dimension>
1316 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreatePerspectiveLH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar)
1317 {
1318         return MatrixType().MakePerspectiveLH(left, right, top, bottom, zNear, zFar);
1319 }
1320
1321 template<typename T, int Dimension>
1322 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreatePerspectiveRH(const TypeReference left, const TypeReference right, const TypeReference top, const TypeReference bottom, const TypeReference zNear, const TypeReference zFar)
1323 {
1324         return MatrixType().MakePerspectiveRH(left, right, top, bottom, zNear, zFar);
1325 }
1326
1327 template<typename T, int Dimension>
1328 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreatePerspectiveLH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar)
1329 {
1330         return MatrixType().MakePerspectiveLH(width, height, zNear, zFar);
1331 }
1332
1333 template<typename T, int Dimension>
1334 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreatePerspectiveRH(const TypeReference width, const TypeReference height, const TypeReference zNear, const TypeReference zFar)
1335 {
1336         return MatrixType().MakePerspectiveRH(width, height, zNear, zFar);
1337 }
1338
1339 template<typename T, int Dimension>
1340 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreatePerspectiveFovLH(const TypeReference fovY, const TypeReference aspect, const TypeReference zNear, const TypeReference zFar)
1341 {
1342         return MatrixType().MakePerspectiveFovLH(fovY, aspect, zNear, zFar);
1343 }
1344
1345 template<typename T, int Dimension>
1346 typename MatrixTraits<T, Dimension>::MatrixType MatrixTraits<T, Dimension>::CreatePerspectiveFovRH(const TypeReference fovY, const TypeReference aspect, const TypeReference zNear, const TypeReference zFar)
1347 {
1348         return MatrixType().MakePerspectiveFovRH(fovY, aspect, zNear, zFar);
1349 }
1350
1351 template<typename T, int Dimension>
1352 bool MatrixTraits<T, Dimension>::GetOrthoParamsRH(T& left, T& right, T& top, T& bottom, T& zNear, T& zFar) const
1353 {
1354         static const T t1(1.0f);
1355
1356         zNear = (data[2].data[3] + t1) / data[2].data[2];
1357         zFar = (data[2].data[3] - t1) / data[2].data[2];
1358
1359         left = -(t1 + data[0].data[3]) / data[0].data[0];
1360         right = (t1 - data[0].data[3]) / data[0].data[0];
1361
1362         bottom = -(t1 + data[1].data[3]) / data[1].data[1];
1363         top = (t1 - data[1].data[3]) / data[1].data[1];
1364
1365         return true;
1366 }
1367
1368 template<typename T, int Dimension>
1369 bool MatrixTraits<T, Dimension>::GetPerspectiveParamsRH(T& left, T& right, T& top, T& bottom, T& zNear, T& zFar) const
1370 {
1371         static const T t1(1.0f);
1372
1373         zNear = data[2].data[3] / (data[2].data[2] - t1);
1374         zFar = data[2].data[3] / (t1 + data[2].data[2]);
1375
1376         left = zNear * (data[0].data[2] - t1) / data[0].data[0];
1377         right = zNear * (t1 + data[0].data[2]) / data[0].data[0];
1378
1379         top = zNear * (t1 + data[1].data[2]) / data[1].data[1];
1380         bottom = zNear * (data[1].data[2] - t1) / data[1].data[1];
1381
1382         return true;
1383 }
1384
1385 template<typename T, int Dimension>
1386 bool MatrixTraits<T, Dimension>::GetPerspectiveParamsRH(T& fovY, T& aspect, T& zNear, T& zFar) const
1387 {
1388         T left, right, bottom, top;
1389         bool result = GetPerspectiveParamsRH(left, right, top, bottom, zNear, zFar);
1390         if (result)
1391         {
1392                 T height = top - bottom;
1393                 T width = right - left;
1394                 aspect = width / height;
1395                 fovY = T(2.0f) * effects_atan(height / zNear * T(0.5f));
1396         }
1397         return result;
1398 }
1399
1400 template<typename T, int Dimension>
1401 bool MatrixTraits<T, Dimension>::GetViewParams(Vector3& position, Vector3& direction, Vector3& up, Vector3& right) const
1402 {
1403         right.Set(data[0].data[0], data[0].data[1], data[0].data[2]);
1404         up.Set(data[1].data[0], data[1].data[1], data[1].data[2]);
1405         direction.Set(-data[2].data[0], -data[2].data[1], -data[2].data[2]);
1406         position = direction * data[2].data[3] - right * data[0].data[3] - up * data[1].data[3];
1407         return true;
1408 }
1409
1410
1411 }}}}} //Tizen::Ui::Effects::_Renderer::Math
1412
1413 #endif //_FUI_EFFECTS_INTERNAL_RENDERER_MATH_MATRIX_TRAITS_H_