summaryrefslogtreecommitdiffstats
path: root/src/gui/math3d
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2015-02-26 18:04:43 +0400
committerKonstantin Ritt <ritt.ks@gmail.com>2015-04-07 13:07:48 +0000
commit95d034a14f78aaefd6990de180f715c8b4d510b1 (patch)
treef1f2879ffd11dd697ee268a335e92aacfb07a5f9 /src/gui/math3d
parent3fb6014ce71febe1cb18ceaff16840bb4aea7deb (diff)
Introduce QQuaternion::fromDirection()
...which constructs a quaternion using specified forward and upward directions, so that the resulting Z axis "faces" a given forward direction. Change-Id: Ib77b8ab5c359a4880b0d946face87026acdc6f0b Reviewed-by: Paul Lemire <paul.lemire@kdab.com> Reviewed-by: Michael Krasnyk <michael.krasnyk@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/gui/math3d')
-rw-r--r--src/gui/math3d/qquaternion.cpp30
-rw-r--r--src/gui/math3d/qquaternion.h2
2 files changed, 32 insertions, 0 deletions
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index 6914a0b45e..4b35ee4e79 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -720,8 +720,38 @@ QQuaternion QQuaternion::fromAxes(const QVector3D &xAxis, const QVector3D &yAxis
/*!
\since 5.5
+ Constructs the quaternion using specified forward direction \a direction
+ and upward direction \a up.
+ If the upward direction was not specified or the forward and upward
+ vectors are collinear, a new orthonormal upward direction will be generated.
+
+ \sa fromAxes(), rotationTo()
+*/
+QQuaternion QQuaternion::fromDirection(const QVector3D &direction, const QVector3D &up)
+{
+ if (qFuzzyIsNull(direction.x()) && qFuzzyIsNull(direction.y()) && qFuzzyIsNull(direction.z()))
+ return QQuaternion();
+
+ const QVector3D zAxis(direction.normalized());
+ QVector3D xAxis(QVector3D::crossProduct(up, zAxis));
+ if (qFuzzyIsNull(xAxis.lengthSquared())) {
+ // collinear or invalid up vector; derive shortest arc to new direction
+ return QQuaternion::rotationTo(QVector3D(0.0f, 0.0f, 1.0f), zAxis);
+ }
+
+ xAxis.normalize();
+ const QVector3D yAxis(QVector3D::crossProduct(zAxis, xAxis));
+
+ return QQuaternion::fromAxes(xAxis, yAxis, zAxis);
+}
+
+/*!
+ \since 5.5
+
Returns the shortest arc quaternion to rotate from the direction described by the vector \a from
to the direction described by the vector \a to.
+
+ \sa fromDirection()
*/
QQuaternion QQuaternion::rotationTo(const QVector3D &from, const QVector3D &to)
{
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index c3918645d4..240e31a5c2 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -138,6 +138,8 @@ public:
void getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const;
static QQuaternion fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis);
+ static QQuaternion fromDirection(const QVector3D &direction, const QVector3D &up);
+
static QQuaternion rotationTo(const QVector3D &from, const QVector3D &to);
#endif