2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <dali/public-api/dali-core.h>
23 #include <dali-test-suite-utils.h>
28 void utc_dali_quaternion_startup(void)
30 test_return_value = TET_UNDEF;
33 void utc_dali_quaternion_cleanup(void)
35 test_return_value = TET_PASS;
39 int UtcDaliQuaternionCtor01(void)
41 TestApplication application; // Reset all test adapter return codes
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);
50 int UtcDaliQuaternionCtor02(void)
52 TestApplication application; // Reset all test adapter return codes
54 Quaternion r(M_PI/2.0f, Vector4(1.0f, 2.0f, 3.0f, M_PI/3.0f));
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);
65 int UtcDaliQuaternionCtor03(void)
67 TestApplication application; // Reset all test adapter return codes
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);
73 Quaternion e2(0.0f, Radian(Degree(75)), 0.0f);
74 Vector4 r2(0.0f, 0.609f, 0.0f, 0.793f);
76 Quaternion e3(0.0f, 0.0f, Radian(Degree(135)));
77 Vector4 r3(0.0f, 0.0f, 0.924f, 0.383f);
79 Quaternion e4(Radian(Degree(71)), Radian(Degree(36)), Radian(Degree(27)));
80 Vector4 r4(0.478f, 0.374f, 0.006f, 0.795f);
82 Quaternion e5(Radian(Degree(-31)), Radian(Degree(-91)), Radian(Degree(-173)));
83 Vector4 r5(-0.697f, 0.145f, -0.686f, -0.149f);
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);
94 int UtcDaliQuaternionFromAxisAngle(void)
96 TestApplication application; // Reset all test adapter return codes
98 Quaternion q = Quaternion::FromAxisAngle(Vector4(1.0f, 2.0f, 3.0f, M_PI/3.0f), M_PI/2.0f);
100 Quaternion r(0.707f, 0.189f, 0.378f, 0.567f);
102 DALI_TEST_EQUALS(q, r, 0.001, TEST_LOCATION);
106 int UtcDaliQuaternionToAxisAngle01(void)
108 TestApplication application; // Reset all test adapter return codes
109 Quaternion q(0.932f, 1.1f, 3.4f, 2.7f);
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);
121 int UtcDaliQuaternionToAxisAngle02(void)
123 TestApplication application; // Reset all test adapter return codes
124 Quaternion q(0.932f, 1.1f, 3.4f, 2.7f);
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);
138 int UtcDaliQuaternionToAxisAngle03(void)
140 TestApplication application; // Reset all test adapter return codes
141 Quaternion q(1, 2, 3, 4);
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);
153 int UtcDaliQuaternionToAxisAngle04(void)
155 TestApplication application; // Reset all test adapter return codes
156 Quaternion q(1, 2, 3, 4);
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);
171 int UtcDaliQuaternionEulerAngles(void)
173 TestApplication application; // Reset all test adapter return codes
175 Quaternion q1(0.924f, 0.383f, 0.0f, 0.0f);
176 Vector4 r1(Radian(Degree(45)), 0.0f, 0.0f, 0.0f);
178 Quaternion q2(0.793f, 0.0f, 0.609f, 0.0f);
179 Vector4 r2(0.0f, Radian(Degree(75)), 0.0f, 0.0f);
181 Quaternion q3(0.383f, 0.0f, 0.0f, 0.924f);
182 Vector4 r3(0.0f, 0.0f, Radian(Degree(135)), 0.0f);
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);
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);
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);
199 int UtcDaliQuaternionToMatrix01(void)
201 TestApplication application; // Reset all test adapter return codes
203 Quaternion q(0.69813, Vector4(1.0f, 0.0f, 0.0f, 0.0f)); // 40 degree rotation around X axis
205 // Result calculated using a different maths library (with appropriate row/col ordering)
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 };
214 DALI_TEST_EQUALS(m, mRes, 0.01, TEST_LOCATION);
218 int UtcDaliQuaternionToMatrix02(void)
220 TestApplication application; // Reset all test adapter return codes
222 // rotation around arbitrary axis
223 Quaternion q2(-1.23918f, Vector4(7.0f, -13.0f, 11.0f, 0.0f));
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 };
233 DALI_TEST_EQUALS(m2, mRes2, 0.01, TEST_LOCATION);
238 int UtcDaliQuaternionFromMatrix01(void)
240 TestApplication application; // Reset all test adapter return codes
245 Matrix m(q); // Convert to matrix
247 Quaternion q2(m); // and back to a quaternion
249 DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
250 DALI_TEST_EQUALS(m, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
254 int UtcDaliQuaternionFromMatrix02(void)
256 TestApplication application; // Reset all test adapter return codes
258 // Create an arbitrary forward vector
259 for( float x=-1.0f; x<=1.0f; x+=0.1f )
261 for( float y=-1.0f; y<1.0f; y+=0.1f )
263 for( float z=-1.0f; z<1.0f; z+=0.1f )
265 Vector3 vForward(x, y, z);
266 vForward.Normalize();
268 // Construct an up vector from a sideways move
270 Vector3 vUp = vForward.Cross(Vector3(vForward.x+1.0f, vForward.y, vForward.z));
271 if(vUp.Length() > 0.01 )
274 vSide = vUp.Cross(vForward);
279 vSide = vForward.Cross(Vector3(vForward.x, vForward.y+1.0f, vForward.z));
281 vUp = vForward.Cross(vSide);
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 );
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);
296 // Rotate an arbitrary vector by both quaternion and rotation matrix,
297 // check the result is the same
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);
309 int UtcDaliQuaternionFromAxes01(void)
311 TestApplication application; // Reset all test adapter return codes
313 Vector3 xAxis( Vector3::XAXIS );
314 Vector3 yAxis( Vector3::YAXIS );
315 Vector3 zAxis( Vector3::ZAXIS );
317 Quaternion q1( xAxis, yAxis, zAxis);
319 DALI_TEST_EQUALS( q1, Quaternion::IDENTITY, TEST_LOCATION );
321 xAxis = Vector3( 1.0f, 1.0f, 0.0f );
323 yAxis = Vector3( -1.0f, 1.0f, 0.0f ); // 45 degrees anticlockwise (+ve) around z
325 zAxis = xAxis.Cross(yAxis);
327 Quaternion q2( xAxis, yAxis, zAxis );
329 DALI_TEST_EQUALS( q2, Quaternion(Radian(Degree(45)), Vector3::ZAXIS), 0.001f, TEST_LOCATION);
334 int UtcDaliQuaternionFromAxes02(void)
336 TestApplication application; // Reset all test adapter return codes
338 // Create an arbitrary forward vector
339 for( float x=-1.0f; x<=1.0f; x+=0.1f )
341 for( float y=-1.0f; y<1.0f; y+=0.1f )
343 for( float z=-1.0f; z<1.0f; z+=0.1f )
345 Vector3 vForward(x, y, z);
346 vForward.Normalize();
348 // Construct an up vector from a sideways move
350 Vector3 vUp = vForward.Cross(Vector3(vForward.x+1.0f, vForward.y, vForward.z));
351 if(vUp.Length() > 0.01 )
354 vSide = vUp.Cross(vForward);
359 vSide = vForward.Cross(Vector3(vForward.x, vForward.y+1.0f, vForward.z));
361 vUp = vForward.Cross(vSide);
365 // Generate a quaternion
366 Quaternion q( vSide, vUp, vForward );
369 rotMatrix.SetXAxis(vSide);
370 rotMatrix.SetYAxis(vUp);
371 rotMatrix.SetZAxis(vForward);
373 // Generate a matrix from the quaternion, check they are the same
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);
379 // Rotate an arbitrary vector by both quaternion and rotation matrix,
380 // check the result is the same
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);
392 int UtcDaliQuaternionOperatorAddition(void)
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);
398 Quaternion r1(0.383f, 0.609f, 0.0f, 1.717f);
400 DALI_TEST_EQUALS(q1+q2, r1, 0.001f, TEST_LOCATION);
404 int UtcDaliQuaternionOperatorSubtraction(void)
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);
410 Quaternion r1(0.0f, 0.240f, 0.111f, 0.993f);
412 DALI_TEST_EQUALS(q2-q1, r1, 0.001f, TEST_LOCATION);
416 int UtcDaliQuaternionConjugate(void)
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);
422 Quaternion q1(s1, v1.x, v1.y, v1.z);
423 Quaternion q2(s2, v2.x, v2.y, v2.z);
427 Quaternion r1(s1, -v1.x, -v1.y, -v1.z);
428 Quaternion r2(s2, -v2.x, -v2.y, -v2.z);
430 DALI_TEST_EQUALS(q1, r1, 0.001f, TEST_LOCATION);
431 DALI_TEST_EQUALS(q2, r2, 0.001f, TEST_LOCATION);
435 int UtcDaliQuaternionOperatorMultiplication01(void)
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);
441 Quaternion q1(s1, v1.x, v1.y, v1.z);
442 Quaternion q2(s2, v2.x, v2.y, v2.z);
444 Vector3 vp = v1.Cross(v2) + v2*s1 + v1*s2;
445 Quaternion r1(s1*s2-v1.Dot(v2), vp.x, vp.y, vp.z);
447 DALI_TEST_EQUALS(q1*q2, r1, 0.001f, TEST_LOCATION);
451 int UtcDaliQuaternionOperatorDivision(void)
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);
457 // q1 / q2 = q1 * q2^-1
458 // q2^-1 = q2* / ||q2||^2
459 // = Conjugate of q2 / Square of Norm of q2
463 r1 *= 1.0f/q2.LengthSquared();
464 Quaternion r2 = q1 * r1;
466 DALI_TEST_EQUALS(q1 / q2, r2, 0.001f, TEST_LOCATION);
470 int UtcDaliQuaternionOperatorScale01(void)
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);
476 DALI_TEST_EQUALS(q1 * 2.0f, r1, 0.001f, TEST_LOCATION);
480 int UtcDaliQuaternionOperatorScale02(void)
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);
486 DALI_TEST_EQUALS(q1 / 2.0f, r1, 0.001f, TEST_LOCATION);
490 int UtcDaliQuaternionOperatorNegation(void)
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);
496 DALI_TEST_EQUALS(-q1, r1, 0.001f, TEST_LOCATION);
500 int UtcDaliQuaternionOperatorAddAssign(void)
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);
506 Quaternion r1(0.383f, 0.609f, 0.0f, 1.717f);
509 DALI_TEST_EQUALS(q1, r1, 0.001f, TEST_LOCATION);
513 int UtcDaliQuaternionOperatorSubtractAssign(void)
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);
519 Quaternion r1(0.0f, 0.240f, 0.111f, 0.993f);
521 DALI_TEST_EQUALS(q2, r1, 0.001f, TEST_LOCATION);
525 int UtcDaliQuaternionOperatorMultiplyAssign(void)
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);
531 Quaternion q1(s1, v1.x, v1.y, v1.z);
532 Quaternion q2(s2, v2.x, v2.y, v2.z);
534 Quaternion r3 = q2 * q1;
536 DALI_TEST_EQUALS(q2, r3, 0.001f, TEST_LOCATION);
540 int UtcDaliQuaternionOperatorScaleAssign01(void)
542 TestApplication application; // Reset all test adapter return codes
543 Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
545 Quaternion r1(scale*0.383f, scale*0.450f, scale*0.123f, scale*0.924f);
547 DALI_TEST_EQUALS(q1, r1, 0.001f, TEST_LOCATION);
551 int UtcDaliQuaternionOperatorScaleAssign02(void)
553 TestApplication application; // Reset all test adapter return codes
554 Quaternion q1(0.383f, 0.450f, 0.123f, 0.924f);
556 Quaternion r1(0.383f/scale, 0.450f/scale, 0.123f/scale, 0.924f/scale);
558 DALI_TEST_EQUALS(q1, r1, 0.001f, TEST_LOCATION);
562 int UtcDaliQuaternionOperatorEquality(void)
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);
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);
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) );
589 int UtcDaliQuaternionOperatorInequality(void)
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 );
600 int UtcDaliQuaternionLength(void)
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);
609 int UtcDaliQuaternionLengthSquared(void)
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);
618 int UtcDaliQuaternionNormalize(void)
620 TestApplication application; // Reset all test adapter return codes
621 Quaternion q1(0.118f, 0.692f, -0.127f, 0.701f);
625 DALI_TEST_EQUALS(q1, q2, 0.001f, TEST_LOCATION);
629 int UtcDaliQuaternionNormalized(void)
631 TestApplication application; // Reset all test adapter return codes
632 Quaternion q1(0.118f, 0.692f, -0.127f, 0.701f);
635 DALI_TEST_EQUALS(q1, q2.Normalized(), 0.001f, TEST_LOCATION);
639 int UtcDaliQuaternionInvert(void)
641 TestApplication application; // Reset all test adapter return codes
642 Quaternion q1(0.383f, 0.0f, 0.0f, 0.924f);
644 // q1^-1 = q1* / ||q1||^2
645 // = Conjugate of q1 / Square of Norm of q1
649 r1 *= 1.0f/q1.LengthSquared();
653 DALI_TEST_EQUALS(q2, r1, 0.001f, TEST_LOCATION);
658 int UtcDaliQuaternionDot(void)
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);
665 Quaternion q1(s1, v1.x, v1.y, v1.z);
666 Quaternion q2(s2, v2.x, v2.y, v2.z);
668 float r1 = s1*s2 + v1.Dot(v2);
670 DALI_TEST_EQUALS(Quaternion::Dot(q1, q2), r1, TEST_LOCATION);
675 // Quaternion * vector == Vector rotation
676 int UtcDaliQuaternionOperatorMultiplication02(void)
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
681 Quaternion q(Radian(Degree(72)), Vector3::ZAXIS);
684 Quaternion qv(0.0f, v.x, v.y, v.z);
685 Quaternion r1 = (q * qv) * qI;
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);
695 int UtcDaliQuaternionRotate01(void)
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
700 Quaternion q(Radian(Degree(72)), Vector3::ZAXIS);
703 Quaternion qv(0.0f, v.x, v.y, v.z);
704 Quaternion r1 = q * qv * qI;
706 Vector3 r2 = q.Rotate(v);
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);
712 DALI_TEST_EQUALS(q.Rotate(v), q*v, 0.001f, TEST_LOCATION);
717 int UtcDaliQuaternionRotate02(void)
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);
725 Quaternion qv(0.0f, v.x, v.y, v.z);
726 Quaternion r1 = q * qv * qI;
728 Vector4 r2 = q.Rotate(v);
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);
738 int UtcDaliQuaternionExp01(void)
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);
745 DALI_TEST_EQUALS(q2.Length(), 1.0f, 0.01f, TEST_LOCATION);
747 DALI_TEST_EQUALS(q2, r2, 0.001f, TEST_LOCATION);
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);
756 int UtcDaliQuaternionExp02(void)
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);
763 DALI_TEST_EQUALS(q2.Length(), 1.0f, 0.01f, TEST_LOCATION);
765 DALI_TEST_EQUALS(q2, r2, 0.001f, TEST_LOCATION);
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);
774 int UtcDaliQuaternionExp03(void)
778 Quaternion q(0.0f, Vector3(5.0f, 6.0f, 7.0f));
780 // q.w is non-zero. Should assert.
784 DALI_TEST_CHECK(false);
786 catch(DaliException& e)
788 DALI_TEST_CHECK(true);
794 int UtcDaliQuaternionLog01(void)
796 TestApplication application; // Reset all test adapter return codes
797 Quaternion q(Math::PI*0.73f, Vector3(2,3,4));
801 Quaternion r = q2.Log();
802 DALI_TEST_EQUALS(r.mVector.w, 0.0f, 0.01f, TEST_LOCATION);
804 Quaternion r2 = r.Exp();
805 DALI_TEST_EQUALS(r2, q2, 0.01f, TEST_LOCATION);
809 int UtcDaliQuaternionLog02(void)
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);
815 Quaternion q2 = q1.Log();
817 DALI_TEST_EQUALS(q2, r1, 0.01f, TEST_LOCATION);
819 Quaternion q3 = q2.Exp();
820 DALI_TEST_EQUALS(q1, q3, 0.01f, TEST_LOCATION);
826 int UtcDaliQuaternionLerp(void)
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));
832 Quaternion p = Quaternion::Lerp(q1, q2, 0.0f);
833 DALI_TEST_EQUALS(p, q1, 0.001f, TEST_LOCATION);
835 p = Quaternion::Lerp(q1, q2, 1.0f);
836 DALI_TEST_EQUALS(p, q2, 0.001f, TEST_LOCATION);
838 p = Quaternion::Lerp(q1, q2, 0.5f);
839 Quaternion r1 = (q1 + q2) * 0.5f;
841 DALI_TEST_EQUALS(p, r1, 0.001f, TEST_LOCATION);
847 int UtcDaliQuaternionSlerp01(void)
849 TestApplication application;
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));
854 Quaternion q = Quaternion::Slerp(q1, q2, 0.0f);
855 DALI_TEST_EQUALS(q, q1, 0.001, TEST_LOCATION);
857 q = Quaternion::Slerp(q1, q2, 1.0f);
858 DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
860 // @ 25%, will be at M_PI/8
861 q = Quaternion::Slerp(q1, q2, 0.25f);
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);
875 int UtcDaliQuaternionSlerp02(void)
877 TestApplication application;
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));
882 Quaternion q = Quaternion::Slerp(q1, q2, 0.0f);
884 DALI_TEST_EQUALS(q, q1, 0.001, TEST_LOCATION);
886 q = Quaternion::Slerp(q1, q2, 1.0f);
888 DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
890 // @ 50%, will be at M_PI/3 around z
891 q = Quaternion::Slerp(q1, q2, 0.5f);
893 Quaternion r( M_PI/3, Vector3( 0.0f, 0.0f, 1.0f));
894 DALI_TEST_EQUALS( q, r, 0.001, TEST_LOCATION );
899 int UtcDaliQuaternionSlerp03(void)
901 TestApplication application;
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));
906 Quaternion q = Quaternion::Slerp(q1, q2, 0.0f);
907 DALI_TEST_EQUALS(q, q1, 0.001, TEST_LOCATION);
909 q = Quaternion::Slerp(q1, q2, 1.0f);
910 DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
912 q = Quaternion::Slerp(q1, q2, 0.05f);
915 bool converted = q.ToAxisAngle(axis, angle);
916 DALI_TEST_EQUALS(converted, true, TEST_LOCATION);
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);
926 int UtcDaliQuaternionSlerp04(void)
928 TestApplication application;
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));
933 Quaternion q = Quaternion::Slerp(q1, q2, 0.0f);
934 DALI_TEST_EQUALS(q, q1, 0.001, TEST_LOCATION);
936 q = Quaternion::Slerp(q1, q2, 1.0f);
937 DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
939 q = Quaternion::Slerp(q1, q2, 0.5f);
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);
953 int UtcDaliQuaternionSlerpNoInvert01(void)
955 TestApplication application;
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));
960 Quaternion q = Quaternion::SlerpNoInvert(q1, q2, 0.0f);
961 DALI_TEST_EQUALS(q, q1, 0.001, TEST_LOCATION);
963 q = Quaternion::SlerpNoInvert(q1, q2, 1.0f);
964 DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
966 // @ 25%, will be at M_PI/8
967 q = Quaternion::SlerpNoInvert(q1, q2, 0.25f);
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);
980 int UtcDaliQuaternionSlerpNoInvert02(void)
982 TestApplication application;
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));
987 Quaternion q = Quaternion::SlerpNoInvert(q1, q2, 0.0f);
988 DALI_TEST_EQUALS(q, q1, 0.001, TEST_LOCATION);
990 q = Quaternion::SlerpNoInvert(q1, q2, 1.0f);
991 DALI_TEST_EQUALS(q, q2, 0.001, TEST_LOCATION);
993 q = Quaternion::SlerpNoInvert(q1, q2, 0.5f);
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);
1006 int UtcDaliQuaternionSquad(void)
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));
1014 Quaternion q = Quaternion::Squad(q1, q2, q1out, q2in, 0.0f);
1015 DALI_TEST_EQUALS(q, q1, 0.001f, TEST_LOCATION);
1017 q = Quaternion::Squad(q1, q2, q1out, q2in, 1.0f);
1018 DALI_TEST_EQUALS(q, q2, 0.001f, TEST_LOCATION);
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);
1025 q.ToAxisAngle(axis, angle);
1029 q = -q; // Might get negative quat
1030 q.ToAxisAngle(axis, angle);
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);
1039 int UtcDaliAngleBetween(void)
1041 TestApplication application; // Reset all test adapter return codes
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);
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);
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);
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);
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);
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);
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);
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);
1077 int UtcDaliQuaternionOStreamOperator(void)
1079 TestApplication application; // Reset all test adapter return codes
1081 std::ostringstream oss;
1083 Quaternion quaternion(M_PI, Vector3::YAXIS);
1087 std::string expectedOutput = "[ Axis: [0, 1, 0], Angle: 180 degrees ]";
1089 DALI_TEST_EQUALS( oss.str(), expectedOutput, TEST_LOCATION);