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>
This commit is contained in:
Sean Harmer 2012-08-20 20:55:40 +01:00 committed by Qt by Nokia
parent 56414e2498
commit 51d40d7e9b
24 changed files with 2499 additions and 2635 deletions

View File

@ -121,24 +121,6 @@ void Tile::setColors(GLfloat colorArray[4][4])
geom->setColors(start, colorArray); geom->setColors(start, colorArray);
} }
static inline void qMultMatrix(const QMatrix4x4 &mat)
{
if (sizeof(qreal) == sizeof(GLfloat))
glMultMatrixf((GLfloat*)mat.constData());
#ifndef QT_OPENGL_ES
else if (sizeof(qreal) == sizeof(GLdouble))
glMultMatrixd((GLdouble*)mat.constData());
#endif
else
{
GLfloat fmat[16];
qreal const *r = mat.constData();
for (int i = 0; i < 16; ++i)
fmat[i] = r[i];
glMultMatrixf(fmat);
}
}
void Tile::draw() const void Tile::draw() const
{ {
QMatrix4x4 mat; QMatrix4x4 mat;
@ -146,7 +128,7 @@ void Tile::draw() const
mat.rotate(orientation); mat.rotate(orientation);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
qMultMatrix(mat); glMultMatrixf(mat.constData());
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, geom->indices() + start); glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, geom->indices() + start);
glPopMatrix(); glPopMatrix();

View File

@ -173,29 +173,11 @@ void Patch::translate(const QVector3D &t)
mat.translate(t); mat.translate(t);
} }
static inline void qMultMatrix(const QMatrix4x4 &mat)
{
if (sizeof(qreal) == sizeof(GLfloat))
glMultMatrixf((GLfloat*)mat.constData());
#ifndef QT_OPENGL_ES
else if (sizeof(qreal) == sizeof(GLdouble))
glMultMatrixd((GLdouble*)mat.constData());
#endif
else
{
GLfloat fmat[16];
qreal const *r = mat.constData();
for (int i = 0; i < 16; ++i)
fmat[i] = r[i];
glMultMatrixf(fmat);
}
}
//! [2] //! [2]
void Patch::draw() const void Patch::draw() const
{ {
glPushMatrix(); glPushMatrix();
qMultMatrix(mat); glMultMatrixf(mat.constData());
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor);
const GLushort *indices = geom->faces.constData(); const GLushort *indices = geom->faces.constData();

View File

@ -655,22 +655,12 @@ static void loadMatrix(const QMatrix4x4& m)
{ {
// static to prevent glLoadMatrixf to fail on certain drivers // static to prevent glLoadMatrixf to fail on certain drivers
static GLfloat mat[16]; static GLfloat mat[16];
const qreal *data = m.constData(); const float *data = m.constData();
for (int index = 0; index < 16; ++index) for (int index = 0; index < 16; ++index)
mat[index] = data[index]; mat[index] = data[index];
glLoadMatrixf(mat); glLoadMatrixf(mat);
} }
static void multMatrix(const QMatrix4x4& m)
{
// static to prevent glMultMatrixf to fail on certain drivers
static GLfloat mat[16];
const qreal *data = m.constData();
for (int index = 0; index < 16; ++index)
mat[index] = data[index];
glMultMatrixf(mat);
}
// If one of the boxes should not be rendered, set excludeBox to its index. // If one of the boxes should not be rendered, set excludeBox to its index.
// If the main box should not be rendered, set excludeBox to -1. // If the main box should not be rendered, set excludeBox to -1.
void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox) void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox)
@ -722,7 +712,7 @@ void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox)
glPushMatrix(); glPushMatrix();
QMatrix4x4 m; QMatrix4x4 m;
m.rotate(m_trackBalls[1].rotation()); m.rotate(m_trackBalls[1].rotation());
multMatrix(m); glMultMatrixf(m.constData());
glRotatef(360.0f * i / m_programs.size(), 0.0f, 0.0f, 1.0f); glRotatef(360.0f * i / m_programs.size(), 0.0f, 0.0f, 1.0f);
glTranslatef(2.0f, 0.0f, 0.0f); glTranslatef(2.0f, 0.0f, 0.0f);
@ -755,7 +745,7 @@ void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox)
if (-1 != excludeBox) { if (-1 != excludeBox) {
QMatrix4x4 m; QMatrix4x4 m;
m.rotate(m_trackBalls[0].rotation()); m.rotate(m_trackBalls[0].rotation());
multMatrix(m); glMultMatrixf(m.constData());
if (glActiveTexture) { if (glActiveTexture) {
if (m_dynamicCubemap) if (m_dynamicCubemap)

View File

@ -273,7 +273,7 @@ QT_BEGIN_NAMESPACE
\relates QGenericMatrix \relates QGenericMatrix
The QMatrix2x2 type defines a convenient instantiation of the The QMatrix2x2 type defines a convenient instantiation of the
QGenericMatrix template for 2 columns, 2 rows, and qreal as QGenericMatrix template for 2 columns, 2 rows, and float as
the element type. the element type.
*/ */
@ -282,7 +282,7 @@ QT_BEGIN_NAMESPACE
\relates QGenericMatrix \relates QGenericMatrix
The QMatrix2x3 type defines a convenient instantiation of the The QMatrix2x3 type defines a convenient instantiation of the
QGenericMatrix template for 2 columns, 3 rows, and qreal as QGenericMatrix template for 2 columns, 3 rows, and float as
the element type. the element type.
*/ */
@ -291,7 +291,7 @@ QT_BEGIN_NAMESPACE
\relates QGenericMatrix \relates QGenericMatrix
The QMatrix2x4 type defines a convenient instantiation of the The QMatrix2x4 type defines a convenient instantiation of the
QGenericMatrix template for 2 columns, 4 rows, and qreal as QGenericMatrix template for 2 columns, 4 rows, and float as
the element type. the element type.
*/ */
@ -300,7 +300,7 @@ QT_BEGIN_NAMESPACE
\relates QGenericMatrix \relates QGenericMatrix
The QMatrix3x2 type defines a convenient instantiation of the The QMatrix3x2 type defines a convenient instantiation of the
QGenericMatrix template for 3 columns, 2 rows, and qreal as QGenericMatrix template for 3 columns, 2 rows, and float as
the element type. the element type.
*/ */
@ -309,7 +309,7 @@ QT_BEGIN_NAMESPACE
\relates QGenericMatrix \relates QGenericMatrix
The QMatrix3x3 type defines a convenient instantiation of the The QMatrix3x3 type defines a convenient instantiation of the
QGenericMatrix template for 3 columns, 3 rows, and qreal as QGenericMatrix template for 3 columns, 3 rows, and float as
the element type. the element type.
*/ */
@ -318,7 +318,7 @@ QT_BEGIN_NAMESPACE
\relates QGenericMatrix \relates QGenericMatrix
The QMatrix3x4 type defines a convenient instantiation of the The QMatrix3x4 type defines a convenient instantiation of the
QGenericMatrix template for 3 columns, 4 rows, and qreal as QGenericMatrix template for 3 columns, 4 rows, and float as
the element type. the element type.
*/ */
@ -327,7 +327,7 @@ QT_BEGIN_NAMESPACE
\relates QGenericMatrix \relates QGenericMatrix
The QMatrix4x2 type defines a convenient instantiation of the The QMatrix4x2 type defines a convenient instantiation of the
QGenericMatrix template for 4 columns, 2 rows, and qreal as QGenericMatrix template for 4 columns, 2 rows, and float as
the element type. the element type.
*/ */
@ -336,7 +336,7 @@ QT_BEGIN_NAMESPACE
\relates QGenericMatrix \relates QGenericMatrix
The QMatrix4x3 type defines a convenient instantiation of the The QMatrix4x3 type defines a convenient instantiation of the
QGenericMatrix template for 4 columns, 3 rows, and qreal as QGenericMatrix template for 4 columns, 3 rows, and float as
the element type. the element type.
*/ */

View File

@ -336,14 +336,14 @@ Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
} }
// Define aliases for the useful variants of QGenericMatrix. // Define aliases for the useful variants of QGenericMatrix.
typedef QGenericMatrix<2, 2, qreal> QMatrix2x2; typedef QGenericMatrix<2, 2, float> QMatrix2x2;
typedef QGenericMatrix<2, 3, qreal> QMatrix2x3; typedef QGenericMatrix<2, 3, float> QMatrix2x3;
typedef QGenericMatrix<2, 4, qreal> QMatrix2x4; typedef QGenericMatrix<2, 4, float> QMatrix2x4;
typedef QGenericMatrix<3, 2, qreal> QMatrix3x2; typedef QGenericMatrix<3, 2, float> QMatrix3x2;
typedef QGenericMatrix<3, 3, qreal> QMatrix3x3; typedef QGenericMatrix<3, 3, float> QMatrix3x3;
typedef QGenericMatrix<3, 4, qreal> QMatrix3x4; typedef QGenericMatrix<3, 4, float> QMatrix3x4;
typedef QGenericMatrix<4, 2, qreal> QMatrix4x2; typedef QGenericMatrix<4, 2, float> QMatrix4x2;
typedef QGenericMatrix<4, 3, qreal> QMatrix4x3; typedef QGenericMatrix<4, 3, float> QMatrix4x3;
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM

View File

@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
\sa QVector3D, QGenericMatrix \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() \fn QMatrix4x4::QMatrix4x4()
@ -93,7 +93,7 @@ static const qreal inv_dist_to_plane = 1. / 1024.;
\sa copyDataTo(), optimize() \sa copyDataTo(), optimize()
*/ */
QMatrix4x4::QMatrix4x4(const qreal *values) QMatrix4x4::QMatrix4x4(const float *values)
{ {
for (int row = 0; row < 4; ++row) for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col) for (int col = 0; col < 4; ++col)
@ -101,8 +101,17 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
flagBits = General; 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, 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, \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 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, 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 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, 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 \relates QMatrix4x4
\obsolete \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 \relates QMatrix4x4
\obsolete \obsolete
@ -166,7 +175,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
/*! /*!
\internal \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 col = 0; col < 4; ++col) {
for (int row = 0; row < 4; ++row) { 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 Returns a constant reference to the element at position
(\a row, \a column) in this matrix. (\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) Returns a reference to the element at position (\a row, \a column)
in this matrix so that the element can be assigned to. 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. 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]; 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 | // | A B C |
// M = | D E F | det(M) = A * (EI - HF) - B * (DI - GF) + C * (DH - GE) // M = | D E F | det(M) = A * (EI - HF) - B * (DI - GF) + C * (DH - GE)
// | G H I | // | G H I |
static inline qreal matrixDet3 static inline double matrixDet3
(const qreal m[4][4], int col0, int col1, int col2, (const double m[4][4], int col0, int col1, int col2,
int row0, int row1, int row2) int row0, int row1, int row2)
{ {
return m[col0][row0] * matrixDet2(m, col1, col2, row1, 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. // 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[0][0] * matrixDet3(m, 1, 2, 3, 1, 2, 3);
det -= m[1][0] * matrixDet3(m, 0, 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); 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; 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. Returns the determinant of this matrix.
*/ */
qreal QMatrix4x4::determinant() const double QMatrix4x4::determinant() const
{ {
if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity)
return 1; return 1.0;
double mm[4][4];
copyToDoubles(m, mm);
if (flagBits < Rotation2D) 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) if (flagBits < Perspective)
return matrixDet3(m, 0, 1, 2, 0, 1, 2); return matrixDet3(mm, 0, 1, 2, 0, 1, 2);
return matrixDet4(m); return matrixDet4(mm);
} }
/*! /*!
@ -420,7 +439,10 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
} else if (flagBits < Perspective) { } else if (flagBits < Perspective) {
QMatrix4x4 inv(1); // The "1" says to not load the identity. 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 (det == 0.0f) {
if (invertible) if (invertible)
*invertible = false; *invertible = false;
@ -428,17 +450,17 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
} }
det = 1.0f / det; det = 1.0f / det;
inv.m[0][0] = matrixDet2(m, 1, 2, 1, 2) * det; inv.m[0][0] = matrixDet2(mm, 1, 2, 1, 2) * det;
inv.m[0][1] = -matrixDet2(m, 0, 2, 1, 2) * det; inv.m[0][1] = -matrixDet2(mm, 0, 2, 1, 2) * det;
inv.m[0][2] = matrixDet2(m, 0, 1, 1, 2) * det; inv.m[0][2] = matrixDet2(mm, 0, 1, 1, 2) * det;
inv.m[0][3] = 0; inv.m[0][3] = 0;
inv.m[1][0] = -matrixDet2(m, 1, 2, 0, 2) * det; inv.m[1][0] = -matrixDet2(mm, 1, 2, 0, 2) * det;
inv.m[1][1] = matrixDet2(m, 0, 2, 0, 2) * det; inv.m[1][1] = matrixDet2(mm, 0, 2, 0, 2) * det;
inv.m[1][2] = -matrixDet2(m, 0, 1, 0, 2) * det; inv.m[1][2] = -matrixDet2(mm, 0, 1, 0, 2) * det;
inv.m[1][3] = 0; inv.m[1][3] = 0;
inv.m[2][0] = matrixDet2(m, 1, 2, 0, 1) * det; inv.m[2][0] = matrixDet2(mm, 1, 2, 0, 1) * det;
inv.m[2][1] = -matrixDet2(m, 0, 2, 0, 1) * det; inv.m[2][1] = -matrixDet2(mm, 0, 2, 0, 1) * det;
inv.m[2][2] = matrixDet2(m, 0, 1, 0, 1) * det; inv.m[2][2] = matrixDet2(mm, 0, 1, 0, 1) * det;
inv.m[2][3] = 0; 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][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]; 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. 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 (det == 0.0f) {
if (invertible) if (invertible)
*invertible = false; *invertible = false;
@ -461,22 +486,22 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
} }
det = 1.0f / det; det = 1.0f / det;
inv.m[0][0] = matrixDet3(m, 1, 2, 3, 1, 2, 3) * det; inv.m[0][0] = matrixDet3(mm, 1, 2, 3, 1, 2, 3) * det;
inv.m[0][1] = -matrixDet3(m, 0, 2, 3, 1, 2, 3) * det; inv.m[0][1] = -matrixDet3(mm, 0, 2, 3, 1, 2, 3) * det;
inv.m[0][2] = matrixDet3(m, 0, 1, 3, 1, 2, 3) * det; inv.m[0][2] = matrixDet3(mm, 0, 1, 3, 1, 2, 3) * det;
inv.m[0][3] = -matrixDet3(m, 0, 1, 2, 1, 2, 3) * det; inv.m[0][3] = -matrixDet3(mm, 0, 1, 2, 1, 2, 3) * det;
inv.m[1][0] = -matrixDet3(m, 1, 2, 3, 0, 2, 3) * det; inv.m[1][0] = -matrixDet3(mm, 1, 2, 3, 0, 2, 3) * det;
inv.m[1][1] = matrixDet3(m, 0, 2, 3, 0, 2, 3) * det; inv.m[1][1] = matrixDet3(mm, 0, 2, 3, 0, 2, 3) * det;
inv.m[1][2] = -matrixDet3(m, 0, 1, 3, 0, 2, 3) * det; inv.m[1][2] = -matrixDet3(mm, 0, 1, 3, 0, 2, 3) * det;
inv.m[1][3] = matrixDet3(m, 0, 1, 2, 0, 2, 3) * det; inv.m[1][3] = matrixDet3(mm, 0, 1, 2, 0, 2, 3) * det;
inv.m[2][0] = matrixDet3(m, 1, 2, 3, 0, 1, 3) * det; inv.m[2][0] = matrixDet3(mm, 1, 2, 3, 0, 1, 3) * det;
inv.m[2][1] = -matrixDet3(m, 0, 2, 3, 0, 1, 3) * det; inv.m[2][1] = -matrixDet3(mm, 0, 2, 3, 0, 1, 3) * det;
inv.m[2][2] = matrixDet3(m, 0, 1, 3, 0, 1, 3) * det; inv.m[2][2] = matrixDet3(mm, 0, 1, 3, 0, 1, 3) * det;
inv.m[2][3] = -matrixDet3(m, 0, 1, 2, 0, 1, 3) * det; inv.m[2][3] = -matrixDet3(mm, 0, 1, 2, 0, 1, 3) * det;
inv.m[3][0] = -matrixDet3(m, 1, 2, 3, 0, 1, 2) * det; inv.m[3][0] = -matrixDet3(mm, 1, 2, 3, 0, 1, 2) * det;
inv.m[3][1] = matrixDet3(m, 0, 2, 3, 0, 1, 2) * det; inv.m[3][1] = matrixDet3(mm, 0, 2, 3, 0, 1, 2) * det;
inv.m[3][2] = -matrixDet3(m, 0, 1, 3, 0, 1, 2) * det; inv.m[3][2] = -matrixDet3(mm, 0, 1, 3, 0, 1, 2) * det;
inv.m[3][3] = matrixDet3(m, 0, 1, 2, 0, 1, 2) * det; inv.m[3][3] = matrixDet3(mm, 0, 1, 2, 0, 1, 2) * det;
inv.flagBits = flagBits; inv.flagBits = flagBits;
if (invertible) if (invertible)
@ -509,7 +534,7 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const
inv.data()[8] = 1.0f / m[2][2]; inv.data()[8] = 1.0f / m[2][2];
return inv; return inv;
} else if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) { } else if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) {
qreal *invm = inv.data(); float *invm = inv.data();
invm[0 + 0 * 3] = m[0][0]; invm[0 + 0 * 3] = m[0][0];
invm[1 + 0 * 3] = m[0][1]; invm[1 + 0 * 3] = m[0][1];
invm[2 + 0 * 3] = m[0][2]; invm[2 + 0 * 3] = m[0][2];
@ -522,23 +547,25 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const
return inv; 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) if (det == 0.0f)
return inv; return inv;
det = 1.0f / det; det = 1.0f / det;
qreal *invm = inv.data(); float *invm = inv.data();
// Invert and transpose in a single step. // 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[0 + 0 * 3] = (mm[1][1] * mm[2][2] - mm[2][1] * mm[1][2]) * det;
invm[1 + 0 * 3] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) * det; invm[1 + 0 * 3] = -(mm[1][0] * mm[2][2] - mm[1][2] * mm[2][0]) * det;
invm[2 + 0 * 3] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) * det; invm[2 + 0 * 3] = (mm[1][0] * mm[2][1] - mm[1][1] * mm[2][0]) * det;
invm[0 + 1 * 3] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * det; invm[0 + 1 * 3] = -(mm[0][1] * mm[2][2] - mm[2][1] * mm[0][2]) * det;
invm[1 + 1 * 3] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) * det; invm[1 + 1 * 3] = (mm[0][0] * mm[2][2] - mm[0][2] * mm[2][0]) * det;
invm[2 + 1 * 3] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) * det; invm[2 + 1 * 3] = -(mm[0][0] * mm[2][1] - mm[0][1] * mm[2][0]) * det;
invm[0 + 2 * 3] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) * det; invm[0 + 2 * 3] = (mm[0][1] * mm[1][2] - mm[0][2] * mm[1][1]) * det;
invm[1 + 2 * 3] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) * det; invm[1 + 2 * 3] = -(mm[0][0] * mm[1][2] - mm[0][2] * mm[1][0]) * det;
invm[2 + 2 * 3] = (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * det; invm[2 + 2 * 3] = (mm[0][0] * mm[1][1] - mm[1][0] * mm[0][1]) * det;
return inv; return inv;
} }
@ -578,7 +605,7 @@ QMatrix4x4 QMatrix4x4::transposed() const
*/ */
/*! /*!
\fn QMatrix4x4& QMatrix4x4::operator*=(qreal factor) \fn QMatrix4x4& QMatrix4x4::operator*=(float factor)
\overload \overload
Multiplies all elements of this matrix by \a factor. 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. 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][0] /= divisor;
m[0][1] /= 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 \relates QMatrix4x4
Returns the result of multiplying all elements of \a matrix by \a factor. 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 \relates QMatrix4x4
Returns the result of multiplying all elements of \a matrix by \a factor. 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. 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. QMatrix4x4 m(1); // The "1" says to not load the identity.
m.m[0][0] = matrix.m[0][0] / divisor; 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) void QMatrix4x4::scale(const QVector3D& vector)
{ {
qreal vx = vector.x(); float vx = vector.x();
qreal vy = vector.y(); float vy = vector.y();
qreal vz = vector.z(); float vz = vector.z();
if (flagBits < Scale) { if (flagBits < Scale) {
m[0][0] = vx; m[0][0] = vx;
m[1][1] = vy; m[1][1] = vy;
@ -830,7 +857,7 @@ void QMatrix4x4::scale(const QVector3D& vector)
\sa translate(), rotate() \sa translate(), rotate()
*/ */
void QMatrix4x4::scale(qreal x, qreal y) void QMatrix4x4::scale(float x, float y)
{ {
if (flagBits < Scale) { if (flagBits < Scale) {
m[0][0] = x; m[0][0] = x;
@ -864,7 +891,7 @@ void QMatrix4x4::scale(qreal x, qreal y)
\sa translate(), rotate() \sa translate(), rotate()
*/ */
void QMatrix4x4::scale(qreal x, qreal y, qreal z) void QMatrix4x4::scale(float x, float y, float z)
{ {
if (flagBits < Scale) { if (flagBits < Scale) {
m[0][0] = x; m[0][0] = x;
@ -905,7 +932,7 @@ void QMatrix4x4::scale(qreal x, qreal y, qreal z)
\sa translate(), rotate() \sa translate(), rotate()
*/ */
void QMatrix4x4::scale(qreal factor) void QMatrix4x4::scale(float factor)
{ {
if (flagBits < Scale) { if (flagBits < Scale) {
m[0][0] = factor; m[0][0] = factor;
@ -948,9 +975,9 @@ void QMatrix4x4::scale(qreal factor)
void QMatrix4x4::translate(const QVector3D& vector) void QMatrix4x4::translate(const QVector3D& vector)
{ {
qreal vx = vector.x(); float vx = vector.x();
qreal vy = vector.y(); float vy = vector.y();
qreal vz = vector.z(); float vz = vector.z();
if (flagBits == Identity) { if (flagBits == Identity) {
m[3][0] = vx; m[3][0] = vx;
m[3][1] = vy; m[3][1] = vy;
@ -989,7 +1016,7 @@ void QMatrix4x4::translate(const QVector3D& vector)
\sa scale(), rotate() \sa scale(), rotate()
*/ */
void QMatrix4x4::translate(qreal x, qreal y) void QMatrix4x4::translate(float x, float y)
{ {
if (flagBits == Identity) { if (flagBits == Identity) {
m[3][0] = x; m[3][0] = x;
@ -1023,7 +1050,7 @@ void QMatrix4x4::translate(qreal x, qreal y)
\sa scale(), rotate() \sa scale(), rotate()
*/ */
void QMatrix4x4::translate(qreal x, qreal y, qreal z) void QMatrix4x4::translate(float x, float y, float z)
{ {
if (flagBits == Identity) { if (flagBits == Identity) {
m[3][0] = x; m[3][0] = x;
@ -1062,7 +1089,7 @@ void QMatrix4x4::translate(qreal x, qreal y, qreal z)
\sa scale(), translate() \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()); rotate(angle, vector.x(), vector.y(), vector.z());
} }
@ -1077,11 +1104,11 @@ void QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
\sa scale(), translate() \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) if (angle == 0.0f)
return; return;
qreal c, s; float c, s;
if (angle == 90.0f || angle == -270.0f) { if (angle == 90.0f || angle == -270.0f) {
s = 1.0f; s = 1.0f;
c = 0.0f; c = 0.0f;
@ -1092,9 +1119,9 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
s = 0.0f; s = 0.0f;
c = -1.0f; c = -1.0f;
} else { } else {
qreal a = angle * M_PI / 180.0f; float a = angle * M_PI / 180.0f;
c = qCos(a); c = cosf(a);
s = qSin(a); s = sinf(a);
} }
if (x == 0.0f) { if (x == 0.0f) {
if (y == 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. // Rotate around the Z axis.
if (z < 0) if (z < 0)
s = -s; s = -s;
qreal tmp; float tmp;
m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s; m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s;
m[1][0] = m[1][0] * c - tmp * s; m[1][0] = m[1][0] * c - tmp * s;
m[0][1] = (tmp = m[0][1]) * c + m[1][1] * 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. // Rotate around the Y axis.
if (y < 0) if (y < 0)
s = -s; s = -s;
qreal tmp; float tmp;
m[2][0] = (tmp = m[2][0]) * c + m[0][0] * s; m[2][0] = (tmp = m[2][0]) * c + m[0][0] * s;
m[0][0] = m[0][0] * c - tmp * s; m[0][0] = m[0][0] * c - tmp * s;
m[2][1] = (tmp = m[2][1]) * c + m[0][1] * 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. // Rotate around the X axis.
if (x < 0) if (x < 0)
s = -s; s = -s;
qreal tmp; float tmp;
m[1][0] = (tmp = m[1][0]) * c + m[2][0] * s; m[1][0] = (tmp = m[1][0]) * c + m[2][0] * s;
m[2][0] = m[2][0] * c - tmp * s; m[2][0] = m[2][0] * c - tmp * s;
m[1][1] = (tmp = m[1][1]) * c + m[2][1] * 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; return;
} }
qreal len = x * x + y * y + z * z; double len = double(x) * double(x) +
if (!qFuzzyCompare(len, qreal(1)) && !qFuzzyIsNull(len)) { double(y) * double(y) +
len = qSqrt(len); double(z) * double(z);
x /= len; if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) {
y /= len; len = sqrt(len);
z /= 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. QMatrix4x4 rot(1); // The "1" says to not load the identity.
rot.m[0][0] = x * x * ic + c; rot.m[0][0] = x * x * ic + c;
rot.m[1][0] = x * y * ic - z * s; 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 \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 // Used by QGraphicsRotation::applyTo() to perform a rotation
// and projection back to 2D in a single step. // and projection back to 2D in a single step.
if (angle == 0.0f) if (angle == 0.0f)
return; return;
qreal c, s; float c, s;
if (angle == 90.0f || angle == -270.0f) { if (angle == 90.0f || angle == -270.0f) {
s = 1.0f; s = 1.0f;
c = 0.0f; c = 0.0f;
@ -1199,9 +1228,9 @@ void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
s = 0.0f; s = 0.0f;
c = -1.0f; c = -1.0f;
} else { } else {
qreal a = angle * M_PI / 180.0f; float a = angle * M_PI / 180.0f;
c = qCos(a); c = cosf(a);
s = qSin(a); s = sinf(a);
} }
if (x == 0.0f) { if (x == 0.0f) {
if (y == 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. // Rotate around the Z axis.
if (z < 0) if (z < 0)
s = -s; s = -s;
qreal tmp; float tmp;
m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s; m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s;
m[1][0] = m[1][0] * c - tmp * s; m[1][0] = m[1][0] * c - tmp * s;
m[0][1] = (tmp = m[0][1]) * c + m[1][1] * 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; flagBits = General;
return; return;
} }
qreal len = x * x + y * y + z * z; double len = double(x) * double(x) +
if (!qFuzzyIsNull(len - 1.0f) && !qFuzzyIsNull(len)) { double(y) * double(y) +
len = qSqrt(len); double(z) * double(z);
x /= len; if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) {
y /= len; len = sqrt(len);
z /= 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. QMatrix4x4 rot(1); // The "1" says to not load the identity.
rot.m[0][0] = x * x * ic + c; rot.m[0][0] = x * x * ic + c;
rot.m[1][0] = x * y * ic - z * s; rot.m[1][0] = x * y * ic - z * s;
@ -1287,15 +1318,15 @@ void QMatrix4x4::rotate(const QQuaternion& quaternion)
// Algorithm from: // Algorithm from:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54 // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54
QMatrix4x4 m(1); QMatrix4x4 m(1);
qreal xx = quaternion.x() * quaternion.x(); float xx = quaternion.x() * quaternion.x();
qreal xy = quaternion.x() * quaternion.y(); float xy = quaternion.x() * quaternion.y();
qreal xz = quaternion.x() * quaternion.z(); float xz = quaternion.x() * quaternion.z();
qreal xw = quaternion.x() * quaternion.scalar(); float xw = quaternion.x() * quaternion.scalar();
qreal yy = quaternion.y() * quaternion.y(); float yy = quaternion.y() * quaternion.y();
qreal yz = quaternion.y() * quaternion.z(); float yz = quaternion.y() * quaternion.z();
qreal yw = quaternion.y() * quaternion.scalar(); float yw = quaternion.y() * quaternion.scalar();
qreal zz = quaternion.z() * quaternion.z(); float zz = quaternion.z() * quaternion.z();
qreal zw = quaternion.z() * quaternion.scalar(); float zw = quaternion.z() * quaternion.scalar();
m.m[0][0] = 1.0f - 2 * (yy + zz); m.m[0][0] = 1.0f - 2 * (yy + zz);
m.m[1][0] = 2 * (xy - zw); m.m[1][0] = 2 * (xy - zw);
m.m[2][0] = 2 * (xz + yw); m.m[2][0] = 2 * (xz + yw);
@ -1358,16 +1389,16 @@ void QMatrix4x4::ortho(const QRectF& rect)
\sa frustum(), perspective() \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. // Bail out if the projection volume is zero-sized.
if (left == right || bottom == top || nearPlane == farPlane) if (left == right || bottom == top || nearPlane == farPlane)
return; return;
// Construct the projection. // Construct the projection.
qreal width = right - left; float width = right - left;
qreal invheight = top - bottom; float invheight = top - bottom;
qreal clip = farPlane - nearPlane; float clip = farPlane - nearPlane;
QMatrix4x4 m(1); QMatrix4x4 m(1);
m.m[0][0] = 2.0f / width; m.m[0][0] = 2.0f / width;
m.m[1][0] = 0.0f; 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() \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. // Bail out if the projection volume is zero-sized.
if (left == right || bottom == top || nearPlane == farPlane) 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. // Construct the projection.
QMatrix4x4 m(1); QMatrix4x4 m(1);
qreal width = right - left; float width = right - left;
qreal invheight = top - bottom; float invheight = top - bottom;
qreal clip = farPlane - nearPlane; float clip = farPlane - nearPlane;
m.m[0][0] = 2.0f * nearPlane / width; m.m[0][0] = 2.0f * nearPlane / width;
m.m[1][0] = 0.0f; m.m[1][0] = 0.0f;
m.m[2][0] = (left + right) / width; 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() \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. // Bail out if the projection volume is zero-sized.
if (nearPlane == farPlane || aspect == 0.0f) if (nearPlane == farPlane || aspect == 0.0f)
@ -1448,12 +1479,12 @@ void QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal f
// Construct the projection. // Construct the projection.
QMatrix4x4 m(1); QMatrix4x4 m(1);
qreal radians = (angle / 2.0f) * M_PI / 180.0f; float radians = (angle / 2.0f) * M_PI / 180.0f;
qreal sine = qSin(radians); float sine = sinf(radians);
if (sine == 0.0f) if (sine == 0.0f)
return; return;
qreal cotan = qCos(radians) / sine; float cotan = cosf(radians) / sine;
qreal clip = farPlane - nearPlane; float clip = farPlane - nearPlane;
m.m[0][0] = cotan / aspect; m.m[0][0] = cotan / aspect;
m.m[1][0] = 0.0f; m.m[1][0] = 0.0f;
m.m[2][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 Retrieves the 16 items in this matrix and copies them to \a values
in row-major order. 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 row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col) 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() \sa toAffine()
*/ */
QTransform QMatrix4x4::toTransform(qreal distanceToPlane) const QTransform QMatrix4x4::toTransform(float distanceToPlane) const
{ {
if (distanceToPlane == 1024.0f) { if (distanceToPlane == 1024.0f) {
// Optimize the common case with constants. // Optimize the common case with constants.
@ -1622,7 +1653,7 @@ QTransform QMatrix4x4::toTransform(qreal distanceToPlane) const
// | 0 0 d 1 | // | 0 0 d 1 |
// where d = -1 / distanceToPlane. After projection, row 3 and // where d = -1 / distanceToPlane. After projection, row 3 and
// column 3 are dropped to form the final QTransform. // 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, 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[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); 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()); rect.width(), rect.height());
} else if (flagBits < Rotation2D) { } else if (flagBits < Rotation2D) {
// Translation | Scale // Translation | Scale
qreal x = rect.x() * m[0][0] + m[3][0]; float x = rect.x() * m[0][0] + m[3][0];
qreal y = rect.y() * m[1][1] + m[3][1]; float y = rect.y() * m[1][1] + m[3][1];
qreal w = rect.width() * m[0][0]; float w = rect.width() * m[0][0];
qreal h = rect.height() * m[1][1]; float h = rect.height() * m[1][1];
if (w < 0) { if (w < 0) {
w = -w; w = -w;
x -= w; x -= w;
@ -1745,10 +1776,10 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
return rect.translated(m[3][0], m[3][1]); return rect.translated(m[3][0], m[3][1]);
} else if (flagBits < Rotation2D) { } else if (flagBits < Rotation2D) {
// Translation | Scale // Translation | Scale
qreal x = rect.x() * m[0][0] + m[3][0]; float x = rect.x() * m[0][0] + m[3][0];
qreal y = rect.y() * m[1][1] + m[3][1]; float y = rect.y() * m[1][1] + m[3][1];
qreal w = rect.width() * m[0][0]; float w = rect.width() * m[0][0];
qreal h = rect.height() * m[1][1]; float h = rect.height() * m[1][1];
if (w < 0) { if (w < 0) {
w = -w; w = -w;
x -= 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 tl = map(rect.topLeft()); QPointF tr = map(rect.topRight());
QPointF bl = map(rect.bottomLeft()); QPointF br = map(rect.bottomRight()); QPointF bl = map(rect.bottomLeft()); QPointF br = map(rect.bottomRight());
qreal xmin = qMin(qMin(tl.x(), tr.x()), qMin(bl.x(), br.x())); float 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())); float 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())); float 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 ymax = qMax(qMax(tl.y(), tr.y()), qMax(bl.y(), br.y()));
return QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); 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. 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. Returns a constant pointer to the raw data of this matrix.
This raw data is stored in column-major format. 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. Returns a constant pointer to the raw data of this matrix.
This raw data is stored in column-major format. This raw data is stored in column-major format.
@ -1873,24 +1904,28 @@ void QMatrix4x4::optimize()
flagBits &= ~Scale; flagBits &= ~Scale;
} else { } else {
// If the columns are orthonormal and form a right-handed system, then there is no scale. // If the columns are orthonormal and form a right-handed system, then there is no scale.
qreal det = matrixDet2(m, 0, 1, 0, 1); double mm[4][4];
qreal lenX = m[0][0] * m[0][0] + m[0][1] * m[0][1]; copyToDoubles(m, mm);
qreal lenY = m[1][0] * m[1][0] + m[1][1] * m[1][1]; double det = matrixDet2(mm, 0, 1, 0, 1);
qreal lenZ = m[2][2]; double lenX = mm[0][0] * mm[0][0] + mm[0][1] * mm[0][1];
if (qFuzzyCompare(det, qreal(1)) && qFuzzyCompare(lenX, qreal(1)) double lenY = mm[1][0] * mm[1][0] + mm[1][1] * mm[1][1];
&& qFuzzyCompare(lenY, qreal(1)) && qFuzzyCompare(lenZ, qreal(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; flagBits &= ~Scale;
} }
} }
} else { } else {
// If the columns are orthonormal and form a right-handed system, then there is no scale. // 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); double mm[4][4];
qreal lenX = m[0][0] * m[0][0] + m[0][1] * m[0][1] + m[0][2] * m[0][2]; copyToDoubles(m, mm);
qreal lenY = m[1][0] * m[1][0] + m[1][1] * m[1][1] + m[1][2] * m[1][2]; double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);
qreal lenZ = m[2][0] * m[2][0] + m[2][1] * m[2][1] + m[2][2] * m[2][2]; double lenX = mm[0][0] * mm[0][0] + mm[0][1] * mm[0][1] + mm[0][2] * mm[0][2];
if (qFuzzyCompare(det, qreal(1)) && qFuzzyCompare(lenX, qreal(1)) double lenY = mm[1][0] * mm[1][0] + mm[1][1] * mm[1][1] + mm[1][2] * mm[1][2];
&& qFuzzyCompare(lenY, qreal(1)) && qFuzzyCompare(lenZ, qreal(1))) 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; flagBits &= ~Scale;
} }
@ -1959,7 +1994,7 @@ QDataStream &operator<<(QDataStream &stream, const QMatrix4x4 &matrix)
{ {
for (int row = 0; row < 4; ++row) for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col) for (int col = 0; col < 4; ++col)
stream << double(matrix(row, col)); stream << matrix(row, col);
return stream; return stream;
} }
@ -1975,11 +2010,11 @@ QDataStream &operator<<(QDataStream &stream, const QMatrix4x4 &matrix)
QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix) QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix)
{ {
double x; float x;
for (int row = 0; row < 4; ++row) { for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) { for (int col = 0; col < 4; ++col) {
stream >> x; stream >> x;
matrix(row, col) = qreal(x); matrix(row, col) = x;
} }
} }
matrix.optimize(); matrix.optimize();

View File

@ -63,21 +63,24 @@ class Q_GUI_EXPORT QMatrix4x4
{ {
public: public:
inline QMatrix4x4() { setToIdentity(); } inline QMatrix4x4() { setToIdentity(); }
explicit QMatrix4x4(const qreal *values); explicit QMatrix4x4(const float *values);
inline QMatrix4x4(qreal m11, qreal m12, qreal m13, qreal m14,
qreal m21, qreal m22, qreal m23, qreal m24, // ###TODO This is temporary to get through the CI's revdep qtdeclarative tests. Remove it!
qreal m31, qreal m32, qreal m33, qreal m34, explicit QMatrix4x4(const double *values);
qreal m41, qreal m42, qreal m43, qreal m44); inline 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);
template <int N, int M> template <int N, int M>
explicit QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix); explicit QMatrix4x4(const QGenericMatrix<N, M, float>& matrix);
QMatrix4x4(const qreal *values, int cols, int rows); QMatrix4x4(const float *values, int cols, int rows);
QMatrix4x4(const QTransform& transform); QMatrix4x4(const QTransform& transform);
QMatrix4x4(const QMatrix& matrix); QMatrix4x4(const QMatrix& matrix);
inline const qreal& operator()(int row, int column) const; inline const float& operator()(int row, int column) const;
inline qreal& operator()(int row, int column); inline float& operator()(int row, int column);
#ifndef QT_NO_VECTOR4D #ifndef QT_NO_VECTOR4D
inline QVector4D column(int index) const; inline QVector4D column(int index) const;
@ -90,9 +93,9 @@ public:
inline bool isIdentity() const; inline bool isIdentity() const;
inline void setToIdentity(); inline void setToIdentity();
inline void fill(qreal value); inline void fill(float value);
qreal determinant() const; double determinant() const;
QMatrix4x4 inverted(bool *invertible = 0) const; QMatrix4x4 inverted(bool *invertible = 0) const;
QMatrix4x4 transposed() const; QMatrix4x4 transposed() const;
QMatrix3x3 normalMatrix() const; QMatrix3x3 normalMatrix() const;
@ -100,8 +103,8 @@ public:
inline QMatrix4x4& operator+=(const QMatrix4x4& other); inline QMatrix4x4& operator+=(const QMatrix4x4& other);
inline QMatrix4x4& operator-=(const QMatrix4x4& other); inline QMatrix4x4& operator-=(const QMatrix4x4& other);
inline QMatrix4x4& operator*=(const QMatrix4x4& other); inline QMatrix4x4& operator*=(const QMatrix4x4& other);
inline QMatrix4x4& operator*=(qreal factor); inline QMatrix4x4& operator*=(float factor);
QMatrix4x4& operator/=(qreal divisor); QMatrix4x4& operator/=(float divisor);
inline bool operator==(const QMatrix4x4& other) const; inline bool operator==(const QMatrix4x4& other) const;
inline bool operator!=(const QMatrix4x4& other) const; inline bool operator!=(const QMatrix4x4& other) const;
@ -121,42 +124,42 @@ public:
friend QMatrix4x4 operator-(const QMatrix4x4& matrix); friend QMatrix4x4 operator-(const QMatrix4x4& matrix);
friend QPoint operator*(const QMatrix4x4& matrix, const QPoint& point); friend QPoint operator*(const QMatrix4x4& matrix, const QPoint& point);
friend QPointF operator*(const QMatrix4x4& matrix, const QPointF& point); friend QPointF operator*(const QMatrix4x4& matrix, const QPointF& point);
friend QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix); friend QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix);
friend QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor); friend QMatrix4x4 operator*(const QMatrix4x4& matrix, float factor);
friend Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor); friend Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor);
friend inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2); friend inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2);
#ifndef QT_NO_VECTOR3D #ifndef QT_NO_VECTOR3D
void scale(const QVector3D& vector); void scale(const QVector3D& vector);
void translate(const QVector3D& vector); void translate(const QVector3D& vector);
void rotate(qreal angle, const QVector3D& vector); void rotate(float angle, const QVector3D& vector);
#endif #endif
void scale(qreal x, qreal y); void scale(float x, float y);
void scale(qreal x, qreal y, qreal z); void scale(float x, float y, float z);
void scale(qreal factor); void scale(float factor);
void translate(qreal x, qreal y); void translate(float x, float y);
void translate(qreal x, qreal y, qreal z); void translate(float x, float y, float z);
void rotate(qreal angle, qreal x, qreal y, qreal z = 0.0f); void rotate(float angle, float x, float y, float z = 0.0f);
#ifndef QT_NO_QUATERNION #ifndef QT_NO_QUATERNION
void rotate(const QQuaternion& quaternion); void rotate(const QQuaternion& quaternion);
#endif #endif
void ortho(const QRect& rect); void ortho(const QRect& rect);
void ortho(const QRectF& rect); void ortho(const QRectF& rect);
void ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane); void ortho(float left, float right, float bottom, float top, float nearPlane, float farPlane);
void frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane); void frustum(float left, float right, float bottom, float top, float nearPlane, float farPlane);
void perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane); void perspective(float angle, float aspect, float nearPlane, float farPlane);
#ifndef QT_NO_VECTOR3D #ifndef QT_NO_VECTOR3D
void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up); void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
#endif #endif
void flipCoordinates(); void flipCoordinates();
void copyDataTo(qreal *values) const; void copyDataTo(float *values) const;
QMatrix toAffine() const; QMatrix toAffine() const;
QTransform toTransform() const; QTransform toTransform() const;
QTransform toTransform(qreal distanceToPlane) const; QTransform toTransform(float distanceToPlane) const;
QPoint map(const QPoint& point) const; QPoint map(const QPoint& point) const;
QPointF map(const QPointF& point) const; QPointF map(const QPointF& point) const;
@ -171,11 +174,11 @@ public:
QRectF mapRect(const QRectF& rect) const; QRectF mapRect(const QRectF& rect) const;
template <int N, int M> template <int N, int M>
QGenericMatrix<N, M, qreal> toGenericMatrix() const; QGenericMatrix<N, M, float> toGenericMatrix() const;
inline qreal *data(); inline float *data();
inline const qreal *data() const { return *m; } inline const float *data() const { return *m; }
inline const qreal *constData() const { return *m; } inline const float *constData() const { return *m; }
void optimize(); void optimize();
@ -186,7 +189,7 @@ public:
#endif #endif
private: private:
qreal m[4][4]; // Column-major order to match OpenGL. float m[4][4]; // Column-major order to match OpenGL.
int flagBits; // Flag bits from the enum below. int flagBits; // Flag bits from the enum below.
// When matrices are multiplied, the flag bits are or-ed together. // When matrices are multiplied, the flag bits are or-ed together.
@ -205,7 +208,7 @@ private:
QMatrix4x4 orthonormalInverse() const; QMatrix4x4 orthonormalInverse() const;
void projectedRotate(qreal angle, qreal x, qreal y, qreal z); void projectedRotate(float angle, float x, float y, float z);
friend class QGraphicsRotation; friend class QGraphicsRotation;
}; };
@ -213,10 +216,10 @@ private:
Q_DECLARE_TYPEINFO(QMatrix4x4, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QMatrix4x4, Q_MOVABLE_TYPE);
inline QMatrix4x4::QMatrix4x4 inline QMatrix4x4::QMatrix4x4
(qreal m11, qreal m12, qreal m13, qreal m14, (float m11, float m12, float m13, float m14,
qreal m21, qreal m22, qreal m23, qreal m24, float m21, float m22, float m23, float m24,
qreal m31, qreal m32, qreal m33, qreal m34, float m31, float m32, float m33, float m34,
qreal m41, qreal m42, qreal m43, qreal m44) float m41, float m42, float m43, float m44)
{ {
m[0][0] = m11; m[0][1] = m21; m[0][2] = m31; m[0][3] = m41; m[0][0] = m11; m[0][1] = m21; m[0][2] = m31; m[0][3] = m41;
m[1][0] = m12; m[1][1] = m22; m[1][2] = m32; m[1][3] = m42; m[1][0] = m12; m[1][1] = m22; m[1][2] = m32; m[1][3] = m42;
@ -227,9 +230,9 @@ inline QMatrix4x4::QMatrix4x4
template <int N, int M> template <int N, int M>
Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4 Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4
(const QGenericMatrix<N, M, qreal>& matrix) (const QGenericMatrix<N, M, float>& matrix)
{ {
const qreal *values = matrix.constData(); const float *values = matrix.constData();
for (int matrixCol = 0; matrixCol < 4; ++matrixCol) { for (int matrixCol = 0; matrixCol < 4; ++matrixCol) {
for (int matrixRow = 0; matrixRow < 4; ++matrixRow) { for (int matrixRow = 0; matrixRow < 4; ++matrixRow) {
if (matrixCol < N && matrixRow < M) if (matrixCol < N && matrixRow < M)
@ -244,10 +247,10 @@ Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4
} }
template <int N, int M> template <int N, int M>
QGenericMatrix<N, M, qreal> QMatrix4x4::toGenericMatrix() const QGenericMatrix<N, M, float> QMatrix4x4::toGenericMatrix() const
{ {
QGenericMatrix<N, M, qreal> result; QGenericMatrix<N, M, float> result;
qreal *values = result.data(); float *values = result.data();
for (int matrixCol = 0; matrixCol < N; ++matrixCol) { for (int matrixCol = 0; matrixCol < N; ++matrixCol) {
for (int matrixRow = 0; matrixRow < M; ++matrixRow) { for (int matrixRow = 0; matrixRow < M; ++matrixRow) {
if (matrixCol < 4 && matrixRow < 4) if (matrixCol < 4 && matrixRow < 4)
@ -261,13 +264,13 @@ QGenericMatrix<N, M, qreal> QMatrix4x4::toGenericMatrix() const
return result; return result;
} }
inline const qreal& QMatrix4x4::operator()(int aRow, int aColumn) const inline const float& QMatrix4x4::operator()(int aRow, int aColumn) const
{ {
Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4); Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
return m[aColumn][aRow]; return m[aColumn][aRow];
} }
inline qreal& QMatrix4x4::operator()(int aRow, int aColumn) inline float& QMatrix4x4::operator()(int aRow, int aColumn)
{ {
Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4); Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
flagBits = General; flagBits = General;
@ -308,7 +311,7 @@ inline void QMatrix4x4::setRow(int index, const QVector4D& value)
} }
#endif #endif
Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor); Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor);
inline bool QMatrix4x4::isIdentity() const inline bool QMatrix4x4::isIdentity() const
{ {
@ -348,7 +351,7 @@ inline void QMatrix4x4::setToIdentity()
flagBits = Identity; flagBits = Identity;
} }
inline void QMatrix4x4::fill(qreal value) inline void QMatrix4x4::fill(float value)
{ {
m[0][0] = value; m[0][0] = value;
m[0][1] = value; m[0][1] = value;
@ -428,7 +431,7 @@ inline QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& other)
return *this; return *this;
} }
qreal m0, m1, m2; float m0, m1, m2;
m0 = m[0][0] * other.m[0][0] m0 = m[0][0] * other.m[0][0]
+ m[1][0] * other.m[0][1] + m[1][0] * other.m[0][1]
+ m[2][0] * other.m[0][2] + m[2][0] * other.m[0][2]
@ -511,7 +514,7 @@ inline QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& other)
return *this; return *this;
} }
inline QMatrix4x4& QMatrix4x4::operator*=(qreal factor) inline QMatrix4x4& QMatrix4x4::operator*=(float factor)
{ {
m[0][0] *= factor; m[0][0] *= factor;
m[0][1] *= factor; m[0][1] *= factor;
@ -711,7 +714,7 @@ inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2)
inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix) inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix)
{ {
qreal x, y, z, w; float x, y, z, w;
x = vector.x() * matrix.m[0][0] + x = vector.x() * matrix.m[0][0] +
vector.y() * matrix.m[0][1] + vector.y() * matrix.m[0][1] +
vector.z() * matrix.m[0][2] + vector.z() * matrix.m[0][2] +
@ -736,7 +739,7 @@ inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix)
inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector) inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector)
{ {
qreal x, y, z, w; float x, y, z, w;
if (matrix.flagBits == QMatrix4x4::Identity) { if (matrix.flagBits == QMatrix4x4::Identity) {
return vector; return vector;
} else if (matrix.flagBits < QMatrix4x4::Rotation2D) { } else if (matrix.flagBits < QMatrix4x4::Rotation2D) {
@ -779,7 +782,7 @@ inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector)
inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix) inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix)
{ {
qreal x, y, z, w; float x, y, z, w;
x = vector.x() * matrix.m[0][0] + x = vector.x() * matrix.m[0][0] +
vector.y() * matrix.m[0][1] + vector.y() * matrix.m[0][1] +
vector.z() * matrix.m[0][2] + vector.z() * matrix.m[0][2] +
@ -801,7 +804,7 @@ inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix)
inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector) inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector)
{ {
qreal x, y, z, w; float x, y, z, w;
x = vector.x() * matrix.m[0][0] + x = vector.x() * matrix.m[0][0] +
vector.y() * matrix.m[1][0] + vector.y() * matrix.m[1][0] +
vector.z() * matrix.m[2][0] + vector.z() * matrix.m[2][0] +
@ -825,8 +828,8 @@ inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector)
inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix) inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix)
{ {
qreal xin, yin; float xin, yin;
qreal x, y, w; float x, y, w;
xin = point.x(); xin = point.x();
yin = point.y(); yin = point.y();
x = xin * matrix.m[0][0] + x = xin * matrix.m[0][0] +
@ -846,8 +849,8 @@ inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix)
inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix) inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix)
{ {
qreal xin, yin; float xin, yin;
qreal x, y, w; float x, y, w;
xin = point.x(); xin = point.x();
yin = point.y(); yin = point.y();
x = xin * matrix.m[0][0] + x = xin * matrix.m[0][0] +
@ -860,16 +863,16 @@ inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix)
yin * matrix.m[3][1] + yin * matrix.m[3][1] +
matrix.m[3][3]; matrix.m[3][3];
if (w == 1.0f) { if (w == 1.0f) {
return QPointF(qreal(x), qreal(y)); return QPointF(float(x), float(y));
} else { } else {
return QPointF(qreal(x / w), qreal(y / w)); return QPointF(float(x / w), float(y / w));
} }
} }
inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point) inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point)
{ {
qreal xin, yin; float xin, yin;
qreal x, y, w; float x, y, w;
xin = point.x(); xin = point.x();
yin = point.y(); yin = point.y();
if (matrix.flagBits == QMatrix4x4::Identity) { if (matrix.flagBits == QMatrix4x4::Identity) {
@ -900,8 +903,8 @@ inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point)
inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point) inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point)
{ {
qreal xin, yin; float xin, yin;
qreal x, y, w; float x, y, w;
xin = point.x(); xin = point.x();
yin = point.y(); yin = point.y();
if (matrix.flagBits == QMatrix4x4::Identity) { if (matrix.flagBits == QMatrix4x4::Identity) {
@ -924,9 +927,9 @@ inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point)
yin * matrix.m[1][3] + yin * matrix.m[1][3] +
matrix.m[3][3]; matrix.m[3][3];
if (w == 1.0f) { if (w == 1.0f) {
return QPointF(qreal(x), qreal(y)); return QPointF(float(x), float(y));
} else { } else {
return QPointF(qreal(x / w), qreal(y / w)); return QPointF(float(x / w), float(y / w));
} }
} }
} }
@ -954,7 +957,7 @@ inline QMatrix4x4 operator-(const QMatrix4x4& matrix)
return m; return m;
} }
inline QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix) inline QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix)
{ {
QMatrix4x4 m(1); QMatrix4x4 m(1);
m.m[0][0] = matrix.m[0][0] * factor; m.m[0][0] = matrix.m[0][0] * factor;
@ -977,7 +980,7 @@ inline QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix)
return m; return m;
} }
inline QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor) inline QMatrix4x4 operator*(const QMatrix4x4& matrix, float factor)
{ {
QMatrix4x4 m(1); QMatrix4x4 m(1);
m.m[0][0] = matrix.m[0][0] * factor; m.m[0][0] = matrix.m[0][0] * factor;
@ -1071,7 +1074,7 @@ inline QVector4D QMatrix4x4::map(const QVector4D& point) const
#endif #endif
inline qreal *QMatrix4x4::data() inline float *QMatrix4x4::data()
{ {
// We have to assume that the caller will modify the matrix elements, // We have to assume that the caller will modify the matrix elements,
// so we flip it over to "General" mode. // so we flip it over to "General" mode.
@ -1090,17 +1093,17 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix4x4 &);
#if QT_DEPRECATED_SINCE(5, 0) #if QT_DEPRECATED_SINCE(5, 0)
template <int N, int M> template <int N, int M>
QT_DEPRECATED QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix) QT_DEPRECATED QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, float>& matrix)
{ {
return QMatrix4x4(matrix.constData(), N, M); return QMatrix4x4(matrix.constData(), N, M);
} }
template <int N, int M> template <int N, int M>
QT_DEPRECATED QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) QT_DEPRECATED QGenericMatrix<N, M, float> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)
{ {
QGenericMatrix<N, M, qreal> result; QGenericMatrix<N, M, float> result;
const qreal *m = matrix.constData(); const float *m = matrix.constData();
qreal *values = result.data(); float *values = result.data();
for (int col = 0; col < N; ++col) { for (int col = 0; col < N; ++col) {
for (int row = 0; row < M; ++row) { for (int row = 0; row < M; ++row) {
if (col < 4 && row < 4) if (col < 4 && row < 4)

View File

@ -68,7 +68,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn QQuaternion::QQuaternion(qreal scalar, qreal xpos, qreal ypos, qreal zpos) \fn QQuaternion::QQuaternion(float scalar, float xpos, float ypos, float zpos)
Constructs a quaternion with the vector (\a xpos, \a ypos, \a zpos) Constructs a quaternion with the vector (\a xpos, \a ypos, \a zpos)
and \a scalar. and \a scalar.
@ -77,7 +77,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_VECTOR3D #ifndef QT_NO_VECTOR3D
/*! /*!
\fn QQuaternion::QQuaternion(qreal scalar, const QVector3D& vector) \fn QQuaternion::QQuaternion(float scalar, const QVector3D& vector)
Constructs a quaternion vector from the specified \a vector and Constructs a quaternion vector from the specified \a vector and
\a scalar. \a scalar.
@ -104,7 +104,7 @@ QT_BEGIN_NAMESPACE
#endif #endif
/*! /*!
\fn void QQuaternion::setVector(qreal x, qreal y, qreal z) \fn void QQuaternion::setVector(float x, float y, float z)
Sets the vector component of this quaternion to (\a x, \a y, \a z). Sets the vector component of this quaternion to (\a x, \a y, \a z).
@ -143,7 +143,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn qreal QQuaternion::x() const \fn float QQuaternion::x() const
Returns the x coordinate of this quaternion's vector. Returns the x coordinate of this quaternion's vector.
@ -151,7 +151,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn qreal QQuaternion::y() const \fn float QQuaternion::y() const
Returns the y coordinate of this quaternion's vector. Returns the y coordinate of this quaternion's vector.
@ -159,7 +159,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn qreal QQuaternion::z() const \fn float QQuaternion::z() const
Returns the z coordinate of this quaternion's vector. Returns the z coordinate of this quaternion's vector.
@ -167,7 +167,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn qreal QQuaternion::scalar() const \fn float QQuaternion::scalar() const
Returns the scalar component of this quaternion. Returns the scalar component of this quaternion.
@ -175,7 +175,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn void QQuaternion::setX(qreal x) \fn void QQuaternion::setX(float x)
Sets the x coordinate of this quaternion's vector to the given Sets the x coordinate of this quaternion's vector to the given
\a x coordinate. \a x coordinate.
@ -184,7 +184,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn void QQuaternion::setY(qreal y) \fn void QQuaternion::setY(float y)
Sets the y coordinate of this quaternion's vector to the given Sets the y coordinate of this quaternion's vector to the given
\a y coordinate. \a y coordinate.
@ -193,7 +193,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn void QQuaternion::setZ(qreal z) \fn void QQuaternion::setZ(float z)
Sets the z coordinate of this quaternion's vector to the given Sets the z coordinate of this quaternion's vector to the given
\a z coordinate. \a z coordinate.
@ -202,7 +202,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn void QQuaternion::setScalar(qreal scalar) \fn void QQuaternion::setScalar(float scalar)
Sets the scalar component of this quaternion to \a scalar. Sets the scalar component of this quaternion to \a scalar.
@ -214,7 +214,7 @@ QT_BEGIN_NAMESPACE
\sa lengthSquared(), normalized() \sa lengthSquared(), normalized()
*/ */
qreal QQuaternion::length() const float QQuaternion::length() const
{ {
return qSqrt(xp * xp + yp * yp + zp * zp + wp * wp); return qSqrt(xp * xp + yp * yp + zp * zp + wp * wp);
} }
@ -224,7 +224,7 @@ qreal QQuaternion::length() const
\sa length() \sa length()
*/ */
qreal QQuaternion::lengthSquared() const float QQuaternion::lengthSquared() const
{ {
return xp * xp + yp * yp + zp * zp + wp * wp; return xp * xp + yp * yp + zp * zp + wp * wp;
} }
@ -323,7 +323,7 @@ QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const
*/ */
/*! /*!
\fn QQuaternion &QQuaternion::operator*=(qreal factor) \fn QQuaternion &QQuaternion::operator*=(float factor)
Multiplies this quaternion's components by the given \a factor, and Multiplies this quaternion's components by the given \a factor, and
returns a reference to this quaternion. returns a reference to this quaternion.
@ -339,7 +339,7 @@ QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const
*/ */
/*! /*!
\fn QQuaternion &QQuaternion::operator/=(qreal divisor) \fn QQuaternion &QQuaternion::operator/=(float divisor)
Divides this quaternion's components by the given \a divisor, and Divides this quaternion's components by the given \a divisor, and
returns a reference to this quaternion. returns a reference to this quaternion.
@ -353,15 +353,15 @@ QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const
Creates a normalized quaternion that corresponds to rotating through Creates a normalized quaternion that corresponds to rotating through
\a angle degrees about the specified 3D \a axis. \a angle degrees about the specified 3D \a axis.
*/ */
QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, qreal angle) QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, float angle)
{ {
// Algorithm from: // Algorithm from:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q56 // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q56
// We normalize the result just in case the values are close // We normalize the result just in case the values are close
// to zero, as suggested in the above FAQ. // to zero, as suggested in the above FAQ.
qreal a = (angle / 2.0f) * M_PI / 180.0f; float a = (angle / 2.0f) * M_PI / 180.0f;
qreal s = qSin(a); float s = sinf(a);
qreal c = qCos(a); float c = cosf(a);
QVector3D ax = axis.normalized(); QVector3D ax = axis.normalized();
return QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized(); return QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized();
} }
@ -373,17 +373,17 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, qreal angle)
\a angle degrees about the 3D axis (\a x, \a y, \a z). \a angle degrees about the 3D axis (\a x, \a y, \a z).
*/ */
QQuaternion QQuaternion::fromAxisAndAngle QQuaternion QQuaternion::fromAxisAndAngle
(qreal x, qreal y, qreal z, qreal angle) (float x, float y, float z, float angle)
{ {
qreal length = qSqrt(x * x + y * y + z * z); float length = qSqrt(x * x + y * y + z * z);
if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) { if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) {
x /= length; x /= length;
y /= length; y /= length;
z /= length; z /= length;
} }
qreal a = (angle / 2.0f) * M_PI / 180.0f; float a = (angle / 2.0f) * M_PI / 180.0f;
qreal s = qSin(a); float s = qSin(a);
qreal c = qCos(a); float c = qCos(a);
return QQuaternion(c, x * s, y * s, z * s).normalized(); return QQuaternion(c, x * s, y * s, z * s).normalized();
} }
@ -424,7 +424,7 @@ QQuaternion QQuaternion::fromAxisAndAngle
*/ */
/*! /*!
\fn const QQuaternion operator*(qreal factor, const QQuaternion &quaternion) \fn const QQuaternion operator*(float factor, const QQuaternion &quaternion)
\relates QQuaternion \relates QQuaternion
Returns a copy of the given \a quaternion, multiplied by the Returns a copy of the given \a quaternion, multiplied by the
@ -434,7 +434,7 @@ QQuaternion QQuaternion::fromAxisAndAngle
*/ */
/*! /*!
\fn const QQuaternion operator*(const QQuaternion &quaternion, qreal factor) \fn const QQuaternion operator*(const QQuaternion &quaternion, float factor)
\relates QQuaternion \relates QQuaternion
Returns a copy of the given \a quaternion, multiplied by the Returns a copy of the given \a quaternion, multiplied by the
@ -466,7 +466,7 @@ QQuaternion QQuaternion::fromAxisAndAngle
*/ */
/*! /*!
\fn const QQuaternion operator/(const QQuaternion &quaternion, qreal divisor) \fn const QQuaternion operator/(const QQuaternion &quaternion, float divisor)
\relates QQuaternion \relates QQuaternion
Returns the QQuaternion object formed by dividing all components of Returns the QQuaternion object formed by dividing all components of
@ -495,7 +495,7 @@ QQuaternion QQuaternion::fromAxisAndAngle
\sa nlerp() \sa nlerp()
*/ */
QQuaternion QQuaternion::slerp QQuaternion QQuaternion::slerp
(const QQuaternion& q1, const QQuaternion& q2, qreal t) (const QQuaternion& q1, const QQuaternion& q2, float t)
{ {
// Handle the easy cases first. // Handle the easy cases first.
if (t <= 0.0f) if (t <= 0.0f)
@ -505,7 +505,7 @@ QQuaternion QQuaternion::slerp
// Determine the angle between the two quaternions. // Determine the angle between the two quaternions.
QQuaternion q2b; QQuaternion q2b;
qreal dot; float dot;
dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp;
if (dot >= 0.0f) { if (dot >= 0.0f) {
q2b = q2; q2b = q2;
@ -516,14 +516,14 @@ QQuaternion QQuaternion::slerp
// Get the scale factors. If they are too small, // Get the scale factors. If they are too small,
// then revert to simple linear interpolation. // then revert to simple linear interpolation.
qreal factor1 = 1.0f - t; float factor1 = 1.0f - t;
qreal factor2 = t; float factor2 = t;
if ((1.0f - dot) > 0.0000001) { if ((1.0f - dot) > 0.0000001) {
qreal angle = qreal(qAcos(dot)); float angle = float(qAcos(dot));
qreal sinOfAngle = qreal(qSin(angle)); float sinOfAngle = float(qSin(angle));
if (sinOfAngle > 0.0000001) { if (sinOfAngle > 0.0000001) {
factor1 = qreal(qSin((1.0f - t) * angle)) / sinOfAngle; factor1 = float(qSin((1.0f - t) * angle)) / sinOfAngle;
factor2 = qreal(qSin(t * angle)) / sinOfAngle; factor2 = float(qSin(t * angle)) / sinOfAngle;
} }
} }
@ -547,7 +547,7 @@ QQuaternion QQuaternion::slerp
\sa slerp() \sa slerp()
*/ */
QQuaternion QQuaternion::nlerp QQuaternion QQuaternion::nlerp
(const QQuaternion& q1, const QQuaternion& q2, qreal t) (const QQuaternion& q1, const QQuaternion& q2, float t)
{ {
// Handle the easy cases first. // Handle the easy cases first.
if (t <= 0.0f) if (t <= 0.0f)
@ -557,7 +557,7 @@ QQuaternion QQuaternion::nlerp
// Determine the angle between the two quaternions. // Determine the angle between the two quaternions.
QQuaternion q2b; QQuaternion q2b;
qreal dot; float dot;
dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp;
if (dot >= 0.0f) if (dot >= 0.0f)
q2b = q2; q2b = q2;
@ -602,8 +602,8 @@ QDebug operator<<(QDebug dbg, const QQuaternion &q)
QDataStream &operator<<(QDataStream &stream, const QQuaternion &quaternion) QDataStream &operator<<(QDataStream &stream, const QQuaternion &quaternion)
{ {
stream << double(quaternion.scalar()) << double(quaternion.x()) stream << quaternion.scalar() << quaternion.x()
<< double(quaternion.y()) << double(quaternion.z()); << quaternion.y() << quaternion.z();
return stream; return stream;
} }
@ -619,15 +619,15 @@ QDataStream &operator<<(QDataStream &stream, const QQuaternion &quaternion)
QDataStream &operator>>(QDataStream &stream, QQuaternion &quaternion) QDataStream &operator>>(QDataStream &stream, QQuaternion &quaternion)
{ {
double scalar, x, y, z; float scalar, x, y, z;
stream >> scalar; stream >> scalar;
stream >> x; stream >> x;
stream >> y; stream >> y;
stream >> z; stream >> z;
quaternion.setScalar(qreal(scalar)); quaternion.setScalar(scalar);
quaternion.setX(qreal(x)); quaternion.setX(x);
quaternion.setY(qreal(y)); quaternion.setY(y);
quaternion.setZ(qreal(z)); quaternion.setZ(z);
return stream; return stream;
} }

View File

@ -59,9 +59,9 @@ class Q_GUI_EXPORT QQuaternion
{ {
public: public:
QQuaternion(); QQuaternion();
QQuaternion(qreal scalar, qreal xpos, qreal ypos, qreal zpos); QQuaternion(float scalar, float xpos, float ypos, float zpos);
#ifndef QT_NO_VECTOR3D #ifndef QT_NO_VECTOR3D
QQuaternion(qreal scalar, const QVector3D& vector); QQuaternion(float scalar, const QVector3D& vector);
#endif #endif
#ifndef QT_NO_VECTOR4D #ifndef QT_NO_VECTOR4D
explicit QQuaternion(const QVector4D& vector); explicit QQuaternion(const QVector4D& vector);
@ -74,20 +74,20 @@ public:
QVector3D vector() const; QVector3D vector() const;
void setVector(const QVector3D& vector); void setVector(const QVector3D& vector);
#endif #endif
void setVector(qreal x, qreal y, qreal z); void setVector(float x, float y, float z);
qreal x() const; float x() const;
qreal y() const; float y() const;
qreal z() const; float z() const;
qreal scalar() const; float scalar() const;
void setX(qreal x); void setX(float x);
void setY(qreal y); void setY(float y);
void setZ(qreal z); void setZ(float z);
void setScalar(qreal scalar); void setScalar(float scalar);
qreal length() const; float length() const;
qreal lengthSquared() const; float lengthSquared() const;
QQuaternion normalized() const; QQuaternion normalized() const;
void normalize(); void normalize();
@ -98,19 +98,19 @@ public:
QQuaternion &operator+=(const QQuaternion &quaternion); QQuaternion &operator+=(const QQuaternion &quaternion);
QQuaternion &operator-=(const QQuaternion &quaternion); QQuaternion &operator-=(const QQuaternion &quaternion);
QQuaternion &operator*=(qreal factor); QQuaternion &operator*=(float factor);
QQuaternion &operator*=(const QQuaternion &quaternion); QQuaternion &operator*=(const QQuaternion &quaternion);
QQuaternion &operator/=(qreal divisor); QQuaternion &operator/=(float divisor);
friend inline bool operator==(const QQuaternion &q1, const QQuaternion &q2); friend inline bool operator==(const QQuaternion &q1, const QQuaternion &q2);
friend inline bool operator!=(const QQuaternion &q1, const QQuaternion &q2); friend inline bool operator!=(const QQuaternion &q1, const QQuaternion &q2);
friend inline const QQuaternion operator+(const QQuaternion &q1, const QQuaternion &q2); friend inline const QQuaternion operator+(const QQuaternion &q1, const QQuaternion &q2);
friend inline const QQuaternion operator-(const QQuaternion &q1, const QQuaternion &q2); friend inline const QQuaternion operator-(const QQuaternion &q1, const QQuaternion &q2);
friend inline const QQuaternion operator*(qreal factor, const QQuaternion &quaternion); friend inline const QQuaternion operator*(float factor, const QQuaternion &quaternion);
friend inline const QQuaternion operator*(const QQuaternion &quaternion, qreal factor); friend inline const QQuaternion operator*(const QQuaternion &quaternion, float factor);
friend inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2); friend inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2);
friend inline const QQuaternion operator-(const QQuaternion &quaternion); friend inline const QQuaternion operator-(const QQuaternion &quaternion);
friend inline const QQuaternion operator/(const QQuaternion &quaternion, qreal divisor); friend inline const QQuaternion operator/(const QQuaternion &quaternion, float divisor);
friend inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2); friend inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2);
@ -121,25 +121,25 @@ public:
operator QVariant() const; operator QVariant() const;
#ifndef QT_NO_VECTOR3D #ifndef QT_NO_VECTOR3D
static QQuaternion fromAxisAndAngle(const QVector3D& axis, qreal angle); static QQuaternion fromAxisAndAngle(const QVector3D& axis, float angle);
#endif #endif
static QQuaternion fromAxisAndAngle static QQuaternion fromAxisAndAngle
(qreal x, qreal y, qreal z, qreal angle); (float x, float y, float z, float angle);
static QQuaternion slerp static QQuaternion slerp
(const QQuaternion& q1, const QQuaternion& q2, qreal t); (const QQuaternion& q1, const QQuaternion& q2, float t);
static QQuaternion nlerp static QQuaternion nlerp
(const QQuaternion& q1, const QQuaternion& q2, qreal t); (const QQuaternion& q1, const QQuaternion& q2, float t);
private: private:
qreal wp, xp, yp, zp; float wp, xp, yp, zp;
}; };
Q_DECLARE_TYPEINFO(QQuaternion, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QQuaternion, Q_MOVABLE_TYPE);
inline QQuaternion::QQuaternion() : wp(1.0f), xp(0.0f), yp(0.0f), zp(0.0f) {} inline QQuaternion::QQuaternion() : wp(1.0f), xp(0.0f), yp(0.0f), zp(0.0f) {}
inline QQuaternion::QQuaternion(qreal aScalar, qreal xpos, qreal ypos, qreal zpos) : wp(aScalar), xp(xpos), yp(ypos), zp(zpos) {} inline QQuaternion::QQuaternion(float aScalar, float xpos, float ypos, float zpos) : wp(aScalar), xp(xpos), yp(ypos), zp(zpos) {}
inline bool QQuaternion::isNull() const inline bool QQuaternion::isNull() const
@ -152,15 +152,15 @@ inline bool QQuaternion::isIdentity() const
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && wp == 1.0f; return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && wp == 1.0f;
} }
inline qreal QQuaternion::x() const { return qreal(xp); } inline float QQuaternion::x() const { return xp; }
inline qreal QQuaternion::y() const { return qreal(yp); } inline float QQuaternion::y() const { return yp; }
inline qreal QQuaternion::z() const { return qreal(zp); } inline float QQuaternion::z() const { return zp; }
inline qreal QQuaternion::scalar() const { return qreal(wp); } inline float QQuaternion::scalar() const { return wp; }
inline void QQuaternion::setX(qreal aX) { xp = aX; } inline void QQuaternion::setX(float aX) { xp = aX; }
inline void QQuaternion::setY(qreal aY) { yp = aY; } inline void QQuaternion::setY(float aY) { yp = aY; }
inline void QQuaternion::setZ(qreal aZ) { zp = aZ; } inline void QQuaternion::setZ(float aZ) { zp = aZ; }
inline void QQuaternion::setScalar(qreal aScalar) { wp = aScalar; } inline void QQuaternion::setScalar(float aScalar) { wp = aScalar; }
inline QQuaternion QQuaternion::conjugate() const inline QQuaternion QQuaternion::conjugate() const
{ {
@ -185,7 +185,7 @@ inline QQuaternion &QQuaternion::operator-=(const QQuaternion &quaternion)
return *this; return *this;
} }
inline QQuaternion &QQuaternion::operator*=(qreal factor) inline QQuaternion &QQuaternion::operator*=(float factor)
{ {
xp *= factor; xp *= factor;
yp *= factor; yp *= factor;
@ -196,16 +196,16 @@ inline QQuaternion &QQuaternion::operator*=(qreal factor)
inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2) inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2)
{ {
qreal ww = (q1.zp + q1.xp) * (q2.xp + q2.yp); float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp);
qreal yy = (q1.wp - q1.yp) * (q2.wp + q2.zp); float yy = (q1.wp - q1.yp) * (q2.wp + q2.zp);
qreal zz = (q1.wp + q1.yp) * (q2.wp - q2.zp); float zz = (q1.wp + q1.yp) * (q2.wp - q2.zp);
qreal xx = ww + yy + zz; float xx = ww + yy + zz;
qreal qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp)); float qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp));
qreal w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp); float w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp);
qreal x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp); float x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp);
qreal y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp); float y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp);
qreal z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp); float z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp);
return QQuaternion(w, x, y, z); return QQuaternion(w, x, y, z);
} }
@ -216,7 +216,7 @@ inline QQuaternion &QQuaternion::operator*=(const QQuaternion &quaternion)
return *this; return *this;
} }
inline QQuaternion &QQuaternion::operator/=(qreal divisor) inline QQuaternion &QQuaternion::operator/=(float divisor)
{ {
xp /= divisor; xp /= divisor;
yp /= divisor; yp /= divisor;
@ -245,12 +245,12 @@ inline const QQuaternion operator-(const QQuaternion &q1, const QQuaternion &q2)
return QQuaternion(q1.wp - q2.wp, q1.xp - q2.xp, q1.yp - q2.yp, q1.zp - q2.zp); return QQuaternion(q1.wp - q2.wp, q1.xp - q2.xp, q1.yp - q2.yp, q1.zp - q2.zp);
} }
inline const QQuaternion operator*(qreal factor, const QQuaternion &quaternion) inline const QQuaternion operator*(float factor, const QQuaternion &quaternion)
{ {
return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor); return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor);
} }
inline const QQuaternion operator*(const QQuaternion &quaternion, qreal factor) inline const QQuaternion operator*(const QQuaternion &quaternion, float factor)
{ {
return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor); return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor);
} }
@ -260,7 +260,7 @@ inline const QQuaternion operator-(const QQuaternion &quaternion)
return QQuaternion(-quaternion.wp, -quaternion.xp, -quaternion.yp, -quaternion.zp); return QQuaternion(-quaternion.wp, -quaternion.xp, -quaternion.yp, -quaternion.zp);
} }
inline const QQuaternion operator/(const QQuaternion &quaternion, qreal divisor) inline const QQuaternion operator/(const QQuaternion &quaternion, float divisor)
{ {
return QQuaternion(quaternion.wp / divisor, quaternion.xp / divisor, quaternion.yp / divisor, quaternion.zp / divisor); return QQuaternion(quaternion.wp / divisor, quaternion.xp / divisor, quaternion.yp / divisor, quaternion.zp / divisor);
} }
@ -275,7 +275,7 @@ inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2)
#ifndef QT_NO_VECTOR3D #ifndef QT_NO_VECTOR3D
inline QQuaternion::QQuaternion(qreal aScalar, const QVector3D& aVector) inline QQuaternion::QQuaternion(float aScalar, const QVector3D& aVector)
: wp(aScalar), xp(aVector.x()), yp(aVector.y()), zp(aVector.z()) {} : wp(aScalar), xp(aVector.x()), yp(aVector.y()), zp(aVector.z()) {}
inline void QQuaternion::setVector(const QVector3D& aVector) inline void QQuaternion::setVector(const QVector3D& aVector)
@ -292,7 +292,7 @@ inline QVector3D QQuaternion::vector() const
#endif #endif
inline void QQuaternion::setVector(qreal aX, qreal aY, qreal aZ) inline void QQuaternion::setVector(float aX, float aY, float aZ)
{ {
xp = aX; xp = aX;
yp = aY; yp = aY;

View File

@ -62,11 +62,6 @@ QT_BEGIN_NAMESPACE
The QVector2D class can also be used to represent vertices in 2D space. The QVector2D class can also be used to represent vertices in 2D space.
We therefore do not need to provide a separate vertex class. We therefore do not need to provide a separate vertex class.
\b{Note:} By design values in the QVector2D instance are stored as \c float.
This means that on platforms where the \c qreal arguments to QVector2D
functions are represented by \c double values, it is possible to
lose precision.
\sa QVector3D, QVector4D, QQuaternion \sa QVector3D, QVector4D, QQuaternion
*/ */
@ -77,7 +72,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn QVector2D::QVector2D(qreal xpos, qreal ypos) \fn QVector2D::QVector2D(float xpos, float ypos)
Constructs a vector with coordinates (\a xpos, \a ypos). Constructs a vector with coordinates (\a xpos, \a ypos).
*/ */
@ -134,7 +129,7 @@ QVector2D::QVector2D(const QVector4D& vector)
*/ */
/*! /*!
\fn qreal QVector2D::x() const \fn float QVector2D::x() const
Returns the x coordinate of this point. Returns the x coordinate of this point.
@ -142,7 +137,7 @@ QVector2D::QVector2D(const QVector4D& vector)
*/ */
/*! /*!
\fn qreal QVector2D::y() const \fn float QVector2D::y() const
Returns the y coordinate of this point. Returns the y coordinate of this point.
@ -150,7 +145,7 @@ QVector2D::QVector2D(const QVector4D& vector)
*/ */
/*! /*!
\fn void QVector2D::setX(qreal x) \fn void QVector2D::setX(float x)
Sets the x coordinate of this point to the given \a x coordinate. Sets the x coordinate of this point to the given \a x coordinate.
@ -158,7 +153,7 @@ QVector2D::QVector2D(const QVector4D& vector)
*/ */
/*! /*!
\fn void QVector2D::setY(qreal y) \fn void QVector2D::setY(float y)
Sets the y coordinate of this point to the given \a y coordinate. Sets the y coordinate of this point to the given \a y coordinate.
@ -170,9 +165,12 @@ QVector2D::QVector2D(const QVector4D& vector)
\sa lengthSquared(), normalized() \sa lengthSquared(), normalized()
*/ */
qreal QVector2D::length() const float QVector2D::length() const
{ {
return qSqrt(xp * xp + yp * yp); // Need some extra precision if the length is very small.
double len = double(xp) * double(xp) +
double(yp) * double(yp);
return float(sqrt(len));
} }
/*! /*!
@ -181,7 +179,7 @@ qreal QVector2D::length() const
\sa length(), dotProduct() \sa length(), dotProduct()
*/ */
qreal QVector2D::lengthSquared() const float QVector2D::lengthSquared() const
{ {
return xp * xp + yp * yp; return xp * xp + yp * yp;
} }
@ -200,12 +198,14 @@ QVector2D QVector2D::normalized() const
// Need some extra precision if the length is very small. // Need some extra precision if the length is very small.
double len = double(xp) * double(xp) + double len = double(xp) * double(xp) +
double(yp) * double(yp); double(yp) * double(yp);
if (qFuzzyIsNull(len - 1.0f)) if (qFuzzyIsNull(len - 1.0f)) {
return *this; return *this;
else if (!qFuzzyIsNull(len)) } else if (!qFuzzyIsNull(len)) {
return *this / qSqrt(len); double sqrtLen = sqrt(len);
else return QVector2D(float(double(xp) / sqrtLen), float(double(yp) / sqrtLen));
} else {
return QVector2D(); return QVector2D();
}
} }
/*! /*!
@ -222,10 +222,10 @@ void QVector2D::normalize()
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return; return;
len = qSqrt(len); len = sqrt(len);
xp /= len; xp = float(double(xp) / len);
yp /= len; yp = float(double(yp) / len);
} }
/*! /*!
@ -247,7 +247,7 @@ void QVector2D::normalize()
*/ */
/*! /*!
\fn QVector2D &QVector2D::operator*=(qreal factor) \fn QVector2D &QVector2D::operator*=(float factor)
Multiplies this vector's coordinates by the given \a factor, and Multiplies this vector's coordinates by the given \a factor, and
returns a reference to this vector. returns a reference to this vector.
@ -263,7 +263,7 @@ void QVector2D::normalize()
*/ */
/*! /*!
\fn QVector2D &QVector2D::operator/=(qreal divisor) \fn QVector2D &QVector2D::operator/=(float divisor)
Divides this vector's coordinates by the given \a divisor, and Divides this vector's coordinates by the given \a divisor, and
returns a reference to this vector. returns a reference to this vector.
@ -274,7 +274,7 @@ void QVector2D::normalize()
/*! /*!
Returns the dot product of \a v1 and \a v2. Returns the dot product of \a v1 and \a v2.
*/ */
qreal QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2) float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
{ {
return v1.xp * v2.xp + v1.yp * v2.yp; return v1.xp * v2.xp + v1.yp * v2.yp;
} }
@ -316,7 +316,7 @@ qreal QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
*/ */
/*! /*!
\fn const QVector2D operator*(qreal factor, const QVector2D &vector) \fn const QVector2D operator*(float factor, const QVector2D &vector)
\relates QVector2D \relates QVector2D
Returns a copy of the given \a vector, multiplied by the given \a factor. Returns a copy of the given \a vector, multiplied by the given \a factor.
@ -325,7 +325,7 @@ qreal QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
*/ */
/*! /*!
\fn const QVector2D operator*(const QVector2D &vector, qreal factor) \fn const QVector2D operator*(const QVector2D &vector, float factor)
\relates QVector2D \relates QVector2D
Returns a copy of the given \a vector, multiplied by the given \a factor. Returns a copy of the given \a vector, multiplied by the given \a factor.
@ -353,7 +353,7 @@ qreal QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
*/ */
/*! /*!
\fn const QVector2D operator/(const QVector2D &vector, qreal divisor) \fn const QVector2D operator/(const QVector2D &vector, float divisor)
\relates QVector2D \relates QVector2D
Returns the QVector2D object formed by dividing all three components of Returns the QVector2D object formed by dividing all three components of
@ -379,7 +379,7 @@ qreal QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
*/ */
QVector3D QVector2D::toVector3D() const QVector3D QVector2D::toVector3D() const
{ {
return QVector3D(xp, yp, 0.0f, 1); return QVector3D(xp, yp, 0.0f);
} }
#endif #endif
@ -393,7 +393,7 @@ QVector3D QVector2D::toVector3D() const
*/ */
QVector4D QVector2D::toVector4D() const QVector4D QVector2D::toVector4D() const
{ {
return QVector4D(xp, yp, 0.0f, 0.0f, 1); return QVector4D(xp, yp, 0.0f, 0.0f);
} }
#endif #endif
@ -446,7 +446,7 @@ QDebug operator<<(QDebug dbg, const QVector2D &vector)
QDataStream &operator<<(QDataStream &stream, const QVector2D &vector) QDataStream &operator<<(QDataStream &stream, const QVector2D &vector)
{ {
stream << double(vector.x()) << double(vector.y()); stream << vector.x() << vector.y();
return stream; return stream;
} }
@ -462,11 +462,11 @@ QDataStream &operator<<(QDataStream &stream, const QVector2D &vector)
QDataStream &operator>>(QDataStream &stream, QVector2D &vector) QDataStream &operator>>(QDataStream &stream, QVector2D &vector)
{ {
double x, y; float x, y;
stream >> x; stream >> x;
stream >> y; stream >> y;
vector.setX(qreal(x)); vector.setX(x);
vector.setY(qreal(y)); vector.setY(y);
return stream; return stream;
} }

View File

@ -60,7 +60,7 @@ class Q_GUI_EXPORT QVector2D
{ {
public: public:
QVector2D(); QVector2D();
QVector2D(qreal xpos, qreal ypos); QVector2D(float xpos, float ypos);
explicit QVector2D(const QPoint& point); explicit QVector2D(const QPoint& point);
explicit QVector2D(const QPointF& point); explicit QVector2D(const QPointF& point);
#ifndef QT_NO_VECTOR3D #ifndef QT_NO_VECTOR3D
@ -72,35 +72,35 @@ public:
bool isNull() const; bool isNull() const;
qreal x() const; float x() const;
qreal y() const; float y() const;
void setX(qreal x); void setX(float x);
void setY(qreal y); void setY(float y);
qreal length() const; float length() const;
qreal lengthSquared() const; float lengthSquared() const;
QVector2D normalized() const; QVector2D normalized() const;
void normalize(); void normalize();
QVector2D &operator+=(const QVector2D &vector); QVector2D &operator+=(const QVector2D &vector);
QVector2D &operator-=(const QVector2D &vector); QVector2D &operator-=(const QVector2D &vector);
QVector2D &operator*=(qreal factor); QVector2D &operator*=(float factor);
QVector2D &operator*=(const QVector2D &vector); QVector2D &operator*=(const QVector2D &vector);
QVector2D &operator/=(qreal divisor); QVector2D &operator/=(float divisor);
static qreal dotProduct(const QVector2D& v1, const QVector2D& v2); static float dotProduct(const QVector2D& v1, const QVector2D& v2);
friend inline bool operator==(const QVector2D &v1, const QVector2D &v2); friend inline bool operator==(const QVector2D &v1, const QVector2D &v2);
friend inline bool operator!=(const QVector2D &v1, const QVector2D &v2); friend inline bool operator!=(const QVector2D &v1, const QVector2D &v2);
friend inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2); friend inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2);
friend inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2); friend inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2);
friend inline const QVector2D operator*(qreal factor, const QVector2D &vector); friend inline const QVector2D operator*(float factor, const QVector2D &vector);
friend inline const QVector2D operator*(const QVector2D &vector, qreal factor); friend inline const QVector2D operator*(const QVector2D &vector, float factor);
friend inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2); friend inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2);
friend inline const QVector2D operator-(const QVector2D &vector); friend inline const QVector2D operator-(const QVector2D &vector);
friend inline const QVector2D operator/(const QVector2D &vector, qreal divisor); friend inline const QVector2D operator/(const QVector2D &vector, float divisor);
friend inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2); friend inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2);
@ -119,8 +119,6 @@ public:
private: private:
float xp, yp; float xp, yp;
QVector2D(float xpos, float ypos, int dummy);
friend class QVector3D; friend class QVector3D;
friend class QVector4D; friend class QVector4D;
}; };
@ -129,9 +127,7 @@ Q_DECLARE_TYPEINFO(QVector2D, Q_MOVABLE_TYPE);
inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {} inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {}
inline QVector2D::QVector2D(float xpos, float ypos, int) : xp(xpos), yp(ypos) {} inline QVector2D::QVector2D(float xpos, float ypos) : xp(xpos), yp(ypos) {}
inline QVector2D::QVector2D(qreal xpos, qreal ypos) : xp(xpos), yp(ypos) {}
inline QVector2D::QVector2D(const QPoint& point) : xp(point.x()), yp(point.y()) {} inline QVector2D::QVector2D(const QPoint& point) : xp(point.x()), yp(point.y()) {}
@ -142,11 +138,11 @@ inline bool QVector2D::isNull() const
return qIsNull(xp) && qIsNull(yp); return qIsNull(xp) && qIsNull(yp);
} }
inline qreal QVector2D::x() const { return qreal(xp); } inline float QVector2D::x() const { return xp; }
inline qreal QVector2D::y() const { return qreal(yp); } inline float QVector2D::y() const { return yp; }
inline void QVector2D::setX(qreal aX) { xp = aX; } inline void QVector2D::setX(float aX) { xp = aX; }
inline void QVector2D::setY(qreal aY) { yp = aY; } inline void QVector2D::setY(float aY) { yp = aY; }
inline QVector2D &QVector2D::operator+=(const QVector2D &vector) inline QVector2D &QVector2D::operator+=(const QVector2D &vector)
{ {
@ -162,7 +158,7 @@ inline QVector2D &QVector2D::operator-=(const QVector2D &vector)
return *this; return *this;
} }
inline QVector2D &QVector2D::operator*=(qreal factor) inline QVector2D &QVector2D::operator*=(float factor)
{ {
xp *= factor; xp *= factor;
yp *= factor; yp *= factor;
@ -176,7 +172,7 @@ inline QVector2D &QVector2D::operator*=(const QVector2D &vector)
return *this; return *this;
} }
inline QVector2D &QVector2D::operator/=(qreal divisor) inline QVector2D &QVector2D::operator/=(float divisor)
{ {
xp /= divisor; xp /= divisor;
yp /= divisor; yp /= divisor;
@ -195,37 +191,37 @@ inline bool operator!=(const QVector2D &v1, const QVector2D &v2)
inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2) inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2)
{ {
return QVector2D(v1.xp + v2.xp, v1.yp + v2.yp, 1); return QVector2D(v1.xp + v2.xp, v1.yp + v2.yp);
} }
inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2) inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2)
{ {
return QVector2D(v1.xp - v2.xp, v1.yp - v2.yp, 1); return QVector2D(v1.xp - v2.xp, v1.yp - v2.yp);
} }
inline const QVector2D operator*(qreal factor, const QVector2D &vector) inline const QVector2D operator*(float factor, const QVector2D &vector)
{ {
return QVector2D(vector.xp * factor, vector.yp * factor, 1); return QVector2D(vector.xp * factor, vector.yp * factor);
} }
inline const QVector2D operator*(const QVector2D &vector, qreal factor) inline const QVector2D operator*(const QVector2D &vector, float factor)
{ {
return QVector2D(vector.xp * factor, vector.yp * factor, 1); return QVector2D(vector.xp * factor, vector.yp * factor);
} }
inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2) inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2)
{ {
return QVector2D(v1.xp * v2.xp, v1.yp * v2.yp, 1); return QVector2D(v1.xp * v2.xp, v1.yp * v2.yp);
} }
inline const QVector2D operator-(const QVector2D &vector) inline const QVector2D operator-(const QVector2D &vector)
{ {
return QVector2D(-vector.xp, -vector.yp, 1); return QVector2D(-vector.xp, -vector.yp);
} }
inline const QVector2D operator/(const QVector2D &vector, qreal divisor) inline const QVector2D operator/(const QVector2D &vector, float divisor)
{ {
return QVector2D(vector.xp / divisor, vector.yp / divisor, 1); return QVector2D(vector.xp / divisor, vector.yp / divisor);
} }
inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2) inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2)

View File

@ -65,11 +65,6 @@ QT_BEGIN_NAMESPACE
The QVector3D class can also be used to represent vertices in 3D space. The QVector3D class can also be used to represent vertices in 3D space.
We therefore do not need to provide a separate vertex class. We therefore do not need to provide a separate vertex class.
\b{Note:} By design values in the QVector3D instance are stored as \c float.
This means that on platforms where the \c qreal arguments to QVector3D
functions are represented by \c double values, it is possible to
lose precision.
\sa QVector2D, QVector4D, QQuaternion \sa QVector2D, QVector4D, QQuaternion
*/ */
@ -80,7 +75,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn QVector3D::QVector3D(qreal xpos, qreal ypos, qreal zpos) \fn QVector3D::QVector3D(float xpos, float ypos, float zpos)
Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos). Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos).
*/ */
@ -120,7 +115,7 @@ QVector3D::QVector3D(const QVector2D& vector)
\sa toVector2D() \sa toVector2D()
*/ */
QVector3D::QVector3D(const QVector2D& vector, qreal zpos) QVector3D::QVector3D(const QVector2D& vector, float zpos)
{ {
xp = vector.xp; xp = vector.xp;
yp = vector.yp; yp = vector.yp;
@ -154,7 +149,7 @@ QVector3D::QVector3D(const QVector4D& vector)
*/ */
/*! /*!
\fn qreal QVector3D::x() const \fn float QVector3D::x() const
Returns the x coordinate of this point. Returns the x coordinate of this point.
@ -162,7 +157,7 @@ QVector3D::QVector3D(const QVector4D& vector)
*/ */
/*! /*!
\fn qreal QVector3D::y() const \fn float QVector3D::y() const
Returns the y coordinate of this point. Returns the y coordinate of this point.
@ -170,7 +165,7 @@ QVector3D::QVector3D(const QVector4D& vector)
*/ */
/*! /*!
\fn qreal QVector3D::z() const \fn float QVector3D::z() const
Returns the z coordinate of this point. Returns the z coordinate of this point.
@ -178,7 +173,7 @@ QVector3D::QVector3D(const QVector4D& vector)
*/ */
/*! /*!
\fn void QVector3D::setX(qreal x) \fn void QVector3D::setX(float x)
Sets the x coordinate of this point to the given \a x coordinate. Sets the x coordinate of this point to the given \a x coordinate.
@ -186,7 +181,7 @@ QVector3D::QVector3D(const QVector4D& vector)
*/ */
/*! /*!
\fn void QVector3D::setY(qreal y) \fn void QVector3D::setY(float y)
Sets the y coordinate of this point to the given \a y coordinate. Sets the y coordinate of this point to the given \a y coordinate.
@ -194,7 +189,7 @@ QVector3D::QVector3D(const QVector4D& vector)
*/ */
/*! /*!
\fn void QVector3D::setZ(qreal z) \fn void QVector3D::setZ(float z)
Sets the z coordinate of this point to the given \a z coordinate. Sets the z coordinate of this point to the given \a z coordinate.
@ -216,12 +211,16 @@ QVector3D QVector3D::normalized() const
double len = double(xp) * double(xp) + double len = double(xp) * double(xp) +
double(yp) * double(yp) + double(yp) * double(yp) +
double(zp) * double(zp); double(zp) * double(zp);
if (qFuzzyIsNull(len - 1.0f)) if (qFuzzyIsNull(len - 1.0f)) {
return *this; return *this;
else if (!qFuzzyIsNull(len)) } else if (!qFuzzyIsNull(len)) {
return *this / qSqrt(len); double sqrtLen = sqrt(len);
else return QVector3D(float(double(xp) / sqrtLen),
float(double(yp) / sqrtLen),
float(double(zp) / sqrtLen));
} else {
return QVector3D(); return QVector3D();
}
} }
/*! /*!
@ -239,11 +238,11 @@ void QVector3D::normalize()
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return; return;
len = qSqrt(len); len = sqrt(len);
xp /= len; xp = float(double(xp) / len);
yp /= len; yp = float(double(yp) / len);
zp /= len; zp = float(double(zp) / len);
} }
/*! /*!
@ -265,7 +264,7 @@ void QVector3D::normalize()
*/ */
/*! /*!
\fn QVector3D &QVector3D::operator*=(qreal factor) \fn QVector3D &QVector3D::operator*=(float factor)
Multiplies this vector's coordinates by the given \a factor, and Multiplies this vector's coordinates by the given \a factor, and
returns a reference to this vector. returns a reference to this vector.
@ -287,7 +286,7 @@ void QVector3D::normalize()
*/ */
/*! /*!
\fn QVector3D &QVector3D::operator/=(qreal divisor) \fn QVector3D &QVector3D::operator/=(float divisor)
Divides this vector's coordinates by the given \a divisor, and Divides this vector's coordinates by the given \a divisor, and
returns a reference to this vector. returns a reference to this vector.
@ -298,7 +297,7 @@ void QVector3D::normalize()
/*! /*!
Returns the dot product of \a v1 and \a v2. Returns the dot product of \a v1 and \a v2.
*/ */
qreal QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2) float QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2)
{ {
return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp; return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp;
} }
@ -312,8 +311,8 @@ qreal QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2)
QVector3D QVector3D::crossProduct(const QVector3D& v1, const QVector3D& v2) QVector3D QVector3D::crossProduct(const QVector3D& v1, const QVector3D& v2)
{ {
return QVector3D(v1.yp * v2.zp - v1.zp * v2.yp, return QVector3D(v1.yp * v2.zp - v1.zp * v2.yp,
v1.zp * v2.xp - v1.xp * v2.zp, v1.zp * v2.xp - v1.xp * v2.zp,
v1.xp * v2.yp - v1.yp * v2.xp, 1); v1.xp * v2.yp - v1.yp * v2.xp);
} }
/*! /*!
@ -358,7 +357,7 @@ QVector3D QVector3D::normal
\sa normal(), distanceToLine() \sa normal(), distanceToLine()
*/ */
qreal QVector3D::distanceToPlane float QVector3D::distanceToPlane
(const QVector3D& plane, const QVector3D& normal) const (const QVector3D& plane, const QVector3D& normal) const
{ {
return dotProduct(*this - plane, normal); return dotProduct(*this - plane, normal);
@ -378,7 +377,7 @@ qreal QVector3D::distanceToPlane
\sa normal(), distanceToLine() \sa normal(), distanceToLine()
*/ */
qreal QVector3D::distanceToPlane float QVector3D::distanceToPlane
(const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const (const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const
{ {
QVector3D n = normal(plane2 - plane1, plane3 - plane1); QVector3D n = normal(plane2 - plane1, plane3 - plane1);
@ -394,7 +393,7 @@ qreal QVector3D::distanceToPlane
\sa distanceToPlane() \sa distanceToPlane()
*/ */
qreal QVector3D::distanceToLine float QVector3D::distanceToLine
(const QVector3D& point, const QVector3D& direction) const (const QVector3D& point, const QVector3D& direction) const
{ {
if (direction.isNull()) if (direction.isNull())
@ -440,7 +439,7 @@ qreal QVector3D::distanceToLine
*/ */
/*! /*!
\fn const QVector3D operator*(qreal factor, const QVector3D &vector) \fn const QVector3D operator*(float factor, const QVector3D &vector)
\relates QVector3D \relates QVector3D
Returns a copy of the given \a vector, multiplied by the given \a factor. Returns a copy of the given \a vector, multiplied by the given \a factor.
@ -449,7 +448,7 @@ qreal QVector3D::distanceToLine
*/ */
/*! /*!
\fn const QVector3D operator*(const QVector3D &vector, qreal factor) \fn const QVector3D operator*(const QVector3D &vector, float factor)
\relates QVector3D \relates QVector3D
Returns a copy of the given \a vector, multiplied by the given \a factor. Returns a copy of the given \a vector, multiplied by the given \a factor.
@ -480,7 +479,7 @@ qreal QVector3D::distanceToLine
*/ */
/*! /*!
\fn const QVector3D operator/(const QVector3D &vector, qreal divisor) \fn const QVector3D operator/(const QVector3D &vector, float divisor)
\relates QVector3D \relates QVector3D
Returns the QVector3D object formed by dividing all three components of Returns the QVector3D object formed by dividing all three components of
@ -506,7 +505,7 @@ qreal QVector3D::distanceToLine
*/ */
QVector2D QVector3D::toVector2D() const QVector2D QVector3D::toVector2D() const
{ {
return QVector2D(xp, yp, 1); return QVector2D(xp, yp);
} }
#endif #endif
@ -520,7 +519,7 @@ QVector2D QVector3D::toVector2D() const
*/ */
QVector4D QVector3D::toVector4D() const QVector4D QVector3D::toVector4D() const
{ {
return QVector4D(xp, yp, zp, 0.0f, 1); return QVector4D(xp, yp, zp, 0.0f);
} }
#endif #endif
@ -556,9 +555,13 @@ QVector3D::operator QVariant() const
\sa lengthSquared(), normalized() \sa lengthSquared(), normalized()
*/ */
qreal QVector3D::length() const float QVector3D::length() const
{ {
return qSqrt(xp * xp + yp * yp + zp * zp); // Need some extra precision if the length is very small.
double len = double(xp) * double(xp) +
double(yp) * double(yp) +
double(zp) * double(zp);
return float(sqrt(len));
} }
/*! /*!
@ -567,7 +570,7 @@ qreal QVector3D::length() const
\sa length(), dotProduct() \sa length(), dotProduct()
*/ */
qreal QVector3D::lengthSquared() const float QVector3D::lengthSquared() const
{ {
return xp * xp + yp * yp + zp * zp; return xp * xp + yp * yp + zp * zp;
} }
@ -597,8 +600,7 @@ QDebug operator<<(QDebug dbg, const QVector3D &vector)
QDataStream &operator<<(QDataStream &stream, const QVector3D &vector) QDataStream &operator<<(QDataStream &stream, const QVector3D &vector)
{ {
stream << double(vector.x()) << double(vector.y()) stream << vector.x() << vector.y() << vector.z();
<< double(vector.z());
return stream; return stream;
} }
@ -614,13 +616,13 @@ QDataStream &operator<<(QDataStream &stream, const QVector3D &vector)
QDataStream &operator>>(QDataStream &stream, QVector3D &vector) QDataStream &operator>>(QDataStream &stream, QVector3D &vector)
{ {
double x, y, z; float x, y, z;
stream >> x; stream >> x;
stream >> y; stream >> y;
stream >> z; stream >> z;
vector.setX(qreal(x)); vector.setX(x);
vector.setY(qreal(y)); vector.setY(y);
vector.setZ(qreal(z)); vector.setZ(z);
return stream; return stream;
} }

View File

@ -60,12 +60,12 @@ class Q_GUI_EXPORT QVector3D
{ {
public: public:
QVector3D(); QVector3D();
QVector3D(qreal xpos, qreal ypos, qreal zpos); QVector3D(float xpos, float ypos, float zpos);
explicit QVector3D(const QPoint& point); explicit QVector3D(const QPoint& point);
explicit QVector3D(const QPointF& point); explicit QVector3D(const QPointF& point);
#ifndef QT_NO_VECTOR2D #ifndef QT_NO_VECTOR2D
QVector3D(const QVector2D& vector); QVector3D(const QVector2D& vector);
QVector3D(const QVector2D& vector, qreal zpos); QVector3D(const QVector2D& vector, float zpos);
#endif #endif
#ifndef QT_NO_VECTOR4D #ifndef QT_NO_VECTOR4D
explicit QVector3D(const QVector4D& vector); explicit QVector3D(const QVector4D& vector);
@ -73,45 +73,45 @@ public:
bool isNull() const; bool isNull() const;
qreal x() const; float x() const;
qreal y() const; float y() const;
qreal z() const; float z() const;
void setX(qreal x); void setX(float x);
void setY(qreal y); void setY(float y);
void setZ(qreal z); void setZ(float z);
qreal length() const; float length() const;
qreal lengthSquared() const; float lengthSquared() const;
QVector3D normalized() const; QVector3D normalized() const;
void normalize(); void normalize();
QVector3D &operator+=(const QVector3D &vector); QVector3D &operator+=(const QVector3D &vector);
QVector3D &operator-=(const QVector3D &vector); QVector3D &operator-=(const QVector3D &vector);
QVector3D &operator*=(qreal factor); QVector3D &operator*=(float factor);
QVector3D &operator*=(const QVector3D& vector); QVector3D &operator*=(const QVector3D& vector);
QVector3D &operator/=(qreal divisor); QVector3D &operator/=(float divisor);
static qreal dotProduct(const QVector3D& v1, const QVector3D& v2); static float dotProduct(const QVector3D& v1, const QVector3D& v2);
static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2); static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2);
static QVector3D normal(const QVector3D& v1, const QVector3D& v2); static QVector3D normal(const QVector3D& v1, const QVector3D& v2);
static QVector3D normal static QVector3D normal
(const QVector3D& v1, const QVector3D& v2, const QVector3D& v3); (const QVector3D& v1, const QVector3D& v2, const QVector3D& v3);
qreal distanceToPlane(const QVector3D& plane, const QVector3D& normal) const; float distanceToPlane(const QVector3D& plane, const QVector3D& normal) const;
qreal distanceToPlane(const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const; float distanceToPlane(const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const;
qreal distanceToLine(const QVector3D& point, const QVector3D& direction) const; float distanceToLine(const QVector3D& point, const QVector3D& direction) const;
friend inline bool operator==(const QVector3D &v1, const QVector3D &v2); friend inline bool operator==(const QVector3D &v1, const QVector3D &v2);
friend inline bool operator!=(const QVector3D &v1, const QVector3D &v2); friend inline bool operator!=(const QVector3D &v1, const QVector3D &v2);
friend inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2); friend inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2);
friend inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2); friend inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2);
friend inline const QVector3D operator*(qreal factor, const QVector3D &vector); friend inline const QVector3D operator*(float factor, const QVector3D &vector);
friend inline const QVector3D operator*(const QVector3D &vector, qreal factor); friend inline const QVector3D operator*(const QVector3D &vector, float factor);
friend const QVector3D operator*(const QVector3D &v1, const QVector3D& v2); friend const QVector3D operator*(const QVector3D &v1, const QVector3D& v2);
friend inline const QVector3D operator-(const QVector3D &vector); friend inline const QVector3D operator-(const QVector3D &vector);
friend inline const QVector3D operator/(const QVector3D &vector, qreal divisor); friend inline const QVector3D operator/(const QVector3D &vector, float divisor);
friend inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2); friend inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2);
@ -130,8 +130,6 @@ public:
private: private:
float xp, yp, zp; float xp, yp, zp;
QVector3D(float xpos, float ypos, float zpos, int dummy);
friend class QVector2D; friend class QVector2D;
friend class QVector4D; friend class QVector4D;
#ifndef QT_NO_MATRIX4X4 #ifndef QT_NO_MATRIX4X4
@ -144,9 +142,7 @@ Q_DECLARE_TYPEINFO(QVector3D, Q_MOVABLE_TYPE);
inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {} inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {}
inline QVector3D::QVector3D(qreal xpos, qreal ypos, qreal zpos) : xp(xpos), yp(ypos), zp(zpos) {} inline QVector3D::QVector3D(float xpos, float ypos, float zpos) : xp(xpos), yp(ypos), zp(zpos) {}
inline QVector3D::QVector3D(float xpos, float ypos, float zpos, int) : xp(xpos), yp(ypos), zp(zpos) {}
inline QVector3D::QVector3D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f) {} inline QVector3D::QVector3D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
@ -157,13 +153,13 @@ inline bool QVector3D::isNull() const
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp); return qIsNull(xp) && qIsNull(yp) && qIsNull(zp);
} }
inline qreal QVector3D::x() const { return qreal(xp); } inline float QVector3D::x() const { return xp; }
inline qreal QVector3D::y() const { return qreal(yp); } inline float QVector3D::y() const { return yp; }
inline qreal QVector3D::z() const { return qreal(zp); } inline float QVector3D::z() const { return zp; }
inline void QVector3D::setX(qreal aX) { xp = aX; } inline void QVector3D::setX(float aX) { xp = aX; }
inline void QVector3D::setY(qreal aY) { yp = aY; } inline void QVector3D::setY(float aY) { yp = aY; }
inline void QVector3D::setZ(qreal aZ) { zp = aZ; } inline void QVector3D::setZ(float aZ) { zp = aZ; }
inline QVector3D &QVector3D::operator+=(const QVector3D &vector) inline QVector3D &QVector3D::operator+=(const QVector3D &vector)
{ {
@ -181,7 +177,7 @@ inline QVector3D &QVector3D::operator-=(const QVector3D &vector)
return *this; return *this;
} }
inline QVector3D &QVector3D::operator*=(qreal factor) inline QVector3D &QVector3D::operator*=(float factor)
{ {
xp *= factor; xp *= factor;
yp *= factor; yp *= factor;
@ -197,7 +193,7 @@ inline QVector3D &QVector3D::operator*=(const QVector3D& vector)
return *this; return *this;
} }
inline QVector3D &QVector3D::operator/=(qreal divisor) inline QVector3D &QVector3D::operator/=(float divisor)
{ {
xp /= divisor; xp /= divisor;
yp /= divisor; yp /= divisor;
@ -217,37 +213,37 @@ inline bool operator!=(const QVector3D &v1, const QVector3D &v2)
inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2) inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2)
{ {
return QVector3D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp, 1); return QVector3D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp);
} }
inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2) inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2)
{ {
return QVector3D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp, 1); return QVector3D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp);
} }
inline const QVector3D operator*(qreal factor, const QVector3D &vector) inline const QVector3D operator*(float factor, const QVector3D &vector)
{ {
return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor, 1); return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor);
} }
inline const QVector3D operator*(const QVector3D &vector, qreal factor) inline const QVector3D operator*(const QVector3D &vector, float factor)
{ {
return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor, 1); return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor);
} }
inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2) inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2)
{ {
return QVector3D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp, 1); return QVector3D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp);
} }
inline const QVector3D operator-(const QVector3D &vector) inline const QVector3D operator-(const QVector3D &vector)
{ {
return QVector3D(-vector.xp, -vector.yp, -vector.zp, 1); return QVector3D(-vector.xp, -vector.yp, -vector.zp);
} }
inline const QVector3D operator/(const QVector3D &vector, qreal divisor) inline const QVector3D operator/(const QVector3D &vector, float divisor)
{ {
return QVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, 1); return QVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor);
} }
inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2) inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2)

View File

@ -61,11 +61,6 @@ QT_BEGIN_NAMESPACE
The QVector4D class can also be used to represent vertices in 4D space. The QVector4D class can also be used to represent vertices in 4D space.
We therefore do not need to provide a separate vertex class. We therefore do not need to provide a separate vertex class.
\b{Note:} By design values in the QVector4D instance are stored as \c float.
This means that on platforms where the \c qreal arguments to QVector4D
functions are represented by \c double values, it is possible to
lose precision.
\sa QQuaternion, QVector2D, QVector3D \sa QQuaternion, QVector2D, QVector3D
*/ */
@ -76,7 +71,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn QVector4D::QVector4D(qreal xpos, qreal ypos, qreal zpos, qreal wpos) \fn QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos)
Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos, \a wpos). Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos, \a wpos).
*/ */
@ -117,7 +112,7 @@ QVector4D::QVector4D(const QVector2D& vector)
\sa toVector2D() \sa toVector2D()
*/ */
QVector4D::QVector4D(const QVector2D& vector, qreal zpos, qreal wpos) QVector4D::QVector4D(const QVector2D& vector, float zpos, float wpos)
{ {
xp = vector.xp; xp = vector.xp;
yp = vector.yp; yp = vector.yp;
@ -149,7 +144,7 @@ QVector4D::QVector4D(const QVector3D& vector)
\sa toVector3D() \sa toVector3D()
*/ */
QVector4D::QVector4D(const QVector3D& vector, qreal wpos) QVector4D::QVector4D(const QVector3D& vector, float wpos)
{ {
xp = vector.xp; xp = vector.xp;
yp = vector.yp; yp = vector.yp;
@ -167,7 +162,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
*/ */
/*! /*!
\fn qreal QVector4D::x() const \fn float QVector4D::x() const
Returns the x coordinate of this point. Returns the x coordinate of this point.
@ -175,7 +170,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
*/ */
/*! /*!
\fn qreal QVector4D::y() const \fn float QVector4D::y() const
Returns the y coordinate of this point. Returns the y coordinate of this point.
@ -183,7 +178,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
*/ */
/*! /*!
\fn qreal QVector4D::z() const \fn float QVector4D::z() const
Returns the z coordinate of this point. Returns the z coordinate of this point.
@ -191,7 +186,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
*/ */
/*! /*!
\fn qreal QVector4D::w() const \fn float QVector4D::w() const
Returns the w coordinate of this point. Returns the w coordinate of this point.
@ -199,7 +194,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
*/ */
/*! /*!
\fn void QVector4D::setX(qreal x) \fn void QVector4D::setX(float x)
Sets the x coordinate of this point to the given \a x coordinate. Sets the x coordinate of this point to the given \a x coordinate.
@ -207,7 +202,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
*/ */
/*! /*!
\fn void QVector4D::setY(qreal y) \fn void QVector4D::setY(float y)
Sets the y coordinate of this point to the given \a y coordinate. Sets the y coordinate of this point to the given \a y coordinate.
@ -215,7 +210,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
*/ */
/*! /*!
\fn void QVector4D::setZ(qreal z) \fn void QVector4D::setZ(float z)
Sets the z coordinate of this point to the given \a z coordinate. Sets the z coordinate of this point to the given \a z coordinate.
@ -223,7 +218,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
*/ */
/*! /*!
\fn void QVector4D::setW(qreal w) \fn void QVector4D::setW(float w)
Sets the w coordinate of this point to the given \a w coordinate. Sets the w coordinate of this point to the given \a w coordinate.
@ -235,9 +230,14 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos)
\sa lengthSquared(), normalized() \sa lengthSquared(), normalized()
*/ */
qreal QVector4D::length() const float QVector4D::length() const
{ {
return qSqrt(xp * xp + yp * yp + zp * zp + wp * wp); // Need some extra precision if the length is very small.
double len = double(xp) * double(xp) +
double(yp) * double(yp) +
double(zp) * double(zp) +
double(wp) * double(wp);
return float(sqrt(len));
} }
/*! /*!
@ -246,7 +246,7 @@ qreal QVector4D::length() const
\sa length(), dotProduct() \sa length(), dotProduct()
*/ */
qreal QVector4D::lengthSquared() const float QVector4D::lengthSquared() const
{ {
return xp * xp + yp * yp + zp * zp + wp * wp; return xp * xp + yp * yp + zp * zp + wp * wp;
} }
@ -267,12 +267,17 @@ QVector4D QVector4D::normalized() const
double(yp) * double(yp) + double(yp) * double(yp) +
double(zp) * double(zp) + double(zp) * double(zp) +
double(wp) * double(wp); double(wp) * double(wp);
if (qFuzzyIsNull(len - 1.0f)) if (qFuzzyIsNull(len - 1.0f)) {
return *this; return *this;
else if (!qFuzzyIsNull(len)) } else if (!qFuzzyIsNull(len)) {
return *this / qSqrt(len); double sqrtLen = sqrt(len);
else return QVector4D(float(double(xp) / sqrtLen),
float(double(yp) / sqrtLen),
float(double(zp) / sqrtLen),
float(double(wp) / sqrtLen));
} else {
return QVector4D(); return QVector4D();
}
} }
/*! /*!
@ -291,12 +296,12 @@ void QVector4D::normalize()
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return; return;
len = qSqrt(len); len = sqrt(len);
xp /= len; xp = float(double(xp) / len);
yp /= len; yp = float(double(yp) / len);
zp /= len; zp = float(double(zp) / len);
wp /= len; wp = float(double(wp) / len);
} }
/*! /*!
@ -318,7 +323,7 @@ void QVector4D::normalize()
*/ */
/*! /*!
\fn QVector4D &QVector4D::operator*=(qreal factor) \fn QVector4D &QVector4D::operator*=(float factor)
Multiplies this vector's coordinates by the given \a factor, and Multiplies this vector's coordinates by the given \a factor, and
returns a reference to this vector. returns a reference to this vector.
@ -334,7 +339,7 @@ void QVector4D::normalize()
*/ */
/*! /*!
\fn QVector4D &QVector4D::operator/=(qreal divisor) \fn QVector4D &QVector4D::operator/=(float divisor)
Divides this vector's coordinates by the given \a divisor, and Divides this vector's coordinates by the given \a divisor, and
returns a reference to this vector. returns a reference to this vector.
@ -345,7 +350,7 @@ void QVector4D::normalize()
/*! /*!
Returns the dot product of \a v1 and \a v2. Returns the dot product of \a v1 and \a v2.
*/ */
qreal QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2) float QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
{ {
return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp + v1.wp * v2.wp; return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp + v1.wp * v2.wp;
} }
@ -387,7 +392,7 @@ qreal QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
*/ */
/*! /*!
\fn const QVector4D operator*(qreal factor, const QVector4D &vector) \fn const QVector4D operator*(float factor, const QVector4D &vector)
\relates QVector4D \relates QVector4D
Returns a copy of the given \a vector, multiplied by the given \a factor. Returns a copy of the given \a vector, multiplied by the given \a factor.
@ -396,7 +401,7 @@ qreal QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
*/ */
/*! /*!
\fn const QVector4D operator*(const QVector4D &vector, qreal factor) \fn const QVector4D operator*(const QVector4D &vector, float factor)
\relates QVector4D \relates QVector4D
Returns a copy of the given \a vector, multiplied by the given \a factor. Returns a copy of the given \a vector, multiplied by the given \a factor.
@ -426,7 +431,7 @@ qreal QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
*/ */
/*! /*!
\fn const QVector4D operator/(const QVector4D &vector, qreal divisor) \fn const QVector4D operator/(const QVector4D &vector, float divisor)
\relates QVector4D \relates QVector4D
Returns the QVector4D object formed by dividing all four components of Returns the QVector4D object formed by dividing all four components of
@ -452,7 +457,7 @@ qreal QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
*/ */
QVector2D QVector4D::toVector2D() const QVector2D QVector4D::toVector2D() const
{ {
return QVector2D(xp, yp, 1); return QVector2D(xp, yp);
} }
/*! /*!
@ -466,7 +471,7 @@ QVector2D QVector4D::toVector2DAffine() const
{ {
if (qIsNull(wp)) if (qIsNull(wp))
return QVector2D(); return QVector2D();
return QVector2D(xp / wp, yp / wp, 1); return QVector2D(xp / wp, yp / wp);
} }
#endif #endif
@ -480,7 +485,7 @@ QVector2D QVector4D::toVector2DAffine() const
*/ */
QVector3D QVector4D::toVector3D() const QVector3D QVector4D::toVector3D() const
{ {
return QVector3D(xp, yp, zp, 1); return QVector3D(xp, yp, zp);
} }
/*! /*!
@ -493,7 +498,7 @@ QVector3D QVector4D::toVector3DAffine() const
{ {
if (qIsNull(wp)) if (qIsNull(wp))
return QVector3D(); return QVector3D();
return QVector3D(xp / wp, yp / wp, zp / wp, 1); return QVector3D(xp / wp, yp / wp, zp / wp);
} }
#endif #endif
@ -550,8 +555,8 @@ QDebug operator<<(QDebug dbg, const QVector4D &vector)
QDataStream &operator<<(QDataStream &stream, const QVector4D &vector) QDataStream &operator<<(QDataStream &stream, const QVector4D &vector)
{ {
stream << double(vector.x()) << double(vector.y()) stream << vector.x() << vector.y()
<< double(vector.z()) << double(vector.w()); << vector.z() << vector.w();
return stream; return stream;
} }
@ -567,15 +572,15 @@ QDataStream &operator<<(QDataStream &stream, const QVector4D &vector)
QDataStream &operator>>(QDataStream &stream, QVector4D &vector) QDataStream &operator>>(QDataStream &stream, QVector4D &vector)
{ {
double x, y, z, w; float x, y, z, w;
stream >> x; stream >> x;
stream >> y; stream >> y;
stream >> z; stream >> z;
stream >> w; stream >> w;
vector.setX(qreal(x)); vector.setX(x);
vector.setY(qreal(y)); vector.setY(y);
vector.setZ(qreal(z)); vector.setZ(z);
vector.setW(qreal(w)); vector.setW(w);
return stream; return stream;
} }

View File

@ -60,53 +60,53 @@ class Q_GUI_EXPORT QVector4D
{ {
public: public:
QVector4D(); QVector4D();
QVector4D(qreal xpos, qreal ypos, qreal zpos, qreal wpos); QVector4D(float xpos, float ypos, float zpos, float wpos);
explicit QVector4D(const QPoint& point); explicit QVector4D(const QPoint& point);
explicit QVector4D(const QPointF& point); explicit QVector4D(const QPointF& point);
#ifndef QT_NO_VECTOR2D #ifndef QT_NO_VECTOR2D
QVector4D(const QVector2D& vector); QVector4D(const QVector2D& vector);
QVector4D(const QVector2D& vector, qreal zpos, qreal wpos); QVector4D(const QVector2D& vector, float zpos, float wpos);
#endif #endif
#ifndef QT_NO_VECTOR3D #ifndef QT_NO_VECTOR3D
QVector4D(const QVector3D& vector); QVector4D(const QVector3D& vector);
QVector4D(const QVector3D& vector, qreal wpos); QVector4D(const QVector3D& vector, float wpos);
#endif #endif
bool isNull() const; bool isNull() const;
qreal x() const; float x() const;
qreal y() const; float y() const;
qreal z() const; float z() const;
qreal w() const; float w() const;
void setX(qreal x); void setX(float x);
void setY(qreal y); void setY(float y);
void setZ(qreal z); void setZ(float z);
void setW(qreal w); void setW(float w);
qreal length() const; float length() const;
qreal lengthSquared() const; float lengthSquared() const;
QVector4D normalized() const; QVector4D normalized() const;
void normalize(); void normalize();
QVector4D &operator+=(const QVector4D &vector); QVector4D &operator+=(const QVector4D &vector);
QVector4D &operator-=(const QVector4D &vector); QVector4D &operator-=(const QVector4D &vector);
QVector4D &operator*=(qreal factor); QVector4D &operator*=(float factor);
QVector4D &operator*=(const QVector4D &vector); QVector4D &operator*=(const QVector4D &vector);
QVector4D &operator/=(qreal divisor); QVector4D &operator/=(float divisor);
static qreal dotProduct(const QVector4D& v1, const QVector4D& v2); static float dotProduct(const QVector4D& v1, const QVector4D& v2);
friend inline bool operator==(const QVector4D &v1, const QVector4D &v2); friend inline bool operator==(const QVector4D &v1, const QVector4D &v2);
friend inline bool operator!=(const QVector4D &v1, const QVector4D &v2); friend inline bool operator!=(const QVector4D &v1, const QVector4D &v2);
friend inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2); friend inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2);
friend inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2); friend inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2);
friend inline const QVector4D operator*(qreal factor, const QVector4D &vector); friend inline const QVector4D operator*(float factor, const QVector4D &vector);
friend inline const QVector4D operator*(const QVector4D &vector, qreal factor); friend inline const QVector4D operator*(const QVector4D &vector, float factor);
friend inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2); friend inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2);
friend inline const QVector4D operator-(const QVector4D &vector); friend inline const QVector4D operator-(const QVector4D &vector);
friend inline const QVector4D operator/(const QVector4D &vector, qreal divisor); friend inline const QVector4D operator/(const QVector4D &vector, float divisor);
friend inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2); friend inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2);
@ -127,8 +127,6 @@ public:
private: private:
float xp, yp, zp, wp; float xp, yp, zp, wp;
QVector4D(float xpos, float ypos, float zpos, float wpos, int dummy);
friend class QVector2D; friend class QVector2D;
friend class QVector3D; friend class QVector3D;
#ifndef QT_NO_MATRIX4X4 #ifndef QT_NO_MATRIX4X4
@ -141,9 +139,7 @@ Q_DECLARE_TYPEINFO(QVector4D, Q_MOVABLE_TYPE);
inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {} inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {}
inline QVector4D::QVector4D(qreal xpos, qreal ypos, qreal zpos, qreal wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {} inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {}
inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos, int) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {}
inline QVector4D::QVector4D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {} inline QVector4D::QVector4D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
@ -154,15 +150,15 @@ inline bool QVector4D::isNull() const
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp); return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp);
} }
inline qreal QVector4D::x() const { return qreal(xp); } inline float QVector4D::x() const { return xp; }
inline qreal QVector4D::y() const { return qreal(yp); } inline float QVector4D::y() const { return yp; }
inline qreal QVector4D::z() const { return qreal(zp); } inline float QVector4D::z() const { return zp; }
inline qreal QVector4D::w() const { return qreal(wp); } inline float QVector4D::w() const { return wp; }
inline void QVector4D::setX(qreal aX) { xp = aX; } inline void QVector4D::setX(float aX) { xp = aX; }
inline void QVector4D::setY(qreal aY) { yp = aY; } inline void QVector4D::setY(float aY) { yp = aY; }
inline void QVector4D::setZ(qreal aZ) { zp = aZ; } inline void QVector4D::setZ(float aZ) { zp = aZ; }
inline void QVector4D::setW(qreal aW) { wp = aW; } inline void QVector4D::setW(float aW) { wp = aW; }
inline QVector4D &QVector4D::operator+=(const QVector4D &vector) inline QVector4D &QVector4D::operator+=(const QVector4D &vector)
{ {
@ -182,7 +178,7 @@ inline QVector4D &QVector4D::operator-=(const QVector4D &vector)
return *this; return *this;
} }
inline QVector4D &QVector4D::operator*=(qreal factor) inline QVector4D &QVector4D::operator*=(float factor)
{ {
xp *= factor; xp *= factor;
yp *= factor; yp *= factor;
@ -200,7 +196,7 @@ inline QVector4D &QVector4D::operator*=(const QVector4D &vector)
return *this; return *this;
} }
inline QVector4D &QVector4D::operator/=(qreal divisor) inline QVector4D &QVector4D::operator/=(float divisor)
{ {
xp /= divisor; xp /= divisor;
yp /= divisor; yp /= divisor;
@ -221,37 +217,37 @@ inline bool operator!=(const QVector4D &v1, const QVector4D &v2)
inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2) inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2)
{ {
return QVector4D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp, v1.wp + v2.wp, 1); return QVector4D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp, v1.wp + v2.wp);
} }
inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2) inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2)
{ {
return QVector4D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp, v1.wp - v2.wp, 1); return QVector4D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp, v1.wp - v2.wp);
} }
inline const QVector4D operator*(qreal factor, const QVector4D &vector) inline const QVector4D operator*(float factor, const QVector4D &vector)
{ {
return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor, 1); return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor);
} }
inline const QVector4D operator*(const QVector4D &vector, qreal factor) inline const QVector4D operator*(const QVector4D &vector, float factor)
{ {
return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor, 1); return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor);
} }
inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2) inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2)
{ {
return QVector4D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp, v1.wp * v2.wp, 1); return QVector4D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp, v1.wp * v2.wp);
} }
inline const QVector4D operator-(const QVector4D &vector) inline const QVector4D operator-(const QVector4D &vector)
{ {
return QVector4D(-vector.xp, -vector.yp, -vector.zp, -vector.wp, 1); return QVector4D(-vector.xp, -vector.yp, -vector.zp, -vector.wp);
} }
inline const QVector4D operator/(const QVector4D &vector, qreal divisor) inline const QVector4D operator/(const QVector4D &vector, float divisor)
{ {
return QVector4D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, vector.wp / divisor, 1); return QVector4D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, vector.wp / divisor);
} }
inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2) inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)

View File

@ -2131,35 +2131,6 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QSizeF& size)
setUniformValue(uniformLocation(name), size); setUniformValue(uniformLocation(name), size);
} }
// We have to repack matrices from qreal to GLfloat.
#define setUniformMatrix(func,location,value,cols,rows) \
if (location == -1) \
return; \
if (sizeof(qreal) == sizeof(GLfloat)) { \
func(location, 1, GL_FALSE, \
reinterpret_cast<const GLfloat *>(value.constData())); \
} else { \
GLfloat mat[cols * rows]; \
const qreal *data = value.constData(); \
for (int i = 0; i < cols * rows; ++i) \
mat[i] = data[i]; \
func(location, 1, GL_FALSE, mat); \
}
#define setUniformGenericMatrix(colfunc,location,value,cols,rows) \
if (location == -1) \
return; \
if (sizeof(qreal) == sizeof(GLfloat)) { \
const GLfloat *data = reinterpret_cast<const GLfloat *> \
(value.constData()); \
colfunc(location, cols, data); \
} else { \
GLfloat mat[cols * rows]; \
const qreal *data = value.constData(); \
for (int i = 0; i < cols * rows; ++i) \
mat[i] = data[i]; \
colfunc(location, cols, mat); \
}
/*! /*!
Sets the uniform variable at \a location in the current context Sets the uniform variable at \a location in the current context
to a 2x2 matrix \a value. to a 2x2 matrix \a value.
@ -2170,7 +2141,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformMatrix(d->glfuncs->glUniformMatrix2fv, location, value, 2, 2); d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value.constData());
} }
/*! /*!
@ -2196,8 +2167,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix d->glfuncs->glUniform3fv(location, 2, value.constData());
(d->glfuncs->glUniform3fv, location, value, 2, 3);
} }
/*! /*!
@ -2223,8 +2193,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix d->glfuncs->glUniform4fv(location, 2, value.constData());
(d->glfuncs->glUniform4fv, location, value, 2, 4);
} }
/*! /*!
@ -2250,8 +2219,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix d->glfuncs->glUniform2fv(location, 3, value.constData());
(d->glfuncs->glUniform2fv, location, value, 3, 2);
} }
/*! /*!
@ -2277,7 +2245,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformMatrix(d->glfuncs->glUniformMatrix3fv, location, value, 3, 3); d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value.constData());
} }
/*! /*!
@ -2303,8 +2271,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix d->glfuncs->glUniform4fv(location, 3, value.constData());
(d->glfuncs->glUniform4fv, location, value, 3, 4);
} }
/*! /*!
@ -2330,8 +2297,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix d->glfuncs->glUniform2fv(location, 4, value.constData());
(d->glfuncs->glUniform2fv, location, value, 4, 2);
} }
/*! /*!
@ -2357,8 +2323,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix d->glfuncs->glUniform3fv(location, 4, value.constData());
(d->glfuncs->glUniform3fv, location, value, 4, 3);
} }
/*! /*!
@ -2384,7 +2349,7 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value
{ {
Q_D(QOpenGLShaderProgram); Q_D(QOpenGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformMatrix(d->glfuncs->glUniformMatrix4fv, location, value, 4, 4); d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value.constData());
} }
/*! /*!

View File

@ -2191,58 +2191,6 @@ void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& size)
setUniformValue(uniformLocation(name), size); setUniformValue(uniformLocation(name), size);
} }
// We have to repack matrices from qreal to GLfloat.
#define setUniformMatrix(func,location,value,cols,rows) \
if (location == -1) \
return; \
if (sizeof(qreal) == sizeof(GLfloat)) { \
func(location, 1, GL_FALSE, \
reinterpret_cast<const GLfloat *>(value.constData())); \
} else { \
GLfloat mat[cols * rows]; \
const qreal *data = value.constData(); \
for (int i = 0; i < cols * rows; ++i) \
mat[i] = data[i]; \
func(location, 1, GL_FALSE, mat); \
}
#if !defined(QT_OPENGL_ES_2)
#define setUniformGenericMatrix(func,colfunc,location,value,cols,rows) \
if (location == -1) \
return; \
if (sizeof(qreal) == sizeof(GLfloat)) { \
const GLfloat *data = reinterpret_cast<const GLfloat *> \
(value.constData()); \
if (func) \
func(location, 1, GL_FALSE, data); \
else \
colfunc(location, cols, data); \
} else { \
GLfloat mat[cols * rows]; \
const qreal *data = value.constData(); \
for (int i = 0; i < cols * rows; ++i) \
mat[i] = data[i]; \
if (func) \
func(location, 1, GL_FALSE, mat); \
else \
colfunc(location, cols, mat); \
}
#else
#define setUniformGenericMatrix(func,colfunc,location,value,cols,rows) \
if (location == -1) \
return; \
if (sizeof(qreal) == sizeof(GLfloat)) { \
const GLfloat *data = reinterpret_cast<const GLfloat *> \
(value.constData()); \
colfunc(location, cols, data); \
} else { \
GLfloat mat[cols * rows]; \
const qreal *data = value.constData(); \
for (int i = 0; i < cols * rows; ++i) \
mat[i] = data[i]; \
colfunc(location, cols, mat); \
}
#endif
/*! /*!
Sets the uniform variable at \a location in the current context Sets the uniform variable at \a location in the current context
to a 2x2 matrix \a value. to a 2x2 matrix \a value.
@ -2253,7 +2201,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformMatrix(glUniformMatrix2fv, location, value, 2, 2); glUniformMatrix2fv(location, 1, GL_FALSE, value.constData());
} }
/*! /*!
@ -2279,8 +2227,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix glUniform3fv(location, 2, value.constData());
(glUniformMatrix2x3fv, glUniform3fv, location, value, 2, 3);
} }
/*! /*!
@ -2306,8 +2253,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix glUniform4fv(location, 2, value.constData());
(glUniformMatrix2x4fv, glUniform4fv, location, value, 2, 4);
} }
/*! /*!
@ -2333,8 +2279,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix glUniform2fv(location, 3, value.constData());
(glUniformMatrix3x2fv, glUniform2fv, location, value, 3, 2);
} }
/*! /*!
@ -2360,7 +2305,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformMatrix(glUniformMatrix3fv, location, value, 3, 3); glUniformMatrix3fv(location, 1, GL_FALSE, value.constData());
} }
/*! /*!
@ -2386,8 +2331,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix glUniform4fv(location, 3, value.constData());
(glUniformMatrix3x4fv, glUniform4fv, location, value, 3, 4);
} }
/*! /*!
@ -2413,8 +2357,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix glUniform2fv(location, 4, value.constData());
(glUniformMatrix4x2fv, glUniform2fv, location, value, 4, 2);
} }
/*! /*!
@ -2440,8 +2383,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformGenericMatrix glUniform3fv(location, 4, value.constData());
(glUniformMatrix4x3fv, glUniform3fv, location, value, 4, 3);
} }
/*! /*!
@ -2467,7 +2409,7 @@ void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
{ {
Q_D(QGLShaderProgram); Q_D(QGLShaderProgram);
Q_UNUSED(d); Q_UNUSED(d);
setUniformMatrix(glUniformMatrix4fv, location, value, 4, 4); glUniformMatrix4fv(location, 1, GL_FALSE, value.constData());
} }
/*! /*!

File diff suppressed because it is too large Load Diff

View File

@ -98,113 +98,106 @@ private slots:
void metaTypes(); void metaTypes();
}; };
// QVector3D uses float internally, which can lead to some precision
// issues when using it with the qreal-based QQuaternion.
static bool fuzzyCompare(qreal x, qreal y)
{
return qFuzzyIsNull(float(x - y));
}
// Test the creation of QQuaternion objects in various ways: // Test the creation of QQuaternion objects in various ways:
// construct, copy, and modify. // construct, copy, and modify.
void tst_QQuaternion::create() void tst_QQuaternion::create()
{ {
QQuaternion identity; QQuaternion identity;
QCOMPARE(identity.x(), (qreal)0.0f); QCOMPARE(identity.x(), 0.0f);
QCOMPARE(identity.y(), (qreal)0.0f); QCOMPARE(identity.y(), 0.0f);
QCOMPARE(identity.z(), (qreal)0.0f); QCOMPARE(identity.z(), 0.0f);
QCOMPARE(identity.scalar(), (qreal)1.0f); QCOMPARE(identity.scalar(), 1.0f);
QVERIFY(identity.isIdentity()); QVERIFY(identity.isIdentity());
QQuaternion negativeZeroIdentity(qreal(1.0), qreal(-0.0), qreal(-0.0), qreal(-0.0)); QQuaternion negativeZeroIdentity(1.0f, -0.0f, -0.0f, -0.0f);
QCOMPARE(negativeZeroIdentity.x(), qreal(-0.0)); QCOMPARE(negativeZeroIdentity.x(), -0.0f);
QCOMPARE(negativeZeroIdentity.y(), qreal(-0.0)); QCOMPARE(negativeZeroIdentity.y(), -0.0f);
QCOMPARE(negativeZeroIdentity.z(), qreal(-0.0)); QCOMPARE(negativeZeroIdentity.z(), -0.0f);
QCOMPARE(negativeZeroIdentity.scalar(), qreal(1.0)); QCOMPARE(negativeZeroIdentity.scalar(), 1.0f);
QVERIFY(negativeZeroIdentity.isIdentity()); QVERIFY(negativeZeroIdentity.isIdentity());
QQuaternion v1(34.0f, 1.0f, 2.5f, -89.25f); QQuaternion v1(34.0f, 1.0f, 2.5f, -89.25f);
QCOMPARE(v1.x(), (qreal)1.0f); QCOMPARE(v1.x(), 1.0f);
QCOMPARE(v1.y(), (qreal)2.5f); QCOMPARE(v1.y(), 2.5f);
QCOMPARE(v1.z(), (qreal)-89.25f); QCOMPARE(v1.z(), -89.25f);
QCOMPARE(v1.scalar(), (qreal)34.0f); QCOMPARE(v1.scalar(), 34.0f);
QVERIFY(!v1.isNull()); QVERIFY(!v1.isNull());
QQuaternion v1i(34, 1, 2, -89); QQuaternion v1i(34, 1, 2, -89);
QCOMPARE(v1i.x(), (qreal)1.0f); QCOMPARE(v1i.x(), 1.0f);
QCOMPARE(v1i.y(), (qreal)2.0f); QCOMPARE(v1i.y(), 2.0f);
QCOMPARE(v1i.z(), (qreal)-89.0f); QCOMPARE(v1i.z(), -89.0f);
QCOMPARE(v1i.scalar(), (qreal)34.0f); QCOMPARE(v1i.scalar(), 34.0f);
QVERIFY(!v1i.isNull()); QVERIFY(!v1i.isNull());
QQuaternion v2(v1); QQuaternion v2(v1);
QCOMPARE(v2.x(), (qreal)1.0f); QCOMPARE(v2.x(), 1.0f);
QCOMPARE(v2.y(), (qreal)2.5f); QCOMPARE(v2.y(), 2.5f);
QCOMPARE(v2.z(), (qreal)-89.25f); QCOMPARE(v2.z(), -89.25f);
QCOMPARE(v2.scalar(), (qreal)34.0f); QCOMPARE(v2.scalar(), 34.0f);
QVERIFY(!v2.isNull()); QVERIFY(!v2.isNull());
QQuaternion v4; QQuaternion v4;
QCOMPARE(v4.x(), (qreal)0.0f); QCOMPARE(v4.x(), 0.0f);
QCOMPARE(v4.y(), (qreal)0.0f); QCOMPARE(v4.y(), 0.0f);
QCOMPARE(v4.z(), (qreal)0.0f); QCOMPARE(v4.z(), 0.0f);
QCOMPARE(v4.scalar(), (qreal)1.0f); QCOMPARE(v4.scalar(), 1.0f);
QVERIFY(v4.isIdentity()); QVERIFY(v4.isIdentity());
v4 = v1; v4 = v1;
QCOMPARE(v4.x(), (qreal)1.0f); QCOMPARE(v4.x(), 1.0f);
QCOMPARE(v4.y(), (qreal)2.5f); QCOMPARE(v4.y(), 2.5f);
QCOMPARE(v4.z(), (qreal)-89.25f); QCOMPARE(v4.z(), -89.25f);
QCOMPARE(v4.scalar(), (qreal)34.0f); QCOMPARE(v4.scalar(), 34.0f);
QVERIFY(!v4.isNull()); QVERIFY(!v4.isNull());
QQuaternion v9(34, QVector3D(1.0f, 2.5f, -89.25f)); QQuaternion v9(34, QVector3D(1.0f, 2.5f, -89.25f));
QCOMPARE(v9.x(), (qreal)1.0f); QCOMPARE(v9.x(), 1.0f);
QCOMPARE(v9.y(), (qreal)2.5f); QCOMPARE(v9.y(), 2.5f);
QCOMPARE(v9.z(), (qreal)-89.25f); QCOMPARE(v9.z(), -89.25f);
QCOMPARE(v9.scalar(), (qreal)34.0f); QCOMPARE(v9.scalar(), 34.0f);
QVERIFY(!v9.isNull()); QVERIFY(!v9.isNull());
v1.setX(3.0f); v1.setX(3.0f);
QCOMPARE(v1.x(), (qreal)3.0f); QCOMPARE(v1.x(), 3.0f);
QCOMPARE(v1.y(), (qreal)2.5f); QCOMPARE(v1.y(), 2.5f);
QCOMPARE(v1.z(), (qreal)-89.25f); QCOMPARE(v1.z(), -89.25f);
QCOMPARE(v1.scalar(), (qreal)34.0f); QCOMPARE(v1.scalar(), 34.0f);
QVERIFY(!v1.isNull()); QVERIFY(!v1.isNull());
v1.setY(10.5f); v1.setY(10.5f);
QCOMPARE(v1.x(), (qreal)3.0f); QCOMPARE(v1.x(), 3.0f);
QCOMPARE(v1.y(), (qreal)10.5f); QCOMPARE(v1.y(), 10.5f);
QCOMPARE(v1.z(), (qreal)-89.25f); QCOMPARE(v1.z(), -89.25f);
QCOMPARE(v1.scalar(), (qreal)34.0f); QCOMPARE(v1.scalar(), 34.0f);
QVERIFY(!v1.isNull()); QVERIFY(!v1.isNull());
v1.setZ(15.5f); v1.setZ(15.5f);
QCOMPARE(v1.x(), (qreal)3.0f); QCOMPARE(v1.x(), 3.0f);
QCOMPARE(v1.y(), (qreal)10.5f); QCOMPARE(v1.y(), 10.5f);
QCOMPARE(v1.z(), (qreal)15.5f); QCOMPARE(v1.z(), 15.5f);
QCOMPARE(v1.scalar(), (qreal)34.0f); QCOMPARE(v1.scalar(), 34.0f);
QVERIFY(!v1.isNull()); QVERIFY(!v1.isNull());
v1.setScalar(6.0f); v1.setScalar(6.0f);
QCOMPARE(v1.x(), (qreal)3.0f); QCOMPARE(v1.x(), 3.0f);
QCOMPARE(v1.y(), (qreal)10.5f); QCOMPARE(v1.y(), 10.5f);
QCOMPARE(v1.z(), (qreal)15.5f); QCOMPARE(v1.z(), 15.5f);
QCOMPARE(v1.scalar(), (qreal)6.0f); QCOMPARE(v1.scalar(), 6.0f);
QVERIFY(!v1.isNull()); QVERIFY(!v1.isNull());
v1.setVector(2.0f, 6.5f, -1.25f); v1.setVector(2.0f, 6.5f, -1.25f);
QCOMPARE(v1.x(), (qreal)2.0f); QCOMPARE(v1.x(), 2.0f);
QCOMPARE(v1.y(), (qreal)6.5f); QCOMPARE(v1.y(), 6.5f);
QCOMPARE(v1.z(), (qreal)-1.25f); QCOMPARE(v1.z(), -1.25f);
QCOMPARE(v1.scalar(), (qreal)6.0f); QCOMPARE(v1.scalar(), 6.0f);
QVERIFY(!v1.isNull()); QVERIFY(!v1.isNull());
QVERIFY(v1.vector() == QVector3D(2.0f, 6.5f, -1.25f)); QVERIFY(v1.vector() == QVector3D(2.0f, 6.5f, -1.25f));
v1.setVector(QVector3D(-2.0f, -6.5f, 1.25f)); v1.setVector(QVector3D(-2.0f, -6.5f, 1.25f));
QCOMPARE(v1.x(), (qreal)-2.0f); QCOMPARE(v1.x(), -2.0f);
QCOMPARE(v1.y(), (qreal)-6.5f); QCOMPARE(v1.y(), -6.5f);
QCOMPARE(v1.z(), (qreal)1.25f); QCOMPARE(v1.z(), 1.25f);
QCOMPARE(v1.scalar(), (qreal)6.0f); QCOMPARE(v1.scalar(), 6.0f);
QVERIFY(!v1.isNull()); QVERIFY(!v1.isNull());
QVERIFY(v1.vector() == QVector3D(-2.0f, -6.5f, 1.25f)); QVERIFY(v1.vector() == QVector3D(-2.0f, -6.5f, 1.25f));
@ -212,46 +205,46 @@ void tst_QQuaternion::create()
v1.setY(0.0f); v1.setY(0.0f);
v1.setZ(0.0f); v1.setZ(0.0f);
v1.setScalar(0.0f); v1.setScalar(0.0f);
QCOMPARE(v1.x(), (qreal)0.0f); QCOMPARE(v1.x(), 0.0f);
QCOMPARE(v1.y(), (qreal)0.0f); QCOMPARE(v1.y(), 0.0f);
QCOMPARE(v1.z(), (qreal)0.0f); QCOMPARE(v1.z(), 0.0f);
QCOMPARE(v1.scalar(), (qreal)0.0f); QCOMPARE(v1.scalar(), 0.0f);
QVERIFY(v1.isNull()); QVERIFY(v1.isNull());
QVector4D v10 = v9.toVector4D(); QVector4D v10 = v9.toVector4D();
QCOMPARE(v10.x(), (qreal)1.0f); QCOMPARE(v10.x(), 1.0f);
QCOMPARE(v10.y(), (qreal)2.5f); QCOMPARE(v10.y(), 2.5f);
QCOMPARE(v10.z(), (qreal)-89.25f); QCOMPARE(v10.z(), -89.25f);
QCOMPARE(v10.w(), (qreal)34.0f); QCOMPARE(v10.w(), 34.0f);
} }
// Test length computation for quaternions. // Test length computation for quaternions.
void tst_QQuaternion::length_data() void tst_QQuaternion::length_data()
{ {
QTest::addColumn<qreal>("x"); QTest::addColumn<float>("x");
QTest::addColumn<qreal>("y"); QTest::addColumn<float>("y");
QTest::addColumn<qreal>("z"); QTest::addColumn<float>("z");
QTest::addColumn<qreal>("w"); QTest::addColumn<float>("w");
QTest::addColumn<qreal>("len"); QTest::addColumn<float>("len");
QTest::newRow("null") << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; QTest::newRow("null") << 0.0f << 0.0f << 0.0f << 0.0f << 0.0f;
QTest::newRow("1x") << (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f; QTest::newRow("1x") << 1.0f << 0.0f << 0.0f << 0.0f << 1.0f;
QTest::newRow("1y") << (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f; QTest::newRow("1y") << 0.0f << 1.0f << 0.0f << 0.0f << 1.0f;
QTest::newRow("1z") << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)1.0f; QTest::newRow("1z") << 0.0f << 0.0f << 1.0f << 0.0f << 1.0f;
QTest::newRow("1w") << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << (qreal)1.0f; QTest::newRow("1w") << 0.0f << 0.0f << 0.0f << 1.0f << 1.0f;
QTest::newRow("-1x") << (qreal)-1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f; QTest::newRow("-1x") << -1.0f << 0.0f << 0.0f << 0.0f << 1.0f;
QTest::newRow("-1y") << (qreal)0.0f << (qreal)-1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f; QTest::newRow("-1y") << 0.0f << -1.0f << 0.0f << 0.0f << 1.0f;
QTest::newRow("-1z") << (qreal)0.0f << (qreal)0.0f << (qreal)-1.0f << (qreal)0.0f << (qreal)1.0f; QTest::newRow("-1z") << 0.0f << 0.0f << -1.0f << 0.0f << 1.0f;
QTest::newRow("-1w") << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)-1.0f << (qreal)1.0f; QTest::newRow("-1w") << 0.0f << 0.0f << 0.0f << -1.0f << 1.0f;
QTest::newRow("two") << (qreal)2.0f << (qreal)-2.0f << (qreal)2.0f << (qreal)2.0f << (qreal)qSqrt(16.0f); QTest::newRow("two") << 2.0f << -2.0f << 2.0f << 2.0f << sqrtf(16.0f);
} }
void tst_QQuaternion::length() void tst_QQuaternion::length()
{ {
QFETCH(qreal, x); QFETCH(float, x);
QFETCH(qreal, y); QFETCH(float, y);
QFETCH(qreal, z); QFETCH(float, z);
QFETCH(qreal, w); QFETCH(float, w);
QFETCH(qreal, len); QFETCH(float, len);
QQuaternion v(w, x, y, z); QQuaternion v(w, x, y, z);
QCOMPARE(v.length(), len); QCOMPARE(v.length(), len);
@ -266,18 +259,18 @@ void tst_QQuaternion::normalized_data()
} }
void tst_QQuaternion::normalized() void tst_QQuaternion::normalized()
{ {
QFETCH(qreal, x); QFETCH(float, x);
QFETCH(qreal, y); QFETCH(float, y);
QFETCH(qreal, z); QFETCH(float, z);
QFETCH(qreal, w); QFETCH(float, w);
QFETCH(qreal, len); QFETCH(float, len);
QQuaternion v(w, x, y, z); QQuaternion v(w, x, y, z);
QQuaternion u = v.normalized(); QQuaternion u = v.normalized();
if (v.isNull()) if (v.isNull())
QVERIFY(u.isNull()); QVERIFY(u.isNull());
else else
QCOMPARE(u.length(), qreal(1.0f)); QCOMPARE(u.length(), 1.0f);
QCOMPARE(u.x() * len, v.x()); QCOMPARE(u.x() * len, v.x());
QCOMPARE(u.y() * len, v.y()); QCOMPARE(u.y() * len, v.y());
QCOMPARE(u.z() * len, v.z()); QCOMPARE(u.z() * len, v.z());
@ -292,10 +285,10 @@ void tst_QQuaternion::normalize_data()
} }
void tst_QQuaternion::normalize() void tst_QQuaternion::normalize()
{ {
QFETCH(qreal, x); QFETCH(float, x);
QFETCH(qreal, y); QFETCH(float, y);
QFETCH(qreal, z); QFETCH(float, z);
QFETCH(qreal, w); QFETCH(float, w);
QQuaternion v(w, x, y, z); QQuaternion v(w, x, y, z);
bool isNull = v.isNull(); bool isNull = v.isNull();
@ -303,7 +296,7 @@ void tst_QQuaternion::normalize()
if (isNull) if (isNull)
QVERIFY(v.isNull()); QVERIFY(v.isNull());
else else
QCOMPARE(v.length(), qreal(1.0f)); QCOMPARE(v.length(), 1.0f);
} }
// Test the comparison operators for quaternions. // Test the comparison operators for quaternions.
@ -326,63 +319,63 @@ void tst_QQuaternion::compare()
// Test addition for quaternions. // Test addition for quaternions.
void tst_QQuaternion::add_data() void tst_QQuaternion::add_data()
{ {
QTest::addColumn<qreal>("x1"); QTest::addColumn<float>("x1");
QTest::addColumn<qreal>("y1"); QTest::addColumn<float>("y1");
QTest::addColumn<qreal>("z1"); QTest::addColumn<float>("z1");
QTest::addColumn<qreal>("w1"); QTest::addColumn<float>("w1");
QTest::addColumn<qreal>("x2"); QTest::addColumn<float>("x2");
QTest::addColumn<qreal>("y2"); QTest::addColumn<float>("y2");
QTest::addColumn<qreal>("z2"); QTest::addColumn<float>("z2");
QTest::addColumn<qreal>("w2"); QTest::addColumn<float>("w2");
QTest::addColumn<qreal>("x3"); QTest::addColumn<float>("x3");
QTest::addColumn<qreal>("y3"); QTest::addColumn<float>("y3");
QTest::addColumn<qreal>("z3"); QTest::addColumn<float>("z3");
QTest::addColumn<qreal>("w3"); QTest::addColumn<float>("w3");
QTest::newRow("null") QTest::newRow("null")
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << 0.0f << 0.0f << 0.0f << 0.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << 0.0f << 0.0f << 0.0f << 0.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; << 0.0f << 0.0f << 0.0f << 0.0f;
QTest::newRow("xonly") QTest::newRow("xonly")
<< (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << 1.0f << 0.0f << 0.0f << 0.0f
<< (qreal)2.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << 2.0f << 0.0f << 0.0f << 0.0f
<< (qreal)3.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; << 3.0f << 0.0f << 0.0f << 0.0f;
QTest::newRow("yonly") QTest::newRow("yonly")
<< (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << 0.0f << 1.0f << 0.0f << 0.0f
<< (qreal)0.0f << (qreal)2.0f << (qreal)0.0f << (qreal)0.0f << 0.0f << 2.0f << 0.0f << 0.0f
<< (qreal)0.0f << (qreal)3.0f << (qreal)0.0f << (qreal)0.0f; << 0.0f << 3.0f << 0.0f << 0.0f;
QTest::newRow("zonly") QTest::newRow("zonly")
<< (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << 0.0f << 0.0f << 1.0f << 0.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)2.0f << (qreal)0.0f << 0.0f << 0.0f << 2.0f << 0.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)3.0f << (qreal)0.0f; << 0.0f << 0.0f << 3.0f << 0.0f;
QTest::newRow("wonly") QTest::newRow("wonly")
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << 0.0f << 0.0f << 0.0f << 1.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)2.0f << 0.0f << 0.0f << 0.0f << 2.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)3.0f; << 0.0f << 0.0f << 0.0f << 3.0f;
QTest::newRow("all") QTest::newRow("all")
<< (qreal)1.0f << (qreal)2.0f << (qreal)3.0f << (qreal)8.0f << 1.0f << 2.0f << 3.0f << 8.0f
<< (qreal)4.0f << (qreal)5.0f << (qreal)-6.0f << (qreal)9.0f << 4.0f << 5.0f << -6.0f << 9.0f
<< (qreal)5.0f << (qreal)7.0f << (qreal)-3.0f << (qreal)17.0f; << 5.0f << 7.0f << -3.0f << 17.0f;
} }
void tst_QQuaternion::add() void tst_QQuaternion::add()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, w1); QFETCH(float, w1);
QFETCH(qreal, x2); QFETCH(float, x2);
QFETCH(qreal, y2); QFETCH(float, y2);
QFETCH(qreal, z2); QFETCH(float, z2);
QFETCH(qreal, w2); QFETCH(float, w2);
QFETCH(qreal, x3); QFETCH(float, x3);
QFETCH(qreal, y3); QFETCH(float, y3);
QFETCH(qreal, z3); QFETCH(float, z3);
QFETCH(qreal, w3); QFETCH(float, w3);
QQuaternion v1(w1, x1, y1, z1); QQuaternion v1(w1, x1, y1, z1);
QQuaternion v2(w2, x2, y2, z2); QQuaternion v2(w2, x2, y2, z2);
@ -408,18 +401,18 @@ void tst_QQuaternion::subtract_data()
} }
void tst_QQuaternion::subtract() void tst_QQuaternion::subtract()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, w1); QFETCH(float, w1);
QFETCH(qreal, x2); QFETCH(float, x2);
QFETCH(qreal, y2); QFETCH(float, y2);
QFETCH(qreal, z2); QFETCH(float, z2);
QFETCH(qreal, w2); QFETCH(float, w2);
QFETCH(qreal, x3); QFETCH(float, x3);
QFETCH(qreal, y3); QFETCH(float, y3);
QFETCH(qreal, z3); QFETCH(float, z3);
QFETCH(qreal, w3); QFETCH(float, w3);
QQuaternion v1(w1, x1, y1, z1); QQuaternion v1(w1, x1, y1, z1);
QQuaternion v2(w2, x2, y2, z2); QQuaternion v2(w2, x2, y2, z2);
@ -450,31 +443,31 @@ void tst_QQuaternion::subtract()
// Test quaternion multiplication. // Test quaternion multiplication.
void tst_QQuaternion::multiply_data() void tst_QQuaternion::multiply_data()
{ {
QTest::addColumn<qreal>("x1"); QTest::addColumn<float>("x1");
QTest::addColumn<qreal>("y1"); QTest::addColumn<float>("y1");
QTest::addColumn<qreal>("z1"); QTest::addColumn<float>("z1");
QTest::addColumn<qreal>("w1"); QTest::addColumn<float>("w1");
QTest::addColumn<qreal>("x2"); QTest::addColumn<float>("x2");
QTest::addColumn<qreal>("y2"); QTest::addColumn<float>("y2");
QTest::addColumn<qreal>("z2"); QTest::addColumn<float>("z2");
QTest::addColumn<qreal>("w2"); QTest::addColumn<float>("w2");
QTest::newRow("null") QTest::newRow("null")
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << 0.0f << 0.0f << 0.0f << 0.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; << 0.0f << 0.0f << 0.0f << 0.0f;
QTest::newRow("unitvec") QTest::newRow("unitvec")
<< (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << 1.0f << 0.0f << 0.0f << 1.0f
<< (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)1.0f; << 0.0f << 1.0f << 0.0f << 1.0f;
QTest::newRow("complex") QTest::newRow("complex")
<< (qreal)1.0f << (qreal)2.0f << (qreal)3.0f << (qreal)7.0f << 1.0f << 2.0f << 3.0f << 7.0f
<< (qreal)4.0f << (qreal)5.0f << (qreal)6.0f << (qreal)8.0f; << 4.0f << 5.0f << 6.0f << 8.0f;
for (qreal w = -1.0f; w <= 1.0f; w += 0.5f) for (float w = -1.0f; w <= 1.0f; w += 0.5f)
for (qreal x = -1.0f; x <= 1.0f; x += 0.5f) for (float x = -1.0f; x <= 1.0f; x += 0.5f)
for (qreal y = -1.0f; y <= 1.0f; y += 0.5f) for (float y = -1.0f; y <= 1.0f; y += 0.5f)
for (qreal z = -1.0f; z <= 1.0f; z += 0.5f) { for (float z = -1.0f; z <= 1.0f; z += 0.5f) {
QTest::newRow("exhaustive") QTest::newRow("exhaustive")
<< x << y << z << w << x << y << z << w
<< z << w << y << x; << z << w << y << x;
@ -482,14 +475,14 @@ void tst_QQuaternion::multiply_data()
} }
void tst_QQuaternion::multiply() void tst_QQuaternion::multiply()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, w1); QFETCH(float, w1);
QFETCH(qreal, x2); QFETCH(float, x2);
QFETCH(qreal, y2); QFETCH(float, y2);
QFETCH(qreal, z2); QFETCH(float, z2);
QFETCH(qreal, w2); QFETCH(float, w2);
QQuaternion q1(w1, x1, y1, z1); QQuaternion q1(w1, x1, y1, z1);
QQuaternion q2(w2, x2, y2, z2); QQuaternion q2(w2, x2, y2, z2);
@ -499,7 +492,7 @@ void tst_QQuaternion::multiply()
// to calculate the answer we expect to get. // to calculate the answer we expect to get.
QVector3D v1(x1, y1, z1); QVector3D v1(x1, y1, z1);
QVector3D v2(x2, y2, z2); QVector3D v2(x2, y2, z2);
qreal scalar = w1 * w2 - QVector3D::dotProduct(v1, v2); float scalar = w1 * w2 - QVector3D::dotProduct(v1, v2);
QVector3D vector = w1 * v2 + w2 * v1 + QVector3D::crossProduct(v1, v2); QVector3D vector = w1 * v2 + w2 * v1 + QVector3D::crossProduct(v1, v2);
QQuaternion result(scalar, vector); QQuaternion result(scalar, vector);
@ -509,62 +502,62 @@ void tst_QQuaternion::multiply()
// Test multiplication by a factor for quaternions. // Test multiplication by a factor for quaternions.
void tst_QQuaternion::multiplyFactor_data() void tst_QQuaternion::multiplyFactor_data()
{ {
QTest::addColumn<qreal>("x1"); QTest::addColumn<float>("x1");
QTest::addColumn<qreal>("y1"); QTest::addColumn<float>("y1");
QTest::addColumn<qreal>("z1"); QTest::addColumn<float>("z1");
QTest::addColumn<qreal>("w1"); QTest::addColumn<float>("w1");
QTest::addColumn<qreal>("factor"); QTest::addColumn<float>("factor");
QTest::addColumn<qreal>("x2"); QTest::addColumn<float>("x2");
QTest::addColumn<qreal>("y2"); QTest::addColumn<float>("y2");
QTest::addColumn<qreal>("z2"); QTest::addColumn<float>("z2");
QTest::addColumn<qreal>("w2"); QTest::addColumn<float>("w2");
QTest::newRow("null") QTest::newRow("null")
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << 0.0f << 0.0f << 0.0f << 0.0f
<< (qreal)100.0f << 100.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; << 0.0f << 0.0f << 0.0f << 0.0f;
QTest::newRow("xonly") QTest::newRow("xonly")
<< (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << 1.0f << 0.0f << 0.0f << 0.0f
<< (qreal)2.0f << 2.0f
<< (qreal)2.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; << 2.0f << 0.0f << 0.0f << 0.0f;
QTest::newRow("yonly") QTest::newRow("yonly")
<< (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << 0.0f << 1.0f << 0.0f << 0.0f
<< (qreal)2.0f << 2.0f
<< (qreal)0.0f << (qreal)2.0f << (qreal)0.0f << (qreal)0.0f; << 0.0f << 2.0f << 0.0f << 0.0f;
QTest::newRow("zonly") QTest::newRow("zonly")
<< (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << 0.0f << 0.0f << 1.0f << 0.0f
<< (qreal)2.0f << 2.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)2.0f << (qreal)0.0f; << 0.0f << 0.0f << 2.0f << 0.0f;
QTest::newRow("wonly") QTest::newRow("wonly")
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << 0.0f << 0.0f << 0.0f << 1.0f
<< (qreal)2.0f << 2.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)2.0f; << 0.0f << 0.0f << 0.0f << 2.0f;
QTest::newRow("all") QTest::newRow("all")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)4.0f << 1.0f << 2.0f << -3.0f << 4.0f
<< (qreal)2.0f << 2.0f
<< (qreal)2.0f << (qreal)4.0f << (qreal)-6.0f << (qreal)8.0f; << 2.0f << 4.0f << -6.0f << 8.0f;
QTest::newRow("allzero") QTest::newRow("allzero")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)4.0f << 1.0f << 2.0f << -3.0f << 4.0f
<< (qreal)0.0f << 0.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; << 0.0f << 0.0f << 0.0f << 0.0f;
} }
void tst_QQuaternion::multiplyFactor() void tst_QQuaternion::multiplyFactor()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, w1); QFETCH(float, w1);
QFETCH(qreal, factor); QFETCH(float, factor);
QFETCH(qreal, x2); QFETCH(float, x2);
QFETCH(qreal, y2); QFETCH(float, y2);
QFETCH(qreal, z2); QFETCH(float, z2);
QFETCH(qreal, w2); QFETCH(float, w2);
QQuaternion v1(w1, x1, y1, z1); QQuaternion v1(w1, x1, y1, z1);
QQuaternion v2(w2, x2, y2, z2); QQuaternion v2(w2, x2, y2, z2);
@ -590,20 +583,20 @@ void tst_QQuaternion::divide_data()
} }
void tst_QQuaternion::divide() void tst_QQuaternion::divide()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, w1); QFETCH(float, w1);
QFETCH(qreal, factor); QFETCH(float, factor);
QFETCH(qreal, x2); QFETCH(float, x2);
QFETCH(qreal, y2); QFETCH(float, y2);
QFETCH(qreal, z2); QFETCH(float, z2);
QFETCH(qreal, w2); QFETCH(float, w2);
QQuaternion v1(w1, x1, y1, z1); QQuaternion v1(w1, x1, y1, z1);
QQuaternion v2(w2, x2, y2, z2); QQuaternion v2(w2, x2, y2, z2);
if (factor == (qreal)0.0f) if (factor == 0.0f)
return; return;
QVERIFY((v2 / factor) == v1); QVERIFY((v2 / factor) == v1);
@ -626,10 +619,10 @@ void tst_QQuaternion::negate_data()
} }
void tst_QQuaternion::negate() void tst_QQuaternion::negate()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, w1); QFETCH(float, w1);
QQuaternion v1(w1, x1, y1, z1); QQuaternion v1(w1, x1, y1, z1);
QQuaternion v2(-w1, -x1, -y1, -z1); QQuaternion v2(-w1, -x1, -y1, -z1);
@ -645,10 +638,10 @@ void tst_QQuaternion::conjugate_data()
} }
void tst_QQuaternion::conjugate() void tst_QQuaternion::conjugate()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, w1); QFETCH(float, w1);
QQuaternion v1(w1, x1, y1, z1); QQuaternion v1(w1, x1, y1, z1);
QQuaternion v2(w1, -x1, -y1, -z1); QQuaternion v2(w1, -x1, -y1, -z1);
@ -659,121 +652,121 @@ void tst_QQuaternion::conjugate()
// Test quaternion creation from an axis and an angle. // Test quaternion creation from an axis and an angle.
void tst_QQuaternion::fromAxisAndAngle_data() void tst_QQuaternion::fromAxisAndAngle_data()
{ {
QTest::addColumn<qreal>("x1"); QTest::addColumn<float>("x1");
QTest::addColumn<qreal>("y1"); QTest::addColumn<float>("y1");
QTest::addColumn<qreal>("z1"); QTest::addColumn<float>("z1");
QTest::addColumn<qreal>("angle"); QTest::addColumn<float>("angle");
QTest::newRow("null") QTest::newRow("null")
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; << 0.0f << 0.0f << 0.0f << 0.0f;
QTest::newRow("xonly") QTest::newRow("xonly")
<< (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)90.0f; << 1.0f << 0.0f << 0.0f << 90.0f;
QTest::newRow("yonly") QTest::newRow("yonly")
<< (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)180.0f; << 0.0f << 1.0f << 0.0f << 180.0f;
QTest::newRow("zonly") QTest::newRow("zonly")
<< (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << (qreal)270.0f; << 0.0f << 0.0f << 1.0f << 270.0f;
QTest::newRow("complex") QTest::newRow("complex")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)45.0f; << 1.0f << 2.0f << -3.0f << 45.0f;
} }
void tst_QQuaternion::fromAxisAndAngle() void tst_QQuaternion::fromAxisAndAngle()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, angle); QFETCH(float, angle);
// Use a straight-forward implementation of the algorithm at: // Use a straight-forward implementation of the algorithm at:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q56 // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q56
// to calculate the answer we expect to get. // to calculate the answer we expect to get.
QVector3D vector = QVector3D(x1, y1, z1).normalized(); QVector3D vector = QVector3D(x1, y1, z1).normalized();
qreal sin_a = qSin((angle * M_PI / 180.0) / 2.0); float sin_a = sinf((angle * M_PI / 180.0) / 2.0);
qreal cos_a = qCos((angle * M_PI / 180.0) / 2.0); float cos_a = cosf((angle * M_PI / 180.0) / 2.0);
QQuaternion result((qreal)cos_a, QQuaternion result(cos_a,
(qreal)(vector.x() * sin_a), (vector.x() * sin_a),
(qreal)(vector.y() * sin_a), (vector.y() * sin_a),
(qreal)(vector.z() * sin_a)); (vector.z() * sin_a));
result = result.normalized(); result = result.normalized();
QQuaternion answer = QQuaternion::fromAxisAndAngle(QVector3D(x1, y1, z1), angle); QQuaternion answer = QQuaternion::fromAxisAndAngle(QVector3D(x1, y1, z1), angle);
QVERIFY(fuzzyCompare(answer.x(), result.x())); QVERIFY(qFuzzyCompare(answer.x(), result.x()));
QVERIFY(fuzzyCompare(answer.y(), result.y())); QVERIFY(qFuzzyCompare(answer.y(), result.y()));
QVERIFY(fuzzyCompare(answer.z(), result.z())); QVERIFY(qFuzzyCompare(answer.z(), result.z()));
QVERIFY(fuzzyCompare(answer.scalar(), result.scalar())); QVERIFY(qFuzzyCompare(answer.scalar(), result.scalar()));
answer = QQuaternion::fromAxisAndAngle(x1, y1, z1, angle); answer = QQuaternion::fromAxisAndAngle(x1, y1, z1, angle);
QVERIFY(fuzzyCompare(answer.x(), result.x())); QVERIFY(qFuzzyCompare(answer.x(), result.x()));
QVERIFY(fuzzyCompare(answer.y(), result.y())); QVERIFY(qFuzzyCompare(answer.y(), result.y()));
QVERIFY(fuzzyCompare(answer.z(), result.z())); QVERIFY(qFuzzyCompare(answer.z(), result.z()));
QVERIFY(fuzzyCompare(answer.scalar(), result.scalar())); QVERIFY(qFuzzyCompare(answer.scalar(), result.scalar()));
} }
// Test spherical interpolation of quaternions. // Test spherical interpolation of quaternions.
void tst_QQuaternion::slerp_data() void tst_QQuaternion::slerp_data()
{ {
QTest::addColumn<qreal>("x1"); QTest::addColumn<float>("x1");
QTest::addColumn<qreal>("y1"); QTest::addColumn<float>("y1");
QTest::addColumn<qreal>("z1"); QTest::addColumn<float>("z1");
QTest::addColumn<qreal>("angle1"); QTest::addColumn<float>("angle1");
QTest::addColumn<qreal>("x2"); QTest::addColumn<float>("x2");
QTest::addColumn<qreal>("y2"); QTest::addColumn<float>("y2");
QTest::addColumn<qreal>("z2"); QTest::addColumn<float>("z2");
QTest::addColumn<qreal>("angle2"); QTest::addColumn<float>("angle2");
QTest::addColumn<qreal>("t"); QTest::addColumn<float>("t");
QTest::addColumn<qreal>("x3"); QTest::addColumn<float>("x3");
QTest::addColumn<qreal>("y3"); QTest::addColumn<float>("y3");
QTest::addColumn<qreal>("z3"); QTest::addColumn<float>("z3");
QTest::addColumn<qreal>("angle3"); QTest::addColumn<float>("angle3");
QTest::newRow("first") QTest::newRow("first")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)90.0f << 1.0f << 2.0f << -3.0f << 90.0f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)180.0f << 1.0f << 2.0f << -3.0f << 180.0f
<< (qreal)0.0f << 0.0f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)90.0f; << 1.0f << 2.0f << -3.0f << 90.0f;
QTest::newRow("first2") QTest::newRow("first2")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)90.0f << 1.0f << 2.0f << -3.0f << 90.0f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)180.0f << 1.0f << 2.0f << -3.0f << 180.0f
<< (qreal)-0.5f << -0.5f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)90.0f; << 1.0f << 2.0f << -3.0f << 90.0f;
QTest::newRow("second") QTest::newRow("second")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)90.0f << 1.0f << 2.0f << -3.0f << 90.0f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)180.0f << 1.0f << 2.0f << -3.0f << 180.0f
<< (qreal)1.0f << 1.0f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)180.0f; << 1.0f << 2.0f << -3.0f << 180.0f;
QTest::newRow("second2") QTest::newRow("second2")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)90.0f << 1.0f << 2.0f << -3.0f << 90.0f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)180.0f << 1.0f << 2.0f << -3.0f << 180.0f
<< (qreal)1.5f << 1.5f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)180.0f; << 1.0f << 2.0f << -3.0f << 180.0f;
QTest::newRow("middle") QTest::newRow("middle")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)90.0f << 1.0f << 2.0f << -3.0f << 90.0f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)180.0f << 1.0f << 2.0f << -3.0f << 180.0f
<< (qreal)0.5f << 0.5f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)135.0f; << 1.0f << 2.0f << -3.0f << 135.0f;
QTest::newRow("wide angle") QTest::newRow("wide angle")
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)0.0f << 1.0f << 2.0f << -3.0f << 0.0f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)270.0f << 1.0f << 2.0f << -3.0f << 270.0f
<< (qreal)0.5f << 0.5f
<< (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)-45.0f; << 1.0f << 2.0f << -3.0f << -45.0f;
} }
void tst_QQuaternion::slerp() void tst_QQuaternion::slerp()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, angle1); QFETCH(float, angle1);
QFETCH(qreal, x2); QFETCH(float, x2);
QFETCH(qreal, y2); QFETCH(float, y2);
QFETCH(qreal, z2); QFETCH(float, z2);
QFETCH(qreal, angle2); QFETCH(float, angle2);
QFETCH(qreal, t); QFETCH(float, t);
QFETCH(qreal, x3); QFETCH(float, x3);
QFETCH(qreal, y3); QFETCH(float, y3);
QFETCH(qreal, z3); QFETCH(float, z3);
QFETCH(qreal, angle3); QFETCH(float, angle3);
QQuaternion q1 = QQuaternion::fromAxisAndAngle(x1, y1, z1, angle1); QQuaternion q1 = QQuaternion::fromAxisAndAngle(x1, y1, z1, angle1);
QQuaternion q2 = QQuaternion::fromAxisAndAngle(x2, y2, z2, angle2); QQuaternion q2 = QQuaternion::fromAxisAndAngle(x2, y2, z2, angle2);
@ -781,10 +774,10 @@ void tst_QQuaternion::slerp()
QQuaternion result = QQuaternion::slerp(q1, q2, t); QQuaternion result = QQuaternion::slerp(q1, q2, t);
QVERIFY(fuzzyCompare(result.x(), q3.x())); QVERIFY(qFuzzyCompare(result.x(), q3.x()));
QVERIFY(fuzzyCompare(result.y(), q3.y())); QVERIFY(qFuzzyCompare(result.y(), q3.y()));
QVERIFY(fuzzyCompare(result.z(), q3.z())); QVERIFY(qFuzzyCompare(result.z(), q3.z()));
QVERIFY(fuzzyCompare(result.scalar(), q3.scalar())); QVERIFY(qFuzzyCompare(result.scalar(), q3.scalar()));
} }
// Test normalized linear interpolation of quaternions. // Test normalized linear interpolation of quaternions.
@ -794,22 +787,22 @@ void tst_QQuaternion::nlerp_data()
} }
void tst_QQuaternion::nlerp() void tst_QQuaternion::nlerp()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, angle1); QFETCH(float, angle1);
QFETCH(qreal, x2); QFETCH(float, x2);
QFETCH(qreal, y2); QFETCH(float, y2);
QFETCH(qreal, z2); QFETCH(float, z2);
QFETCH(qreal, angle2); QFETCH(float, angle2);
QFETCH(qreal, t); QFETCH(float, t);
QQuaternion q1 = QQuaternion::fromAxisAndAngle(x1, y1, z1, angle1); QQuaternion q1 = QQuaternion::fromAxisAndAngle(x1, y1, z1, angle1);
QQuaternion q2 = QQuaternion::fromAxisAndAngle(x2, y2, z2, angle2); QQuaternion q2 = QQuaternion::fromAxisAndAngle(x2, y2, z2, angle2);
QQuaternion result = QQuaternion::nlerp(q1, q2, t); QQuaternion result = QQuaternion::nlerp(q1, q2, t);
qreal resultx, resulty, resultz, resultscalar; float resultx, resulty, resultz, resultscalar;
if (t <= 0.0f) { if (t <= 0.0f) {
resultx = q1.x(); resultx = q1.x();
resulty = q1.y(); resulty = q1.y();
@ -835,10 +828,10 @@ void tst_QQuaternion::nlerp()
QQuaternion q3 = QQuaternion(resultscalar, resultx, resulty, resultz).normalized(); QQuaternion q3 = QQuaternion(resultscalar, resultx, resulty, resultz).normalized();
QVERIFY(fuzzyCompare(result.x(), q3.x())); QVERIFY(qFuzzyCompare(result.x(), q3.x()));
QVERIFY(fuzzyCompare(result.y(), q3.y())); QVERIFY(qFuzzyCompare(result.y(), q3.y()));
QVERIFY(fuzzyCompare(result.z(), q3.z())); QVERIFY(qFuzzyCompare(result.z(), q3.z()));
QVERIFY(fuzzyCompare(result.scalar(), q3.scalar())); QVERIFY(qFuzzyCompare(result.scalar(), q3.scalar()));
} }
class tst_QQuaternionProperties : public QObject class tst_QQuaternionProperties : public QObject
@ -863,19 +856,19 @@ void tst_QQuaternion::properties()
obj.setQuaternion(QQuaternion(6.0f, 7.0f, 8.0f, 9.0f)); obj.setQuaternion(QQuaternion(6.0f, 7.0f, 8.0f, 9.0f));
QQuaternion q = qvariant_cast<QQuaternion>(obj.property("quaternion")); QQuaternion q = qvariant_cast<QQuaternion>(obj.property("quaternion"));
QCOMPARE(q.scalar(), (qreal)6.0f); QCOMPARE(q.scalar(), 6.0f);
QCOMPARE(q.x(), (qreal)7.0f); QCOMPARE(q.x(), 7.0f);
QCOMPARE(q.y(), (qreal)8.0f); QCOMPARE(q.y(), 8.0f);
QCOMPARE(q.z(), (qreal)9.0f); QCOMPARE(q.z(), 9.0f);
obj.setProperty("quaternion", obj.setProperty("quaternion",
QVariant::fromValue(QQuaternion(-6.0f, -7.0f, -8.0f, -9.0f))); QVariant::fromValue(QQuaternion(-6.0f, -7.0f, -8.0f, -9.0f)));
q = qvariant_cast<QQuaternion>(obj.property("quaternion")); q = qvariant_cast<QQuaternion>(obj.property("quaternion"));
QCOMPARE(q.scalar(), (qreal)-6.0f); QCOMPARE(q.scalar(), -6.0f);
QCOMPARE(q.x(), (qreal)-7.0f); QCOMPARE(q.x(), -7.0f);
QCOMPARE(q.y(), (qreal)-8.0f); QCOMPARE(q.y(), -8.0f);
QCOMPARE(q.z(), (qreal)-9.0f); QCOMPARE(q.z(), -9.0f);
} }
void tst_QQuaternion::metaTypes() void tst_QQuaternion::metaTypes()

File diff suppressed because it is too large Load Diff

View File

@ -4,5 +4,4 @@ QT += widgets testlib
SOURCES += tst_qgraphicstransform.cpp SOURCES += tst_qgraphicstransform.cpp
CONFIG += parallel_test CONFIG += parallel_test
linux-*:contains(QT_CONFIG,release):DEFINES+=MAY_HIT_QTBUG_20661
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0

View File

@ -156,31 +156,39 @@ void tst_QGraphicsTransform::scale()
QCOMPARE(t3.map(QPointF(4, 5)), QPointF(31 / t3.m33(), 8 / t3.m33())); QCOMPARE(t3.map(QPointF(4, 5)), QPointF(31 / t3.m33(), 8 / t3.m33()));
} }
// QMatrix4x4 uses float internally, whereas QTransform uses qreal. // fuzzyCompareNonZero is a very slightly looser version of qFuzzyCompare
// This can lead to issues with qFuzzyCompare() where it uses double // for use with values that are not very close to zero
// precision to compare values that have no more than float precision Q_DECL_CONSTEXPR static inline bool fuzzyCompareNonZero(float p1, float p2)
// after conversion from QMatrix4x4 to QTransform. The following
// definitions correct for the difference.
static inline bool fuzzyCompare(qreal p1, qreal p2)
{ {
// increase delta on small machines using float instead of double return (qAbs(p1 - p2) <= 0.00003f * qMin(qAbs(p1), qAbs(p2)));
if (sizeof(qreal) == sizeof(float))
return (qAbs(p1 - p2) <= 0.00003f * qMin(qAbs(p1), qAbs(p2)));
else
return (qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2)));
} }
static bool fuzzyCompare(const QTransform& t1, const QTransform& t2) // This is a more tolerant version of qFuzzyCompare that also handles the case
// where one or more of the values being compare are close to zero
static inline bool fuzzyCompare(float p1, float p2)
{ {
return fuzzyCompare(t1.m11(), t2.m11()) && if (qFuzzyIsNull(p1))
fuzzyCompare(t1.m12(), t2.m12()) && return qFuzzyIsNull(p2);
fuzzyCompare(t1.m13(), t2.m13()) && else if (qFuzzyIsNull(p2))
fuzzyCompare(t1.m21(), t2.m21()) && return false;
fuzzyCompare(t1.m22(), t2.m22()) && else
fuzzyCompare(t1.m23(), t2.m23()) && return fuzzyCompareNonZero(p1, p2);
fuzzyCompare(t1.m31(), t2.m31()) && }
fuzzyCompare(t1.m32(), t2.m32()) &&
fuzzyCompare(t1.m33(), t2.m33()); // This compares two QTransforms by casting the elements to float. This is
// necessary here because in this test one of the transforms is created from
// a QMatrix4x4 which uses float storage.
static bool fuzzyCompareAsFloat(const QTransform& t1, const QTransform& t2)
{
return fuzzyCompare(float(t1.m11()), float(t2.m11())) &&
fuzzyCompare(float(t1.m12()), float(t2.m12())) &&
fuzzyCompare(float(t1.m13()), float(t2.m13())) &&
fuzzyCompare(float(t1.m21()), float(t2.m21())) &&
fuzzyCompare(float(t1.m22()), float(t2.m22())) &&
fuzzyCompare(float(t1.m23()), float(t2.m23())) &&
fuzzyCompare(float(t1.m31()), float(t2.m31())) &&
fuzzyCompare(float(t1.m32()), float(t2.m32())) &&
fuzzyCompare(float(t1.m33()), float(t2.m33()));
} }
static inline bool fuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2) static inline bool fuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2)
@ -221,7 +229,7 @@ void tst_QGraphicsTransform::rotation()
QTransform res; QTransform res;
res.rotate(40); res.rotate(40);
QVERIFY(fuzzyCompare(transform2D(rotation), res)); QVERIFY(fuzzyCompareAsFloat(transform2D(rotation), res));
rotation.setOrigin(QVector3D(10, 10, 0)); rotation.setOrigin(QVector3D(10, 10, 0));
rotation.setAngle(90); rotation.setAngle(90);
@ -271,20 +279,14 @@ void tst_QGraphicsTransform::rotation3d()
else else
expected.rotate(angle, axis); expected.rotate(angle, axis);
QVERIFY(fuzzyCompare(transform2D(rotation), expected)); QVERIFY(fuzzyCompareAsFloat(transform2D(rotation), expected));
// Check that "rotation" produces the 4x4 form of the 3x3 matrix. // Check that "rotation" produces the 4x4 form of the 3x3 matrix.
// i.e. third row and column are 0 0 1 0. // i.e. third row and column are 0 0 1 0.
t.setToIdentity(); t.setToIdentity();
rotation.applyTo(&t); rotation.applyTo(&t);
QMatrix4x4 r(expected); QMatrix4x4 r(expected);
if (sizeof(qreal) == sizeof(float) && angle == 268) { QVERIFY(fuzzyCompare(t, r));
// This test fails, on only this angle, when qreal == float
// because the deg2rad value in QTransform is not accurate
// enough to match what QMatrix4x4 is doing.
} else {
QVERIFY(fuzzyCompare(t, r));
}
//now let's check that a null vector will not change the transform //now let's check that a null vector will not change the transform
rotation.setAxis(QVector3D(0, 0, 0)); rotation.setAxis(QVector3D(0, 0, 0));
@ -358,21 +360,8 @@ void tst_QGraphicsTransform::rotation3dArbitraryAxis()
exp.rotate(angle, axis); exp.rotate(angle, axis);
QTransform expected = exp.toTransform(1024.0f); QTransform expected = exp.toTransform(1024.0f);
#if defined(MAY_HIT_QTBUG_20661)
// These failures possibly relate to the float vs qreal issue mentioned
// in the comment above fuzzyCompare().
if (sizeof(qreal) == sizeof(double)) {
QEXPECT_FAIL("rotation of 120 on (1, 1, 1)", "QTBUG-20661", Abort);
QEXPECT_FAIL("rotation of 240 on (1, 1, 1)", "QTBUG-20661", Abort);
QEXPECT_FAIL("rotation of 120 on (0.01, 0.01, 0.01)", "QTBUG-20661", Abort);
QEXPECT_FAIL("rotation of 240 on (0.01, 0.01, 0.01)", "QTBUG-20661", Abort);
QEXPECT_FAIL("rotation of 120 on (0.0001, 0.0001, 0.0001)", "QTBUG-20661", Abort);
QEXPECT_FAIL("rotation of 240 on (0.0001, 0.0001, 0.0001)", "QTBUG-20661", Abort);
}
#endif
QTransform actual = transform2D(rotation); QTransform actual = transform2D(rotation);
QVERIFY2(fuzzyCompare(actual, expected), qPrintable( QVERIFY2(fuzzyCompareAsFloat(actual, expected), qPrintable(
QString("\nactual: %1\n" QString("\nactual: %1\n"
"expected: %2") "expected: %2")
.arg(toString(actual)) .arg(toString(actual))
@ -384,7 +373,13 @@ void tst_QGraphicsTransform::rotation3dArbitraryAxis()
t.setToIdentity(); t.setToIdentity();
rotation.applyTo(&t); rotation.applyTo(&t);
QMatrix4x4 r(expected); QMatrix4x4 r(expected);
QVERIFY(qFuzzyCompare(t, r)); for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
float a = t(row, col);
float b = r(row, col);
QVERIFY2(fuzzyCompare(a, b), QString("%1 is not equal to %2").arg(a).arg(b).toLatin1());
}
}
} }
QString tst_QGraphicsTransform::toString(QTransform const& t) QString tst_QGraphicsTransform::toString(QTransform const& t)

View File

@ -96,7 +96,7 @@ private slots:
void compareRotateAfterScale(); void compareRotateAfterScale();
}; };
static qreal const generalValues[16] = static float const generalValues[16] =
{1.0f, 2.0f, 3.0f, 4.0f, {1.0f, 2.0f, 3.0f, 4.0f,
5.0f, 6.0f, 7.0f, 8.0f, 5.0f, 6.0f, 7.0f, 8.0f,
9.0f, 10.0f, 11.0f, 12.0f, 9.0f, 10.0f, 11.0f, 12.0f,
@ -171,9 +171,9 @@ void tst_QMatrix4x4::multiplyDirect()
QMatrix4x4 m3; QMatrix4x4 m3;
const qreal *m1data = m1.constData(); const float *m1data = m1.constData();
const qreal *m2data = m2.constData(); const float *m2data = m2.constData();
qreal *m3data = m3.data(); float *m3data = m3.data();
QBENCHMARK { QBENCHMARK {
for (int row = 0; row < 4; ++row) { for (int row = 0; row < 4; ++row) {
@ -266,9 +266,9 @@ void tst_QMatrix4x4::mapVectorDirect()
{ {
QFETCH(QMatrix4x4, m1); QFETCH(QMatrix4x4, m1);
const qreal *m1data = m1.constData(); const float *m1data = m1.constData();
qreal v[4] = {10.5f, -2.0f, 3.0f, 1.0f}; float v[4] = {10.5f, -2.0f, 3.0f, 1.0f};
qreal result[4]; float result[4];
QBENCHMARK { QBENCHMARK {
for (int row = 0; row < 4; ++row) { for (int row = 0; row < 4; ++row) {
@ -310,9 +310,9 @@ void tst_QMatrix4x4::compareTranslate()
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(QVector3D, translation); QFETCH(QVector3D, translation);
qreal x = translation.x(); float x = translation.x();
qreal y = translation.y(); float y = translation.y();
qreal z = translation.z(); float z = translation.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;
@ -343,9 +343,9 @@ void tst_QMatrix4x4::compareTranslateAfterScale()
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(QVector3D, translation); QFETCH(QVector3D, translation);
qreal x = translation.x(); float x = translation.x();
qreal y = translation.y(); float y = translation.y();
qreal z = translation.z(); float z = translation.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;
@ -379,9 +379,9 @@ void tst_QMatrix4x4::compareTranslateAfterRotate()
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(QVector3D, translation); QFETCH(QVector3D, translation);
qreal x = translation.x(); float x = translation.x();
qreal y = translation.y(); float y = translation.y();
qreal z = translation.z(); float z = translation.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;
@ -431,9 +431,9 @@ void tst_QMatrix4x4::compareScale()
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(QVector3D, scale); QFETCH(QVector3D, scale);
qreal x = scale.x(); float x = scale.x();
qreal y = scale.y(); float y = scale.y();
qreal z = scale.z(); float z = scale.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;
@ -464,9 +464,9 @@ void tst_QMatrix4x4::compareScaleAfterTranslate()
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(QVector3D, scale); QFETCH(QVector3D, scale);
qreal x = scale.x(); float x = scale.x();
qreal y = scale.y(); float y = scale.y();
qreal z = scale.z(); float z = scale.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;
@ -500,9 +500,9 @@ void tst_QMatrix4x4::compareScaleAfterRotate()
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(QVector3D, scale); QFETCH(QVector3D, scale);
qreal x = scale.x(); float x = scale.x();
qreal y = scale.y(); float y = scale.y();
qreal z = scale.z(); float z = scale.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;
@ -530,65 +530,65 @@ void tst_QMatrix4x4::compareScaleAfterRotate()
void tst_QMatrix4x4::compareRotate_data() void tst_QMatrix4x4::compareRotate_data()
{ {
QTest::addColumn<bool>("useQTransform"); QTest::addColumn<bool>("useQTransform");
QTest::addColumn<qreal>("angle"); QTest::addColumn<float>("angle");
QTest::addColumn<QVector3D>("rotation"); QTest::addColumn<QVector3D>("rotation");
QTest::addColumn<int>("axis"); QTest::addColumn<int>("axis");
QTest::newRow("QTransform::rotate(0, ZAxis)") QTest::newRow("QTransform::rotate(0, ZAxis)")
<< true << qreal(0.0f) << QVector3D(0, 0, 1) << int(Qt::ZAxis); << true << 0.0f << QVector3D(0, 0, 1) << int(Qt::ZAxis);
QTest::newRow("QMatrix4x4::rotate(0, ZAxis)") QTest::newRow("QMatrix4x4::rotate(0, ZAxis)")
<< false << qreal(0.0f) << QVector3D(0, 0, 1) << int(Qt::ZAxis); << false << 0.0f << QVector3D(0, 0, 1) << int(Qt::ZAxis);
QTest::newRow("QTransform::rotate(45, ZAxis)") QTest::newRow("QTransform::rotate(45, ZAxis)")
<< true << qreal(45.0f) << QVector3D(0, 0, 1) << int(Qt::ZAxis); << true << 45.0f << QVector3D(0, 0, 1) << int(Qt::ZAxis);
QTest::newRow("QMatrix4x4::rotate(45, ZAxis)") QTest::newRow("QMatrix4x4::rotate(45, ZAxis)")
<< false << qreal(45.0f) << QVector3D(0, 0, 1) << int(Qt::ZAxis); << false << 45.0f << QVector3D(0, 0, 1) << int(Qt::ZAxis);
QTest::newRow("QTransform::rotate(90, ZAxis)") QTest::newRow("QTransform::rotate(90, ZAxis)")
<< true << qreal(90.0f) << QVector3D(0, 0, 1) << int(Qt::ZAxis); << true << 90.0f << QVector3D(0, 0, 1) << int(Qt::ZAxis);
QTest::newRow("QMatrix4x4::rotate(90, ZAxis)") QTest::newRow("QMatrix4x4::rotate(90, ZAxis)")
<< false << qreal(90.0f) << QVector3D(0, 0, 1) << int(Qt::ZAxis); << false << 90.0f << QVector3D(0, 0, 1) << int(Qt::ZAxis);
QTest::newRow("QTransform::rotate(0, YAxis)") QTest::newRow("QTransform::rotate(0, YAxis)")
<< true << qreal(0.0f) << QVector3D(0, 1, 0) << int(Qt::YAxis); << true << 0.0f << QVector3D(0, 1, 0) << int(Qt::YAxis);
QTest::newRow("QMatrix4x4::rotate(0, YAxis)") QTest::newRow("QMatrix4x4::rotate(0, YAxis)")
<< false << qreal(0.0f) << QVector3D(0, 1, 0) << int(Qt::YAxis); << false << 0.0f << QVector3D(0, 1, 0) << int(Qt::YAxis);
QTest::newRow("QTransform::rotate(45, YAxis)") QTest::newRow("QTransform::rotate(45, YAxis)")
<< true << qreal(45.0f) << QVector3D(0, 1, 0) << int(Qt::YAxis); << true << 45.0f << QVector3D(0, 1, 0) << int(Qt::YAxis);
QTest::newRow("QMatrix4x4::rotate(45, YAxis)") QTest::newRow("QMatrix4x4::rotate(45, YAxis)")
<< false << qreal(45.0f) << QVector3D(0, 1, 0) << int(Qt::YAxis); << false << 45.0f << QVector3D(0, 1, 0) << int(Qt::YAxis);
QTest::newRow("QTransform::rotate(90, YAxis)") QTest::newRow("QTransform::rotate(90, YAxis)")
<< true << qreal(90.0f) << QVector3D(0, 1, 0) << int(Qt::YAxis); << true << 90.0f << QVector3D(0, 1, 0) << int(Qt::YAxis);
QTest::newRow("QMatrix4x4::rotate(90, YAxis)") QTest::newRow("QMatrix4x4::rotate(90, YAxis)")
<< false << qreal(90.0f) << QVector3D(0, 1, 0) << int(Qt::YAxis); << false << 90.0f << QVector3D(0, 1, 0) << int(Qt::YAxis);
QTest::newRow("QTransform::rotate(0, XAxis)") QTest::newRow("QTransform::rotate(0, XAxis)")
<< true << qreal(0.0f) << QVector3D(0, 1, 0) << int(Qt::XAxis); << true << 0.0f << QVector3D(0, 1, 0) << int(Qt::XAxis);
QTest::newRow("QMatrix4x4::rotate(0, XAxis)") QTest::newRow("QMatrix4x4::rotate(0, XAxis)")
<< false << qreal(0.0f) << QVector3D(0, 1, 0) << int(Qt::XAxis); << false << 0.0f << QVector3D(0, 1, 0) << int(Qt::XAxis);
QTest::newRow("QTransform::rotate(45, XAxis)") QTest::newRow("QTransform::rotate(45, XAxis)")
<< true << qreal(45.0f) << QVector3D(1, 0, 0) << int(Qt::XAxis); << true << 45.0f << QVector3D(1, 0, 0) << int(Qt::XAxis);
QTest::newRow("QMatrix4x4::rotate(45, XAxis)") QTest::newRow("QMatrix4x4::rotate(45, XAxis)")
<< false << qreal(45.0f) << QVector3D(1, 0, 0) << int(Qt::XAxis); << false << 45.0f << QVector3D(1, 0, 0) << int(Qt::XAxis);
QTest::newRow("QTransform::rotate(90, XAxis)") QTest::newRow("QTransform::rotate(90, XAxis)")
<< true << qreal(90.0f) << QVector3D(1, 0, 0) << int(Qt::XAxis); << true << 90.0f << QVector3D(1, 0, 0) << int(Qt::XAxis);
QTest::newRow("QMatrix4x4::rotate(90, XAxis)") QTest::newRow("QMatrix4x4::rotate(90, XAxis)")
<< false << qreal(90.0f) << QVector3D(1, 0, 0) << int(Qt::XAxis); << false << 90.0f << QVector3D(1, 0, 0) << int(Qt::XAxis);
} }
void tst_QMatrix4x4::compareRotate() void tst_QMatrix4x4::compareRotate()
{ {
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(qreal, angle); QFETCH(float, angle);
QFETCH(QVector3D, rotation); QFETCH(QVector3D, rotation);
QFETCH(int, axis); QFETCH(int, axis);
qreal x = rotation.x(); float x = rotation.x();
qreal y = rotation.y(); float y = rotation.y();
qreal z = rotation.z(); float z = rotation.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;
@ -612,13 +612,13 @@ void tst_QMatrix4x4::compareRotateAfterTranslate_data()
void tst_QMatrix4x4::compareRotateAfterTranslate() void tst_QMatrix4x4::compareRotateAfterTranslate()
{ {
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(qreal, angle); QFETCH(float, angle);
QFETCH(QVector3D, rotation); QFETCH(QVector3D, rotation);
QFETCH(int, axis); QFETCH(int, axis);
qreal x = rotation.x(); float x = rotation.x();
qreal y = rotation.y(); float y = rotation.y();
qreal z = rotation.z(); float z = rotation.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;
@ -644,13 +644,13 @@ void tst_QMatrix4x4::compareRotateAfterScale_data()
void tst_QMatrix4x4::compareRotateAfterScale() void tst_QMatrix4x4::compareRotateAfterScale()
{ {
QFETCH(bool, useQTransform); QFETCH(bool, useQTransform);
QFETCH(qreal, angle); QFETCH(float, angle);
QFETCH(QVector3D, rotation); QFETCH(QVector3D, rotation);
QFETCH(int, axis); QFETCH(int, axis);
qreal x = rotation.x(); float x = rotation.x();
qreal y = rotation.y(); float y = rotation.y();
qreal z = rotation.z(); float z = rotation.z();
if (useQTransform) { if (useQTransform) {
QTransform t; QTransform t;

View File

@ -77,38 +77,38 @@ void tst_QQuaternion::cleanup()
void tst_QQuaternion::multiply_data() void tst_QQuaternion::multiply_data()
{ {
QTest::addColumn<qreal>("x1"); QTest::addColumn<float>("x1");
QTest::addColumn<qreal>("y1"); QTest::addColumn<float>("y1");
QTest::addColumn<qreal>("z1"); QTest::addColumn<float>("z1");
QTest::addColumn<qreal>("w1"); QTest::addColumn<float>("w1");
QTest::addColumn<qreal>("x2"); QTest::addColumn<float>("x2");
QTest::addColumn<qreal>("y2"); QTest::addColumn<float>("y2");
QTest::addColumn<qreal>("z2"); QTest::addColumn<float>("z2");
QTest::addColumn<qreal>("w2"); QTest::addColumn<float>("w2");
QTest::newRow("null") QTest::newRow("null")
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << 0.0f << 0.0f << 0.0f << 0.0f
<< (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; << 0.0f << 0.0f << 0.0f << 0.0f;
QTest::newRow("unitvec") QTest::newRow("unitvec")
<< (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f << 1.0f << 0.0f << 0.0f << 1.0f
<< (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)1.0f; << 0.0f << 1.0f << 0.0f << 1.0f;
QTest::newRow("complex") QTest::newRow("complex")
<< (qreal)1.0f << (qreal)2.0f << (qreal)3.0f << (qreal)7.0f << 1.0f << 2.0f << 3.0f << 7.0f
<< (qreal)4.0f << (qreal)5.0f << (qreal)6.0f << (qreal)8.0f; << 4.0f << 5.0f << 6.0f << 8.0f;
} }
void tst_QQuaternion::multiply() void tst_QQuaternion::multiply()
{ {
QFETCH(qreal, x1); QFETCH(float, x1);
QFETCH(qreal, y1); QFETCH(float, y1);
QFETCH(qreal, z1); QFETCH(float, z1);
QFETCH(qreal, w1); QFETCH(float, w1);
QFETCH(qreal, x2); QFETCH(float, x2);
QFETCH(qreal, y2); QFETCH(float, y2);
QFETCH(qreal, z2); QFETCH(float, z2);
QFETCH(qreal, w2); QFETCH(float, w2);
QQuaternion q1(w1, x1, y1, z1); QQuaternion q1(w1, x1, y1, z1);
QQuaternion q2(w2, x2, y2, z2); QQuaternion q2(w2, x2, y2, z2);