2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://floralicense.org/license/
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FUiAnim_MatrixUtil.cpp
20 * @brief This file contains implementation of _MatrixUtil module
22 * This file contains implementation _MatrixUtil module.
26 #include <FUiVariant.h>
27 #include <FGrpRectangle.h>
28 #include <FGrpFloatRectangle.h>
29 #include <FGrpPoint.h>
30 #include <FGrpFloatPoint.h>
31 #include <FGrpDimension.h>
32 #include <FGrpFloatDimension.h>
33 #include <FGrpColor.h>
34 #include <FGrpFloatMatrix4.h>
35 #include <FGrpFloatVector4.h>
38 #include "FUiAnim_MatrixUtil.h"
41 using namespace Tizen;
42 using namespace Tizen::Base;
43 using namespace Tizen::Graphics;
45 namespace Tizen { namespace Ui { namespace Animations
48 static const float _IDENTITY_MATRIX[4][4] =
50 { 1.0f, 0.0f, 0.0f, 0.0f },
51 { 0.0f, 1.0f, 0.0f, 0.0f },
52 { 0.0f, 0.0f, 1.0f, 0.0f },
53 { 0.0f, 0.0f, 0.0f, 1.0f }
58 _GetMatrix4Type(const Tizen::Graphics::FloatMatrix4& floatMatrix)
60 if (floatMatrix.matrix[3][3] != 1.0f)
62 return MATRIX4_Generic;
65 if (floatMatrix.matrix[1][0] != 0.0f || floatMatrix.matrix[2][0] != 0.0f || floatMatrix.matrix[2][1] != 0.0f)
67 return MATRIX4_Generic;
70 if (floatMatrix.matrix[0][1] != 0.0f || floatMatrix.matrix[0][2] != 0.0f || floatMatrix.matrix[0][3] != 0.0f ||
71 floatMatrix.matrix[1][2] != 0.0f || floatMatrix.matrix[1][3] != 0.0f || floatMatrix.matrix[2][3] != 0.0f)
73 return MATRIX4_Generic;
76 bool isTranslate = (floatMatrix.matrix[3][0] != 0.0f || floatMatrix.matrix[3][1] != 0.0f || floatMatrix.matrix[3][2] != 0.0f);
77 bool isDiagonal = (floatMatrix.matrix[0][0] == 1.0f && floatMatrix.matrix[1][1] == 1.0f && floatMatrix.matrix[2][2] == 1.0f);
79 if (isTranslate && isDiagonal)
81 return MATRIX4_Translation;
86 return MATRIX4_Generic;
91 return MATRIX4_Identity;
98 _MatrixUtilIsEqual(const Tizen::Graphics::FloatMatrix4& m1, const Tizen::Graphics::FloatMatrix4& m2)
100 return (memcmp(m1.matrix, m2.matrix, sizeof(m1.matrix)) == 0);
104 _MatrixUtilSetIdentity(Tizen::Graphics::FloatMatrix4& m)
106 memcpy(m.matrix, _IDENTITY_MATRIX, sizeof(_IDENTITY_MATRIX));
110 _MatrixUtilSetTranslation(Tizen::Graphics::FloatMatrix4& m, float tx, float ty, float tz)
112 memcpy(m.matrix, _IDENTITY_MATRIX, sizeof(_IDENTITY_MATRIX));
116 m.matrix[3][3] = 1.0f;
120 _MatrixUtilTransform(const Tizen::Graphics::FloatMatrix4& m, float* pX, float* pY, float* pZ)
122 FloatVector4 vec4(*pX, *pY, *pZ, 1.0f);
128 if (vec4.w != 1.0f && vec4.w != 0.0f)
137 _MatrixUtilTranslate(Tizen::Graphics::FloatMatrix4& m, float tx, float ty, float tz)
139 m.matrix[3][0] += (m.matrix[0][0] * tx + m.matrix[1][0] * ty + m.matrix[2][0] * tz);
140 m.matrix[3][1] += (m.matrix[0][1] * tx + m.matrix[1][1] * ty + m.matrix[2][1] * tz);
141 m.matrix[3][2] += (m.matrix[0][2] * tx + m.matrix[1][2] * ty + m.matrix[2][2] * tz);
142 m.matrix[3][3] += (m.matrix[0][3] * tx + m.matrix[1][3] * ty + m.matrix[2][3] * tz);
146 _MatrixUtilIsTranslation(const Tizen::Graphics::FloatMatrix4& m)
148 bool isTranslate = (m.matrix[3][0] != 0.0f || m.matrix[3][1] != 0.0f || m.matrix[3][2] != 0.0f);
149 bool isDiagonal = (m.matrix[0][0] == 1.0f && m.matrix[1][1] == 1.0f && m.matrix[2][2] == 1.0f);
151 if (isTranslate && isDiagonal)
160 _MatrixUtilScale(Tizen::Graphics::FloatMatrix4& m, float sx, float sy, float sz)
164 m.matrix[0][0] *= sx;
165 m.matrix[0][1] *= sx;
166 m.matrix[0][2] *= sx;
167 m.matrix[0][3] *= sx;
172 m.matrix[1][0] *= sy;
173 m.matrix[1][1] *= sy;
174 m.matrix[1][2] *= sy;
175 m.matrix[1][3] *= sy;
180 m.matrix[2][0] *= sz;
181 m.matrix[2][1] *= sz;
182 m.matrix[2][2] *= sz;
183 m.matrix[2][3] *= sz;
188 _MatrixUtilAtAnchor(Tizen::Graphics::FloatMatrix4& m, float x, float y, float z)
190 Tizen::Graphics::FloatMatrix4 tr;
191 Tizen::Graphics::FloatMatrix4 trInv;
197 trInv.matrix[3][0] = -x;
198 trInv.matrix[3][1] = -y;
199 trInv.matrix[3][2] = -z;
205 _MatrixUtilRotate(Tizen::Graphics::FloatMatrix4& m, float angle, float x, float y, float z)
212 // Rotation using quaternion
214 angle = angle * M_PI / 180.0f;
217 float sinA = sinf(angle);
218 float cosA = cosf(angle);
219 float sinA2 = sinA * sinA;
222 float length = sqrtf(x * x + y * y + z * z);
225 // bad vector, just use something reasonable
228 else if (length != 1.0f)
236 float mat[4][4] = { {0.0f, }, };
238 // optimize case where axis is along major axis
239 if (x == 1.0f && y == 0.0f && z == 0.0f)
245 mat[1][1] = 1.0f - 2.0f * sinA2;
246 mat[1][2] = 2.0f * sinA * cosA;
248 mat[2][1] = -2.0f * sinA * cosA;
249 mat[2][2] = 1.0f - 2.0f * sinA2;
250 mat[0][3] = mat[1][3] = mat[2][3] = 0.0f;
251 mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
254 else if (x == 0.0f && y == 1.0f && z == 0.0f)
256 mat[0][0] = 1.0f - 2.0f * sinA2;
258 mat[0][2] = -2.0f * sinA * cosA;
262 mat[2][0] = 2.0f * sinA * cosA;
264 mat[2][2] = 1.0f - 2.0f * sinA2;
265 mat[0][3] = mat[1][3] = mat[2][3] = 0.0f;
266 mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
269 else if (x == 0.0f && y == 0.0f && z == 1.0f)
271 mat[0][0] = 1.0f - 2.0f * sinA2;
272 mat[0][1] = 2.0f * sinA * cosA;
274 mat[1][0] = -2.0f * sinA * cosA;
275 mat[1][1] = 1.0f - 2.0f * sinA2;
280 mat[0][3] = mat[1][3] = mat[2][3] = 0.0f;
281 mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
290 mat[0][0] = 1.0f - 2.0f * (y2 + z2) * sinA2;
291 mat[0][1] = 2.0f * (x * y * sinA2 + z * sinA * cosA);
292 mat[0][2] = 2.0f * (x * z * sinA2 - y * sinA * cosA);
293 mat[1][0] = 2.0f * (y * x * sinA2 - z * sinA * cosA);
294 mat[1][1] = 1.0f - 2.0f * (z2 + x2) * sinA2;
295 mat[1][2] = 2.0f * (y * z * sinA2 + x * sinA * cosA);
296 mat[2][0] = 2.0f * (z * x * sinA2 + y * sinA * cosA);
297 mat[2][1] = 2.0f * (z * y * sinA2 - x * sinA * cosA);
298 mat[2][2] = 1.0f - 2.0f * (x2 + y2) * sinA2;
299 mat[0][3] = mat[1][3] = mat[2][3] = 0.0f;
300 mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
304 m *= Tizen::Graphics::FloatMatrix4(mat);
308 _MatrixUtilInvert(Tizen::Graphics::FloatMatrix4& m)
311 // WOW!!! WOW!!! WOW!!! WOW!!!
332 a0 = m.matrix[0][0] * m.matrix[1][1] - m.matrix[0][1] * m.matrix[1][0];
333 a1 = m.matrix[0][0] * m.matrix[1][2] - m.matrix[0][2] * m.matrix[1][0];
334 a2 = m.matrix[0][0] * m.matrix[1][3] - m.matrix[0][3] * m.matrix[1][0];
335 a3 = m.matrix[0][1] * m.matrix[1][2] - m.matrix[0][2] * m.matrix[1][1];
336 a4 = m.matrix[0][1] * m.matrix[1][3] - m.matrix[0][3] * m.matrix[1][1];
337 a5 = m.matrix[0][2] * m.matrix[1][3] - m.matrix[0][3] * m.matrix[1][2];
339 b0 = m.matrix[2][0] * m.matrix[3][1] - m.matrix[2][1] * m.matrix[3][0];
340 b1 = m.matrix[2][0] * m.matrix[3][2] - m.matrix[2][2] * m.matrix[3][0];
341 b2 = m.matrix[2][0] * m.matrix[3][3] - m.matrix[2][3] * m.matrix[3][0];
342 b3 = m.matrix[2][1] * m.matrix[3][2] - m.matrix[2][2] * m.matrix[3][1];
343 b4 = m.matrix[2][1] * m.matrix[3][3] - m.matrix[2][3] * m.matrix[3][1];
344 b5 = m.matrix[2][2] * m.matrix[3][3] - m.matrix[2][3] * m.matrix[3][2];
346 det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
347 // if (_FloatHardCompare(det, 0.0f))
354 float inverse_m[4][4];
356 inverse_m[0][0] = +m.matrix[1][1] * b5 - m.matrix[1][2] * b4 + m.matrix[1][3] * b3;
357 inverse_m[1][0] = -m.matrix[1][0] * b5 + m.matrix[1][2] * b2 + m.matrix[1][3] * b1;
358 inverse_m[2][0] = +m.matrix[1][0] * b4 - m.matrix[1][1] * b2 + m.matrix[1][3] * b0;
359 inverse_m[3][0] = -m.matrix[1][0] * b3 + m.matrix[1][1] * b1 - m.matrix[1][2] * b0;
360 inverse_m[0][1] = -m.matrix[0][1] * b5 + m.matrix[0][2] * b4 - m.matrix[0][3] * b3;
361 inverse_m[1][1] = +m.matrix[0][0] * b5 - m.matrix[0][2] * b2 + m.matrix[0][3] * b1;
362 inverse_m[2][1] = -m.matrix[0][0] * b4 + m.matrix[0][1] * b2 - m.matrix[0][3] * b0;
363 inverse_m[3][1] = +m.matrix[0][0] * b3 - m.matrix[0][1] * b1 + m.matrix[0][2] * b0;
364 inverse_m[0][2] = +m.matrix[3][1] * a5 - m.matrix[3][2] * a4 + m.matrix[3][3] * a3;
365 inverse_m[1][2] = -m.matrix[3][0] * a5 + m.matrix[3][2] * a2 - m.matrix[3][3] * a1;
366 inverse_m[2][2] = +m.matrix[3][0] * a4 - m.matrix[3][1] * a2 + m.matrix[3][3] * a0;
367 inverse_m[3][2] = -m.matrix[3][0] * a3 + m.matrix[3][1] * a1 - m.matrix[3][2] * a0;
368 inverse_m[0][3] = -m.matrix[2][1] * a5 + m.matrix[2][2] * a4 - m.matrix[2][3] * a3;
369 inverse_m[1][3] = +m.matrix[2][0] * a5 - m.matrix[2][2] * a2 + m.matrix[2][3] * a1;
370 inverse_m[2][3] = -m.matrix[2][0] * a4 + m.matrix[2][1] * a2 - m.matrix[2][3] * a0;
371 inverse_m[3][3] = +m.matrix[2][0] * a3 - m.matrix[2][1] * a1 + m.matrix[2][2] * a0;
373 for (int i = 0; i < 4; i++)
375 for (int j = 0; j < 4; j++)
377 inverse_m[j][i] /= det;
381 memcpy(m.matrix, inverse_m, sizeof(m.matrix));
382 // __complexity = GenericMatrix;
388 _MatrixUtilMultiply(Tizen::Graphics::FloatMatrix4& d, const Tizen::Graphics::FloatMatrix4& m1, const Tizen::Graphics::FloatMatrix4& m2)
398 __PrintMatrix(const Tizen::Graphics::FloatMatrix4& m)
400 printf("Matrix: %f %f %f %f\n", m.matrix[0][0], m.matrix[1][0], m.matrix[2][0], m.matrix[3][0]);
401 printf(" %f %f %f %f\n", m.matrix[0][1], m.matrix[1][1], m.matrix[2][1], m.matrix[3][1]);
402 printf(" %f %f %f %f\n", m.matrix[0][2], m.matrix[1][2], m.matrix[2][2], m.matrix[3][2]);
403 printf(" %f %f %f %f\n", m.matrix[0][3], m.matrix[1][3], m.matrix[2][2], m.matrix[3][3]);
409 Tizen::Graphics::FloatMatrix4 ok;
410 Tizen::Graphics::FloatMatrix4 m;
411 Tizen::Graphics::FloatMatrix4 m1;
412 Tizen::Graphics::FloatMatrix4 m2;
414 Tizen::Ui::Animations::_MatrixUtilRotate(m1, 45, 0, 0, 1);
415 Tizen::Ui::Animations::_MatrixUtilRotate(m2, 45, 0, 1, 0);
419 Tizen::Ui::Animations::_MatrixUtilMultiply(m, m1, m2);
427 unsigned int valueUInt;
432 unsigned long valueULong;
433 long long valueLongLong;
434 unsigned long long valueULongLong;
436 Tizen::Base::String* pString;
437 Tizen::Base::DateTime* dateTime;
438 Tizen::Graphics::Color* color;
439 Tizen::Graphics::Point* point;
440 Tizen::Graphics::FloatPoint* floatPoint;
441 Tizen::Graphics::Rectangle* rect;
442 Tizen::Graphics::FloatRectangle* rectf;
443 Tizen::Graphics::Dimension* dimension;
444 Tizen::Graphics::FloatDimension* floatDimension;
445 Tizen::Graphics::FloatMatrix4* floatMatrix4;
451 gettimeofday(&s, null);
452 for (int i = 0; i < 10000; i++)
454 Tizen::Ui::Variant v;
456 // memset(&v, 0, sizeof(v));
457 // v.floatMatrix4 = new FloatMatrix4;
460 gettimeofday(&e, null);
461 printf("--------- %d\n", static_cast< int >(e.tv_usec - s.tv_usec));