summaryrefslogtreecommitdiffstats
path: root/src/gui/math3d
diff options
context:
space:
mode:
authorRhys Weatherley <rhys.weatherley@nokia.com>2009-08-19 23:05:43 (GMT)
committerRhys Weatherley <rhys.weatherley@nokia.com>2009-08-19 23:05:43 (GMT)
commitfeabd6584880c775a516d157c9cd24f0e707060d (patch)
tree2534b40681c8957c72f713c4fdfb53b876ec10df /src/gui/math3d
parent865a649b68f2b09c887527d42f1216a841c62474 (diff)
downloadQt-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.cpp53
-rw-r--r--src/gui/math3d/qmatrix4x4.h2
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;