2 * Copyright (c) 2019 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 UtcDaliMatrixConstructor01P(void)
41 // State of memory cannot be guaranteed, so use
42 // a buffer in a known state to check for changes
43 char buffer[sizeof(Matrix)];
45 memset(buffer, 1, sizeof(Matrix));
47 Matrix* m2 = new(&buffer) Matrix(false);
48 bool initialisation_occured = false;
50 float* els = m2->AsFloat();
51 for(size_t idx=0; idx<16; ++idx, ++els)
54 initialisation_occured = true;
58 DALI_TEST_EQUALS(initialisation_occured, false, TEST_LOCATION);
63 int UtcDaliMatrixConstructor02P(void)
65 float r[] = { 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};
68 float* els = m.AsFloat();
70 bool initialised = true;
71 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
76 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
81 int UtcDaliMatrixConstructor03P(void)
83 float r[] = { 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};
88 float* els = ma.AsFloat();
89 float* init = mb.AsFloat();
90 bool initialised = true;
91 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
96 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
101 int UtcDaliMatrixConstructor04P(void)
103 Quaternion q(Quaternion::IDENTITY);
105 DALI_TEST_EQUALS(Matrix(Matrix::IDENTITY), m, 0.001, TEST_LOCATION);
109 int UtcDaliMatrixAssignP(void)
111 Matrix a(Matrix::IDENTITY);
113 DALI_TEST_EQUALS(a, b, 0.001, TEST_LOCATION);
117 int UtcDaliMatrixAssign02P(void)
119 Matrix a(Matrix::IDENTITY);
120 a = a; // self assign does the do nothing branch
121 DALI_TEST_EQUALS(Matrix(Matrix::IDENTITY), a, 0.001, TEST_LOCATION);
125 int UtcDaliMatrixSetIdentityP(void)
127 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
128 4.0f, 5.0f, 6.0f, 7.0f,
129 8.0f, 9.0f, 10.0f, 11.0f,
130 12.0f, 13.0f, 14.0f, 15.0f };
134 DALI_TEST_EQUALS(m, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
138 int UtcDaliMatrixSetIdentityAndScaleP(void)
140 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
141 4.0f, 5.0f, 6.0f, 7.0f,
142 8.0f, 9.0f, 10.0f, 11.0f,
143 12.0f, 13.0f, 14.0f, 15.0f };
145 m.SetIdentityAndScale(Vector3(4.0f, 4.0f, 4.0f));
147 float els2[] = { 4.0f, 0.0f, 0.0f, 0.0f,
148 0.0f, 4.0f, 0.0f, 0.0f,
149 0.0f, 0.0f, 4.0f, 0.0f,
150 0.0f, 0.0f, 0.0f, 1.0f };
153 DALI_TEST_EQUALS(m, r, 0.001f, TEST_LOCATION);
157 int UtcDaliMatrixInvertTransformP(void)
159 for (int i=0;i<1000;++i)
162 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
164 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
168 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
171 m0.InvertTransform(m1);
174 Matrix::Multiply( m2, m0, m1 );
176 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
181 int UtcDaliMatrixInvertTransformN(void)
183 std::string exceptionString( "EqualsZero( mMatrix[3] ) && EqualsZero( mMatrix[7] ) && EqualsZero( mMatrix[11] ) && Equals( mMatrix[15], 1.0f" );
186 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
187 4.0f, 5.0f, 6.0f, 7.0f,
188 8.0f, 9.0f, 10.0f, 11.0f,
189 12.0f, 13.0f, 14.0f, 15.0f };
193 m.InvertTransform(it);
194 tet_result(TET_FAIL);
196 catch (Dali::DaliException& e)
198 DALI_TEST_PRINT_ASSERT( e );
199 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
204 float els[] = { 0.0f, 1.0f, 2.0f, 0.0f,
205 4.0f, 5.0f, 6.0f, 7.0f,
206 8.0f, 9.0f, 10.0f, 11.0f,
207 12.0f, 13.0f, 14.0f, 15.0f };
211 m.InvertTransform(it);
212 tet_result(TET_FAIL);
214 catch (Dali::DaliException& e)
216 DALI_TEST_PRINT_ASSERT( e );
217 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
222 float els[] = { 0.0f, 1.0f, 2.0f, 0.0f,
223 4.0f, 5.0f, 6.0f, 0.0f,
224 8.0f, 9.0f, 10.0f, 11.0f,
225 12.0f, 13.0f, 14.0f, 15.0f };
229 m.InvertTransform(it);
230 tet_result(TET_FAIL);
232 catch (Dali::DaliException& e)
234 DALI_TEST_PRINT_ASSERT( e );
235 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
240 float els[] = { 0.0f, 1.0f, 2.0f, 0.0f,
241 4.0f, 5.0f, 6.0f, 0.0f,
242 8.0f, 9.0f, 10.0f, 0.0f,
243 12.0f, 13.0f, 14.0f, 15.0f };
247 m.InvertTransform(it);
248 tet_result(TET_FAIL);
250 catch (Dali::DaliException& e)
252 DALI_TEST_PRINT_ASSERT( e );
253 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
258 int UtcDaliMatrixInvert01P(void)
260 // We're going to invert a whole load of different matrices to make sure we don't
261 // fail on particular orientations.
262 for (int i=0;i<1000;++i)
265 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
267 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
271 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
277 Matrix::Multiply( m2, m0, m1 );
279 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
281 m1.Invert(); // doube invert - should be back to m0
283 DALI_TEST_EQUALS(m0, m1, 0.001f, TEST_LOCATION);
288 int UtcDaliMatrixInvert02P(void)
290 Matrix m1 = Matrix::IDENTITY;
291 m1.SetXAxis(Vector3(0.0f, 0.0f, 0.0f));
292 DALI_TEST_EQUALS(m1.Invert(), false, TEST_LOCATION);
296 int UtcDaliMatrixTransposeP(void)
299 { 0.0f, 1.0f, 2.0f, 3.0f,
300 4.0f, 5.0f, 6.0f, 7.0f,
301 8.0f, 9.0f, 10.0f, 11.0f,
302 12.0f, 13.0f, 14.0f, 15.0f
310 for (int x=0;x<4;++x)
312 for (int y=0;y<4;++y)
314 success &= (m.AsFloat()[x+y*4] == floats[x*4+y]);
318 DALI_TEST_CHECK(success);
322 int UtcDaliMatrixGetXAxisP(void)
324 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
325 4.0f, 5.0f, 6.0f, 7.0f,
326 8.0f, 9.0f, 10.0f, 11.0f,
327 12.0f, 13.0f, 14.0f, 15.0f };
330 DALI_TEST_CHECK(m.GetXAxis() == Vector3(0.0f, 1.0f, 2.0f));
334 int UtcDaliMatrixGetYAxisP(void)
336 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
337 4.0f, 5.0f, 6.0f, 7.0f,
338 8.0f, 9.0f, 10.0f, 11.0f,
339 12.0f, 13.0f, 14.0f, 15.0f };
342 DALI_TEST_CHECK(m.GetYAxis() == Vector3(4.0f, 5.0f, 6.0f));
346 int UtcDaliMatrixGetZAxisP(void)
348 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
349 4.0f, 5.0f, 6.0f, 7.0f,
350 8.0f, 9.0f, 10.0f, 11.0f,
351 12.0f, 13.0f, 14.0f, 15.0f };
354 DALI_TEST_CHECK(m.GetZAxis() == Vector3(8.0f, 9.0f, 10.0f));
358 int UtcDaliMatrixSetXAxisP(void)
361 Vector3 v(2.0f, 3.0f, 4.0f);
364 DALI_TEST_CHECK(m.GetXAxis() == v);
368 int UtcDaliMatrixSetYAxisP(void)
371 Vector3 v(2.0f, 3.0f, 4.0f);
374 DALI_TEST_CHECK(m.GetYAxis() == v);
378 int UtcDaliMatrixSetZAxisP(void)
381 Vector3 v(2.0f, 3.0f, 4.0f);
384 DALI_TEST_CHECK(m.GetZAxis() == v);
388 int UtcDaliMatrixGetTranslationP(void)
390 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
391 4.0f, 5.0f, 6.0f, 7.0f,
392 8.0f, 9.0f, 10.0f, 11.0f,
393 12.0f, 13.0f, 14.0f, 15.0f };
396 DALI_TEST_EQUALS(m.GetTranslation(), Vector4(12.0f, 13.0f, 14.0f, 15.0f), TEST_LOCATION);
400 int UtcDaliMatrixGetTranslation3P(void)
402 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
403 4.0f, 5.0f, 6.0f, 7.0f,
404 8.0f, 9.0f, 10.0f, 11.0f,
405 12.0f, 13.0f, 14.0f, 15.0f };
408 DALI_TEST_EQUALS(m.GetTranslation3(), Vector3(12.0f, 13.0f, 14.0f), TEST_LOCATION);
412 int UtcDaliMatrixSetTranslationP(void)
415 Vector4 v(2.0f, 3.0f, 4.0f, 5.0f);
418 DALI_TEST_CHECK(m.GetTranslation() == v);
422 int UtcDaliMatrixSetTranslation3P(void)
425 Vector3 v(2.0f, 3.0f, 4.0f);
428 DALI_TEST_CHECK(m.GetTranslation3() == v);
432 int UtcDaliMatrixOrthoNormalize0P(void)
434 // OrthoNormalise fixes floating point errors from matrix rotations
438 for (int i=0;i<1000;++i)
441 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
444 m.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), Vector3::ZERO );
449 success &= fabsf(m.GetXAxis().Dot(m.GetYAxis())) < 0.001f;
450 success &= fabsf(m.GetYAxis().Dot(m.GetXAxis())) < 0.001f;
451 success &= fabsf(m.GetZAxis().Dot(m.GetYAxis())) < 0.001f;
453 success &= fabsf(m.GetXAxis().Length() - 1.0f) < 0.001f;
454 success &= fabsf(m.GetYAxis().Length() - 1.0f) < 0.001f;
455 success &= fabsf(m.GetZAxis().Length() - 1.0f) < 0.001f;
457 DALI_TEST_CHECK(success);
461 int UtcDaliMatrixOrthoNormalize1P(void)
463 // OrthoNormalize is not flipping the axes and is maintaining the translation
464 for (int i=0;i<1000;++i)
467 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
469 Vector3 center(10.0f, 15.0f, 5.0f);
473 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
478 DALI_TEST_EQUALS(m0.GetXAxis(), m1.GetXAxis(), 0.001f, TEST_LOCATION);
479 DALI_TEST_EQUALS(m0.GetYAxis(), m1.GetYAxis(), 0.001f, TEST_LOCATION);
480 DALI_TEST_EQUALS(m0.GetZAxis(), m1.GetZAxis(), 0.001f, TEST_LOCATION);
481 DALI_TEST_EQUALS(m0.GetTranslation(), m1.GetTranslation(), 0.001f, TEST_LOCATION);
486 int UtcDaliMatrixConstAsFloatP(void)
488 float r[] = { 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};
491 const float* els = m.AsFloat();
492 const float* init = r;
493 bool initialised = true;
494 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
499 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
505 int UtcDaliMatrixAsFloatP(void)
507 float r[] = { 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};
510 float* els = m.AsFloat();
512 bool initialised = true;
513 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
518 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
524 int UtcDaliMatrixMultiplyP(void)
526 Matrix m1 = Matrix::IDENTITY;
528 float els[] = { 1.0f, 0.0f, 0.0f, 0.0f,
529 0.0f, 0.707f, 0.707f, 0.0f,
530 0.0f, -0.707f, 0.707f, 0.0f,
531 0.0f, 0.0f, 0.0f, 1.0f };
534 Quaternion q(Radian(Degree(45.0f)), Vector3::XAXIS);
536 Matrix::Multiply(m2, m1, q);
538 DALI_TEST_EQUALS(m2, result, 0.01f, TEST_LOCATION);
542 int UtcDaliMatrixOperatorMultiply01P(void)
544 Vector4 v1(2.0f, 5.0f, 4.0f, 0.0f);
546 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
547 0.0f, 3.0f, 0.0f, 0.0f,
548 0.0f, 0.0f, 4.0f, 0.0f,
549 0.0f, 0.0f, 0.0f, 1.0f };
552 Vector4 v2 = m1 * v1;
553 Vector4 r1(4.0f, 15.0f, 16.0f, 0.0f);
554 DALI_TEST_EQUALS(v2, r1, 0.01f, TEST_LOCATION);
558 int UtcDaliMatrixOperatorMultiply02P(void)
560 TestApplication application;
562 Vector3 position ( 30.f, 40.f, 50.f);
566 m1.SetTranslation(-position);
568 Vector4 positionV4(position);
570 Vector4 output = m1 * positionV4;
573 DALI_TEST_EQUALS(output, Vector4::ZERO, 0.01f, TEST_LOCATION);
577 int UtcDaliMatrixOperatorEqualsP(void)
579 Matrix m1 = Matrix::IDENTITY;
581 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};
583 DALI_TEST_EQUALS(m1 == r2, true, TEST_LOCATION);
585 float *f = m1.AsFloat();
586 for(size_t i=0; i<16; i++)
589 DALI_TEST_EQUALS(m1 == r2, false, TEST_LOCATION);
594 int UtcDaliMatrixOperatorNotEqualsP(void)
596 Matrix m1 = Matrix::IDENTITY;
597 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
598 0.0f, 3.0f, 0.0f, 0.0f,
599 0.0f, 0.0f, 4.0f, 0.0f,
600 0.0f, 0.0f, 0.0f, 1.0f };
603 DALI_TEST_CHECK(m1 != r1);
604 DALI_TEST_CHECK(!(m1 != m1));
608 int UtcDaliMatrixSetTransformComponents01P(void)
610 // Create an arbitrary vector
611 for( float x=-1.0f; x<=1.0f; x+=0.1f )
613 for( float y=-1.0f; y<1.0f; y+=0.1f )
615 for( float z=-1.0f; z<1.0f; z+=0.1f )
617 Vector3 vForward(x, y, z);
618 vForward.Normalize();
620 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
622 Quaternion rotation1(Radian(Degree(angle)), vForward);
624 Matrix m1(rotation1);
625 Matrix result1(false);
626 Vector3 vForward3(vForward.x, vForward.y, vForward.z);
627 result1.SetTransformComponents( Vector3::ONE, Quaternion(Radian(Degree(angle)), vForward3), Vector3::ZERO );
629 DALI_TEST_EQUALS(m1, result1, 0.001, TEST_LOCATION);
632 m2.SetTransformComponents(vForward, Quaternion::IDENTITY, Vector3::ZERO);
634 Matrix result2a(Matrix::IDENTITY);
635 result2a.SetXAxis(result2a.GetXAxis() * vForward[0]);
636 result2a.SetYAxis(result2a.GetYAxis() * vForward[1]);
637 result2a.SetZAxis(result2a.GetZAxis() * vForward[2]);
639 DALI_TEST_EQUALS(m2, result2a, 0.001, TEST_LOCATION);
642 m3.SetTransformComponents(vForward, rotation1, Vector3::ZERO);
644 Matrix result3(Matrix::IDENTITY);
645 result3.SetXAxis(result3.GetXAxis() * vForward[0]);
646 result3.SetYAxis(result3.GetYAxis() * vForward[1]);
647 result3.SetZAxis(result3.GetZAxis() * vForward[2]);
649 Matrix::Multiply(result3, result3, m1);
650 DALI_TEST_EQUALS(m3, result3, 0.001, TEST_LOCATION);
658 int UtcDaliMatrixSetInverseTransformComponent01P(void)
660 // Create an arbitrary vector
661 for( float x=-1.0f; x<=1.0f; x+=0.1f )
663 for( float y=-1.0f; y<1.0f; y+=0.1f )
665 for( float z=-1.0f; z<1.0f; z+=0.1f )
667 Vector3 vForward(x, y, z);
668 vForward.Normalize();
671 Quaternion rotation1(Quaternion::IDENTITY); // test no rotation branch
672 Vector3 scale1(2.0f, 3.0f, 4.0f);
673 Vector3 position1(1.0f, 2.0f, 3.0f);
676 m1.SetTransformComponents(scale1, rotation1, position1);
679 m2.SetInverseTransformComponents(scale1, rotation1, position1);
682 Matrix::Multiply(result, m1, m2);
684 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
692 int UtcDaliMatrixSetInverseTransformComponent02P(void)
694 // Create an arbitrary vector
695 for( float x=-1.0f; x<=1.0f; x+=0.1f )
697 for( float y=-1.0f; y<1.0f; y+=0.1f )
699 for( float z=-1.0f; z<1.0f; z+=0.1f )
701 Vector3 vForward(x, y, z);
702 vForward.Normalize();
704 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
706 Quaternion rotation1(Radian(Degree(angle)), vForward);
707 Matrix rotationMatrix(rotation1); // TEST RELIES ON THIS METHOD WORKING!!!
709 Vector3 position1(5.0f, -6.0f, 7.0f);
712 m1.SetTransformComponents( Vector3::ONE, rotation1, position1 );
715 m2.SetInverseTransformComponents( rotationMatrix.GetXAxis(),
716 rotationMatrix.GetYAxis(),
717 rotationMatrix.GetZAxis(),
721 Matrix::Multiply(result, m1, m2);
723 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
731 int UtcDaliMatrixGetTransformComponents01P(void)
733 Matrix m2(Matrix::IDENTITY.AsFloat());
737 m2.GetTransformComponents(pos2, q2, scale2);
738 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
739 DALI_TEST_EQUALS(Vector3(1.0f, 1.0f, 1.0f), scale2, 0.001, TEST_LOCATION);
740 DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
745 int UtcDaliMatrixGetTransformComponents02P(void)
747 // Create an arbitrary vector
748 for( float x=-1.0f; x<=1.0f; x+=0.1f )
750 for( float y=-1.0f; y<1.0f; y+=0.1f )
752 for( float z=-1.0f; z<1.0f; z+=0.1f )
754 Vector3 vForward(x, y, z);
755 vForward.Normalize();
757 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
759 Quaternion rotation1(Radian(Degree(angle)), vForward);
760 Vector3 scale1(2.0f, 3.0f, 4.0f);
761 Vector3 position1(1.0f, 2.0f, 3.0f);
764 m1.SetTransformComponents(scale1, rotation1, position1);
767 Quaternion rotation2;
769 m1.GetTransformComponents(position2, rotation2, scale2);
771 DALI_TEST_EQUALS(position1, position2, 0.001, TEST_LOCATION);
772 DALI_TEST_EQUALS(scale1, scale2, 0.001, TEST_LOCATION);
773 DALI_TEST_EQUALS(rotation1, rotation2, 0.001, TEST_LOCATION);
781 int UtcDaliMatrixGetTransformComponents03P(void)
783 Matrix m2; // zero branch
787 m2.GetTransformComponents(pos2, q2, scale2);
788 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
789 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), scale2, 0.001, TEST_LOCATION);
790 // DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
794 int UtcDaliMatrixOStreamOperator(void)
796 std::ostringstream oss;
799 matrix.SetIdentity();
803 std::string expectedOutput = "[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]";
805 DALI_TEST_EQUALS( oss.str(), expectedOutput, TEST_LOCATION);