Commit cbc229081a9df67a577b4bea61ad6aac52d470cb

  • avatar
  • Ariya Hidayat <ariya.hidayat @no…a.com>
  • Thu Aug 06 12:55:01 CEST 2009
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
  
198198
199199inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2)
200200{
201 // Algorithm from:
202 // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q53
203 float x = q1.wp * q2.xp +
204 q1.xp * q2.wp +
205 q1.yp * q2.zp -
206 q1.zp * q2.yp;
207 float y = q1.wp * q2.yp +
208 q1.yp * q2.wp +
209 q1.zp * q2.xp -
210 q1.xp * q2.zp;
211 float z = q1.wp * q2.zp +
212 q1.zp * q2.wp +
213 q1.xp * q2.yp -
214 q1.yp * q2.xp;
215 float w = q1.wp * q2.wp -
216 q1.xp * q2.xp -
217 q1.yp * q2.yp -
218 q1.zp * q2.zp;
201 float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp);
202 float yy = (q1.wp - q1.yp) * (q2.wp + q2.zp);
203 float zz = (q1.wp + q1.yp) * (q2.wp - q2.zp);
204 float xx = ww + yy + zz;
205 float qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp));
206
207 float w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp);
208 float x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp);
209 float y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp);
210 float z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp);
211
219212 return QQuaternion(w, x, y, z, 1);
220213}
221214