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 UtcDaliMatrixConstructor01P(void)
43 bool initialised = true;
45 float* els = m2.AsFloat();
46 for(size_t idx=0; idx<16; ++idx, ++els)
53 DALI_TEST_EQUALS(initialised, false, TEST_LOCATION);
58 int UtcDaliMatrixConstructor02P(void)
60 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};
63 float* els = m.AsFloat();
65 bool initialised = true;
66 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
71 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
76 int UtcDaliMatrixConstructor03P(void)
78 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};
83 float* els = ma.AsFloat();
84 float* init = mb.AsFloat();
85 bool initialised = true;
86 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
91 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
96 int UtcDaliMatrixConstructor04P(void)
98 Quaternion q(Quaternion::IDENTITY);
100 DALI_TEST_EQUALS(Matrix(Matrix::IDENTITY), m, 0.001, TEST_LOCATION);
104 int UtcDaliMatrixAssignP(void)
106 Matrix a(Matrix::IDENTITY);
108 DALI_TEST_EQUALS(a, b, 0.001, TEST_LOCATION);
112 int UtcDaliMatrixAssign02P(void)
114 Matrix a(Matrix::IDENTITY);
115 a = a; // self assign does the do nothing branch
116 DALI_TEST_EQUALS(Matrix(Matrix::IDENTITY), a, 0.001, TEST_LOCATION);
120 int UtcDaliMatrixSetIdentityP(void)
122 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
123 4.0f, 5.0f, 6.0f, 7.0f,
124 8.0f, 9.0f, 10.0f, 11.0f,
125 12.0f, 13.0f, 14.0f, 15.0f };
129 DALI_TEST_EQUALS(m, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
133 int UtcDaliMatrixSetIdentityAndScaleP(void)
135 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
136 4.0f, 5.0f, 6.0f, 7.0f,
137 8.0f, 9.0f, 10.0f, 11.0f,
138 12.0f, 13.0f, 14.0f, 15.0f };
140 m.SetIdentityAndScale(Vector3(4.0f, 4.0f, 4.0f));
142 float els2[] = { 4.0f, 0.0f, 0.0f, 0.0f,
143 0.0f, 4.0f, 0.0f, 0.0f,
144 0.0f, 0.0f, 4.0f, 0.0f,
145 0.0f, 0.0f, 0.0f, 1.0f };
148 DALI_TEST_EQUALS(m, r, 0.001f, TEST_LOCATION);
152 int UtcDaliMatrixInvertTransformP(void)
154 for (int i=0;i<1000;++i)
157 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
159 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
163 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
166 m0.InvertTransform(m1);
169 Matrix::Multiply( m2, m0, m1 );
171 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
176 int UtcDaliMatrixInvertTransformN(void)
178 std::string exceptionString( "EqualsZero( mMatrix[3] ) && EqualsZero( mMatrix[7] ) && EqualsZero( mMatrix[11] ) && Equals( mMatrix[15], 1.0f" );
181 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
182 4.0f, 5.0f, 6.0f, 7.0f,
183 8.0f, 9.0f, 10.0f, 11.0f,
184 12.0f, 13.0f, 14.0f, 15.0f };
188 m.InvertTransform(it);
189 tet_result(TET_FAIL);
191 catch (Dali::DaliException& e)
193 DALI_TEST_PRINT_ASSERT( e );
194 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
199 float els[] = { 0.0f, 1.0f, 2.0f, 0.0f,
200 4.0f, 5.0f, 6.0f, 7.0f,
201 8.0f, 9.0f, 10.0f, 11.0f,
202 12.0f, 13.0f, 14.0f, 15.0f };
206 m.InvertTransform(it);
207 tet_result(TET_FAIL);
209 catch (Dali::DaliException& e)
211 DALI_TEST_PRINT_ASSERT( e );
212 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
217 float els[] = { 0.0f, 1.0f, 2.0f, 0.0f,
218 4.0f, 5.0f, 6.0f, 0.0f,
219 8.0f, 9.0f, 10.0f, 11.0f,
220 12.0f, 13.0f, 14.0f, 15.0f };
224 m.InvertTransform(it);
225 tet_result(TET_FAIL);
227 catch (Dali::DaliException& e)
229 DALI_TEST_PRINT_ASSERT( e );
230 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
235 float els[] = { 0.0f, 1.0f, 2.0f, 0.0f,
236 4.0f, 5.0f, 6.0f, 0.0f,
237 8.0f, 9.0f, 10.0f, 0.0f,
238 12.0f, 13.0f, 14.0f, 15.0f };
242 m.InvertTransform(it);
243 tet_result(TET_FAIL);
245 catch (Dali::DaliException& e)
247 DALI_TEST_PRINT_ASSERT( e );
248 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
253 int UtcDaliMatrixInvert01P(void)
255 // We're going to invert a whole load of different matrices to make sure we don't
256 // fail on particular orientations.
257 for (int i=0;i<1000;++i)
260 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
262 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
266 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
272 Matrix::Multiply( m2, m0, m1 );
274 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
276 m1.Invert(); // doube invert - should be back to m0
278 DALI_TEST_EQUALS(m0, m1, 0.001f, TEST_LOCATION);
283 int UtcDaliMatrixInvert02P(void)
285 Matrix m1 = Matrix::IDENTITY;
286 m1.SetXAxis(Vector3(0.0f, 0.0f, 0.0f));
287 DALI_TEST_EQUALS(m1.Invert(), false, TEST_LOCATION);
291 int UtcDaliMatrixTransposeP(void)
294 { 0.0f, 1.0f, 2.0f, 3.0f,
295 4.0f, 5.0f, 6.0f, 7.0f,
296 8.0f, 9.0f, 10.0f, 11.0f,
297 12.0f, 13.0f, 14.0f, 15.0f
305 for (int x=0;x<4;++x)
307 for (int y=0;y<4;++y)
309 success &= (m.AsFloat()[x+y*4] == floats[x*4+y]);
313 DALI_TEST_CHECK(success);
317 int UtcDaliMatrixGetXAxisP(void)
319 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
320 4.0f, 5.0f, 6.0f, 7.0f,
321 8.0f, 9.0f, 10.0f, 11.0f,
322 12.0f, 13.0f, 14.0f, 15.0f };
325 DALI_TEST_CHECK(m.GetXAxis() == Vector3(0.0f, 1.0f, 2.0f));
329 int UtcDaliMatrixGetYAxisP(void)
331 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
332 4.0f, 5.0f, 6.0f, 7.0f,
333 8.0f, 9.0f, 10.0f, 11.0f,
334 12.0f, 13.0f, 14.0f, 15.0f };
337 DALI_TEST_CHECK(m.GetYAxis() == Vector3(4.0f, 5.0f, 6.0f));
341 int UtcDaliMatrixGetZAxisP(void)
343 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
344 4.0f, 5.0f, 6.0f, 7.0f,
345 8.0f, 9.0f, 10.0f, 11.0f,
346 12.0f, 13.0f, 14.0f, 15.0f };
349 DALI_TEST_CHECK(m.GetZAxis() == Vector3(8.0f, 9.0f, 10.0f));
353 int UtcDaliMatrixSetXAxisP(void)
356 Vector3 v(2.0f, 3.0f, 4.0f);
359 DALI_TEST_CHECK(m.GetXAxis() == v);
363 int UtcDaliMatrixSetYAxisP(void)
366 Vector3 v(2.0f, 3.0f, 4.0f);
369 DALI_TEST_CHECK(m.GetYAxis() == v);
373 int UtcDaliMatrixSetZAxisP(void)
376 Vector3 v(2.0f, 3.0f, 4.0f);
379 DALI_TEST_CHECK(m.GetZAxis() == v);
383 int UtcDaliMatrixGetTranslationP(void)
385 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
386 4.0f, 5.0f, 6.0f, 7.0f,
387 8.0f, 9.0f, 10.0f, 11.0f,
388 12.0f, 13.0f, 14.0f, 15.0f };
391 DALI_TEST_EQUALS(m.GetTranslation(), Vector4(12.0f, 13.0f, 14.0f, 15.0f), TEST_LOCATION);
395 int UtcDaliMatrixGetTranslation3P(void)
397 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
398 4.0f, 5.0f, 6.0f, 7.0f,
399 8.0f, 9.0f, 10.0f, 11.0f,
400 12.0f, 13.0f, 14.0f, 15.0f };
403 DALI_TEST_EQUALS(m.GetTranslation3(), Vector3(12.0f, 13.0f, 14.0f), TEST_LOCATION);
407 int UtcDaliMatrixSetTranslationP(void)
410 Vector4 v(2.0f, 3.0f, 4.0f, 5.0f);
413 DALI_TEST_CHECK(m.GetTranslation() == v);
417 int UtcDaliMatrixSetTranslation3P(void)
420 Vector3 v(2.0f, 3.0f, 4.0f);
423 DALI_TEST_CHECK(m.GetTranslation3() == v);
427 int UtcDaliMatrixOrthoNormalize0P(void)
429 // OrthoNormalise fixes floating point errors from matrix rotations
433 for (int i=0;i<1000;++i)
436 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
439 m.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), Vector3::ZERO );
444 success &= fabsf(m.GetXAxis().Dot(m.GetYAxis())) < 0.001f;
445 success &= fabsf(m.GetYAxis().Dot(m.GetXAxis())) < 0.001f;
446 success &= fabsf(m.GetZAxis().Dot(m.GetYAxis())) < 0.001f;
448 success &= fabsf(m.GetXAxis().Length() - 1.0f) < 0.001f;
449 success &= fabsf(m.GetYAxis().Length() - 1.0f) < 0.001f;
450 success &= fabsf(m.GetZAxis().Length() - 1.0f) < 0.001f;
452 DALI_TEST_CHECK(success);
456 int UtcDaliMatrixOrthoNormalize1P(void)
458 // OrthoNormalize is not flipping the axes and is maintaining the translation
459 for (int i=0;i<1000;++i)
462 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
464 Vector3 center(10.0f, 15.0f, 5.0f);
468 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
473 DALI_TEST_EQUALS(m0.GetXAxis(), m1.GetXAxis(), 0.001f, TEST_LOCATION);
474 DALI_TEST_EQUALS(m0.GetYAxis(), m1.GetYAxis(), 0.001f, TEST_LOCATION);
475 DALI_TEST_EQUALS(m0.GetZAxis(), m1.GetZAxis(), 0.001f, TEST_LOCATION);
476 DALI_TEST_EQUALS(m0.GetTranslation(), m1.GetTranslation(), 0.001f, TEST_LOCATION);
481 int UtcDaliMatrixConstAsFloatP(void)
483 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};
486 const float* els = m.AsFloat();
487 const float* init = r;
488 bool initialised = true;
489 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
494 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
500 int UtcDaliMatrixAsFloatP(void)
502 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};
505 float* els = m.AsFloat();
507 bool initialised = true;
508 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
513 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
519 int UtcDaliMatrixMultiplyP(void)
521 Matrix m1 = Matrix::IDENTITY;
523 float els[] = { 1.0f, 0.0f, 0.0f, 0.0f,
524 0.0f, 0.707f, 0.707f, 0.0f,
525 0.0f, -0.707f, 0.707f, 0.0f,
526 0.0f, 0.0f, 0.0f, 1.0f };
529 Quaternion q(Radian(Degree(45.0f)), Vector3::XAXIS);
531 Matrix::Multiply(m2, m1, q);
533 DALI_TEST_EQUALS(m2, result, 0.01f, TEST_LOCATION);
537 int UtcDaliMatrixOperatorMultiply01P(void)
539 Vector4 v1(2.0f, 5.0f, 4.0f, 0.0f);
541 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
542 0.0f, 3.0f, 0.0f, 0.0f,
543 0.0f, 0.0f, 4.0f, 0.0f,
544 0.0f, 0.0f, 0.0f, 1.0f };
547 Vector4 v2 = m1 * v1;
548 Vector4 r1(4.0f, 15.0f, 16.0f, 0.0f);
549 DALI_TEST_EQUALS(v2, r1, 0.01f, TEST_LOCATION);
553 int UtcDaliMatrixOperatorMultiply02P(void)
555 TestApplication application;
557 Vector3 position ( 30.f, 40.f, 50.f);
561 m1.SetTranslation(-position);
563 Vector4 positionV4(position);
565 Vector4 output = m1 * positionV4;
568 DALI_TEST_EQUALS(output, Vector4::ZERO, 0.01f, TEST_LOCATION);
572 int UtcDaliMatrixOperatorEqualsP(void)
574 Matrix m1 = Matrix::IDENTITY;
576 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};
578 DALI_TEST_EQUALS(m1 == r2, true, TEST_LOCATION);
580 float *f = m1.AsFloat();
581 for(size_t i=0; i<16; i++)
584 DALI_TEST_EQUALS(m1 == r2, false, TEST_LOCATION);
589 int UtcDaliMatrixOperatorNotEqualsP(void)
591 Matrix m1 = Matrix::IDENTITY;
592 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
593 0.0f, 3.0f, 0.0f, 0.0f,
594 0.0f, 0.0f, 4.0f, 0.0f,
595 0.0f, 0.0f, 0.0f, 1.0f };
598 DALI_TEST_CHECK(m1 != r1);
599 DALI_TEST_CHECK(!(m1 != m1));
603 int UtcDaliMatrixSetTransformComponents01P(void)
605 // Create an arbitrary vector
606 for( float x=-1.0f; x<=1.0f; x+=0.1f )
608 for( float y=-1.0f; y<1.0f; y+=0.1f )
610 for( float z=-1.0f; z<1.0f; z+=0.1f )
612 Vector3 vForward(x, y, z);
613 vForward.Normalize();
615 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
617 Quaternion rotation1(Radian(Degree(angle)), vForward);
619 Matrix m1(rotation1);
620 Matrix result1(false);
621 Vector3 vForward3(vForward.x, vForward.y, vForward.z);
622 result1.SetTransformComponents( Vector3::ONE, Quaternion(Radian(Degree(angle)), vForward3), Vector3::ZERO );
624 DALI_TEST_EQUALS(m1, result1, 0.001, TEST_LOCATION);
627 m2.SetTransformComponents(vForward, Quaternion::IDENTITY, Vector3::ZERO);
629 Matrix result2a(Matrix::IDENTITY);
630 result2a.SetXAxis(result2a.GetXAxis() * vForward[0]);
631 result2a.SetYAxis(result2a.GetYAxis() * vForward[1]);
632 result2a.SetZAxis(result2a.GetZAxis() * vForward[2]);
634 DALI_TEST_EQUALS(m2, result2a, 0.001, TEST_LOCATION);
637 m3.SetTransformComponents(vForward, rotation1, Vector3::ZERO);
639 Matrix result3(Matrix::IDENTITY);
640 result3.SetXAxis(result3.GetXAxis() * vForward[0]);
641 result3.SetYAxis(result3.GetYAxis() * vForward[1]);
642 result3.SetZAxis(result3.GetZAxis() * vForward[2]);
644 Matrix::Multiply(result3, result3, m1);
645 DALI_TEST_EQUALS(m3, result3, 0.001, TEST_LOCATION);
653 int UtcDaliMatrixSetInverseTransformComponent01P(void)
655 // Create an arbitrary vector
656 for( float x=-1.0f; x<=1.0f; x+=0.1f )
658 for( float y=-1.0f; y<1.0f; y+=0.1f )
660 for( float z=-1.0f; z<1.0f; z+=0.1f )
662 Vector3 vForward(x, y, z);
663 vForward.Normalize();
666 Quaternion rotation1(Quaternion::IDENTITY); // test no rotation branch
667 Vector3 scale1(2.0f, 3.0f, 4.0f);
668 Vector3 position1(1.0f, 2.0f, 3.0f);
671 m1.SetTransformComponents(scale1, rotation1, position1);
674 m2.SetInverseTransformComponents(scale1, rotation1, position1);
677 Matrix::Multiply(result, m1, m2);
679 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
687 int UtcDaliMatrixSetInverseTransformComponent02P(void)
689 // Create an arbitrary vector
690 for( float x=-1.0f; x<=1.0f; x+=0.1f )
692 for( float y=-1.0f; y<1.0f; y+=0.1f )
694 for( float z=-1.0f; z<1.0f; z+=0.1f )
696 Vector3 vForward(x, y, z);
697 vForward.Normalize();
699 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
701 Quaternion rotation1(Radian(Degree(angle)), vForward);
702 Matrix rotationMatrix(rotation1); // TEST RELIES ON THIS METHOD WORKING!!!
704 Vector3 position1(5.0f, -6.0f, 7.0f);
707 m1.SetTransformComponents( Vector3::ONE, rotation1, position1 );
710 m2.SetInverseTransformComponents( rotationMatrix.GetXAxis(),
711 rotationMatrix.GetYAxis(),
712 rotationMatrix.GetZAxis(),
716 Matrix::Multiply(result, m1, m2);
718 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
726 int UtcDaliMatrixGetTransformComponents01P(void)
728 Matrix m2(Matrix::IDENTITY.AsFloat());
732 m2.GetTransformComponents(pos2, q2, scale2);
733 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
734 DALI_TEST_EQUALS(Vector3(1.0f, 1.0f, 1.0f), scale2, 0.001, TEST_LOCATION);
735 DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
740 int UtcDaliMatrixGetTransformComponents02P(void)
742 // Create an arbitrary vector
743 for( float x=-1.0f; x<=1.0f; x+=0.1f )
745 for( float y=-1.0f; y<1.0f; y+=0.1f )
747 for( float z=-1.0f; z<1.0f; z+=0.1f )
749 Vector3 vForward(x, y, z);
750 vForward.Normalize();
752 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
754 Quaternion rotation1(Radian(Degree(angle)), vForward);
755 Vector3 scale1(2.0f, 3.0f, 4.0f);
756 Vector3 position1(1.0f, 2.0f, 3.0f);
759 m1.SetTransformComponents(scale1, rotation1, position1);
762 Quaternion rotation2;
764 m1.GetTransformComponents(position2, rotation2, scale2);
766 DALI_TEST_EQUALS(position1, position2, 0.001, TEST_LOCATION);
767 DALI_TEST_EQUALS(scale1, scale2, 0.001, TEST_LOCATION);
768 DALI_TEST_EQUALS(rotation1, rotation2, 0.001, TEST_LOCATION);
776 int UtcDaliMatrixGetTransformComponents03P(void)
778 Matrix m2; // zero branch
782 m2.GetTransformComponents(pos2, q2, scale2);
783 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
784 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), scale2, 0.001, TEST_LOCATION);
785 // DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
789 int UtcDaliMatrixOStreamOperator(void)
791 std::ostringstream oss;
794 matrix.SetIdentity();
798 std::string expectedOutput = "[ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]";
800 DALI_TEST_EQUALS( oss.str(), expectedOutput, TEST_LOCATION);