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