Add BuildPickingRay to devel api
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Matrix.cpp
1 /*
2  * Copyright (c) 2022 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 UtcDaliMatrixSetTranslationP(void)
409 {
410   Matrix  m;
411   Vector4 v(2.0f, 3.0f, 4.0f, 5.0f);
412   m.SetTranslation(v);
413
414   DALI_TEST_CHECK(m.GetTranslation() == v);
415   END_TEST;
416 }
417
418 int UtcDaliMatrixSetTranslation3P(void)
419 {
420   Matrix  m;
421   Vector3 v(2.0f, 3.0f, 4.0f);
422   m.SetTranslation(v);
423
424   DALI_TEST_CHECK(m.GetTranslation3() == v);
425   END_TEST;
426 }
427
428 int UtcDaliMatrixOrthoNormalize0P(void)
429 {
430   // OrthoNormalise fixes floating point errors from matrix rotations
431   Matrix m;
432   m.SetIdentity();
433
434   for(int i = 0; i < 1000; ++i)
435   {
436     float   f = i;
437     Vector3 axis(cosf(f * 0.001f), cosf(f * 0.02f), cosf(f * 0.03f));
438     axis.Normalize();
439
440     m.SetTransformComponents(Vector3::ONE, Quaternion(Radian(1.0f), axis), Vector3::ZERO);
441     m.OrthoNormalize();
442   }
443
444   bool success = true;
445   success &= fabsf(m.GetXAxis().Dot(m.GetYAxis())) < 0.001f;
446   success &= fabsf(m.GetYAxis().Dot(m.GetXAxis())) < 0.001f;
447   success &= fabsf(m.GetZAxis().Dot(m.GetYAxis())) < 0.001f;
448
449   success &= fabsf(m.GetXAxis().Length() - 1.0f) < 0.001f;
450   success &= fabsf(m.GetYAxis().Length() - 1.0f) < 0.001f;
451   success &= fabsf(m.GetZAxis().Length() - 1.0f) < 0.001f;
452
453   DALI_TEST_CHECK(success);
454   END_TEST;
455 }
456
457 int UtcDaliMatrixOrthoNormalize1P(void)
458 {
459   // OrthoNormalize is not flipping the axes and is maintaining the translation
460   for(int i = 0; i < 1000; ++i)
461   {
462     float   f = i;
463     Vector3 axis(cosf(f * 0.001f), cosf(f * 0.02f), cosf(f * 0.03f));
464     axis.Normalize();
465     Vector3 center(10.0f, 15.0f, 5.0f);
466
467     Matrix m0;
468     m0.SetIdentity();
469     m0.SetTransformComponents(Vector3::ONE, Quaternion(Radian(1.0f), axis), center);
470
471     Matrix m1(m0);
472     m1.OrthoNormalize();
473
474     DALI_TEST_EQUALS(m0.GetXAxis(), m1.GetXAxis(), 0.001f, TEST_LOCATION);
475     DALI_TEST_EQUALS(m0.GetYAxis(), m1.GetYAxis(), 0.001f, TEST_LOCATION);
476     DALI_TEST_EQUALS(m0.GetZAxis(), m1.GetZAxis(), 0.001f, TEST_LOCATION);
477     DALI_TEST_EQUALS(m0.GetTranslation(), m1.GetTranslation(), 0.001f, TEST_LOCATION);
478   }
479   END_TEST;
480 }
481
482 int UtcDaliMatrixConstAsFloatP(void)
483 {
484   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};
485   const Matrix m(r);
486
487   const float* els         = m.AsFloat();
488   const float* init        = r;
489   bool         initialised = true;
490   for(size_t idx = 0; idx < 16; ++idx, ++els, ++init)
491   {
492     if(*els != *init)
493       initialised = false;
494   }
495   DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
496
497   END_TEST;
498 }
499
500 int UtcDaliMatrixAsFloatP(void)
501 {
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};
503   Matrix m(r);
504
505   float* els         = m.AsFloat();
506   float* init        = r;
507   bool   initialised = true;
508   for(size_t idx = 0; idx < 16; ++idx, ++els, ++init)
509   {
510     if(*els != *init)
511       initialised = false;
512   }
513   DALI_TEST_EQUALS(initialised, true, TEST_LOCATION);
514
515   END_TEST;
516 }
517
518 int UtcDaliMatrixMultiplyP(void)
519 {
520   Matrix m1 = Matrix::IDENTITY;
521
522   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};
523   Matrix result(els);
524
525   Quaternion q(Radian(Degree(45.0f)), Vector3::XAXIS);
526   Matrix     m2(false);
527   Matrix::Multiply(m2, m1, q);
528
529   DALI_TEST_EQUALS(m2, result, 0.01f, TEST_LOCATION);
530   END_TEST;
531 }
532
533 int UtcDaliMatrixOperatorMultiply01P(void)
534 {
535   Vector4 v1(2.0f, 5.0f, 4.0f, 0.0f);
536
537   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};
538   Matrix m1(els);
539
540   Vector4 v2 = m1 * v1;
541   Vector4 r1(4.0f, 15.0f, 16.0f, 0.0f);
542   DALI_TEST_EQUALS(v2, r1, 0.01f, TEST_LOCATION);
543   END_TEST;
544 }
545
546 int UtcDaliMatrixOperatorMultiply02P(void)
547 {
548   TestApplication application;
549
550   Vector3 position(30.f, 40.f, 50.f);
551
552   Matrix m1(false);
553   m1.SetIdentity();
554   m1.SetTranslation(-position);
555
556   Vector4 positionV4(position);
557   positionV4.w   = 1.0f;
558   Vector4 output = m1 * positionV4;
559
560   output.w = 0.0f;
561   DALI_TEST_EQUALS(output, Vector4::ZERO, 0.01f, TEST_LOCATION);
562   END_TEST;
563 }
564
565 int UtcDaliMatrixOperatorMultiply03P(void)
566 {
567   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};
568   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};
569   Matrix      left(ll);
570   Matrix      right(rr);
571
572   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};
573   Matrix      result(els);
574
575   // Get result by operator*
576   Matrix multResult = left * right;
577   DALI_TEST_EQUALS(multResult, result, 0.01f, TEST_LOCATION);
578
579   // Get result by Multiply API
580   Matrix::Multiply(multResult, right, left);
581   DALI_TEST_EQUALS(multResult, result, 0.01f, TEST_LOCATION);
582
583   END_TEST;
584 }
585
586 int UtcDaliMatrixOperatorMultiplyAssign01P(void)
587 {
588   tet_infoline("Multiplication Assign operator\n");
589   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};
590   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};
591   Matrix      left(ll);
592   Matrix      right(rr);
593   Matrix      copyedLeft(ll);
594
595   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};
596   Matrix      result(els);
597
598   // Get result by operator*
599   Matrix multResult = left * right;
600   DALI_TEST_EQUALS(multResult, result, 0.01f, TEST_LOCATION);
601
602   // Get result by operator*=
603   left *= right;
604   DALI_TEST_EQUALS(left, result, 0.01f, TEST_LOCATION);
605
606   END_TEST;
607 }
608
609 int UtcDaliMatrixOperatorMultiplyAssign02P(void)
610 {
611   tet_infoline("Multiplication Assign operator with self matrix\n");
612   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};
613   Matrix      left(ll);
614   Matrix      copyedLeft(ll);
615
616   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};
617   Matrix      result(els);
618
619   // Get result by operator*
620   Matrix multResult = left * copyedLeft;
621   DALI_TEST_EQUALS(multResult, result, 0.01f, TEST_LOCATION);
622
623   // Get result by operator*=
624   left *= left;
625   DALI_TEST_EQUALS(left, result, 0.01f, TEST_LOCATION);
626
627   END_TEST;
628 }
629
630 int UtcDaliMatrixOperatorEqualsP(void)
631 {
632   Matrix m1 = Matrix::IDENTITY;
633
634   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};
635   Matrix r2(els);
636   DALI_TEST_EQUALS(m1 == r2, true, TEST_LOCATION);
637
638   float* f = m1.AsFloat();
639   for(size_t i = 0; i < 16; i++)
640   {
641     f[15 - i] = 1.2f;
642     DALI_TEST_EQUALS(m1 == r2, false, TEST_LOCATION);
643   }
644   END_TEST;
645 }
646
647 int UtcDaliMatrixOperatorNotEqualsP(void)
648 {
649   Matrix m1    = Matrix::IDENTITY;
650   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};
651   Matrix r1(els);
652
653   DALI_TEST_CHECK(m1 != r1);
654   DALI_TEST_CHECK(!(m1 != m1));
655   END_TEST;
656 }
657
658 int UtcDaliMatrixSetTransformComponents01P(void)
659 {
660   // Create an arbitrary vector
661   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
662   {
663     for(float y = -1.0f; y < 1.0f; y += 0.1f)
664     {
665       for(float z = -1.0f; z < 1.0f; z += 0.1f)
666       {
667         Vector3 vForward(x, y, z);
668         vForward.Normalize();
669
670         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
671         {
672           Quaternion rotation1(Radian(Degree(angle)), vForward);
673
674           Matrix  m1(rotation1);
675           Matrix  result1(false);
676           Vector3 vForward3(vForward.x, vForward.y, vForward.z);
677           result1.SetTransformComponents(Vector3::ONE, Quaternion(Radian(Degree(angle)), vForward3), Vector3::ZERO);
678
679           DALI_TEST_EQUALS(m1, result1, 0.001, TEST_LOCATION);
680
681           Matrix m2(false);
682           m2.SetTransformComponents(vForward, Quaternion::IDENTITY, Vector3::ZERO);
683
684           Matrix result2a(Matrix::IDENTITY);
685           result2a.SetXAxis(result2a.GetXAxis() * vForward[0]);
686           result2a.SetYAxis(result2a.GetYAxis() * vForward[1]);
687           result2a.SetZAxis(result2a.GetZAxis() * vForward[2]);
688
689           DALI_TEST_EQUALS(m2, result2a, 0.001, TEST_LOCATION);
690
691           Matrix m3(false);
692           m3.SetTransformComponents(vForward, rotation1, Vector3::ZERO);
693
694           Matrix result3(Matrix::IDENTITY);
695           result3.SetXAxis(result3.GetXAxis() * vForward[0]);
696           result3.SetYAxis(result3.GetYAxis() * vForward[1]);
697           result3.SetZAxis(result3.GetZAxis() * vForward[2]);
698
699           Matrix::Multiply(result3, result3, m1);
700           DALI_TEST_EQUALS(m3, result3, 0.001, TEST_LOCATION);
701         }
702       }
703     }
704   }
705   END_TEST;
706 }
707
708 int UtcDaliMatrixSetInverseTransformComponent01P(void)
709 {
710   // Create an arbitrary vector
711   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
712   {
713     for(float y = -1.0f; y < 1.0f; y += 0.1f)
714     {
715       for(float z = -1.0f; z < 1.0f; z += 0.1f)
716       {
717         Vector3 vForward(x, y, z);
718         vForward.Normalize();
719
720         {
721           Quaternion rotation1(Quaternion::IDENTITY); // test no rotation branch
722           Vector3    scale1(2.0f, 3.0f, 4.0f);
723           Vector3    position1(1.0f, 2.0f, 3.0f);
724
725           Matrix m1(false);
726           m1.SetTransformComponents(scale1, rotation1, position1);
727
728           Matrix m2(false);
729           m2.SetInverseTransformComponents(scale1, rotation1, position1);
730
731           Matrix result;
732           Matrix::Multiply(result, m1, m2);
733
734           DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
735         }
736       }
737     }
738   }
739   END_TEST;
740 }
741
742 int UtcDaliMatrixSetInverseTransformComponent02P(void)
743 {
744   // Create an arbitrary vector
745   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
746   {
747     for(float y = -1.0f; y < 1.0f; y += 0.1f)
748     {
749       for(float z = -1.0f; z < 1.0f; z += 0.1f)
750       {
751         Vector3 vForward(x, y, z);
752         vForward.Normalize();
753
754         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
755         {
756           Quaternion rotation1(Radian(Degree(angle)), vForward);
757           Matrix     rotationMatrix(rotation1); // TEST RELIES ON THIS METHOD WORKING!!!
758
759           Vector3 position1(5.0f, -6.0f, 7.0f);
760
761           Matrix m1(false);
762           m1.SetTransformComponents(Vector3::ONE, rotation1, position1);
763
764           Matrix m2(false);
765           m2.SetInverseTransformComponents(rotationMatrix.GetXAxis(),
766                                            rotationMatrix.GetYAxis(),
767                                            rotationMatrix.GetZAxis(),
768                                            position1);
769
770           Matrix result;
771           Matrix::Multiply(result, m1, m2);
772
773           DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
774         }
775       }
776     }
777   }
778   END_TEST;
779 }
780
781 int UtcDaliMatrixGetTransformComponents01P(void)
782 {
783   Matrix     m2(Matrix::IDENTITY.AsFloat());
784   Vector3    pos2;
785   Vector3    scale2;
786   Quaternion q2;
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(1.0f, 1.0f, 1.0f), scale2, 0.001, TEST_LOCATION);
790   DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
791   END_TEST;
792 }
793
794 int UtcDaliMatrixGetTransformComponents02P(void)
795 {
796   // Create an arbitrary vector
797   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
798   {
799     for(float y = -1.0f; y < 1.0f; y += 0.1f)
800     {
801       for(float z = -1.0f; z < 1.0f; z += 0.1f)
802       {
803         Vector3 vForward(x, y, z);
804         vForward.Normalize();
805
806         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
807         {
808           Quaternion rotation1(Radian(Degree(angle)), vForward);
809           Vector3    scale1(2.0f, 3.0f, 4.0f);
810           Vector3    position1(1.0f, 2.0f, 3.0f);
811
812           Matrix m1(false);
813           m1.SetTransformComponents(scale1, rotation1, position1);
814
815           Vector3    position2;
816           Quaternion rotation2;
817           Vector3    scale2;
818           m1.GetTransformComponents(position2, rotation2, scale2);
819
820           DALI_TEST_EQUALS(position1, position2, 0.001, TEST_LOCATION);
821           DALI_TEST_EQUALS(scale1, scale2, 0.001, TEST_LOCATION);
822           DALI_TEST_EQUALS(rotation1, rotation2, 0.001, TEST_LOCATION);
823         }
824       }
825     }
826   }
827   END_TEST;
828 }
829
830 int UtcDaliMatrixGetTransformComponents03P(void)
831 {
832   Matrix     m2; // zero branch
833   Vector3    pos2;
834   Vector3    scale2;
835   Quaternion q2;
836   m2.GetTransformComponents(pos2, q2, scale2);
837   DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
838   DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), scale2, 0.001, TEST_LOCATION);
839   // DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
840   END_TEST;
841 }
842
843 int UtcDaliMatrixOStreamOperator(void)
844 {
845   std::ostringstream oss;
846
847   Matrix matrix;
848   matrix.SetIdentity();
849
850   oss << matrix;
851
852   std::string expectedOutput = "[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]";
853
854   DALI_TEST_EQUALS(oss.str(), expectedOutput, TEST_LOCATION);
855   END_TEST;
856 }