00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef QMATRIX4X4_H
00043 #define QMATRIX4X4_H
00044
00045 #include <QtGui/qvector3d.h>
00046 #include <QtGui/qvector4d.h>
00047 #include <QtGui/qquaternion.h>
00048 #include <QtGui/qgenericmatrix.h>
00049 #include <QtCore/qrect.h>
00050
00051 QT_BEGIN_HEADER
00052
00053 QT_BEGIN_NAMESPACE
00054
00055 QT_MODULE(Gui)
00056
00057 #ifndef QT_NO_MATRIX4X4
00058
00059 class QMatrix;
00060 class QTransform;
00061 class QVariant;
00062
00063 class Q_GUI_EXPORT QMatrix4x4
00064 {
00065 public:
00066 inline QMatrix4x4() { setToIdentity(); }
00067 explicit QMatrix4x4(const qreal *values);
00068 inline QMatrix4x4(qreal m11, qreal m12, qreal m13, qreal m14,
00069 qreal m21, qreal m22, qreal m23, qreal m24,
00070 qreal m31, qreal m32, qreal m33, qreal m34,
00071 qreal m41, qreal m42, qreal m43, qreal m44);
00072 #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
00073 template <int N, int M>
00074 explicit QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix);
00075 #endif
00076 QMatrix4x4(const qreal *values, int cols, int rows);
00077 QMatrix4x4(const QTransform& transform);
00078 QMatrix4x4(const QMatrix& matrix);
00079
00080 inline const qreal& operator()(int row, int column) const;
00081 inline qreal& operator()(int row, int column);
00082
00083 inline QVector4D column(int index) const;
00084 inline void setColumn(int index, const QVector4D& value);
00085
00086 inline QVector4D row(int index) const;
00087 inline void setRow(int index, const QVector4D& value);
00088
00089 inline bool isIdentity() const;
00090 inline void setToIdentity();
00091
00092 inline void fill(qreal value);
00093
00094 qreal determinant() const;
00095 QMatrix4x4 inverted(bool *invertible = 0) const;
00096 QMatrix4x4 transposed() const;
00097 QMatrix3x3 normalMatrix() const;
00098
00099 inline QMatrix4x4& operator+=(const QMatrix4x4& other);
00100 inline QMatrix4x4& operator-=(const QMatrix4x4& other);
00101 inline QMatrix4x4& operator*=(const QMatrix4x4& other);
00102 inline QMatrix4x4& operator*=(qreal factor);
00103 QMatrix4x4& operator/=(qreal divisor);
00104 inline bool operator==(const QMatrix4x4& other) const;
00105 inline bool operator!=(const QMatrix4x4& other) const;
00106
00107 friend QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2);
00108 friend QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2);
00109 friend QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2);
00110 #ifndef QT_NO_VECTOR3D
00111 friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector);
00112 friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix);
00113 #endif
00114 #ifndef QT_NO_VECTOR4D
00115 friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix);
00116 friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector);
00117 #endif
00118 friend QPoint operator*(const QPoint& point, const QMatrix4x4& matrix);
00119 friend QPointF operator*(const QPointF& point, const QMatrix4x4& matrix);
00120 friend QMatrix4x4 operator-(const QMatrix4x4& matrix);
00121 friend QPoint operator*(const QMatrix4x4& matrix, const QPoint& point);
00122 friend QPointF operator*(const QMatrix4x4& matrix, const QPointF& point);
00123 friend QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix);
00124 friend QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor);
00125 friend Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor);
00126
00127 friend inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2);
00128
00129 #ifndef QT_NO_VECTOR3D
00130 void scale(const QVector3D& vector);
00131 void translate(const QVector3D& vector);
00132 void rotate(qreal angle, const QVector3D& vector);
00133 #endif
00134 void scale(qreal x, qreal y);
00135 void scale(qreal x, qreal y, qreal z);
00136 void scale(qreal factor);
00137 void translate(qreal x, qreal y);
00138 void translate(qreal x, qreal y, qreal z);
00139 void rotate(qreal angle, qreal x, qreal y, qreal z = 0.0f);
00140 #ifndef QT_NO_QUATERNION
00141 void rotate(const QQuaternion& quaternion);
00142 #endif
00143
00144 void ortho(const QRect& rect);
00145 void ortho(const QRectF& rect);
00146 void ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
00147 void frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
00148 void perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane);
00149 #ifndef QT_NO_VECTOR3D
00150 void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
00151 #endif
00152 void flipCoordinates();
00153
00154 void copyDataTo(qreal *values) const;
00155
00156 QMatrix toAffine() const;
00157 QTransform toTransform() const;
00158 QTransform toTransform(qreal distanceToPlane) const;
00159
00160 QPoint map(const QPoint& point) const;
00161 QPointF map(const QPointF& point) const;
00162 #ifndef QT_NO_VECTOR3D
00163 QVector3D map(const QVector3D& point) const;
00164 QVector3D mapVector(const QVector3D& vector) const;
00165 #endif
00166 #ifndef QT_NO_VECTOR4D
00167 QVector4D map(const QVector4D& point) const;
00168 #endif
00169 QRect mapRect(const QRect& rect) const;
00170 QRectF mapRect(const QRectF& rect) const;
00171
00172 #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
00173 template <int N, int M>
00174 QGenericMatrix<N, M, qreal> toGenericMatrix() const;
00175 #endif
00176
00177 inline qreal *data();
00178 inline const qreal *data() const { return m[0]; }
00179 inline const qreal *constData() const { return m[0]; }
00180
00181 void optimize();
00182
00183 operator QVariant() const;
00184
00185 #ifndef QT_NO_DEBUG_STREAM
00186 friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m);
00187 #endif
00188
00189 private:
00190 qreal m[4][4];
00191 int flagBits;
00192
00193 enum {
00194 Identity = 0x0001,
00195 General = 0x0002,
00196 Translation = 0x0004,
00197 Scale = 0x0008,
00198 Rotation = 0x0010
00199 };
00200
00201
00202 QMatrix4x4(int) { flagBits = General; }
00203
00204 QMatrix4x4 orthonormalInverse() const;
00205
00206 void projectedRotate(qreal angle, qreal x, qreal y, qreal z);
00207
00208 friend class QGraphicsRotation;
00209 };
00210
00211 Q_DECLARE_TYPEINFO(QMatrix4x4, Q_MOVABLE_TYPE);
00212
00213 inline QMatrix4x4::QMatrix4x4
00214 (qreal m11, qreal m12, qreal m13, qreal m14,
00215 qreal m21, qreal m22, qreal m23, qreal m24,
00216 qreal m31, qreal m32, qreal m33, qreal m34,
00217 qreal m41, qreal m42, qreal m43, qreal m44)
00218 {
00219 m[0][0] = m11; m[0][1] = m21; m[0][2] = m31; m[0][3] = m41;
00220 m[1][0] = m12; m[1][1] = m22; m[1][2] = m32; m[1][3] = m42;
00221 m[2][0] = m13; m[2][1] = m23; m[2][2] = m33; m[2][3] = m43;
00222 m[3][0] = m14; m[3][1] = m24; m[3][2] = m34; m[3][3] = m44;
00223 flagBits = General;
00224 }
00225
00226 #if !defined(QT_NO_MEMBER_TEMPLATES)
00227
00228 template <int N, int M>
00229 Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4
00230 (const QGenericMatrix<N, M, qreal>& matrix)
00231 {
00232 const qreal *values = matrix.constData();
00233 for (int matrixCol = 0; matrixCol < 4; ++matrixCol) {
00234 for (int matrixRow = 0; matrixRow < 4; ++matrixRow) {
00235 if (matrixCol < N && matrixRow < M)
00236 m[matrixCol][matrixRow] = values[matrixCol * M + matrixRow];
00237 else if (matrixCol == matrixRow)
00238 m[matrixCol][matrixRow] = 1.0f;
00239 else
00240 m[matrixCol][matrixRow] = 0.0f;
00241 }
00242 }
00243 flagBits = General;
00244 }
00245
00246 template <int N, int M>
00247 QGenericMatrix<N, M, qreal> QMatrix4x4::toGenericMatrix() const
00248 {
00249 QGenericMatrix<N, M, qreal> result;
00250 qreal *values = result.data();
00251 for (int matrixCol = 0; matrixCol < N; ++matrixCol) {
00252 for (int matrixRow = 0; matrixRow < M; ++matrixRow) {
00253 if (matrixCol < 4 && matrixRow < 4)
00254 values[matrixCol * M + matrixRow] = m[matrixCol][matrixRow];
00255 else if (matrixCol == matrixRow)
00256 values[matrixCol * M + matrixRow] = 1.0f;
00257 else
00258 values[matrixCol * M + matrixRow] = 0.0f;
00259 }
00260 }
00261 return result;
00262 }
00263
00264 #endif
00265
00266 inline const qreal& QMatrix4x4::operator()(int aRow, int aColumn) const
00267 {
00268 Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
00269 return m[aColumn][aRow];
00270 }
00271
00272 inline qreal& QMatrix4x4::operator()(int aRow, int aColumn)
00273 {
00274 Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
00275 flagBits = General;
00276 return m[aColumn][aRow];
00277 }
00278
00279 inline QVector4D QMatrix4x4::column(int index) const
00280 {
00281 Q_ASSERT(index >= 0 && index < 4);
00282 return QVector4D(m[index][0], m[index][1], m[index][2], m[index][3]);
00283 }
00284
00285 inline void QMatrix4x4::setColumn(int index, const QVector4D& value)
00286 {
00287 Q_ASSERT(index >= 0 && index < 4);
00288 m[index][0] = value.x();
00289 m[index][1] = value.y();
00290 m[index][2] = value.z();
00291 m[index][3] = value.w();
00292 flagBits = General;
00293 }
00294
00295 inline QVector4D QMatrix4x4::row(int index) const
00296 {
00297 Q_ASSERT(index >= 0 && index < 4);
00298 return QVector4D(m[0][index], m[1][index], m[2][index], m[3][index]);
00299 }
00300
00301 inline void QMatrix4x4::setRow(int index, const QVector4D& value)
00302 {
00303 Q_ASSERT(index >= 0 && index < 4);
00304 m[0][index] = value.x();
00305 m[1][index] = value.y();
00306 m[2][index] = value.z();
00307 m[3][index] = value.w();
00308 flagBits = General;
00309 }
00310
00311 Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor);
00312
00313 inline bool QMatrix4x4::isIdentity() const
00314 {
00315 if (flagBits == Identity)
00316 return true;
00317 if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f)
00318 return false;
00319 if (m[0][3] != 0.0f || m[1][0] != 0.0f || m[1][1] != 1.0f)
00320 return false;
00321 if (m[1][2] != 0.0f || m[1][3] != 0.0f || m[2][0] != 0.0f)
00322 return false;
00323 if (m[2][1] != 0.0f || m[2][2] != 1.0f || m[2][3] != 0.0f)
00324 return false;
00325 if (m[3][0] != 0.0f || m[3][1] != 0.0f || m[3][2] != 0.0f)
00326 return false;
00327 return (m[3][3] == 1.0f);
00328 }
00329
00330 inline void QMatrix4x4::setToIdentity()
00331 {
00332 m[0][0] = 1.0f;
00333 m[0][1] = 0.0f;
00334 m[0][2] = 0.0f;
00335 m[0][3] = 0.0f;
00336 m[1][0] = 0.0f;
00337 m[1][1] = 1.0f;
00338 m[1][2] = 0.0f;
00339 m[1][3] = 0.0f;
00340 m[2][0] = 0.0f;
00341 m[2][1] = 0.0f;
00342 m[2][2] = 1.0f;
00343 m[2][3] = 0.0f;
00344 m[3][0] = 0.0f;
00345 m[3][1] = 0.0f;
00346 m[3][2] = 0.0f;
00347 m[3][3] = 1.0f;
00348 flagBits = Identity;
00349 }
00350
00351 inline void QMatrix4x4::fill(qreal value)
00352 {
00353 m[0][0] = value;
00354 m[0][1] = value;
00355 m[0][2] = value;
00356 m[0][3] = value;
00357 m[1][0] = value;
00358 m[1][1] = value;
00359 m[1][2] = value;
00360 m[1][3] = value;
00361 m[2][0] = value;
00362 m[2][1] = value;
00363 m[2][2] = value;
00364 m[2][3] = value;
00365 m[3][0] = value;
00366 m[3][1] = value;
00367 m[3][2] = value;
00368 m[3][3] = value;
00369 flagBits = General;
00370 }
00371
00372 inline QMatrix4x4& QMatrix4x4::operator+=(const QMatrix4x4& other)
00373 {
00374 m[0][0] += other.m[0][0];
00375 m[0][1] += other.m[0][1];
00376 m[0][2] += other.m[0][2];
00377 m[0][3] += other.m[0][3];
00378 m[1][0] += other.m[1][0];
00379 m[1][1] += other.m[1][1];
00380 m[1][2] += other.m[1][2];
00381 m[1][3] += other.m[1][3];
00382 m[2][0] += other.m[2][0];
00383 m[2][1] += other.m[2][1];
00384 m[2][2] += other.m[2][2];
00385 m[2][3] += other.m[2][3];
00386 m[3][0] += other.m[3][0];
00387 m[3][1] += other.m[3][1];
00388 m[3][2] += other.m[3][2];
00389 m[3][3] += other.m[3][3];
00390 flagBits = General;
00391 return *this;
00392 }
00393
00394 inline QMatrix4x4& QMatrix4x4::operator-=(const QMatrix4x4& other)
00395 {
00396 m[0][0] -= other.m[0][0];
00397 m[0][1] -= other.m[0][1];
00398 m[0][2] -= other.m[0][2];
00399 m[0][3] -= other.m[0][3];
00400 m[1][0] -= other.m[1][0];
00401 m[1][1] -= other.m[1][1];
00402 m[1][2] -= other.m[1][2];
00403 m[1][3] -= other.m[1][3];
00404 m[2][0] -= other.m[2][0];
00405 m[2][1] -= other.m[2][1];
00406 m[2][2] -= other.m[2][2];
00407 m[2][3] -= other.m[2][3];
00408 m[3][0] -= other.m[3][0];
00409 m[3][1] -= other.m[3][1];
00410 m[3][2] -= other.m[3][2];
00411 m[3][3] -= other.m[3][3];
00412 flagBits = General;
00413 return *this;
00414 }
00415
00416 inline QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& other)
00417 {
00418 if (flagBits == Identity) {
00419 *this = other;
00420 return *this;
00421 } else if (other.flagBits == Identity) {
00422 return *this;
00423 } else {
00424 *this = *this * other;
00425 return *this;
00426 }
00427 }
00428
00429 inline QMatrix4x4& QMatrix4x4::operator*=(qreal factor)
00430 {
00431 m[0][0] *= factor;
00432 m[0][1] *= factor;
00433 m[0][2] *= factor;
00434 m[0][3] *= factor;
00435 m[1][0] *= factor;
00436 m[1][1] *= factor;
00437 m[1][2] *= factor;
00438 m[1][3] *= factor;
00439 m[2][0] *= factor;
00440 m[2][1] *= factor;
00441 m[2][2] *= factor;
00442 m[2][3] *= factor;
00443 m[3][0] *= factor;
00444 m[3][1] *= factor;
00445 m[3][2] *= factor;
00446 m[3][3] *= factor;
00447 flagBits = General;
00448 return *this;
00449 }
00450
00451 inline bool QMatrix4x4::operator==(const QMatrix4x4& other) const
00452 {
00453 return m[0][0] == other.m[0][0] &&
00454 m[0][1] == other.m[0][1] &&
00455 m[0][2] == other.m[0][2] &&
00456 m[0][3] == other.m[0][3] &&
00457 m[1][0] == other.m[1][0] &&
00458 m[1][1] == other.m[1][1] &&
00459 m[1][2] == other.m[1][2] &&
00460 m[1][3] == other.m[1][3] &&
00461 m[2][0] == other.m[2][0] &&
00462 m[2][1] == other.m[2][1] &&
00463 m[2][2] == other.m[2][2] &&
00464 m[2][3] == other.m[2][3] &&
00465 m[3][0] == other.m[3][0] &&
00466 m[3][1] == other.m[3][1] &&
00467 m[3][2] == other.m[3][2] &&
00468 m[3][3] == other.m[3][3];
00469 }
00470
00471 inline bool QMatrix4x4::operator!=(const QMatrix4x4& other) const
00472 {
00473 return m[0][0] != other.m[0][0] ||
00474 m[0][1] != other.m[0][1] ||
00475 m[0][2] != other.m[0][2] ||
00476 m[0][3] != other.m[0][3] ||
00477 m[1][0] != other.m[1][0] ||
00478 m[1][1] != other.m[1][1] ||
00479 m[1][2] != other.m[1][2] ||
00480 m[1][3] != other.m[1][3] ||
00481 m[2][0] != other.m[2][0] ||
00482 m[2][1] != other.m[2][1] ||
00483 m[2][2] != other.m[2][2] ||
00484 m[2][3] != other.m[2][3] ||
00485 m[3][0] != other.m[3][0] ||
00486 m[3][1] != other.m[3][1] ||
00487 m[3][2] != other.m[3][2] ||
00488 m[3][3] != other.m[3][3];
00489 }
00490
00491 inline QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2)
00492 {
00493 QMatrix4x4 m(1);
00494 m.m[0][0] = m1.m[0][0] + m2.m[0][0];
00495 m.m[0][1] = m1.m[0][1] + m2.m[0][1];
00496 m.m[0][2] = m1.m[0][2] + m2.m[0][2];
00497 m.m[0][3] = m1.m[0][3] + m2.m[0][3];
00498 m.m[1][0] = m1.m[1][0] + m2.m[1][0];
00499 m.m[1][1] = m1.m[1][1] + m2.m[1][1];
00500 m.m[1][2] = m1.m[1][2] + m2.m[1][2];
00501 m.m[1][3] = m1.m[1][3] + m2.m[1][3];
00502 m.m[2][0] = m1.m[2][0] + m2.m[2][0];
00503 m.m[2][1] = m1.m[2][1] + m2.m[2][1];
00504 m.m[2][2] = m1.m[2][2] + m2.m[2][2];
00505 m.m[2][3] = m1.m[2][3] + m2.m[2][3];
00506 m.m[3][0] = m1.m[3][0] + m2.m[3][0];
00507 m.m[3][1] = m1.m[3][1] + m2.m[3][1];
00508 m.m[3][2] = m1.m[3][2] + m2.m[3][2];
00509 m.m[3][3] = m1.m[3][3] + m2.m[3][3];
00510 return m;
00511 }
00512
00513 inline QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2)
00514 {
00515 QMatrix4x4 m(1);
00516 m.m[0][0] = m1.m[0][0] - m2.m[0][0];
00517 m.m[0][1] = m1.m[0][1] - m2.m[0][1];
00518 m.m[0][2] = m1.m[0][2] - m2.m[0][2];
00519 m.m[0][3] = m1.m[0][3] - m2.m[0][3];
00520 m.m[1][0] = m1.m[1][0] - m2.m[1][0];
00521 m.m[1][1] = m1.m[1][1] - m2.m[1][1];
00522 m.m[1][2] = m1.m[1][2] - m2.m[1][2];
00523 m.m[1][3] = m1.m[1][3] - m2.m[1][3];
00524 m.m[2][0] = m1.m[2][0] - m2.m[2][0];
00525 m.m[2][1] = m1.m[2][1] - m2.m[2][1];
00526 m.m[2][2] = m1.m[2][2] - m2.m[2][2];
00527 m.m[2][3] = m1.m[2][3] - m2.m[2][3];
00528 m.m[3][0] = m1.m[3][0] - m2.m[3][0];
00529 m.m[3][1] = m1.m[3][1] - m2.m[3][1];
00530 m.m[3][2] = m1.m[3][2] - m2.m[3][2];
00531 m.m[3][3] = m1.m[3][3] - m2.m[3][3];
00532 return m;
00533 }
00534
00535 inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2)
00536 {
00537 if (m1.flagBits == QMatrix4x4::Identity)
00538 return m2;
00539 else if (m2.flagBits == QMatrix4x4::Identity)
00540 return m1;
00541
00542 QMatrix4x4 m(1);
00543 m.m[0][0] = m1.m[0][0] * m2.m[0][0] +
00544 m1.m[1][0] * m2.m[0][1] +
00545 m1.m[2][0] * m2.m[0][2] +
00546 m1.m[3][0] * m2.m[0][3];
00547 m.m[0][1] = m1.m[0][1] * m2.m[0][0] +
00548 m1.m[1][1] * m2.m[0][1] +
00549 m1.m[2][1] * m2.m[0][2] +
00550 m1.m[3][1] * m2.m[0][3];
00551 m.m[0][2] = m1.m[0][2] * m2.m[0][0] +
00552 m1.m[1][2] * m2.m[0][1] +
00553 m1.m[2][2] * m2.m[0][2] +
00554 m1.m[3][2] * m2.m[0][3];
00555 m.m[0][3] = m1.m[0][3] * m2.m[0][0] +
00556 m1.m[1][3] * m2.m[0][1] +
00557 m1.m[2][3] * m2.m[0][2] +
00558 m1.m[3][3] * m2.m[0][3];
00559 m.m[1][0] = m1.m[0][0] * m2.m[1][0] +
00560 m1.m[1][0] * m2.m[1][1] +
00561 m1.m[2][0] * m2.m[1][2] +
00562 m1.m[3][0] * m2.m[1][3];
00563 m.m[1][1] = m1.m[0][1] * m2.m[1][0] +
00564 m1.m[1][1] * m2.m[1][1] +
00565 m1.m[2][1] * m2.m[1][2] +
00566 m1.m[3][1] * m2.m[1][3];
00567 m.m[1][2] = m1.m[0][2] * m2.m[1][0] +
00568 m1.m[1][2] * m2.m[1][1] +
00569 m1.m[2][2] * m2.m[1][2] +
00570 m1.m[3][2] * m2.m[1][3];
00571 m.m[1][3] = m1.m[0][3] * m2.m[1][0] +
00572 m1.m[1][3] * m2.m[1][1] +
00573 m1.m[2][3] * m2.m[1][2] +
00574 m1.m[3][3] * m2.m[1][3];
00575 m.m[2][0] = m1.m[0][0] * m2.m[2][0] +
00576 m1.m[1][0] * m2.m[2][1] +
00577 m1.m[2][0] * m2.m[2][2] +
00578 m1.m[3][0] * m2.m[2][3];
00579 m.m[2][1] = m1.m[0][1] * m2.m[2][0] +
00580 m1.m[1][1] * m2.m[2][1] +
00581 m1.m[2][1] * m2.m[2][2] +
00582 m1.m[3][1] * m2.m[2][3];
00583 m.m[2][2] = m1.m[0][2] * m2.m[2][0] +
00584 m1.m[1][2] * m2.m[2][1] +
00585 m1.m[2][2] * m2.m[2][2] +
00586 m1.m[3][2] * m2.m[2][3];
00587 m.m[2][3] = m1.m[0][3] * m2.m[2][0] +
00588 m1.m[1][3] * m2.m[2][1] +
00589 m1.m[2][3] * m2.m[2][2] +
00590 m1.m[3][3] * m2.m[2][3];
00591 m.m[3][0] = m1.m[0][0] * m2.m[3][0] +
00592 m1.m[1][0] * m2.m[3][1] +
00593 m1.m[2][0] * m2.m[3][2] +
00594 m1.m[3][0] * m2.m[3][3];
00595 m.m[3][1] = m1.m[0][1] * m2.m[3][0] +
00596 m1.m[1][1] * m2.m[3][1] +
00597 m1.m[2][1] * m2.m[3][2] +
00598 m1.m[3][1] * m2.m[3][3];
00599 m.m[3][2] = m1.m[0][2] * m2.m[3][0] +
00600 m1.m[1][2] * m2.m[3][1] +
00601 m1.m[2][2] * m2.m[3][2] +
00602 m1.m[3][2] * m2.m[3][3];
00603 m.m[3][3] = m1.m[0][3] * m2.m[3][0] +
00604 m1.m[1][3] * m2.m[3][1] +
00605 m1.m[2][3] * m2.m[3][2] +
00606 m1.m[3][3] * m2.m[3][3];
00607 return m;
00608 }
00609
00610 #ifndef QT_NO_VECTOR3D
00611
00612 inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix)
00613 {
00614 qreal x, y, z, w;
00615 x = vector.x() * matrix.m[0][0] +
00616 vector.y() * matrix.m[0][1] +
00617 vector.z() * matrix.m[0][2] +
00618 matrix.m[0][3];
00619 y = vector.x() * matrix.m[1][0] +
00620 vector.y() * matrix.m[1][1] +
00621 vector.z() * matrix.m[1][2] +
00622 matrix.m[1][3];
00623 z = vector.x() * matrix.m[2][0] +
00624 vector.y() * matrix.m[2][1] +
00625 vector.z() * matrix.m[2][2] +
00626 matrix.m[2][3];
00627 w = vector.x() * matrix.m[3][0] +
00628 vector.y() * matrix.m[3][1] +
00629 vector.z() * matrix.m[3][2] +
00630 matrix.m[3][3];
00631 if (w == 1.0f)
00632 return QVector3D(x, y, z);
00633 else
00634 return QVector3D(x / w, y / w, z / w);
00635 }
00636
00637 inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector)
00638 {
00639 qreal x, y, z, w;
00640 if (matrix.flagBits == QMatrix4x4::Identity) {
00641 return vector;
00642 } else if (matrix.flagBits == QMatrix4x4::Translation) {
00643 return QVector3D(vector.x() + matrix.m[3][0],
00644 vector.y() + matrix.m[3][1],
00645 vector.z() + matrix.m[3][2]);
00646 } else if (matrix.flagBits ==
00647 (QMatrix4x4::Translation | QMatrix4x4::Scale)) {
00648 return QVector3D(vector.x() * matrix.m[0][0] + matrix.m[3][0],
00649 vector.y() * matrix.m[1][1] + matrix.m[3][1],
00650 vector.z() * matrix.m[2][2] + matrix.m[3][2]);
00651 } else if (matrix.flagBits == QMatrix4x4::Scale) {
00652 return QVector3D(vector.x() * matrix.m[0][0],
00653 vector.y() * matrix.m[1][1],
00654 vector.z() * matrix.m[2][2]);
00655 } else {
00656 x = vector.x() * matrix.m[0][0] +
00657 vector.y() * matrix.m[1][0] +
00658 vector.z() * matrix.m[2][0] +
00659 matrix.m[3][0];
00660 y = vector.x() * matrix.m[0][1] +
00661 vector.y() * matrix.m[1][1] +
00662 vector.z() * matrix.m[2][1] +
00663 matrix.m[3][1];
00664 z = vector.x() * matrix.m[0][2] +
00665 vector.y() * matrix.m[1][2] +
00666 vector.z() * matrix.m[2][2] +
00667 matrix.m[3][2];
00668 w = vector.x() * matrix.m[0][3] +
00669 vector.y() * matrix.m[1][3] +
00670 vector.z() * matrix.m[2][3] +
00671 matrix.m[3][3];
00672 if (w == 1.0f)
00673 return QVector3D(x, y, z);
00674 else
00675 return QVector3D(x / w, y / w, z / w);
00676 }
00677 }
00678
00679 #endif
00680
00681 #ifndef QT_NO_VECTOR4D
00682
00683 inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix)
00684 {
00685 qreal x, y, z, w;
00686 x = vector.x() * matrix.m[0][0] +
00687 vector.y() * matrix.m[0][1] +
00688 vector.z() * matrix.m[0][2] +
00689 vector.w() * matrix.m[0][3];
00690 y = vector.x() * matrix.m[1][0] +
00691 vector.y() * matrix.m[1][1] +
00692 vector.z() * matrix.m[1][2] +
00693 vector.w() * matrix.m[1][3];
00694 z = vector.x() * matrix.m[2][0] +
00695 vector.y() * matrix.m[2][1] +
00696 vector.z() * matrix.m[2][2] +
00697 vector.w() * matrix.m[2][3];
00698 w = vector.x() * matrix.m[3][0] +
00699 vector.y() * matrix.m[3][1] +
00700 vector.z() * matrix.m[3][2] +
00701 vector.w() * matrix.m[3][3];
00702 return QVector4D(x, y, z, w);
00703 }
00704
00705 inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector)
00706 {
00707 qreal x, y, z, w;
00708 x = vector.x() * matrix.m[0][0] +
00709 vector.y() * matrix.m[1][0] +
00710 vector.z() * matrix.m[2][0] +
00711 vector.w() * matrix.m[3][0];
00712 y = vector.x() * matrix.m[0][1] +
00713 vector.y() * matrix.m[1][1] +
00714 vector.z() * matrix.m[2][1] +
00715 vector.w() * matrix.m[3][1];
00716 z = vector.x() * matrix.m[0][2] +
00717 vector.y() * matrix.m[1][2] +
00718 vector.z() * matrix.m[2][2] +
00719 vector.w() * matrix.m[3][2];
00720 w = vector.x() * matrix.m[0][3] +
00721 vector.y() * matrix.m[1][3] +
00722 vector.z() * matrix.m[2][3] +
00723 vector.w() * matrix.m[3][3];
00724 return QVector4D(x, y, z, w);
00725 }
00726
00727 #endif
00728
00729 inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix)
00730 {
00731 qreal xin, yin;
00732 qreal x, y, w;
00733 xin = point.x();
00734 yin = point.y();
00735 x = xin * matrix.m[0][0] +
00736 yin * matrix.m[0][1] +
00737 matrix.m[0][3];
00738 y = xin * matrix.m[1][0] +
00739 yin * matrix.m[1][1] +
00740 matrix.m[1][3];
00741 w = xin * matrix.m[3][0] +
00742 yin * matrix.m[3][1] +
00743 matrix.m[3][3];
00744 if (w == 1.0f)
00745 return QPoint(qRound(x), qRound(y));
00746 else
00747 return QPoint(qRound(x / w), qRound(y / w));
00748 }
00749
00750 inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix)
00751 {
00752 qreal xin, yin;
00753 qreal x, y, w;
00754 xin = point.x();
00755 yin = point.y();
00756 x = xin * matrix.m[0][0] +
00757 yin * matrix.m[0][1] +
00758 matrix.m[0][3];
00759 y = xin * matrix.m[1][0] +
00760 yin * matrix.m[1][1] +
00761 matrix.m[1][3];
00762 w = xin * matrix.m[3][0] +
00763 yin * matrix.m[3][1] +
00764 matrix.m[3][3];
00765 if (w == 1.0f) {
00766 return QPointF(qreal(x), qreal(y));
00767 } else {
00768 return QPointF(qreal(x / w), qreal(y / w));
00769 }
00770 }
00771
00772 inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point)
00773 {
00774 qreal xin, yin;
00775 qreal x, y, w;
00776 xin = point.x();
00777 yin = point.y();
00778 if (matrix.flagBits == QMatrix4x4::Identity) {
00779 return point;
00780 } else if (matrix.flagBits == QMatrix4x4::Translation) {
00781 return QPoint(qRound(xin + matrix.m[3][0]),
00782 qRound(yin + matrix.m[3][1]));
00783 } else if (matrix.flagBits ==
00784 (QMatrix4x4::Translation | QMatrix4x4::Scale)) {
00785 return QPoint(qRound(xin * matrix.m[0][0] + matrix.m[3][0]),
00786 qRound(yin * matrix.m[1][1] + matrix.m[3][1]));
00787 } else if (matrix.flagBits == QMatrix4x4::Scale) {
00788 return QPoint(qRound(xin * matrix.m[0][0]),
00789 qRound(yin * matrix.m[1][1]));
00790 } else {
00791 x = xin * matrix.m[0][0] +
00792 yin * matrix.m[1][0] +
00793 matrix.m[3][0];
00794 y = xin * matrix.m[0][1] +
00795 yin * matrix.m[1][1] +
00796 matrix.m[3][1];
00797 w = xin * matrix.m[0][3] +
00798 yin * matrix.m[1][3] +
00799 matrix.m[3][3];
00800 if (w == 1.0f)
00801 return QPoint(qRound(x), qRound(y));
00802 else
00803 return QPoint(qRound(x / w), qRound(y / w));
00804 }
00805 }
00806
00807 inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point)
00808 {
00809 qreal xin, yin;
00810 qreal x, y, w;
00811 xin = point.x();
00812 yin = point.y();
00813 if (matrix.flagBits == QMatrix4x4::Identity) {
00814 return point;
00815 } else if (matrix.flagBits == QMatrix4x4::Translation) {
00816 return QPointF(xin + matrix.m[3][0],
00817 yin + matrix.m[3][1]);
00818 } else if (matrix.flagBits ==
00819 (QMatrix4x4::Translation | QMatrix4x4::Scale)) {
00820 return QPointF(xin * matrix.m[0][0] + matrix.m[3][0],
00821 yin * matrix.m[1][1] + matrix.m[3][1]);
00822 } else if (matrix.flagBits == QMatrix4x4::Scale) {
00823 return QPointF(xin * matrix.m[0][0],
00824 yin * matrix.m[1][1]);
00825 } else {
00826 x = xin * matrix.m[0][0] +
00827 yin * matrix.m[1][0] +
00828 matrix.m[3][0];
00829 y = xin * matrix.m[0][1] +
00830 yin * matrix.m[1][1] +
00831 matrix.m[3][1];
00832 w = xin * matrix.m[0][3] +
00833 yin * matrix.m[1][3] +
00834 matrix.m[3][3];
00835 if (w == 1.0f) {
00836 return QPointF(qreal(x), qreal(y));
00837 } else {
00838 return QPointF(qreal(x / w), qreal(y / w));
00839 }
00840 }
00841 }
00842
00843 inline QMatrix4x4 operator-(const QMatrix4x4& matrix)
00844 {
00845 QMatrix4x4 m(1);
00846 m.m[0][0] = -matrix.m[0][0];
00847 m.m[0][1] = -matrix.m[0][1];
00848 m.m[0][2] = -matrix.m[0][2];
00849 m.m[0][3] = -matrix.m[0][3];
00850 m.m[1][0] = -matrix.m[1][0];
00851 m.m[1][1] = -matrix.m[1][1];
00852 m.m[1][2] = -matrix.m[1][2];
00853 m.m[1][3] = -matrix.m[1][3];
00854 m.m[2][0] = -matrix.m[2][0];
00855 m.m[2][1] = -matrix.m[2][1];
00856 m.m[2][2] = -matrix.m[2][2];
00857 m.m[2][3] = -matrix.m[2][3];
00858 m.m[3][0] = -matrix.m[3][0];
00859 m.m[3][1] = -matrix.m[3][1];
00860 m.m[3][2] = -matrix.m[3][2];
00861 m.m[3][3] = -matrix.m[3][3];
00862 return m;
00863 }
00864
00865 inline QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix)
00866 {
00867 QMatrix4x4 m(1);
00868 m.m[0][0] = matrix.m[0][0] * factor;
00869 m.m[0][1] = matrix.m[0][1] * factor;
00870 m.m[0][2] = matrix.m[0][2] * factor;
00871 m.m[0][3] = matrix.m[0][3] * factor;
00872 m.m[1][0] = matrix.m[1][0] * factor;
00873 m.m[1][1] = matrix.m[1][1] * factor;
00874 m.m[1][2] = matrix.m[1][2] * factor;
00875 m.m[1][3] = matrix.m[1][3] * factor;
00876 m.m[2][0] = matrix.m[2][0] * factor;
00877 m.m[2][1] = matrix.m[2][1] * factor;
00878 m.m[2][2] = matrix.m[2][2] * factor;
00879 m.m[2][3] = matrix.m[2][3] * factor;
00880 m.m[3][0] = matrix.m[3][0] * factor;
00881 m.m[3][1] = matrix.m[3][1] * factor;
00882 m.m[3][2] = matrix.m[3][2] * factor;
00883 m.m[3][3] = matrix.m[3][3] * factor;
00884 return m;
00885 }
00886
00887 inline QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor)
00888 {
00889 QMatrix4x4 m(1);
00890 m.m[0][0] = matrix.m[0][0] * factor;
00891 m.m[0][1] = matrix.m[0][1] * factor;
00892 m.m[0][2] = matrix.m[0][2] * factor;
00893 m.m[0][3] = matrix.m[0][3] * factor;
00894 m.m[1][0] = matrix.m[1][0] * factor;
00895 m.m[1][1] = matrix.m[1][1] * factor;
00896 m.m[1][2] = matrix.m[1][2] * factor;
00897 m.m[1][3] = matrix.m[1][3] * factor;
00898 m.m[2][0] = matrix.m[2][0] * factor;
00899 m.m[2][1] = matrix.m[2][1] * factor;
00900 m.m[2][2] = matrix.m[2][2] * factor;
00901 m.m[2][3] = matrix.m[2][3] * factor;
00902 m.m[3][0] = matrix.m[3][0] * factor;
00903 m.m[3][1] = matrix.m[3][1] * factor;
00904 m.m[3][2] = matrix.m[3][2] * factor;
00905 m.m[3][3] = matrix.m[3][3] * factor;
00906 return m;
00907 }
00908
00909 inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2)
00910 {
00911 return qFuzzyCompare(m1.m[0][0], m2.m[0][0]) &&
00912 qFuzzyCompare(m1.m[0][1], m2.m[0][1]) &&
00913 qFuzzyCompare(m1.m[0][2], m2.m[0][2]) &&
00914 qFuzzyCompare(m1.m[0][3], m2.m[0][3]) &&
00915 qFuzzyCompare(m1.m[1][0], m2.m[1][0]) &&
00916 qFuzzyCompare(m1.m[1][1], m2.m[1][1]) &&
00917 qFuzzyCompare(m1.m[1][2], m2.m[1][2]) &&
00918 qFuzzyCompare(m1.m[1][3], m2.m[1][3]) &&
00919 qFuzzyCompare(m1.m[2][0], m2.m[2][0]) &&
00920 qFuzzyCompare(m1.m[2][1], m2.m[2][1]) &&
00921 qFuzzyCompare(m1.m[2][2], m2.m[2][2]) &&
00922 qFuzzyCompare(m1.m[2][3], m2.m[2][3]) &&
00923 qFuzzyCompare(m1.m[3][0], m2.m[3][0]) &&
00924 qFuzzyCompare(m1.m[3][1], m2.m[3][1]) &&
00925 qFuzzyCompare(m1.m[3][2], m2.m[3][2]) &&
00926 qFuzzyCompare(m1.m[3][3], m2.m[3][3]);
00927 }
00928
00929 inline QPoint QMatrix4x4::map(const QPoint& point) const
00930 {
00931 return *this * point;
00932 }
00933
00934 inline QPointF QMatrix4x4::map(const QPointF& point) const
00935 {
00936 return *this * point;
00937 }
00938
00939 #ifndef QT_NO_VECTOR3D
00940
00941 inline QVector3D QMatrix4x4::map(const QVector3D& point) const
00942 {
00943 return *this * point;
00944 }
00945
00946 inline QVector3D QMatrix4x4::mapVector(const QVector3D& vector) const
00947 {
00948 if (flagBits == Identity || flagBits == Translation) {
00949 return vector;
00950 } else if (flagBits == Scale || flagBits == (Translation | Scale)) {
00951 return QVector3D(vector.x() * m[0][0],
00952 vector.y() * m[1][1],
00953 vector.z() * m[2][2]);
00954 } else {
00955 return QVector3D(vector.x() * m[0][0] +
00956 vector.y() * m[1][0] +
00957 vector.z() * m[2][0],
00958 vector.x() * m[0][1] +
00959 vector.y() * m[1][1] +
00960 vector.z() * m[2][1],
00961 vector.x() * m[0][2] +
00962 vector.y() * m[1][2] +
00963 vector.z() * m[2][2]);
00964 }
00965 }
00966
00967 #endif
00968
00969 #ifndef QT_NO_VECTOR4D
00970
00971 inline QVector4D QMatrix4x4::map(const QVector4D& point) const
00972 {
00973 return *this * point;
00974 }
00975
00976 #endif
00977
00978 inline qreal *QMatrix4x4::data()
00979 {
00980
00981
00982 flagBits = General;
00983 return m[0];
00984 }
00985
00986 #ifndef QT_NO_DEBUG_STREAM
00987 Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m);
00988 #endif
00989
00990 #ifndef QT_NO_DATASTREAM
00991 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QMatrix4x4 &);
00992 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix4x4 &);
00993 #endif
00994
00995 template <int N, int M>
00996 QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix)
00997 {
00998 return QMatrix4x4(matrix.constData(), N, M);
00999 }
01000
01001 template <int N, int M>
01002 QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)
01003 {
01004 QGenericMatrix<N, M, qreal> result;
01005 const qreal *m = matrix.constData();
01006 qreal *values = result.data();
01007 for (int col = 0; col < N; ++col) {
01008 for (int row = 0; row < M; ++row) {
01009 if (col < 4 && row < 4)
01010 values[col * M + row] = m[col * 4 + row];
01011 else if (col == row)
01012 values[col * M + row] = 1.0f;
01013 else
01014 values[col * M + row] = 0.0f;
01015 }
01016 }
01017 return result;
01018 }
01019
01020 #endif
01021
01022 QT_END_NAMESPACE
01023
01024 QT_END_HEADER
01025
01026 #endif