Matrix operator*
[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 UtcDaliMatrixOperatorEqualsP(void)
587 {
588   Matrix m1 = Matrix::IDENTITY;
589
590   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};
591   Matrix r2(els);
592   DALI_TEST_EQUALS(m1 == r2, true, TEST_LOCATION);
593
594   float* f = m1.AsFloat();
595   for(size_t i = 0; i < 16; i++)
596   {
597     f[15 - i] = 1.2f;
598     DALI_TEST_EQUALS(m1 == r2, false, TEST_LOCATION);
599   }
600   END_TEST;
601 }
602
603 int UtcDaliMatrixOperatorNotEqualsP(void)
604 {
605   Matrix m1    = Matrix::IDENTITY;
606   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};
607   Matrix r1(els);
608
609   DALI_TEST_CHECK(m1 != r1);
610   DALI_TEST_CHECK(!(m1 != m1));
611   END_TEST;
612 }
613
614 int UtcDaliMatrixSetTransformComponents01P(void)
615 {
616   // Create an arbitrary vector
617   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
618   {
619     for(float y = -1.0f; y < 1.0f; y += 0.1f)
620     {
621       for(float z = -1.0f; z < 1.0f; z += 0.1f)
622       {
623         Vector3 vForward(x, y, z);
624         vForward.Normalize();
625
626         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
627         {
628           Quaternion rotation1(Radian(Degree(angle)), vForward);
629
630           Matrix  m1(rotation1);
631           Matrix  result1(false);
632           Vector3 vForward3(vForward.x, vForward.y, vForward.z);
633           result1.SetTransformComponents(Vector3::ONE, Quaternion(Radian(Degree(angle)), vForward3), Vector3::ZERO);
634
635           DALI_TEST_EQUALS(m1, result1, 0.001, TEST_LOCATION);
636
637           Matrix m2(false);
638           m2.SetTransformComponents(vForward, Quaternion::IDENTITY, Vector3::ZERO);
639
640           Matrix result2a(Matrix::IDENTITY);
641           result2a.SetXAxis(result2a.GetXAxis() * vForward[0]);
642           result2a.SetYAxis(result2a.GetYAxis() * vForward[1]);
643           result2a.SetZAxis(result2a.GetZAxis() * vForward[2]);
644
645           DALI_TEST_EQUALS(m2, result2a, 0.001, TEST_LOCATION);
646
647           Matrix m3(false);
648           m3.SetTransformComponents(vForward, rotation1, Vector3::ZERO);
649
650           Matrix result3(Matrix::IDENTITY);
651           result3.SetXAxis(result3.GetXAxis() * vForward[0]);
652           result3.SetYAxis(result3.GetYAxis() * vForward[1]);
653           result3.SetZAxis(result3.GetZAxis() * vForward[2]);
654
655           Matrix::Multiply(result3, result3, m1);
656           DALI_TEST_EQUALS(m3, result3, 0.001, TEST_LOCATION);
657         }
658       }
659     }
660   }
661   END_TEST;
662 }
663
664 int UtcDaliMatrixSetInverseTransformComponent01P(void)
665 {
666   // Create an arbitrary vector
667   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
668   {
669     for(float y = -1.0f; y < 1.0f; y += 0.1f)
670     {
671       for(float z = -1.0f; z < 1.0f; z += 0.1f)
672       {
673         Vector3 vForward(x, y, z);
674         vForward.Normalize();
675
676         {
677           Quaternion rotation1(Quaternion::IDENTITY); // test no rotation branch
678           Vector3    scale1(2.0f, 3.0f, 4.0f);
679           Vector3    position1(1.0f, 2.0f, 3.0f);
680
681           Matrix m1(false);
682           m1.SetTransformComponents(scale1, rotation1, position1);
683
684           Matrix m2(false);
685           m2.SetInverseTransformComponents(scale1, rotation1, position1);
686
687           Matrix result;
688           Matrix::Multiply(result, m1, m2);
689
690           DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
691         }
692       }
693     }
694   }
695   END_TEST;
696 }
697
698 int UtcDaliMatrixSetInverseTransformComponent02P(void)
699 {
700   // Create an arbitrary vector
701   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
702   {
703     for(float y = -1.0f; y < 1.0f; y += 0.1f)
704     {
705       for(float z = -1.0f; z < 1.0f; z += 0.1f)
706       {
707         Vector3 vForward(x, y, z);
708         vForward.Normalize();
709
710         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
711         {
712           Quaternion rotation1(Radian(Degree(angle)), vForward);
713           Matrix     rotationMatrix(rotation1); // TEST RELIES ON THIS METHOD WORKING!!!
714
715           Vector3 position1(5.0f, -6.0f, 7.0f);
716
717           Matrix m1(false);
718           m1.SetTransformComponents(Vector3::ONE, rotation1, position1);
719
720           Matrix m2(false);
721           m2.SetInverseTransformComponents(rotationMatrix.GetXAxis(),
722                                            rotationMatrix.GetYAxis(),
723                                            rotationMatrix.GetZAxis(),
724                                            position1);
725
726           Matrix result;
727           Matrix::Multiply(result, m1, m2);
728
729           DALI_TEST_EQUALS(result, Matrix::IDENTITY, 0.001, TEST_LOCATION);
730         }
731       }
732     }
733   }
734   END_TEST;
735 }
736
737 int UtcDaliMatrixGetTransformComponents01P(void)
738 {
739   Matrix     m2(Matrix::IDENTITY.AsFloat());
740   Vector3    pos2;
741   Vector3    scale2;
742   Quaternion q2;
743   m2.GetTransformComponents(pos2, q2, scale2);
744   DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
745   DALI_TEST_EQUALS(Vector3(1.0f, 1.0f, 1.0f), scale2, 0.001, TEST_LOCATION);
746   DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
747   END_TEST;
748 }
749
750 int UtcDaliMatrixGetTransformComponents02P(void)
751 {
752   // Create an arbitrary vector
753   for(float x = -1.0f; x <= 1.0f; x += 0.1f)
754   {
755     for(float y = -1.0f; y < 1.0f; y += 0.1f)
756     {
757       for(float z = -1.0f; z < 1.0f; z += 0.1f)
758       {
759         Vector3 vForward(x, y, z);
760         vForward.Normalize();
761
762         for(float angle = 5.0f; angle <= 360.0f; angle += 15.0f)
763         {
764           Quaternion rotation1(Radian(Degree(angle)), vForward);
765           Vector3    scale1(2.0f, 3.0f, 4.0f);
766           Vector3    position1(1.0f, 2.0f, 3.0f);
767
768           Matrix m1(false);
769           m1.SetTransformComponents(scale1, rotation1, position1);
770
771           Vector3    position2;
772           Quaternion rotation2;
773           Vector3    scale2;
774           m1.GetTransformComponents(position2, rotation2, scale2);
775
776           DALI_TEST_EQUALS(position1, position2, 0.001, TEST_LOCATION);
777           DALI_TEST_EQUALS(scale1, scale2, 0.001, TEST_LOCATION);
778           DALI_TEST_EQUALS(rotation1, rotation2, 0.001, TEST_LOCATION);
779         }
780       }
781     }
782   }
783   END_TEST;
784 }
785
786 int UtcDaliMatrixGetTransformComponents03P(void)
787 {
788   Matrix     m2; // zero branch
789   Vector3    pos2;
790   Vector3    scale2;
791   Quaternion q2;
792   m2.GetTransformComponents(pos2, q2, scale2);
793   DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), pos2, 0.001, TEST_LOCATION);
794   DALI_TEST_EQUALS(Vector3(0.0f, 0.0f, 0.0f), scale2, 0.001, TEST_LOCATION);
795   // DALI_TEST_EQUALS(Quaternion(), q2, 0.001, TEST_LOCATION);
796   END_TEST;
797 }
798
799 int UtcDaliMatrixOStreamOperator(void)
800 {
801   std::ostringstream oss;
802
803   Matrix matrix;
804   matrix.SetIdentity();
805
806   oss << matrix;
807
808   std::string expectedOutput = "[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]";
809
810   DALI_TEST_EQUALS(oss.str(), expectedOutput, TEST_LOCATION);
811   END_TEST;
812 }