diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-01-19 12:50:05 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2015-01-22 12:39:20 +0100 |
commit | 595ed595eabe01a1cf11c8b846fd777de8233721 (patch) | |
tree | c23d42c57c16fe0df5ec5450f237512d8202e85a /src | |
parent | fdbf3bec3009343362448141faa42734ec31b1c3 (diff) |
Add project/unproject methods in QVector3D
Equivalent of gluProject and gluUnproject.
[ChangeLog][QtCore][QVector3D] add convenience project and unproject methods
to use like gluProject and gluUnproject
Change-Id: I6e4e3e79ea6e34d1fb0c375e15185c950b699ef0
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/math3d/qvector3d.cpp | 65 | ||||
-rw-r--r-- | src/gui/math3d/qvector3d.h | 4 |
2 files changed, 69 insertions, 0 deletions
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 75d61e5f85..014987b90d 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -34,10 +34,12 @@ #include "qvector3d.h" #include "qvector2d.h" #include "qvector4d.h" +#include "qmatrix4x4.h" #include <QtCore/qdatastream.h> #include <QtCore/qmath.h> #include <QtCore/qvariant.h> #include <QtCore/qdebug.h> +#include <QtCore/qrect.h> QT_BEGIN_NAMESPACE @@ -359,6 +361,69 @@ QVector3D QVector3D::normal } /*! + \since 5.5 + + Returns the window coordinates of this vector initially in object/model + coordinates using the model view matrix \a modelView, the projection matrix + \a projection and the viewport dimensions \a viewport. + + When transforming from clip to normalized space, a division by the w + component on the vector components takes place. To prevent dividing by 0 if + w equals to 0, it is set to 1. + + \note the returned y coordinates are in OpenGL orientation. OpenGL expects + the bottom to be 0 whereas for Qt top is 0. + + \sa unproject() + */ +QVector3D QVector3D::project(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const +{ + QVector4D tmp(*this, 1.0f); + tmp = projection * modelView * tmp; + if (qFuzzyIsNull(tmp.w())) + tmp.setW(1.0f); + tmp /= tmp.w(); + + tmp = tmp * 0.5f + QVector4D(0.5f, 0.5f, 0.5f, 0.5f); + tmp.setX(tmp.x() * viewport.width() + viewport.x()); + tmp.setY(tmp.y() * viewport.height() + viewport.y()); + + return tmp.toVector3D(); +} + +/*! + \since 5.5 + + Returns the object/model coordinates of this vector initially in window + coordinates using the model view matrix \a modelView, the projection matrix + \a projection and the viewport dimensions \a viewport. + + When transforming from clip to normalized space, a division by the w + component of the vector components takes place. To prevent dividing by 0 if + w equals to 0, it is set to 1. + + \note y coordinates in \a point should use OpenGL orientation. OpenGL + expects the bottom to be 0 whereas for Qt top is 0. + + \sa project() + */ +QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const +{ + QMatrix4x4 inverse = QMatrix4x4( projection * modelView ).inverted(); + + QVector4D tmp(*this, 1.0f); + tmp.setX((tmp.x() - float(viewport.x())) / float(viewport.width())); + tmp.setY((tmp.y() - float(viewport.y())) / float(viewport.height())); + tmp = tmp * 2.0f - QVector4D(1.0f, 1.0f, 1.0f, 1.0f); + + QVector4D obj = inverse * tmp; + if (qFuzzyIsNull(obj.w())) + obj.setW(1.0f); + obj /= obj.w(); + return obj.toVector3D(); +} + +/*! \since 5.1 Returns the distance from this vertex to a point defined by diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h index 40e9035621..4c25451bab 100644 --- a/src/gui/math3d/qvector3d.h +++ b/src/gui/math3d/qvector3d.h @@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE class QMatrix4x4; class QVector2D; class QVector4D; +class QRect; #ifndef QT_NO_VECTOR3D @@ -94,6 +95,9 @@ public: static QVector3D normal (const QVector3D& v1, const QVector3D& v2, const QVector3D& v3); + QVector3D project(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const; + QVector3D unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const; + float distanceToPoint(const QVector3D& point) const; float distanceToPlane(const QVector3D& plane, const QVector3D& normal) const; float distanceToPlane(const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const; |