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