diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2015-02-26 18:04:43 +0400 |
---|---|---|
committer | Konstantin Ritt <ritt.ks@gmail.com> | 2015-04-07 13:07:48 +0000 |
commit | 95d034a14f78aaefd6990de180f715c8b4d510b1 (patch) | |
tree | f1f2879ffd11dd697ee268a335e92aacfb07a5f9 /src/gui/math3d | |
parent | 3fb6014ce71febe1cb18ceaff16840bb4aea7deb (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.cpp | 30 | ||||
-rw-r--r-- | src/gui/math3d/qquaternion.h | 2 |
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 |