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_TransformMatrix3Df.cpp
20 * @brief This file contains implementation of _TransformMatrix3Df class
22 * This file contains implementation _TransformMatrix3Df class.
26 #include <FGrpFloatMatrix4.h>
28 #include "FUiAnim_MatrixUtil.h"
29 #include "FUiAnim_TransformMatrix3Df.h"
31 using namespace Tizen::Graphics;
32 using namespace Tizen::Ui;
33 using namespace Tizen::Ui::Animations;
35 #define DEGTORAD(d) ((d) * M_PI / 180.0f)
36 #define RADTODEG(r) ((r) * 180.0f / M_PI)
40 DumpQuaternion(const _TransformMatrix3Df& tm)
45 tm.GetQuaternion(x, y, z, w);
49 float sinh = sin(halfth);
53 printf("QuatR: x= %f, y= %f, z= %f, w= %f\n", x, y, z, w);
54 printf("Quat: rx= %f, ry= %f, rz= %f, theta= %f\n", rx, ry, rz, 2.0f * halfth * 180.0f / M_PI);
57 tm.GetEulerAngles(x, y, z);
58 printf("Euler Rotation: %f, %f, %f\n", x, y, z);
62 DumpMatrix(const FloatMatrix4& m)
64 printf("Matrix: %f %f %f %f\n", m.matrix[0][0], m.matrix[1][0], m.matrix[2][0], m.matrix[3][0]);
65 printf(" %f %f %f %f\n", m.matrix[0][1], m.matrix[1][1], m.matrix[2][1], m.matrix[3][1]);
66 printf(" %f %f %f %f\n", m.matrix[0][2], m.matrix[1][2], m.matrix[2][2], m.matrix[3][2]);
67 printf(" %f %f %f %f\n", m.matrix[0][3], m.matrix[1][3], m.matrix[2][2], m.matrix[3][3]);
74 GetTranslationMatrix(float tx, float ty, float tz)
85 namespace Tizen { namespace Ui { namespace Animations {
87 _TransformMatrix3Df::_TransformMatrix3Df(void)
88 : __transformType(MATRIX4_Identity)
89 , __usePerspective(false)
92 , __useRotation(false)
93 , __useTranslation(false)
104 , __translationX(0.0f)
105 , __translationY(0.0f)
106 , __translationZ(0.0f)
107 , __perspectiveX(0.0f)
108 , __perspectiveY(0.0f)
109 , __perspectiveZ(0.0f)
110 , __perspectiveW(1.0f)
114 , __scaleAnchorX(0.0f)
115 , __scaleAnchorY(0.0f)
116 , __scaleAnchorZ(0.0f)
123 _TransformMatrix3Df::~_TransformMatrix3Df(void)
128 _TransformMatrix3Df::Clear(void)
130 __rotX = __rotY = __rotZ = 0.0f;
131 __scaleX = __scaleY = __scaleZ = 1.0f;
132 __shearXY = __shearXZ = __shearYZ = 0.0f;
133 __quatX = __quatY = __quatZ = 0.0f; __quatW = 1.0f;
134 __translationX = __translationY = __translationZ = 0.0f;
135 __perspectiveX = __perspectiveY = __perspectiveZ = 0.0f; __perspectiveW = 1.0f;
137 __usePerspective = false;
139 __useRotation = false;
140 __useTranslation = false;
141 __transformType = MATRIX4_Identity;
145 _TransformMatrix3Df::SetTransformMatrix(const FloatMatrix4& transformMatrix)
147 // Check if fast-path is available
148 // if (transformMatrix.IsIdentity())
150 if (transformMatrix == FloatMatrix4::IDENTITY_MATRIX)
157 // Normalize the matrix.
158 // float mw = transformMatrix.Get(3, 3);
159 float mw = transformMatrix.matrix[3][3];
160 // if (_FloatHardCompare(mw, 0.0f))
161 if (unlikely(mw == 0.0f))
167 for (int i = 0; i < 4; i++)
169 for (int j = 0; j < 4; j++)
170 //locmat.Set(i, j, transformMatrix.Get(j, i) / mw);
171 locmat.matrix[j][i] = transformMatrix.matrix[i][j] / mw;
174 // pmat is used to solve for perspective, but it also provides
175 // an easy way to test for singularity of the upper 3x3 component.
177 FloatMatrix4 pmat(locmat);
178 for (int i = 0; i < 3; i++)
179 // pmat.Set(i, 3, 0.0f);
180 pmat.matrix[3][i] = 0.0f;
182 // pmat.Set(3, 3, 1.0f);
183 pmat.matrix[3][3] = 1.0f;
185 FloatMatrix4 pmatInverseTranspose(pmat);
186 // if (!pmatInverseTranspose.Invert())
189 if (!pmatInverseTranspose.IsInvertible())
194 if (pmatInverseTranspose.Invert() != E_SUCCESS)
200 // First, isolate perspective. This is the messiest.
201 // if (!_FloatHardCompare(locmat.Get(0, 3), 0.0f) || !_FloatHardCompare(locmat.Get(1, 3), 0.0f) || !_FloatHardCompare(locmat.Get(2, 3), 0.0f))
202 if (unlikely(locmat.matrix[3][0] != 0.0f) || unlikely(locmat.matrix[3][1] != 0.0f) || unlikely(locmat.matrix[3][2] != 0.0f))
204 // prhs is the right hand side of the equation.
205 Vector4Df prhs, psol;
207 // prhs.x = locmat.Get(0, 3);
208 // prhs.y = locmat.Get(1, 3);
209 // prhs.z = locmat.Get(2, 3);
210 // prhs.w = locmat.Get(3, 3);
211 prhs.x = locmat.matrix[3][0];
212 prhs.y = locmat.matrix[3][1];
213 prhs.z = locmat.matrix[3][2];
214 prhs.w = locmat.matrix[3][3];
217 pmatInverseTranspose.Transpose();
219 // Solve the equation by inverting pmat and multiplying
220 // prhs by the inverse. (This is the easiest way, not necessarily the best.)
221 // inverse function (and det4x4, above) from the Matrix Inversion gem in the first volume.
223 //V4MulPointByMatrix(prhs, pmatInverseTranspose, psol);
224 psol = prhs.Transform(pmatInverseTranspose);
227 // Stuff the answer away.
228 __perspectiveX = psol.x;
229 __perspectiveY = psol.y;
230 __perspectiveZ = psol.z;
231 __perspectiveW = psol.w;
233 // Clear the perspective partition.
234 // locmat.Set(0, 3, 0.0f);
235 // locmat.Set(1, 3, 0.0f);
236 // locmat.Set(2, 3, 0.0f);
237 // locmat.Set(3, 3, 1.0f);
238 locmat.matrix[3][0] = (0.0f);
239 locmat.matrix[3][1] = (0.0f);
240 locmat.matrix[3][2] = (0.0f);
241 locmat.matrix[3][3] = (1.0f);
246 __perspectiveX = 0.0f;
247 __perspectiveY = 0.0f;
248 __perspectiveZ = 0.0f;
249 __perspectiveW = 1.0f; // CHECKME: W of perspective is 1, right ? (or 0 ?)
252 // Next take care of translation (easy).
253 // __translationX = locmat.Get(3, 0);
254 // __translationY = locmat.Get(3, 1);
255 // __translationZ = locmat.Get(3, 2);
256 __translationX = locmat.matrix[0][3];
257 __translationY = locmat.matrix[1][3];
258 __translationZ = locmat.matrix[2][3];
260 for (int i = 0; i < 3; i++)
262 // locmat.Set(3, i, 0.0f);
263 locmat.matrix[i][3] = 0.0f;
267 // Now get scale and shear.
269 for (int i = 0; i < 3; i++)
271 // row[i].x = locmat.Get(i, 0);
272 // row[i].y = locmat.Get(i, 1);
273 // row[i].z = locmat.Get(i, 2);
274 row[i].x = locmat.matrix[0][i];
275 row[i].y = locmat.matrix[1][i];
276 row[i].z = locmat.matrix[2][i];
279 // Compute X scale factor and normalize first row.
280 __scaleX = row[0].GetLength();
283 // Compute XY shear factor and make 2nd row orthogonal to 1st.
284 __shearXY = row[0].Dot(row[1]);
285 Vector3Df::Combine(row[1], row[1], row[0], 1.0f, -__shearXY);
287 // Now, compute Y scale and normalize 2nd row.
288 __scaleY = row[1].GetLength();
290 __shearXY /= __scaleY;
292 // Compute XZ and YZ shears, orthogonalize 3rd row.
293 __shearXZ = row[0].Dot(row[2]);
294 Vector3Df::Combine(row[2], row[2], row[0], 1.0f, -__shearXZ);
295 __shearYZ = row[1].Dot(row[2]);
296 Vector3Df::Combine(row[2], row[2], row[1], 1.0f, -__shearYZ);
298 // Next, get Z scale and normalize 3rd row.
299 __scaleZ = row[2].GetLength();
301 __shearXZ /= __scaleZ;
302 __shearYZ /= __scaleZ;
304 // At this point, the matrix (in rows[]) is orthonormal.
305 // Check for a coordinate system flip. If the determinant
306 // is -1, then negate the matrix and the scaling factors.
308 Vector3Df pdum3 = row[1].Cross(row[2]);
309 if (row[0].Dot(pdum3) < 0.0f)
311 for (int i = 0; i < 3; i++)
323 // Now, get the rotations out
324 // For correctness, we use quaternions
325 float s, t, x, y, z, w;
327 t = row[0].x + row[1].y + row[2].z + 1.0f;
333 x = (row[2].y - row[1].z) * s;
334 y = (row[0].z - row[2].x) * s;
335 z = (row[1].x - row[0].y) * s;
337 else if (row[0].x > row[1].y && row[0].x > row[2].z)
339 s = sqrtf(1.0f + row[0].x - row[1].y - row[2].z) * 2.0f; // S = 4 * qx
341 y = (row[0].y + row[1].x) / s;
342 z = (row[0].z + row[2].x) / s;
343 w = (row[2].y - row[1].z) / s;
345 else if (row[1].y > row[2].z)
347 s = sqrtf(1.0f + row[1].y - row[0].x - row[2].z) * 2.0f; // S = 4 * qy
348 x = (row[0].y + row[1].x) / s;
350 z = (row[1].z + row[2].y) / s;
351 w = (row[0].z - row[2].x) / s;
355 s = sqrtf(1.0f + row[2].z - row[0].x - row[1].y) * 2.0f; // S = 4 * qz
356 x = (row[0].z + row[2].x) / s;
357 y = (row[1].z + row[2].y) / s;
359 w = (row[1].x - row[0].y) / s;
368 __rotY = asinf(-row[0].z);
369 if (cosf(__rotY) != 0.0f)
371 __rotX = RADTODEG(atan2f(row[1].z, row[2].z));
372 __rotZ = RADTODEG(atan2f(row[0].y, row[0].x));
376 __rotX = RADTODEG(atan2f(-row[2].x, row[1].y));
380 __rotY = RADTODEG(__rotY);
384 // Clear anchor information
388 __scaleAnchorX = 0.0f;
389 __scaleAnchorY = 0.0f;
390 __scaleAnchorZ = 0.0f;
393 //printf("--------- Rotate: %f, %f, %f, %f\n", __quatX, __quatY, __quatZ, __quatW);
394 DumpQuaternion(*this);
395 DumpMatrix(transformMatrix);
396 // printf("--------- Scale: %f, %f, %f\n", __scaleX, __scaleY, __scaleZ);
397 // printf("--------- Translate: %f, %f, %f\n", __translationX, __translationY, __translationZ);
401 UpdateMatrixType(true);
407 _TransformMatrix3Df::Interpolate(const _TransformMatrix3Df& transformMatrixFrom, float progress) const
409 #define FLOAT_INTP(v, c, f, t, p) do { if (likely((f.v) != (t.v))) c.v = (f.v) + ((t.v) - (f.v)) * (p); else c.v = f.v; } while (0)
411 const _TransformMatrix3Df& fromTransform = transformMatrixFrom;
412 const _TransformMatrix3Df& toTransform = *this;
413 _TransformMatrix3Df currentTransform;
415 FLOAT_INTP(__scaleX, currentTransform, fromTransform, toTransform, progress);
416 FLOAT_INTP(__scaleY, currentTransform, fromTransform, toTransform, progress);
417 FLOAT_INTP(__scaleZ, currentTransform, fromTransform, toTransform, progress);
418 FLOAT_INTP(__shearXY, currentTransform, fromTransform, toTransform, progress);
419 FLOAT_INTP(__shearXZ, currentTransform, fromTransform, toTransform, progress);
420 FLOAT_INTP(__shearYZ, currentTransform, fromTransform, toTransform, progress);
421 FLOAT_INTP(__translationX, currentTransform, fromTransform, toTransform, progress);
422 FLOAT_INTP(__translationY, currentTransform, fromTransform, toTransform, progress);
423 FLOAT_INTP(__translationZ, currentTransform, fromTransform, toTransform, progress);
424 FLOAT_INTP(__perspectiveX, currentTransform, fromTransform, toTransform, progress);
425 FLOAT_INTP(__perspectiveY, currentTransform, fromTransform, toTransform, progress);
426 FLOAT_INTP(__perspectiveZ, currentTransform, fromTransform, toTransform, progress);
427 FLOAT_INTP(__perspectiveW, currentTransform, fromTransform, toTransform, progress);
429 // Interpolate anchor points
430 FLOAT_INTP(__rotAnchorX, currentTransform, fromTransform, toTransform, progress);
431 FLOAT_INTP(__rotAnchorY, currentTransform, fromTransform, toTransform, progress);
432 FLOAT_INTP(__rotAnchorZ, currentTransform, fromTransform, toTransform, progress);
433 FLOAT_INTP(__scaleAnchorX, currentTransform, fromTransform, toTransform, progress);
434 FLOAT_INTP(__scaleAnchorY, currentTransform, fromTransform, toTransform, progress);
435 FLOAT_INTP(__scaleAnchorZ, currentTransform, fromTransform, toTransform, progress);
437 // rotation component
439 // It is not needed to update __rotX/Y/Z because the calculating interpolated matrix would not use those values
441 FLOAT_INTP(__rotX, currentTransform, fromTransform, toTransform, progress);
442 FLOAT_INTP(__rotY, currentTransform, fromTransform, toTransform, progress);
443 FLOAT_INTP(__rotZ, currentTransform, fromTransform, toTransform, progress);
444 currentTransform.UpdateRotationFromEulerAngles(currentTransform.__rotX, currentTransform.__rotY, currentTransform.__rotZ);
446 DoSlerp(¤tTransform.__quatX, &fromTransform.__quatX, &toTransform.__quatX, progress);
450 // 'GetTransformMatrix' will use matrix type
451 currentTransform.UpdateMatrixType(true);
455 printf("----------p: %f\n", progress);
456 printf("--------- qf: %f, %f, %f, %f\n", fromTransform.__quatX, fromTransform.__quatY, fromTransform.__quatZ, fromTransform.__quatW);
457 printf("--------- qt: %f, %f, %f, %f\n", toTransform.__quatX, toTransform.__quatY, toTransform.__quatZ, toTransform.__quatW);
458 printf("--------- q: %f, %f, %f, %f\n", currentTransform.__quatX, currentTransform.__quatY, currentTransform.__quatZ, currentTransform.__quatW);
461 float halfth = acosf(currentTransform.__quatW);
464 rx = currentTransform.__quatX / sinf(halfth);
465 ry = currentTransform.__quatY / sinf(halfth);
466 rz = currentTransform.__quatZ / sinf(halfth);
467 printf(" ==> q: %f, %f, %f, %f\n", rx, ry, rz, 2.0f * halfth * 180 / M_PI);
468 printf(" ==> q: %f, %f, %f, %f\n", -rx, -ry, -rz, 2.0f * halfth * 180 / M_PI);
473 return currentTransform.GetTransformMatrix();
475 printf("--------- q: %f, %f, %f, %f\n", currentTransform.__quatX, currentTransform.__quatY, currentTransform.__quatZ, currentTransform.__quatW);
476 FloatMatrix4 cm = currentTransform.GetTransformMatrix();
485 _TransformMatrix3Df::UpdateMatrixType(bool needFullCheck)
487 if (unlikely(needFullCheck))
489 __useRotation = (unlikely(!_FloatCompare(__quatX, 0.0f)) || unlikely(!_FloatCompare(__quatY, 0.0f)) || unlikely(!_FloatCompare(__quatZ, 0.0f)) || unlikely(!_FloatCompare(__quatW, 1.0f)));
490 __useShear = (unlikely(!_FloatCompare(__shearXY, 0.0f)) || unlikely(!_FloatCompare(__shearXZ, 0.0f)) || unlikely(!_FloatCompare(__shearYZ, 0.0f)));
491 __useScale = (unlikely(!_FloatCompare(__scaleX, 1.0f)) || unlikely(!_FloatCompare(__scaleY, 1.0f)) || unlikely(!_FloatCompare(__scaleZ, 1.0f)));
492 __useTranslation = (unlikely(!_FloatCompare(__translationX, 0.0f)) || unlikely(!_FloatCompare(__translationY, 0.0f)) || unlikely(!_FloatCompare(__translationZ, 0.0f)));
493 __usePerspective = (unlikely(!_FloatCompare(__perspectiveX, 0.0f)) || unlikely(!_FloatCompare(__perspectiveY, 0.0f)) || unlikely(!_FloatCompare(__perspectiveZ, 0.0f)) || unlikely(!_FloatCompare(__perspectiveW, 1.0f)));
497 if (unlikely(__usePerspective) || unlikely(__useRotation) || unlikely(__useShear))
499 __transformType = MATRIX4_Generic;
501 else if (unlikely(__useScale))
503 __transformType = MATRIX4_Scale;
505 else if (likely(__useTranslation))
507 __transformType = MATRIX4_Translation;
511 __transformType = MATRIX4_Identity;
516 _TransformMatrix3Df::GetTransformMatrix(void) const
520 if (likely(__transformType == MATRIX4_Translation))
522 m.matrix[3][0] = __translationX;
523 m.matrix[3][1] = __translationY;
524 m.matrix[3][2] = __translationZ;
525 m.matrix[3][3] = 1.0f;
528 else if (unlikely(__transformType == MATRIX4_Identity))
530 _MatrixUtilSetIdentity(m);
536 // apply perspective;
537 // m.Set(0, 3, __perspectiveX);
538 // m.Set(1, 3, __perspectiveY);
539 // m.Set(2, 3, __perspectiveZ);
540 // m.Set(3, 3, __perspectiveW);
541 m.matrix[3][0] = __perspectiveX;
542 m.matrix[3][1] = __perspectiveY;
543 m.matrix[3][2] = __perspectiveZ;
544 m.matrix[3][3] = __perspectiveW;
548 // m.Set(3, 0, __translationX);
549 // m.Set(3, 1, __translationY);
550 // m.Set(3, 2, __translationZ);
551 // m.Set(3, 3, __perspectiveW + (__perspectiveX * __translationX) + (__perspectiveY * __translationY) + (__perspectiveZ * __translationZ));
552 m.matrix[0][3] = __translationX;
553 m.matrix[1][3] = __translationY;
554 m.matrix[2][3] = __translationZ;
555 m.matrix[3][3] = __perspectiveW + (__perspectiveX * __translationX) + (__perspectiveY * __translationY) + (__perspectiveZ * __translationZ);
559 if (unlikely(__quatX != 0.0f) || unlikely(__quatY != 0.0f) || unlikely(__quatZ != 0.0f))
561 float xx = __quatX * __quatX;
562 float xy = __quatX * __quatY;
563 float xz = __quatX * __quatZ;
564 float xw = __quatX * __quatW;
565 float yy = __quatY * __quatY;
566 float yz = __quatY * __quatZ;
567 float yw = __quatY * __quatW;
568 float zz = __quatZ * __quatZ;
569 float zw = __quatZ * __quatW;
571 // Construct a composite rotation matrix from the quaternion values
573 const float rotM[4][4] = { // WARNING: C++ array is row-major order !
574 { 1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0 },
575 { 2 * (xy - zw), 1 - 2 * (xx + zz), 2 * (yz + xw), 0 },
576 { 2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy), 0 },
580 const float rotM[4][4] = { // WARNING: C++ array is row-major order !
581 { 1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0 },
582 { 2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0 },
583 { 2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0 },
588 m = FloatMatrix4(rotM) * m;
591 if (__rotAnchorX != 0.0f || __rotAnchorY != 0.0f || __rotAnchorZ != 0.0f)
592 m = GetTranslationMatrix(-__rotAnchorX, -__rotAnchorY, -__rotAnchorZ) * FloatMatrix4(rotM) * GetTranslationMatrix(__rotAnchorX, __rotAnchorY, __rotAnchorZ) * m;
594 m = FloatMatrix4(rotM) * m;
596 if (__rotAnchorX != 0.0f || __rotAnchorY != 0.0f || __rotAnchorZ != 0.0f)
598 const FloatMatrix4& back = GetTranslationMatrix(-__rotAnchorX, -__rotAnchorY, -__rotAnchorZ);
599 const FloatMatrix4& move = GetTranslationMatrix(__rotAnchorX, __rotAnchorY, __rotAnchorZ);
601 _MatrixUtilMultiply(intm, back, FloatMatrix4(rotM));
602 _MatrixUtilMultiply(intm, intm, move);
603 _MatrixUtilMultiply(m, intm, m);
607 _MatrixUtilMultiply(m, FloatMatrix4(rotM), m);
619 //sh.Set(2, 1, __shearYZ);
620 sh.matrix[1][2] = __shearYZ;
622 _MatrixUtilMultiply(m, sh, m);
628 //sh.Set(2, 0, __shearXZ);
629 sh.matrix[0][2] = __shearXZ;
631 _MatrixUtilMultiply(m, sh, m);
637 //sh.Set(1, 0, __shearXY);
638 sh.matrix[0][1] = __shearXY;
640 _MatrixUtilMultiply(m, sh, m);
645 if (__scaleX != 1.0f)
647 // m.Set(0, 0, m.Get(0, 0) * __scaleX);
648 // m.Set(0, 1, m.Get(0, 1) * __scaleX);
649 // m.Set(0, 2, m.Get(0, 2) * __scaleX);
650 // m.Set(0, 3, m.Get(0, 3) * __scaleX);
651 m.matrix[0][0] = m.matrix[0][0] * __scaleX;
652 m.matrix[1][0] = m.matrix[1][0] * __scaleX;
653 m.matrix[2][0] = m.matrix[2][0] * __scaleX;
654 m.matrix[3][0] = m.matrix[3][0] * __scaleX;
657 if (__scaleY != 1.0f)
659 // m.Set(1, 0, m.Get(1, 0) * __scaleY);
660 // m.Set(1, 1, m.Get(1, 1) * __scaleY);
661 // m.Set(1, 2, m.Get(1, 2) * __scaleY);
662 // m.Set(1, 3, m.Get(1, 3) * __scaleY);
663 m.matrix[0][1] = m.matrix[0][1] * __scaleX;
664 m.matrix[1][1] = m.matrix[1][1] * __scaleX;
665 m.matrix[2][1] = m.matrix[2][1] * __scaleX;
666 m.matrix[3][1] = m.matrix[3][1] * __scaleX;
669 if (__scaleZ != 1.0f)
671 // m.Set(2, 0, m.Get(2, 0) * __scaleZ);
672 // m.Set(2, 1, m.Get(2, 1) * __scaleZ);
673 // m.Set(2, 2, m.Get(2, 2) * __scaleZ);
674 // m.Set(2, 3, m.Get(2, 3) * __scaleZ);
675 m.matrix[0][2] = m.matrix[0][2] * __scaleX;
676 m.matrix[1][2] = m.matrix[1][2] * __scaleX;
677 m.matrix[2][2] = m.matrix[2][2] * __scaleX;
678 m.matrix[3][2] = m.matrix[3][2] * __scaleX;
681 if (__scaleAnchorX != 0.0f || __scaleAnchorY != 0.0f || __scaleAnchorZ != 0.0f)
684 _MatrixUtilScale(sc, __scaleX, __scaleY, __scaleZ);
685 // m = GetTranslationMatrix(-__scaleAnchorX, -__scaleAnchorY, -__scaleAnchorZ) * sc * GetTranslationMatrix(__scaleAnchorX, __scaleAnchorY, __scaleAnchorZ) * m;
687 const FloatMatrix4& back = GetTranslationMatrix(-__scaleAnchorX, -__scaleAnchorY, -__scaleAnchorZ);
688 const FloatMatrix4& move = GetTranslationMatrix(__scaleAnchorX, __scaleAnchorY, __scaleAnchorZ);
690 _MatrixUtilMultiply(intm, back, sc);
691 _MatrixUtilMultiply(intm, intm, move);
692 _MatrixUtilMultiply(m, intm, m);
696 if (__scaleX != 1.0f)
698 m.matrix[0][0] = m.matrix[0][0] * __scaleX;
699 m.matrix[1][0] = m.matrix[1][0] * __scaleX;
700 m.matrix[2][0] = m.matrix[2][0] * __scaleX;
701 m.matrix[3][0] = m.matrix[3][0] * __scaleX;
704 if (__scaleY != 1.0f)
706 m.matrix[0][1] = m.matrix[0][1] * __scaleY;
707 m.matrix[1][1] = m.matrix[1][1] * __scaleY;
708 m.matrix[2][1] = m.matrix[2][1] * __scaleY;
709 m.matrix[3][1] = m.matrix[3][1] * __scaleY;
712 if (__scaleZ != 1.0f)
714 m.matrix[0][2] = m.matrix[0][2] * __scaleZ;
715 m.matrix[1][2] = m.matrix[1][2] * __scaleZ;
716 m.matrix[2][2] = m.matrix[2][2] * __scaleZ;
717 m.matrix[3][2] = m.matrix[3][2] * __scaleZ;
728 _TransformMatrix3Df::UpdateRotationFromEulerAngles(float x, float y, float z)
731 // Internal quaternion complies with left-hand system.
733 float hx = 0.5f * DEGTORAD(x);
734 float hy = 0.5f * DEGTORAD(y);
735 float hz = 0.5f * DEGTORAD(z);
736 float xcosh = cosf(hx);
737 float ycosh = cosf(hy);
738 float zcosh = cosf(hz);
739 float xsinh = sinf(hx);
740 float ysinh = sinf(hy);
741 float zsinh = sinf(hz);
743 __quatW = zcosh * ycosh * xcosh + zsinh * ysinh * xsinh;
744 __quatX = zcosh * ycosh * xsinh - zsinh * ysinh * xcosh;
745 __quatY = zcosh * ysinh * xcosh + zsinh * ycosh * xsinh;
746 __quatZ = zsinh * ycosh * xcosh - zcosh * ysinh * xsinh;
749 printf("--euler:%f,%f,%f(%f, %f, %f)\n",
751 atan2f(2.0f * (__quatW * __quatX + __quatY * __quatZ), 1.0f - 2.0f * (__quatX * __quatX + __quatY * __quatY)) * 180.0f / M_PI,
752 asinf(2.0f * (__quatW * __quatY - __quatZ * __quatX)) * 180.0f / M_PI,
753 atan2f(2.0f * (__quatW * __quatZ + __quatX * __quatY), 1.0f - 2.0f * (__quatY * __quatY + __quatZ * __quatZ)) * 180.0f / M_PI
762 __useRotation = (unlikely(!_FloatCompare(__quatX, 0.0f)) || unlikely(!_FloatCompare(__quatY, 0.0f)) || unlikely(!_FloatCompare(__quatZ, 0.0f)) || unlikely(!_FloatCompare(__quatW, 1.0f)));
763 UpdateMatrixType(false);
765 //DumpQuaternion(*this);
770 _TransformMatrix3Df::CalcEulerAngles(void)
774 float sx = __quatX * __quatX;
775 float sy = __quatY * __quatY;
776 float sz = __quatZ * __quatZ;
779 float sw = __quatW * __quatW;
781 __rotX = atan2f(2.0f * (__quatY * __quatZ + __quatX * __quatW), (sw - sx - sy + sz));
782 __rotY = asinf(-2.0f * (__quatX * __quatZ - __quatY * __quatW));
783 __rotZ = atan2f(2.0f * (__quatX * __quatY + __quatZ * __quatW), (sw + sx - sy - sz));
785 __rotX = atan2f(2.0f * (__quatX * __quatW + __quatY * __quatZ), 1.0f - 2.0f * (sx + sy));
786 __rotY = asinf(-2.0f * (__quatX * __quatZ - __quatY * __quatW));
787 __rotZ = atan2f(2.0f * (__quatX * __quatY + __quatZ * __quatW), 1.0f - 2.0f * (sy + sz));
790 __rotX *= 180.0f / M_PI;
791 __rotY *= 180.0f / M_PI;
792 __rotZ *= 180.0f / M_PI;
797 _TransformMatrix3Df::GetEulerAngles(float& x, float& y, float& z) const
805 _TransformMatrix3Df::GetQuaternion(float& x, float& y, float& z, float& w) const
814 _TransformMatrix3Df::GetRotationAnchor(float& x, float& y, float& z) const
822 _TransformMatrix3Df::SetRotationAnchor(float x, float y, float z)
830 _TransformMatrix3Df::GetScaleFactors(float& x, float& y, float& z) const
838 _TransformMatrix3Df::SetScaleFactors(float x, float y, float z)
844 __useScale = (unlikely(!_FloatCompare(x, 1.0f)) || unlikely(!_FloatCompare(y, 1.0f)) || unlikely(!_FloatCompare(z, 1.0f)));
845 UpdateMatrixType(false);
849 _TransformMatrix3Df::GetScaleAnchor(float& x, float& y, float& z) const
857 _TransformMatrix3Df::SetScaleAnchor(float x, float y, float z)
865 _TransformMatrix3Df::GetShearFactors(float& xy, float& xz, float& yz) const
873 _TransformMatrix3Df::SetShearFactors(float xy, float xz, float yz)
879 __useShear = (unlikely(!_FloatCompare(xy, 0.0f)) || unlikely(!_FloatCompare(xz, 0.0f)) || unlikely(!_FloatCompare(yz, 0.0f)));
880 UpdateMatrixType(false);
884 _TransformMatrix3Df::GetTranslationFactors(float& x, float& y, float& z) const
892 _TransformMatrix3Df::SetTranslationFactors(float x, float y, float z)
898 __useTranslation = (unlikely(!_FloatCompare(x, 0.0f)) || unlikely(!_FloatCompare(y, 0.0f)) || unlikely(!_FloatCompare(z, 0.0f)));
899 UpdateMatrixType(false);
903 _TransformMatrix3Df::GetPerspectiveFactors(float& x, float& y, float& z, float& w) const
912 _TransformMatrix3Df::SetPerspectiveFactors(float x, float y, float z, float w)
919 __usePerspective = (unlikely(!_FloatCompare(x, 0.0f)) || !unlikely(_FloatCompare(y, 0.0f)) || !unlikely(_FloatCompare(z, 0.0f)) || unlikely(!_FloatCompare(w, 1.0f)));
920 UpdateMatrixType(false);
923 // Perform a spherical linear interpolation between the two
924 // passed quaternions with 0 <= t <= 1
926 _TransformMatrix3Df::DoSlerp(float* result, const float* src1, const float* src2, float t) const
928 float ax, ay, az, aw;
929 float bx, by, bz, bw;
930 float cx, cy, cz, cw;
932 float th, invth, scale, invscale;
934 if (unlikely(t == 0.0f))
943 if (unlikely(t == 1.0f))
953 ax = src1[0]; ay = src1[1]; az = src1[2]; aw = src1[3];
954 bx = src2[0]; by = src2[1]; bz = src2[2]; bw = src2[3];
956 angle = ax * bx + ay * by + az * bz + aw * bw;
966 if (angle + 1.0f > 0.05f)
968 if (1.0f - angle >= 0.05f)
971 invth = 1.0f / sinf(th);
972 scale = sinf(th * (1.0f - t)) * invth;
973 invscale = sinf(th * t) * invth;
987 scale = sinf(M_PI * (0.5f - t));
988 invscale = sinf(M_PI * t);
991 cx = ax * scale + bx * invscale;
992 cy = ay * scale + by * invscale;
993 cz = az * scale + bz * invscale;
994 cw = aw * scale + bw * invscale;
997 float the, a, rx, ry, rz;
999 a = the * 2.0f * 180.0f / M_PI;
1000 rx = cx / sinf(the);
1001 ry = cy / sinf(the);
1002 rz = cz / sinf(the);
1003 //printf("--- angle= %f(f= %f,%f,%f)(%f, %f, %f, %f)\n", a, rx, ry, rz, cx, cy, cz, cw);
1017 if (angle <= -1.0f || angle >= 1.0f)
1027 float sinHalfTheta = sqrt(1.0 - angle * angle);
1028 if (abs(sinHalfTheta) < 0.001)
1030 cx = ax * 0.5 + bx * 0.5;
1031 cy = ay * 0.5 + by * 0.5;
1032 cz = az * 0.5 + bz * 0.5;
1033 cw = aw * 0.5 + bw * 0.5;
1037 float ra = sin((1.0 - t) * th) / sinHalfTheta;
1038 float rb = sin(t * th) / sinHalfTheta;
1039 cx = ax * ra + bx * rb;
1040 cy = ay * ra + by * rb;
1041 cz = az * ra + bz * rb;
1042 cw = aw * ra + bw * rb;
1056 _TransformMatrix3Df::V4MulPointByMatrix(const _Vector4Df& pin, const FloatMatrix4& m, _Vector4Df& pout) const
1059 pout.x = (pin.x * m.Get(0, 0))
1060 + (pin.y * m.Get(1, 0))
1061 + (pin.z * m.Get(2, 0))
1062 + (pin.w * m.Get(3, 0));
1064 pout.y = (pin.x * m.Get(0, 1))
1065 + (pin.y * m.Get(1, 1))
1066 + (pin.z * m.Get(2, 1))
1067 + (pin.w * m.Get(3, 1));
1069 pout.z = (pin.x * m.Get(0, 2))
1070 + (pin.y * m.Get(1, 2))
1071 + (pin.z * m.Get(2, 2))
1072 + (pin.w * m.Get(3, 2));
1074 pout.w = (pin.x * m.Get(0, 3))
1075 + (pin.y * m.Get(1, 3))
1076 + (pin.z * m.Get(2, 3))
1077 + (pin.w * m.Get(3, 3));
1080 pout.x = (pin.x * m.matrix[0][0])
1081 + (pin.y * m.matrix[0][1])
1082 + (pin.z * m.matrix[0][2])
1083 + (pin.w * m.matrix[0][3]);
1085 pout.y = (pin.x * m.matrix[1][0])
1086 + (pin.y * m.matrix[1][1])
1087 + (pin.z * m.matrix[1][2])
1088 + (pin.w * m.matrix[1][3]);
1090 pout.z = (pin.x * m.matrix[2][0])
1091 + (pin.y * m.matrix[2][1])
1092 + (pin.z * m.matrix[2][2])
1093 + (pin.w * m.matrix[2][3]);
1095 pout.w = (pin.x * m.matrix[3][0])
1096 + (pin.y * m.matrix[3][1])
1097 + (pin.z * m.matrix[3][2])
1098 + (pin.w * m.matrix[3][3]);
1103 _TransformMatrix3Df::V3SquaredLength(const _Vector3Df& v) const
1105 return ((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
1109 _TransformMatrix3Df::V3Length(const _Vector3Df& v) const
1111 return (sqrtf(V3SquaredLength(v)));
1115 _TransformMatrix3Df::V3Scale(_Vector3Df& v, float newlen) const
1117 float len = V3Length(v);
1121 v.x *= newlen / len;
1122 v.y *= newlen / len;
1123 v.z *= newlen / len;
1128 _TransformMatrix3Df::V3Dot(const _Vector3Df& a, const _Vector3Df& b) const
1130 return ((a.x * b.x) + (a.y * b.y) + (a.z * b.z));
1134 _TransformMatrix3Df::V3Combine(const _Vector3Df& a, const _Vector3Df& b, _Vector3Df& result, float ascl, float bscl) const
1136 result.x = (ascl * a.x) + (bscl * b.x);
1137 result.y = (ascl * a.y) + (bscl * b.y);
1138 result.z = (ascl * a.z) + (bscl * b.z);
1142 _TransformMatrix3Df::V3Cross(const _Vector3Df& a, const _Vector3Df& b, _Vector3Df& c) const
1144 c.x = (a.y * b.z) - (a.z * b.y);
1145 c.y = (a.z * b.x) - (a.x * b.z);
1146 c.z = (a.x * b.y) - (a.y * b.x);
1150 }}} // Tizen::Ui::Animations