summaryrefslogtreecommitdiffstats
path: root/src/gui/math3d/qmatrix4x4.cpp
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2012-08-20 20:55:40 +0100
committerQt by Nokia <qt-info@nokia.com>2012-09-07 13:27:38 +0200
commit51d40d7e9bdfc63c5109aef5b732aa2ba10f985a (patch)
treeffa750956ab2e96e0cd8f02bafa820042aa9f78a /src/gui/math3d/qmatrix4x4.cpp
parent56414e2498ae19d305b391678afe3a67a9069832 (diff)
Make gui/math3d classes use float rather than qreal
This corrects the mismatch between using floats for internal storage and qreal in the API of QVector*D which leads to lots of implicit casts between double and float. This change also stops users from being surprised by the loss of precision when using these classes on desktop platforms and removes the need for the private constructors taking a dummy int as the final argument. The QMatrix4x4 and QQuaternion classes have been changed to use float for their internal storage since these are meant to be used in conjunction with the QVector*D classes. This is to prevent unexpected loss of precision and to improve performance. The on-disk format has also been changed from double to float thereby reducing the storage required when streaming vectors and matrices. This is potentially a large saving when working with complex 3D meshes etc. This also has a significant performance improvement when passing matrices to QOpenGLShaderProgram (and QGLShaderProgram) as we no longer have to iterate and convert the data to floats. This is an operation that could easily be needed many times per frame. This change also opens the door for further optimisations of these classes to be implemented by using SIMD intrinsics. This needs to be applied in conjunction with https://codereview.qt-project.org/#change,33548 Task-number: QTBUG-21035 Task-number: QTBUG-20661 Change-Id: I9321b06040ffb93ae1cbd72fd2013267ac901b2e Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/gui/math3d/qmatrix4x4.cpp')
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp357
1 files changed, 196 insertions, 161 deletions
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index 76135f0eff..899939c2c3 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
\sa QVector3D, QGenericMatrix
*/
-static const qreal inv_dist_to_plane = 1. / 1024.;
+static const float inv_dist_to_plane = 1.0f / 1024.0f;
/*!
\fn QMatrix4x4::QMatrix4x4()
@@ -93,7 +93,7 @@ static const qreal inv_dist_to_plane = 1. / 1024.;
\sa copyDataTo(), optimize()
*/
-QMatrix4x4::QMatrix4x4(const qreal *values)
+QMatrix4x4::QMatrix4x4(const float *values)
{
for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col)
@@ -101,8 +101,17 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
flagBits = General;
}
+// ###TODO This is temporary to get through the CI's revdep qtdeclarative tests. Remove it!
+QMatrix4x4::QMatrix4x4(const double *values)
+{
+ for (int row = 0; row < 4; ++row)
+ for (int col = 0; col < 4; ++col)
+ m[col][row] = float(values[row * 4 + col]);
+ flagBits = General;
+}
+
/*!
- \fn QMatrix4x4::QMatrix4x4(qreal m11, qreal m12, qreal m13, qreal m14, qreal m21, qreal m22, qreal m23, qreal m24, qreal m31, qreal m32, qreal m33, qreal m34, qreal m41, qreal m42, qreal m43, qreal m44)
+ \fn QMatrix4x4::QMatrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
Constructs a matrix from the 16 elements \a m11, \a m12, \a m13, \a m14,
\a m21, \a m22, \a m23, \a m24, \a m31, \a m32, \a m33, \a m34,
@@ -118,7 +127,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
*/
/*!
- \fn QMatrix4x4::QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix)
+ \fn QMatrix4x4::QMatrix4x4(const QGenericMatrix<N, M, float>& matrix)
Constructs a 4x4 matrix from the left-most 4 columns and top-most
4 rows of \a matrix. If \a matrix has less than 4 columns or rows,
@@ -129,7 +138,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
*/
/*!
- \fn QGenericMatrix<N, M, qreal> QMatrix4x4::toGenericMatrix() const
+ \fn QGenericMatrix<N, M, float> QMatrix4x4::toGenericMatrix() const
Constructs a NxM generic matrix from the left-most N columns and
top-most M rows of this 4x4 matrix. If N or M is greater than 4,
@@ -138,7 +147,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
*/
/*!
- \fn QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix)
+ \fn QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, float>& matrix)
\relates QMatrix4x4
\obsolete
@@ -151,7 +160,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
*/
/*!
- \fn QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)
+ \fn QGenericMatrix<N, M, float> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)
\relates QMatrix4x4
\obsolete
@@ -166,7 +175,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
/*!
\internal
*/
-QMatrix4x4::QMatrix4x4(const qreal *values, int cols, int rows)
+QMatrix4x4::QMatrix4x4(const float *values, int cols, int rows)
{
for (int col = 0; col < 4; ++col) {
for (int row = 0; row < 4; ++row) {
@@ -246,7 +255,7 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform)
}
/*!
- \fn const qreal& QMatrix4x4::operator()(int row, int column) const
+ \fn const float& QMatrix4x4::operator()(int row, int column) const
Returns a constant reference to the element at position
(\a row, \a column) in this matrix.
@@ -255,7 +264,7 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform)
*/
/*!
- \fn qreal& QMatrix4x4::operator()(int row, int column)
+ \fn float& QMatrix4x4::operator()(int row, int column)
Returns a reference to the element at position (\a row, \a column)
in this matrix so that the element can be assigned to.
@@ -312,12 +321,12 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform)
*/
/*!
- \fn void QMatrix4x4::fill(qreal value)
+ \fn void QMatrix4x4::fill(float value)
Fills all elements of this matrx with \a value.
*/
-static inline qreal matrixDet2(const qreal m[4][4], int col0, int col1, int row0, int row1)
+static inline double matrixDet2(const double m[4][4], int col0, int col1, int row0, int row1)
{
return m[col0][row0] * m[col1][row1] - m[col0][row1] * m[col1][row0];
}
@@ -332,8 +341,8 @@ static inline qreal matrixDet2(const qreal m[4][4], int col0, int col1, int row0
// | A B C |
// M = | D E F | det(M) = A * (EI - HF) - B * (DI - GF) + C * (DH - GE)
// | G H I |
-static inline qreal matrixDet3
- (const qreal m[4][4], int col0, int col1, int col2,
+static inline double matrixDet3
+ (const double m[4][4], int col0, int col1, int col2,
int row0, int row1, int row2)
{
return m[col0][row0] * matrixDet2(m, col1, col2, row1, row2)
@@ -342,9 +351,9 @@ static inline qreal matrixDet3
}
// Calculate the determinant of a 4x4 matrix.
-static inline qreal matrixDet4(const qreal m[4][4])
+static inline double matrixDet4(const double m[4][4])
{
- qreal det;
+ double det;
det = m[0][0] * matrixDet3(m, 1, 2, 3, 1, 2, 3);
det -= m[1][0] * matrixDet3(m, 0, 2, 3, 1, 2, 3);
det += m[2][0] * matrixDet3(m, 0, 1, 3, 1, 2, 3);
@@ -352,18 +361,28 @@ static inline qreal matrixDet4(const qreal m[4][4])
return det;
}
+static inline void copyToDoubles(const float m[4][4], double mm[4][4])
+{
+ for (int i = 0; i < 4; ++i)
+ for (int j = 0; j < 4; ++j)
+ mm[i][j] = double(m[i][j]);
+}
+
/*!
Returns the determinant of this matrix.
*/
-qreal QMatrix4x4::determinant() const
+double QMatrix4x4::determinant() const
{
if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity)
- return 1;
+ return 1.0;
+
+ double mm[4][4];
+ copyToDoubles(m, mm);
if (flagBits < Rotation2D)
- return m[0][0] * m[1][1] * m[2][2]; // Translation | Scale
+ return mm[0][0] * mm[1][1] * mm[2][2]; // Translation | Scale
if (flagBits < Perspective)
- return matrixDet3(m, 0, 1, 2, 0, 1, 2);
- return matrixDet4(m);
+ return matrixDet3(mm, 0, 1, 2, 0, 1, 2);
+ return matrixDet4(mm);
}
/*!
@@ -420,7 +439,10 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
} else if (flagBits < Perspective) {
QMatrix4x4 inv(1); // The "1" says to not load the identity.
- qreal det = matrixDet3(m, 0, 1, 2, 0, 1, 2);
+ double mm[4][4];
+ copyToDoubles(m, mm);
+
+ double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);
if (det == 0.0f) {
if (invertible)
*invertible = false;
@@ -428,17 +450,17 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
}
det = 1.0f / det;
- inv.m[0][0] = matrixDet2(m, 1, 2, 1, 2) * det;
- inv.m[0][1] = -matrixDet2(m, 0, 2, 1, 2) * det;
- inv.m[0][2] = matrixDet2(m, 0, 1, 1, 2) * det;
+ inv.m[0][0] = matrixDet2(mm, 1, 2, 1, 2) * det;
+ inv.m[0][1] = -matrixDet2(mm, 0, 2, 1, 2) * det;
+ inv.m[0][2] = matrixDet2(mm, 0, 1, 1, 2) * det;
inv.m[0][3] = 0;
- inv.m[1][0] = -matrixDet2(m, 1, 2, 0, 2) * det;
- inv.m[1][1] = matrixDet2(m, 0, 2, 0, 2) * det;
- inv.m[1][2] = -matrixDet2(m, 0, 1, 0, 2) * det;
+ inv.m[1][0] = -matrixDet2(mm, 1, 2, 0, 2) * det;
+ inv.m[1][1] = matrixDet2(mm, 0, 2, 0, 2) * det;
+ inv.m[1][2] = -matrixDet2(mm, 0, 1, 0, 2) * det;
inv.m[1][3] = 0;
- inv.m[2][0] = matrixDet2(m, 1, 2, 0, 1) * det;
- inv.m[2][1] = -matrixDet2(m, 0, 2, 0, 1) * det;
- inv.m[2][2] = matrixDet2(m, 0, 1, 0, 1) * det;
+ inv.m[2][0] = matrixDet2(mm, 1, 2, 0, 1) * det;
+ inv.m[2][1] = -matrixDet2(mm, 0, 2, 0, 1) * det;
+ inv.m[2][2] = matrixDet2(mm, 0, 1, 0, 1) * det;
inv.m[2][3] = 0;
inv.m[3][0] = -inv.m[0][0] * m[3][0] - inv.m[1][0] * m[3][1] - inv.m[2][0] * m[3][2];
inv.m[3][1] = -inv.m[0][1] * m[3][0] - inv.m[1][1] * m[3][1] - inv.m[2][1] * m[3][2];
@@ -453,7 +475,10 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
QMatrix4x4 inv(1); // The "1" says to not load the identity.
- qreal det = matrixDet4(m);
+ double mm[4][4];
+ copyToDoubles(m, mm);
+
+ double det = matrixDet4(mm);
if (det == 0.0f) {
if (invertible)
*invertible = false;
@@ -461,22 +486,22 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
}
det = 1.0f / det;
- inv.m[0][0] = matrixDet3(m, 1, 2, 3, 1, 2, 3) * det;
- inv.m[0][1] = -matrixDet3(m, 0, 2, 3, 1, 2, 3) * det;
- inv.m[0][2] = matrixDet3(m, 0, 1, 3, 1, 2, 3) * det;
- inv.m[0][3] = -matrixDet3(m, 0, 1, 2, 1, 2, 3) * det;
- inv.m[1][0] = -matrixDet3(m, 1, 2, 3, 0, 2, 3) * det;
- inv.m[1][1] = matrixDet3(m, 0, 2, 3, 0, 2, 3) * det;
- inv.m[1][2] = -matrixDet3(m, 0, 1, 3, 0, 2, 3) * det;
- inv.m[1][3] = matrixDet3(m, 0, 1, 2, 0, 2, 3) * det;
- inv.m[2][0] = matrixDet3(m, 1, 2, 3, 0, 1, 3) * det;
- inv.m[2][1] = -matrixDet3(m, 0, 2, 3, 0, 1, 3) * det;
- inv.m[2][2] = matrixDet3(m, 0, 1, 3, 0, 1, 3) * det;
- inv.m[2][3] = -matrixDet3(m, 0, 1, 2, 0, 1, 3) * det;
- inv.m[3][0] = -matrixDet3(m, 1, 2, 3, 0, 1, 2) * det;
- inv.m[3][1] = matrixDet3(m, 0, 2, 3, 0, 1, 2) * det;
- inv.m[3][2] = -matrixDet3(m, 0, 1, 3, 0, 1, 2) * det;
- inv.m[3][3] = matrixDet3(m, 0, 1, 2, 0, 1, 2) * det;
+ inv.m[0][0] = matrixDet3(mm, 1, 2, 3, 1, 2, 3) * det;
+ inv.m[0][1] = -matrixDet3(mm, 0, 2, 3, 1, 2, 3) * det;
+ inv.m[0][2] = matrixDet3(mm, 0, 1, 3, 1, 2, 3) * det;
+ inv.m[0][3] = -matrixDet3(mm, 0, 1, 2, 1, 2, 3) * det;
+ inv.m[1][0] = -matrixDet3(mm, 1, 2, 3, 0, 2, 3) * det;
+ inv.m[1][1] = matrixDet3(mm, 0, 2, 3, 0, 2, 3) * det;
+ inv.m[1][2] = -matrixDet3(mm, 0, 1, 3, 0, 2, 3) * det;
+ inv.m[1][3] = matrixDet3(mm, 0, 1, 2, 0, 2, 3) * det;
+ inv.m[2][0] = matrixDet3(mm, 1, 2, 3, 0, 1, 3) * det;
+ inv.m[2][1] = -matrixDet3(mm, 0, 2, 3, 0, 1, 3) * det;
+ inv.m[2][2] = matrixDet3(mm, 0, 1, 3, 0, 1, 3) * det;
+ inv.m[2][3] = -matrixDet3(mm, 0, 1, 2, 0, 1, 3) * det;
+ inv.m[3][0] = -matrixDet3(mm, 1, 2, 3, 0, 1, 2) * det;
+ inv.m[3][1] = matrixDet3(mm, 0, 2, 3, 0, 1, 2) * det;
+ inv.m[3][2] = -matrixDet3(mm, 0, 1, 3, 0, 1, 2) * det;
+ inv.m[3][3] = matrixDet3(mm, 0, 1, 2, 0, 1, 2) * det;
inv.flagBits = flagBits;
if (invertible)
@@ -509,7 +534,7 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const
inv.data()[8] = 1.0f / m[2][2];
return inv;
} else if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) {
- qreal *invm = inv.data();
+ float *invm = inv.data();
invm[0 + 0 * 3] = m[0][0];
invm[1 + 0 * 3] = m[0][1];
invm[2 + 0 * 3] = m[0][2];
@@ -522,23 +547,25 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const
return inv;
}
- qreal det = matrixDet3(m, 0, 1, 2, 0, 1, 2);
+ double mm[4][4];
+ copyToDoubles(m, mm);
+ double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);
if (det == 0.0f)
return inv;
det = 1.0f / det;
- qreal *invm = inv.data();
+ float *invm = inv.data();
// Invert and transpose in a single step.
- invm[0 + 0 * 3] = (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * det;
- invm[1 + 0 * 3] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) * det;
- invm[2 + 0 * 3] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) * det;
- invm[0 + 1 * 3] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * det;
- invm[1 + 1 * 3] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) * det;
- invm[2 + 1 * 3] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) * det;
- invm[0 + 2 * 3] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) * det;
- invm[1 + 2 * 3] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) * det;
- invm[2 + 2 * 3] = (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * det;
+ invm[0 + 0 * 3] = (mm[1][1] * mm[2][2] - mm[2][1] * mm[1][2]) * det;
+ invm[1 + 0 * 3] = -(mm[1][0] * mm[2][2] - mm[1][2] * mm[2][0]) * det;
+ invm[2 + 0 * 3] = (mm[1][0] * mm[2][1] - mm[1][1] * mm[2][0]) * det;
+ invm[0 + 1 * 3] = -(mm[0][1] * mm[2][2] - mm[2][1] * mm[0][2]) * det;
+ invm[1 + 1 * 3] = (mm[0][0] * mm[2][2] - mm[0][2] * mm[2][0]) * det;
+ invm[2 + 1 * 3] = -(mm[0][0] * mm[2][1] - mm[0][1] * mm[2][0]) * det;
+ invm[0 + 2 * 3] = (mm[0][1] * mm[1][2] - mm[0][2] * mm[1][1]) * det;
+ invm[1 + 2 * 3] = -(mm[0][0] * mm[1][2] - mm[0][2] * mm[1][0]) * det;
+ invm[2 + 2 * 3] = (mm[0][0] * mm[1][1] - mm[1][0] * mm[0][1]) * det;
return inv;
}
@@ -578,7 +605,7 @@ QMatrix4x4 QMatrix4x4::transposed() const
*/
/*!
- \fn QMatrix4x4& QMatrix4x4::operator*=(qreal factor)
+ \fn QMatrix4x4& QMatrix4x4::operator*=(float factor)
\overload
Multiplies all elements of this matrix by \a factor.
@@ -589,7 +616,7 @@ QMatrix4x4 QMatrix4x4::transposed() const
Divides all elements of this matrix by \a divisor.
*/
-QMatrix4x4& QMatrix4x4::operator/=(qreal divisor)
+QMatrix4x4& QMatrix4x4::operator/=(float divisor)
{
m[0][0] /= divisor;
m[0][1] /= divisor;
@@ -727,14 +754,14 @@ QMatrix4x4& QMatrix4x4::operator/=(qreal divisor)
*/
/*!
- \fn QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix)
+ \fn QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix)
\relates QMatrix4x4
Returns the result of multiplying all elements of \a matrix by \a factor.
*/
/*!
- \fn QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor)
+ \fn QMatrix4x4 operator*(const QMatrix4x4& matrix, float factor)
\relates QMatrix4x4
Returns the result of multiplying all elements of \a matrix by \a factor.
@@ -745,7 +772,7 @@ QMatrix4x4& QMatrix4x4::operator/=(qreal divisor)
Returns the result of dividing all elements of \a matrix by \a divisor.
*/
-QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor)
+QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor)
{
QMatrix4x4 m(1); // The "1" says to not load the identity.
m.m[0][0] = matrix.m[0][0] / divisor;
@@ -786,9 +813,9 @@ QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor)
*/
void QMatrix4x4::scale(const QVector3D& vector)
{
- qreal vx = vector.x();
- qreal vy = vector.y();
- qreal vz = vector.z();
+ float vx = vector.x();
+ float vy = vector.y();
+ float vz = vector.z();
if (flagBits < Scale) {
m[0][0] = vx;
m[1][1] = vy;
@@ -830,7 +857,7 @@ void QMatrix4x4::scale(const QVector3D& vector)
\sa translate(), rotate()
*/
-void QMatrix4x4::scale(qreal x, qreal y)
+void QMatrix4x4::scale(float x, float y)
{
if (flagBits < Scale) {
m[0][0] = x;
@@ -864,7 +891,7 @@ void QMatrix4x4::scale(qreal x, qreal y)
\sa translate(), rotate()
*/
-void QMatrix4x4::scale(qreal x, qreal y, qreal z)
+void QMatrix4x4::scale(float x, float y, float z)
{
if (flagBits < Scale) {
m[0][0] = x;
@@ -905,7 +932,7 @@ void QMatrix4x4::scale(qreal x, qreal y, qreal z)
\sa translate(), rotate()
*/
-void QMatrix4x4::scale(qreal factor)
+void QMatrix4x4::scale(float factor)
{
if (flagBits < Scale) {
m[0][0] = factor;
@@ -948,9 +975,9 @@ void QMatrix4x4::scale(qreal factor)
void QMatrix4x4::translate(const QVector3D& vector)
{
- qreal vx = vector.x();
- qreal vy = vector.y();
- qreal vz = vector.z();
+ float vx = vector.x();
+ float vy = vector.y();
+ float vz = vector.z();
if (flagBits == Identity) {
m[3][0] = vx;
m[3][1] = vy;
@@ -989,7 +1016,7 @@ void QMatrix4x4::translate(const QVector3D& vector)
\sa scale(), rotate()
*/
-void QMatrix4x4::translate(qreal x, qreal y)
+void QMatrix4x4::translate(float x, float y)
{
if (flagBits == Identity) {
m[3][0] = x;
@@ -1023,7 +1050,7 @@ void QMatrix4x4::translate(qreal x, qreal y)
\sa scale(), rotate()
*/
-void QMatrix4x4::translate(qreal x, qreal y, qreal z)
+void QMatrix4x4::translate(float x, float y, float z)
{
if (flagBits == Identity) {
m[3][0] = x;
@@ -1062,7 +1089,7 @@ void QMatrix4x4::translate(qreal x, qreal y, qreal z)
\sa scale(), translate()
*/
-void QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
+void QMatrix4x4::rotate(float angle, const QVector3D& vector)
{
rotate(angle, vector.x(), vector.y(), vector.z());
}
@@ -1077,11 +1104,11 @@ void QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
\sa scale(), translate()
*/
-void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
+void QMatrix4x4::rotate(float angle, float x, float y, float z)
{
if (angle == 0.0f)
return;
- qreal c, s;
+ float c, s;
if (angle == 90.0f || angle == -270.0f) {
s = 1.0f;
c = 0.0f;
@@ -1092,9 +1119,9 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
s = 0.0f;
c = -1.0f;
} else {
- qreal a = angle * M_PI / 180.0f;
- c = qCos(a);
- s = qSin(a);
+ float a = angle * M_PI / 180.0f;
+ c = cosf(a);
+ s = sinf(a);
}
if (x == 0.0f) {
if (y == 0.0f) {
@@ -1102,7 +1129,7 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
// Rotate around the Z axis.
if (z < 0)
s = -s;
- qreal tmp;
+ float tmp;
m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s;
m[1][0] = m[1][0] * c - tmp * s;
m[0][1] = (tmp = m[0][1]) * c + m[1][1] * s;
@@ -1119,7 +1146,7 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
// Rotate around the Y axis.
if (y < 0)
s = -s;
- qreal tmp;
+ float tmp;
m[2][0] = (tmp = m[2][0]) * c + m[0][0] * s;
m[0][0] = m[0][0] * c - tmp * s;
m[2][1] = (tmp = m[2][1]) * c + m[0][1] * s;
@@ -1136,7 +1163,7 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
// Rotate around the X axis.
if (x < 0)
s = -s;
- qreal tmp;
+ float tmp;
m[1][0] = (tmp = m[1][0]) * c + m[2][0] * s;
m[2][0] = m[2][0] * c - tmp * s;
m[1][1] = (tmp = m[1][1]) * c + m[2][1] * s;
@@ -1150,14 +1177,16 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
return;
}
- qreal len = x * x + y * y + z * z;
- if (!qFuzzyCompare(len, qreal(1)) && !qFuzzyIsNull(len)) {
- len = qSqrt(len);
- x /= len;
- y /= len;
- z /= len;
+ double len = double(x) * double(x) +
+ double(y) * double(y) +
+ double(z) * double(z);
+ if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) {
+ len = sqrt(len);
+ x = float(double(x) / len);
+ y = float(double(y) / len);
+ z = float(double(z) / len);
}
- qreal ic = 1.0f - c;
+ float ic = 1.0f - c;
QMatrix4x4 rot(1); // The "1" says to not load the identity.
rot.m[0][0] = x * x * ic + c;
rot.m[1][0] = x * y * ic - z * s;
@@ -1182,13 +1211,13 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
/*!
\internal
*/
-void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
+void QMatrix4x4::projectedRotate(float angle, float x, float y, float z)
{
// Used by QGraphicsRotation::applyTo() to perform a rotation
// and projection back to 2D in a single step.
if (angle == 0.0f)
return;
- qreal c, s;
+ float c, s;
if (angle == 90.0f || angle == -270.0f) {
s = 1.0f;
c = 0.0f;
@@ -1199,9 +1228,9 @@ void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
s = 0.0f;
c = -1.0f;
} else {
- qreal a = angle * M_PI / 180.0f;
- c = qCos(a);
- s = qSin(a);
+ float a = angle * M_PI / 180.0f;
+ c = cosf(a);
+ s = sinf(a);
}
if (x == 0.0f) {
if (y == 0.0f) {
@@ -1209,7 +1238,7 @@ void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
// Rotate around the Z axis.
if (z < 0)
s = -s;
- qreal tmp;
+ float tmp;
m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s;
m[1][0] = m[1][0] * c - tmp * s;
m[0][1] = (tmp = m[0][1]) * c + m[1][1] * s;
@@ -1244,14 +1273,16 @@ void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
flagBits = General;
return;
}
- qreal len = x * x + y * y + z * z;
- if (!qFuzzyIsNull(len - 1.0f) && !qFuzzyIsNull(len)) {
- len = qSqrt(len);
- x /= len;
- y /= len;
- z /= len;
+ double len = double(x) * double(x) +
+ double(y) * double(y) +
+ double(z) * double(z);
+ if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) {
+ len = sqrt(len);
+ x = float(double(x) / len);
+ y = float(double(y) / len);
+ z = float(double(z) / len);
}
- qreal ic = 1.0f - c;
+ float ic = 1.0f - c;
QMatrix4x4 rot(1); // The "1" says to not load the identity.
rot.m[0][0] = x * x * ic + c;
rot.m[1][0] = x * y * ic - z * s;
@@ -1287,15 +1318,15 @@ void QMatrix4x4::rotate(const QQuaternion& quaternion)
// Algorithm from:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54
QMatrix4x4 m(1);
- qreal xx = quaternion.x() * quaternion.x();
- qreal xy = quaternion.x() * quaternion.y();
- qreal xz = quaternion.x() * quaternion.z();
- qreal xw = quaternion.x() * quaternion.scalar();
- qreal yy = quaternion.y() * quaternion.y();
- qreal yz = quaternion.y() * quaternion.z();
- qreal yw = quaternion.y() * quaternion.scalar();
- qreal zz = quaternion.z() * quaternion.z();
- qreal zw = quaternion.z() * quaternion.scalar();
+ float xx = quaternion.x() * quaternion.x();
+ float xy = quaternion.x() * quaternion.y();
+ float xz = quaternion.x() * quaternion.z();
+ float xw = quaternion.x() * quaternion.scalar();
+ float yy = quaternion.y() * quaternion.y();
+ float yz = quaternion.y() * quaternion.z();
+ float yw = quaternion.y() * quaternion.scalar();
+ float zz = quaternion.z() * quaternion.z();
+ float zw = quaternion.z() * quaternion.scalar();
m.m[0][0] = 1.0f - 2 * (yy + zz);
m.m[1][0] = 2 * (xy - zw);
m.m[2][0] = 2 * (xz + yw);
@@ -1358,16 +1389,16 @@ void QMatrix4x4::ortho(const QRectF& rect)
\sa frustum(), perspective()
*/
-void QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::ortho(float left, float right, float bottom, float top, float nearPlane, float farPlane)
{
// Bail out if the projection volume is zero-sized.
if (left == right || bottom == top || nearPlane == farPlane)
return;
// Construct the projection.
- qreal width = right - left;
- qreal invheight = top - bottom;
- qreal clip = farPlane - nearPlane;
+ float width = right - left;
+ float invheight = top - bottom;
+ float clip = farPlane - nearPlane;
QMatrix4x4 m(1);
m.m[0][0] = 2.0f / width;
m.m[1][0] = 0.0f;
@@ -1399,7 +1430,7 @@ void QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, qreal n
\sa ortho(), perspective()
*/
-void QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::frustum(float left, float right, float bottom, float top, float nearPlane, float farPlane)
{
// Bail out if the projection volume is zero-sized.
if (left == right || bottom == top || nearPlane == farPlane)
@@ -1407,9 +1438,9 @@ void QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top, qreal
// Construct the projection.
QMatrix4x4 m(1);
- qreal width = right - left;
- qreal invheight = top - bottom;
- qreal clip = farPlane - nearPlane;
+ float width = right - left;
+ float invheight = top - bottom;
+ float clip = farPlane - nearPlane;
m.m[0][0] = 2.0f * nearPlane / width;
m.m[1][0] = 0.0f;
m.m[2][0] = (left + right) / width;
@@ -1440,7 +1471,7 @@ void QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top, qreal
\sa ortho(), frustum()
*/
-void QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::perspective(float angle, float aspect, float nearPlane, float farPlane)
{
// Bail out if the projection volume is zero-sized.
if (nearPlane == farPlane || aspect == 0.0f)
@@ -1448,12 +1479,12 @@ void QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal f
// Construct the projection.
QMatrix4x4 m(1);
- qreal radians = (angle / 2.0f) * M_PI / 180.0f;
- qreal sine = qSin(radians);
+ float radians = (angle / 2.0f) * M_PI / 180.0f;
+ float sine = sinf(radians);
if (sine == 0.0f)
return;
- qreal cotan = qCos(radians) / sine;
- qreal clip = farPlane - nearPlane;
+ float cotan = cosf(radians) / sine;
+ float clip = farPlane - nearPlane;
m.m[0][0] = cotan / aspect;
m.m[1][0] = 0.0f;
m.m[2][0] = 0.0f;
@@ -1551,11 +1582,11 @@ void QMatrix4x4::flipCoordinates()
Retrieves the 16 items in this matrix and copies them to \a values
in row-major order.
*/
-void QMatrix4x4::copyDataTo(qreal *values) const
+void QMatrix4x4::copyDataTo(float *values) const
{
for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col)
- values[row * 4 + col] = qreal(m[col][row]);
+ values[row * 4 + col] = float(m[col][row]);
}
/*!
@@ -1607,7 +1638,7 @@ QTransform QMatrix4x4::toTransform() const
\sa toAffine()
*/
-QTransform QMatrix4x4::toTransform(qreal distanceToPlane) const
+QTransform QMatrix4x4::toTransform(float distanceToPlane) const
{
if (distanceToPlane == 1024.0f) {
// Optimize the common case with constants.
@@ -1622,7 +1653,7 @@ QTransform QMatrix4x4::toTransform(qreal distanceToPlane) const
// | 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;
+ float d = 1.0f / distanceToPlane;
return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * d,
m[1][0], m[1][1], m[1][3] - m[1][2] * d,
m[3][0], m[3][1], m[3][3] - m[3][2] * d);
@@ -1701,10 +1732,10 @@ QRect QMatrix4x4::mapRect(const QRect& rect) const
rect.width(), rect.height());
} else if (flagBits < Rotation2D) {
// Translation | Scale
- qreal x = rect.x() * m[0][0] + m[3][0];
- qreal y = rect.y() * m[1][1] + m[3][1];
- qreal w = rect.width() * m[0][0];
- qreal h = rect.height() * m[1][1];
+ float x = rect.x() * m[0][0] + m[3][0];
+ float y = rect.y() * m[1][1] + m[3][1];
+ float w = rect.width() * m[0][0];
+ float h = rect.height() * m[1][1];
if (w < 0) {
w = -w;
x -= w;
@@ -1745,10 +1776,10 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
return rect.translated(m[3][0], m[3][1]);
} else if (flagBits < Rotation2D) {
// Translation | Scale
- qreal x = rect.x() * m[0][0] + m[3][0];
- qreal y = rect.y() * m[1][1] + m[3][1];
- qreal w = rect.width() * m[0][0];
- qreal h = rect.height() * m[1][1];
+ float x = rect.x() * m[0][0] + m[3][0];
+ float y = rect.y() * m[1][1] + m[3][1];
+ float w = rect.width() * m[0][0];
+ float h = rect.height() * m[1][1];
if (w < 0) {
w = -w;
x -= w;
@@ -1763,16 +1794,16 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
QPointF tl = map(rect.topLeft()); QPointF tr = map(rect.topRight());
QPointF bl = map(rect.bottomLeft()); QPointF br = map(rect.bottomRight());
- qreal xmin = qMin(qMin(tl.x(), tr.x()), qMin(bl.x(), br.x()));
- qreal xmax = qMax(qMax(tl.x(), tr.x()), qMax(bl.x(), br.x()));
- qreal ymin = qMin(qMin(tl.y(), tr.y()), qMin(bl.y(), br.y()));
- qreal ymax = qMax(qMax(tl.y(), tr.y()), qMax(bl.y(), br.y()));
+ float xmin = qMin(qMin(tl.x(), tr.x()), qMin(bl.x(), br.x()));
+ float xmax = qMax(qMax(tl.x(), tr.x()), qMax(bl.x(), br.x()));
+ float ymin = qMin(qMin(tl.y(), tr.y()), qMin(bl.y(), br.y()));
+ float ymax = qMax(qMax(tl.y(), tr.y()), qMax(bl.y(), br.y()));
return QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax));
}
/*!
- \fn qreal *QMatrix4x4::data()
+ \fn float *QMatrix4x4::data()
Returns a pointer to the raw data of this matrix.
@@ -1780,7 +1811,7 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
*/
/*!
- \fn const qreal *QMatrix4x4::data() const
+ \fn const float *QMatrix4x4::data() const
Returns a constant pointer to the raw data of this matrix.
This raw data is stored in column-major format.
@@ -1789,7 +1820,7 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
*/
/*!
- \fn const qreal *QMatrix4x4::constData() const
+ \fn const float *QMatrix4x4::constData() const
Returns a constant pointer to the raw data of this matrix.
This raw data is stored in column-major format.
@@ -1873,24 +1904,28 @@ void QMatrix4x4::optimize()
flagBits &= ~Scale;
} else {
// If the columns are orthonormal and form a right-handed system, then there is no scale.
- qreal det = matrixDet2(m, 0, 1, 0, 1);
- qreal lenX = m[0][0] * m[0][0] + m[0][1] * m[0][1];
- qreal lenY = m[1][0] * m[1][0] + m[1][1] * m[1][1];
- qreal lenZ = m[2][2];
- if (qFuzzyCompare(det, qreal(1)) && qFuzzyCompare(lenX, qreal(1))
- && qFuzzyCompare(lenY, qreal(1)) && qFuzzyCompare(lenZ, qreal(1)))
+ double mm[4][4];
+ copyToDoubles(m, mm);
+ double det = matrixDet2(mm, 0, 1, 0, 1);
+ double lenX = mm[0][0] * mm[0][0] + mm[0][1] * mm[0][1];
+ double lenY = mm[1][0] * mm[1][0] + mm[1][1] * mm[1][1];
+ double lenZ = mm[2][2];
+ if (qFuzzyCompare(det, 1.0) && qFuzzyCompare(lenX, 1.0)
+ && qFuzzyCompare(lenY, 1.0) && qFuzzyCompare(lenZ, 1.0))
{
flagBits &= ~Scale;
}
}
} else {
// If the columns are orthonormal and form a right-handed system, then there is no scale.
- qreal det = matrixDet3(m, 0, 1, 2, 0, 1, 2);
- qreal lenX = m[0][0] * m[0][0] + m[0][1] * m[0][1] + m[0][2] * m[0][2];
- qreal lenY = m[1][0] * m[1][0] + m[1][1] * m[1][1] + m[1][2] * m[1][2];
- qreal lenZ = m[2][0] * m[2][0] + m[2][1] * m[2][1] + m[2][2] * m[2][2];
- if (qFuzzyCompare(det, qreal(1)) && qFuzzyCompare(lenX, qreal(1))
- && qFuzzyCompare(lenY, qreal(1)) && qFuzzyCompare(lenZ, qreal(1)))
+ double mm[4][4];
+ copyToDoubles(m, mm);
+ double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);
+ double lenX = mm[0][0] * mm[0][0] + mm[0][1] * mm[0][1] + mm[0][2] * mm[0][2];
+ double lenY = mm[1][0] * mm[1][0] + mm[1][1] * mm[1][1] + mm[1][2] * mm[1][2];
+ double lenZ = mm[2][0] * mm[2][0] + mm[2][1] * mm[2][1] + mm[2][2] * mm[2][2];
+ if (qFuzzyCompare(det, 1.0) && qFuzzyCompare(lenX, 1.0)
+ && qFuzzyCompare(lenY, 1.0) && qFuzzyCompare(lenZ, 1.0))
{
flagBits &= ~Scale;
}
@@ -1959,7 +1994,7 @@ QDataStream &operator<<(QDataStream &stream, const QMatrix4x4 &matrix)
{
for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col)
- stream << double(matrix(row, col));
+ stream << matrix(row, col);
return stream;
}
@@ -1975,11 +2010,11 @@ QDataStream &operator<<(QDataStream &stream, const QMatrix4x4 &matrix)
QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix)
{
- double x;
+ float x;
for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
stream >> x;
- matrix(row, col) = qreal(x);
+ matrix(row, col) = x;
}
}
matrix.optimize();