diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-09-04 04:12:08 (GMT) |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-09-04 07:00:23 (GMT) |
commit | 974aec137dfdbb1dd68c41113b22eb25131965b8 (patch) | |
tree | adbf042502fd35d1bce5a2aea811d41633ecd495 | |
parent | 4c501d7fce503a610edabfba5d6efc3ef2778bef (diff) | |
download | Qt-974aec137dfdbb1dd68c41113b22eb25131965b8.zip Qt-974aec137dfdbb1dd68c41113b22eb25131965b8.tar.gz Qt-974aec137dfdbb1dd68c41113b22eb25131965b8.tar.bz2 |
Modify QMatrix4x4 and QQuaternion to use qreal internally
Some concerns were expressed about the float precision of QMatrix4x4,
which this change addresses by using qreal instead.
The QVector2D/3D/4D classes still use float internally, so that they
can be used directly in large arrays of vertex values to be uploaded
to an OpenGL server.
QQuaternion is a client-side class, and it should produce rotations
that are consistent with QMatrix4x4. So its precision was changed too.
A consequence of this change is that the following no longer works
in a portable fashion:
QMatrix4x4 mat;
...
glLoadMatrixf(mat.constData());
The caller must now repack the argument to convert from qreal to GLfloat.
Reviewed-by: Michael Goddard
Reviewed-by: Andreas
-rw-r--r-- | demos/boxes/scene.cpp | 28 | ||||
-rw-r--r-- | src/gui/math3d/qgenericmatrix.cpp | 53 | ||||
-rw-r--r-- | src/gui/math3d/qgenericmatrix.h | 209 | ||||
-rw-r--r-- | src/gui/math3d/qmatrix4x4.cpp | 298 | ||||
-rw-r--r-- | src/gui/math3d/qmatrix4x4.h | 232 | ||||
-rw-r--r-- | src/gui/math3d/qquaternion.cpp | 17 | ||||
-rw-r--r-- | src/gui/math3d/qquaternion.h | 60 | ||||
-rw-r--r-- | src/gui/math3d/qvector3d.h | 3 | ||||
-rw-r--r-- | src/gui/math3d/qvector4d.h | 3 | ||||
-rw-r--r-- | src/opengl/qglshaderprogram.cpp | 197 | ||||
-rw-r--r-- | tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp | 125 | ||||
-rw-r--r-- | tests/auto/qquaternion/tst_qquaternion.cpp | 29 | ||||
-rw-r--r-- | tests/auto/qvectornd/tst_qvectornd.cpp | 55 | ||||
-rw-r--r-- | tests/benchmarks/qmatrix4x4/tst_qmatrix4x4.cpp | 12 |
14 files changed, 630 insertions, 691 deletions
diff --git a/demos/boxes/scene.cpp b/demos/boxes/scene.cpp index 2a7ca0e..7c0d4d8 100644 --- a/demos/boxes/scene.cpp +++ b/demos/boxes/scene.cpp @@ -649,6 +649,24 @@ void Scene::initGL() m_renderOptions->emitParameterChanged(); } +static void loadMatrix(const QMatrix4x4& m) +{ + GLfloat mat[16]; + const qreal *data = m.constData(); + for (int index = 0; index < 16; ++index) + mat[index] = data[index]; + glLoadMatrixf(mat); +} + +static void multMatrix(const QMatrix4x4& m) +{ + 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 the main box should not be rendered, set excludeBox to -1. void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox) @@ -673,7 +691,7 @@ void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox) viewRotation(3, 0) = viewRotation(3, 1) = viewRotation(3, 2) = 0.0f; viewRotation(0, 3) = viewRotation(1, 3) = viewRotation(2, 3) = 0.0f; viewRotation(3, 3) = 1.0f; - glLoadMatrixf(viewRotation.data()); + loadMatrix(viewRotation); glScalef(20.0f, 20.0f, 20.0f); // Don't render the environment if the environment texture can't be set for the correct sampler. @@ -688,7 +706,7 @@ void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox) m_environment->unbind(); } - glLoadMatrixf(view.data()); + loadMatrix(view); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); @@ -702,7 +720,7 @@ void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox) m.rotate(m_trackBalls[1].rotation()); m = m.transposed(); - glMultMatrixf(m.data()); + multMatrix(m); glRotatef(360.0f * i / m_programs.size(), 0.0f, 0.0f, 1.0f); glTranslatef(2.0f, 0.0f, 0.0f); @@ -736,7 +754,7 @@ void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox) QMatrix4x4 m; m.rotate(m_trackBalls[0].rotation()); m = m.transposed(); - glMultMatrixf(m.data()); + multMatrix(m); if (glActiveTexture) { if (m_dynamicCubemap) @@ -842,7 +860,7 @@ void Scene::renderCubemaps() glMatrixMode(GL_PROJECTION); glPushMatrix(); - glLoadMatrixf(mat.data()); + loadMatrix(mat); glMatrixMode(GL_MODELVIEW); glPushMatrix(); diff --git a/src/gui/math3d/qgenericmatrix.cpp b/src/gui/math3d/qgenericmatrix.cpp index 290c9c2..b5d8824 100644 --- a/src/gui/math3d/qgenericmatrix.cpp +++ b/src/gui/math3d/qgenericmatrix.cpp @@ -50,19 +50,14 @@ QT_BEGIN_NAMESPACE \ingroup painting \ingroup painting-3D - The QGenericMatrix template has four parameters: + The QGenericMatrix template has three parameters: \table \row \i N \i Number of columns. \row \i M \i Number of rows. \row \i T \i Element type that is visible to users of the class. - \row \i InnerT \i Element type that is used inside the class. \endtable - Normally T and InnerT are the same type; e.g. float or double. - But they can be different if the user wants to store elements - internally in a fixed-point format for the underlying hardware. - \sa QMatrix4x4 */ @@ -73,7 +68,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QGenericMatrix::QGenericMatrix(const QGenericMatrix<N, M, T, InnerT>& other) + \fn QGenericMatrix::QGenericMatrix(const QGenericMatrix<N, M, T>& other) Constructs a copy of \a other. */ @@ -89,13 +84,14 @@ QT_BEGIN_NAMESPACE */ /*! - \fn T QGenericMatrix::operator()(int row, int column) const + \fn const T& QGenericMatrix::operator()(int row, int column) const - Returns the element at position (\a row, \a column) in this matrix. + Returns a constant reference to the element at position + (\a row, \a column) in this matrix. */ /*! - \fn InnerT& QGenericMatrix::operator()(int row, int column) + \fn T& QGenericMatrix::operator()(int row, int column) Returns a reference to the element at position (\a row, \a column) in this matrix so that the element can be assigned to. @@ -130,57 +126,57 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QGenericMatrix<N, M, T, InnerT>& QGenericMatrix::operator+=(const QGenericMatrix<N, M, T, InnerT>& other) + \fn QGenericMatrix<N, M, T>& QGenericMatrix::operator+=(const QGenericMatrix<N, M, T>& other) Adds the contents of \a other to this matrix. */ /*! - \fn QGenericMatrix<N, M, T, InnerT>& QGenericMatrix::operator-=(const QGenericMatrix<N, M, T, InnerT>& other) + \fn QGenericMatrix<N, M, T>& QGenericMatrix::operator-=(const QGenericMatrix<N, M, T>& other) Subtracts the contents of \a other from this matrix. */ /*! - \fn QGenericMatrix<N, M, T, InnerT>& QGenericMatrix::operator*=(T factor) + \fn QGenericMatrix<N, M, T>& QGenericMatrix::operator*=(T factor) Multiplies all elements of this matrix by \a factor. */ /*! - \fn QGenericMatrix<N, M, T, InnerT>& QGenericMatrix::operator/=(T divisor) + \fn QGenericMatrix<N, M, T>& QGenericMatrix::operator/=(T divisor) Divides all elements of this matrix by \a divisor. */ /*! - \fn bool QGenericMatrix::operator==(const QGenericMatrix<N, M, T, InnerT>& other) const + \fn bool QGenericMatrix::operator==(const QGenericMatrix<N, M, T>& other) const Returns true if this matrix is identical to \a other; false otherwise. */ /*! - \fn bool QGenericMatrix::operator!=(const QGenericMatrix<N, M, T, InnerT>& other) const + \fn bool QGenericMatrix::operator!=(const QGenericMatrix<N, M, T>& other) const Returns true if this matrix is not identical to \a other; false otherwise. */ /*! - \fn QGenericMatrix<N, M, T, InnerT> operator+(const QGenericMatrix<N, M, T, InnerT>& m1, const QGenericMatrix<N, M, T, InnerT>& m2) + \fn QGenericMatrix<N, M, T> operator+(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2) \relates QGenericMatrix Returns the sum of \a m1 and \a m2. */ /*! - \fn QGenericMatrix<N, M, T, InnerT> operator-(const QGenericMatrix<N, M, T, InnerT>& m1, const QGenericMatrix<N, M, T, InnerT>& m2) + \fn QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2) \relates QGenericMatrix Returns the difference of \a m1 and \a m2. */ /*! - \fn QGenericMatrix<M1, M2, T, InnerT> operator*(const QGenericMatrix<N, M2, T, InnerT>& m1, const QGenericMatrix<M1, N, T, InnerT>& m2) + \fn QGenericMatrix<M1, M2, T> operator*(const QGenericMatrix<N, M2, T>& m1, const QGenericMatrix<M1, N, T>& m2) \relates QGenericMatrix Returns the product of the NxM2 matrix \a m1 and the M1xN matrix \a m2 @@ -188,7 +184,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QGenericMatrix<N, M, T, InnerT> operator-(const QGenericMatrix<N, M, T, InnerT>& matrix) + \fn QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& matrix) \overload \relates QGenericMatrix @@ -196,21 +192,21 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QGenericMatrix<N, M, T, InnerT> operator*(T factor, const QGenericMatrix<N, M, T, InnerT>& matrix) + \fn QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix) \relates QGenericMatrix Returns the result of multiplying all elements of \a matrix by \a factor. */ /*! - \fn QGenericMatrix<N, M, T, InnerT> operator*(const QGenericMatrix<N, M, T, InnerT>& matrix, T factor) + \fn QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor) \relates QGenericMatrix Returns the result of multiplying all elements of \a matrix by \a factor. */ /*! - \fn QGenericMatrix<N, M, T, InnerT> operator/(const QGenericMatrix<N, M, T, InnerT>& matrix, T divisor) + \fn QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M, T>& matrix, T divisor) \relates QGenericMatrix Returns the result of dividing all elements of \a matrix by \a divisor. @@ -224,28 +220,25 @@ QT_BEGIN_NAMESPACE */ /*! - \fn InnerT *QGenericMatrix::data() + \fn T *QGenericMatrix::data() - Returns a pointer to the raw data of this matrix. This is intended - for use with raw GL functions. + Returns a pointer to the raw data of this matrix. \sa constData() */ /*! - \fn const InnerT *QGenericMatrix::data() const + \fn const T *QGenericMatrix::data() const Returns a constant pointer to the raw data of this matrix. - This is intended for use with raw GL functions. \sa constData() */ /*! - \fn const InnerT *QGenericMatrix::constData() const + \fn const T *QGenericMatrix::constData() const Returns a constant pointer to the raw data of this matrix. - This is intended for use with raw GL functions. \sa data() */ diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h index fe7ba5f..39c4ed8 100644 --- a/src/gui/math3d/qgenericmatrix.h +++ b/src/gui/math3d/qgenericmatrix.h @@ -51,103 +51,103 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -template <int N, int M, typename T, typename InnerT = T> +template <int N, int M, typename T> class QGenericMatrix { public: QGenericMatrix(); - QGenericMatrix(const QGenericMatrix<N, M, T, InnerT>& other); + QGenericMatrix(const QGenericMatrix<N, M, T>& other); explicit QGenericMatrix(const T *values); - T operator()(int row, int column) const; - InnerT& operator()(int row, int column); + const T& operator()(int row, int column) const; + T& operator()(int row, int column); bool isIdentity() const; void setIdentity(); void fill(T value); - QGenericMatrix<M, N, T, InnerT> transposed() const; + QGenericMatrix<M, N, T> transposed() const; - QGenericMatrix<N, M, T, InnerT>& operator+=(const QGenericMatrix<N, M, T, InnerT>& other); - QGenericMatrix<N, M, T, InnerT>& operator-=(const QGenericMatrix<N, M, T, InnerT>& other); - QGenericMatrix<N, M, T, InnerT>& operator*=(T factor); - QGenericMatrix<N, M, T, InnerT>& operator/=(T divisor); - bool operator==(const QGenericMatrix<N, M, T, InnerT>& other) const; - bool operator!=(const QGenericMatrix<N, M, T, InnerT>& other) const; + QGenericMatrix<N, M, T>& operator+=(const QGenericMatrix<N, M, T>& other); + QGenericMatrix<N, M, T>& operator-=(const QGenericMatrix<N, M, T>& other); + QGenericMatrix<N, M, T>& operator*=(T factor); + QGenericMatrix<N, M, T>& operator/=(T divisor); + bool operator==(const QGenericMatrix<N, M, T>& other) const; + bool operator!=(const QGenericMatrix<N, M, T>& other) const; void toValueArray(T *values); - InnerT *data() { return m[0]; } - const InnerT *data() const { return m[0]; } - const InnerT *constData() const { return m[0]; } + T *data() { return m[0]; } + const T *data() const { return m[0]; } + const T *constData() const { return m[0]; } #if !defined(Q_NO_TEMPLATE_FRIENDS) - template<int NN, int MM, typename TT, typename ITT> - friend QGenericMatrix<NN, MM, TT, ITT> operator+(const QGenericMatrix<NN, MM, TT, ITT>& m1, const QGenericMatrix<NN, MM, TT, ITT>& m2); - template<int NN, int MM, typename TT, typename ITT> - friend QGenericMatrix<NN, MM, TT, ITT> operator-(const QGenericMatrix<NN, MM, TT, ITT>& m1, const QGenericMatrix<NN, MM, TT, ITT>& m2); - template<int NN, int M1, int M2, typename TT, typename ITT> - friend QGenericMatrix<M1, M2, TT, ITT> operator*(const QGenericMatrix<NN, M2, TT, ITT>& m1, const QGenericMatrix<M1, NN, TT, ITT>& m2); - template<int NN, int MM, typename TT, typename ITT> - friend QGenericMatrix<NN, MM, TT, ITT> operator-(const QGenericMatrix<NN, MM, TT, ITT>& matrix); - template<int NN, int MM, typename TT, typename ITT> - friend QGenericMatrix<NN, MM, TT, ITT> operator*(TT factor, const QGenericMatrix<NN, MM, TT, ITT>& matrix); - template<int NN, int MM, typename TT, typename ITT> - friend QGenericMatrix<NN, MM, TT, ITT> operator*(const QGenericMatrix<NN, MM, TT, ITT>& matrix, TT factor); - template<int NN, int MM, typename TT, typename ITT> - friend QGenericMatrix<NN, MM, TT, ITT> operator/(const QGenericMatrix<NN, MM, TT, ITT>& matrix, TT divisor); + template<int NN, int MM, typename TT> + friend QGenericMatrix<NN, MM, TT> operator+(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2); + template<int NN, int MM, typename TT> + friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2); + template<int NN, int M1, int M2, typename TT> + friend QGenericMatrix<M1, M2, TT> operator*(const QGenericMatrix<NN, M2, TT>& m1, const QGenericMatrix<M1, NN, TT>& m2); + template<int NN, int MM, typename TT> + friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& matrix); + template<int NN, int MM, typename TT> + friend QGenericMatrix<NN, MM, TT> operator*(TT factor, const QGenericMatrix<NN, MM, TT>& matrix); + template<int NN, int MM, typename TT> + friend QGenericMatrix<NN, MM, TT> operator*(const QGenericMatrix<NN, MM, TT>& matrix, TT factor); + template<int NN, int MM, typename TT> + friend QGenericMatrix<NN, MM, TT> operator/(const QGenericMatrix<NN, MM, TT>& matrix, TT divisor); private: #endif - InnerT m[N][M]; // Column-major order to match OpenGL. + T m[N][M]; // Column-major order to match OpenGL. QGenericMatrix(int) {} // Construct without initializing identity matrix. #if !defined(Q_NO_TEMPLATE_FRIENDS) - template <int NN, int MM, typename TT, typename ITT> + template <int NN, int MM, typename TT> friend class QGenericMatrix; #endif }; -template <int N, int M, typename T, typename InnerT> -Q_INLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>::QGenericMatrix() +template <int N, int M, typename T> +Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix() { setIdentity(); } -template <int N, int M, typename T, typename InnerT> -Q_INLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>::QGenericMatrix(const QGenericMatrix<N, M, T, InnerT>& other) +template <int N, int M, typename T> +Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const QGenericMatrix<N, M, T>& other) { for (int col = 0; col < N; ++col) for (int row = 0; row < M; ++row) m[col][row] = other.m[col][row]; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>::QGenericMatrix(const T *values) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const T *values) { for (int col = 0; col < N; ++col) for (int row = 0; row < M; ++row) m[col][row] = values[row * N + col]; } -template <int N, int M, typename T, typename InnerT> -Q_INLINE_TEMPLATE T QGenericMatrix<N, M, T, InnerT>::operator()(int row, int column) const +template <int N, int M, typename T> +Q_INLINE_TEMPLATE const T& QGenericMatrix<N, M, T>::operator()(int row, int column) const { Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N); - return T(m[column][row]); + return m[column][row]; } -template <int N, int M, typename T, typename InnerT> -Q_INLINE_TEMPLATE InnerT& QGenericMatrix<N, M, T, InnerT>::operator()(int row, int column) +template <int N, int M, typename T> +Q_INLINE_TEMPLATE T& QGenericMatrix<N, M, T>::operator()(int row, int column) { Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N); return m[column][row]; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T, InnerT>::isIdentity() const +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const { for (int col = 0; col < N; ++col) { for (int row = 0; row < M; ++row) { @@ -163,8 +163,8 @@ Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T, InnerT>::isIdentity() const return true; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T, InnerT>::setIdentity() +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setIdentity() { for (int col = 0; col < N; ++col) { for (int row = 0; row < M; ++row) { @@ -176,51 +176,50 @@ Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T, InnerT>::setIdentity() } } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T, InnerT>::fill(T value) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::fill(T value) { for (int col = 0; col < N; ++col) for (int row = 0; row < M; ++row) m[col][row] = value; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<M, N, T, InnerT> QGenericMatrix<N, M, T, InnerT>::transposed() const +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<M, N, T> QGenericMatrix<N, M, T>::transposed() const { - QGenericMatrix<M, N, T, InnerT> result(1); + QGenericMatrix<M, N, T> result(1); for (int row = 0; row < M; ++row) for (int col = 0; col < N; ++col) result.m[row][col] = m[col][row]; return result; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>& QGenericMatrix<N, M, T, InnerT>::operator+=(const QGenericMatrix<N, M, T, InnerT>& other) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator+=(const QGenericMatrix<N, M, T>& other) { for (int index = 0; index < N * M; ++index) m[0][index] += other.m[0][index]; return *this; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>& QGenericMatrix<N, M, T, InnerT>::operator-=(const QGenericMatrix<N, M, T, InnerT>& other) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator-=(const QGenericMatrix<N, M, T>& other) { for (int index = 0; index < N * M; ++index) m[0][index] -= other.m[0][index]; return *this; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>& QGenericMatrix<N, M, T, InnerT>::operator*=(T factor) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator*=(T factor) { - InnerT f(factor); for (int index = 0; index < N * M; ++index) - m[0][index] *= f; + m[0][index] *= factor; return *this; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T, InnerT>::operator==(const QGenericMatrix<N, M, T, InnerT>& other) const +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator==(const QGenericMatrix<N, M, T>& other) const { for (int index = 0; index < N * M; ++index) { if (m[0][index] != other.m[0][index]) @@ -229,8 +228,8 @@ Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T, InnerT>::operator==(const QGen return true; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T, InnerT>::operator!=(const QGenericMatrix<N, M, T, InnerT>& other) const +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator!=(const QGenericMatrix<N, M, T>& other) const { for (int index = 0; index < N * M; ++index) { if (m[0][index] != other.m[0][index]) @@ -239,40 +238,39 @@ Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T, InnerT>::operator!=(const QGen return false; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>& QGenericMatrix<N, M, T, InnerT>::operator/=(T divisor) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator/=(T divisor) { - InnerT d(divisor); for (int index = 0; index < N * M; ++index) - m[0][index] /= d; + m[0][index] /= divisor; return *this; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT> operator+(const QGenericMatrix<N, M, T, InnerT>& m1, const QGenericMatrix<N, M, T, InnerT>& m2) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator+(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2) { - QGenericMatrix<N, M, T, InnerT> result(1); + QGenericMatrix<N, M, T> result(1); for (int index = 0; index < N * M; ++index) result.m[0][index] = m1.m[0][index] + m2.m[0][index]; return result; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT> operator-(const QGenericMatrix<N, M, T, InnerT>& m1, const QGenericMatrix<N, M, T, InnerT>& m2) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2) { - QGenericMatrix<N, M, T, InnerT> result(1); + QGenericMatrix<N, M, T> result(1); for (int index = 0; index < N * M; ++index) result.m[0][index] = m1.m[0][index] - m2.m[0][index]; return result; } -template <int N, int M1, int M2, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T, InnerT> operator*(const QGenericMatrix<N, M2, T, InnerT>& m1, const QGenericMatrix<M1, N, T, InnerT>& m2) +template <int N, int M1, int M2, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T> operator*(const QGenericMatrix<N, M2, T>& m1, const QGenericMatrix<M1, N, T>& m2) { - QGenericMatrix<M1, M2, T, InnerT> result(1); + QGenericMatrix<M1, M2, T> result(1); for (int row = 0; row < M2; ++row) { for (int col = 0; col < M1; ++col) { - InnerT sum(0.0f); + T sum(0.0f); for (int j = 0; j < N; ++j) sum += m1.m[j][row] * m2.m[col][j]; result.m[col][row] = sum; @@ -281,47 +279,44 @@ Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T, InnerT> operator*(const QGenericM return result; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT> operator-(const QGenericMatrix<N, M, T, InnerT>& matrix) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& matrix) { - QGenericMatrix<N, M, T, InnerT> result(1); + QGenericMatrix<N, M, T> result(1); for (int index = 0; index < N * M; ++index) result.m[0][index] = -matrix.m[0][index]; return result; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT> operator*(T factor, const QGenericMatrix<N, M, T, InnerT>& matrix) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix) { - InnerT f(factor); - QGenericMatrix<N, M, T, InnerT> result(1); + QGenericMatrix<N, M, T> result(1); for (int index = 0; index < N * M; ++index) - result.m[0][index] = matrix.m[0][index] * f; + result.m[0][index] = matrix.m[0][index] * factor; return result; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT> operator*(const QGenericMatrix<N, M, T, InnerT>& matrix, T factor) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor) { - InnerT f(factor); - QGenericMatrix<N, M, T, InnerT> result(1); + QGenericMatrix<N, M, T> result(1); for (int index = 0; index < N * M; ++index) - result.m[0][index] = matrix.m[0][index] * f; + result.m[0][index] = matrix.m[0][index] * factor; return result; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT> operator/(const QGenericMatrix<N, M, T, InnerT>& matrix, T divisor) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M, T>& matrix, T divisor) { - InnerT d(divisor); - QGenericMatrix<N, M, T, InnerT> result(1); + QGenericMatrix<N, M, T> result(1); for (int index = 0; index < N * M; ++index) - result.m[0][index] = matrix.m[0][index] / d; + result.m[0][index] = matrix.m[0][index] / divisor; return result; } -template <int N, int M, typename T, typename InnerT> -Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T, InnerT>::toValueArray(T *values) +template <int N, int M, typename T> +Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::toValueArray(T *values) { for (int col = 0; col < N; ++col) for (int row = 0; row < M; ++row) @@ -329,22 +324,22 @@ Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T, InnerT>::toValueArray(T *value } // Define aliases for the useful variants of QGenericMatrix. -typedef QGenericMatrix<2, 2, qreal, float> QMatrix2x2; -typedef QGenericMatrix<2, 3, qreal, float> QMatrix2x3; -typedef QGenericMatrix<2, 4, qreal, float> QMatrix2x4; -typedef QGenericMatrix<3, 2, qreal, float> QMatrix3x2; -typedef QGenericMatrix<3, 3, qreal, float> QMatrix3x3; -typedef QGenericMatrix<3, 4, qreal, float> QMatrix3x4; -typedef QGenericMatrix<4, 2, qreal, float> QMatrix4x2; -typedef QGenericMatrix<4, 3, qreal, float> QMatrix4x3; +typedef QGenericMatrix<2, 2, qreal> QMatrix2x2; +typedef QGenericMatrix<2, 3, qreal> QMatrix2x3; +typedef QGenericMatrix<2, 4, qreal> QMatrix2x4; +typedef QGenericMatrix<3, 2, qreal> QMatrix3x2; +typedef QGenericMatrix<3, 3, qreal> QMatrix3x3; +typedef QGenericMatrix<3, 4, qreal> QMatrix3x4; +typedef QGenericMatrix<4, 2, qreal> QMatrix4x2; +typedef QGenericMatrix<4, 3, qreal> QMatrix4x3; #ifndef QT_NO_DEBUG_STREAM -template <int N, int M, typename T, typename InnerT> -QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T, InnerT> &m) +template <int N, int M, typename T> +QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m) { dbg.nospace() << "QGenericMatrix<" << N << ", " << M - << ", " << QTypeInfo<T>::name() << ", " << QTypeInfo<InnerT>::name() + << ", " << QTypeInfo<T>::name() << ">(" << endl << qSetFieldWidth(10); for (int row = 0; row < M; ++row) { for (int col = 0; col < N; ++col) diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index eb5858c..2164aca 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -103,7 +103,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC) /*! - \fn QMatrix4x4::QMatrix4x4(const QGenericMatrix<N, M, qreal, float>& matrix) + \fn QMatrix4x4::QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix) Constructs a 4x4 matrix from the left-most 4 columns and top-most 4 rows of \a matrix. If \a matrix has less than 4 columns or rows, @@ -114,7 +114,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) */ /*! - \fn QGenericMatrix<N, M, qreal, float> QMatrix4x4::toGenericMatrix() const + \fn QGenericMatrix<N, M, qreal> QMatrix4x4::toGenericMatrix() const Constructs a NxM generic matrix from the left-most N columns and top-most M rows of this 4x4 matrix. If N or M is greater than 4, @@ -127,7 +127,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) #endif /*! - \fn QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal, float>& matrix) + \fn QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix) \relates QMatrix4x4 Returns a 4x4 matrix constructed from the left-most 4 columns and @@ -139,7 +139,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) */ /*! - \fn QGenericMatrix<N, M, qreal, float> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) + \fn QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) \relates QMatrix4x4 Returns a NxM generic matrix constructed from the left-most N columns @@ -153,7 +153,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) /*! \internal */ -QMatrix4x4::QMatrix4x4(const float *values, int cols, int rows) +QMatrix4x4::QMatrix4x4(const qreal *values, int cols, int rows) { for (int col = 0; col < 4; ++col) { for (int row = 0; row < 4; ++row) { @@ -233,15 +233,16 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform) } /*! - \fn qreal QMatrix4x4::operator()(int row, int column) const + \fn const qreal& QMatrix4x4::operator()(int row, int column) const - Returns the element at position (\a row, \a column) in this matrix. + Returns a constant reference to the element at position + (\a row, \a column) in this matrix. \sa column(), row() */ /*! - \fn float& QMatrix4x4::operator()(int row, int column) + \fn qreal& QMatrix4x4::operator()(int row, int column) Returns a reference to the element at position (\a row, \a column) in this matrix so that the element can be assigned to. @@ -312,8 +313,8 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform) // | A B C | // M = | D E F | det(M) = A * (EI - HF) - B * (DI - GF) + C * (DH - GE) // | G H I | -static inline float matrixDet3 - (const float m[4][4], int col0, int col1, int col2, +static inline qreal matrixDet3 + (const qreal m[4][4], int col0, int col1, int col2, int row0, int row1, int row2) { return m[col0][row0] * @@ -328,9 +329,9 @@ static inline float matrixDet3 } // Calculate the determinant of a 4x4 matrix. -static inline float matrixDet4(const float m[4][4]) +static inline qreal matrixDet4(const qreal m[4][4]) { - float det; + qreal det; det = m[0][0] * matrixDet3(m, 1, 2, 3, 1, 2, 3); det -= m[1][0] * matrixDet3(m, 0, 2, 3, 1, 2, 3); det += m[2][0] * matrixDet3(m, 0, 1, 3, 1, 2, 3); @@ -382,7 +383,7 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const QMatrix4x4 inv(1); // The "1" says to not load the identity. - float det = matrixDet4(m); + qreal det = matrixDet4(m); if (det == 0.0f) { if (invertible) *invertible = false; @@ -436,12 +437,12 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const return inv; } - float det = matrixDet3(m, 0, 1, 2, 0, 1, 2); + qreal det = matrixDet3(m, 0, 1, 2, 0, 1, 2); if (det == 0.0f) return inv; det = 1.0f / det; - float *invm = inv.data(); + qreal *invm = inv.data(); // Invert and transpose in a single step. invm[0 + 0 * 3] = (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * det; @@ -697,9 +698,9 @@ QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor) */ QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector) { - float vx = vector.xp; - float vy = vector.yp; - float vz = vector.zp; + qreal vx = vector.x(); + qreal vy = vector.y(); + qreal vz = vector.z(); if (flagBits == Identity) { m[0][0] = vx; m[1][1] = vy; @@ -743,28 +744,26 @@ QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector) */ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y) { - float vx(x); - float vy(y); if (flagBits == Identity) { - m[0][0] = vx; - m[1][1] = vy; + m[0][0] = x; + m[1][1] = y; flagBits = Scale; } else if (flagBits == Scale || flagBits == (Scale | Translation)) { - m[0][0] *= vx; - m[1][1] *= vy; + m[0][0] *= x; + m[1][1] *= y; } else if (flagBits == Translation) { - m[0][0] = vx; - m[1][1] = vy; + m[0][0] = x; + m[1][1] = y; flagBits |= Scale; } else { - m[0][0] *= vx; - m[0][1] *= vx; - m[0][2] *= vx; - m[0][3] *= vx; - m[1][0] *= vy; - m[1][1] *= vy; - m[1][2] *= vy; - m[1][3] *= vy; + m[0][0] *= x; + m[0][1] *= x; + m[0][2] *= x; + m[0][3] *= x; + m[1][0] *= y; + m[1][1] *= y; + m[1][2] *= y; + m[1][3] *= y; flagBits = General; } return *this; @@ -780,36 +779,33 @@ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y) */ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y, qreal z) { - float vx(x); - float vy(y); - float vz(z); if (flagBits == Identity) { - m[0][0] = vx; - m[1][1] = vy; - m[2][2] = vz; + m[0][0] = x; + m[1][1] = y; + m[2][2] = z; flagBits = Scale; } else if (flagBits == Scale || flagBits == (Scale | Translation)) { - m[0][0] *= vx; - m[1][1] *= vy; - m[2][2] *= vz; + m[0][0] *= x; + m[1][1] *= y; + m[2][2] *= z; } else if (flagBits == Translation) { - m[0][0] = vx; - m[1][1] = vy; - m[2][2] = vz; + m[0][0] = x; + m[1][1] = y; + m[2][2] = z; flagBits |= Scale; } else { - m[0][0] *= vx; - m[0][1] *= vx; - m[0][2] *= vx; - m[0][3] *= vx; - m[1][0] *= vy; - m[1][1] *= vy; - m[1][2] *= vy; - m[1][3] *= vy; - m[2][0] *= vz; - m[2][1] *= vz; - m[2][2] *= vz; - m[2][3] *= vz; + m[0][0] *= x; + m[0][1] *= x; + m[0][2] *= x; + m[0][3] *= x; + m[1][0] *= y; + m[1][1] *= y; + m[1][2] *= y; + m[1][3] *= y; + m[2][0] *= z; + m[2][1] *= z; + m[2][2] *= z; + m[2][3] *= z; flagBits = General; } return *this; @@ -866,9 +862,9 @@ QMatrix4x4& QMatrix4x4::scale(qreal factor) */ QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector) { - float vx = vector.xp; - float vy = vector.yp; - float vz = vector.zp; + qreal vx = vector.x(); + qreal vy = vector.y(); + qreal vz = vector.z(); if (flagBits == Identity) { m[3][0] = vx; m[3][1] = vy; @@ -912,28 +908,26 @@ QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector) */ QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y) { - float vx(x); - float vy(y); if (flagBits == Identity) { - m[3][0] = vx; - m[3][1] = vy; + m[3][0] = x; + m[3][1] = y; flagBits = Translation; } else if (flagBits == Translation) { - m[3][0] += vx; - m[3][1] += vy; + m[3][0] += x; + m[3][1] += y; } else if (flagBits == Scale) { - m[3][0] = m[0][0] * vx; - m[3][1] = m[1][1] * vy; + m[3][0] = m[0][0] * x; + m[3][1] = m[1][1] * y; m[3][2] = 0.; flagBits |= Translation; } else if (flagBits == (Scale | Translation)) { - m[3][0] += m[0][0] * vx; - m[3][1] += m[1][1] * vy; + m[3][0] += m[0][0] * x; + m[3][1] += m[1][1] * y; } else { - m[3][0] += m[0][0] * vx + m[1][0] * vy; - m[3][1] += m[0][1] * vx + m[1][1] * vy; - m[3][2] += m[0][2] * vx + m[1][2] * vy; - m[3][3] += m[0][3] * vx + m[1][3] * vy; + m[3][0] += m[0][0] * x + m[1][0] * y; + m[3][1] += m[0][1] * x + m[1][1] * y; + m[3][2] += m[0][2] * x + m[1][2] * y; + m[3][3] += m[0][3] * x + m[1][3] * y; if (flagBits == Rotation) flagBits |= Translation; else if (flagBits != (Rotation | Translation)) @@ -952,32 +946,29 @@ QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y) */ QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y, qreal z) { - float vx(x); - float vy(y); - float vz(z); if (flagBits == Identity) { - m[3][0] = vx; - m[3][1] = vy; - m[3][2] = vz; + m[3][0] = x; + m[3][1] = y; + m[3][2] = z; flagBits = Translation; } else if (flagBits == Translation) { - m[3][0] += vx; - m[3][1] += vy; - m[3][2] += vz; + m[3][0] += x; + m[3][1] += y; + m[3][2] += z; } else if (flagBits == Scale) { - m[3][0] = m[0][0] * vx; - m[3][1] = m[1][1] * vy; - m[3][2] = m[2][2] * vz; + m[3][0] = m[0][0] * x; + m[3][1] = m[1][1] * y; + m[3][2] = m[2][2] * z; flagBits |= Translation; } else if (flagBits == (Scale | Translation)) { - m[3][0] += m[0][0] * vx; - m[3][1] += m[1][1] * vy; - m[3][2] += m[2][2] * vz; + m[3][0] += m[0][0] * x; + m[3][1] += m[1][1] * y; + m[3][2] += m[2][2] * z; } else { - m[3][0] += m[0][0] * vx + m[1][0] * vy + m[2][0] * vz; - m[3][1] += m[0][1] * vx + m[1][1] * vy + m[2][1] * vz; - m[3][2] += m[0][2] * vx + m[1][2] * vy + m[2][2] * vz; - m[3][3] += m[0][3] * vx + m[1][3] * vy + m[2][3] * vz; + m[3][0] += m[0][0] * x + m[1][0] * y + m[2][0] * z; + m[3][1] += m[0][1] * x + m[1][1] * y + m[2][1] * z; + m[3][2] += m[0][2] * x + m[1][2] * y + m[2][2] * z; + m[3][3] += m[0][3] * x + m[1][3] * y + m[2][3] * z; if (flagBits == Rotation) flagBits |= Translation; else if (flagBits != (Rotation | Translation)) @@ -1126,15 +1117,15 @@ QMatrix4x4& QMatrix4x4::rotate(const QQuaternion& quaternion) // Algorithm from: // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54 QMatrix4x4 m(1); - float xx = quaternion.xp * quaternion.xp; - float xy = quaternion.xp * quaternion.yp; - float xz = quaternion.xp * quaternion.zp; - float xw = quaternion.xp * quaternion.wp; - float yy = quaternion.yp * quaternion.yp; - float yz = quaternion.yp * quaternion.zp; - float yw = quaternion.yp * quaternion.wp; - float zz = quaternion.zp * quaternion.zp; - float zw = quaternion.zp * quaternion.wp; + qreal xx = quaternion.x() * quaternion.x(); + qreal xy = quaternion.x() * quaternion.y(); + qreal xz = quaternion.x() * quaternion.z(); + qreal xw = quaternion.x() * quaternion.scalar(); + qreal yy = quaternion.y() * quaternion.y(); + qreal yz = quaternion.y() * quaternion.z(); + qreal yw = quaternion.y() * quaternion.scalar(); + qreal zz = quaternion.z() * quaternion.z(); + qreal zw = quaternion.z() * quaternion.scalar(); m.m[0][0] = 1.0f - 2 * (yy + zz); m.m[1][0] = 2 * (xy - zw); m.m[2][0] = 2 * (xz + yw); @@ -1222,11 +1213,11 @@ QMatrix4x4& QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, translate(QVector3D (-(left + right) / width, -(top + bottom) / invheight, - 0.0f, 1)); + 0.0f)); scale(QVector3D (2.0f / width, 2.0f / invheight, - -1.0f, 1)); + -1.0f)); return *this; } #endif @@ -1356,17 +1347,17 @@ QMatrix4x4& QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, co QMatrix4x4 m(1); - m.m[0][0] = side.xp; - m.m[1][0] = side.yp; - m.m[2][0] = side.zp; + m.m[0][0] = side.x(); + m.m[1][0] = side.y(); + m.m[2][0] = side.z(); m.m[3][0] = 0.0f; - m.m[0][1] = upVector.xp; - m.m[1][1] = upVector.yp; - m.m[2][1] = upVector.zp; + m.m[0][1] = upVector.x(); + m.m[1][1] = upVector.y(); + m.m[2][1] = upVector.z(); m.m[3][1] = 0.0f; - m.m[0][2] = -forward.xp; - m.m[1][2] = -forward.yp; - m.m[2][2] = -forward.zp; + m.m[0][2] = -forward.x(); + m.m[1][2] = -forward.y(); + m.m[2][2] = -forward.z(); m.m[3][2] = 0.0f; m.m[0][3] = 0.0f; m.m[1][3] = 0.0f; @@ -1434,9 +1425,9 @@ void QMatrix4x4::toValueArray(qreal *values) const */ QMatrix QMatrix4x4::toAffine() const { - return QMatrix(qreal(m[0][0]), qreal(m[0][1]), - qreal(m[1][0]), qreal(m[1][1]), - qreal(m[3][0]), qreal(m[3][1])); + return QMatrix(m[0][0], m[0][1], + m[1][0], m[1][1], + m[3][0], m[3][1]); } static const qreal inv_dist_to_plane = 1. / 1024.; @@ -1462,15 +1453,12 @@ QTransform QMatrix4x4::toTransform(qreal distanceToPlane) const { if (distanceToPlane == 1024.0f) { // Optimize the common case with constants. - return QTransform(qreal(m[0][0]), qreal(m[0][1]), - qreal(m[0][3]) - qreal(m[0][2]) * - inv_dist_to_plane, - qreal(m[1][0]), qreal(m[1][1]), - qreal(m[1][3]) - qreal(m[1][2]) * - inv_dist_to_plane, - qreal(m[3][0]), qreal(m[3][1]), - qreal(m[3][3]) - qreal(m[3][2]) * - inv_dist_to_plane); + return QTransform(m[0][0], m[0][1], + m[0][3] - m[0][2] * inv_dist_to_plane, + m[1][0], m[1][1], + m[1][3] - m[1][2] * inv_dist_to_plane, + m[3][0], m[3][1], + m[3][3] - m[3][2] * inv_dist_to_plane); } else if (distanceToPlane != 0.0f) { // The following projection matrix is pre-multiplied with "matrix": // | 1 0 0 0 | @@ -1480,17 +1468,14 @@ QTransform QMatrix4x4::toTransform(qreal distanceToPlane) const // where d = -1 / distanceToPlane. After projection, row 3 and // column 3 are dropped to form the final QTransform. qreal d = 1.0f / distanceToPlane; - return QTransform(qreal(m[0][0]), qreal(m[0][1]), - qreal(m[0][3]) - qreal(m[0][2]) * d, - qreal(m[1][0]), qreal(m[1][1]), - qreal(m[1][3]) - qreal(m[1][2]) * d, - qreal(m[3][0]), qreal(m[3][1]), - qreal(m[3][3]) - qreal(m[3][2]) * d); + return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * d, + m[1][0], m[1][1], m[1][3] - m[1][2] * d, + m[3][0], m[3][1], m[3][3] - m[3][2] * d); } else { // Orthographic projection: drop row 3 and column 3. - return QTransform(qreal(m[0][0]), qreal(m[0][1]), qreal(m[0][3]), - qreal(m[1][0]), qreal(m[1][1]), qreal(m[1][3]), - qreal(m[3][0]), qreal(m[3][1]), qreal(m[3][3])); + return QTransform(m[0][0], m[0][1], m[0][3], + m[1][0], m[1][1], m[1][3], + m[3][0], m[3][1], m[3][3]); } } @@ -1618,28 +1603,25 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const } /*! - \fn float *QMatrix4x4::data() + \fn qreal *QMatrix4x4::data() - Returns a pointer to the raw data of this matrix. This is intended - for use with raw GL functions. + Returns a pointer to the raw data of this matrix. \sa constData(), inferSpecialType() */ /*! - \fn const float *QMatrix4x4::data() const + \fn const qreal *QMatrix4x4::data() const Returns a constant pointer to the raw data of this matrix. - This is intended for use with raw GL functions. \sa constData() */ /*! - \fn const float *QMatrix4x4::constData() const + \fn const qreal *QMatrix4x4::constData() const Returns a constant pointer to the raw data of this matrix. - This is intended for use with raw GL functions. \sa data() */ @@ -1695,7 +1677,7 @@ void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const { // Orientation is dependent on the upper 3x3 matrix; subtract the // homogeneous scaling element from the trace of the 4x4 matrix - float tr = m[0][0] + m[1][1] + m[2][2]; + qreal tr = m[0][0] + m[1][1] + m[2][2]; qreal cosa = qreal(0.5f * (tr - 1.0f)); angle = acos(cosa) * 180.0f / M_PI; @@ -1708,38 +1690,38 @@ void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const } if (angle < 180.0f) { - axis.xp = m[1][2] - m[2][1]; - axis.yp = m[2][0] - m[0][2]; - axis.zp = m[0][1] - m[1][0]; + axis.setX(m[1][2] - m[2][1]); + axis.setY(m[2][0] - m[0][2]); + axis.setZ(m[0][1] - m[1][0]); axis.normalize(); return; } // rads == PI - float tmp; + qreal tmp; // r00 is maximum if ((m[0][0] >= m[2][2]) && (m[0][0] >= m[1][1])) { - axis.xp = 0.5f * qSqrt(m[0][0] - m[1][1] - m[2][2] + 1.0f); + axis.setX(0.5f * qSqrt(m[0][0] - m[1][1] - m[2][2] + 1.0f)); tmp = 0.5f / axis.x(); - axis.yp = m[1][0] * tmp; - axis.zp = m[2][0] * tmp; + axis.setY(m[1][0] * tmp); + axis.setZ(m[2][0] * tmp); } // r11 is maximum if ((m[1][1] >= m[2][2]) && (m[1][1] >= m[0][0])) { - axis.yp = 0.5f * qSqrt(m[1][1] - m[0][0] - m[2][2] + 1.0f); + axis.setY(0.5f * qSqrt(m[1][1] - m[0][0] - m[2][2] + 1.0f)); tmp = 0.5f / axis.y(); - axis.xp = tmp * m[1][0]; - axis.zp = tmp * m[2][1]; + axis.setX(tmp * m[1][0]); + axis.setZ(tmp * m[2][1]); } // r22 is maximum if ((m[2][2] >= m[1][1]) && (m[2][2] >= m[0][0])) { - axis.zp = 0.5f * qSqrt(m[2][2] - m[0][0] - m[1][1] + 1.0f); + axis.setZ(0.5f * qSqrt(m[2][2] - m[0][0] - m[1][1] + 1.0f)); tmp = 0.5f / axis.z(); - axis.xp = m[2][0]*tmp; - axis.yp = m[2][1]*tmp; + axis.setX(m[2][0]*tmp); + axis.setY(m[2][1]*tmp); } } @@ -1756,7 +1738,7 @@ QVector3D QMatrix4x4::extractTranslation() const return QVector3D (m[0][0] * m[3][0] + m[0][1] * m[3][1] + m[0][2] * m[3][2], m[1][0] * m[3][0] + m[1][1] * m[3][1] + m[1][2] * m[3][2], - m[2][0] * m[3][0] + m[2][1] * m[3][1] + m[2][2] * m[3][2], 1); + m[2][0] * m[3][0] + m[2][1] * m[3][1] + m[2][2] * m[3][2]); } #endif @@ -1894,7 +1876,7 @@ QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix) for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { stream >> x; - matrix(row, col) = float(x); + matrix(row, col) = qreal(x); } } matrix.inferSpecialType(); diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index 4207bdf..8811027 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -71,14 +71,14 @@ public: qreal m41, qreal m42, qreal m43, qreal m44); #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC) template <int N, int M> - explicit QMatrix4x4(const QGenericMatrix<N, M, qreal, float>& matrix); + explicit QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix); #endif - QMatrix4x4(const float *values, int cols, int rows); + QMatrix4x4(const qreal *values, int cols, int rows); QMatrix4x4(const QTransform& transform); QMatrix4x4(const QMatrix& matrix); - inline qreal operator()(int row, int column) const; - inline float& operator()(int row, int column); + inline const qreal& operator()(int row, int column) const; + inline qreal& operator()(int row, int column); inline QVector4D column(int index) const; inline void setColumn(int index, const QVector4D& value); @@ -174,12 +174,12 @@ public: #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC) template <int N, int M> - QGenericMatrix<N, M, qreal, float> toGenericMatrix() const; + QGenericMatrix<N, M, qreal> toGenericMatrix() const; #endif - inline float *data(); - inline const float *data() const { return m[0]; } - inline const float *constData() const { return m[0]; } + inline qreal *data(); + inline const qreal *data() const { return m[0]; } + inline const qreal *constData() const { return m[0]; } void inferSpecialType(); @@ -190,7 +190,7 @@ public: #endif private: - float m[4][4]; // Column-major order to match OpenGL. + qreal m[4][4]; // Column-major order to match OpenGL. int flagBits; // Flag bits from the enum below. enum { @@ -224,9 +224,9 @@ inline QMatrix4x4::QMatrix4x4 template <int N, int M> Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4 - (const QGenericMatrix<N, M, qreal, float>& matrix) + (const QGenericMatrix<N, M, qreal>& matrix) { - const float *values = matrix.constData(); + const qreal *values = matrix.constData(); for (int col = 0; col < 4; ++col) { for (int row = 0; row < 4; ++row) { if (col < N && row < M) @@ -241,10 +241,10 @@ Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4 } template <int N, int M> -QGenericMatrix<N, M, qreal, float> QMatrix4x4::toGenericMatrix() const +QGenericMatrix<N, M, qreal> QMatrix4x4::toGenericMatrix() const { - QGenericMatrix<N, M, qreal, float> result; - float *values = result.data(); + QGenericMatrix<N, M, qreal> result; + qreal *values = result.data(); for (int col = 0; col < N; ++col) { for (int row = 0; row < M; ++row) { if (col < 4 && row < 4) @@ -260,13 +260,13 @@ QGenericMatrix<N, M, qreal, float> QMatrix4x4::toGenericMatrix() const #endif -inline qreal QMatrix4x4::operator()(int row, int column) const +inline const qreal& QMatrix4x4::operator()(int row, int column) const { Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4); - return qreal(m[column][row]); + return m[column][row]; } -inline float& QMatrix4x4::operator()(int row, int column) +inline qreal& QMatrix4x4::operator()(int row, int column) { Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4); flagBits = General; @@ -276,32 +276,32 @@ inline float& QMatrix4x4::operator()(int row, int column) inline QVector4D QMatrix4x4::column(int index) const { Q_ASSERT(index >= 0 && index < 4); - return QVector4D(m[index][0], m[index][1], m[index][2], m[index][3], 1); + return QVector4D(m[index][0], m[index][1], m[index][2], m[index][3]); } inline void QMatrix4x4::setColumn(int index, const QVector4D& value) { Q_ASSERT(index >= 0 && index < 4); - m[index][0] = value.xp; - m[index][1] = value.yp; - m[index][2] = value.zp; - m[index][3] = value.wp; + m[index][0] = value.x(); + m[index][1] = value.y(); + m[index][2] = value.z(); + m[index][3] = value.w(); flagBits = General; } inline QVector4D QMatrix4x4::row(int index) const { Q_ASSERT(index >= 0 && index < 4); - return QVector4D(m[0][index], m[1][index], m[2][index], m[3][index], 1); + return QVector4D(m[0][index], m[1][index], m[2][index], m[3][index]); } inline void QMatrix4x4::setRow(int index, const QVector4D& value) { Q_ASSERT(index >= 0 && index < 4); - m[0][index] = value.xp; - m[1][index] = value.yp; - m[2][index] = value.zp; - m[3][index] = value.wp; + m[0][index] = value.x(); + m[1][index] = value.y(); + m[2][index] = value.z(); + m[3][index] = value.w(); flagBits = General; } @@ -608,68 +608,68 @@ inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2) inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix) { - float x, y, z, w; - x = vector.xp * matrix.m[0][0] + - vector.yp * matrix.m[0][1] + - vector.zp * matrix.m[0][2] + + qreal x, y, z, w; + x = vector.x() * matrix.m[0][0] + + vector.y() * matrix.m[0][1] + + vector.z() * matrix.m[0][2] + matrix.m[0][3]; - y = vector.xp * matrix.m[1][0] + - vector.yp * matrix.m[1][1] + - vector.zp * matrix.m[1][2] + + y = vector.x() * matrix.m[1][0] + + vector.y() * matrix.m[1][1] + + vector.z() * matrix.m[1][2] + matrix.m[1][3]; - z = vector.xp * matrix.m[2][0] + - vector.yp * matrix.m[2][1] + - vector.zp * matrix.m[2][2] + + z = vector.x() * matrix.m[2][0] + + vector.y() * matrix.m[2][1] + + vector.z() * matrix.m[2][2] + matrix.m[2][3]; - w = vector.xp * matrix.m[3][0] + - vector.yp * matrix.m[3][1] + - vector.zp * matrix.m[3][2] + + w = vector.x() * matrix.m[3][0] + + vector.y() * matrix.m[3][1] + + vector.z() * matrix.m[3][2] + matrix.m[3][3]; if (w == 1.0f) - return QVector3D(x, y, z, 1); + return QVector3D(x, y, z); else - return QVector3D(x / w, y / w, z / w, 1); + return QVector3D(x / w, y / w, z / w); } inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector) { - float x, y, z, w; + qreal x, y, z, w; if (matrix.flagBits == QMatrix4x4::Identity) { return vector; } else if (matrix.flagBits == QMatrix4x4::Translation) { - return QVector3D(vector.xp + matrix.m[3][0], - vector.yp + matrix.m[3][1], - vector.zp + matrix.m[3][2], 1); + return QVector3D(vector.x() + matrix.m[3][0], + vector.y() + matrix.m[3][1], + vector.z() + matrix.m[3][2]); } else if (matrix.flagBits == (QMatrix4x4::Translation | QMatrix4x4::Scale)) { - return QVector3D(vector.xp * matrix.m[0][0] + matrix.m[3][0], - vector.yp * matrix.m[1][1] + matrix.m[3][1], - vector.zp * matrix.m[2][2] + matrix.m[3][2], 1); + return QVector3D(vector.x() * matrix.m[0][0] + matrix.m[3][0], + vector.y() * matrix.m[1][1] + matrix.m[3][1], + vector.z() * matrix.m[2][2] + matrix.m[3][2]); } else if (matrix.flagBits == QMatrix4x4::Scale) { - return QVector3D(vector.xp * matrix.m[0][0], - vector.yp * matrix.m[1][1], - vector.zp * matrix.m[2][2], 1); + return QVector3D(vector.x() * matrix.m[0][0], + vector.y() * matrix.m[1][1], + vector.z() * matrix.m[2][2]); } else { - x = vector.xp * matrix.m[0][0] + - vector.yp * matrix.m[1][0] + - vector.zp * matrix.m[2][0] + + x = vector.x() * matrix.m[0][0] + + vector.y() * matrix.m[1][0] + + vector.z() * matrix.m[2][0] + matrix.m[3][0]; - y = vector.xp * matrix.m[0][1] + - vector.yp * matrix.m[1][1] + - vector.zp * matrix.m[2][1] + + y = vector.x() * matrix.m[0][1] + + vector.y() * matrix.m[1][1] + + vector.z() * matrix.m[2][1] + matrix.m[3][1]; - z = vector.xp * matrix.m[0][2] + - vector.yp * matrix.m[1][2] + - vector.zp * matrix.m[2][2] + + z = vector.x() * matrix.m[0][2] + + vector.y() * matrix.m[1][2] + + vector.z() * matrix.m[2][2] + matrix.m[3][2]; - w = vector.xp * matrix.m[0][3] + - vector.yp * matrix.m[1][3] + - vector.zp * matrix.m[2][3] + + w = vector.x() * matrix.m[0][3] + + vector.y() * matrix.m[1][3] + + vector.z() * matrix.m[2][3] + matrix.m[3][3]; if (w == 1.0f) - return QVector3D(x, y, z, 1); + return QVector3D(x, y, z); else - return QVector3D(x / w, y / w, z / w, 1); + return QVector3D(x / w, y / w, z / w); } } @@ -679,54 +679,54 @@ inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector) inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix) { - float x, y, z, w; - x = vector.xp * matrix.m[0][0] + - vector.yp * matrix.m[0][1] + - vector.zp * matrix.m[0][2] + - vector.wp * matrix.m[0][3]; - y = vector.xp * matrix.m[1][0] + - vector.yp * matrix.m[1][1] + - vector.zp * matrix.m[1][2] + - vector.wp * matrix.m[1][3]; - z = vector.xp * matrix.m[2][0] + - vector.yp * matrix.m[2][1] + - vector.zp * matrix.m[2][2] + - vector.wp * matrix.m[2][3]; - w = vector.xp * matrix.m[3][0] + - vector.yp * matrix.m[3][1] + - vector.zp * matrix.m[3][2] + - vector.wp * matrix.m[3][3]; - return QVector4D(x, y, z, w, 1); + qreal x, y, z, w; + x = vector.x() * matrix.m[0][0] + + vector.y() * matrix.m[0][1] + + vector.z() * matrix.m[0][2] + + vector.w() * matrix.m[0][3]; + y = vector.x() * matrix.m[1][0] + + vector.y() * matrix.m[1][1] + + vector.z() * matrix.m[1][2] + + vector.w() * matrix.m[1][3]; + z = vector.x() * matrix.m[2][0] + + vector.y() * matrix.m[2][1] + + vector.z() * matrix.m[2][2] + + vector.w() * matrix.m[2][3]; + w = vector.x() * matrix.m[3][0] + + vector.y() * matrix.m[3][1] + + vector.z() * matrix.m[3][2] + + vector.w() * matrix.m[3][3]; + return QVector4D(x, y, z, w); } inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector) { - float x, y, z, w; - x = vector.xp * matrix.m[0][0] + - vector.yp * matrix.m[1][0] + - vector.zp * matrix.m[2][0] + - vector.wp * matrix.m[3][0]; - y = vector.xp * matrix.m[0][1] + - vector.yp * matrix.m[1][1] + - vector.zp * matrix.m[2][1] + - vector.wp * matrix.m[3][1]; - z = vector.xp * matrix.m[0][2] + - vector.yp * matrix.m[1][2] + - vector.zp * matrix.m[2][2] + - vector.wp * matrix.m[3][2]; - w = vector.xp * matrix.m[0][3] + - vector.yp * matrix.m[1][3] + - vector.zp * matrix.m[2][3] + - vector.wp * matrix.m[3][3]; - return QVector4D(x, y, z, w, 1); + qreal x, y, z, w; + x = vector.x() * matrix.m[0][0] + + vector.y() * matrix.m[1][0] + + vector.z() * matrix.m[2][0] + + vector.w() * matrix.m[3][0]; + y = vector.x() * matrix.m[0][1] + + vector.y() * matrix.m[1][1] + + vector.z() * matrix.m[2][1] + + vector.w() * matrix.m[3][1]; + z = vector.x() * matrix.m[0][2] + + vector.y() * matrix.m[1][2] + + vector.z() * matrix.m[2][2] + + vector.w() * matrix.m[3][2]; + w = vector.x() * matrix.m[0][3] + + vector.y() * matrix.m[1][3] + + vector.z() * matrix.m[2][3] + + vector.w() * matrix.m[3][3]; + return QVector4D(x, y, z, w); } #endif inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix) { - float xin, yin; - float x, y, w; + qreal xin, yin; + qreal x, y, w; xin = point.x(); yin = point.y(); x = xin * matrix.m[0][0] + @@ -746,8 +746,8 @@ inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix) inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix) { - float xin, yin; - float x, y, w; + qreal xin, yin; + qreal x, y, w; xin = point.x(); yin = point.y(); x = xin * matrix.m[0][0] + @@ -768,8 +768,8 @@ inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix) inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point) { - float xin, yin; - float x, y, w; + qreal xin, yin; + qreal x, y, w; xin = point.x(); yin = point.y(); if (matrix.flagBits == QMatrix4x4::Identity) { @@ -803,8 +803,8 @@ inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point) inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point) { - float xin, yin; - float x, y, w; + qreal xin, yin; + qreal x, y, w; xin = point.x(); yin = point.y(); if (matrix.flagBits == QMatrix4x4::Identity) { @@ -951,7 +951,7 @@ inline QVector4D QMatrix4x4::map(const QVector4D& point) const #endif -inline float *QMatrix4x4::data() +inline qreal *QMatrix4x4::data() { // We have to assume that the caller will modify the matrix elements, // so we flip it over to "General" mode. @@ -969,17 +969,17 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix4x4 &); #endif template <int N, int M> -QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal, float>& matrix) +QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix) { return QMatrix4x4(matrix.constData(), N, M); } template <int N, int M> -QGenericMatrix<N, M, qreal, float> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) +QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) { - QGenericMatrix<N, M, qreal, float> result; - const float *m = matrix.constData(); - float *values = result.data(); + QGenericMatrix<N, M, qreal> result; + const qreal *m = matrix.constData(); + qreal *values = result.data(); for (int col = 0; col < N; ++col) { for (int row = 0; row < M; ++row) { if (col < 4 && row < 4) diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index ece4482..7206e9a 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -353,7 +353,7 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, qreal angle) qreal s = qSin(a); qreal c = qCos(a); QVector3D ax = axis.normalized(); - return QQuaternion(c, ax.xp * s, ax.yp * s, ax.zp * s, 1).normalized(); + return QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized(); } #endif @@ -365,19 +365,16 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, qreal angle) QQuaternion QQuaternion::fromAxisAndAngle (qreal x, qreal y, qreal z, qreal angle) { - float xp = x; - float yp = y; - float zp = z; - qreal length = qSqrt(xp * xp + yp * yp + zp * zp); - if (!qIsNull(length)) { - xp /= length; - yp /= length; - zp /= length; + qreal length = qSqrt(x * x + y * y + z * z); + if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) { + x /= length; + y /= length; + z /= length; } qreal a = (angle / 2.0f) * M_PI / 180.0f; qreal s = qSin(a); qreal c = qCos(a); - return QQuaternion(c, xp * s, yp * s, zp * s, 1).normalized(); + return QQuaternion(c, x * s, y * s, z * s).normalized(); } /*! diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 12576d2..f243c42 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -133,11 +133,7 @@ public: (const QQuaternion& q1, const QQuaternion& q2, qreal t); private: - float wp, xp, yp, zp; - - friend class QMatrix4x4; - - QQuaternion(float scalar, float xpos, float ypos, float zpos, int dummy); + qreal wp, xp, yp, zp; }; inline QQuaternion::QQuaternion() : wp(1.0f), xp(0.0f), yp(0.0f), zp(0.0f) {} @@ -145,8 +141,6 @@ inline QQuaternion::QQuaternion() : wp(1.0f), xp(0.0f), yp(0.0f), zp(0.0f) {} inline QQuaternion::QQuaternion(qreal scalar, qreal xpos, qreal ypos, qreal zpos) : wp(scalar), xp(xpos), yp(ypos), zp(zpos) {} -inline QQuaternion::QQuaternion(float scalar, float xpos, float ypos, float zpos, int) : wp(scalar), xp(xpos), yp(ypos), zp(zpos) {} - inline bool QQuaternion::isNull() const { return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp); @@ -169,7 +163,7 @@ inline void QQuaternion::setScalar(qreal scalar) { wp = scalar; } inline QQuaternion QQuaternion::conjugate() const { - return QQuaternion(wp, -xp, -yp, -zp, 1); + return QQuaternion(wp, -xp, -yp, -zp); } inline QQuaternion &QQuaternion::operator+=(const QQuaternion &quaternion) @@ -201,18 +195,18 @@ inline QQuaternion &QQuaternion::operator*=(qreal factor) inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2) { - float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp); - float yy = (q1.wp - q1.yp) * (q2.wp + q2.zp); - float zz = (q1.wp + q1.yp) * (q2.wp - q2.zp); - float xx = ww + yy + zz; - float qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp)); - - float w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp); - float x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp); - float y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp); - float z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp); - - return QQuaternion(w, x, y, z, 1); + qreal ww = (q1.zp + q1.xp) * (q2.xp + q2.yp); + qreal yy = (q1.wp - q1.yp) * (q2.wp + q2.zp); + qreal zz = (q1.wp + q1.yp) * (q2.wp - q2.zp); + qreal xx = ww + yy + zz; + qreal qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp)); + + qreal w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp); + qreal x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp); + qreal y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp); + qreal z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp); + + return QQuaternion(w, x, y, z); } inline QQuaternion &QQuaternion::operator*=(const QQuaternion &quaternion) @@ -242,32 +236,32 @@ inline bool operator!=(const QQuaternion &q1, const QQuaternion &q2) 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, 1); + return QQuaternion(q1.wp + q2.wp, q1.xp + q2.xp, q1.yp + q2.yp, q1.zp + q2.zp); } 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, 1); + 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) { - return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor, 1); + return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor); } inline const QQuaternion operator*(const QQuaternion &quaternion, qreal factor) { - return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor, 1); + return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor); } inline const QQuaternion operator-(const QQuaternion &quaternion) { - return QQuaternion(-quaternion.wp, -quaternion.xp, -quaternion.yp, -quaternion.zp, 1); + return QQuaternion(-quaternion.wp, -quaternion.xp, -quaternion.yp, -quaternion.zp); } inline const QQuaternion operator/(const QQuaternion &quaternion, qreal divisor) { - return QQuaternion(quaternion.wp / divisor, quaternion.xp / divisor, quaternion.yp / divisor, quaternion.zp / divisor, 1); + return QQuaternion(quaternion.wp / divisor, quaternion.xp / divisor, quaternion.yp / divisor, quaternion.zp / divisor); } inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2) @@ -281,18 +275,18 @@ inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2) #ifndef QT_NO_VECTOR3D inline QQuaternion::QQuaternion(qreal scalar, const QVector3D& vector) - : wp(scalar), xp(vector.xp), yp(vector.yp), zp(vector.zp) {} + : wp(scalar), xp(vector.x()), yp(vector.y()), zp(vector.z()) {} inline void QQuaternion::setVector(const QVector3D& vector) { - xp = vector.xp; - yp = vector.yp; - zp = vector.zp; + xp = vector.x(); + yp = vector.y(); + zp = vector.z(); } inline QVector3D QQuaternion::vector() const { - return QVector3D(xp, yp, zp, 1); + return QVector3D(xp, yp, zp); } #endif @@ -307,11 +301,11 @@ inline void QQuaternion::setVector(qreal x, qreal y, qreal z) #ifndef QT_NO_VECTOR4D inline QQuaternion::QQuaternion(const QVector4D& vector) - : wp(vector.wp), xp(vector.xp), yp(vector.yp), zp(vector.zp) {} + : wp(vector.w()), xp(vector.x()), yp(vector.y()), zp(vector.z()) {} inline QVector4D QQuaternion::toVector4D() const { - return QVector4D(xp, yp, zp, wp, 1); + return QVector4D(xp, yp, zp, wp); } #endif diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h index 767517e..1e95865 100644 --- a/src/gui/math3d/qvector3d.h +++ b/src/gui/math3d/qvector3d.h @@ -54,7 +54,6 @@ QT_MODULE(Gui) class QMatrix4x4; class QVector2D; class QVector4D; -class QQuaternion; #ifndef QT_NO_VECTOR3D @@ -136,8 +135,6 @@ private: friend class QVector2D; friend class QVector4D; - friend class QQuaternion; - friend class QMatrix4x4; #ifndef QT_NO_MATRIX4X4 friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix); friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector); diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h index 4bd6639..520319a 100644 --- a/src/gui/math3d/qvector4d.h +++ b/src/gui/math3d/qvector4d.h @@ -54,7 +54,6 @@ QT_MODULE(Gui) class QMatrix4x4; class QVector2D; class QVector3D; -class QQuaternion; #ifndef QT_NO_VECTOR4D @@ -133,8 +132,6 @@ private: friend class QVector2D; friend class QVector3D; - friend class QQuaternion; - friend class QMatrix4x4; #ifndef QT_NO_MATRIX4X4 friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix); friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector); diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 56b55d0..bcc6c61 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -2288,6 +2288,58 @@ void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& 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 to a 2x2 matrix \a value. @@ -2296,8 +2348,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& size) */ void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value) { - if (location != -1) - glUniformMatrix2fv(location, 1, GL_FALSE, value.data()); + setUniformMatrix(glUniformMatrix2fv, location, value, 2, 2); } /*! @@ -2321,20 +2372,8 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value */ void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value) { -#if !defined(QT_OPENGL_ES_2) - if (location != -1) { - if (glUniformMatrix2x3fv) { - // OpenGL 2.1+: pass the matrix directly. - glUniformMatrix2x3fv(location, 1, GL_FALSE, value.data()); - } else { - // OpenGL 2.0: pass the matrix columns as a vector. - glUniform3fv(location, 2, value.data()); - } - } -#else - if (location != -1) - glUniform3fv(location, 2, value.data()); -#endif + setUniformGenericMatrix + (glUniformMatrix2x3fv, glUniform3fv, location, value, 2, 3); } /*! @@ -2358,20 +2397,8 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value */ void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value) { -#if !defined(QT_OPENGL_ES_2) - if (location != -1) { - if (glUniformMatrix2x4fv) { - // OpenGL 2.1+: pass the matrix directly. - glUniformMatrix2x4fv(location, 1, GL_FALSE, value.data()); - } else { - // OpenGL 2.0: pass the matrix columns as a vector. - glUniform4fv(location, 2, value.data()); - } - } -#else - if (location != -1) - glUniform4fv(location, 2, value.data()); -#endif + setUniformGenericMatrix + (glUniformMatrix2x4fv, glUniform4fv, location, value, 2, 4); } /*! @@ -2395,20 +2422,8 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value */ void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value) { -#if !defined(QT_OPENGL_ES_2) - if (location != -1) { - if (glUniformMatrix3x2fv) { - // OpenGL 2.1+: pass the matrix directly. - glUniformMatrix3x2fv(location, 1, GL_FALSE, value.data()); - } else { - // OpenGL 2.0: pass the matrix columns as a vector. - glUniform2fv(location, 3, value.data()); - } - } -#else - if (location != -1) - glUniform2fv(location, 3, value.data()); -#endif + setUniformGenericMatrix + (glUniformMatrix3x2fv, glUniform2fv, location, value, 3, 2); } /*! @@ -2432,8 +2447,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value */ void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value) { - if (location != -1) - glUniformMatrix3fv(location, 1, GL_FALSE, value.data()); + setUniformMatrix(glUniformMatrix3fv, location, value, 3, 3); } /*! @@ -2457,20 +2471,8 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value */ void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value) { -#if !defined(QT_OPENGL_ES_2) - if (location != -1) { - if (glUniformMatrix3x4fv) { - // OpenGL 2.1+: pass the matrix directly. - glUniformMatrix3x4fv(location, 1, GL_FALSE, value.data()); - } else { - // OpenGL 2.0: pass the matrix columns as a vector. - glUniform4fv(location, 3, value.data()); - } - } -#else - if (location != -1) - glUniform4fv(location, 3, value.data()); -#endif + setUniformGenericMatrix + (glUniformMatrix3x4fv, glUniform4fv, location, value, 3, 4); } /*! @@ -2494,20 +2496,8 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value */ void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value) { -#if !defined(QT_OPENGL_ES_2) - if (location != -1) { - if (glUniformMatrix4x2fv) { - // OpenGL 2.1+: pass the matrix directly. - glUniformMatrix4x2fv(location, 1, GL_FALSE, value.data()); - } else { - // OpenGL 2.0: pass the matrix columns as a vector. - glUniform2fv(location, 4, value.data()); - } - } -#else - if (location != -1) - glUniform2fv(location, 4, value.data()); -#endif + setUniformGenericMatrix + (glUniformMatrix4x2fv, glUniform2fv, location, value, 4, 2); } /*! @@ -2531,20 +2521,8 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value */ void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value) { -#if !defined(QT_OPENGL_ES_2) - if (location != -1) { - if (glUniformMatrix4x3fv) { - // OpenGL 2.1+: pass the matrix directly. - glUniformMatrix4x3fv(location, 1, GL_FALSE, value.data()); - } else { - // OpenGL 2.0: pass the matrix columns as a vector. - glUniform3fv(location, 4, value.data()); - } - } -#else - if (location != -1) - glUniform3fv(location, 4, value.data()); -#endif + setUniformGenericMatrix + (glUniformMatrix4x3fv, glUniform3fv, location, value, 4, 3); } /*! @@ -2568,8 +2546,7 @@ void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value */ void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value) { - if (location != -1) - glUniformMatrix4fv(location, 1, GL_FALSE, value.data()); + setUniformMatrix(glUniformMatrix4fv, location, value, 4, 4); } /*! @@ -2815,18 +2792,20 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *v setUniformValueArray(uniformLocation(name), values, count); } -// We may have to repack matrix arrays if the matrix types -// contain additional flag bits. Especially QMatrix4x4. +// We have to repack matrix arrays from qreal to GLfloat. #define setUniformMatrixArray(func,location,values,count,type,cols,rows) \ if (location == -1 || count <= 0) \ return; \ - if (count == 1 || sizeof(type) == cols * rows * sizeof(GLfloat)) { \ - func(location, count, GL_FALSE, values->constData()); \ + if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \ + func(location, count, GL_FALSE, \ + reinterpret_cast<const GLfloat *>(values[0].constData())); \ } else { \ QVarLengthArray<GLfloat> temp(cols * rows * count); \ for (int index = 0; index < count; ++index) { \ - qMemCopy(temp.data() + cols * rows * index, \ - values[index].constData(), cols * rows * sizeof(GLfloat)); \ + for (int index2 = 0; index2 < (cols * rows); ++index2) { \ + temp.data()[cols * rows * index + index2] = \ + values[index].constData()[index2]; \ + } \ } \ func(location, count, GL_FALSE, temp.constData()); \ } @@ -2834,16 +2813,20 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *v #define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \ if (location == -1 || count <= 0) \ return; \ - if (count == 1 || sizeof(type) == cols * rows * sizeof(GLfloat)) { \ + if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \ + const GLfloat *data = reinterpret_cast<const GLfloat *> \ + (values[0].constData()); \ if (func) \ - func(location, count, GL_FALSE, values->constData()); \ + func(location, count, GL_FALSE, data); \ else \ - colfunc(location, cols * count, values->constData()); \ + colfunc(location, count * cols, data); \ } else { \ QVarLengthArray<GLfloat> temp(cols * rows * count); \ for (int index = 0; index < count; ++index) { \ - qMemCopy(temp.data() + cols * rows * index, \ - values[index].constData(), cols * rows * sizeof(GLfloat)); \ + for (int index2 = 0; index2 < (cols * rows); ++index2) { \ + temp.data()[cols * rows * index + index2] = \ + values[index].constData()[index2]; \ + } \ } \ if (func) \ func(location, count, GL_FALSE, temp.constData()); \ @@ -2854,13 +2837,17 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *v #define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \ if (location == -1 || count <= 0) \ return; \ - if (count == 1 || sizeof(type) == cols * rows * sizeof(GLfloat)) { \ - colfunc(location, cols * count, values->constData()); \ + if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \ + const GLfloat *data = reinterpret_cast<const GLfloat *> \ + (values[0].constData()); \ + colfunc(location, count * cols, data); \ } else { \ QVarLengthArray<GLfloat> temp(cols * rows * count); \ for (int index = 0; index < count; ++index) { \ - qMemCopy(temp.data() + cols * rows * index, \ - values[index].constData(), cols * rows * sizeof(GLfloat)); \ + for (int index2 = 0; index2 < (cols * rows); ++index2) { \ + temp.data()[cols * rows * index + index2] = \ + values[index].constData()[index2]; \ + } \ } \ colfunc(location, count * cols, temp.constData()); \ } diff --git a/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp index fd5ef3e..6a7e625 100644 --- a/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/qmatrixnxn/tst_qmatrixnxn.cpp @@ -328,7 +328,7 @@ void tst_QMatrixNxN::setMatrix(QMatrix4x3& m, const qreal *values) // the internal data() array. void tst_QMatrixNxN::setMatrixDirect(QMatrix2x2& m, const qreal *values) { - float *data = m.data(); + qreal *data = m.data(); for (int row = 0; row < 2; ++row) { for (int col = 0; col < 2; ++col) { data[row + col * 2] = values[row * 2 + col]; @@ -337,7 +337,7 @@ void tst_QMatrixNxN::setMatrixDirect(QMatrix2x2& m, const qreal *values) } void tst_QMatrixNxN::setMatrixDirect(QMatrix3x3& m, const qreal *values) { - float *data = m.data(); + qreal *data = m.data(); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { data[row + col * 3] = values[row * 3 + col]; @@ -346,7 +346,7 @@ void tst_QMatrixNxN::setMatrixDirect(QMatrix3x3& m, const qreal *values) } void tst_QMatrixNxN::setMatrixDirect(QMatrix4x4& m, const qreal *values) { - float *data = m.data(); + qreal *data = m.data(); for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { data[row + col * 4] = values[row * 4 + col]; @@ -355,7 +355,7 @@ void tst_QMatrixNxN::setMatrixDirect(QMatrix4x4& m, const qreal *values) } void tst_QMatrixNxN::setMatrixDirect(QMatrix4x3& m, const qreal *values) { - float *data = m.data(); + qreal *data = m.data(); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 4; ++col) { data[row + col * 3] = values[row * 4 + col]; @@ -363,55 +363,42 @@ void tst_QMatrixNxN::setMatrixDirect(QMatrix4x3& m, const qreal *values) } } -// qFuzzyCompare isn't always "fuzzy" enough to handle conversion -// between float, double, and qreal. So create "fuzzier" compares. -static bool fuzzyCompare(float x, float y, qreal epsilon = 0.001) +// QVector2/3/4D use float internally, which can sometimes lead +// to precision issues when converting to and from qreal during +// operations involving QMatrix4x4. This fuzzy compare is slightly +// "fuzzier" than the default qFuzzyCompare for qreal to compensate. +static bool fuzzyCompare(qreal x, qreal y) { - float diff = x - y; - if (diff < 0.0f) - diff = -diff; - return (diff < epsilon); + return qFuzzyIsNull((float)(x - y)); } -static bool fuzzyCompare(const QVector3D &v1, const QVector3D &v2, qreal epsilon = 0.001) +static bool fuzzyCompare(const QVector3D &v1, const QVector3D &v2) { - if (!fuzzyCompare(v1.x(), v2.x(), epsilon)) + if (!fuzzyCompare(v1.x(), v2.x())) return false; - if (!fuzzyCompare(v1.y(), v2.y(), epsilon)) + if (!fuzzyCompare(v1.y(), v2.y())) return false; - if (!fuzzyCompare(v1.z(), v2.z(), epsilon)) + if (!fuzzyCompare(v1.z(), v2.z())) return false; return true; } -static bool matrixFuzzyCompare(const QMatrix4x4 &m1, const QMatrix4x4 &m2) -{ - bool ret = true; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - ret = ret && fuzzyCompare(m1(i, j), m2(i, j)); - } - } - - return ret; -} - // Determine if a matrix is the same as a specified array of values. // The values are assumed to be specified in row-major order. bool tst_QMatrixNxN::isSame(const QMatrix2x2& m, const qreal *values) { - const float *mv = m.constData(); + const qreal *mv = m.constData(); for (int row = 0; row < 2; ++row) { for (int col = 0; col < 2; ++col) { // Check the values using the operator() function. - if (!fuzzyCompare((float)(m(row, col)), (float)(values[row * 2 + col]))) { + if (!fuzzyCompare(m(row, col), values[row * 2 + col])) { qDebug() << "floating-point failure at" << row << col << "actual =" << m(row, col) << "expected =" << values[row * 2 + col]; return false; } // Check the values using direct access, which verifies that the values // are stored internally in column-major order. - if (!fuzzyCompare((float)(mv[col * 2 + row]), (float)(values[row * 2 + col]))) { + if (!fuzzyCompare(mv[col * 2 + row], values[row * 2 + col])) { qDebug() << "column floating-point failure at" << row << col << "actual =" << mv[col * 2 + row] << "expected =" << values[row * 2 + col]; return false; } @@ -421,18 +408,18 @@ bool tst_QMatrixNxN::isSame(const QMatrix2x2& m, const qreal *values) } bool tst_QMatrixNxN::isSame(const QMatrix3x3& m, const qreal *values) { - const float *mv = m.constData(); + const qreal *mv = m.constData(); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { // Check the values using the operator() access function. - if (!fuzzyCompare((float)(m(row, col)), (float)(values[row * 3 + col]))) { + if (!fuzzyCompare(m(row, col), values[row * 3 + col])) { qDebug() << "floating-point failure at" << row << col << "actual =" << m(row, col) << "expected =" << values[row * 3 + col]; return false; } // Check the values using direct access, which verifies that the values // are stored internally in column-major order. - if (!fuzzyCompare((float)(mv[col * 3 + row]), (float)(values[row * 3 + col]))) { + if (!fuzzyCompare(mv[col * 3 + row], values[row * 3 + col])) { qDebug() << "column floating-point failure at" << row << col << "actual =" << mv[col * 3 + row] << "expected =" << values[row * 3 + col]; return false; } @@ -442,18 +429,18 @@ bool tst_QMatrixNxN::isSame(const QMatrix3x3& m, const qreal *values) } bool tst_QMatrixNxN::isSame(const QMatrix4x4& m, const qreal *values) { - const float *mv = m.constData(); + const qreal *mv = m.constData(); for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { // Check the values using the operator() access function. - if (!fuzzyCompare((float)(m(row, col)), (float)(values[row * 4 + col]))) { + if (!fuzzyCompare(m(row, col), values[row * 4 + col])) { qDebug() << "floating-point failure at" << row << col << "actual =" << m(row, col) << "expected =" << values[row * 4 + col]; return false; } // Check the values using direct access, which verifies that the values // are stored internally in column-major order. - if (!fuzzyCompare((float)(mv[col * 4 + row]), (float)(values[row * 4 + col]))) { + if (!fuzzyCompare(mv[col * 4 + row], values[row * 4 + col])) { qDebug() << "column floating-point failure at" << row << col << "actual =" << mv[col * 4 + row] << "expected =" << values[row * 4 + col]; return false; } @@ -463,18 +450,18 @@ bool tst_QMatrixNxN::isSame(const QMatrix4x4& m, const qreal *values) } bool tst_QMatrixNxN::isSame(const QMatrix4x3& m, const qreal *values) { - const float *mv = m.constData(); + const qreal *mv = m.constData(); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 4; ++col) { // Check the values using the operator() access function. - if (!fuzzyCompare((float)(m(row, col)), (float)(values[row * 4 + col]))) { + if (!fuzzyCompare(m(row, col), values[row * 4 + col])) { qDebug() << "floating-point failure at" << row << col << "actual =" << m(row, col) << "expected =" << values[row * 4 + col]; return false; } // Check the values using direct access, which verifies that the values // are stored internally in column-major order. - if (!fuzzyCompare((float)(mv[col * 3 + row]), (float)(values[row * 4 + col]))) { + if (!fuzzyCompare(mv[col * 3 + row], values[row * 4 + col])) { qDebug() << "column floating-point failure at" << row << col << "actual =" << mv[col * 3 + row] << "expected =" << values[row * 4 + col]; return false; } @@ -533,7 +520,7 @@ void tst_QMatrixNxN::create2x2() qreal vals[4]; m6.toValueArray(vals); for (int index = 0; index < 4; ++index) - QCOMPARE((float)(vals[index]), (float)(uniqueValues2[index])); + QCOMPARE(vals[index], uniqueValues2[index]); } // Test the creation of QMatrix3x3 objects in various ways: @@ -568,7 +555,7 @@ void tst_QMatrixNxN::create3x3() qreal vals[9]; m6.toValueArray(vals); for (int index = 0; index < 9; ++index) - QCOMPARE((float)(vals[index]), (float)(uniqueValues3[index])); + QCOMPARE(vals[index], uniqueValues3[index]); } // Test the creation of QMatrix4x4 objects in various ways: @@ -603,7 +590,7 @@ void tst_QMatrixNxN::create4x4() qreal vals[16]; m6.toValueArray(vals); for (int index = 0; index < 16; ++index) - QCOMPARE((float)(vals[index]), (float)(uniqueValues4[index])); + QCOMPARE(vals[index], uniqueValues4[index]); QMatrix4x4 m8 (uniqueValues4[0], uniqueValues4[1], uniqueValues4[2], uniqueValues4[3], @@ -645,7 +632,7 @@ void tst_QMatrixNxN::create4x3() qreal vals[12]; m6.toValueArray(vals); for (int index = 0; index < 12; ++index) - QCOMPARE((float)(vals[index]), (float)(uniqueValues4x3[index])); + QCOMPARE(vals[index], uniqueValues4x3[index]); } // Test isIdentity() for 2x2 matrices. @@ -1303,7 +1290,7 @@ void tst_QMatrixNxN::multiply4x3() QMatrix4x3 m1((const qreal *)m1Values); QMatrix3x4 m2((const qreal *)m2Values); - QGenericMatrix<3, 3, qreal, float> m4; + QGenericMatrix<3, 3, qreal> m4; m4 = m1 * m2; qreal values[9]; m4.toValueArray(values); @@ -1882,7 +1869,7 @@ void tst_QMatrixNxN::inverted4x4() Matrix4 m1alt; memcpy(m1alt.v, (const qreal *)m1Values, sizeof(m1alt.v)); - QCOMPARE((float)(m1.determinant()), (float)(m4Determinant(m1alt))); + QCOMPARE(m1.determinant(), m4Determinant(m1alt)); QMatrix4x4 m2; bool inv; @@ -1917,7 +1904,7 @@ void tst_QMatrixNxN::inverted4x4() void tst_QMatrixNxN::orthonormalInverse4x4() { QMatrix4x4 m1; - QVERIFY(matrixFuzzyCompare(m1.inverted(), m1)); + QVERIFY(qFuzzyCompare(m1.inverted(), m1)); QMatrix4x4 m2; m2.rotate(45.0, 1.0, 0.0, 0.0); @@ -1930,14 +1917,14 @@ void tst_QMatrixNxN::orthonormalInverse4x4() QMatrix4x4 m3 = m2; m3.inferSpecialType(); bool invertible; - QVERIFY(matrixFuzzyCompare(m2.inverted(&invertible), m3.inverted())); + QVERIFY(qFuzzyCompare(m2.inverted(&invertible), m3.inverted())); QVERIFY(invertible); QMatrix4x4 m4; m4.rotate(45.0, 0.0, 1.0, 0.0); QMatrix4x4 m5 = m4; m5.inferSpecialType(); - QVERIFY(matrixFuzzyCompare(m4.inverted(), m5.inverted())); + QVERIFY(qFuzzyCompare(m4.inverted(), m5.inverted())); QMatrix4x4 m6; m1.rotate(88, 0.0, 0.0, 1.0); @@ -1945,7 +1932,7 @@ void tst_QMatrixNxN::orthonormalInverse4x4() m1.rotate(25, 1.0, 0.0, 0.0); QMatrix4x4 m7 = m6; m7.inferSpecialType(); - QVERIFY(matrixFuzzyCompare(m6.inverted(), m7.inverted())); + QVERIFY(qFuzzyCompare(m6.inverted(), m7.inverted())); } // Test the generation and use of 4x4 scale matrices. @@ -2345,7 +2332,7 @@ void tst_QMatrixNxN::rotate4x4() QMatrix4x4 m3(uniqueValues4); QMatrix4x4 m4(m3); m4.rotate(angle, x, y, z); - QVERIFY(matrixFuzzyCompare(m4, m3 * m1)); + QVERIFY(qFuzzyCompare(m4, m3 * m1)); // Null vectors don't make sense for quaternion rotations. if (x != 0 || y != 0 || z != 0) { @@ -2417,8 +2404,8 @@ void tst_QMatrixNxN::rotate4x4() QPointF p3(2.0f, 3.0f); QPointF p4 = m1 * p3; - QVERIFY(fuzzyCompare((float)(p4.x()), p1x)); - QVERIFY(fuzzyCompare((float)(p4.y()), p1y)); + QVERIFY(fuzzyCompare(p4.x(), p1x)); + QVERIFY(fuzzyCompare(p4.y(), p1y)); if (x != 0 || y != 0 || z != 0) { QQuaternion q = QQuaternion::fromAxisAndAngle(QVector3D(x, y, z), angle); @@ -2911,14 +2898,12 @@ void tst_QMatrixNxN::extractAxisRotation() m.extractAxisRotation(extractedAngle, extractedAxis); - qreal epsilon = 0.001; - if (angle > 180) { - QVERIFY(fuzzyCompare(360.0f - angle, extractedAngle, epsilon)); - QVERIFY(fuzzyCompare(extractedAxis, -origAxis, epsilon)); + QVERIFY(fuzzyCompare(360.0f - angle, extractedAngle)); + QVERIFY(fuzzyCompare(extractedAxis, -origAxis)); } else { - QVERIFY(fuzzyCompare(angle, extractedAngle, epsilon)); - QVERIFY(fuzzyCompare(extractedAxis, origAxis, epsilon)); + QVERIFY(fuzzyCompare(angle, extractedAngle)); + QVERIFY(fuzzyCompare(extractedAxis, origAxis)); } } @@ -2959,11 +2944,9 @@ void tst_QMatrixNxN::extractTranslation() QVector3D vec = rotation.extractTranslation(); - qreal epsilon = 0.001; - - QVERIFY(fuzzyCompare(vec.x(), x, epsilon)); - QVERIFY(fuzzyCompare(vec.y(), y, epsilon)); - QVERIFY(fuzzyCompare(vec.z(), z, epsilon)); + QVERIFY(fuzzyCompare(vec.x(), x)); + QVERIFY(fuzzyCompare(vec.y(), y)); + QVERIFY(fuzzyCompare(vec.z(), z)); QMatrix4x4 lookAt; QVector3D eye(1.5f, -2.5f, 2.5f); @@ -2973,9 +2956,9 @@ void tst_QMatrixNxN::extractTranslation() QVector3D extEye = lookAt.extractTranslation(); - QVERIFY(fuzzyCompare(eye.x(), -extEye.x(), epsilon)); - QVERIFY(fuzzyCompare(eye.y(), -extEye.y(), epsilon)); - QVERIFY(fuzzyCompare(eye.z(), -extEye.z(), epsilon)); + QVERIFY(fuzzyCompare(eye.x(), -extEye.x())); + QVERIFY(fuzzyCompare(eye.y(), -extEye.y())); + QVERIFY(fuzzyCompare(eye.z(), -extEye.z())); } // Copy of "flagBits" in qmatrix4x4.h. @@ -2990,7 +2973,7 @@ enum { // Structure that allows direct access to "flagBits" for testing. struct Matrix4x4 { - float m[4][4]; + qreal m[4][4]; int flagBits; }; @@ -3134,8 +3117,8 @@ void tst_QMatrixNxN::convertQMatrix() QMatrix4x4 m6(m5); QPointF p6 = m6 * QPointF(100.0, 150.0); - QVERIFY(fuzzyCompare(p5.x(), p6.x(), 0.005)); - QVERIFY(fuzzyCompare(p5.y(), p6.y(), 0.005)); + QVERIFY(fuzzyCompare(p5.x(), p6.x())); + QVERIFY(fuzzyCompare(p5.y(), p6.y())); QMatrix m7 = m6.toAffine(); QVERIFY(fuzzyCompare(m5.m11(), m7.m11())); @@ -3181,8 +3164,8 @@ void tst_QMatrixNxN::convertQTransform() QMatrix4x4 m6(m5); QPointF p6 = m6 * QPointF(100.0, 150.0); - QVERIFY(fuzzyCompare(p5.x(), p6.x(), 0.005)); - QVERIFY(fuzzyCompare(p5.y(), p6.y(), 0.005)); + QVERIFY(fuzzyCompare(p5.x(), p6.x())); + QVERIFY(fuzzyCompare(p5.y(), p6.y())); QTransform m7 = m6.toTransform(); QVERIFY(fuzzyCompare(m5.m11(), m7.m11())); diff --git a/tests/auto/qquaternion/tst_qquaternion.cpp b/tests/auto/qquaternion/tst_qquaternion.cpp index 24427c3..e3c4cd6 100644 --- a/tests/auto/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/qquaternion/tst_qquaternion.cpp @@ -98,14 +98,11 @@ private slots: void metaTypes(); }; -// qFuzzyCompare isn't always "fuzzy" enough to handle conversion -// between float, double, and qreal. So create "fuzzier" compares. -static bool fuzzyCompare(float x, float y) -{ - float diff = x - y; - if (diff < 0.0f) - diff = -diff; - return (diff < 0.001); +// 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: @@ -250,8 +247,8 @@ void tst_QQuaternion::length() QFETCH(qreal, len); QQuaternion v(w, x, y, z); - QCOMPARE((float)(v.length()), (float)len); - QCOMPARE((float)(v.lengthSquared()), (float)(x * x + y * y + z * z + w * w)); + QCOMPARE(v.length(), len); + QCOMPARE(v.lengthSquared(), x * x + y * y + z * z + w * w); } // Test the unit vector conversion for quaternions. @@ -273,11 +270,11 @@ void tst_QQuaternion::normalized() if (v.isNull()) QVERIFY(u.isNull()); else - QCOMPARE((float)(u.length()), (float)1.0f); - QCOMPARE((float)(u.x() * len), (float)(v.x())); - QCOMPARE((float)(u.y() * len), (float)(v.y())); - QCOMPARE((float)(u.z() * len), (float)(v.z())); - QCOMPARE((float)(u.scalar() * len), (float)(v.scalar())); + QCOMPARE(u.length(), qreal(1.0f)); + QCOMPARE(u.x() * len, v.x()); + QCOMPARE(u.y() * len, v.y()); + QCOMPARE(u.z() * len, v.z()); + QCOMPARE(u.scalar() * len, v.scalar()); } // Test the unit vector conversion for quaternions. @@ -299,7 +296,7 @@ void tst_QQuaternion::normalize() if (isNull) QVERIFY(v.isNull()); else - QCOMPARE((float)(v.length()), (float)1.0f); + QCOMPARE(v.length(), qreal(1.0f)); } // Test the comparison operators for quaternions. diff --git a/tests/auto/qvectornd/tst_qvectornd.cpp b/tests/auto/qvectornd/tst_qvectornd.cpp index 243b172..75c2eb5 100644 --- a/tests/auto/qvectornd/tst_qvectornd.cpp +++ b/tests/auto/qvectornd/tst_qvectornd.cpp @@ -144,14 +144,13 @@ private slots: void metaTypes(); }; -// qFuzzyCompare isn't always "fuzzy" enough to handle conversion -// between float, double, and qreal. So create "fuzzier" compares. -static bool fuzzyCompare(float x, float y) +// QVector2/3/4D use float internally, which can sometimes lead +// to precision issues when converting to and from qreal. +// This fuzzy compare is slightly "fuzzier" than the default +// qFuzzyCompare for qreal to compensate. +static bool fuzzyCompare(qreal x, qreal y) { - float diff = x - y; - if (diff < 0.0f) - diff = -diff; - return (diff < 0.001); + return qFuzzyIsNull((float)(x - y)); } // Test the creation of QVector2D objects in various ways: @@ -577,8 +576,8 @@ void tst_QVector::length2() QFETCH(qreal, len); QVector2D v(x, y); - QCOMPARE((float)(v.length()), (float)len); - QCOMPARE((float)(v.lengthSquared()), (float)(x * x + y * y)); + QCOMPARE(v.length(), len); + QCOMPARE(v.lengthSquared(), x * x + y * y); } // Test vector length computation for 3D vectors. @@ -606,8 +605,8 @@ void tst_QVector::length3() QFETCH(qreal, len); QVector3D v(x, y, z); - QCOMPARE((float)(v.length()), (float)len); - QCOMPARE((float)(v.lengthSquared()), (float)(x * x + y * y + z * z)); + QCOMPARE(v.length(), len); + QCOMPARE(v.lengthSquared(), x * x + y * y + z * z); } // Test vector length computation for 4D vectors. @@ -639,8 +638,8 @@ void tst_QVector::length4() QFETCH(qreal, len); QVector4D v(x, y, z, w); - QCOMPARE((float)(v.length()), (float)len); - QCOMPARE((float)(v.lengthSquared()), (float)(x * x + y * y + z * z + w * w)); + QCOMPARE(v.length(), len); + QCOMPARE(v.lengthSquared(), x * x + y * y + z * z + w * w); } // Test the unit vector conversion for 2D vectors. @@ -660,9 +659,9 @@ void tst_QVector::normalized2() if (v.isNull()) QVERIFY(u.isNull()); else - QCOMPARE((float)(u.length()), (float)1.0f); - QCOMPARE((float)(u.x() * len), (float)(v.x())); - QCOMPARE((float)(u.y() * len), (float)(v.y())); + QVERIFY(fuzzyCompare(u.length(), qreal(1.0f))); + QVERIFY(fuzzyCompare(u.x() * len, v.x())); + QVERIFY(fuzzyCompare(u.y() * len, v.y())); } // Test the unit vector conversion for 3D vectors. @@ -683,10 +682,10 @@ void tst_QVector::normalized3() if (v.isNull()) QVERIFY(u.isNull()); else - QCOMPARE((float)(u.length()), (float)1.0f); - QCOMPARE((float)(u.x() * len), (float)(v.x())); - QCOMPARE((float)(u.y() * len), (float)(v.y())); - QCOMPARE((float)(u.z() * len), (float)(v.z())); + QVERIFY(fuzzyCompare(u.length(), qreal(1.0f))); + QVERIFY(fuzzyCompare(u.x() * len, v.x())); + QVERIFY(fuzzyCompare(u.y() * len, v.y())); + QVERIFY(fuzzyCompare(u.z() * len, v.z())); } // Test the unit vector conversion for 4D vectors. @@ -708,11 +707,11 @@ void tst_QVector::normalized4() if (v.isNull()) QVERIFY(u.isNull()); else - QCOMPARE((float)(u.length()), (float)1.0f); - QCOMPARE((float)(u.x() * len), (float)(v.x())); - QCOMPARE((float)(u.y() * len), (float)(v.y())); - QCOMPARE((float)(u.z() * len), (float)(v.z())); - QCOMPARE((float)(u.w() * len), (float)(v.w())); + QVERIFY(fuzzyCompare(u.length(), qreal(1.0f))); + QVERIFY(fuzzyCompare(u.x() * len, v.x())); + QVERIFY(fuzzyCompare(u.y() * len, v.y())); + QVERIFY(fuzzyCompare(u.z() * len, v.z())); + QVERIFY(fuzzyCompare(u.w() * len, v.w())); } // Test the unit vector conversion for 2D vectors. @@ -732,7 +731,7 @@ void tst_QVector::normalize2() if (isNull) QVERIFY(v.isNull()); else - QCOMPARE((float)(v.length()), (float)1.0f); + QVERIFY(fuzzyCompare(v.length(), qreal(1.0f))); } // Test the unit vector conversion for 3D vectors. @@ -753,7 +752,7 @@ void tst_QVector::normalize3() if (isNull) QVERIFY(v.isNull()); else - QCOMPARE((float)(v.length()), (float)1.0f); + QVERIFY(fuzzyCompare(v.length(), qreal(1.0f))); } // Test the unit vector conversion for 4D vectors. @@ -775,7 +774,7 @@ void tst_QVector::normalize4() if (isNull) QVERIFY(v.isNull()); else - QCOMPARE((float)(v.length()), (float)1.0f); + QVERIFY(fuzzyCompare(v.length(), qreal(1.0f))); } // Test the comparison operators for 2D vectors. diff --git a/tests/benchmarks/qmatrix4x4/tst_qmatrix4x4.cpp b/tests/benchmarks/qmatrix4x4/tst_qmatrix4x4.cpp index b4c8202..c72bc27 100644 --- a/tests/benchmarks/qmatrix4x4/tst_qmatrix4x4.cpp +++ b/tests/benchmarks/qmatrix4x4/tst_qmatrix4x4.cpp @@ -171,9 +171,9 @@ void tst_QMatrix4x4::multiplyDirect() QMatrix4x4 m3; - const float *m1data = m1.constData(); - const float *m2data = m2.constData(); - float *m3data = m3.data(); + const qreal *m1data = m1.constData(); + const qreal *m2data = m2.constData(); + qreal *m3data = m3.data(); QBENCHMARK { for (int row = 0; row < 4; ++row) { @@ -266,9 +266,9 @@ void tst_QMatrix4x4::mapVectorDirect() { QFETCH(QMatrix4x4, m1); - const float *m1data = m1.constData(); - float v[4] = {10.5f, -2.0f, 3.0f, 1.0f}; - float result[4]; + const qreal *m1data = m1.constData(); + qreal v[4] = {10.5f, -2.0f, 3.0f, 1.0f}; + qreal result[4]; QBENCHMARK { for (int row = 0; row < 4; ++row) { |