summaryrefslogtreecommitdiffstats
path: root/src/gui/math3d
diff options
context:
space:
mode:
authorRhys Weatherley <rhys.weatherley@nokia.com>2009-04-16 08:33:32 +1000
committerRhys Weatherley <rhys.weatherley@nokia.com>2009-04-16 08:33:32 +1000
commit1cb11b428ef1bee070af72676b7eb1fa325bb980 (patch)
treef098bff499691223ba9255a8e0500314cae20e6e /src/gui/math3d
parent10688c0168fc010671abc59f367c19357bb6776c (diff)
Add the QQuaternion::nlerp() function as a counterpart to slerp()
nlerp() implements "normalized linear interpolation", which is faster than slerp() and gives approximate results that are good enough for some applications. Reviewed-by: trustme
Diffstat (limited to 'src/gui/math3d')
-rw-r--r--src/gui/math3d/qquaternion.cpp39
-rw-r--r--src/gui/math3d/qquaternion.h2
2 files changed, 41 insertions, 0 deletions
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index 1348fed322..a91b0b9d4f 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -484,6 +484,8 @@ QQuaternion QQuaternion::fromAxisAndAngle
If \a t is less than or equal to 0, then \a q1 will be returned.
If \a t is greater than or equal to 1, then \a q2 will be returned.
+
+ \sa nlerp()
*/
QQuaternion QQuaternion::slerp
(const QQuaternion& q1, const QQuaternion& q2, qreal t)
@@ -522,6 +524,43 @@ QQuaternion QQuaternion::slerp
return q1 * factor1 + q2b * factor2;
}
+/*!
+ Interpolates along the shortest linear path between the rotational
+ positions \a q1 and \a q2. The value \a t should be between 0 and 1,
+ indicating the distance to travel between \a q1 and \a q2.
+ The result will be normalized().
+
+ If \a t is less than or equal to 0, then \a q1 will be returned.
+ If \a t is greater than or equal to 1, then \a q2 will be returned.
+
+ The nlerp() function is typically faster than slerp() and will
+ give approximate results to spherical interpolation that are
+ good enough for some applications.
+
+ \sa slerp()
+*/
+QQuaternion QQuaternion::nlerp
+ (const QQuaternion& q1, const QQuaternion& q2, qreal t)
+{
+ // Handle the easy cases first.
+ if (t <= 0.0f)
+ return q1;
+ else if (t >= 1.0f)
+ return q2;
+
+ // Determine the angle between the two quaternions.
+ QQuaternion q2b;
+ qreal dot;
+ dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp;
+ if (dot >= 0.0f)
+ q2b = q2;
+ else
+ q2b = -q2;
+
+ // Perform the linear interpolation.
+ return (q1 * (1.0f - t) + q2b * t).normalized();
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QQuaternion &q)
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index ad6fddfb73..c05c6413b9 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -126,6 +126,8 @@ public:
static QQuaternion slerp
(const QQuaternion& q1, const QQuaternion& q2, qreal t);
+ static QQuaternion nlerp
+ (const QQuaternion& q1, const QQuaternion& q2, qreal t);
private:
float wp, xp, yp, zp;