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 UtcDaliMatrixSetIdentityP(void)
114 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
115 4.0f, 5.0f, 6.0f, 7.0f,
116 8.0f, 9.0f, 10.0f, 11.0f,
117 12.0f, 13.0f, 14.0f, 15.0f };
121 DALI_TEST_EQUALS(m, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
125 int UtcDaliMatrixSetIdentityAndScaleP(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 };
132 m.SetIdentityAndScale(Vector3(4.0f, 4.0f, 4.0f));
134 float els2[] = { 4.0f, 0.0f, 0.0f, 0.0f,
135 0.0f, 4.0f, 0.0f, 0.0f,
136 0.0f, 0.0f, 4.0f, 0.0f,
137 0.0f, 0.0f, 0.0f, 1.0f };
140 DALI_TEST_EQUALS(m, r, 0.001f, TEST_LOCATION);
144 int UtcDaliMatrixInvertTransform01P(void)
146 for (int i=0;i<1000;++i)
149 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
151 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
155 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
158 m0.InvertTransform(m1);
161 Matrix::Multiply( m2, m0, m1 );
163 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
168 int UtcDaliMatrixInvertTransform02P(void)
170 std::string exceptionString( "EqualsZero( mMatrix[3] ) && EqualsZero( mMatrix[7] ) && EqualsZero( mMatrix[11] ) && Equals( mMatrix[15], 1.0f" );
173 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
174 4.0f, 5.0f, 6.0f, 7.0f,
175 8.0f, 9.0f, 10.0f, 11.0f,
176 12.0f, 13.0f, 14.0f, 15.0f };
180 m.InvertTransform(it);
181 tet_result(TET_FAIL);
183 catch (Dali::DaliException& e)
185 DALI_TEST_PRINT_ASSERT( e );
186 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
191 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
192 4.0f, 5.0f, 6.0f, 7.0f,
193 8.0f, 9.0f, 10.0f, 11.0f,
194 12.0f, 13.0f, 14.0f, 15.0f };
198 m.InvertTransform(it);
199 tet_result(TET_FAIL);
201 catch (Dali::DaliException& e)
203 DALI_TEST_PRINT_ASSERT( e );
204 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
209 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
210 4.0f, 5.0f, 6.0f, 7.0f,
211 8.0f, 9.0f, 10.0f, 11.0f,
212 12.0f, 13.0f, 14.0f, 15.0f };
216 m.InvertTransform(it);
217 tet_result(TET_FAIL);
219 catch (Dali::DaliException& e)
221 DALI_TEST_PRINT_ASSERT( e );
222 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
227 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
228 4.0f, 5.0f, 6.0f, 7.0f,
229 8.0f, 9.0f, 10.0f, 11.0f,
230 12.0f, 13.0f, 14.0f, 15.0f };
234 m.InvertTransform(it);
235 tet_result(TET_FAIL);
237 catch (Dali::DaliException& e)
239 DALI_TEST_PRINT_ASSERT( e );
240 DALI_TEST_ASSERT( e, exceptionString, TEST_LOCATION );
245 int UtcDaliMatrixInvert01P(void)
247 // We're going to invert a whole load of different matrices to make sure we don't
248 // fail on particular orientations.
249 for (int i=0;i<1000;++i)
252 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
254 Vector3 center(f, cosf(f) * 100.0f, cosf(f*0.5f) * 50.0f);
258 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
264 Matrix::Multiply( m2, m0, m1 );
266 DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
268 m1.Invert(); // doube invert - should be back to m0
270 DALI_TEST_EQUALS(m0, m1, 0.001f, TEST_LOCATION);
275 int UtcDaliMatrixInvert02P(void)
277 Matrix m1 = Matrix::IDENTITY;
278 m1.SetXAxis(Vector3(0.0f, 0.0f, 0.0f));
279 DALI_TEST_EQUALS(m1.Invert(), false, TEST_LOCATION);
283 int UtcDaliMatrixTransposeP(void)
286 { 0.0f, 1.0f, 2.0f, 3.0f,
287 4.0f, 5.0f, 6.0f, 7.0f,
288 8.0f, 9.0f, 10.0f, 11.0f,
289 12.0f, 13.0f, 14.0f, 15.0f
297 for (int x=0;x<4;++x)
299 for (int y=0;y<4;++y)
301 success &= (m.AsFloat()[x+y*4] == floats[x*4+y]);
305 DALI_TEST_CHECK(success);
309 int UtcDaliMatrixGetXAxisP(void)
311 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
312 4.0f, 5.0f, 6.0f, 7.0f,
313 8.0f, 9.0f, 10.0f, 11.0f,
314 12.0f, 13.0f, 14.0f, 15.0f };
317 DALI_TEST_CHECK(m.GetXAxis() == Vector3(0.0f, 1.0f, 2.0f));
321 int UtcDaliMatrixGetYAxisP(void)
323 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
324 4.0f, 5.0f, 6.0f, 7.0f,
325 8.0f, 9.0f, 10.0f, 11.0f,
326 12.0f, 13.0f, 14.0f, 15.0f };
329 DALI_TEST_CHECK(m.GetYAxis() == Vector3(4.0f, 5.0f, 6.0f));
333 int UtcDaliMatrixGetZAxisP(void)
335 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
336 4.0f, 5.0f, 6.0f, 7.0f,
337 8.0f, 9.0f, 10.0f, 11.0f,
338 12.0f, 13.0f, 14.0f, 15.0f };
341 DALI_TEST_CHECK(m.GetZAxis() == Vector3(8.0f, 9.0f, 10.0f));
345 int UtcDaliMatrixSetXAxisP(void)
348 Vector3 v(2.0f, 3.0f, 4.0f);
351 DALI_TEST_CHECK(m.GetXAxis() == v);
355 int UtcDaliMatrixSetYAxisP(void)
358 Vector3 v(2.0f, 3.0f, 4.0f);
361 DALI_TEST_CHECK(m.GetYAxis() == v);
365 int UtcDaliMatrixSetZAxisP(void)
368 Vector3 v(2.0f, 3.0f, 4.0f);
371 DALI_TEST_CHECK(m.GetZAxis() == v);
375 int UtcDaliMatrixGetTranslationP(void)
377 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
378 4.0f, 5.0f, 6.0f, 7.0f,
379 8.0f, 9.0f, 10.0f, 11.0f,
380 12.0f, 13.0f, 14.0f, 15.0f };
383 DALI_TEST_EQUALS(m.GetTranslation(), Vector4(12.0f, 13.0f, 14.0f, 15.0f), TEST_LOCATION);
387 int UtcDaliMatrixGetTranslation3P(void)
389 float els[] = { 0.0f, 1.0f, 2.0f, 3.0f,
390 4.0f, 5.0f, 6.0f, 7.0f,
391 8.0f, 9.0f, 10.0f, 11.0f,
392 12.0f, 13.0f, 14.0f, 15.0f };
395 DALI_TEST_EQUALS(m.GetTranslation3(), Vector3(12.0f, 13.0f, 14.0f), TEST_LOCATION);
399 int UtcDaliMatrixSetTranslationP(void)
402 Vector4 v(2.0f, 3.0f, 4.0f, 5.0f);
405 DALI_TEST_CHECK(m.GetTranslation() == v);
409 int UtcDaliMatrixSetTranslation3P(void)
412 Vector3 v(2.0f, 3.0f, 4.0f);
415 DALI_TEST_CHECK(m.GetTranslation3() == v);
419 int UtcDaliMatrixOrthoNormalize0P(void)
421 // OrthoNormalise fixes floating point errors from matrix rotations
425 for (int i=0;i<1000;++i)
428 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
431 m.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), Vector3::ZERO );
436 success &= fabsf(m.GetXAxis().Dot(m.GetYAxis())) < 0.001f;
437 success &= fabsf(m.GetYAxis().Dot(m.GetXAxis())) < 0.001f;
438 success &= fabsf(m.GetZAxis().Dot(m.GetYAxis())) < 0.001f;
440 success &= fabsf(m.GetXAxis().Length() - 1.0f) < 0.001f;
441 success &= fabsf(m.GetYAxis().Length() - 1.0f) < 0.001f;
442 success &= fabsf(m.GetZAxis().Length() - 1.0f) < 0.001f;
444 DALI_TEST_CHECK(success);
448 int UtcDaliMatrixOrthoNormalize1P(void)
450 // OrthoNormalize is not flipping the axes and is maintaining the translation
451 for (int i=0;i<1000;++i)
454 Vector3 axis(cosf(f*0.001f), cosf(f*0.02f), cosf(f*0.03f));
456 Vector3 center(10.0f, 15.0f, 5.0f);
460 m0.SetTransformComponents( Vector3::ONE, Quaternion(Radian(1.0f), axis), center );
465 DALI_TEST_EQUALS(m0.GetXAxis(), m1.GetXAxis(), 0.001f, TEST_LOCATION);
466 DALI_TEST_EQUALS(m0.GetYAxis(), m1.GetYAxis(), 0.001f, TEST_LOCATION);
467 DALI_TEST_EQUALS(m0.GetZAxis(), m1.GetZAxis(), 0.001f, TEST_LOCATION);
468 DALI_TEST_EQUALS(m0.GetTranslation(), m1.GetTranslation(), 0.001f, TEST_LOCATION);
473 int UtcDaliMatrixConstAsFloatP(void)
475 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};
478 const float* els = m.AsFloat();
479 const float* init = r;
480 bool initialised = true;
481 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
486 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
492 int UtcDaliMatrixAsFloatP(void)
494 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};
497 float* els = m.AsFloat();
499 bool initialised = true;
500 for(size_t idx=0; idx<16; ++idx, ++els, ++init)
505 DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
511 int UtcDaliMatrixMultiplyP(void)
513 Matrix m1 = Matrix::IDENTITY;
515 float els[] = { 1.0f, 0.0f, 0.0f, 0.0f,
516 0.0f, 0.707f, 0.707f, 0.0f,
517 0.0f, -0.707f, 0.707f, 0.0f,
518 0.0f, 0.0f, 0.0f, 1.0f };
521 Quaternion q(Radian(Degree(45.0f)), Vector3::XAXIS);
523 Matrix::Multiply(m2, m1, q);
525 DALI_TEST_EQUALS(m2, result, 0.01f, TEST_LOCATION);
529 int UtcDaliMatrixOperatorMultiply01P(void)
531 Vector4 v1(2.0f, 5.0f, 4.0f, 0.0f);
533 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
534 0.0f, 3.0f, 0.0f, 0.0f,
535 0.0f, 0.0f, 4.0f, 0.0f,
536 0.0f, 0.0f, 0.0f, 1.0f };
539 Vector4 v2 = m1 * v1;
540 Vector4 r1(4.0f, 15.0f, 16.0f, 0.0f);
541 DALI_TEST_EQUALS(v2, r1, 0.01f, TEST_LOCATION);
545 int UtcDaliMatrixOperatorMultiply02P(void)
547 TestApplication application;
549 Vector3 position ( 30.f, 40.f, 50.f);
553 m1.SetTranslation(-position);
555 Vector4 positionV4(position);
557 Vector4 output = m1 * positionV4;
560 DALI_TEST_EQUALS(output, Vector4::ZERO, 0.01f, TEST_LOCATION);
564 int UtcDaliMatrixOperatorEqualsP(void)
566 Matrix m1 = Matrix::IDENTITY;
568 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};
570 DALI_TEST_EQUALS(m1 == r2, true, TEST_LOCATION);
572 float *f = m1.AsFloat();
573 for(size_t i=0; i<16; i++)
576 DALI_TEST_EQUALS(m1 == r2, false, TEST_LOCATION);
581 int UtcDaliMatrixOperatorNotEqualsP(void)
583 Matrix m1 = Matrix::IDENTITY;
584 float els[] = {2.0f, 0.0f, 0.0f, 0.0f,
585 0.0f, 3.0f, 0.0f, 0.0f,
586 0.0f, 0.0f, 4.0f, 0.0f,
587 0.0f, 0.0f, 0.0f, 1.0f };
590 DALI_TEST_CHECK(m1 != r1);
591 DALI_TEST_CHECK(!(m1 != m1));
595 int UtcDaliMatrixSetTransformComponents01P(void)
597 // Create an arbitrary vector
598 for( float x=-1.0f; x<=1.0f; x+=0.1f )
600 for( float y=-1.0f; y<1.0f; y+=0.1f )
602 for( float z=-1.0f; z<1.0f; z+=0.1f )
604 Vector3 vForward(x, y, z);
605 vForward.Normalize();
607 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
609 Quaternion rotation1(Radian(Degree(angle)), vForward);
611 Matrix m1(rotation1);
612 Matrix result1(false);
613 Vector3 vForward3(vForward.x, vForward.y, vForward.z);
614 result1.SetTransformComponents( Vector3::ONE, Quaternion(Radian(Degree(angle)), vForward3), Vector3::ZERO );
616 DALI_TEST_EQUALS(m1, result1, 0.001, TEST_LOCATION);
619 m2.SetTransformComponents(vForward, Quaternion::IDENTITY, Vector3::ZERO);
621 Matrix result2a(Matrix::IDENTITY);
622 result2a.SetXAxis(result2a.GetXAxis() * vForward[0]);
623 result2a.SetYAxis(result2a.GetYAxis() * vForward[1]);
624 result2a.SetZAxis(result2a.GetZAxis() * vForward[2]);
626 DALI_TEST_EQUALS(m2, result2a, 0.001, TEST_LOCATION);
629 m3.SetTransformComponents(vForward, rotation1, Vector3::ZERO);
631 Matrix result3(Matrix::IDENTITY);
632 result3.SetXAxis(result3.GetXAxis() * vForward[0]);
633 result3.SetYAxis(result3.GetYAxis() * vForward[1]);
634 result3.SetZAxis(result3.GetZAxis() * vForward[2]);
636 Matrix::Multiply(result3, result3, m1);
637 DALI_TEST_EQUALS(m3, result3, 0.001, TEST_LOCATION);
646 int UtcDaliMatrixSetInverseTransformComponent01P(void)
648 // Create an arbitrary vector
649 for( float x=-1.0f; x<=1.0f; x+=0.1f )
651 for( float y=-1.0f; y<1.0f; y+=0.1f )
653 for( float z=-1.0f; z<1.0f; z+=0.1f )
655 Vector3 vForward(x, y, z);
656 vForward.Normalize();
658 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
660 Quaternion rotation1(Radian(Degree(angle)), vForward);
661 Vector3 scale1(2.0f, 3.0f, 4.0f);
662 Vector3 position1(1.0f, 2.0f, 3.0f);
665 m1.SetTransformComponents(scale1, rotation1, position1);
668 m2.SetInverseTransformComponents(scale1, rotation1, position1);
671 Matrix::Multiply(result, m1, m2);
673 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
681 int UtcDaliMatrixSetInverseTransformComponent02P(void)
683 // Create an arbitrary vector
684 for( float x=-1.0f; x<=1.0f; x+=0.1f )
686 for( float y=-1.0f; y<1.0f; y+=0.1f )
688 for( float z=-1.0f; z<1.0f; z+=0.1f )
690 Vector3 vForward(x, y, z);
691 vForward.Normalize();
693 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
695 Quaternion rotation1(Radian(Degree(angle)), vForward);
696 Matrix rotationMatrix(rotation1); // TEST RELIES ON THIS METHOD WORKING!!!
698 Vector3 position1(5.0f, -6.0f, 7.0f);
701 m1.SetTransformComponents( Vector3::ONE, rotation1, position1 );
704 m2.SetInverseTransformComponents( rotationMatrix.GetXAxis(),
705 rotationMatrix.GetYAxis(),
706 rotationMatrix.GetZAxis(),
710 Matrix::Multiply(result, m1, m2);
712 DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
720 int UtcDaliMatrixGetTransformComponents01P(void)
722 Matrix m2(Matrix::IDENTITY.AsFloat());
726 m2.GetTransformComponents(pos2, q2, scale2);
727 DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
728 DALI_TEST_EQUALS(Vector3(1.0f, 1.0f, 1.0f), scale2, 0.001, TEST_LOCATION);
729 DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
734 int UtcDaliMatrixGetTransformComponents02P(void)
736 // Create an arbitrary vector
737 for( float x=-1.0f; x<=1.0f; x+=0.1f )
739 for( float y=-1.0f; y<1.0f; y+=0.1f )
741 for( float z=-1.0f; z<1.0f; z+=0.1f )
743 Vector3 vForward(x, y, z);
744 vForward.Normalize();
746 for( float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
748 Quaternion rotation1(Radian(Degree(angle)), vForward);
749 Vector3 scale1(2.0f, 3.0f, 4.0f);
750 Vector3 position1(1.0f, 2.0f, 3.0f);
753 m1.SetTransformComponents(scale1, rotation1, position1);
756 Quaternion rotation2;
758 m1.GetTransformComponents(position2, rotation2, scale2);
760 DALI_TEST_EQUALS(position1, position2, 0.001, TEST_LOCATION);
761 DALI_TEST_EQUALS(scale1, scale2, 0.001, TEST_LOCATION);
762 DALI_TEST_EQUALS(rotation1, rotation2, 0.001, TEST_LOCATION);
771 int UtcDaliMatrixOStreamOperator(void)
773 std::ostringstream oss;
776 matrix.SetIdentity();
780 std::string expectedOutput = "[ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]";
782 DALI_TEST_EQUALS( oss.str(), expectedOutput, TEST_LOCATION);