Revert "[Tizen] Appendix log for ttrace + Print keycode and timestamp"
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Matrix.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <dali-test-suite-utils.h>
19 #include <dali/public-api/dali-core.h>
20 #include <stdlib.h>
21
22 #include <iostream>
23 #include <sstream>
24
25 using namespace Dali;
26
27 void utc_dali_matrix_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31
32 void utc_dali_matrix_cleanup(void)
33 {
34   test_return_value = TET_PASS;
35 }
36
37 int UtcDaliMatrixConstructor01P(void)
38 {
39   // State of memory cannot be guaranteed, so use
40   // a buffer in a known state to check for changes
41   char buffer[sizeof(Matrix)];
42
43   memset(buffer, 1, sizeof(Matrix));
44
45   Matrix* m2                     = new(&buffer) Matrix(false);
46   bool    initialisation_occured = false;
47   {
48     float* els = m2->AsFloat();
49     for(size_t idx = 0; idx < 16; ++idx, ++els)
50     {
51       if(*els == 0.0f)
52         initialisation_occured = true;
53     }
54   }
55
56   DALI_TEST_EQUALS(initialisation_occured, false, TEST_LOCATION);
57
58   END_TEST;
59 }
60
61 int UtcDaliMatrixConstructor02P(void)
62 {
63   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};
64   Matrix m(r);
65
66   float* els         = m.AsFloat();
67   float* init        = r;
68   bool   initialised = true;
69   for(size_t idx = 0; idx < 16; ++idx, ++els, ++init)
70   {
71     if(*els != *init)
72       initialised = false;
73   }
74   DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
75
76   END_TEST;
77 }
78
79 int UtcDaliMatrixConstructor03P(void)
80 {
81   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};
82
83   Matrix ma(r);
84   Matrix mb(ma);
85
86   float* els         = ma.AsFloat();
87   float* init        = mb.AsFloat();
88   bool   initialised = true;
89   for(size_t idx = 0; idx < 16; ++idx, ++els, ++init)
90   {
91     if(*els != *init)
92       initialised = false;
93   }
94   DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
95
96   END_TEST;
97 }
98
99 int UtcDaliMatrixConstructor04P(void)
100 {
101   Quaternion q(Quaternion::IDENTITY);
102   Matrix     m(q);
103   DALI_TEST_EQUALS(Matrix(Matrix::IDENTITY), m, 0.001, TEST_LOCATION);
104   END_TEST;
105 }
106
107 int UtcDaliMatrixCopyConstructor(void)
108 {
109   Matrix m0(Matrix::IDENTITY);
110   Matrix m1(m0);
111   DALI_TEST_EQUALS(m1, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
112
113   END_TEST;
114 }
115
116 int UtcDaliMatrixMoveConstructor(void)
117 {
118   Matrix m0(Matrix::IDENTITY);
119   Matrix m1 = std::move(m0);
120   DALI_TEST_EQUALS(m1, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
121
122   END_TEST;
123 }
124
125 int UtcDaliMatrixCopyAssignment(void)
126 {
127   Matrix m0(Matrix::IDENTITY);
128   Matrix m1;
129   m1 = m0;
130   DALI_TEST_EQUALS(m1, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
131
132   END_TEST;
133 }
134
135 int UtcDaliMatrixMoveAssignment(void)
136 {
137   Matrix m0(Matrix::IDENTITY);
138   Matrix m1;
139   m1 = std::move(m0);
140   DALI_TEST_EQUALS(m1, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
141
142   END_TEST;
143 }
144
145 int UtcDaliMatrixAssignP(void)
146 {
147   Matrix a(Matrix::IDENTITY);
148   Matrix b = a;
149   DALI_TEST_EQUALS(a, b, 0.001, TEST_LOCATION);
150   END_TEST;
151 }
152
153 int UtcDaliMatrixAssign02P(void)
154 {
155   Matrix a(Matrix::IDENTITY);
156   a = a; // self assign does the do nothing branch
157   DALI_TEST_EQUALS(Matrix(Matrix::IDENTITY), a, 0.001, TEST_LOCATION);
158   END_TEST;
159 }
160
161 int UtcDaliMatrixSetIdentityP(void)
162 {
163   float  els[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
164   Matrix m(els);
165   m.SetIdentity();
166
167   DALI_TEST_EQUALS(m, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
168   END_TEST;
169 }
170
171 int UtcDaliMatrixSetIdentityAndScaleP(void)
172 {
173   float  els[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
174   Matrix m(els);
175   m.SetIdentityAndScale(Vector3(4.0f, 4.0f, 4.0f));
176
177   float  els2[] = {4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
178   Matrix r(els2);
179
180   DALI_TEST_EQUALS(m, r, 0.001f, TEST_LOCATION);
181   END_TEST;
182 }
183
184 int UtcDaliMatrixInvertTransformP(void)
185 {
186   for(int i = 0; i < 1000; ++i)
187   {
188     float   f = i;
189     Vector3 axis(cosf(f * 0.001f), cosf(f * 0.02f), cosf(f * 0.03f));
190     axis.Normalize();
191     Vector3 center(f, cosf(f) * 100.0f, cosf(f * 0.5f) * 50.0f);
192
193     Matrix m0;
194     m0.SetIdentity();
195     m0.SetTransformComponents(Vector3::ONE, Quaternion(Radian(1.0f), axis), center);
196
197     Matrix m1;
198     m0.InvertTransform(m1);
199
200     Matrix m2(false);
201     Matrix::Multiply(m2, m0, m1);
202
203     DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
204   }
205   END_TEST;
206 }
207
208 int UtcDaliMatrixInvertTransformN(void)
209 {
210   std::string exceptionString("EqualsZero(mMatrix[3]) && EqualsZero(mMatrix[7]) && EqualsZero(mMatrix[11]) && Equals(mMatrix[15], 1.0f");
211   try
212   {
213     float  els[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
214     Matrix m(els);
215
216     Matrix it;
217     m.InvertTransform(it);
218     tet_result(TET_FAIL);
219   }
220   catch(Dali::DaliException& e)
221   {
222     DALI_TEST_PRINT_ASSERT(e);
223     DALI_TEST_ASSERT(e, exceptionString, TEST_LOCATION);
224   }
225
226   try
227   {
228     float  els[] = {0.0f, 1.0f, 2.0f, 0.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
229     Matrix m(els);
230
231     Matrix it;
232     m.InvertTransform(it);
233     tet_result(TET_FAIL);
234   }
235   catch(Dali::DaliException& e)
236   {
237     DALI_TEST_PRINT_ASSERT(e);
238     DALI_TEST_ASSERT(e, exceptionString, TEST_LOCATION);
239   }
240
241   try
242   {
243     float  els[] = {0.0f, 1.0f, 2.0f, 0.0f, 4.0f, 5.0f, 6.0f, 0.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
244     Matrix m(els);
245
246     Matrix it;
247     m.InvertTransform(it);
248     tet_result(TET_FAIL);
249   }
250   catch(Dali::DaliException& e)
251   {
252     DALI_TEST_PRINT_ASSERT(e);
253     DALI_TEST_ASSERT(e, exceptionString, TEST_LOCATION);
254   }
255
256   try
257   {
258     float  els[] = {0.0f, 1.0f, 2.0f, 0.0f, 4.0f, 5.0f, 6.0f, 0.0f, 8.0f, 9.0f, 10.0f, 0.0f, 12.0f, 13.0f, 14.0f, 15.0f};
259     Matrix m(els);
260
261     Matrix it;
262     m.InvertTransform(it);
263     tet_result(TET_FAIL);
264   }
265   catch(Dali::DaliException& e)
266   {
267     DALI_TEST_PRINT_ASSERT(e);
268     DALI_TEST_ASSERT(e, exceptionString, TEST_LOCATION);
269   }
270   END_TEST;
271 }
272
273 int UtcDaliMatrixInvert01P(void)
274 {
275   // We're going to invert a whole load of different matrices to make sure we don't
276   // fail on particular orientations.
277   for(int i = 0; i < 1000; ++i)
278   {
279     float   f = i;
280     Vector3 axis(cosf(f * 0.001f), cosf(f * 0.02f), cosf(f * 0.03f));
281     axis.Normalize();
282     Vector3 center(f, cosf(f) * 100.0f, cosf(f * 0.5f) * 50.0f);
283
284     Matrix m0;
285     m0.SetIdentity();
286     m0.SetTransformComponents(Vector3::ONE, Quaternion(Radian(1.0f), axis), center);
287
288     Matrix m1(m0);
289     m1.Invert();
290
291     Matrix m2(false);
292     Matrix::Multiply(m2, m0, m1);
293
294     DALI_TEST_EQUALS(m2, Matrix::IDENTITY, 0.001f, TEST_LOCATION);
295
296     m1.Invert(); // doube invert - should be back to m0
297
298     DALI_TEST_EQUALS(m0, m1, 0.001f, TEST_LOCATION);
299   }
300   END_TEST;
301 }
302
303 int UtcDaliMatrixInvert02P(void)
304 {
305   Matrix m1 = Matrix::IDENTITY;
306   m1.SetXAxis(Vector3(0.0f, 0.0f, 0.0f));
307   DALI_TEST_EQUALS(m1.Invert(), false, TEST_LOCATION);
308   END_TEST;
309 }
310
311 int UtcDaliMatrixTransposeP(void)
312 {
313   float floats[] =
314     {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
315
316   Matrix m(floats);
317   m.Transpose();
318
319   bool success = true;
320
321   for(int x = 0; x < 4; ++x)
322   {
323     for(int y = 0; y < 4; ++y)
324     {
325       success &= (m.AsFloat()[x + y * 4] == floats[x * 4 + y]);
326     }
327   }
328
329   DALI_TEST_CHECK(success);
330   END_TEST;
331 }
332
333 int UtcDaliMatrixGetXAxisP(void)
334 {
335   float  els[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
336   Matrix m(els);
337
338   DALI_TEST_CHECK(m.GetXAxis() == Vector3(0.0f, 1.0f, 2.0f));
339   END_TEST;
340 }
341
342 int UtcDaliMatrixGetYAxisP(void)
343 {
344   float  els[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
345   Matrix m(els);
346
347   DALI_TEST_CHECK(m.GetYAxis() == Vector3(4.0f, 5.0f, 6.0f));
348   END_TEST;
349 }
350
351 int UtcDaliMatrixGetZAxisP(void)
352 {
353   float  els[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
354   Matrix m(els);
355
356   DALI_TEST_CHECK(m.GetZAxis() == Vector3(8.0f, 9.0f, 10.0f));
357   END_TEST;
358 }
359
360 int UtcDaliMatrixSetXAxisP(void)
361 {
362   Matrix  m;
363   Vector3 v(2.0f, 3.0f, 4.0f);
364   m.SetXAxis(v);
365
366   DALI_TEST_CHECK(m.GetXAxis() == v);
367   END_TEST;
368 }
369
370 int UtcDaliMatrixSetYAxisP(void)
371 {
372   Matrix  m;
373   Vector3 v(2.0f, 3.0f, 4.0f);
374   m.SetYAxis(v);
375
376   DALI_TEST_CHECK(m.GetYAxis() == v);
377   END_TEST;
378 }
379
380 int UtcDaliMatrixSetZAxisP(void)
381 {
382   Matrix  m;
383   Vector3 v(2.0f, 3.0f, 4.0f);
384   m.SetZAxis(v);
385
386   DALI_TEST_CHECK(m.GetZAxis() == v);
387   END_TEST;
388 }
389
390 int UtcDaliMatrixGetTranslationP(void)
391 {
392   float  els[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
393   Matrix m(els);
394
395   DALI_TEST_EQUALS(m.GetTranslation(), Vector4(12.0f, 13.0f, 14.0f, 15.0f), TEST_LOCATION);
396   END_TEST;
397 }
398
399 int UtcDaliMatrixGetTranslation3P(void)
400 {
401   float  els[] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f};
402   Matrix m(els);
403
404   DALI_TEST_EQUALS(m.GetTranslation3(), Vector3(12.0f, 13.0f, 14.0f), TEST_LOCATION);
405   END_TEST;
406 }
407
408 int UtcDaliMatrixGetScale(void)
409 {
410   // Create an arbitrary vector
411   for(float x = 0.0f; x <= 2.0f; x += 0.1f)
412   {
413     for(float y = 0.0f; y < 2.0f; y += 0.1f)
414     {
415       for(float z = 0.0f; z < 2.0f; z += 0.1f)
416       {
417         Vector3 vScale(x, y, z);
418
419         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
420         {
421           Vector3 forward(1.0f, 1.3f, 2.0f);
422           forward.Normalize();
423
424           Quaternion rotation1(Radian(Degree(angle)), forward);
425           Vector3    position1(1.0f, 2.0f, 3.0f);
426
427           Matrix m1(false);
428           m1.SetTransformComponents(vScale, rotation1, position1);
429
430           Vector3 scale2 = m1.GetScale();
431
432           DALI_TEST_EQUALS(vScale, scale2, 0.001, TEST_LOCATION);
433         }
434       }
435     }
436   }
437   END_TEST;
438 }
439
440 int UtcDaliMatrixSetTranslationP(void)
441 {
442   Matrix  m;
443   Vector4 v(2.0f, 3.0f, 4.0f, 5.0f);
444   m.SetTranslation(v);
445
446   DALI_TEST_CHECK(m.GetTranslation() == v);
447   END_TEST;
448 }
449
450 int UtcDaliMatrixSetTranslation3P(void)
451 {
452   Matrix  m;
453   Vector3 v(2.0f, 3.0f, 4.0f);
454   m.SetTranslation(v);
455
456   DALI_TEST_CHECK(m.GetTranslation3() == v);
457   END_TEST;
458 }
459
460 int UtcDaliMatrixOrthoNormalize0P(void)
461 {
462   // OrthoNormalise fixes floating point errors from matrix rotations
463   Matrix m;
464   m.SetIdentity();
465
466   for(int i = 0; i < 1000; ++i)
467   {
468     float   f = i;
469     Vector3 axis(cosf(f * 0.001f), cosf(f * 0.02f), cosf(f * 0.03f));
470     axis.Normalize();
471
472     m.SetTransformComponents(Vector3::ONE, Quaternion(Radian(1.0f), axis), Vector3::ZERO);
473     m.OrthoNormalize();
474   }
475
476   bool success = true;
477   success &= fabsf(m.GetXAxis().Dot(m.GetYAxis())) < 0.001f;
478   success &= fabsf(m.GetYAxis().Dot(m.GetXAxis())) < 0.001f;
479   success &= fabsf(m.GetZAxis().Dot(m.GetYAxis())) < 0.001f;
480
481   success &= fabsf(m.GetXAxis().Length() - 1.0f) < 0.001f;
482   success &= fabsf(m.GetYAxis().Length() - 1.0f) < 0.001f;
483   success &= fabsf(m.GetZAxis().Length() - 1.0f) < 0.001f;
484
485   DALI_TEST_CHECK(success);
486   END_TEST;
487 }
488
489 int UtcDaliMatrixOrthoNormalize1P(void)
490 {
491   // OrthoNormalize is not flipping the axes and is maintaining the translation
492   for(int i = 0; i < 1000; ++i)
493   {
494     float   f = i;
495     Vector3 axis(cosf(f * 0.001f), cosf(f * 0.02f), cosf(f * 0.03f));
496     axis.Normalize();
497     Vector3 center(10.0f, 15.0f, 5.0f);
498
499     Matrix m0;
500     m0.SetIdentity();
501     m0.SetTransformComponents(Vector3::ONE, Quaternion(Radian(1.0f), axis), center);
502
503     Matrix m1(m0);
504     m1.OrthoNormalize();
505
506     DALI_TEST_EQUALS(m0.GetXAxis(), m1.GetXAxis(), 0.001f, TEST_LOCATION);
507     DALI_TEST_EQUALS(m0.GetYAxis(), m1.GetYAxis(), 0.001f, TEST_LOCATION);
508     DALI_TEST_EQUALS(m0.GetZAxis(), m1.GetZAxis(), 0.001f, TEST_LOCATION);
509     DALI_TEST_EQUALS(m0.GetTranslation(), m1.GetTranslation(), 0.001f, TEST_LOCATION);
510   }
511   END_TEST;
512 }
513
514 int UtcDaliMatrixConstAsFloatP(void)
515 {
516   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};
517   const Matrix m(r);
518
519   const float* els         = m.AsFloat();
520   const float* init        = r;
521   bool         initialised = true;
522   for(size_t idx = 0; idx < 16; ++idx, ++els, ++init)
523   {
524     if(*els != *init)
525       initialised = false;
526   }
527   DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
528
529   END_TEST;
530 }
531
532 int UtcDaliMatrixAsFloatP(void)
533 {
534   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};
535   Matrix m(r);
536
537   float* els         = m.AsFloat();
538   float* init        = r;
539   bool   initialised = true;
540   for(size_t idx = 0; idx < 16; ++idx, ++els, ++init)
541   {
542     if(*els != *init)
543       initialised = false;
544   }
545   DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
546
547   END_TEST;
548 }
549
550 int UtcDaliMatrixMultiplyP(void)
551 {
552   Matrix m1 = Matrix::IDENTITY;
553
554   float  els[] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.707f, 0.707f, 0.0f, 0.0f, -0.707f, 0.707f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
555   Matrix result(els);
556
557   Quaternion q(Radian(Degree(45.0f)), Vector3::XAXIS);
558   Matrix     m2(false);
559   Matrix::Multiply(m2, m1, q);
560
561   DALI_TEST_EQUALS(m2, result, 0.01f, TEST_LOCATION);
562   END_TEST;
563 }
564
565 int UtcDaliMatrixOperatorMultiply01P(void)
566 {
567   Vector4 v1(2.0f, 5.0f, 4.0f, 0.0f);
568
569   float  els[] = {2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
570   Matrix m1(els);
571
572   Vector4 v2 = m1 * v1;
573   Vector4 r1(4.0f, 15.0f, 16.0f, 0.0f);
574   DALI_TEST_EQUALS(v2, r1, 0.01f, TEST_LOCATION);
575   END_TEST;
576 }
577
578 int UtcDaliMatrixOperatorMultiply02P(void)
579 {
580   TestApplication application;
581
582   Vector3 position(30.f, 40.f, 50.f);
583
584   Matrix m1(false);
585   m1.SetIdentity();
586   m1.SetTranslation(-position);
587
588   Vector4 positionV4(position);
589   positionV4.w   = 1.0f;
590   Vector4 output = m1 * positionV4;
591
592   output.w = 0.0f;
593   DALI_TEST_EQUALS(output, Vector4::ZERO, 0.01f, TEST_LOCATION);
594   END_TEST;
595 }
596
597 int UtcDaliMatrixOperatorMultiply03P(void)
598 {
599   const float ll[16] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
600   const float rr[16] = {1.0f, 5.0f, 0.0f, 0.0f, 2.0f, 6.0f, 0.0f, 0.0f, 3.0f, 7.0f, 0.0f, 0.0f, 4.0f, 8.0f, 0.0f, 0.0f};
601   Matrix      left(ll);
602   Matrix      right(rr);
603
604   const float els[16] = {26.0f, 32.0f, 38.0f, 44.0f, 32.0f, 40.0f, 48.0f, 56.0f, 38.0f, 48.0f, 58.0f, 68.0f, 44.0f, 56.0f, 68.0f, 80.0f};
605   Matrix      result(els);
606
607   // Get result by operator*
608   Matrix multResult = left * right;
609   DALI_TEST_EQUALS(multResult, result, 0.01f, TEST_LOCATION);
610
611   // Get result by Multiply API
612   Matrix::Multiply(multResult, right, left);
613   DALI_TEST_EQUALS(multResult, result, 0.01f, TEST_LOCATION);
614
615   END_TEST;
616 }
617
618 int UtcDaliMatrixOperatorMultiplyAssign01P(void)
619 {
620   tet_infoline("Multiplication Assign operator\n");
621   const float ll[16] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 0.0f, 0.0f, 11.0f, 12.0f, 0.0f, 0.0f};
622   const float rr[16] = {1.0f, 5.0f, 9.0f, 10.0f, 2.0f, 6.0f, 11.0f, 12.0f, 3.0f, 7.0f, 0.0f, 0.0f, 4.0f, 8.0f, 0.0f, 0.0f};
623   Matrix      left(ll);
624   Matrix      right(rr);
625   Matrix      copyedLeft(ll);
626
627   const float els[16] = {217.0f, 242.0f, 38.0f, 44.0f, 263.0f, 294.0f, 48.0f, 56.0f, 38.0f, 48.0f, 58.0f, 68.0f, 44.0f, 56.0f, 68.0f, 80.0f};
628   Matrix      result(els);
629
630   // Get result by operator*
631   Matrix multResult = left * right;
632   DALI_TEST_EQUALS(multResult, result, 0.01f, TEST_LOCATION);
633
634   // Get result by operator*=
635   left *= right;
636   DALI_TEST_EQUALS(left, result, 0.01f, TEST_LOCATION);
637
638   END_TEST;
639 }
640
641 int UtcDaliMatrixOperatorMultiplyAssign02P(void)
642 {
643   tet_infoline("Multiplication Assign operator with self matrix\n");
644   const float ll[16] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 0.0f, 0.0f, 11.0f, 12.0f, 0.0f, 0.0f};
645   Matrix      left(ll);
646   Matrix      copyedLeft(ll);
647
648   const float els[16] = {82.0f, 92.0f, 17.0f, 20.0f, 186.0f, 212.0f, 57.0f, 68.0f, 59.0f, 78.0f, 97.0f, 116.0f, 71.0f, 94.0f, 117.0f, 140.0f};
649   Matrix      result(els);
650
651   // Get result by operator*
652   Matrix multResult = left * copyedLeft;
653   DALI_TEST_EQUALS(multResult, result, 0.01f, TEST_LOCATION);
654
655   // Get result by operator*=
656   left *= left;
657   DALI_TEST_EQUALS(left, result, 0.01f, TEST_LOCATION);
658
659   END_TEST;
660 }
661
662 int UtcDaliMatrixOperatorEqualsP(void)
663 {
664   Matrix m1 = Matrix::IDENTITY;
665
666   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};
667   Matrix r2(els);
668   DALI_TEST_EQUALS(m1 == r2, true, TEST_LOCATION);
669
670   float* f = m1.AsFloat();
671   for(size_t i = 0; i < 16; i++)
672   {
673     f[15 - i] = 1.2f;
674     DALI_TEST_EQUALS(m1 == r2, false, TEST_LOCATION);
675   }
676   END_TEST;
677 }
678
679 int UtcDaliMatrixOperatorNotEqualsP(void)
680 {
681   Matrix m1    = Matrix::IDENTITY;
682   float  els[] = {2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
683   Matrix r1(els);
684
685   DALI_TEST_CHECK(m1 != r1);
686   DALI_TEST_CHECK(!(m1 != m1));
687   END_TEST;
688 }
689
690 int UtcDaliMatrixSetTransformComponents01P(void)
691 {
692   // Create an arbitrary vector
693   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
694   {
695     for(float y = -1.0f; y < 1.0f; y += 0.1f)
696     {
697       for(float z = -1.0f; z < 1.0f; z += 0.1f)
698       {
699         Vector3 vForward(x, y, z);
700         vForward.Normalize();
701
702         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
703         {
704           Quaternion rotation1(Radian(Degree(angle)), vForward);
705
706           Matrix  m1(rotation1);
707           Matrix  result1(false);
708           Vector3 vForward3(vForward.x, vForward.y, vForward.z);
709           result1.SetTransformComponents(Vector3::ONE, Quaternion(Radian(Degree(angle)), vForward3), Vector3::ZERO);
710
711           DALI_TEST_EQUALS(m1, result1, 0.001, TEST_LOCATION);
712
713           Matrix m2(false);
714           m2.SetTransformComponents(vForward, Quaternion::IDENTITY, Vector3::ZERO);
715
716           Matrix result2a(Matrix::IDENTITY);
717           result2a.SetXAxis(result2a.GetXAxis() * vForward[0]);
718           result2a.SetYAxis(result2a.GetYAxis() * vForward[1]);
719           result2a.SetZAxis(result2a.GetZAxis() * vForward[2]);
720
721           DALI_TEST_EQUALS(m2, result2a, 0.001, TEST_LOCATION);
722
723           Matrix m3(false);
724           m3.SetTransformComponents(vForward, rotation1, Vector3::ZERO);
725
726           Matrix result3(Matrix::IDENTITY);
727           result3.SetXAxis(result3.GetXAxis() * vForward[0]);
728           result3.SetYAxis(result3.GetYAxis() * vForward[1]);
729           result3.SetZAxis(result3.GetZAxis() * vForward[2]);
730
731           Matrix::Multiply(result3, result3, m1);
732           DALI_TEST_EQUALS(m3, result3, 0.001, TEST_LOCATION);
733         }
734       }
735     }
736   }
737   END_TEST;
738 }
739
740 int UtcDaliMatrixSetInverseTransformComponent01P(void)
741 {
742   // Create an arbitrary vector
743   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
744   {
745     for(float y = -1.0f; y < 1.0f; y += 0.1f)
746     {
747       for(float z = -1.0f; z < 1.0f; z += 0.1f)
748       {
749         Vector3 vForward(x, y, z);
750         vForward.Normalize();
751
752         {
753           Quaternion rotation1(Quaternion::IDENTITY); // test no rotation branch
754           Vector3    scale1(2.0f, 3.0f, 4.0f);
755           Vector3    position1(1.0f, 2.0f, 3.0f);
756
757           Matrix m1(false);
758           m1.SetTransformComponents(scale1, rotation1, position1);
759
760           Matrix m2(false);
761           m2.SetInverseTransformComponents(scale1, rotation1, position1);
762
763           Matrix result;
764           Matrix::Multiply(result, m1, m2);
765
766           DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
767         }
768       }
769     }
770   }
771   END_TEST;
772 }
773
774 int UtcDaliMatrixSetInverseTransformComponent02P(void)
775 {
776   // Create an arbitrary vector
777   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
778   {
779     for(float y = -1.0f; y < 1.0f; y += 0.1f)
780     {
781       for(float z = -1.0f; z < 1.0f; z += 0.1f)
782       {
783         Vector3 vForward(x, y, z);
784         vForward.Normalize();
785
786         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
787         {
788           Quaternion rotation1(Radian(Degree(angle)), vForward);
789           Matrix     rotationMatrix(rotation1); // TEST RELIES ON THIS METHOD WORKING!!!
790
791           Vector3 position1(5.0f, -6.0f, 7.0f);
792
793           Matrix m1(false);
794           m1.SetTransformComponents(Vector3::ONE, rotation1, position1);
795
796           Matrix m2(false);
797           m2.SetInverseTransformComponents(rotationMatrix.GetXAxis(),
798                                            rotationMatrix.GetYAxis(),
799                                            rotationMatrix.GetZAxis(),
800                                            position1);
801
802           Matrix result;
803           Matrix::Multiply(result, m1, m2);
804
805           DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
806         }
807       }
808     }
809   }
810   END_TEST;
811 }
812
813 int UtcDaliMatrixGetTransformComponents01P(void)
814 {
815   Matrix     m2(Matrix::IDENTITY.AsFloat());
816   Vector3    pos2;
817   Vector3    scale2;
818   Quaternion q2;
819   m2.GetTransformComponents(pos2, q2, scale2);
820   DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
821   DALI_TEST_EQUALS(Vector3(1.0f, 1.0f, 1.0f), scale2, 0.001, TEST_LOCATION);
822   DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
823   END_TEST;
824 }
825
826 int UtcDaliMatrixGetTransformComponents02P(void)
827 {
828   // Create an arbitrary vector
829   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
830   {
831     for(float y = -1.0f; y < 1.0f; y += 0.1f)
832     {
833       for(float z = -1.0f; z < 1.0f; z += 0.1f)
834       {
835         Vector3 vForward(x, y, z);
836         vForward.Normalize();
837
838         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
839         {
840           Quaternion rotation1(Radian(Degree(angle)), vForward);
841           Vector3    scale1(2.0f, 3.0f, 4.0f);
842           Vector3    position1(1.0f, 2.0f, 3.0f);
843
844           Matrix m1(false);
845           m1.SetTransformComponents(scale1, rotation1, position1);
846
847           Vector3    position2;
848           Quaternion rotation2;
849           Vector3    scale2;
850           m1.GetTransformComponents(position2, rotation2, scale2);
851
852           DALI_TEST_EQUALS(position1, position2, 0.001, TEST_LOCATION);
853           DALI_TEST_EQUALS(scale1, scale2, 0.001, TEST_LOCATION);
854           DALI_TEST_EQUALS(rotation1, rotation2, 0.001, TEST_LOCATION);
855         }
856       }
857     }
858   }
859   END_TEST;
860 }
861
862 int UtcDaliMatrixGetTransformComponents03P(void)
863 {
864   Matrix     m2; // zero branch
865   Vector3    pos2;
866   Vector3    scale2;
867   Quaternion q2;
868   m2.GetTransformComponents(pos2, q2, scale2);
869   DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
870   DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), scale2, 0.001, TEST_LOCATION);
871   // DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
872   END_TEST;
873 }
874
875 int UtcDaliMatrixOStreamOperator(void)
876 {
877   std::ostringstream oss;
878
879   Matrix matrix;
880   matrix.SetIdentity();
881
882   oss << matrix;
883
884   std::string expectedOutput = "[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]";
885
886   DALI_TEST_EQUALS(oss.str(), expectedOutput, TEST_LOCATION);
887   END_TEST;
888 }