Warning, file /include/QtGui/qmatrix4x4.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004 #ifndef QMATRIX4X4_H
0005 #define QMATRIX4X4_H
0006
0007 #include <QtGui/qtguiglobal.h>
0008 #include <QtGui/qvector3d.h>
0009 #include <QtGui/qvector4d.h>
0010 #include <QtGui/qquaternion.h>
0011 #include <QtGui/qgenericmatrix.h>
0012 #include <QtCore/qrect.h>
0013
0014 class tst_QMatrixNxN;
0015
0016 QT_BEGIN_NAMESPACE
0017
0018
0019 #ifndef QT_NO_MATRIX4X4
0020
0021 class QTransform;
0022 class QVariant;
0023
0024 class Q_GUI_EXPORT QMatrix4x4
0025 {
0026 public:
0027 inline QMatrix4x4() { setToIdentity(); }
0028 explicit QMatrix4x4(Qt::Initialization) : flagBits(General) {}
0029 explicit QMatrix4x4(const float *values);
0030 inline QMatrix4x4(float m11, float m12, float m13, float m14,
0031 float m21, float m22, float m23, float m24,
0032 float m31, float m32, float m33, float m34,
0033 float m41, float m42, float m43, float m44);
0034
0035 template <int N, int M>
0036 explicit QMatrix4x4(const QGenericMatrix<N, M, float>& matrix);
0037
0038 QMatrix4x4(const float *values, int cols, int rows);
0039 QMatrix4x4(const QTransform& transform);
0040
0041 inline const float& operator()(int row, int column) const;
0042 inline float& operator()(int row, int column);
0043
0044 #ifndef QT_NO_VECTOR4D
0045 inline QVector4D column(int index) const;
0046 inline void setColumn(int index, const QVector4D& value);
0047
0048 inline QVector4D row(int index) const;
0049 inline void setRow(int index, const QVector4D& value);
0050 #endif
0051
0052 inline bool isAffine() const;
0053
0054 inline bool isIdentity() const;
0055 inline void setToIdentity();
0056
0057 inline void fill(float value);
0058
0059 double determinant() const;
0060 QMatrix4x4 inverted(bool *invertible = nullptr) const;
0061 QMatrix4x4 transposed() const;
0062 QMatrix3x3 normalMatrix() const;
0063
0064 inline QMatrix4x4& operator+=(const QMatrix4x4& other);
0065 inline QMatrix4x4& operator-=(const QMatrix4x4& other);
0066 inline QMatrix4x4& operator*=(const QMatrix4x4& other);
0067 inline QMatrix4x4& operator*=(float factor);
0068 QMatrix4x4& operator/=(float divisor);
0069 inline bool operator==(const QMatrix4x4& other) const;
0070 inline bool operator!=(const QMatrix4x4& other) const;
0071
0072 friend QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2);
0073 friend QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2);
0074 friend QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2);
0075 #ifndef QT_NO_VECTOR3D
0076 #if QT_DEPRECATED_SINCE(6, 1)
0077 friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector);
0078 friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix);
0079 #endif
0080 #endif
0081 #ifndef QT_NO_VECTOR4D
0082 friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix);
0083 friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector);
0084 #endif
0085 friend QPoint operator*(const QPoint& point, const QMatrix4x4& matrix);
0086 friend QPointF operator*(const QPointF& point, const QMatrix4x4& matrix);
0087 friend QMatrix4x4 operator-(const QMatrix4x4& matrix);
0088 #if QT_DEPRECATED_SINCE(6, 1)
0089 friend QPoint operator*(const QMatrix4x4& matrix, const QPoint& point);
0090 friend QPointF operator*(const QMatrix4x4& matrix, const QPointF& point);
0091 #endif
0092 friend QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix);
0093 friend QMatrix4x4 operator*(const QMatrix4x4& matrix, float factor);
0094 friend Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor);
0095
0096 friend Q_GUI_EXPORT bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2);
0097
0098 #ifndef QT_NO_VECTOR3D
0099 void scale(const QVector3D& vector);
0100 void translate(const QVector3D& vector);
0101 void rotate(float angle, const QVector3D& vector);
0102 #endif
0103 void scale(float x, float y);
0104 void scale(float x, float y, float z);
0105 void scale(float factor);
0106 void translate(float x, float y);
0107 void translate(float x, float y, float z);
0108 void rotate(float angle, float x, float y, float z = 0.0f);
0109 #ifndef QT_NO_QUATERNION
0110 void rotate(const QQuaternion& quaternion);
0111 #endif
0112
0113 void ortho(const QRect& rect);
0114 void ortho(const QRectF& rect);
0115 void ortho(float left, float right, float bottom, float top, float nearPlane, float farPlane);
0116 void frustum(float left, float right, float bottom, float top, float nearPlane, float farPlane);
0117 void perspective(float verticalAngle, float aspectRatio, float nearPlane, float farPlane);
0118 #ifndef QT_NO_VECTOR3D
0119 void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
0120 #endif
0121 void viewport(const QRectF &rect);
0122 void viewport(float left, float bottom, float width, float height, float nearPlane = 0.0f, float farPlane = 1.0f);
0123 void flipCoordinates();
0124
0125 void copyDataTo(float *values) const;
0126
0127 QTransform toTransform() const;
0128 QTransform toTransform(float distanceToPlane) const;
0129
0130 inline QPoint map(const QPoint& point) const;
0131 inline QPointF map(const QPointF& point) const;
0132 #ifndef QT_NO_VECTOR3D
0133 inline QVector3D map(const QVector3D& point) const;
0134 inline QVector3D mapVector(const QVector3D& vector) const;
0135 #endif
0136 #ifndef QT_NO_VECTOR4D
0137 inline QVector4D map(const QVector4D& point) const;
0138 #endif
0139 QRect mapRect(const QRect& rect) const;
0140 QRectF mapRect(const QRectF& rect) const;
0141
0142 template <int N, int M>
0143 QGenericMatrix<N, M, float> toGenericMatrix() const;
0144
0145 inline float *data();
0146 inline const float *data() const { return *m; }
0147 inline const float *constData() const { return *m; }
0148
0149 void optimize();
0150
0151 operator QVariant() const;
0152
0153 #ifndef QT_NO_DEBUG_STREAM
0154 friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m);
0155 #endif
0156
0157 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
0158 void projectedRotate(float angle, float x, float y, float z, float distanceToPlane);
0159
0160 void projectedRotate(float angle, float x, float y, float z);
0161 #else
0162 void projectedRotate(float angle, float x, float y, float z, float distanceToPlane = 1024.0);
0163 #endif
0164
0165
0166
0167 enum Flag {
0168 Identity = 0x0000,
0169 Translation = 0x0001,
0170 Scale = 0x0002,
0171 Rotation2D = 0x0004,
0172 Rotation = 0x0008,
0173 Perspective = 0x0010,
0174 General = 0x001f
0175 };
0176 Q_DECLARE_FLAGS(Flags, Flag)
0177
0178 Flags flags() const { return flagBits; }
0179
0180 private:
0181 float m[4][4];
0182 Flags flagBits;
0183
0184 QMatrix4x4 orthonormalInverse() const;
0185
0186 friend class ::tst_QMatrixNxN;
0187 };
0188
0189 Q_DECLARE_OPERATORS_FOR_FLAGS(QMatrix4x4::Flags)
0190
0191 QT_WARNING_PUSH
0192 QT_WARNING_DISABLE_FLOAT_COMPARE
0193
0194 Q_DECLARE_TYPEINFO(QMatrix4x4, Q_PRIMITIVE_TYPE);
0195
0196 inline QMatrix4x4::QMatrix4x4
0197 (float m11, float m12, float m13, float m14,
0198 float m21, float m22, float m23, float m24,
0199 float m31, float m32, float m33, float m34,
0200 float m41, float m42, float m43, float m44)
0201 {
0202 m[0][0] = m11; m[0][1] = m21; m[0][2] = m31; m[0][3] = m41;
0203 m[1][0] = m12; m[1][1] = m22; m[1][2] = m32; m[1][3] = m42;
0204 m[2][0] = m13; m[2][1] = m23; m[2][2] = m33; m[2][3] = m43;
0205 m[3][0] = m14; m[3][1] = m24; m[3][2] = m34; m[3][3] = m44;
0206 flagBits = General;
0207 }
0208
0209 template <int N, int M>
0210 Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4
0211 (const QGenericMatrix<N, M, float>& matrix)
0212 {
0213 const float *values = matrix.constData();
0214 for (int matrixCol = 0; matrixCol < 4; ++matrixCol) {
0215 for (int matrixRow = 0; matrixRow < 4; ++matrixRow) {
0216 if (matrixCol < N && matrixRow < M)
0217 m[matrixCol][matrixRow] = values[matrixCol * M + matrixRow];
0218 else if (matrixCol == matrixRow)
0219 m[matrixCol][matrixRow] = 1.0f;
0220 else
0221 m[matrixCol][matrixRow] = 0.0f;
0222 }
0223 }
0224 flagBits = General;
0225 }
0226
0227 template <int N, int M>
0228 QGenericMatrix<N, M, float> QMatrix4x4::toGenericMatrix() const
0229 {
0230 QGenericMatrix<N, M, float> result;
0231 float *values = result.data();
0232 for (int matrixCol = 0; matrixCol < N; ++matrixCol) {
0233 for (int matrixRow = 0; matrixRow < M; ++matrixRow) {
0234 if (matrixCol < 4 && matrixRow < 4)
0235 values[matrixCol * M + matrixRow] = m[matrixCol][matrixRow];
0236 else if (matrixCol == matrixRow)
0237 values[matrixCol * M + matrixRow] = 1.0f;
0238 else
0239 values[matrixCol * M + matrixRow] = 0.0f;
0240 }
0241 }
0242 return result;
0243 }
0244
0245 inline const float& QMatrix4x4::operator()(int aRow, int aColumn) const
0246 {
0247 Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
0248 return m[aColumn][aRow];
0249 }
0250
0251 inline float& QMatrix4x4::operator()(int aRow, int aColumn)
0252 {
0253 Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
0254 flagBits = General;
0255 return m[aColumn][aRow];
0256 }
0257
0258 #ifndef QT_NO_VECTOR4D
0259 inline QVector4D QMatrix4x4::column(int index) const
0260 {
0261 Q_ASSERT(index >= 0 && index < 4);
0262 return QVector4D(m[index][0], m[index][1], m[index][2], m[index][3]);
0263 }
0264
0265 inline void QMatrix4x4::setColumn(int index, const QVector4D& value)
0266 {
0267 Q_ASSERT(index >= 0 && index < 4);
0268 m[index][0] = value.x();
0269 m[index][1] = value.y();
0270 m[index][2] = value.z();
0271 m[index][3] = value.w();
0272 flagBits = General;
0273 }
0274
0275 inline QVector4D QMatrix4x4::row(int index) const
0276 {
0277 Q_ASSERT(index >= 0 && index < 4);
0278 return QVector4D(m[0][index], m[1][index], m[2][index], m[3][index]);
0279 }
0280
0281 inline void QMatrix4x4::setRow(int index, const QVector4D& value)
0282 {
0283 Q_ASSERT(index >= 0 && index < 4);
0284 m[0][index] = value.x();
0285 m[1][index] = value.y();
0286 m[2][index] = value.z();
0287 m[3][index] = value.w();
0288 flagBits = General;
0289 }
0290 #endif
0291
0292 Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor);
0293
0294 inline bool QMatrix4x4::isAffine() const
0295 {
0296 return m[0][3] == 0.0f && m[1][3] == 0.0f && m[2][3] == 0.0f && m[3][3] == 1.0f;
0297 }
0298
0299 inline bool QMatrix4x4::isIdentity() const
0300 {
0301 if (flagBits == Identity)
0302 return true;
0303 if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f)
0304 return false;
0305 if (m[0][3] != 0.0f || m[1][0] != 0.0f || m[1][1] != 1.0f)
0306 return false;
0307 if (m[1][2] != 0.0f || m[1][3] != 0.0f || m[2][0] != 0.0f)
0308 return false;
0309 if (m[2][1] != 0.0f || m[2][2] != 1.0f || m[2][3] != 0.0f)
0310 return false;
0311 if (m[3][0] != 0.0f || m[3][1] != 0.0f || m[3][2] != 0.0f)
0312 return false;
0313 return (m[3][3] == 1.0f);
0314 }
0315
0316 inline void QMatrix4x4::setToIdentity()
0317 {
0318 m[0][0] = 1.0f;
0319 m[0][1] = 0.0f;
0320 m[0][2] = 0.0f;
0321 m[0][3] = 0.0f;
0322 m[1][0] = 0.0f;
0323 m[1][1] = 1.0f;
0324 m[1][2] = 0.0f;
0325 m[1][3] = 0.0f;
0326 m[2][0] = 0.0f;
0327 m[2][1] = 0.0f;
0328 m[2][2] = 1.0f;
0329 m[2][3] = 0.0f;
0330 m[3][0] = 0.0f;
0331 m[3][1] = 0.0f;
0332 m[3][2] = 0.0f;
0333 m[3][3] = 1.0f;
0334 flagBits = Identity;
0335 }
0336
0337 inline void QMatrix4x4::fill(float value)
0338 {
0339 m[0][0] = value;
0340 m[0][1] = value;
0341 m[0][2] = value;
0342 m[0][3] = value;
0343 m[1][0] = value;
0344 m[1][1] = value;
0345 m[1][2] = value;
0346 m[1][3] = value;
0347 m[2][0] = value;
0348 m[2][1] = value;
0349 m[2][2] = value;
0350 m[2][3] = value;
0351 m[3][0] = value;
0352 m[3][1] = value;
0353 m[3][2] = value;
0354 m[3][3] = value;
0355 flagBits = General;
0356 }
0357
0358 inline QMatrix4x4& QMatrix4x4::operator+=(const QMatrix4x4& other)
0359 {
0360 m[0][0] += other.m[0][0];
0361 m[0][1] += other.m[0][1];
0362 m[0][2] += other.m[0][2];
0363 m[0][3] += other.m[0][3];
0364 m[1][0] += other.m[1][0];
0365 m[1][1] += other.m[1][1];
0366 m[1][2] += other.m[1][2];
0367 m[1][3] += other.m[1][3];
0368 m[2][0] += other.m[2][0];
0369 m[2][1] += other.m[2][1];
0370 m[2][2] += other.m[2][2];
0371 m[2][3] += other.m[2][3];
0372 m[3][0] += other.m[3][0];
0373 m[3][1] += other.m[3][1];
0374 m[3][2] += other.m[3][2];
0375 m[3][3] += other.m[3][3];
0376 flagBits = General;
0377 return *this;
0378 }
0379
0380 inline QMatrix4x4& QMatrix4x4::operator-=(const QMatrix4x4& other)
0381 {
0382 m[0][0] -= other.m[0][0];
0383 m[0][1] -= other.m[0][1];
0384 m[0][2] -= other.m[0][2];
0385 m[0][3] -= other.m[0][3];
0386 m[1][0] -= other.m[1][0];
0387 m[1][1] -= other.m[1][1];
0388 m[1][2] -= other.m[1][2];
0389 m[1][3] -= other.m[1][3];
0390 m[2][0] -= other.m[2][0];
0391 m[2][1] -= other.m[2][1];
0392 m[2][2] -= other.m[2][2];
0393 m[2][3] -= other.m[2][3];
0394 m[3][0] -= other.m[3][0];
0395 m[3][1] -= other.m[3][1];
0396 m[3][2] -= other.m[3][2];
0397 m[3][3] -= other.m[3][3];
0398 flagBits = General;
0399 return *this;
0400 }
0401
0402 inline QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& o)
0403 {
0404 const QMatrix4x4 other = o;
0405 flagBits |= other.flagBits;
0406
0407 if (flagBits.toInt() < Rotation2D) {
0408 m[3][0] += m[0][0] * other.m[3][0];
0409 m[3][1] += m[1][1] * other.m[3][1];
0410 m[3][2] += m[2][2] * other.m[3][2];
0411
0412 m[0][0] *= other.m[0][0];
0413 m[1][1] *= other.m[1][1];
0414 m[2][2] *= other.m[2][2];
0415 return *this;
0416 }
0417
0418 float m0, m1, m2;
0419 m0 = m[0][0] * other.m[0][0]
0420 + m[1][0] * other.m[0][1]
0421 + m[2][0] * other.m[0][2]
0422 + m[3][0] * other.m[0][3];
0423 m1 = m[0][0] * other.m[1][0]
0424 + m[1][0] * other.m[1][1]
0425 + m[2][0] * other.m[1][2]
0426 + m[3][0] * other.m[1][3];
0427 m2 = m[0][0] * other.m[2][0]
0428 + m[1][0] * other.m[2][1]
0429 + m[2][0] * other.m[2][2]
0430 + m[3][0] * other.m[2][3];
0431 m[3][0] = m[0][0] * other.m[3][0]
0432 + m[1][0] * other.m[3][1]
0433 + m[2][0] * other.m[3][2]
0434 + m[3][0] * other.m[3][3];
0435 m[0][0] = m0;
0436 m[1][0] = m1;
0437 m[2][0] = m2;
0438
0439 m0 = m[0][1] * other.m[0][0]
0440 + m[1][1] * other.m[0][1]
0441 + m[2][1] * other.m[0][2]
0442 + m[3][1] * other.m[0][3];
0443 m1 = m[0][1] * other.m[1][0]
0444 + m[1][1] * other.m[1][1]
0445 + m[2][1] * other.m[1][2]
0446 + m[3][1] * other.m[1][3];
0447 m2 = m[0][1] * other.m[2][0]
0448 + m[1][1] * other.m[2][1]
0449 + m[2][1] * other.m[2][2]
0450 + m[3][1] * other.m[2][3];
0451 m[3][1] = m[0][1] * other.m[3][0]
0452 + m[1][1] * other.m[3][1]
0453 + m[2][1] * other.m[3][2]
0454 + m[3][1] * other.m[3][3];
0455 m[0][1] = m0;
0456 m[1][1] = m1;
0457 m[2][1] = m2;
0458
0459 m0 = m[0][2] * other.m[0][0]
0460 + m[1][2] * other.m[0][1]
0461 + m[2][2] * other.m[0][2]
0462 + m[3][2] * other.m[0][3];
0463 m1 = m[0][2] * other.m[1][0]
0464 + m[1][2] * other.m[1][1]
0465 + m[2][2] * other.m[1][2]
0466 + m[3][2] * other.m[1][3];
0467 m2 = m[0][2] * other.m[2][0]
0468 + m[1][2] * other.m[2][1]
0469 + m[2][2] * other.m[2][2]
0470 + m[3][2] * other.m[2][3];
0471 m[3][2] = m[0][2] * other.m[3][0]
0472 + m[1][2] * other.m[3][1]
0473 + m[2][2] * other.m[3][2]
0474 + m[3][2] * other.m[3][3];
0475 m[0][2] = m0;
0476 m[1][2] = m1;
0477 m[2][2] = m2;
0478
0479 m0 = m[0][3] * other.m[0][0]
0480 + m[1][3] * other.m[0][1]
0481 + m[2][3] * other.m[0][2]
0482 + m[3][3] * other.m[0][3];
0483 m1 = m[0][3] * other.m[1][0]
0484 + m[1][3] * other.m[1][1]
0485 + m[2][3] * other.m[1][2]
0486 + m[3][3] * other.m[1][3];
0487 m2 = m[0][3] * other.m[2][0]
0488 + m[1][3] * other.m[2][1]
0489 + m[2][3] * other.m[2][2]
0490 + m[3][3] * other.m[2][3];
0491 m[3][3] = m[0][3] * other.m[3][0]
0492 + m[1][3] * other.m[3][1]
0493 + m[2][3] * other.m[3][2]
0494 + m[3][3] * other.m[3][3];
0495 m[0][3] = m0;
0496 m[1][3] = m1;
0497 m[2][3] = m2;
0498 return *this;
0499 }
0500
0501 inline QMatrix4x4& QMatrix4x4::operator*=(float factor)
0502 {
0503 m[0][0] *= factor;
0504 m[0][1] *= factor;
0505 m[0][2] *= factor;
0506 m[0][3] *= factor;
0507 m[1][0] *= factor;
0508 m[1][1] *= factor;
0509 m[1][2] *= factor;
0510 m[1][3] *= factor;
0511 m[2][0] *= factor;
0512 m[2][1] *= factor;
0513 m[2][2] *= factor;
0514 m[2][3] *= factor;
0515 m[3][0] *= factor;
0516 m[3][1] *= factor;
0517 m[3][2] *= factor;
0518 m[3][3] *= factor;
0519 flagBits = General;
0520 return *this;
0521 }
0522
0523 inline bool QMatrix4x4::operator==(const QMatrix4x4& other) const
0524 {
0525 return m[0][0] == other.m[0][0] &&
0526 m[0][1] == other.m[0][1] &&
0527 m[0][2] == other.m[0][2] &&
0528 m[0][3] == other.m[0][3] &&
0529 m[1][0] == other.m[1][0] &&
0530 m[1][1] == other.m[1][1] &&
0531 m[1][2] == other.m[1][2] &&
0532 m[1][3] == other.m[1][3] &&
0533 m[2][0] == other.m[2][0] &&
0534 m[2][1] == other.m[2][1] &&
0535 m[2][2] == other.m[2][2] &&
0536 m[2][3] == other.m[2][3] &&
0537 m[3][0] == other.m[3][0] &&
0538 m[3][1] == other.m[3][1] &&
0539 m[3][2] == other.m[3][2] &&
0540 m[3][3] == other.m[3][3];
0541 }
0542
0543 inline bool QMatrix4x4::operator!=(const QMatrix4x4& other) const
0544 {
0545 return m[0][0] != other.m[0][0] ||
0546 m[0][1] != other.m[0][1] ||
0547 m[0][2] != other.m[0][2] ||
0548 m[0][3] != other.m[0][3] ||
0549 m[1][0] != other.m[1][0] ||
0550 m[1][1] != other.m[1][1] ||
0551 m[1][2] != other.m[1][2] ||
0552 m[1][3] != other.m[1][3] ||
0553 m[2][0] != other.m[2][0] ||
0554 m[2][1] != other.m[2][1] ||
0555 m[2][2] != other.m[2][2] ||
0556 m[2][3] != other.m[2][3] ||
0557 m[3][0] != other.m[3][0] ||
0558 m[3][1] != other.m[3][1] ||
0559 m[3][2] != other.m[3][2] ||
0560 m[3][3] != other.m[3][3];
0561 }
0562
0563 inline QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2)
0564 {
0565 QMatrix4x4 m(Qt::Uninitialized);
0566 m.m[0][0] = m1.m[0][0] + m2.m[0][0];
0567 m.m[0][1] = m1.m[0][1] + m2.m[0][1];
0568 m.m[0][2] = m1.m[0][2] + m2.m[0][2];
0569 m.m[0][3] = m1.m[0][3] + m2.m[0][3];
0570 m.m[1][0] = m1.m[1][0] + m2.m[1][0];
0571 m.m[1][1] = m1.m[1][1] + m2.m[1][1];
0572 m.m[1][2] = m1.m[1][2] + m2.m[1][2];
0573 m.m[1][3] = m1.m[1][3] + m2.m[1][3];
0574 m.m[2][0] = m1.m[2][0] + m2.m[2][0];
0575 m.m[2][1] = m1.m[2][1] + m2.m[2][1];
0576 m.m[2][2] = m1.m[2][2] + m2.m[2][2];
0577 m.m[2][3] = m1.m[2][3] + m2.m[2][3];
0578 m.m[3][0] = m1.m[3][0] + m2.m[3][0];
0579 m.m[3][1] = m1.m[3][1] + m2.m[3][1];
0580 m.m[3][2] = m1.m[3][2] + m2.m[3][2];
0581 m.m[3][3] = m1.m[3][3] + m2.m[3][3];
0582 return m;
0583 }
0584
0585 inline QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2)
0586 {
0587 QMatrix4x4 m(Qt::Uninitialized);
0588 m.m[0][0] = m1.m[0][0] - m2.m[0][0];
0589 m.m[0][1] = m1.m[0][1] - m2.m[0][1];
0590 m.m[0][2] = m1.m[0][2] - m2.m[0][2];
0591 m.m[0][3] = m1.m[0][3] - m2.m[0][3];
0592 m.m[1][0] = m1.m[1][0] - m2.m[1][0];
0593 m.m[1][1] = m1.m[1][1] - m2.m[1][1];
0594 m.m[1][2] = m1.m[1][2] - m2.m[1][2];
0595 m.m[1][3] = m1.m[1][3] - m2.m[1][3];
0596 m.m[2][0] = m1.m[2][0] - m2.m[2][0];
0597 m.m[2][1] = m1.m[2][1] - m2.m[2][1];
0598 m.m[2][2] = m1.m[2][2] - m2.m[2][2];
0599 m.m[2][3] = m1.m[2][3] - m2.m[2][3];
0600 m.m[3][0] = m1.m[3][0] - m2.m[3][0];
0601 m.m[3][1] = m1.m[3][1] - m2.m[3][1];
0602 m.m[3][2] = m1.m[3][2] - m2.m[3][2];
0603 m.m[3][3] = m1.m[3][3] - m2.m[3][3];
0604 return m;
0605 }
0606
0607 inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2)
0608 {
0609 QMatrix4x4::Flags flagBits = m1.flagBits | m2.flagBits;
0610 if (flagBits.toInt() < QMatrix4x4::Rotation2D) {
0611 QMatrix4x4 m = m1;
0612 m.m[3][0] += m.m[0][0] * m2.m[3][0];
0613 m.m[3][1] += m.m[1][1] * m2.m[3][1];
0614 m.m[3][2] += m.m[2][2] * m2.m[3][2];
0615
0616 m.m[0][0] *= m2.m[0][0];
0617 m.m[1][1] *= m2.m[1][1];
0618 m.m[2][2] *= m2.m[2][2];
0619 m.flagBits = flagBits;
0620 return m;
0621 }
0622
0623 QMatrix4x4 m(Qt::Uninitialized);
0624 m.m[0][0] = m1.m[0][0] * m2.m[0][0]
0625 + m1.m[1][0] * m2.m[0][1]
0626 + m1.m[2][0] * m2.m[0][2]
0627 + m1.m[3][0] * m2.m[0][3];
0628 m.m[0][1] = m1.m[0][1] * m2.m[0][0]
0629 + m1.m[1][1] * m2.m[0][1]
0630 + m1.m[2][1] * m2.m[0][2]
0631 + m1.m[3][1] * m2.m[0][3];
0632 m.m[0][2] = m1.m[0][2] * m2.m[0][0]
0633 + m1.m[1][2] * m2.m[0][1]
0634 + m1.m[2][2] * m2.m[0][2]
0635 + m1.m[3][2] * m2.m[0][3];
0636 m.m[0][3] = m1.m[0][3] * m2.m[0][0]
0637 + m1.m[1][3] * m2.m[0][1]
0638 + m1.m[2][3] * m2.m[0][2]
0639 + m1.m[3][3] * m2.m[0][3];
0640
0641 m.m[1][0] = m1.m[0][0] * m2.m[1][0]
0642 + m1.m[1][0] * m2.m[1][1]
0643 + m1.m[2][0] * m2.m[1][2]
0644 + m1.m[3][0] * m2.m[1][3];
0645 m.m[1][1] = m1.m[0][1] * m2.m[1][0]
0646 + m1.m[1][1] * m2.m[1][1]
0647 + m1.m[2][1] * m2.m[1][2]
0648 + m1.m[3][1] * m2.m[1][3];
0649 m.m[1][2] = m1.m[0][2] * m2.m[1][0]
0650 + m1.m[1][2] * m2.m[1][1]
0651 + m1.m[2][2] * m2.m[1][2]
0652 + m1.m[3][2] * m2.m[1][3];
0653 m.m[1][3] = m1.m[0][3] * m2.m[1][0]
0654 + m1.m[1][3] * m2.m[1][1]
0655 + m1.m[2][3] * m2.m[1][2]
0656 + m1.m[3][3] * m2.m[1][3];
0657
0658 m.m[2][0] = m1.m[0][0] * m2.m[2][0]
0659 + m1.m[1][0] * m2.m[2][1]
0660 + m1.m[2][0] * m2.m[2][2]
0661 + m1.m[3][0] * m2.m[2][3];
0662 m.m[2][1] = m1.m[0][1] * m2.m[2][0]
0663 + m1.m[1][1] * m2.m[2][1]
0664 + m1.m[2][1] * m2.m[2][2]
0665 + m1.m[3][1] * m2.m[2][3];
0666 m.m[2][2] = m1.m[0][2] * m2.m[2][0]
0667 + m1.m[1][2] * m2.m[2][1]
0668 + m1.m[2][2] * m2.m[2][2]
0669 + m1.m[3][2] * m2.m[2][3];
0670 m.m[2][3] = m1.m[0][3] * m2.m[2][0]
0671 + m1.m[1][3] * m2.m[2][1]
0672 + m1.m[2][3] * m2.m[2][2]
0673 + m1.m[3][3] * m2.m[2][3];
0674
0675 m.m[3][0] = m1.m[0][0] * m2.m[3][0]
0676 + m1.m[1][0] * m2.m[3][1]
0677 + m1.m[2][0] * m2.m[3][2]
0678 + m1.m[3][0] * m2.m[3][3];
0679 m.m[3][1] = m1.m[0][1] * m2.m[3][0]
0680 + m1.m[1][1] * m2.m[3][1]
0681 + m1.m[2][1] * m2.m[3][2]
0682 + m1.m[3][1] * m2.m[3][3];
0683 m.m[3][2] = m1.m[0][2] * m2.m[3][0]
0684 + m1.m[1][2] * m2.m[3][1]
0685 + m1.m[2][2] * m2.m[3][2]
0686 + m1.m[3][2] * m2.m[3][3];
0687 m.m[3][3] = m1.m[0][3] * m2.m[3][0]
0688 + m1.m[1][3] * m2.m[3][1]
0689 + m1.m[2][3] * m2.m[3][2]
0690 + m1.m[3][3] * m2.m[3][3];
0691 m.flagBits = flagBits;
0692 return m;
0693 }
0694
0695 #ifndef QT_NO_VECTOR3D
0696
0697 #if QT_DEPRECATED_SINCE(6, 1)
0698
0699 QT_DEPRECATED_VERSION_X_6_1("Extend the QVector3D to a QVector4D with 1.0 as the w coordinate before multiplying")
0700 inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix)
0701 {
0702 float x, y, z, w;
0703 x = vector.x() * matrix.m[0][0] +
0704 vector.y() * matrix.m[0][1] +
0705 vector.z() * matrix.m[0][2] +
0706 matrix.m[0][3];
0707 y = vector.x() * matrix.m[1][0] +
0708 vector.y() * matrix.m[1][1] +
0709 vector.z() * matrix.m[1][2] +
0710 matrix.m[1][3];
0711 z = vector.x() * matrix.m[2][0] +
0712 vector.y() * matrix.m[2][1] +
0713 vector.z() * matrix.m[2][2] +
0714 matrix.m[2][3];
0715 w = vector.x() * matrix.m[3][0] +
0716 vector.y() * matrix.m[3][1] +
0717 vector.z() * matrix.m[3][2] +
0718 matrix.m[3][3];
0719 if (w == 1.0f)
0720 return QVector3D(x, y, z);
0721 else
0722 return QVector3D(x / w, y / w, z / w);
0723 }
0724
0725 QT_DEPRECATED_VERSION_X_6_1("Use matrix.map(vector) instead")
0726 inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector)
0727 {
0728 return matrix.map(vector);
0729 }
0730
0731 #endif
0732
0733 #endif
0734
0735 #ifndef QT_NO_VECTOR4D
0736
0737 inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix)
0738 {
0739 float x, y, z, w;
0740 x = vector.x() * matrix.m[0][0] +
0741 vector.y() * matrix.m[0][1] +
0742 vector.z() * matrix.m[0][2] +
0743 vector.w() * matrix.m[0][3];
0744 y = vector.x() * matrix.m[1][0] +
0745 vector.y() * matrix.m[1][1] +
0746 vector.z() * matrix.m[1][2] +
0747 vector.w() * matrix.m[1][3];
0748 z = vector.x() * matrix.m[2][0] +
0749 vector.y() * matrix.m[2][1] +
0750 vector.z() * matrix.m[2][2] +
0751 vector.w() * matrix.m[2][3];
0752 w = vector.x() * matrix.m[3][0] +
0753 vector.y() * matrix.m[3][1] +
0754 vector.z() * matrix.m[3][2] +
0755 vector.w() * matrix.m[3][3];
0756 return QVector4D(x, y, z, w);
0757 }
0758
0759 inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector)
0760 {
0761 float x, y, z, w;
0762 x = vector.x() * matrix.m[0][0] +
0763 vector.y() * matrix.m[1][0] +
0764 vector.z() * matrix.m[2][0] +
0765 vector.w() * matrix.m[3][0];
0766 y = vector.x() * matrix.m[0][1] +
0767 vector.y() * matrix.m[1][1] +
0768 vector.z() * matrix.m[2][1] +
0769 vector.w() * matrix.m[3][1];
0770 z = vector.x() * matrix.m[0][2] +
0771 vector.y() * matrix.m[1][2] +
0772 vector.z() * matrix.m[2][2] +
0773 vector.w() * matrix.m[3][2];
0774 w = vector.x() * matrix.m[0][3] +
0775 vector.y() * matrix.m[1][3] +
0776 vector.z() * matrix.m[2][3] +
0777 vector.w() * matrix.m[3][3];
0778 return QVector4D(x, y, z, w);
0779 }
0780
0781 #endif
0782
0783 inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix)
0784 {
0785 float xin, yin;
0786 float x, y, w;
0787 xin = point.x();
0788 yin = point.y();
0789 x = xin * matrix.m[0][0] +
0790 yin * matrix.m[0][1] +
0791 matrix.m[0][3];
0792 y = xin * matrix.m[1][0] +
0793 yin * matrix.m[1][1] +
0794 matrix.m[1][3];
0795 w = xin * matrix.m[3][0] +
0796 yin * matrix.m[3][1] +
0797 matrix.m[3][3];
0798 if (w == 1.0f)
0799 return QPoint(qRound(x), qRound(y));
0800 else
0801 return QPoint(qRound(x / w), qRound(y / w));
0802 }
0803
0804 inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix)
0805 {
0806 float xin, yin;
0807 float x, y, w;
0808 xin = float(point.x());
0809 yin = float(point.y());
0810 x = xin * matrix.m[0][0] +
0811 yin * matrix.m[0][1] +
0812 matrix.m[0][3];
0813 y = xin * matrix.m[1][0] +
0814 yin * matrix.m[1][1] +
0815 matrix.m[1][3];
0816 w = xin * matrix.m[3][0] +
0817 yin * matrix.m[3][1] +
0818 matrix.m[3][3];
0819 if (w == 1.0f) {
0820 return QPointF(qreal(x), qreal(y));
0821 } else {
0822 return QPointF(qreal(x / w), qreal(y / w));
0823 }
0824 }
0825
0826 #if QT_DEPRECATED_SINCE(6, 1)
0827
0828 QT_DEPRECATED_VERSION_X_6_1("Use matrix.map(point) instead")
0829 inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point)
0830 {
0831 return matrix.map(point);
0832 }
0833
0834 QT_DEPRECATED_VERSION_X_6_1("Use matrix.map(point) instead")
0835 inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point)
0836 {
0837 return matrix.map(point);
0838 }
0839
0840 #endif
0841
0842 inline QMatrix4x4 operator-(const QMatrix4x4& matrix)
0843 {
0844 QMatrix4x4 m(Qt::Uninitialized);
0845 m.m[0][0] = -matrix.m[0][0];
0846 m.m[0][1] = -matrix.m[0][1];
0847 m.m[0][2] = -matrix.m[0][2];
0848 m.m[0][3] = -matrix.m[0][3];
0849 m.m[1][0] = -matrix.m[1][0];
0850 m.m[1][1] = -matrix.m[1][1];
0851 m.m[1][2] = -matrix.m[1][2];
0852 m.m[1][3] = -matrix.m[1][3];
0853 m.m[2][0] = -matrix.m[2][0];
0854 m.m[2][1] = -matrix.m[2][1];
0855 m.m[2][2] = -matrix.m[2][2];
0856 m.m[2][3] = -matrix.m[2][3];
0857 m.m[3][0] = -matrix.m[3][0];
0858 m.m[3][1] = -matrix.m[3][1];
0859 m.m[3][2] = -matrix.m[3][2];
0860 m.m[3][3] = -matrix.m[3][3];
0861 return m;
0862 }
0863
0864 inline QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix)
0865 {
0866 QMatrix4x4 m(Qt::Uninitialized);
0867 m.m[0][0] = matrix.m[0][0] * factor;
0868 m.m[0][1] = matrix.m[0][1] * factor;
0869 m.m[0][2] = matrix.m[0][2] * factor;
0870 m.m[0][3] = matrix.m[0][3] * factor;
0871 m.m[1][0] = matrix.m[1][0] * factor;
0872 m.m[1][1] = matrix.m[1][1] * factor;
0873 m.m[1][2] = matrix.m[1][2] * factor;
0874 m.m[1][3] = matrix.m[1][3] * factor;
0875 m.m[2][0] = matrix.m[2][0] * factor;
0876 m.m[2][1] = matrix.m[2][1] * factor;
0877 m.m[2][2] = matrix.m[2][2] * factor;
0878 m.m[2][3] = matrix.m[2][3] * factor;
0879 m.m[3][0] = matrix.m[3][0] * factor;
0880 m.m[3][1] = matrix.m[3][1] * factor;
0881 m.m[3][2] = matrix.m[3][2] * factor;
0882 m.m[3][3] = matrix.m[3][3] * factor;
0883 return m;
0884 }
0885
0886 inline QMatrix4x4 operator*(const QMatrix4x4& matrix, float factor)
0887 {
0888 QMatrix4x4 m(Qt::Uninitialized);
0889 m.m[0][0] = matrix.m[0][0] * factor;
0890 m.m[0][1] = matrix.m[0][1] * factor;
0891 m.m[0][2] = matrix.m[0][2] * factor;
0892 m.m[0][3] = matrix.m[0][3] * factor;
0893 m.m[1][0] = matrix.m[1][0] * factor;
0894 m.m[1][1] = matrix.m[1][1] * factor;
0895 m.m[1][2] = matrix.m[1][2] * factor;
0896 m.m[1][3] = matrix.m[1][3] * factor;
0897 m.m[2][0] = matrix.m[2][0] * factor;
0898 m.m[2][1] = matrix.m[2][1] * factor;
0899 m.m[2][2] = matrix.m[2][2] * factor;
0900 m.m[2][3] = matrix.m[2][3] * factor;
0901 m.m[3][0] = matrix.m[3][0] * factor;
0902 m.m[3][1] = matrix.m[3][1] * factor;
0903 m.m[3][2] = matrix.m[3][2] * factor;
0904 m.m[3][3] = matrix.m[3][3] * factor;
0905 return m;
0906 }
0907
0908 inline QPoint QMatrix4x4::map(const QPoint& point) const
0909 {
0910 float xin, yin;
0911 float x, y, w;
0912 xin = point.x();
0913 yin = point.y();
0914 if (flagBits == QMatrix4x4::Identity) {
0915 return point;
0916 } else if (flagBits.toInt() < QMatrix4x4::Rotation2D) {
0917
0918 return QPoint(qRound(xin * m[0][0] + m[3][0]),
0919 qRound(yin * m[1][1] + m[3][1]));
0920 } else if (flagBits.toInt() < QMatrix4x4::Perspective) {
0921 return QPoint(qRound(xin * m[0][0] + yin * m[1][0] + m[3][0]),
0922 qRound(xin * m[0][1] + yin * m[1][1] + m[3][1]));
0923 } else {
0924 x = xin * m[0][0] +
0925 yin * m[1][0] +
0926 m[3][0];
0927 y = xin * m[0][1] +
0928 yin * m[1][1] +
0929 m[3][1];
0930 w = xin * m[0][3] +
0931 yin * m[1][3] +
0932 m[3][3];
0933 if (w == 1.0f)
0934 return QPoint(qRound(x), qRound(y));
0935 else
0936 return QPoint(qRound(x / w), qRound(y / w));
0937 }
0938 }
0939
0940 inline QPointF QMatrix4x4::map(const QPointF& point) const
0941 {
0942 qreal xin, yin;
0943 qreal x, y, w;
0944 xin = point.x();
0945 yin = point.y();
0946 if (flagBits == QMatrix4x4::Identity) {
0947 return point;
0948 } else if (flagBits.toInt() < QMatrix4x4::Rotation2D) {
0949
0950 return QPointF(xin * qreal(m[0][0]) + qreal(m[3][0]),
0951 yin * qreal(m[1][1]) + qreal(m[3][1]));
0952 } else if (flagBits.toInt() < QMatrix4x4::Perspective) {
0953 return QPointF(xin * qreal(m[0][0]) + yin * qreal(m[1][0]) +
0954 qreal(m[3][0]),
0955 xin * qreal(m[0][1]) + yin * qreal(m[1][1]) +
0956 qreal(m[3][1]));
0957 } else {
0958 x = xin * qreal(m[0][0]) +
0959 yin * qreal(m[1][0]) +
0960 qreal(m[3][0]);
0961 y = xin * qreal(m[0][1]) +
0962 yin * qreal(m[1][1]) +
0963 qreal(m[3][1]);
0964 w = xin * qreal(m[0][3]) +
0965 yin * qreal(m[1][3]) +
0966 qreal(m[3][3]);
0967 if (w == 1.0) {
0968 return QPointF(qreal(x), qreal(y));
0969 } else {
0970 return QPointF(qreal(x / w), qreal(y / w));
0971 }
0972 }
0973 }
0974
0975 #ifndef QT_NO_VECTOR3D
0976
0977 inline QVector3D QMatrix4x4::map(const QVector3D& point) const
0978 {
0979 float x, y, z, w;
0980 if (flagBits == QMatrix4x4::Identity) {
0981 return point;
0982 } else if (flagBits.toInt() < QMatrix4x4::Rotation2D) {
0983
0984 return QVector3D(point.x() * m[0][0] + m[3][0],
0985 point.y() * m[1][1] + m[3][1],
0986 point.z() * m[2][2] + m[3][2]);
0987 } else if (flagBits.toInt() < QMatrix4x4::Rotation) {
0988
0989 return QVector3D(point.x() * m[0][0] + point.y() * m[1][0] + m[3][0],
0990 point.x() * m[0][1] + point.y() * m[1][1] + m[3][1],
0991 point.z() * m[2][2] + m[3][2]);
0992 } else {
0993 x = point.x() * m[0][0] +
0994 point.y() * m[1][0] +
0995 point.z() * m[2][0] +
0996 m[3][0];
0997 y = point.x() * m[0][1] +
0998 point.y() * m[1][1] +
0999 point.z() * m[2][1] +
1000 m[3][1];
1001 z = point.x() * m[0][2] +
1002 point.y() * m[1][2] +
1003 point.z() * m[2][2] +
1004 m[3][2];
1005 w = point.x() * m[0][3] +
1006 point.y() * m[1][3] +
1007 point.z() * m[2][3] +
1008 m[3][3];
1009 if (w == 1.0f)
1010 return QVector3D(x, y, z);
1011 else
1012 return QVector3D(x / w, y / w, z / w);
1013 }
1014 }
1015
1016 inline QVector3D QMatrix4x4::mapVector(const QVector3D& vector) const
1017 {
1018 if (flagBits.toInt() < Scale) {
1019
1020 return vector;
1021 } else if (flagBits.toInt() < Rotation2D) {
1022
1023 return QVector3D(vector.x() * m[0][0],
1024 vector.y() * m[1][1],
1025 vector.z() * m[2][2]);
1026 } else {
1027 return QVector3D(vector.x() * m[0][0] +
1028 vector.y() * m[1][0] +
1029 vector.z() * m[2][0],
1030 vector.x() * m[0][1] +
1031 vector.y() * m[1][1] +
1032 vector.z() * m[2][1],
1033 vector.x() * m[0][2] +
1034 vector.y() * m[1][2] +
1035 vector.z() * m[2][2]);
1036 }
1037 }
1038
1039 #endif
1040
1041 #ifndef QT_NO_VECTOR4D
1042
1043 inline QVector4D QMatrix4x4::map(const QVector4D& point) const
1044 {
1045 return *this * point;
1046 }
1047
1048 #endif
1049
1050 inline float *QMatrix4x4::data()
1051 {
1052
1053
1054 flagBits = General;
1055 return *m;
1056 }
1057
1058 inline void QMatrix4x4::viewport(const QRectF &rect)
1059 {
1060 viewport(float(rect.x()), float(rect.y()), float(rect.width()), float(rect.height()));
1061 }
1062
1063 QT_WARNING_POP
1064
1065 #ifndef QT_NO_DEBUG_STREAM
1066 Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m);
1067 #endif
1068
1069 #ifndef QT_NO_DATASTREAM
1070 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QMatrix4x4 &);
1071 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix4x4 &);
1072 #endif
1073
1074 #endif
1075
1076 QT_END_NAMESPACE
1077
1078 #endif