diff options
Diffstat (limited to 'src/gui/math3d')
-rw-r--r-- | src/gui/math3d/qgenericmatrix.cpp | 22 | ||||
-rw-r--r-- | src/gui/math3d/qgenericmatrix.h | 15 | ||||
-rw-r--r-- | src/gui/math3d/qmatrix4x4.cpp | 50 | ||||
-rw-r--r-- | src/gui/math3d/qmatrix4x4.h | 22 | ||||
-rw-r--r-- | src/gui/math3d/qquaternion.cpp | 316 | ||||
-rw-r--r-- | src/gui/math3d/qquaternion.h | 61 | ||||
-rw-r--r-- | src/gui/math3d/qvector2d.cpp | 49 | ||||
-rw-r--r-- | src/gui/math3d/qvector2d.h | 29 | ||||
-rw-r--r-- | src/gui/math3d/qvector3d.cpp | 114 | ||||
-rw-r--r-- | src/gui/math3d/qvector3d.h | 34 | ||||
-rw-r--r-- | src/gui/math3d/qvector4d.cpp | 49 | ||||
-rw-r--r-- | src/gui/math3d/qvector4d.h | 31 |
12 files changed, 679 insertions, 113 deletions
diff --git a/src/gui/math3d/qgenericmatrix.cpp b/src/gui/math3d/qgenericmatrix.cpp index 995cf1716c..7b46bb452c 100644 --- a/src/gui/math3d/qgenericmatrix.cpp +++ b/src/gui/math3d/qgenericmatrix.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -61,6 +61,14 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QGenericMatrix::QGenericMatrix(Qt::Initialization) + \since 5.5 + \internal + + Constructs a NxM matrix without initializing the contents. +*/ + +/*! \fn QGenericMatrix::QGenericMatrix(const QGenericMatrix<N, M, T>& other) Constructs a copy of \a other. diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h index 5b45ab7fa1..afce9d935e 100644 --- a/src/gui/math3d/qgenericmatrix.h +++ b/src/gui/math3d/qgenericmatrix.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -46,6 +46,7 @@ class QGenericMatrix { public: QGenericMatrix(); + explicit QGenericMatrix(Qt::Initialization) {} QGenericMatrix(const QGenericMatrix<N, M, T>& other); explicit QGenericMatrix(const T *values); diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index c8a036918c..c196f7cff8 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -76,6 +76,14 @@ static const float inv_dist_to_plane = 1.0f / 1024.0f; */ /*! + \fn QMatrix4x4::QMatrix4x4(Qt::Initialization) + \since 5.5 + \internal + + Constructs a matrix without initializing the contents. +*/ + +/*! Constructs a matrix from the given 16 floating-point \a values. The contents of the array \a values is assumed to be in row-major order. @@ -290,6 +298,18 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform) */ /*! + \fn bool QMatrix4x4::isAffine() const + \since 5.5 + + Returns \c true if this matrix is affine matrix; false otherwise. + + An affine matrix is a 4x4 matrix with row 3 equal to (0, 0, 0, 1), + e.g. no projective coefficients. + + \sa isIdentity() +*/ + +/*! \fn bool QMatrix4x4::isIdentity() const Returns \c true if this matrix is the identity; false otherwise. @@ -1105,8 +1125,8 @@ void QMatrix4x4::rotate(float angle, float x, float y, float z) c = -1.0f; } else { float a = angle * M_PI / 180.0f; - c = cosf(a); - s = sinf(a); + c = std::cos(a); + s = std::sin(a); } if (x == 0.0f) { if (y == 0.0f) { @@ -1166,7 +1186,7 @@ void QMatrix4x4::rotate(float angle, float x, float y, float z) double(y) * double(y) + double(z) * double(z); if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) { - len = sqrt(len); + len = std::sqrt(len); x = float(double(x) / len); y = float(double(y) / len); z = float(double(z) / len); @@ -1214,8 +1234,8 @@ void QMatrix4x4::projectedRotate(float angle, float x, float y, float z) c = -1.0f; } else { float a = angle * M_PI / 180.0f; - c = cosf(a); - s = sinf(a); + c = std::cos(a); + s = std::sin(a); } if (x == 0.0f) { if (y == 0.0f) { @@ -1262,7 +1282,7 @@ void QMatrix4x4::projectedRotate(float angle, float x, float y, float z) double(y) * double(y) + double(z) * double(z); if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) { - len = sqrt(len); + len = std::sqrt(len); x = float(double(x) / len); y = float(double(y) / len); z = float(double(z) / len); @@ -1467,10 +1487,10 @@ void QMatrix4x4::perspective(float verticalAngle, float aspectRatio, float nearP // Construct the projection. QMatrix4x4 m(1); float radians = (verticalAngle / 2.0f) * M_PI / 180.0f; - float sine = sinf(radians); + float sine = std::sin(radians); if (sine == 0.0f) return; - float cotan = cosf(radians) / sine; + float cotan = std::cos(radians) / sine; float clip = farPlane - nearPlane; m.m[0][0] = cotan / aspectRatio; m.m[1][0] = 0.0f; diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index 31a4dbf1ca..234a8502d9 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -53,6 +53,7 @@ class Q_GUI_EXPORT QMatrix4x4 { public: inline QMatrix4x4() { setToIdentity(); } + explicit QMatrix4x4(Qt::Initialization) {} explicit QMatrix4x4(const float *values); inline QMatrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, @@ -77,6 +78,8 @@ public: inline void setRow(int index, const QVector4D& value); #endif + inline bool isAffine() const; + inline bool isIdentity() const; inline void setToIdentity(); @@ -302,6 +305,11 @@ inline void QMatrix4x4::setRow(int index, const QVector4D& value) Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor); +inline bool QMatrix4x4::isAffine() const +{ + return m[0][3] == 0.0f && m[1][3] == 0.0f && m[2][3] == 0.0f && m[3][3] == 1.0f; +} + inline bool QMatrix4x4::isIdentity() const { if (flagBits == Identity) diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index f1af8922ca..f2e79cb834 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -63,6 +63,14 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QQuaternion::QQuaternion(Qt::Initialization) + \since 5.5 + \internal + + Constructs a quaternion without initializing the contents. +*/ + +/*! \fn QQuaternion::QQuaternion(float scalar, float xpos, float ypos, float zpos) Constructs a quaternion with the vector (\a xpos, \a ypos, \a zpos) @@ -211,7 +219,7 @@ QT_BEGIN_NAMESPACE */ float QQuaternion::length() const { - return qSqrt(xp * xp + yp * yp + zp * zp + wp * wp); + return std::sqrt(xp * xp + yp * yp + zp * zp + wp * wp); } /*! @@ -244,7 +252,7 @@ QQuaternion QQuaternion::normalized() const if (qFuzzyIsNull(len - 1.0f)) return *this; else if (!qFuzzyIsNull(len)) - return *this / qSqrt(len); + return *this / std::sqrt(len); else return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f); } @@ -265,7 +273,7 @@ void QQuaternion::normalize() if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) return; - len = qSqrt(len); + len = std::sqrt(len); xp /= len; yp /= len; @@ -274,6 +282,16 @@ void QQuaternion::normalize() } /*! + \fn QQuaternion QQuaternion::inverted() const + \since 5.5 + + Returns the inverse of this quaternion. + If this quaternion is null, then a null quaternion is returned. + + \sa isNull(), length() +*/ + +/*! \fn QQuaternion QQuaternion::conjugate() const Returns the conjugate of this quaternion, which is @@ -345,8 +363,21 @@ QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const #ifndef QT_NO_VECTOR3D /*! + \fn void QQuaternion::toAxisAndAngle(QVector3D *axis, float *angle) const + \since 5.5 + \overload + + Extracts a 3D axis \a axis and a rotating angle \a angle (in degrees) + that corresponds to this quaternion. + + \sa fromAxisAndAngle() +*/ + +/*! Creates a normalized quaternion that corresponds to rotating through \a angle degrees about the specified 3D \a axis. + + \sa toAxisAndAngle() */ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, float angle) { @@ -355,8 +386,8 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, float angle) // We normalize the result just in case the values are close // to zero, as suggested in the above FAQ. float a = (angle / 2.0f) * M_PI / 180.0f; - float s = sinf(a); - float c = cosf(a); + float s = std::sin(a); + float c = std::cos(a); QVector3D ax = axis.normalized(); return QQuaternion(c, ax.x() * s, ax.y() * s, ax.z() * s).normalized(); } @@ -364,24 +395,271 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, float angle) #endif /*! + \since 5.5 + + Extracts a 3D axis (\a x, \a y, \a z) and a rotating angle \a angle (in degrees) + that corresponds to this quaternion. + + \sa fromAxisAndAngle() +*/ +void QQuaternion::toAxisAndAngle(float *x, float *y, float *z, float *angle) const +{ + Q_ASSERT(x && y && z && angle); + + // The quaternion representing the rotation is + // q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k) + + float length = xp * xp + yp * yp + zp * zp; + if (!qFuzzyIsNull(length)) { + *x = xp; + *y = yp; + *z = zp; + if (!qFuzzyIsNull(length - 1.0f)) { + length = std::sqrt(length); + *x /= length; + *y /= length; + *z /= length; + } + *angle = 2.0f * std::acos(wp); + } else { + // angle is 0 (mod 2*pi), so any axis will fit + *x = *y = *z = *angle = 0.0f; + } + + *angle = qRadiansToDegrees(*angle); +} + +/*! Creates a normalized quaternion that corresponds to rotating through \a angle degrees about the 3D axis (\a x, \a y, \a z). + + \sa toAxisAndAngle() */ QQuaternion QQuaternion::fromAxisAndAngle (float x, float y, float z, float angle) { - float length = qSqrt(x * x + y * y + z * z); + float length = std::sqrt(x * x + y * y + z * z); if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) { x /= length; y /= length; z /= length; } float a = (angle / 2.0f) * M_PI / 180.0f; - float s = sinf(a); - float c = cosf(a); + float s = std::sin(a); + float c = std::cos(a); return QQuaternion(c, x * s, y * s, z * s).normalized(); } +#ifndef QT_NO_VECTOR3D + +/*! + \fn QVector3D QQuaternion::toEulerAngles() const + \since 5.5 + \overload + + Calculates \a roll, \a pitch, and \a yaw Euler angles (in degrees) + that corresponds to this quaternion. + + \sa fromEulerAngles() +*/ + +/*! + \fn QQuaternion QQuaternion::fromEulerAngles(const QVector3D &eulerAngles) + \since 5.5 + \overload + + Creates a quaternion that corresponds to a rotation of + \a eulerAngles.z() degrees around the z axis, \a eulerAngles.x() degrees around the x axis, + and \a eulerAngles.y() degrees around the y axis (in that order). + + \sa toEulerAngles() +*/ + +#endif // QT_NO_VECTOR3D + +/*! + \since 5.5 + + Calculates \a roll, \a pitch, and \a yaw Euler angles (in degrees) + that corresponds to this quaternion. + + \sa fromEulerAngles() +*/ +void QQuaternion::toEulerAngles(float *pitch, float *yaw, float *roll) const +{ + Q_ASSERT(pitch && yaw && roll); + + // Algorithm from: + // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q37 + + float xx = xp * xp; + float xy = xp * yp; + float xz = xp * zp; + float xw = xp * wp; + float yy = yp * yp; + float yz = yp * zp; + float yw = yp * wp; + float zz = zp * zp; + float zw = zp * wp; + + const float lengthSquared = xx + yy + zz + wp * wp; + if (!qFuzzyIsNull(lengthSquared - 1.0f) && !qFuzzyIsNull(lengthSquared)) { + xx /= lengthSquared; + xy /= lengthSquared; // same as (xp / length) * (yp / length) + xz /= lengthSquared; + xw /= lengthSquared; + yy /= lengthSquared; + yz /= lengthSquared; + yw /= lengthSquared; + zz /= lengthSquared; + zw /= lengthSquared; + } + + *pitch = std::asin(-2.0f * (yz - xw)); + if (*pitch < M_PI_2) { + if (*pitch > -M_PI_2) { + *yaw = std::atan2(2.0f * (xz + yw), 1.0f - 2.0f * (xx + yy)); + *roll = std::atan2(2.0f * (xy + zw), 1.0f - 2.0f * (xx + zz)); + } else { + // not a unique solution + *roll = 0.0f; + *yaw = -std::atan2(-2.0f * (xy - zw), 1.0f - 2.0f * (yy + zz)); + } + } else { + // not a unique solution + *roll = 0.0f; + *yaw = std::atan2(-2.0f * (xy - zw), 1.0f - 2.0f * (yy + zz)); + } + + *pitch = qRadiansToDegrees(*pitch); + *yaw = qRadiansToDegrees(*yaw); + *roll = qRadiansToDegrees(*roll); +} + +/*! + \since 5.5 + + Creates a quaternion that corresponds to a rotation of + \a roll degrees around the z axis, \a pitch degrees around the x axis, + and \a yaw degrees around the y axis (in that order). + + \sa toEulerAngles() +*/ +QQuaternion QQuaternion::fromEulerAngles(float pitch, float yaw, float roll) +{ + // Algorithm from: + // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q60 + + pitch = qDegreesToRadians(pitch); + yaw = qDegreesToRadians(yaw); + roll = qDegreesToRadians(roll); + + pitch *= 0.5f; + yaw *= 0.5f; + roll *= 0.5f; + + const float c1 = std::cos(yaw); + const float s1 = std::sin(yaw); + const float c2 = std::cos(roll); + const float s2 = std::sin(roll); + const float c3 = std::cos(pitch); + const float s3 = std::sin(pitch); + const float c1c2 = c1 * c2; + const float s1s2 = s1 * s2; + + const float w = c1c2 * c3 + s1s2 * s3; + const float x = c1c2 * s3 + s1s2 * c3; + const float y = s1 * c2 * c3 - c1 * s2 * s3; + const float z = c1 * s2 * c3 - s1 * c2 * s3; + + return QQuaternion(w, x, y, z); +} + +/*! + \since 5.5 + + Creates a rotation matrix that corresponds to this quaternion. + + \note If this quaternion is not normalized, + the resulting rotation matrix will contain scaling information. + + \sa fromRotationMatrix() +*/ +QMatrix3x3 QQuaternion::toRotationMatrix() const +{ + // Algorithm from: + // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54 + + QMatrix3x3 rot3x3(Qt::Uninitialized); + + const float xx = xp * xp; + const float xy = xp * yp; + const float xz = xp * zp; + const float xw = xp * wp; + const float yy = yp * yp; + const float yz = yp * zp; + const float yw = yp * wp; + const float zz = zp * zp; + const float zw = zp * wp; + + rot3x3(0, 0) = 1.0f - 2.0f * (yy + zz); + rot3x3(0, 1) = 2.0f * (xy - zw); + rot3x3(0, 2) = 2.0f * (xz + yw); + rot3x3(1, 0) = 2.0f * (xy + zw); + rot3x3(1, 1) = 1.0f - 2.0f * (xx + zz); + rot3x3(1, 2) = 2.0f * (yz - xw); + rot3x3(2, 0) = 2.0f * (xz - yw); + rot3x3(2, 1) = 2.0f * (yz + xw); + rot3x3(2, 2) = 1.0f - 2.0f * (xx + yy); + + return rot3x3; +} + +/*! + \since 5.5 + + Creates a quaternion that corresponds to a rotation matrix \a rot3x3. + + \note If a given rotation matrix is not normalized, + the resulting quaternion will contain scaling information. + + \sa toRotationMatrix() +*/ +QQuaternion QQuaternion::fromRotationMatrix(const QMatrix3x3 &rot3x3) +{ + // Algorithm from: + // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q55 + + float scalar; + float axis[3]; + + const float trace = rot3x3(0, 0) + rot3x3(1, 1) + rot3x3(2, 2); + if (trace > 0.00000001f) { + const float s = 2.0f * std::sqrt(trace + 1.0f); + scalar = 0.25f * s; + axis[0] = (rot3x3(2, 1) - rot3x3(1, 2)) / s; + axis[1] = (rot3x3(0, 2) - rot3x3(2, 0)) / s; + axis[2] = (rot3x3(1, 0) - rot3x3(0, 1)) / s; + } else { + static int s_next[3] = { 1, 2, 0 }; + int i = 0; + if (rot3x3(1, 1) > rot3x3(0, 0)) + i = 1; + if (rot3x3(2, 2) > rot3x3(i, i)) + i = 2; + int j = s_next[i]; + int k = s_next[j]; + + const float s = 2.0f * std::sqrt(rot3x3(i, i) - rot3x3(j, j) - rot3x3(k, k) + 1.0f); + axis[i] = 0.25f * s; + scalar = (rot3x3(k, j) - rot3x3(j, k)) / s; + axis[j] = (rot3x3(j, i) + rot3x3(i, j)) / s; + axis[k] = (rot3x3(k, i) + rot3x3(i, k)) / s; + } + + return QQuaternion(scalar, axis[0], axis[1], axis[2]); +} + /*! \fn bool operator==(const QQuaternion &q1, const QQuaternion &q2) \relates QQuaternion @@ -514,11 +792,11 @@ QQuaternion QQuaternion::slerp float factor1 = 1.0f - t; float factor2 = t; if ((1.0f - dot) > 0.0000001) { - float angle = acosf(dot); - float sinOfAngle = sinf(angle); + float angle = std::acos(dot); + float sinOfAngle = std::sin(angle); if (sinOfAngle > 0.0000001) { - factor1 = sinf((1.0f - t) * angle) / sinOfAngle; - factor2 = sinf(t * angle) / sinOfAngle; + factor1 = std::sin((1.0f - t) * angle) / sinOfAngle; + factor2 = std::sin(t * angle) / sinOfAngle; } } diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index e0e52cefdd..4a87b63d25 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -34,6 +34,7 @@ #ifndef QQUATERNION_H #define QQUATERNION_H +#include <QtGui/qgenericmatrix.h> #include <QtGui/qvector3d.h> #include <QtGui/qvector4d.h> @@ -49,6 +50,7 @@ class Q_GUI_EXPORT QQuaternion { public: QQuaternion(); + explicit QQuaternion(Qt::Initialization) {} QQuaternion(float scalar, float xpos, float ypos, float zpos); #ifndef QT_NO_VECTOR3D QQuaternion(float scalar, const QVector3D& vector); @@ -82,6 +84,8 @@ public: QQuaternion normalized() const; void normalize(); + inline QQuaternion inverted() const; + QQuaternion conjugate() const; QVector3D rotatedVector(const QVector3D& vector) const; @@ -111,11 +115,23 @@ public: operator QVariant() const; #ifndef QT_NO_VECTOR3D + inline void toAxisAndAngle(QVector3D *axis, float *angle) const; static QQuaternion fromAxisAndAngle(const QVector3D& axis, float angle); #endif + void toAxisAndAngle(float *x, float *y, float *z, float *angle) const; static QQuaternion fromAxisAndAngle (float x, float y, float z, float angle); +#ifndef QT_NO_VECTOR3D + inline QVector3D toEulerAngles() const; + static inline QQuaternion fromEulerAngles(const QVector3D &eulerAngles); +#endif + void toEulerAngles(float *pitch, float *yaw, float *roll) const; + static QQuaternion fromEulerAngles(float pitch, float yaw, float roll); + + QMatrix3x3 toRotationMatrix() const; + static QQuaternion fromRotationMatrix(const QMatrix3x3 &rot3x3); + static QQuaternion slerp (const QQuaternion& q1, const QQuaternion& q2, float t); static QQuaternion nlerp @@ -152,6 +168,18 @@ inline void QQuaternion::setY(float aY) { yp = aY; } inline void QQuaternion::setZ(float aZ) { zp = aZ; } inline void QQuaternion::setScalar(float aScalar) { wp = aScalar; } +inline QQuaternion QQuaternion::inverted() const +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp) + + double(zp) * double(zp) + + double(wp) * double(wp); + if (!qFuzzyIsNull(len)) + return QQuaternion(wp / len, -xp / len, -yp / len, -zp / len); + return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f); +} + inline QQuaternion QQuaternion::conjugate() const { return QQuaternion(wp, -xp, -yp, -zp); @@ -280,6 +308,25 @@ inline QVector3D QQuaternion::vector() const return QVector3D(xp, yp, zp); } +inline void QQuaternion::toAxisAndAngle(QVector3D *axis, float *angle) const +{ + float aX, aY, aZ; + toAxisAndAngle(&aX, &aY, &aZ, angle); + *axis = QVector3D(aX, aY, aZ); +} + +inline QVector3D QQuaternion::toEulerAngles() const +{ + float pitch, yaw, roll; + toEulerAngles(&pitch, &yaw, &roll); + return QVector3D(pitch, yaw, roll); +} + +inline QQuaternion QQuaternion::fromEulerAngles(const QVector3D &eulerAngles) +{ + return QQuaternion::fromEulerAngles(eulerAngles.x(), eulerAngles.y(), eulerAngles.z()); +} + #endif inline void QQuaternion::setVector(float aX, float aY, float aZ) diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp index c46dd35766..fe4c9f8cc2 100644 --- a/src/gui/math3d/qvector2d.cpp +++ b/src/gui/math3d/qvector2d.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -64,6 +64,14 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QVector2D::QVector2D(Qt::Initialization) + \since 5.5 + \internal + + Constructs a vector without initializing the contents. +*/ + +/*! \fn QVector2D::QVector2D(float xpos, float ypos) Constructs a vector with coordinates (\a xpos, \a ypos). @@ -181,7 +189,7 @@ float QVector2D::length() const // Need some extra precision if the length is very small. double len = double(xp) * double(xp) + double(yp) * double(yp); - return float(sqrt(len)); + return float(std::sqrt(len)); } /*! @@ -212,7 +220,7 @@ QVector2D QVector2D::normalized() const if (qFuzzyIsNull(len - 1.0f)) { return *this; } else if (!qFuzzyIsNull(len)) { - double sqrtLen = sqrt(len); + double sqrtLen = std::sqrt(len); return QVector2D(float(double(xp) / sqrtLen), float(double(yp) / sqrtLen)); } else { return QVector2D(); @@ -233,7 +241,7 @@ void QVector2D::normalize() if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) return; - len = sqrt(len); + len = std::sqrt(len); xp = float(double(xp) / len); yp = float(double(yp) / len); @@ -316,6 +324,16 @@ float QVector2D::distanceToLine */ /*! + \fn QVector2D &QVector2D::operator/=(const QVector2D &vector) + \since 5.5 + + Divides the components of this vector by the corresponding + components in \a vector. + + \sa operator*=() +*/ + +/*! Returns the dot product of \a v1 and \a v2. */ float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2) @@ -407,6 +425,17 @@ float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2) */ /*! + \fn const QVector2D operator/(const QVector2D &vector, const QVector2D &divisor) + \relates QVector2D + \since 5.5 + + Returns the QVector2D object formed by dividing components of the given + \a vector by a respective components of the given \a divisor. + + \sa QVector2D::operator/=() +*/ + +/*! \fn bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2) \relates QVector2D diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h index 2cacd8ade0..20264fa84f 100644 --- a/src/gui/math3d/qvector2d.h +++ b/src/gui/math3d/qvector2d.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -50,6 +50,7 @@ class Q_GUI_EXPORT QVector2D { public: Q_DECL_CONSTEXPR QVector2D(); + explicit QVector2D(Qt::Initialization) {} Q_DECL_CONSTEXPR QVector2D(float xpos, float ypos); Q_DECL_CONSTEXPR explicit QVector2D(const QPoint& point); Q_DECL_CONSTEXPR explicit QVector2D(const QPointF& point); @@ -85,6 +86,7 @@ public: QVector2D &operator*=(float factor); QVector2D &operator*=(const QVector2D &vector); QVector2D &operator/=(float divisor); + inline QVector2D &operator/=(const QVector2D &vector); static float dotProduct(const QVector2D& v1, const QVector2D& v2); //In Qt 6 convert to inline and constexpr @@ -97,6 +99,7 @@ public: Q_DECL_CONSTEXPR friend inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2); Q_DECL_CONSTEXPR friend inline const QVector2D operator-(const QVector2D &vector); Q_DECL_CONSTEXPR friend inline const QVector2D operator/(const QVector2D &vector, float divisor); + Q_DECL_CONSTEXPR friend inline const QVector2D operator/(const QVector2D &vector, const QVector2D &divisor); Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2); @@ -187,6 +190,13 @@ inline QVector2D &QVector2D::operator/=(float divisor) return *this; } +inline QVector2D &QVector2D::operator/=(const QVector2D &vector) +{ + xp /= vector.xp; + yp /= vector.yp; + return *this; +} + Q_DECL_CONSTEXPR inline bool operator==(const QVector2D &v1, const QVector2D &v2) { return v1.xp == v2.xp && v1.yp == v2.yp; @@ -232,6 +242,11 @@ Q_DECL_CONSTEXPR inline const QVector2D operator/(const QVector2D &vector, float return QVector2D(vector.xp / divisor, vector.yp / divisor); } +Q_DECL_CONSTEXPR inline const QVector2D operator/(const QVector2D &vector, const QVector2D &divisor) +{ + return QVector2D(vector.xp / divisor.xp, vector.yp / divisor.yp); +} + Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2) { return qFuzzyCompare(v1.xp, v2.xp) && qFuzzyCompare(v1.yp, v2.yp); diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 75d61e5f85..a93d994a70 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -34,10 +34,12 @@ #include "qvector3d.h" #include "qvector2d.h" #include "qvector4d.h" +#include "qmatrix4x4.h" #include <QtCore/qdatastream.h> #include <QtCore/qmath.h> #include <QtCore/qvariant.h> #include <QtCore/qdebug.h> +#include <QtCore/qrect.h> QT_BEGIN_NAMESPACE @@ -67,6 +69,14 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QVector3D::QVector3D(Qt::Initialization) + \since 5.5 + \internal + + Constructs a vector without initializing the contents. +*/ + +/*! \fn QVector3D::QVector3D(float xpos, float ypos, float zpos) Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos). @@ -225,7 +235,7 @@ QVector3D QVector3D::normalized() const if (qFuzzyIsNull(len - 1.0f)) { return *this; } else if (!qFuzzyIsNull(len)) { - double sqrtLen = sqrt(len); + double sqrtLen = std::sqrt(len); return QVector3D(float(double(xp) / sqrtLen), float(double(yp) / sqrtLen), float(double(zp) / sqrtLen)); @@ -249,7 +259,7 @@ void QVector3D::normalize() if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) return; - len = sqrt(len); + len = std::sqrt(len); xp = float(double(xp) / len); yp = float(double(yp) / len); @@ -306,6 +316,16 @@ void QVector3D::normalize() */ /*! + \fn QVector3D &QVector3D::operator/=(const QVector3D &vector) + \since 5.5 + + Divides the components of this vector by the corresponding + components in \a vector. + + \sa operator*=() +*/ + +/*! Returns the dot product of \a v1 and \a v2. */ float QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2) @@ -359,6 +379,69 @@ QVector3D QVector3D::normal } /*! + \since 5.5 + + Returns the window coordinates of this vector initially in object/model + coordinates using the model view matrix \a modelView, the projection matrix + \a projection and the viewport dimensions \a viewport. + + When transforming from clip to normalized space, a division by the w + component on the vector components takes place. To prevent dividing by 0 if + w equals to 0, it is set to 1. + + \note the returned y coordinates are in OpenGL orientation. OpenGL expects + the bottom to be 0 whereas for Qt top is 0. + + \sa unproject() + */ +QVector3D QVector3D::project(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const +{ + QVector4D tmp(*this, 1.0f); + tmp = projection * modelView * tmp; + if (qFuzzyIsNull(tmp.w())) + tmp.setW(1.0f); + tmp /= tmp.w(); + + tmp = tmp * 0.5f + QVector4D(0.5f, 0.5f, 0.5f, 0.5f); + tmp.setX(tmp.x() * viewport.width() + viewport.x()); + tmp.setY(tmp.y() * viewport.height() + viewport.y()); + + return tmp.toVector3D(); +} + +/*! + \since 5.5 + + Returns the object/model coordinates of this vector initially in window + coordinates using the model view matrix \a modelView, the projection matrix + \a projection and the viewport dimensions \a viewport. + + When transforming from clip to normalized space, a division by the w + component of the vector components takes place. To prevent dividing by 0 if + w equals to 0, it is set to 1. + + \note y coordinates in \a point should use OpenGL orientation. OpenGL + expects the bottom to be 0 whereas for Qt top is 0. + + \sa project() + */ +QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const +{ + QMatrix4x4 inverse = QMatrix4x4( projection * modelView ).inverted(); + + QVector4D tmp(*this, 1.0f); + tmp.setX((tmp.x() - float(viewport.x())) / float(viewport.width())); + tmp.setY((tmp.y() - float(viewport.y())) / float(viewport.height())); + tmp = tmp * 2.0f - QVector4D(1.0f, 1.0f, 1.0f, 1.0f); + + QVector4D obj = inverse * tmp; + if (qFuzzyIsNull(obj.w())) + obj.setW(1.0f); + obj /= obj.w(); + return obj.toVector3D(); +} + +/*! \since 5.1 Returns the distance from this vertex to a point defined by @@ -513,6 +596,17 @@ float QVector3D::distanceToLine */ /*! + \fn const QVector3D operator/(const QVector3D &vector, const QVector3D &divisor) + \relates QVector3D + \since 5.5 + + Returns the QVector3D object formed by dividing components of the given + \a vector by a respective components of the given \a divisor. + + \sa QVector3D::operator/=() +*/ + +/*! \fn bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2) \relates QVector3D @@ -585,7 +679,7 @@ float QVector3D::length() const double len = double(xp) * double(xp) + double(yp) * double(yp) + double(zp) * double(zp); - return float(sqrt(len)); + return float(std::sqrt(len)); } /*! diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h index 40e9035621..5be637e0c5 100644 --- a/src/gui/math3d/qvector3d.h +++ b/src/gui/math3d/qvector3d.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE class QMatrix4x4; class QVector2D; class QVector4D; +class QRect; #ifndef QT_NO_VECTOR3D @@ -50,6 +51,7 @@ class Q_GUI_EXPORT QVector3D { public: Q_DECL_CONSTEXPR QVector3D(); + explicit QVector3D(Qt::Initialization) {} Q_DECL_CONSTEXPR QVector3D(float xpos, float ypos, float zpos) : xp(xpos), yp(ypos), zp(zpos) {} Q_DECL_CONSTEXPR explicit QVector3D(const QPoint& point); @@ -86,6 +88,7 @@ public: QVector3D &operator*=(float factor); QVector3D &operator*=(const QVector3D& vector); QVector3D &operator/=(float divisor); + inline QVector3D &operator/=(const QVector3D &vector); static float dotProduct(const QVector3D& v1, const QVector3D& v2); //In Qt 6 convert to inline and constexpr static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2); //in Qt 6 convert to inline and constexpr @@ -94,6 +97,9 @@ public: static QVector3D normal (const QVector3D& v1, const QVector3D& v2, const QVector3D& v3); + QVector3D project(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const; + QVector3D unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const; + float distanceToPoint(const QVector3D& point) const; float distanceToPlane(const QVector3D& plane, const QVector3D& normal) const; float distanceToPlane(const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const; @@ -108,6 +114,7 @@ public: Q_DECL_CONSTEXPR friend const QVector3D operator*(const QVector3D &v1, const QVector3D& v2); Q_DECL_CONSTEXPR friend inline const QVector3D operator-(const QVector3D &vector); Q_DECL_CONSTEXPR friend inline const QVector3D operator/(const QVector3D &vector, float divisor); + Q_DECL_CONSTEXPR friend inline const QVector3D operator/(const QVector3D &vector, const QVector3D &divisor); Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2); @@ -207,6 +214,14 @@ inline QVector3D &QVector3D::operator/=(float divisor) return *this; } +inline QVector3D &QVector3D::operator/=(const QVector3D &vector) +{ + xp /= vector.xp; + yp /= vector.yp; + zp /= vector.zp; + return *this; +} + Q_DECL_CONSTEXPR inline bool operator==(const QVector3D &v1, const QVector3D &v2) { return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp; @@ -252,6 +267,11 @@ Q_DECL_CONSTEXPR inline const QVector3D operator/(const QVector3D &vector, float return QVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor); } +Q_DECL_CONSTEXPR inline const QVector3D operator/(const QVector3D &vector, const QVector3D &divisor) +{ + return QVector3D(vector.xp / divisor.xp, vector.yp / divisor.yp, vector.zp / divisor.zp); +} + Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2) { return qFuzzyCompare(v1.xp, v2.xp) && diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp index 3603f655cb..6afe9b8cad 100644 --- a/src/gui/math3d/qvector4d.cpp +++ b/src/gui/math3d/qvector4d.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -63,6 +63,14 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QVector4D::QVector4D(Qt::Initialization) + \since 5.5 + \internal + + Constructs a vector without initializing the contents. +*/ + +/*! \fn QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos, \a wpos). @@ -248,7 +256,7 @@ float QVector4D::length() const double(yp) * double(yp) + double(zp) * double(zp) + double(wp) * double(wp); - return float(sqrt(len)); + return float(std::sqrt(len)); } /*! @@ -281,7 +289,7 @@ QVector4D QVector4D::normalized() const if (qFuzzyIsNull(len - 1.0f)) { return *this; } else if (!qFuzzyIsNull(len)) { - double sqrtLen = sqrt(len); + double sqrtLen = std::sqrt(len); return QVector4D(float(double(xp) / sqrtLen), float(double(yp) / sqrtLen), float(double(zp) / sqrtLen), @@ -307,7 +315,7 @@ void QVector4D::normalize() if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) return; - len = sqrt(len); + len = std::sqrt(len); xp = float(double(xp) / len); yp = float(double(yp) / len); @@ -359,6 +367,16 @@ void QVector4D::normalize() */ /*! + \fn QVector4D &QVector4D::operator/=(const QVector4D &vector) + \since 5.5 + + Divides the components of this vector by the corresponding + components in \a vector. + + \sa operator*=() +*/ + +/*! Returns the dot product of \a v1 and \a v2. */ float QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2) @@ -452,6 +470,17 @@ float QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2) */ /*! + \fn const QVector4D operator/(const QVector4D &vector, const QVector4D &divisor) + \relates QVector4D + \since 5.5 + + Returns the QVector4D object formed by dividing components of the given + \a vector by a respective components of the given \a divisor. + + \sa QVector4D::operator/=() +*/ + +/*! \fn bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2) \relates QVector4D diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h index 291af5c072..aa69104f55 100644 --- a/src/gui/math3d/qvector4d.h +++ b/src/gui/math3d/qvector4d.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -50,6 +50,7 @@ class Q_GUI_EXPORT QVector4D { public: Q_DECL_CONSTEXPR QVector4D(); + explicit QVector4D(Qt::Initialization) {} Q_DECL_CONSTEXPR QVector4D(float xpos, float ypos, float zpos, float wpos); Q_DECL_CONSTEXPR explicit QVector4D(const QPoint& point); Q_DECL_CONSTEXPR explicit QVector4D(const QPointF& point); @@ -88,6 +89,7 @@ public: QVector4D &operator*=(float factor); QVector4D &operator*=(const QVector4D &vector); QVector4D &operator/=(float divisor); + inline QVector4D &operator/=(const QVector4D &vector); static float dotProduct(const QVector4D& v1, const QVector4D& v2); //In Qt 6 convert to inline and constexpr @@ -100,6 +102,7 @@ public: Q_DECL_CONSTEXPR friend inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2); Q_DECL_CONSTEXPR friend inline const QVector4D operator-(const QVector4D &vector); Q_DECL_CONSTEXPR friend inline const QVector4D operator/(const QVector4D &vector, float divisor); + Q_DECL_CONSTEXPR friend inline const QVector4D operator/(const QVector4D &vector, const QVector4D &divisor); Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2); @@ -210,6 +213,15 @@ inline QVector4D &QVector4D::operator/=(float divisor) return *this; } +inline QVector4D &QVector4D::operator/=(const QVector4D &vector) +{ + xp /= vector.xp; + yp /= vector.yp; + zp /= vector.zp; + wp /= vector.wp; + return *this; +} + Q_DECL_CONSTEXPR inline bool operator==(const QVector4D &v1, const QVector4D &v2) { return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp && v1.wp == v2.wp; @@ -255,6 +267,11 @@ Q_DECL_CONSTEXPR inline const QVector4D operator/(const QVector4D &vector, float return QVector4D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, vector.wp / divisor); } +Q_DECL_CONSTEXPR inline const QVector4D operator/(const QVector4D &vector, const QVector4D &divisor) +{ + return QVector4D(vector.xp / divisor.xp, vector.yp / divisor.yp, vector.zp / divisor.zp, vector.wp / divisor.wp); +} + Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2) { return qFuzzyCompare(v1.xp, v2.xp) && |