2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
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.
21 #include <dali/dali.h>
22 #include <dali-test-suite-utils.h>
27 void utc_dali_matrix_startup(void)
29 test_return_value = TET_UNDEF;
32 void utc_dali_matrix_cleanup(void)
34 test_return_value = TET_PASS;
38 int UtcDaliMatrixCtor(void)
40 // Test initialized startup
43 float r1[] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
44 float r2[] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
48 DALI_TEST_EQUALS(m1, mr1, 0.001f, TEST_LOCATION);
50 // Test uninitialized startup
51 // Stack construct a matrix to non zero, then stack construct another matrix over the top of it.
52 float r3[] = { 1.0f, 2.0f, 3.0f, 4.0f, 1.0f, 2.0f, 3.0f, 4.0f, 1.0f, 2.0f, 3.0f, 4.0f, 1.0f, 2.0f, 3.0f, 4.0f};
59 bool initialised = true;
61 float* els = m2.AsFloat();
62 for(size_t idx=0; idx<16; ++idx, ++els)
69 DALI_TEST_EQUALS(initialised, false, TEST_LOCATION);
73 DALI_TEST_EQUALS(m4, mr1, 0.001f, TEST_LOCATION);
76 DALI_TEST_EQUALS(m4, mr1, 0.001f, TEST_LOCATION);
81 DALI_TEST_EQUALS(m6, mr2, 0.001f, TEST_LOCATION);
85 // OrthoNormalise fixes floating point errors from matrix rotations
86 int UtcDaliMatrixOrthoNormalize0(void)
91 for (int i=0;i<1000;++i)
94 Vector4 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f), 0.0f);
97 m.SetTransformComponents( Vector3::ONE, Quaternion(1.0f, axis), Vector3::ZERO );
102 success &= fabsf(m.GetXAxis().Dot(m.GetYAxis())) < 0.001f;
103 success &= fabsf(m.GetYAxis().Dot(m.GetXAxis())) < 0.001f;
104 success &= fabsf(m.GetZAxis().Dot(m.GetYAxis())) < 0.001f;
106 success &= fabsf(m.GetXAxis().Length() - 1.0f) < 0.001f;
107 success &= fabsf(m.GetYAxis().Length() - 1.0f) < 0.001f;
108 success &= fabsf(m.GetZAxis().Length() - 1.0f) < 0.001f;
110 DALI_TEST_CHECK(success);
114 // OrthoNormalize is not flipping the axes and is maintaining the translation
115 int UtcDaliMatrixOrthoNormalize1(void)
117 for (int i=0;i<1000;++i)
120 Vector4 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f), 0.0f);
122 Vector3 center(10.0f, 15.0f, 5.0f);
126 m0.SetTransformComponents( Vector3::ONE, Quaternion(1.0f, axis), center );
131 DALI_TEST_EQUALS(m0.GetXAxis(), m1.GetXAxis(), 0.001f, TEST_LOCATION);
132 DALI_TEST_EQUALS(m0.GetYAxis(), m1.GetYAxis(), 0.001f, TEST_LOCATION);
133 DALI_TEST_EQUALS(m0.GetZAxis(), m1.GetZAxis(), 0.001f, TEST_LOCATION);
134 DALI_TEST_EQUALS(m0.GetTranslation(), m1.GetTranslation(), 0.001f, TEST_LOCATION);
140 int UtcDaliMatrixInvert01(void)
142 // We're going to invert a whole load of different matrices to make sure we don't
143 // fail on particular orientations.
144 for (int i=0;i<1000;++i)
147 Vector4 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f), 0.0f);
149 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
153 m0.SetTransformComponents( Vector3::ONE, Quaternion(1.0f, axis), center );
159 Matrix::Multiply( m2, m0, m1 );
161 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
163 m1.Invert(); // doube invert - should be back to m0
165 DALI_TEST_EQUALS(m0, m1, 0.001f, TEST_LOCATION);
171 int UtcDaliMatrixInvert02(void)
173 Matrix m1 = Matrix::IDENTITY;
174 m1.SetXAxis(Vector3(0.0f, 0.0f, 0.0f));
175 DALI_TEST_EQUALS(m1.Invert(), false, TEST_LOCATION);
180 // Invert transform works
181 int UtcDaliMatrixInvertTransform01(void)
183 for (int i=0;i<1000;++i)
186 Vector4 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f), 0.0f);
188 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
192 m0.SetTransformComponents( Vector3::ONE, Quaternion(1.0f, axis), center );
195 m0.InvertTransform(m1);
198 Matrix::Multiply( m2, m0, m1 );
200 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
206 // Invert transform works
207 int UtcDaliMatrixInvertTransform02(void)
209 std::string exceptionString( "EqualsZero( mMatrix[3] ) && EqualsZero( mMatrix[7] ) && EqualsZero( mMatrix[11] ) && Equals( mMatrix[15], 1.0f" );
212 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
213 4.0f, 5.0f, 6.0f, 7.0f,
214 8.0f, 9.0f, 10.0f, 11.0f,
215 12.0f, 13.0f, 14.0f, 15.0f };
219 m.InvertTransform(it);
220 tet_result(TET_FAIL);
222 catch (Dali::DaliException& e)
224 tet_printf("Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str());
225 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
230 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
231 4.0f, 5.0f, 6.0f, 7.0f,
232 8.0f, 9.0f, 10.0f, 11.0f,
233 12.0f, 13.0f, 14.0f, 15.0f };
237 m.InvertTransform(it);
238 tet_result(TET_FAIL);
240 catch (Dali::DaliException& e)
242 tet_printf("Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str());
243 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
248 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
249 4.0f, 5.0f, 6.0f, 7.0f,
250 8.0f, 9.0f, 10.0f, 11.0f,
251 12.0f, 13.0f, 14.0f, 15.0f };
255 m.InvertTransform(it);
256 tet_result(TET_FAIL);
258 catch (Dali::DaliException& e)
260 tet_printf("Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str());
261 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
266 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
267 4.0f, 5.0f, 6.0f, 7.0f,
268 8.0f, 9.0f, 10.0f, 11.0f,
269 12.0f, 13.0f, 14.0f, 15.0f };
273 m.InvertTransform(it);
274 tet_result(TET_FAIL);
276 catch (Dali::DaliException& e)
278 tet_printf("Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str());
279 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
286 int UtcDaliMatrixGetXAxis(void)
288 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
289 4.0f, 5.0f, 6.0f, 7.0f,
290 8.0f, 9.0f, 10.0f, 11.0f,
291 12.0f, 13.0f, 14.0f, 15.0f };
294 DALI_TEST_CHECK(m.GetXAxis() == Vector3(0.0f, 1.0f, 2.0f));
299 int UtcDaliMatrixGetYAxis(void)
301 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
302 4.0f, 5.0f, 6.0f, 7.0f,
303 8.0f, 9.0f, 10.0f, 11.0f,
304 12.0f, 13.0f, 14.0f, 15.0f };
307 DALI_TEST_CHECK(m.GetYAxis() == Vector3(4.0f, 5.0f, 6.0f));
312 int UtcDaliMatrixGetZAxis(void)
314 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
315 4.0f, 5.0f, 6.0f, 7.0f,
316 8.0f, 9.0f, 10.0f, 11.0f,
317 12.0f, 13.0f, 14.0f, 15.0f };
320 DALI_TEST_CHECK(m.GetZAxis() == Vector3(8.0f, 9.0f, 10.0f));
325 int UtcDaliMatrixGetTranslation(void)
327 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
328 4.0f, 5.0f, 6.0f, 7.0f,
329 8.0f, 9.0f, 10.0f, 11.0f,
330 12.0f, 13.0f, 14.0f, 15.0f };
333 DALI_TEST_EQUALS(m.GetTranslation(), Vector4(12.0f, 13.0f, 14.0f, 15.0f), TEST_LOCATION);
338 int UtcDaliMatrixGetTranslation3(void)
340 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
341 4.0f, 5.0f, 6.0f, 7.0f,
342 8.0f, 9.0f, 10.0f, 11.0f,
343 12.0f, 13.0f, 14.0f, 15.0f };
346 DALI_TEST_EQUALS(m.GetTranslation3(), Vector3(12.0f, 13.0f, 14.0f), TEST_LOCATION);
351 int UtcDaliMatrixSetIdentity(void)
353 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
354 4.0f, 5.0f, 6.0f, 7.0f,
355 8.0f, 9.0f, 10.0f, 11.0f,
356 12.0f, 13.0f, 14.0f, 15.0f };
360 DALI_TEST_EQUALS(m, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
365 int UtcDaliMatrixSetIdentityAndScale(void)
367 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
368 4.0f, 5.0f, 6.0f, 7.0f,
369 8.0f, 9.0f, 10.0f, 11.0f,
370 12.0f, 13.0f, 14.0f, 15.0f };
372 m.SetIdentityAndScale(Vector3(4.0f, 4.0f, 4.0f));
374 float els2[] = { 4.0f, 0.0f, 0.0f, 0.0f,
375 0.0f, 4.0f, 0.0f, 0.0f,
376 0.0f, 0.0f, 4.0f, 0.0f,
377 0.0f, 0.0f, 0.0f, 1.0f };
380 DALI_TEST_EQUALS(m, r, 0.001f, TEST_LOCATION);
386 int UtcDaliMatrixSetXAxis(void)
389 Vector3 v(2.0f, 3.0f, 4.0f);
392 DALI_TEST_CHECK(m.GetXAxis() == v);
397 int UtcDaliMatrixSetYAxis(void)
400 Vector3 v(2.0f, 3.0f, 4.0f);
403 DALI_TEST_CHECK(m.GetYAxis() == v);
408 int UtcDaliMatrixSetZAxis(void)
411 Vector3 v(2.0f, 3.0f, 4.0f);
414 DALI_TEST_CHECK(m.GetZAxis() == v);
419 int UtcDaliMatrixSetTranslation(void)
422 Vector4 v(2.0f, 3.0f, 4.0f, 5.0f);
425 DALI_TEST_CHECK(m.GetTranslation() == v);
430 int UtcDaliMatrixSetTranslation3(void)
433 Vector3 v(2.0f, 3.0f, 4.0f);
436 DALI_TEST_CHECK(m.GetTranslation3() == v);
443 int UtcDaliMatrixTranspose(void)
446 { 0.0f, 1.0f, 2.0f, 3.0f,
447 4.0f, 5.0f, 6.0f, 7.0f,
448 8.0f, 9.0f, 10.0f, 11.0f,
449 12.0f, 13.0f, 14.0f, 15.0f
457 for (int x=0;x<4;++x)
459 for (int y=0;y<4;++y)
461 success &= (m.AsFloat()[x+y*4] == floats[x*4+y]);
465 DALI_TEST_CHECK(success);
469 int UtcDaliMatrixOStreamOperator(void)
471 std::ostringstream oss;
474 matrix.SetIdentity();
478 std::string expectedOutput = "[ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]";
480 DALI_TEST_EQUALS( oss.str(), expectedOutput, TEST_LOCATION);
484 int UtcDaliMatrixMultiply(void)
486 Matrix m1 = Matrix::IDENTITY;
488 float els[] = { 1.0f, 0.0f, 0.0f, 0.0f,
489 0.0f, 0.707f, 0.707f, 0.0f,
490 0.0f, -0.707f, 0.707f, 0.0f,
491 0.0f, 0.0f, 0.0f, 1.0f };
494 Quaternion q(Radian(Degree(45.0f)), Vector3::XAXIS);
496 Matrix::Multiply(m2, m1, q);
498 DALI_TEST_EQUALS(m2, result, 0.01f, TEST_LOCATION);
502 int UtcDaliMatrixOperatorMultiply01(void)
504 Vector4 v1(2.0f, 5.0f, 4.0f, 0.0f);
506 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
507 0.0f, 3.0f, 0.0f, 0.0f,
508 0.0f, 0.0f, 4.0f, 0.0f,
509 0.0f, 0.0f, 0.0f, 1.0f };
512 Vector4 v2 = m1 * v1;
513 Vector4 r1(4.0f, 15.0f, 16.0f, 0.0f);
514 DALI_TEST_EQUALS(v2, r1, 0.01f, TEST_LOCATION);
518 int UtcDaliMatrixOperatorMultiply02(void)
520 TestApplication application;
522 Vector3 position ( 30.f, 40.f, 50.f);
526 m1.SetTranslation(-position);
528 Vector4 positionV4(position);
530 Vector4 output = m1 * positionV4;
533 DALI_TEST_EQUALS(output, Vector4::ZERO, 0.01f, TEST_LOCATION);
537 int UtcDaliMatrixOperatorEquals(void)
539 Matrix m1 = Matrix::IDENTITY;
541 float els[] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
543 DALI_TEST_EQUALS(m1 == r2, true, TEST_LOCATION);
545 float *f = m1.AsFloat();
546 for(size_t i=0; i<16; i++)
549 DALI_TEST_EQUALS(m1 == r2, false, TEST_LOCATION);
555 int UtcDaliMatrixOperatorNotEquals(void)
557 Matrix m1 = Matrix::IDENTITY;
558 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
559 0.0f, 3.0f, 0.0f, 0.0f,
560 0.0f, 0.0f, 4.0f, 0.0f,
561 0.0f, 0.0f, 0.0f, 1.0f };
564 DALI_TEST_CHECK(m1 != r1);
565 DALI_TEST_CHECK(!(m1 != m1));
569 int UtcDaliMatrixGetTransformComponents01(void)
571 Matrix m2(Matrix::IDENTITY.AsFloat());
575 m2.GetTransformComponents(pos2, q2, scale2);
576 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
577 DALI_TEST_EQUALS(Vector3(1.0f, 1.0f, 1.0f), scale2, 0.001, TEST_LOCATION);
578 DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
583 int UtcDaliMatrixGetTransformComponents02(void)
585 // Create an arbitrary vector
586 for( float x=-1.0f; x<=1.0f; x+=0.1f )
588 for( float y=-1.0f; y<1.0f; y+=0.1f )
590 for( float z=-1.0f; z<1.0f; z+=0.1f )
592 Vector3 vForward(x, y, z);
593 vForward.Normalize();
595 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
597 Quaternion rotation1(Radian(Degree(angle)), vForward);
598 Vector3 scale1(2.0f, 3.0f, 4.0f);
599 Vector3 position1(1.0f, 2.0f, 3.0f);
602 m1.SetTransformComponents(scale1, rotation1, position1);
605 Quaternion rotation2;
607 m1.GetTransformComponents(position2, rotation2, scale2);
609 DALI_TEST_EQUALS(position1, position2, 0.001, TEST_LOCATION);
610 DALI_TEST_EQUALS(scale1, scale2, 0.001, TEST_LOCATION);
611 DALI_TEST_EQUALS(rotation1, rotation2, 0.001, TEST_LOCATION);
619 int UtcDaliMatrixSetTransformComponents01(void)
621 // Create an arbitrary vector
622 for( float x=-1.0f; x<=1.0f; x+=0.1f )
624 for( float y=-1.0f; y<1.0f; y+=0.1f )
626 for( float z=-1.0f; z<1.0f; z+=0.1f )
628 Vector3 vForward(x, y, z);
629 vForward.Normalize();
631 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
633 Quaternion rotation1(Radian(Degree(angle)), vForward);
635 Matrix m1(rotation1);
636 Matrix result1(false);
637 Vector4 vForward4(vForward.x, vForward.y, vForward.z, 0.0f);
638 result1.SetTransformComponents( Vector3::ONE, Quaternion(Radian(Degree(angle)), vForward4), Vector3::ZERO );
640 DALI_TEST_EQUALS(m1, result1, 0.001, TEST_LOCATION);
643 m2.SetTransformComponents(vForward, Quaternion::IDENTITY, Vector3::ZERO);
645 Matrix result2a(Matrix::IDENTITY);
646 result2a.SetXAxis(result2a.GetXAxis() * vForward[0]);
647 result2a.SetYAxis(result2a.GetYAxis() * vForward[1]);
648 result2a.SetZAxis(result2a.GetZAxis() * vForward[2]);
650 DALI_TEST_EQUALS(m2, result2a, 0.001, TEST_LOCATION);
653 m3.SetTransformComponents(vForward, rotation1, Vector3::ZERO);
655 Matrix result3(Matrix::IDENTITY);
656 result3.SetXAxis(result3.GetXAxis() * vForward[0]);
657 result3.SetYAxis(result3.GetYAxis() * vForward[1]);
658 result3.SetZAxis(result3.GetZAxis() * vForward[2]);
660 Matrix::Multiply(result3, result3, m1);
661 DALI_TEST_EQUALS(m3, result3, 0.001, TEST_LOCATION);
670 int UtcDaliMatrixSetInverseTransformComponent01(void)
672 // Create an arbitrary vector
673 for( float x=-1.0f; x<=1.0f; x+=0.1f )
675 for( float y=-1.0f; y<1.0f; y+=0.1f )
677 for( float z=-1.0f; z<1.0f; z+=0.1f )
679 Vector3 vForward(x, y, z);
680 vForward.Normalize();
682 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
684 Quaternion rotation1(Radian(Degree(angle)), vForward);
685 Vector3 scale1(2.0f, 3.0f, 4.0f);
686 Vector3 position1(1.0f, 2.0f, 3.0f);
689 m1.SetTransformComponents(scale1, rotation1, position1);
692 m2.SetInverseTransformComponents(scale1, rotation1, position1);
695 Matrix::Multiply(result, m1, m2);
697 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
705 int UtcDaliMatrixSetInverseTransformComponent02(void)
707 // Create an arbitrary vector
708 for( float x=-1.0f; x<=1.0f; x+=0.1f )
710 for( float y=-1.0f; y<1.0f; y+=0.1f )
712 for( float z=-1.0f; z<1.0f; z+=0.1f )
714 Vector3 vForward(x, y, z);
715 vForward.Normalize();
717 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
719 Quaternion rotation1(Radian(Degree(angle)), vForward);
720 Matrix rotationMatrix(rotation1); // TEST RELIES ON THIS METHOD WORKING!!!
722 Vector3 position1(5.0f, -6.0f, 7.0f);
725 m1.SetTransformComponents( Vector3::ONE, rotation1, position1 );
728 m2.SetInverseTransformComponents( rotationMatrix.GetXAxis(),
729 rotationMatrix.GetYAxis(),
730 rotationMatrix.GetZAxis(),
734 Matrix::Multiply(result, m1, m2);
736 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);