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_matrix_startup(void)
30 test_return_value = TET_UNDEF;
33 void utc_dali_matrix_cleanup(void)
35 test_return_value = TET_PASS;
39 int UtcDaliMatrixCtor(void)
41 // Test initialized startup
44 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};
45 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};
49 DALI_TEST_EQUALS(m1, mr1, 0.001f, TEST_LOCATION);
51 // Test uninitialized startup
52 // Stack construct a matrix to non zero, then stack construct another matrix over the top of it.
53 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};
60 bool initialised = true;
62 float* els = m2.AsFloat();
63 for(size_t idx=0; idx<16; ++idx, ++els)
70 DALI_TEST_EQUALS(initialised, false, TEST_LOCATION);
74 DALI_TEST_EQUALS(m4, mr1, 0.001f, TEST_LOCATION);
77 DALI_TEST_EQUALS(m4, mr1, 0.001f, TEST_LOCATION);
82 DALI_TEST_EQUALS(m6, mr2, 0.001f, TEST_LOCATION);
86 // OrthoNormalise fixes floating point errors from matrix rotations
87 int UtcDaliMatrixOrthoNormalize0(void)
92 for (int i=0;i<1000;++i)
95 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f) );
98 m.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), Vector3::ZERO );
103 success &= fabsf(m.GetXAxis().Dot(m.GetYAxis())) < 0.001f;
104 success &= fabsf(m.GetYAxis().Dot(m.GetXAxis())) < 0.001f;
105 success &= fabsf(m.GetZAxis().Dot(m.GetYAxis())) < 0.001f;
107 success &= fabsf(m.GetXAxis().Length() - 1.0f) < 0.001f;
108 success &= fabsf(m.GetYAxis().Length() - 1.0f) < 0.001f;
109 success &= fabsf(m.GetZAxis().Length() - 1.0f) < 0.001f;
111 DALI_TEST_CHECK(success);
115 // OrthoNormalize is not flipping the axes and is maintaining the translation
116 int UtcDaliMatrixOrthoNormalize1(void)
118 for (int i=0;i<1000;++i)
121 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
123 Vector3 center(10.0f, 15.0f, 5.0f);
127 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
132 DALI_TEST_EQUALS(m0.GetXAxis(), m1.GetXAxis(), 0.001f, TEST_LOCATION);
133 DALI_TEST_EQUALS(m0.GetYAxis(), m1.GetYAxis(), 0.001f, TEST_LOCATION);
134 DALI_TEST_EQUALS(m0.GetZAxis(), m1.GetZAxis(), 0.001f, TEST_LOCATION);
135 DALI_TEST_EQUALS(m0.GetTranslation(), m1.GetTranslation(), 0.001f, TEST_LOCATION);
141 int UtcDaliMatrixInvert01(void)
143 // We're going to invert a whole load of different matrices to make sure we don't
144 // fail on particular orientations.
145 for (int i=0;i<1000;++i)
148 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
150 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
154 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
160 Matrix::Multiply( m2, m0, m1 );
162 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
164 m1.Invert(); // doube invert - should be back to m0
166 DALI_TEST_EQUALS(m0, m1, 0.001f, TEST_LOCATION);
172 int UtcDaliMatrixInvert02(void)
174 Matrix m1 = Matrix::IDENTITY;
175 m1.SetXAxis(Vector3(0.0f, 0.0f, 0.0f));
176 DALI_TEST_EQUALS(m1.Invert(), false, TEST_LOCATION);
181 // Invert transform works
182 int UtcDaliMatrixInvertTransform01(void)
184 for (int i=0;i<1000;++i)
187 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
189 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
193 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
196 m0.InvertTransform(m1);
199 Matrix::Multiply( m2, m0, m1 );
201 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
207 // Invert transform works
208 int UtcDaliMatrixInvertTransform02(void)
210 std::string exceptionString( "EqualsZero( mMatrix[3] ) && EqualsZero( mMatrix[7] ) && EqualsZero( mMatrix[11] ) && Equals( mMatrix[15], 1.0f" );
213 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
214 4.0f, 5.0f, 6.0f, 7.0f,
215 8.0f, 9.0f, 10.0f, 11.0f,
216 12.0f, 13.0f, 14.0f, 15.0f };
220 m.InvertTransform(it);
221 tet_result(TET_FAIL);
223 catch (Dali::DaliException& e)
225 DALI_TEST_PRINT_ASSERT( e );
226 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
231 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
232 4.0f, 5.0f, 6.0f, 7.0f,
233 8.0f, 9.0f, 10.0f, 11.0f,
234 12.0f, 13.0f, 14.0f, 15.0f };
238 m.InvertTransform(it);
239 tet_result(TET_FAIL);
241 catch (Dali::DaliException& e)
243 DALI_TEST_PRINT_ASSERT( e );
244 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
249 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
250 4.0f, 5.0f, 6.0f, 7.0f,
251 8.0f, 9.0f, 10.0f, 11.0f,
252 12.0f, 13.0f, 14.0f, 15.0f };
256 m.InvertTransform(it);
257 tet_result(TET_FAIL);
259 catch (Dali::DaliException& e)
261 DALI_TEST_PRINT_ASSERT( e );
262 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
267 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
268 4.0f, 5.0f, 6.0f, 7.0f,
269 8.0f, 9.0f, 10.0f, 11.0f,
270 12.0f, 13.0f, 14.0f, 15.0f };
274 m.InvertTransform(it);
275 tet_result(TET_FAIL);
277 catch (Dali::DaliException& e)
279 DALI_TEST_PRINT_ASSERT( e );
280 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
287 int UtcDaliMatrixGetXAxis(void)
289 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
290 4.0f, 5.0f, 6.0f, 7.0f,
291 8.0f, 9.0f, 10.0f, 11.0f,
292 12.0f, 13.0f, 14.0f, 15.0f };
295 DALI_TEST_CHECK(m.GetXAxis() == Vector3(0.0f, 1.0f, 2.0f));
300 int UtcDaliMatrixGetYAxis(void)
302 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
303 4.0f, 5.0f, 6.0f, 7.0f,
304 8.0f, 9.0f, 10.0f, 11.0f,
305 12.0f, 13.0f, 14.0f, 15.0f };
308 DALI_TEST_CHECK(m.GetYAxis() == Vector3(4.0f, 5.0f, 6.0f));
313 int UtcDaliMatrixGetZAxis(void)
315 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
316 4.0f, 5.0f, 6.0f, 7.0f,
317 8.0f, 9.0f, 10.0f, 11.0f,
318 12.0f, 13.0f, 14.0f, 15.0f };
321 DALI_TEST_CHECK(m.GetZAxis() == Vector3(8.0f, 9.0f, 10.0f));
326 int UtcDaliMatrixGetTranslation(void)
328 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
329 4.0f, 5.0f, 6.0f, 7.0f,
330 8.0f, 9.0f, 10.0f, 11.0f,
331 12.0f, 13.0f, 14.0f, 15.0f };
334 DALI_TEST_EQUALS(m.GetTranslation(), Vector4(12.0f, 13.0f, 14.0f, 15.0f), TEST_LOCATION);
339 int UtcDaliMatrixGetTranslation3(void)
341 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
342 4.0f, 5.0f, 6.0f, 7.0f,
343 8.0f, 9.0f, 10.0f, 11.0f,
344 12.0f, 13.0f, 14.0f, 15.0f };
347 DALI_TEST_EQUALS(m.GetTranslation3(), Vector3(12.0f, 13.0f, 14.0f), TEST_LOCATION);
352 int UtcDaliMatrixSetIdentity(void)
354 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
355 4.0f, 5.0f, 6.0f, 7.0f,
356 8.0f, 9.0f, 10.0f, 11.0f,
357 12.0f, 13.0f, 14.0f, 15.0f };
361 DALI_TEST_EQUALS(m, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
366 int UtcDaliMatrixSetIdentityAndScale(void)
368 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
369 4.0f, 5.0f, 6.0f, 7.0f,
370 8.0f, 9.0f, 10.0f, 11.0f,
371 12.0f, 13.0f, 14.0f, 15.0f };
373 m.SetIdentityAndScale(Vector3(4.0f, 4.0f, 4.0f));
375 float els2[] = { 4.0f, 0.0f, 0.0f, 0.0f,
376 0.0f, 4.0f, 0.0f, 0.0f,
377 0.0f, 0.0f, 4.0f, 0.0f,
378 0.0f, 0.0f, 0.0f, 1.0f };
381 DALI_TEST_EQUALS(m, r, 0.001f, TEST_LOCATION);
387 int UtcDaliMatrixSetXAxis(void)
390 Vector3 v(2.0f, 3.0f, 4.0f);
393 DALI_TEST_CHECK(m.GetXAxis() == v);
398 int UtcDaliMatrixSetYAxis(void)
401 Vector3 v(2.0f, 3.0f, 4.0f);
404 DALI_TEST_CHECK(m.GetYAxis() == v);
409 int UtcDaliMatrixSetZAxis(void)
412 Vector3 v(2.0f, 3.0f, 4.0f);
415 DALI_TEST_CHECK(m.GetZAxis() == v);
420 int UtcDaliMatrixSetTranslation(void)
423 Vector4 v(2.0f, 3.0f, 4.0f, 5.0f);
426 DALI_TEST_CHECK(m.GetTranslation() == v);
431 int UtcDaliMatrixSetTranslation3(void)
434 Vector3 v(2.0f, 3.0f, 4.0f);
437 DALI_TEST_CHECK(m.GetTranslation3() == v);
444 int UtcDaliMatrixTranspose(void)
447 { 0.0f, 1.0f, 2.0f, 3.0f,
448 4.0f, 5.0f, 6.0f, 7.0f,
449 8.0f, 9.0f, 10.0f, 11.0f,
450 12.0f, 13.0f, 14.0f, 15.0f
458 for (int x=0;x<4;++x)
460 for (int y=0;y<4;++y)
462 success &= (m.AsFloat()[x+y*4] == floats[x*4+y]);
466 DALI_TEST_CHECK(success);
470 int UtcDaliMatrixOStreamOperator(void)
472 std::ostringstream oss;
475 matrix.SetIdentity();
479 std::string expectedOutput = "[ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]";
481 DALI_TEST_EQUALS( oss.str(), expectedOutput, TEST_LOCATION);
485 int UtcDaliMatrixMultiply(void)
487 Matrix m1 = Matrix::IDENTITY;
489 float els[] = { 1.0f, 0.0f, 0.0f, 0.0f,
490 0.0f, 0.707f, 0.707f, 0.0f,
491 0.0f, -0.707f, 0.707f, 0.0f,
492 0.0f, 0.0f, 0.0f, 1.0f };
495 Quaternion q(Radian(Degree(45.0f)), Vector3::XAXIS);
497 Matrix::Multiply(m2, m1, q);
499 DALI_TEST_EQUALS(m2, result, 0.01f, TEST_LOCATION);
503 int UtcDaliMatrixOperatorMultiply01(void)
505 Vector4 v1(2.0f, 5.0f, 4.0f, 0.0f);
507 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
508 0.0f, 3.0f, 0.0f, 0.0f,
509 0.0f, 0.0f, 4.0f, 0.0f,
510 0.0f, 0.0f, 0.0f, 1.0f };
513 Vector4 v2 = m1 * v1;
514 Vector4 r1(4.0f, 15.0f, 16.0f, 0.0f);
515 DALI_TEST_EQUALS(v2, r1, 0.01f, TEST_LOCATION);
519 int UtcDaliMatrixOperatorMultiply02(void)
521 TestApplication application;
523 Vector3 position ( 30.f, 40.f, 50.f);
527 m1.SetTranslation(-position);
529 Vector4 positionV4(position);
531 Vector4 output = m1 * positionV4;
534 DALI_TEST_EQUALS(output, Vector4::ZERO, 0.01f, TEST_LOCATION);
538 int UtcDaliMatrixOperatorEquals(void)
540 Matrix m1 = Matrix::IDENTITY;
542 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};
544 DALI_TEST_EQUALS(m1 == r2, true, TEST_LOCATION);
546 float *f = m1.AsFloat();
547 for(size_t i=0; i<16; i++)
550 DALI_TEST_EQUALS(m1 == r2, false, TEST_LOCATION);
556 int UtcDaliMatrixOperatorNotEquals(void)
558 Matrix m1 = Matrix::IDENTITY;
559 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
560 0.0f, 3.0f, 0.0f, 0.0f,
561 0.0f, 0.0f, 4.0f, 0.0f,
562 0.0f, 0.0f, 0.0f, 1.0f };
565 DALI_TEST_CHECK(m1 != r1);
566 DALI_TEST_CHECK(!(m1 != m1));
570 int UtcDaliMatrixGetTransformComponents01(void)
572 Matrix m2(Matrix::IDENTITY.AsFloat());
576 m2.GetTransformComponents(pos2, q2, scale2);
577 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
578 DALI_TEST_EQUALS(Vector3(1.0f, 1.0f, 1.0f), scale2, 0.001, TEST_LOCATION);
579 DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
584 int UtcDaliMatrixGetTransformComponents02(void)
586 // Create an arbitrary vector
587 for( float x=-1.0f; x<=1.0f; x+=0.1f )
589 for( float y=-1.0f; y<1.0f; y+=0.1f )
591 for( float z=-1.0f; z<1.0f; z+=0.1f )
593 Vector3 vForward(x, y, z);
594 vForward.Normalize();
596 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
598 Quaternion rotation1(Radian(Degree(angle)), vForward);
599 Vector3 scale1(2.0f, 3.0f, 4.0f);
600 Vector3 position1(1.0f, 2.0f, 3.0f);
603 m1.SetTransformComponents(scale1, rotation1, position1);
606 Quaternion rotation2;
608 m1.GetTransformComponents(position2, rotation2, scale2);
610 DALI_TEST_EQUALS(position1, position2, 0.001, TEST_LOCATION);
611 DALI_TEST_EQUALS(scale1, scale2, 0.001, TEST_LOCATION);
612 DALI_TEST_EQUALS(rotation1, rotation2, 0.001, TEST_LOCATION);
620 int UtcDaliMatrixSetTransformComponents01(void)
622 // Create an arbitrary vector
623 for( float x=-1.0f; x<=1.0f; x+=0.1f )
625 for( float y=-1.0f; y<1.0f; y+=0.1f )
627 for( float z=-1.0f; z<1.0f; z+=0.1f )
629 Vector3 vForward(x, y, z);
630 vForward.Normalize();
632 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
634 Quaternion rotation1(Radian(Degree(angle)), vForward);
636 Matrix m1(rotation1);
637 Matrix result1(false);
638 Vector3 vForward3(vForward.x, vForward.y, vForward.z);
639 result1.SetTransformComponents( Vector3::ONE, Quaternion(Radian(Degree(angle)), vForward3), Vector3::ZERO );
641 DALI_TEST_EQUALS(m1, result1, 0.001, TEST_LOCATION);
644 m2.SetTransformComponents(vForward, Quaternion::IDENTITY, Vector3::ZERO);
646 Matrix result2a(Matrix::IDENTITY);
647 result2a.SetXAxis(result2a.GetXAxis() * vForward[0]);
648 result2a.SetYAxis(result2a.GetYAxis() * vForward[1]);
649 result2a.SetZAxis(result2a.GetZAxis() * vForward[2]);
651 DALI_TEST_EQUALS(m2, result2a, 0.001, TEST_LOCATION);
654 m3.SetTransformComponents(vForward, rotation1, Vector3::ZERO);
656 Matrix result3(Matrix::IDENTITY);
657 result3.SetXAxis(result3.GetXAxis() * vForward[0]);
658 result3.SetYAxis(result3.GetYAxis() * vForward[1]);
659 result3.SetZAxis(result3.GetZAxis() * vForward[2]);
661 Matrix::Multiply(result3, result3, m1);
662 DALI_TEST_EQUALS(m3, result3, 0.001, TEST_LOCATION);
671 int UtcDaliMatrixSetInverseTransformComponent01(void)
673 // Create an arbitrary vector
674 for( float x=-1.0f; x<=1.0f; x+=0.1f )
676 for( float y=-1.0f; y<1.0f; y+=0.1f )
678 for( float z=-1.0f; z<1.0f; z+=0.1f )
680 Vector3 vForward(x, y, z);
681 vForward.Normalize();
683 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
685 Quaternion rotation1(Radian(Degree(angle)), vForward);
686 Vector3 scale1(2.0f, 3.0f, 4.0f);
687 Vector3 position1(1.0f, 2.0f, 3.0f);
690 m1.SetTransformComponents(scale1, rotation1, position1);
693 m2.SetInverseTransformComponents(scale1, rotation1, position1);
696 Matrix::Multiply(result, m1, m2);
698 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
706 int UtcDaliMatrixSetInverseTransformComponent02(void)
708 // Create an arbitrary vector
709 for( float x=-1.0f; x<=1.0f; x+=0.1f )
711 for( float y=-1.0f; y<1.0f; y+=0.1f )
713 for( float z=-1.0f; z<1.0f; z+=0.1f )
715 Vector3 vForward(x, y, z);
716 vForward.Normalize();
718 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
720 Quaternion rotation1(Radian(Degree(angle)), vForward);
721 Matrix rotationMatrix(rotation1); // TEST RELIES ON THIS METHOD WORKING!!!
723 Vector3 position1(5.0f, -6.0f, 7.0f);
726 m1.SetTransformComponents( Vector3::ONE, rotation1, position1 );
729 m2.SetInverseTransformComponents( rotationMatrix.GetXAxis(),
730 rotationMatrix.GetYAxis(),
731 rotationMatrix.GetZAxis(),
735 Matrix::Multiply(result, m1, m2);
737 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);