8391302aba0c8c12f7261fcb10e13daedcb72feb
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Quaternion.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <iostream>
18 #include <sstream>
19
20 #include <stdlib.h>
21 #include <dali/dali.h>
22 #include <dali-test-suite-utils.h>
23
24 using namespace Dali;
25
26
27 void utc_dali_quaternion_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31
32 void utc_dali_quaternion_cleanup(void)
33 {
34   test_return_value = TET_PASS;
35 }
36
37
38 int UtcDaliQuaternionCtor01(void)
39 {
40   TestApplication application; // Reset all test adapter return codes
41   Quaternion r;
42   DALI_TEST_EQUALS(r.AsVector().w,  1.0f, TEST_LOCATION);
43   DALI_TEST_EQUALS(r.AsVector().x,  0.0f, TEST_LOCATION);
44   DALI_TEST_EQUALS(r.AsVector().y,  0.0f, TEST_LOCATION);
45   DALI_TEST_EQUALS(r.AsVector().z,  0.0f, TEST_LOCATION);
46   END_TEST;
47 }
48
49 int UtcDaliQuaternionCtor02(void)
50 {
51   TestApplication application; // Reset all test adapter return codes
52
53   Quaternion r(M_PI/2.0f, Vector4(1.0f, 2.0f, 3.0f, M_PI/3.0f));
54
55   // This will be normalised:
56   DALI_TEST_EQUALS(r.AsVector().w,  0.707f, 0.001, TEST_LOCATION);
57   DALI_TEST_EQUALS(r.AsVector().x,  0.189f, 0.001, TEST_LOCATION);
58   DALI_TEST_EQUALS(r.AsVector().y,  0.378f, 0.001, TEST_LOCATION);
59   DALI_TEST_EQUALS(r.AsVector().z,  0.567f, 0.001, TEST_LOCATION);
60   END_TEST;
61 }
62
63
64 int UtcDaliQuaternionCtor03(void)
65 {
66   TestApplication application; // Reset all test adapter return codes
67
68   // Test from euler angles
69   Quaternion e1(Radian(Degree(45)), 0.0f, 0.0f);
70   Vector4 r1(0.383f, 0.0f, 0.0f, 0.924f);
71
72   Quaternion e2(0.0f, Radian(Degree(75)), 0.0f);
73   Vector4 r2(0.0f, 0.609f, 0.0f, 0.793f);
74
75   Quaternion e3(0.0f, 0.0f, Radian(Degree(135)));
76   Vector4 r3(0.0f, 0.0f, 0.924f, 0.383f);
77
78   Quaternion e4(Radian(Degree(71)), Radian(Degree(36)), Radian(Degree(27)));
79   Vector4 r4(0.478f, 0.374f, 0.006f, 0.795f);
80
81   Quaternion e5(Radian(Degree(-31)), Radian(Degree(-91)), Radian(Degree(-173)));
82   Vector4 r5(-0.697f, 0.145f, -0.686f, -0.149f);
83
84   DALI_TEST_EQUALS(e1.AsVector(), r1, 0.001, TEST_LOCATION);
85   DALI_TEST_EQUALS(e2.AsVector(), r2, 0.001, TEST_LOCATION);
86   DALI_TEST_EQUALS(e3.AsVector(), r3, 0.001, TEST_LOCATION);
87   DALI_TEST_EQUALS(e4.AsVector(), r4, 0.001, TEST_LOCATION);
88   DALI_TEST_EQUALS(e5.AsVector(), r5, 0.001, TEST_LOCATION);
89   END_TEST;
90 }
91
92
93 int UtcDaliQuaternionFromAxisAngle(void)
94 {
95   TestApplication application; // Reset all test adapter return codes
96
97   Quaternion q = Quaternion::FromAxisAngle(Vector4(1.0f, 2.0f, 3.0f, M_PI/3.0f), M_PI/2.0f);
98
99   Quaternion r(0.707f, 0.189f, 0.378f, 0.567f);
100
101   DALI_TEST_EQUALS(q, r, 0.001, TEST_LOCATION);
102   END_TEST;
103 }
104
105 int UtcDaliQuaternionToAxisAngle01(void)
106 {
107   TestApplication application; // Reset all test adapter return codes
108   Quaternion q(0.932f, 1.1f, 3.4f, 2.7f);
109   float angle;
110   Vector3 axis;
111   bool converted = q.ToAxisAngle(axis, angle);
112   DALI_TEST_EQUALS(converted, true, TEST_LOCATION);
113   DALI_TEST_EQUALS(angle,  0.74f, 0.01f, TEST_LOCATION);
114   DALI_TEST_EQUALS(axis.x, 3.03f, 0.01f, TEST_LOCATION);
115   DALI_TEST_EQUALS(axis.y, 9.38f, 0.01f, TEST_LOCATION);
116   DALI_TEST_EQUALS(axis.z, 7.45f, 0.01f, TEST_LOCATION);
117   END_TEST;
118 }
119
120 int UtcDaliQuaternionToAxisAngle02(void)
121 {
122   TestApplication application; // Reset all test adapter return codes
123   Quaternion q(0.932f, 1.1f, 3.4f, 2.7f);
124   float angle;
125   Vector4 axis;
126   bool converted = q.ToAxisAngle(axis, angle);
127   DALI_TEST_EQUALS(converted, true, TEST_LOCATION);
128   DALI_TEST_EQUALS(angle,  0.74f, 0.01f, TEST_LOCATION);
129   DALI_TEST_EQUALS(axis.x, 3.03f, 0.01f, TEST_LOCATION);
130   DALI_TEST_EQUALS(axis.y, 9.38f, 0.01f, TEST_LOCATION);
131   DALI_TEST_EQUALS(axis.z, 7.45f, 0.01f, TEST_LOCATION);
132   DALI_TEST_EQUALS(axis.w, 0.0f, 0.01f, TEST_LOCATION);
133   END_TEST;
134 }
135
136
137 int UtcDaliQuaternionToAxisAngle03(void)
138 {
139   TestApplication application; // Reset all test adapter return codes
140   Quaternion q(1, 2, 3, 4);
141   float angle;
142   Vector3 axis;
143   bool converted = q.ToAxisAngle(axis, angle);
144   DALI_TEST_EQUALS(converted, false, TEST_LOCATION);
145   DALI_TEST_EQUALS(angle,  0.0f, 0.01f, TEST_LOCATION);
146   DALI_TEST_EQUALS(axis.x, 0.0f, 0.01f, TEST_LOCATION);
147   DALI_TEST_EQUALS(axis.y, 0.0f, 0.01f, TEST_LOCATION);
148   DALI_TEST_EQUALS(axis.z, 0.0f, 0.01f, TEST_LOCATION);
149   END_TEST;
150 }
151
152 int UtcDaliQuaternionToAxisAngle04(void)
153 {
154   TestApplication application; // Reset all test adapter return codes
155   Quaternion q(1, 2, 3, 4);
156   float angle;
157   Vector4 axis;
158   bool converted = q.ToAxisAngle(axis, angle);
159   DALI_TEST_EQUALS(converted, false, TEST_LOCATION);
160   DALI_TEST_EQUALS(angle,  0.0f, 0.01f, TEST_LOCATION);
161   DALI_TEST_EQUALS(axis.x, 0.0f, 0.01f, TEST_LOCATION);
162   DALI_TEST_EQUALS(axis.y, 0.0f, 0.01f, TEST_LOCATION);
163   DALI_TEST_EQUALS(axis.z, 0.0f, 0.01f, TEST_LOCATION);
164   DALI_TEST_EQUALS(axis.w, 0.0f, 0.01f, TEST_LOCATION);
165   END_TEST;
166 }
167
168
169
170 int UtcDaliQuaternionEulerAngles(void)
171 {
172   TestApplication application; // Reset all test adapter return codes
173
174   Quaternion q1(0.924f, 0.383f, 0.0f, 0.0f);
175   Vector4 r1(Radian(Degree(45)), 0.0f, 0.0f, 0.0f);
176
177   Quaternion q2(0.793f, 0.0f, 0.609f, 0.0f);
178   Vector4 r2(0.0f, Radian(Degree(75)), 0.0f, 0.0f);
179
180   Quaternion q3(0.383f, 0.0f, 0.0f, 0.924f);
181   Vector4 r3(0.0f, 0.0f, Radian(Degree(135)), 0.0f);
182
183   Quaternion q4(0.795f, 0.478f, 0.374f, 0.006f);
184   Vector4 r4(Radian(Degree(71)), Radian(Degree(36)), Radian(Degree(27)), 0.0f);
185
186   Quaternion q5( -0.149f, -0.697f, 0.145f, -0.686f);
187   Vector4 r5(Radian(Degree(148.0)), Radian(Degree(-88.2)), Radian(Degree(8.0)), 0.0f);
188
189   DALI_TEST_EQUALS(q1.EulerAngles(), r1, 0.001, TEST_LOCATION);
190   DALI_TEST_EQUALS(q2.EulerAngles(), r2, 0.001, TEST_LOCATION);
191   DALI_TEST_EQUALS(q3.EulerAngles(), r3, 0.001, TEST_LOCATION);
192   DALI_TEST_EQUALS(q4.EulerAngles(), r4, 0.01,  TEST_LOCATION);
193   DALI_TEST_EQUALS(q5.EulerAngles(), r5, 0.01,  TEST_LOCATION);
194   END_TEST;
195 }
196
197
198 int UtcDaliQuaternionToMatrix01(void)
199 {
200   TestApplication application; // Reset all test adapter return codes
201
202   Quaternion q(0.69813, Vector4(1.0f, 0.0f, 0.0f, 0.0f)); // 40 degree rotation around X axis
203
204   // Result calculated using a different maths library (with appropriate row/col ordering)
205
206   float els[] = { 1.0f,  0.0f,   0.0f,  0.0f,
207                   0.0f,  0.766f, 0.643f, 0.0f,
208                   0.0f, -0.643f, 0.766f, 0.0f,
209                   0.0f,  0.0f,   0.0f,  1.0f };
210   Matrix mRes(els);
211   Matrix m(q);
212
213   DALI_TEST_EQUALS(m, mRes, 0.01, TEST_LOCATION);
214   END_TEST;
215 }
216
217 int UtcDaliQuaternionToMatrix02(void)
218 {
219   TestApplication application; // Reset all test adapter return codes
220
221   // rotation around arbitrary axis
222   Quaternion q2(-1.23918f, Vector4(7.0f, -13.0f, 11.0f, 0.0f));
223
224   float els[] = {  0.423f, -0.746f, -0.514f,  0.00f,
225                    0.384f,  0.662f, -0.644f,  0.00f,
226                    0.821f,  0.075f,  0.566f,  0.00f,
227                    0.000f,  0.000f,  0.000f,  1.00f };
228   Matrix mRes2(els);
229
230   Matrix m2(q2);
231
232   DALI_TEST_EQUALS(m2, mRes2, 0.01, TEST_LOCATION);
233   END_TEST;
234 }
235
236
237 int UtcDaliQuaternionFromMatrix01(void)
238 {
239   TestApplication application; // Reset all test adapter return codes
240
241   // IDENTITY rotation
242   Quaternion q;
243
244   Matrix m(q);     // Convert to matrix
245
246   Quaternion q2(m); // and back to a quaternion
247
248   DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
249   DALI_TEST_EQUALS(m, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
250   END_TEST;
251 }
252
253 int UtcDaliQuaternionFromMatrix02(void)
254 {
255   TestApplication application; // Reset all test adapter return codes
256
257   // Create an arbitrary forward vector
258   for( float x=-1.0f; x<=1.0f; x+=0.1f )
259   {
260     for( float y=-1.0f; y<1.0f; y+=0.1f )
261     {
262       for( float z=-1.0f; z<1.0f; z+=0.1f )
263       {
264         Vector3 vForward(x, y, z);
265         vForward.Normalize();
266
267         // Construct an up vector from a sideways move
268         Vector3 vSide;
269         Vector3 vUp = vForward.Cross(Vector3(vForward.x+1.0f, vForward.y, vForward.z));
270         if(vUp.Length() > 0.01 )
271         {
272           vUp.Normalize();
273           vSide = vUp.Cross(vForward);
274           vSide.Normalize();
275         }
276         else
277         {
278           vSide = vForward.Cross(Vector3(vForward.x, vForward.y+1.0f, vForward.z));
279           vSide.Normalize();
280           vUp = vForward.Cross(vSide);
281           vUp.Normalize();
282         }
283
284         // Generate a matrix, and then a quaternion from it
285         Matrix rotMatrix(Matrix::IDENTITY);
286         rotMatrix.SetXAxis(vSide);
287         rotMatrix.SetYAxis(vUp);
288         rotMatrix.SetZAxis(vForward);
289         Quaternion q( rotMatrix );
290
291         // Generate a matrix from the quaternion, check they are the same
292         Matrix resultMatrix(q);
293         DALI_TEST_EQUALS(resultMatrix, rotMatrix, 0.001f, TEST_LOCATION);
294
295         // Rotate an arbitrary vector by both quaternion and rotation matrix,
296         // check the result is the same
297
298         Vector4 aVector(-2.983f, -3.213f, 8.2239f, 1.0f);
299         Vector3 aVectorRotatedByQ = q.Rotate(Vector3(aVector));
300         Vector4 aVectorRotatedByR = rotMatrix*aVector;
301         DALI_TEST_EQUALS(aVectorRotatedByQ, Vector3(aVectorRotatedByR), 0.001f, TEST_LOCATION);
302       }
303     }
304   }
305   END_TEST;
306 }
307
308 int UtcDaliQuaternionFromAxes01(void)
309 {
310   TestApplication application; // Reset all test adapter return codes
311
312   Vector3 xAxis( Vector3::XAXIS );
313   Vector3 yAxis( Vector3::YAXIS );
314   Vector3 zAxis( Vector3::ZAXIS );
315
316   Quaternion q1( xAxis, yAxis, zAxis);
317
318   DALI_TEST_EQUALS( q1, Quaternion::IDENTITY, TEST_LOCATION );
319
320   xAxis = Vector3( 1.0f, 1.0f, 0.0f );
321   xAxis.Normalize();
322   yAxis = Vector3( -1.0f, 1.0f, 0.0f ); // 45 degrees anticlockwise (+ve) around z
323   yAxis.Normalize();
324   zAxis = xAxis.Cross(yAxis);
325   zAxis.Normalize();
326   Quaternion q2( xAxis, yAxis, zAxis );
327
328   DALI_TEST_EQUALS( q2, Quaternion(Radian(Degree(45)), Vector3::ZAXIS), 0.001f, TEST_LOCATION);
329   END_TEST;
330 }
331
332
333 int UtcDaliQuaternionFromAxes02(void)
334 {
335   TestApplication application; // Reset all test adapter return codes
336
337   // Create an arbitrary forward vector
338   for( float x=-1.0f; x<=1.0f; x+=0.1f )
339   {
340     for( float y=-1.0f; y<1.0f; y+=0.1f )
341     {
342       for( float z=-1.0f; z<1.0f; z+=0.1f )
343       {
344         Vector3 vForward(x, y, z);
345         vForward.Normalize();
346
347         // Construct an up vector from a sideways move
348         Vector3 vSide;
349         Vector3 vUp = vForward.Cross(Vector3(vForward.x+1.0f, vForward.y, vForward.z));
350         if(vUp.Length() > 0.01 )
351         {
352           vUp.Normalize();
353           vSide = vUp.Cross(vForward);
354           vSide.Normalize();
355         }
356         else
357         {
358           vSide = vForward.Cross(Vector3(vForward.x, vForward.y+1.0f, vForward.z));
359           vSide.Normalize();
360           vUp = vForward.Cross(vSide);
361           vUp.Normalize();
362         }
363
364         // Generate a quaternion
365         Quaternion q( vSide, vUp, vForward );
366
367         Matrix rotMatrix;
368         rotMatrix.SetXAxis(vSide);
369         rotMatrix.SetYAxis(vUp);
370         rotMatrix.SetZAxis(vForward);
371
372         // Generate a matrix from the quaternion, check they are the same
373         Matrix m(q);
374         DALI_TEST_EQUALS(m.GetXAxis(), vSide, 0.001f, TEST_LOCATION);
375         DALI_TEST_EQUALS(m.GetYAxis(), vUp, 0.001f, TEST_LOCATION);
376         DALI_TEST_EQUALS(m.GetZAxis(), vForward, 0.001f, TEST_LOCATION);
377
378         // Rotate an arbitrary vector by both quaternion and rotation matrix,
379         // check the result is the same
380
381         Vector4 aVector(2.043f, 12.8f, -3.872f, 1.0f);
382         Vector3 aVectorRotatedByQ = q.Rotate(Vector3(aVector));
383         Vector4 aVectorRotatedByR = rotMatrix*aVector;
384         DALI_TEST_EQUALS(aVectorRotatedByQ, Vector3(aVectorRotatedByR), 0.001f, TEST_LOCATION);
385       }
386     }
387   }
388   END_TEST;
389 }
390
391 int UtcDaliQuaternionOperatorAddition(void)
392 {
393   TestApplication application; // Reset all test adapter return codes
394   Quaternion q1(0.383f, 0.0f, 0.0f, 0.924f);
395   Quaternion q2(0.0f, 0.609f, 0.0f, 0.793f);
396
397   Quaternion r1(0.383f, 0.609f, 0.0f, 1.717f);
398
399   DALI_TEST_EQUALS(q1+q2, r1, 0.001f, TEST_LOCATION);
400   END_TEST;
401 }
402
403 int UtcDaliQuaternionOperatorSubtraction(void)
404 {
405   TestApplication application; // Reset all test adapter return codes
406   Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
407   Quaternion q2(0.383f, 0.690f, 0.234f, 1.917f);
408
409   Quaternion r1(0.0f, 0.240f, 0.111f, 0.993f);
410
411   DALI_TEST_EQUALS(q2-q1, r1, 0.001f, TEST_LOCATION);
412   END_TEST;
413 }
414
415 int UtcDaliQuaternionConjugate(void)
416 {
417   TestApplication application; // Reset all test adapter return codes
418   float s1=0.784f; Vector3 v1(0.045f, 0.443f, 0.432f);
419   float s2=0.697f; Vector3 v2(0.612, 0.344, -0.144);
420
421   Quaternion q1(s1, v1.x, v1.y, v1.z);
422   Quaternion q2(s2, v2.x, v2.y, v2.z);
423   q1.Conjugate();
424   q2.Conjugate();
425
426   Quaternion r1(s1, -v1.x, -v1.y, -v1.z);
427   Quaternion r2(s2, -v2.x, -v2.y, -v2.z);
428
429   DALI_TEST_EQUALS(q1, r1, 0.001f, TEST_LOCATION);
430   DALI_TEST_EQUALS(q2, r2, 0.001f, TEST_LOCATION);
431   END_TEST;
432 }
433
434 int UtcDaliQuaternionOperatorMultiplication01(void)
435 {
436   TestApplication application; // Reset all test adapter return codes
437   float s1=0.784f; Vector3 v1(0.045f, 0.443f, 0.432f);
438   float s2=0.697f; Vector3 v2(0.612, 0.344, -0.144);
439
440   Quaternion q1(s1, v1.x, v1.y, v1.z);
441   Quaternion q2(s2, v2.x, v2.y, v2.z);
442
443   Vector3 vp = v1.Cross(v2) + v2*s1 + v1*s2;
444   Quaternion r1(s1*s2-v1.Dot(v2), vp.x, vp.y, vp.z);
445
446   DALI_TEST_EQUALS(q1*q2, r1, 0.001f, TEST_LOCATION);
447   END_TEST;
448 }
449
450 int UtcDaliQuaternionOperatorDivision(void)
451 {
452   TestApplication application; // Reset all test adapter return codes
453   Quaternion q1(0.383f, 0.0f, 0.0f, 0.924f);
454   Quaternion q2(0.0f, 0.609f, 0.0f, 0.793f);
455
456   // q1 / q2 = q1 * q2^-1
457   // q2^-1 = q2* / ||q2||^2
458   //       = Conjugate of q2 / Square of Norm of q2
459
460   Quaternion r1 = q2;
461   r1.Conjugate();
462   r1 *= 1.0f/q2.LengthSquared();
463   Quaternion r2 = q1 * r1;
464
465   DALI_TEST_EQUALS(q1 / q2, r2, 0.001f, TEST_LOCATION);
466   END_TEST;
467 }
468
469 int UtcDaliQuaternionOperatorScale01(void)
470 {
471   TestApplication application; // Reset all test adapter return codes
472   Quaternion q1(0.383f, 0.0f, 0.0f, 0.924f);
473   Quaternion r1(2.0f* 0.383f, 0.0f, 0.0f, 2.0f * 0.924f);
474
475   DALI_TEST_EQUALS(q1 * 2.0f, r1, 0.001f, TEST_LOCATION);
476   END_TEST;
477 }
478
479 int UtcDaliQuaternionOperatorScale02(void)
480 {
481   TestApplication application; // Reset all test adapter return codes
482   Quaternion q1(0.383f, 0.0f, 0.0f, 0.924f);
483   Quaternion r1(0.5f* 0.383f, 0.0f, 0.0f, 0.5f * 0.924f);
484
485   DALI_TEST_EQUALS(q1 / 2.0f, r1, 0.001f, TEST_LOCATION);
486   END_TEST;
487 }
488
489 int UtcDaliQuaternionOperatorNegation(void)
490 {
491   TestApplication application; // Reset all test adapter return codes
492   Quaternion q1(0.383f, 0.0f, 0.0f, 0.924f);
493   Quaternion r1(-0.383f, -0.0f, -0.0f, -0.924f);
494
495   DALI_TEST_EQUALS(-q1, r1, 0.001f, TEST_LOCATION);
496   END_TEST;
497 }
498
499 int UtcDaliQuaternionOperatorAddAssign(void)
500 {
501   TestApplication application; // Reset all test adapter return codes
502   Quaternion q1(0.383f, 0.0f, 0.0f, 0.924f);
503   Quaternion q2(0.0f, 0.609f, 0.0f, 0.793f);
504
505   Quaternion r1(0.383f, 0.609f, 0.0f, 1.717f);
506
507   q1 += q2;
508   DALI_TEST_EQUALS(q1, r1, 0.001f, TEST_LOCATION);
509   END_TEST;
510 }
511
512 int UtcDaliQuaternionOperatorSubtractAssign(void)
513 {
514   TestApplication application; // Reset all test adapter return codes
515   Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
516   Quaternion q2(0.383f, 0.690f, 0.234f, 1.917f);
517
518   Quaternion r1(0.0f, 0.240f, 0.111f, 0.993f);
519   q2 -= q1;
520   DALI_TEST_EQUALS(q2, r1, 0.001f, TEST_LOCATION);
521   END_TEST;
522 }
523
524 int UtcDaliQuaternionOperatorMultiplyAssign(void)
525 {
526   TestApplication application; // Reset all test adapter return codes
527   float s1=0.784f; Vector3 v1(0.045f, 0.443f, 0.432f);
528   float s2=0.697f; Vector3 v2(0.612, 0.344, -0.144);
529
530   Quaternion q1(s1, v1.x, v1.y, v1.z);
531   Quaternion q2(s2, v2.x, v2.y, v2.z);
532
533   Quaternion r3 = q2 * q1;
534   q2 *= q1;
535   DALI_TEST_EQUALS(q2, r3, 0.001f, TEST_LOCATION);
536   END_TEST;
537 }
538
539 int UtcDaliQuaternionOperatorScaleAssign01(void)
540 {
541   TestApplication application; // Reset all test adapter return codes
542   Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
543   float scale = 2.5f;
544   Quaternion r1(scale*0.383f, scale*0.450f, scale*0.123f, scale*0.924f);
545   q1 *= scale;
546   DALI_TEST_EQUALS(q1, r1, 0.001f, TEST_LOCATION);
547   END_TEST;
548 }
549
550 int UtcDaliQuaternionOperatorScaleAssign02(void)
551 {
552   TestApplication application; // Reset all test adapter return codes
553   Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
554   float scale = 2.5f;
555   Quaternion r1(0.383f/scale, 0.450f/scale, 0.123f/scale, 0.924f/scale);
556   q1 /= scale;
557   DALI_TEST_EQUALS(q1, r1, 0.001f, TEST_LOCATION);
558   END_TEST;
559 }
560
561 int UtcDaliQuaternionOperatorEquality(void)
562 {
563   TestApplication application; // Reset all test adapter return codes
564   Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
565   Quaternion q2(0.383f, 0.450f, 0.123f, 0.924f);
566   Quaternion q3(0.383f, 0.450f, 0.123f, 0.800f);
567   Quaternion q4(0.383f, 0.450f, 0.100f, 0.800f);
568   Quaternion q5(0.383f, 0.100f, 0.100f, 0.800f);
569   Quaternion q6(0.100f, 0.100f, 0.100f, 0.800f);
570
571   Quaternion q7(-0.383f, -0.450f, -0.123f, -0.924f);
572   Quaternion q8(-0.383f, -0.450f, -0.123f,  0.924f);
573   Quaternion q9(-0.383f, -0.450f,  0.123f,  0.924f);
574   Quaternion q10(-0.383f,  0.450f,  0.123f,  0.924f);
575
576   DALI_TEST_CHECK( q1 == q2 );
577   DALI_TEST_CHECK( !(q1 == q3) );
578   DALI_TEST_CHECK( !(q1 == q4) );
579   DALI_TEST_CHECK( !(q1 == q5) );
580   DALI_TEST_CHECK( !(q1 == q6) );
581   DALI_TEST_CHECK( (q1 == q7) );
582   DALI_TEST_CHECK( !(q1 == q8) );
583   DALI_TEST_CHECK( !(q1 == q9) );
584   DALI_TEST_CHECK( !(q1 == q10) );
585   END_TEST;
586 }
587
588 int UtcDaliQuaternionOperatorInequality(void)
589 {
590   TestApplication application; // Reset all test adapter return codes
591   Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
592   Quaternion q2(0.383f, 0.450f, 0.123f, 0.924f);
593   Quaternion q3(-0.383f, -0.0f, -0.0f, -0.924f);
594   DALI_TEST_CHECK( !(q1 != q2) );
595   DALI_TEST_CHECK( q1 != q3 );
596   END_TEST;
597 }
598
599 int UtcDaliQuaternionLength(void)
600 {
601   TestApplication application; // Reset all test adapter return codes
602   Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
603   float length = sqrtf(0.383f*0.383f + 0.450f*0.450f + 0.123f*0.123f + 0.924f*0.924f);
604   DALI_TEST_EQUALS(q1.Length(), length, 0.01f, TEST_LOCATION);
605   END_TEST;
606 }
607
608 int UtcDaliQuaternionLengthSquared(void)
609 {
610   TestApplication application; // Reset all test adapter return codes
611   Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
612   float lengthSquared = 0.383f*0.383f + 0.450f*0.450f + 0.123f*0.123f + 0.924f*0.924f;
613   DALI_TEST_EQUALS(q1.LengthSquared(), lengthSquared, 0.01f, TEST_LOCATION);
614   END_TEST;
615 }
616
617 int UtcDaliQuaternionNormalize(void)
618 {
619   TestApplication application; // Reset all test adapter return codes
620   Quaternion q1(0.118f, 0.692f, -0.127f, 0.701f);
621   Quaternion q2 = q1;
622   q2 *= 5.0f;
623   q2.Normalize();
624   DALI_TEST_EQUALS(q1, q2, 0.001f, TEST_LOCATION);
625   END_TEST;
626 }
627
628 int UtcDaliQuaternionNormalized(void)
629 {
630   TestApplication application; // Reset all test adapter return codes
631   Quaternion q1(0.118f, 0.692f, -0.127f, 0.701f);
632   Quaternion q2 = q1;
633   q2 *= 5.0f;
634   DALI_TEST_EQUALS(q1, q2.Normalized(), 0.001f, TEST_LOCATION);
635   END_TEST;
636 }
637
638 int UtcDaliQuaternionInvert(void)
639 {
640   TestApplication application; // Reset all test adapter return codes
641   Quaternion q1(0.383f, 0.0f, 0.0f, 0.924f);
642
643   // q1^-1 = q1* / ||q1||^2
644   //       = Conjugate of q1 / Square of Norm of q1
645
646   Quaternion r1 = q1;
647   r1.Conjugate();
648   r1 *= 1.0f/q1.LengthSquared();
649
650   Quaternion q2 = q1;
651   q2.Invert();
652   DALI_TEST_EQUALS(q2, r1, 0.001f, TEST_LOCATION);
653   END_TEST;
654 }
655
656
657 int UtcDaliQuaternionDot(void)
658 {
659   TestApplication application; // Reset all test adapter return codes
660   // q.q' = s*s' + v dot v'
661   float s1=0.784f; Vector3 v1(0.045f, 0.443f, 0.432f);
662   float s2=0.697f; Vector3 v2(0.612, 0.344, -0.144);
663
664   Quaternion q1(s1, v1.x, v1.y, v1.z);
665   Quaternion q2(s2, v2.x, v2.y, v2.z);
666
667   float r1 = s1*s2 + v1.Dot(v2);
668
669   DALI_TEST_EQUALS(Quaternion::Dot(q1, q2), r1, TEST_LOCATION);
670   END_TEST;
671 }
672
673
674 // Quaternion * vector == Vector rotation
675 int UtcDaliQuaternionOperatorMultiplication02(void)
676 {
677   TestApplication application; // Reset all test adapter return codes
678   // Rotation of vector p = (x,y,z) by Quaternion q == q [0,p] q^-1
679   Vector3 v(2, 3, 4);
680   Quaternion q(Radian(Degree(72)), Vector3::ZAXIS);
681   Quaternion qI = q;
682   qI.Invert();
683   Quaternion qv(0.0f, v.x, v.y, v.z);
684   Quaternion r1 = (q * qv) * qI;
685
686   Vector3 r2 = q * v;
687
688   DALI_TEST_EQUALS(r1.mVector.x, r2.x, 0.001, TEST_LOCATION);
689   DALI_TEST_EQUALS(r1.mVector.y, r2.y, 0.001, TEST_LOCATION);
690   DALI_TEST_EQUALS(r1.mVector.z, r2.z, 0.001, TEST_LOCATION);
691   END_TEST;
692 }
693
694 int UtcDaliQuaternionRotate01(void)
695 {
696   TestApplication application; // Reset all test adapter return codes
697   // Rotation of vector p = (x,y,z) by Quaternion q == q [0,p] q^-1
698   Vector3 v(2, 3, 4);
699   Quaternion q(Radian(Degree(72)), Vector3::ZAXIS);
700   Quaternion qI = q;
701   qI.Invert();
702   Quaternion qv(0.0f, v.x, v.y, v.z);
703   Quaternion r1 = q * qv * qI;
704
705   Vector3 r2 = q.Rotate(v);
706
707   DALI_TEST_EQUALS(r1.mVector.x, r2.x, 0.001f, TEST_LOCATION);
708   DALI_TEST_EQUALS(r1.mVector.y, r2.y, 0.001f, TEST_LOCATION);
709   DALI_TEST_EQUALS(r1.mVector.z, r2.z, 0.001f, TEST_LOCATION);
710
711   DALI_TEST_EQUALS(q.Rotate(v), q*v, 0.001f, TEST_LOCATION);
712   END_TEST;
713 }
714
715
716 int UtcDaliQuaternionRotate02(void)
717 {
718   TestApplication application; // Reset all test adapter return codes
719   // Rotation of vector p = (x,y,z) by Quaternion q == q [0,p] q^-1
720   Vector4 v(2, 3, 4, 5);
721   Quaternion q(Radian(Degree(72)), Vector3::ZAXIS);
722   Quaternion qI = q;
723   qI.Invert();
724   Quaternion qv(0.0f, v.x, v.y, v.z);
725   Quaternion r1 = q * qv * qI;
726
727   Vector4 r2 = q.Rotate(v);
728
729   DALI_TEST_EQUALS(r1.mVector.x, r2.x, 0.001f, TEST_LOCATION);
730   DALI_TEST_EQUALS(r1.mVector.y, r2.y, 0.001f, TEST_LOCATION);
731   DALI_TEST_EQUALS(r1.mVector.z, r2.z, 0.001f, TEST_LOCATION);
732   DALI_TEST_EQUALS(r1.mVector.w, 0.0f, 0.001f, TEST_LOCATION);
733   END_TEST;
734 }
735
736
737 int UtcDaliQuaternionExp01(void)
738 {
739   TestApplication application; // Reset all test adapter return codes
740   Quaternion q1(0.0f, 1.0f, 1.2f, 1.3f);
741   Quaternion q2 = q1.Exp();
742   Quaternion r2(-0.4452, 0.4406, 0.5287, 0.5728);
743
744   DALI_TEST_EQUALS(q2.Length(), 1.0f, 0.01f, TEST_LOCATION);
745
746   DALI_TEST_EQUALS(q2, r2, 0.001f, TEST_LOCATION);
747
748   // Note, this trick only works when |v| < pi, which it is!
749   Quaternion q3 = q2.Log();
750   DALI_TEST_EQUALS(q1, q3, 0.01f, TEST_LOCATION);
751   END_TEST;
752 }
753
754
755 int UtcDaliQuaternionExp02(void)
756 {
757   TestApplication application; // Reset all test adapter return codes
758   Quaternion q1(0.0f, 0.0f, 0.0f, 0.0f);
759   Quaternion q2 = q1.Exp();
760   Quaternion r2(1.0f, 0.0f, 0.0f, 0.0f);
761
762   DALI_TEST_EQUALS(q2.Length(), 1.0f, 0.01f, TEST_LOCATION);
763
764   DALI_TEST_EQUALS(q2, r2, 0.001f, TEST_LOCATION);
765
766   // Note, this trick only works when |v| < pi, which it is!
767   Quaternion q3 = q2.Log();
768   DALI_TEST_EQUALS(q1, q3, 0.01f, TEST_LOCATION);
769   END_TEST;
770 }
771
772
773 int UtcDaliQuaternionExp03(void)
774 {
775   TestApplication app;
776
777   Quaternion q(0.0f, Vector3(5.0f, 6.0f, 7.0f));
778
779   // q.w is non-zero. Should assert.
780   try
781   {
782     q.Exp();
783     DALI_TEST_CHECK(false);
784   }
785   catch(DaliException& e)
786   {
787     DALI_TEST_CHECK(true);
788   }
789   END_TEST;
790 }
791
792
793 int UtcDaliQuaternionLog01(void)
794 {
795   TestApplication application; // Reset all test adapter return codes
796   Quaternion q(Math::PI*0.73f, Vector3(2,3,4));
797   Quaternion q2 = q;
798   q2.Normalize();
799
800   Quaternion r = q2.Log();
801   DALI_TEST_EQUALS(r.mVector.w, 0.0f, 0.01f, TEST_LOCATION);
802
803   Quaternion r2 = r.Exp();
804   DALI_TEST_EQUALS(r2, q2, 0.01f, TEST_LOCATION);
805   END_TEST;
806 }
807
808 int UtcDaliQuaternionLog02(void)
809 {
810   TestApplication application; // Reset all test adapter return codes
811   Quaternion q1(1.0f, 0.0f, 0.0f, 0.0f);
812   Quaternion r1(0.0f, 0.0f, 0.0f, 0.0f);
813
814   Quaternion q2 = q1.Log();
815
816   DALI_TEST_EQUALS(q2, r1, 0.01f, TEST_LOCATION);
817
818   Quaternion q3 = q2.Exp();
819   DALI_TEST_EQUALS(q1, q3, 0.01f, TEST_LOCATION);
820   END_TEST;
821 }
822
823
824
825 int UtcDaliQuaternionLerp(void)
826 {
827   TestApplication application; // Reset all test adapter return codes
828   Quaternion q1(Radian(Degree(-80)), Vector3(0.0f, 0.0f, 1.0f));
829   Quaternion q2(Radian(Degree( 80)), Vector3(0.0f, 0.0f, 1.0f));
830
831   Quaternion p = Quaternion::Lerp(q1, q2, 0.0f);
832   DALI_TEST_EQUALS(p, q1, 0.001f, TEST_LOCATION);
833
834   p = Quaternion::Lerp(q1, q2, 1.0f);
835   DALI_TEST_EQUALS(p, q2, 0.001f, TEST_LOCATION);
836
837   p = Quaternion::Lerp(q1, q2, 0.5f);
838   Quaternion r1 = (q1 + q2) * 0.5f;
839   r1.Normalize();
840   DALI_TEST_EQUALS(p, r1, 0.001f, TEST_LOCATION);
841   END_TEST;
842 }
843
844
845
846 int UtcDaliQuaternionSlerp01(void)
847 {
848   TestApplication application;
849
850   Quaternion q1(M_PI/4.0f, Vector4(0.0f, 0.0f, 1.0f, 0.0f));
851   Quaternion q2(-M_PI/4.0f, Vector4(0.0f, 0.0f, 1.0f, 0.0f));
852
853   Quaternion q = Quaternion::Slerp(q1, q2, 0.0f);
854   DALI_TEST_EQUALS(q, q1, 0.001, TEST_LOCATION);
855
856   q = Quaternion::Slerp(q1, q2, 1.0f);
857   DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
858
859   // @ 25%, will be at M_PI/8
860   q = Quaternion::Slerp(q1, q2, 0.25f);
861   Vector4 axis;
862   float angle;
863   bool converted = q.ToAxisAngle(axis, angle);
864   DALI_TEST_EQUALS(converted, true, TEST_LOCATION);
865   DALI_TEST_EQUALS(angle, Math::PI/8.0f, 0.001, TEST_LOCATION);
866   DALI_TEST_EQUALS(axis.x, 0.0f, 0.001, TEST_LOCATION);
867   DALI_TEST_EQUALS(axis.y, 0.0f, 0.001, TEST_LOCATION);
868   DALI_TEST_EQUALS(axis.z, 1.0f, 0.001, TEST_LOCATION);
869   END_TEST;
870 }
871
872
873
874 int UtcDaliQuaternionSlerp02(void)
875 {
876   TestApplication application;
877
878   Quaternion q1(M_PI/6, Vector3(0.0f, 0.0f, 1.0f));
879   Quaternion q2(M_PI/2, Vector3(0.0f, 0.0f, 1.0f));
880
881   Quaternion q = Quaternion::Slerp(q1, q2, 0.0f);
882
883   DALI_TEST_EQUALS(q,  q1, 0.001, TEST_LOCATION);
884
885   q = Quaternion::Slerp(q1, q2, 1.0f);
886
887   DALI_TEST_EQUALS(q,  q2, 0.001, TEST_LOCATION);
888
889   // @ 50%, will be at M_PI/3 around z
890   q = Quaternion::Slerp(q1, q2, 0.5f);
891
892   Quaternion r( M_PI/3, Vector3( 0.0f, 0.0f, 1.0f));
893   DALI_TEST_EQUALS( q, r, 0.001, TEST_LOCATION );
894   END_TEST;
895 }
896
897
898 int UtcDaliQuaternionSlerp03(void)
899 {
900   TestApplication application;
901
902   Quaternion q1(Radian(Degree(125)), Vector3(0.0f, 0.0f, 1.0f));
903   Quaternion q2(Radian(Degree(-125)), Vector3(0.002f, 0.001f, 1.001f));
904
905   Quaternion q = Quaternion::Slerp(q1, q2, 0.0f);
906   DALI_TEST_EQUALS(q,  q1, 0.001, TEST_LOCATION);
907
908   q = Quaternion::Slerp(q1, q2, 1.0f);
909   DALI_TEST_EQUALS(q,  q2, 0.001, TEST_LOCATION);
910
911   q = Quaternion::Slerp(q1, q2, 0.05f);
912   Vector4 axis;
913   float angle;
914   bool converted = q.ToAxisAngle(axis, angle);
915   DALI_TEST_EQUALS(converted, true, TEST_LOCATION);
916
917   DALI_TEST_EQUALS(axis.x,  0.0f, 0.01, TEST_LOCATION);
918   DALI_TEST_EQUALS(axis.y,  0.0f, 0.01, TEST_LOCATION);
919   DALI_TEST_EQUALS(axis.z,  1.0f, 0.01, TEST_LOCATION);
920   END_TEST;
921 }
922
923
924
925 int UtcDaliQuaternionSlerp04(void)
926 {
927   TestApplication application;
928
929   Quaternion q1(Radian(Degree(120)), Vector3(0.0f, 0.0f, 1.0f));
930   Quaternion q2(Radian(Degree(130)), Vector3(0.0f, 0.0f, 1.0f));
931
932   Quaternion q = Quaternion::Slerp(q1, q2, 0.0f);
933   DALI_TEST_EQUALS(q,  q1, 0.001, TEST_LOCATION);
934
935   q = Quaternion::Slerp(q1, q2, 1.0f);
936   DALI_TEST_EQUALS(q,  q2, 0.001, TEST_LOCATION);
937
938   q = Quaternion::Slerp(q1, q2, 0.5f);
939   Vector4 axis;
940   float angle;
941   bool converted = q.ToAxisAngle(axis, angle);
942   DALI_TEST_EQUALS(converted, true, TEST_LOCATION);
943   DALI_TEST_EQUALS(angle, float(Radian(Degree(125))), 0.01f, TEST_LOCATION);
944   DALI_TEST_EQUALS(axis.x,  0.0f, 0.01, TEST_LOCATION);
945   DALI_TEST_EQUALS(axis.y,  0.0f, 0.01, TEST_LOCATION);
946   DALI_TEST_EQUALS(axis.z,  1.0f, 0.01, TEST_LOCATION);
947   END_TEST;
948 }
949
950
951
952 int UtcDaliQuaternionSlerpNoInvert01(void)
953 {
954   TestApplication application;
955
956   Quaternion q1(M_PI/4.0f, Vector4(0.0f, 0.0f, 1.0f, 0.0f));
957   Quaternion q2(-M_PI/4.0f, Vector4(0.0f, 0.0f, 1.0f, 0.0f));
958
959   Quaternion q = Quaternion::SlerpNoInvert(q1, q2, 0.0f);
960   DALI_TEST_EQUALS(q, q1, 0.001, TEST_LOCATION);
961
962   q = Quaternion::SlerpNoInvert(q1, q2, 1.0f);
963   DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
964
965   // @ 25%, will be at M_PI/8
966   q = Quaternion::SlerpNoInvert(q1, q2, 0.25f);
967   Vector4 axis;
968   float angle;
969   bool converted = q.ToAxisAngle(axis, angle);
970   DALI_TEST_EQUALS(converted, true, TEST_LOCATION);
971   DALI_TEST_EQUALS(angle, Math::PI/8.0f, 0.001, TEST_LOCATION);
972   DALI_TEST_EQUALS(axis.x, 0.0f, 0.001, TEST_LOCATION);
973   DALI_TEST_EQUALS(axis.y, 0.0f, 0.001, TEST_LOCATION);
974   DALI_TEST_EQUALS(axis.z, 1.0f, 0.001, TEST_LOCATION);
975   END_TEST;
976 }
977
978
979 int UtcDaliQuaternionSlerpNoInvert02(void)
980 {
981   TestApplication application;
982
983   Quaternion q1(Radian(Degree(120)), Vector3(0.0f, 0.0f, 1.0f));
984   Quaternion q2(Radian(Degree(130)), Vector3(0.0f, 0.0f, 1.0f));
985
986   Quaternion q = Quaternion::SlerpNoInvert(q1, q2, 0.0f);
987   DALI_TEST_EQUALS(q,  q1, 0.001, TEST_LOCATION);
988
989   q = Quaternion::SlerpNoInvert(q1, q2, 1.0f);
990   DALI_TEST_EQUALS(q,  q2, 0.001, TEST_LOCATION);
991
992   q = Quaternion::SlerpNoInvert(q1, q2, 0.5f);
993   Vector4 axis;
994   float angle;
995   bool converted = q.ToAxisAngle(axis, angle);
996   DALI_TEST_EQUALS(converted, true, TEST_LOCATION);
997   DALI_TEST_EQUALS(angle, float(Radian(Degree(125))), 0.01f, TEST_LOCATION);
998   DALI_TEST_EQUALS(axis.x,  0.0f, 0.01, TEST_LOCATION);
999   DALI_TEST_EQUALS(axis.y,  0.0f, 0.01, TEST_LOCATION);
1000   DALI_TEST_EQUALS(axis.z,  1.0f, 0.01, TEST_LOCATION);
1001   END_TEST;
1002 }
1003
1004
1005 int UtcDaliQuaternionSquad(void)
1006 {
1007   TestApplication application; // Reset all test adapter return codes
1008   Quaternion q1(Radian(Degree(45)),     Vector3(0.0f, 0.0f, 1.0f));
1009   Quaternion q1out(Radian(Degree(40)),  Vector3(0.0f, 1.0f, 2.0f));
1010   Quaternion q2in(Radian(Degree(35)),   Vector3(0.0f, 2.0f, 3.0f));
1011   Quaternion q2(Radian(Degree(30)),     Vector3(0.0f, 1.0f, 3.0f));
1012
1013   Quaternion q = Quaternion::Squad(q1, q2, q1out, q2in, 0.0f);
1014   DALI_TEST_EQUALS(q, q1, 0.001f, TEST_LOCATION);
1015
1016   q = Quaternion::Squad(q1, q2, q1out, q2in, 1.0f);
1017   DALI_TEST_EQUALS(q, q2, 0.001f, TEST_LOCATION);
1018
1019   // Don't know what actual value should be, but can make some informed guesses.
1020   q = Quaternion::Squad(q1, q2, q1out, q2in, 0.5f);
1021   float angle;
1022   Vector3 axis;
1023   q.Normalize();
1024   q.ToAxisAngle(axis, angle);
1025
1026   if(angle < 0.0f)
1027   {
1028     q = -q; // Might get negative quat
1029     q.ToAxisAngle(axis, angle);
1030   }
1031   float deg = Degree(Radian(angle));
1032   DALI_TEST_CHECK(deg >= 0 && deg <= 90);
1033   DALI_TEST_CHECK(axis.y > 0);
1034   DALI_TEST_CHECK(axis.z > 0);
1035   END_TEST;
1036 }
1037
1038 int UtcDaliAngleBetween(void)
1039 {
1040   TestApplication application; // Reset all test adapter return codes
1041
1042   Quaternion q1(Radian(Degree(45)), 0.0f, 0.0f);
1043   Quaternion q2(Radian(Degree(47)), 0.0f, 0.0f);
1044   DALI_TEST_EQUALS(Quaternion::AngleBetween(q1, q2), fabsf(Radian(Degree(45)) - Radian(Degree(47))), 0.001f, TEST_LOCATION);
1045
1046   Quaternion q3(Radian(Degree(80)), Vector3::YAXIS);
1047   Quaternion q4(Radian(Degree(90)), Vector3::YAXIS);
1048   DALI_TEST_EQUALS(Quaternion::AngleBetween(q3, q4), fabsf(Radian(Degree(80)) - Radian(Degree(90))), 0.001f, TEST_LOCATION);
1049
1050   Quaternion q5(Radian(Degree(0)), Vector3::YAXIS);
1051   Quaternion q6(Radian(Degree(90)), Vector3::XAXIS);
1052   DALI_TEST_EQUALS(Quaternion::AngleBetween(q5, q6), fabsf(Radian(Degree(0)) - Radian(Degree(90))), 0.001f, TEST_LOCATION);
1053
1054   Quaternion q7(Radian(Degree(0)), Vector3::YAXIS);
1055   Quaternion q8(Radian(Degree(0)), Vector3::XAXIS);
1056   DALI_TEST_EQUALS(Quaternion::AngleBetween(q7, q8), fabsf(Radian(Degree(0)) - Radian(Degree(0))), 0.001f, TEST_LOCATION);
1057
1058   Quaternion q9(Radian(Degree(0)), Vector3::XAXIS);
1059   Quaternion q10(Radian(Degree(180)), Vector3::XAXIS);
1060   DALI_TEST_EQUALS(Quaternion::AngleBetween(q9, q10), fabsf(Radian(Degree(0)) - Radian(Degree(180))), 0.001f, TEST_LOCATION);
1061
1062   Quaternion q11(Radian(Degree(1)), Vector3::YAXIS);
1063   Quaternion q12(Radian(Degree(240)), Vector3::YAXIS);
1064   DALI_TEST_EQUALS(Quaternion::AngleBetween(q11, q12), fabsf(Radian( Degree(1 - 240 + 360) )), 0.001f, TEST_LOCATION);
1065
1066   Quaternion q13(Radian(Degree(240)), Vector3::YAXIS);
1067   Quaternion q14(Radian(Degree(1)), Vector3::YAXIS);
1068   DALI_TEST_EQUALS(Quaternion::AngleBetween(q13, q14), fabsf(Radian( Degree(240 - 1 - 360) )), 0.001f, TEST_LOCATION);
1069
1070   Quaternion q15(Radian(Degree(240)), Vector3::YAXIS);
1071   Quaternion q16(Radian(Degree(1)), Vector3::ZAXIS);
1072   DALI_TEST_EQUALS(Quaternion::AngleBetween(q15, q16), Quaternion::AngleBetween(q16, q15), 0.001f, TEST_LOCATION);
1073   END_TEST;
1074 }
1075
1076 int UtcDaliQuaternionOStreamOperator(void)
1077 {
1078   TestApplication application; // Reset all test adapter return codes
1079
1080   std::ostringstream oss;
1081
1082   Quaternion quaternion(M_PI, Vector3::YAXIS);
1083
1084   oss << quaternion;
1085
1086   std::string expectedOutput = "[ Axis: [0, 1, 0], Angle: 180 degrees ]";
1087
1088   DALI_TEST_EQUALS( oss.str(), expectedOutput, TEST_LOCATION);
1089   END_TEST;
1090 }