diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-08-19 23:05:43 (GMT) |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-08-19 23:05:43 (GMT) |
commit | feabd6584880c775a516d157c9cd24f0e707060d (patch) | |
tree | 2534b40681c8957c72f713c4fdfb53b876ec10df /src/gui/math3d | |
parent | 865a649b68f2b09c887527d42f1216a841c62474 (diff) | |
download | Qt-feabd6584880c775a516d157c9cd24f0e707060d.zip Qt-feabd6584880c775a516d157c9cd24f0e707060d.tar.gz Qt-feabd6584880c775a516d157c9cd24f0e707060d.tar.bz2 |
Add projection support to QMatrix4x4::toTransform()
When converting from 3D back to 2D, it is necessary to project
the z component unless an orthographic projection is desired.
This change adds a distanceToPlane argument that specifies the
perspective projection factor to apply during the conversion.
The default value of 1024 corresponds to the projection performed
by QTransform::rotate(), for consistency with existing classes.
Reviewed-by: trustme
Diffstat (limited to 'src/gui/math3d')
-rw-r--r-- | src/gui/math3d/qmatrix4x4.cpp | 53 | ||||
-rw-r--r-- | src/gui/math3d/qmatrix4x4.h | 2 |
2 files changed, 48 insertions, 7 deletions
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 8fc439b..ed0802b 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1438,18 +1438,59 @@ QMatrix QMatrix4x4::toAffine() const qreal(m[3][0]), qreal(m[3][1])); } +static const qreal inv_dist_to_plane = 1. / 1024.; + /*! Returns the conventional Qt 2D transformation matrix that - corresponds to this matrix. It is assumed that this matrix - only contains 2D transformation elements. + corresponds to this matrix. + + If \a distanceToPlane is non-zero, it indicates a projection + factor to use to adjust for the z co-ordinate. The default + value of 1024 corresponds to the projection factor used + by QTransform::rotate() for the x and y axes. + + If \a distToPlane is zero, then the returned QTransform + is formed by simply dropping the third row and third column + of the QMatrix4x4. This is suitable for implementing + orthographic projections where the z co-ordinate should + be dropped rather than projected. \sa toAffine() */ -QTransform QMatrix4x4::toTransform() const +QTransform QMatrix4x4::toTransform(qreal distanceToPlane) const { - return QTransform(qreal(m[0][0]), qreal(m[0][1]), qreal(m[0][3]), - qreal(m[1][0]), qreal(m[1][1]), qreal(m[1][3]), - qreal(m[3][0]), qreal(m[3][1]), qreal(m[3][3])); + if (distanceToPlane == 1024.0f) { + // Optimize the common case with constants. + return QTransform(qreal(m[0][0]), qreal(m[0][1]), + qreal(m[0][3]) - qreal(m[0][2]) * + inv_dist_to_plane, + qreal(m[1][0]), qreal(m[1][1]), + qreal(m[1][3]) - qreal(m[1][2]) * + inv_dist_to_plane, + qreal(m[3][0]), qreal(m[3][1]), + qreal(m[3][3]) - qreal(m[3][2]) * + inv_dist_to_plane); + } else if (distanceToPlane != 0.0f) { + // The following projection matrix is pre-multiplied with "matrix": + // | 1 0 0 0 | + // | 0 1 0 0 | + // | 0 0 1 0 | + // | 0 0 d 1 | + // where d = -1 / distanceToPlane. After projection, row 3 and + // column 3 are dropped to form the final QTransform. + qreal d = 1.0f / distanceToPlane; + return QTransform(qreal(m[0][0]), qreal(m[0][1]), + qreal(m[0][3]) - qreal(m[0][2]) * d, + qreal(m[1][0]), qreal(m[1][1]), + qreal(m[1][3]) - qreal(m[1][2]) * d, + qreal(m[3][0]), qreal(m[3][1]), + qreal(m[3][3]) - qreal(m[3][2]) * d); + } else { + // Orthographic projection: drop row 3 and column 3. + return QTransform(qreal(m[0][0]), qreal(m[0][1]), qreal(m[0][3]), + qreal(m[1][0]), qreal(m[1][1]), qreal(m[1][3]), + qreal(m[3][0]), qreal(m[3][1]), qreal(m[3][3])); + } } /*! diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index b02608d..04a4216 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -158,7 +158,7 @@ public: void toValueArray(qreal *values) const; QMatrix toAffine() const; - QTransform toTransform() const; + QTransform toTransform(qreal distanceToPlane = 1024.0f) const; QPoint map(const QPoint& point) const; QPointF map(const QPointF& point) const; |