summaryrefslogtreecommitdiffstats
path: root/src/gui/math3d/qmatrix4x4.cpp
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2015-02-20 03:38:32 +0400
committerKonstantin Ritt <ritt.ks@gmail.com>2015-02-26 11:02:59 +0000
commitb7d4e4ffebf91ff539e705abef9941073667f373 (patch)
treef8882212752ebdb7794bfb0aa1612505a0425b99 /src/gui/math3d/qmatrix4x4.cpp
parente628c80dc38f00efd5a7821a8be61eadcf838b62 (diff)
Optimize quaternion to rotation matrix convertion
Rearrange operands to get rid of 50% of multiplications (i.e. `2 * (x * x + z * z)` -> `(x + x) * x + (z + z) * z`). Change-Id: Ib5279425ead999fc571b4964ac1681b6e22f9a7e Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/gui/math3d/qmatrix4x4.cpp')
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp44
1 files changed, 25 insertions, 19 deletions
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index c196f7cff8..a54ca451d4 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -1322,27 +1322,33 @@ void QMatrix4x4::rotate(const QQuaternion& quaternion)
{
// Algorithm from:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54
- QMatrix4x4 m(1);
- float xx = quaternion.x() * quaternion.x();
- float xy = quaternion.x() * quaternion.y();
- float xz = quaternion.x() * quaternion.z();
- float xw = quaternion.x() * quaternion.scalar();
- float yy = quaternion.y() * quaternion.y();
- float yz = quaternion.y() * quaternion.z();
- float yw = quaternion.y() * quaternion.scalar();
- float zz = quaternion.z() * quaternion.z();
- float zw = quaternion.z() * quaternion.scalar();
- m.m[0][0] = 1.0f - 2 * (yy + zz);
- m.m[1][0] = 2 * (xy - zw);
- m.m[2][0] = 2 * (xz + yw);
+
+ QMatrix4x4 m(Qt::Uninitialized);
+
+ const float f2x = quaternion.x() + quaternion.x();
+ const float f2y = quaternion.y() + quaternion.y();
+ const float f2z = quaternion.z() + quaternion.z();
+ const float f2xw = f2x * quaternion.scalar();
+ const float f2yw = f2y * quaternion.scalar();
+ const float f2zw = f2z * quaternion.scalar();
+ const float f2xx = f2x * quaternion.x();
+ const float f2xy = f2x * quaternion.y();
+ const float f2xz = f2x * quaternion.z();
+ const float f2yy = f2y * quaternion.y();
+ const float f2yz = f2y * quaternion.z();
+ const float f2zz = f2z * quaternion.z();
+
+ m.m[0][0] = 1.0f - (f2yy + f2zz);
+ m.m[1][0] = f2xy - f2zw;
+ m.m[2][0] = f2xz + f2yw;
m.m[3][0] = 0.0f;
- m.m[0][1] = 2 * (xy + zw);
- m.m[1][1] = 1.0f - 2 * (xx + zz);
- m.m[2][1] = 2 * (yz - xw);
+ m.m[0][1] = f2xy + f2zw;
+ m.m[1][1] = 1.0f - (f2xx + f2zz);
+ m.m[2][1] = f2yz - f2xw;
m.m[3][1] = 0.0f;
- m.m[0][2] = 2 * (xz - yw);
- m.m[1][2] = 2 * (yz + xw);
- m.m[2][2] = 1.0f - 2 * (xx + yy);
+ m.m[0][2] = f2xz - f2yw;
+ m.m[1][2] = f2yz + f2xw;
+ m.m[2][2] = 1.0f - (f2xx + f2yy);
m.m[3][2] = 0.0f;
m.m[0][3] = 0.0f;
m.m[1][3] = 0.0f;