summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAriya Hidayat <ariya.hidayat@nokia.com>2009-06-30 09:18:03 (GMT)
committerAriya Hidayat <ariya.hidayat@nokia.com>2009-08-06 10:55:01 (GMT)
commitcbc229081a9df67a577b4bea61ad6aac52d470cb (patch)
tree36e40064b36ee8611859afd661bc5d8f80a3b205 /src
parente3f3ced70f80369439200b7d7bc3e4e11222c81f (diff)
downloadQt-cbc229081a9df67a577b4bea61ad6aac52d470cb.zip
Qt-cbc229081a9df67a577b4bea61ad6aac52d470cb.tar.gz
Qt-cbc229081a9df67a577b4bea61ad6aac52d470cb.tar.bz2
Faster quaternion multiplications.
Use the known factorization trick to speed-up quaternion multiplication. Now we need only 9 floating-point multiplications, instead of 16 (but at the cost of extra additions and subtractions). Callgrind shows that the function now takes 299 instructions instead of 318 instructions, which is not a big win. However I assume the speed-up has a better effect for mobile CPU, where multiplications are more expensive. Reviewed-by: Rhys Weatherley
Diffstat (limited to 'src')
-rw-r--r--src/gui/math3d/qquaternion.h29
1 files changed, 11 insertions, 18 deletions
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index 55c871d..9a1b590 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -198,24 +198,17 @@ inline QQuaternion &QQuaternion::operator*=(qreal factor)
inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2)
{
- // Algorithm from:
- // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q53
- float x = q1.wp * q2.xp +
- q1.xp * q2.wp +
- q1.yp * q2.zp -
- q1.zp * q2.yp;
- float y = q1.wp * q2.yp +
- q1.yp * q2.wp +
- q1.zp * q2.xp -
- q1.xp * q2.zp;
- float z = q1.wp * q2.zp +
- q1.zp * q2.wp +
- q1.xp * q2.yp -
- q1.yp * q2.xp;
- float w = q1.wp * q2.wp -
- q1.xp * q2.xp -
- q1.yp * q2.yp -
- q1.zp * q2.zp;
+ float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp);
+ float yy = (q1.wp - q1.yp) * (q2.wp + q2.zp);
+ float zz = (q1.wp + q1.yp) * (q2.wp - q2.zp);
+ float xx = ww + yy + zz;
+ float qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp));
+
+ float w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp);
+ float x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp);
+ float y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp);
+ float z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp);
+
return QQuaternion(w, x, y, z, 1);
}