src/gui/math3d/qmatrix4x4.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef QMATRIX4X4_H
       
    43 #define QMATRIX4X4_H
       
    44 
       
    45 #include <QtGui/qvector3d.h>
       
    46 #include <QtGui/qvector4d.h>
       
    47 #include <QtGui/qquaternion.h>
       
    48 #include <QtGui/qgenericmatrix.h>
       
    49 #include <QtCore/qrect.h>
       
    50 
       
    51 QT_BEGIN_HEADER
       
    52 
       
    53 QT_BEGIN_NAMESPACE
       
    54 
       
    55 QT_MODULE(Gui)
       
    56 
       
    57 #ifndef QT_NO_MATRIX4X4
       
    58 
       
    59 class QMatrix;
       
    60 class QTransform;
       
    61 class QVariant;
       
    62 
       
    63 class Q_GUI_EXPORT QMatrix4x4
       
    64 {
       
    65 public:
       
    66     inline QMatrix4x4() { setIdentity(); }
       
    67     explicit QMatrix4x4(const qreal *values);
       
    68     inline QMatrix4x4(qreal m11, qreal m12, qreal m13, qreal m14,
       
    69                       qreal m21, qreal m22, qreal m23, qreal m24,
       
    70                       qreal m31, qreal m32, qreal m33, qreal m34,
       
    71                       qreal m41, qreal m42, qreal m43, qreal m44);
       
    72 #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
       
    73     template <int N, int M>
       
    74     explicit QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix);
       
    75 #endif
       
    76     QMatrix4x4(const qreal *values, int cols, int rows);
       
    77     QMatrix4x4(const QTransform& transform);
       
    78     QMatrix4x4(const QMatrix& matrix);
       
    79 
       
    80     inline const qreal& operator()(int row, int column) const;
       
    81     inline qreal& operator()(int row, int column);
       
    82 
       
    83     inline QVector4D column(int index) const;
       
    84     inline void setColumn(int index, const QVector4D& value);
       
    85 
       
    86     inline QVector4D row(int index) const;
       
    87     inline void setRow(int index, const QVector4D& value);
       
    88 
       
    89     inline bool isIdentity() const;
       
    90     inline void setIdentity();
       
    91 
       
    92     inline void fill(qreal value);
       
    93 
       
    94     qreal determinant() const;
       
    95     QMatrix4x4 inverted(bool *invertible = 0) const;
       
    96     QMatrix4x4 transposed() const;
       
    97     QMatrix3x3 normalMatrix() const;
       
    98 
       
    99     inline QMatrix4x4& operator+=(const QMatrix4x4& other);
       
   100     inline QMatrix4x4& operator-=(const QMatrix4x4& other);
       
   101     inline QMatrix4x4& operator*=(const QMatrix4x4& other);
       
   102     inline QMatrix4x4& operator*=(qreal factor);
       
   103     QMatrix4x4& operator/=(qreal divisor);
       
   104     inline bool operator==(const QMatrix4x4& other) const;
       
   105     inline bool operator!=(const QMatrix4x4& other) const;
       
   106 
       
   107     friend QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2);
       
   108     friend QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2);
       
   109     friend QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2);
       
   110 #ifndef QT_NO_VECTOR3D
       
   111     friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector);
       
   112     friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix);
       
   113 #endif
       
   114 #ifndef QT_NO_VECTOR4D
       
   115     friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix);
       
   116     friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector);
       
   117 #endif
       
   118     friend QPoint operator*(const QPoint& point, const QMatrix4x4& matrix);
       
   119     friend QPointF operator*(const QPointF& point, const QMatrix4x4& matrix);
       
   120     friend QMatrix4x4 operator-(const QMatrix4x4& matrix);
       
   121     friend QPoint operator*(const QMatrix4x4& matrix, const QPoint& point);
       
   122     friend QPointF operator*(const QMatrix4x4& matrix, const QPointF& point);
       
   123     friend QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix);
       
   124     friend QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor);
       
   125     friend Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor);
       
   126 
       
   127     friend inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2);
       
   128 
       
   129 #ifndef QT_NO_VECTOR3D
       
   130     QMatrix4x4& scale(const QVector3D& vector);
       
   131     QMatrix4x4& translate(const QVector3D& vector);
       
   132     QMatrix4x4& rotate(qreal angle, const QVector3D& vector);
       
   133 #endif
       
   134     QMatrix4x4& scale(qreal x, qreal y);
       
   135     QMatrix4x4& scale(qreal x, qreal y, qreal z);
       
   136     QMatrix4x4& scale(qreal factor);
       
   137     QMatrix4x4& translate(qreal x, qreal y);
       
   138     QMatrix4x4& translate(qreal x, qreal y, qreal z);
       
   139     QMatrix4x4& rotate(qreal angle, qreal x, qreal y, qreal z = 0.0f);
       
   140 #ifndef QT_NO_QUATERNION
       
   141     QMatrix4x4& rotate(const QQuaternion& quaternion);
       
   142 #endif
       
   143 
       
   144 #ifndef QT_NO_VECTOR3D
       
   145     void extractAxisRotation(qreal &angle, QVector3D &axis) const;
       
   146     QVector3D extractTranslation() const;
       
   147 #endif
       
   148 
       
   149     QMatrix4x4& ortho(const QRect& rect);
       
   150     QMatrix4x4& ortho(const QRectF& rect);
       
   151     QMatrix4x4& ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
       
   152     QMatrix4x4& frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
       
   153     QMatrix4x4& perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane);
       
   154 #ifndef QT_NO_VECTOR3D
       
   155     QMatrix4x4& lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
       
   156 #endif
       
   157     QMatrix4x4& flipCoordinates();
       
   158 
       
   159     void toValueArray(qreal *values) const;
       
   160 
       
   161     QMatrix toAffine() const;
       
   162     QTransform toTransform(qreal distanceToPlane = 1024.0f) const;
       
   163 
       
   164     QPoint map(const QPoint& point) const;
       
   165     QPointF map(const QPointF& point) const;
       
   166 #ifndef QT_NO_VECTOR3D
       
   167     QVector3D map(const QVector3D& point) const;
       
   168     QVector3D mapVector(const QVector3D& vector) const;
       
   169 #endif
       
   170 #ifndef QT_NO_VECTOR4D
       
   171     QVector4D map(const QVector4D& point) const;
       
   172 #endif
       
   173     QRect mapRect(const QRect& rect) const;
       
   174     QRectF mapRect(const QRectF& rect) const;
       
   175 
       
   176 #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
       
   177     template <int N, int M>
       
   178     QGenericMatrix<N, M, qreal> toGenericMatrix() const;
       
   179 #endif
       
   180 
       
   181     inline qreal *data();
       
   182     inline const qreal *data() const { return m[0]; }
       
   183     inline const qreal *constData() const { return m[0]; }
       
   184 
       
   185     void inferSpecialType();
       
   186 
       
   187     operator QVariant() const;
       
   188 
       
   189 #ifndef QT_NO_DEBUG_STREAM
       
   190     friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m);
       
   191 #endif
       
   192 
       
   193 private:
       
   194     qreal m[4][4];          // Column-major order to match OpenGL.
       
   195     int flagBits;           // Flag bits from the enum below.
       
   196 
       
   197     enum {
       
   198         Identity        = 0x0001,   // Identity matrix
       
   199         General         = 0x0002,   // General matrix, unknown contents
       
   200         Translation     = 0x0004,   // Contains a simple translation
       
   201         Scale           = 0x0008,   // Contains a simple scale
       
   202         Rotation        = 0x0010    // Contains a simple rotation
       
   203     };
       
   204 
       
   205     // Construct without initializing identity matrix.
       
   206     QMatrix4x4(int) { flagBits = General; }
       
   207 
       
   208     QMatrix4x4 orthonormalInverse() const;
       
   209 };
       
   210 
       
   211 inline QMatrix4x4::QMatrix4x4
       
   212         (qreal m11, qreal m12, qreal m13, qreal m14,
       
   213          qreal m21, qreal m22, qreal m23, qreal m24,
       
   214          qreal m31, qreal m32, qreal m33, qreal m34,
       
   215          qreal m41, qreal m42, qreal m43, qreal m44)
       
   216 {
       
   217     m[0][0] = m11; m[0][1] = m21; m[0][2] = m31; m[0][3] = m41;
       
   218     m[1][0] = m12; m[1][1] = m22; m[1][2] = m32; m[1][3] = m42;
       
   219     m[2][0] = m13; m[2][1] = m23; m[2][2] = m33; m[2][3] = m43;
       
   220     m[3][0] = m14; m[3][1] = m24; m[3][2] = m34; m[3][3] = m44;
       
   221     flagBits = General;
       
   222 }
       
   223 
       
   224 #if !defined(QT_NO_MEMBER_TEMPLATES)
       
   225 
       
   226 template <int N, int M>
       
   227 Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4
       
   228     (const QGenericMatrix<N, M, qreal>& matrix)
       
   229 {
       
   230     const qreal *values = matrix.constData();
       
   231     for (int matrixCol = 0; matrixCol < 4; ++matrixCol) {
       
   232         for (int matrixRow = 0; matrixRow < 4; ++matrixRow) {
       
   233             if (matrixCol < N && matrixRow < M)
       
   234                 m[matrixCol][matrixRow] = values[matrixCol * M + matrixRow];
       
   235             else if (matrixCol == matrixRow)
       
   236                 m[matrixCol][matrixRow] = 1.0f;
       
   237             else
       
   238                 m[matrixCol][matrixRow] = 0.0f;
       
   239         }
       
   240     }
       
   241     flagBits = General;
       
   242 }
       
   243 
       
   244 template <int N, int M>
       
   245 QGenericMatrix<N, M, qreal> QMatrix4x4::toGenericMatrix() const
       
   246 {
       
   247     QGenericMatrix<N, M, qreal> result;
       
   248     qreal *values = result.data();
       
   249     for (int matrixCol = 0; matrixCol < N; ++matrixCol) {
       
   250         for (int matrixRow = 0; matrixRow < M; ++matrixRow) {
       
   251             if (matrixCol < 4 && matrixRow < 4)
       
   252                 values[matrixCol * M + matrixRow] = m[matrixCol][matrixRow];
       
   253             else if (matrixCol == matrixRow)
       
   254                 values[matrixCol * M + matrixRow] = 1.0f;
       
   255             else
       
   256                 values[matrixCol * M + matrixRow] = 0.0f;
       
   257         }
       
   258     }
       
   259     return result;
       
   260 }
       
   261 
       
   262 #endif
       
   263 
       
   264 inline const qreal& QMatrix4x4::operator()(int aRow, int aColumn) const
       
   265 {
       
   266     Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
       
   267     return m[aColumn][aRow];
       
   268 }
       
   269 
       
   270 inline qreal& QMatrix4x4::operator()(int aRow, int aColumn)
       
   271 {
       
   272     Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
       
   273     flagBits = General;
       
   274     return m[aColumn][aRow];
       
   275 }
       
   276 
       
   277 inline QVector4D QMatrix4x4::column(int index) const
       
   278 {
       
   279     Q_ASSERT(index >= 0 && index < 4);
       
   280     return QVector4D(m[index][0], m[index][1], m[index][2], m[index][3]);
       
   281 }
       
   282 
       
   283 inline void QMatrix4x4::setColumn(int index, const QVector4D& value)
       
   284 {
       
   285     Q_ASSERT(index >= 0 && index < 4);
       
   286     m[index][0] = value.x();
       
   287     m[index][1] = value.y();
       
   288     m[index][2] = value.z();
       
   289     m[index][3] = value.w();
       
   290     flagBits = General;
       
   291 }
       
   292 
       
   293 inline QVector4D QMatrix4x4::row(int index) const
       
   294 {
       
   295     Q_ASSERT(index >= 0 && index < 4);
       
   296     return QVector4D(m[0][index], m[1][index], m[2][index], m[3][index]);
       
   297 }
       
   298 
       
   299 inline void QMatrix4x4::setRow(int index, const QVector4D& value)
       
   300 {
       
   301     Q_ASSERT(index >= 0 && index < 4);
       
   302     m[0][index] = value.x();
       
   303     m[1][index] = value.y();
       
   304     m[2][index] = value.z();
       
   305     m[3][index] = value.w();
       
   306     flagBits = General;
       
   307 }
       
   308 
       
   309 Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor);
       
   310 
       
   311 inline bool QMatrix4x4::isIdentity() const
       
   312 {
       
   313     if (flagBits == Identity)
       
   314         return true;
       
   315     if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f)
       
   316         return false;
       
   317     if (m[0][3] != 0.0f || m[1][0] != 0.0f || m[1][1] != 1.0f)
       
   318         return false;
       
   319     if (m[1][2] != 0.0f || m[1][3] != 0.0f || m[2][0] != 0.0f)
       
   320         return false;
       
   321     if (m[2][1] != 0.0f || m[2][2] != 1.0f || m[2][3] != 0.0f)
       
   322         return false;
       
   323     if (m[3][0] != 0.0f || m[3][1] != 0.0f || m[3][2] != 0.0f)
       
   324         return false;
       
   325     return (m[3][3] == 1.0f);
       
   326 }
       
   327 
       
   328 inline void QMatrix4x4::setIdentity()
       
   329 {
       
   330     m[0][0] = 1.0f;
       
   331     m[0][1] = 0.0f;
       
   332     m[0][2] = 0.0f;
       
   333     m[0][3] = 0.0f;
       
   334     m[1][0] = 0.0f;
       
   335     m[1][1] = 1.0f;
       
   336     m[1][2] = 0.0f;
       
   337     m[1][3] = 0.0f;
       
   338     m[2][0] = 0.0f;
       
   339     m[2][1] = 0.0f;
       
   340     m[2][2] = 1.0f;
       
   341     m[2][3] = 0.0f;
       
   342     m[3][0] = 0.0f;
       
   343     m[3][1] = 0.0f;
       
   344     m[3][2] = 0.0f;
       
   345     m[3][3] = 1.0f;
       
   346     flagBits = Identity;
       
   347 }
       
   348 
       
   349 inline void QMatrix4x4::fill(qreal value)
       
   350 {
       
   351     m[0][0] = value;
       
   352     m[0][1] = value;
       
   353     m[0][2] = value;
       
   354     m[0][3] = value;
       
   355     m[1][0] = value;
       
   356     m[1][1] = value;
       
   357     m[1][2] = value;
       
   358     m[1][3] = value;
       
   359     m[2][0] = value;
       
   360     m[2][1] = value;
       
   361     m[2][2] = value;
       
   362     m[2][3] = value;
       
   363     m[3][0] = value;
       
   364     m[3][1] = value;
       
   365     m[3][2] = value;
       
   366     m[3][3] = value;
       
   367     flagBits = General;
       
   368 }
       
   369 
       
   370 inline QMatrix4x4& QMatrix4x4::operator+=(const QMatrix4x4& other)
       
   371 {
       
   372     m[0][0] += other.m[0][0];
       
   373     m[0][1] += other.m[0][1];
       
   374     m[0][2] += other.m[0][2];
       
   375     m[0][3] += other.m[0][3];
       
   376     m[1][0] += other.m[1][0];
       
   377     m[1][1] += other.m[1][1];
       
   378     m[1][2] += other.m[1][2];
       
   379     m[1][3] += other.m[1][3];
       
   380     m[2][0] += other.m[2][0];
       
   381     m[2][1] += other.m[2][1];
       
   382     m[2][2] += other.m[2][2];
       
   383     m[2][3] += other.m[2][3];
       
   384     m[3][0] += other.m[3][0];
       
   385     m[3][1] += other.m[3][1];
       
   386     m[3][2] += other.m[3][2];
       
   387     m[3][3] += other.m[3][3];
       
   388     flagBits = General;
       
   389     return *this;
       
   390 }
       
   391 
       
   392 inline QMatrix4x4& QMatrix4x4::operator-=(const QMatrix4x4& other)
       
   393 {
       
   394     m[0][0] -= other.m[0][0];
       
   395     m[0][1] -= other.m[0][1];
       
   396     m[0][2] -= other.m[0][2];
       
   397     m[0][3] -= other.m[0][3];
       
   398     m[1][0] -= other.m[1][0];
       
   399     m[1][1] -= other.m[1][1];
       
   400     m[1][2] -= other.m[1][2];
       
   401     m[1][3] -= other.m[1][3];
       
   402     m[2][0] -= other.m[2][0];
       
   403     m[2][1] -= other.m[2][1];
       
   404     m[2][2] -= other.m[2][2];
       
   405     m[2][3] -= other.m[2][3];
       
   406     m[3][0] -= other.m[3][0];
       
   407     m[3][1] -= other.m[3][1];
       
   408     m[3][2] -= other.m[3][2];
       
   409     m[3][3] -= other.m[3][3];
       
   410     flagBits = General;
       
   411     return *this;
       
   412 }
       
   413 
       
   414 inline QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& other)
       
   415 {
       
   416     if (flagBits == Identity) {
       
   417         *this = other;
       
   418         return *this;
       
   419     } else if (other.flagBits == Identity) {
       
   420         return *this;
       
   421     } else {
       
   422         *this = *this * other;
       
   423         return *this;
       
   424     }
       
   425 }
       
   426 
       
   427 inline QMatrix4x4& QMatrix4x4::operator*=(qreal factor)
       
   428 {
       
   429     m[0][0] *= factor;
       
   430     m[0][1] *= factor;
       
   431     m[0][2] *= factor;
       
   432     m[0][3] *= factor;
       
   433     m[1][0] *= factor;
       
   434     m[1][1] *= factor;
       
   435     m[1][2] *= factor;
       
   436     m[1][3] *= factor;
       
   437     m[2][0] *= factor;
       
   438     m[2][1] *= factor;
       
   439     m[2][2] *= factor;
       
   440     m[2][3] *= factor;
       
   441     m[3][0] *= factor;
       
   442     m[3][1] *= factor;
       
   443     m[3][2] *= factor;
       
   444     m[3][3] *= factor;
       
   445     flagBits = General;
       
   446     return *this;
       
   447 }
       
   448 
       
   449 inline bool QMatrix4x4::operator==(const QMatrix4x4& other) const
       
   450 {
       
   451     return m[0][0] == other.m[0][0] &&
       
   452            m[0][1] == other.m[0][1] &&
       
   453            m[0][2] == other.m[0][2] &&
       
   454            m[0][3] == other.m[0][3] &&
       
   455            m[1][0] == other.m[1][0] &&
       
   456            m[1][1] == other.m[1][1] &&
       
   457            m[1][2] == other.m[1][2] &&
       
   458            m[1][3] == other.m[1][3] &&
       
   459            m[2][0] == other.m[2][0] &&
       
   460            m[2][1] == other.m[2][1] &&
       
   461            m[2][2] == other.m[2][2] &&
       
   462            m[2][3] == other.m[2][3] &&
       
   463            m[3][0] == other.m[3][0] &&
       
   464            m[3][1] == other.m[3][1] &&
       
   465            m[3][2] == other.m[3][2] &&
       
   466            m[3][3] == other.m[3][3];
       
   467 }
       
   468 
       
   469 inline bool QMatrix4x4::operator!=(const QMatrix4x4& other) const
       
   470 {
       
   471     return m[0][0] != other.m[0][0] ||
       
   472            m[0][1] != other.m[0][1] ||
       
   473            m[0][2] != other.m[0][2] ||
       
   474            m[0][3] != other.m[0][3] ||
       
   475            m[1][0] != other.m[1][0] ||
       
   476            m[1][1] != other.m[1][1] ||
       
   477            m[1][2] != other.m[1][2] ||
       
   478            m[1][3] != other.m[1][3] ||
       
   479            m[2][0] != other.m[2][0] ||
       
   480            m[2][1] != other.m[2][1] ||
       
   481            m[2][2] != other.m[2][2] ||
       
   482            m[2][3] != other.m[2][3] ||
       
   483            m[3][0] != other.m[3][0] ||
       
   484            m[3][1] != other.m[3][1] ||
       
   485            m[3][2] != other.m[3][2] ||
       
   486            m[3][3] != other.m[3][3];
       
   487 }
       
   488 
       
   489 inline QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2)
       
   490 {
       
   491     QMatrix4x4 m(1);
       
   492     m.m[0][0] = m1.m[0][0] + m2.m[0][0];
       
   493     m.m[0][1] = m1.m[0][1] + m2.m[0][1];
       
   494     m.m[0][2] = m1.m[0][2] + m2.m[0][2];
       
   495     m.m[0][3] = m1.m[0][3] + m2.m[0][3];
       
   496     m.m[1][0] = m1.m[1][0] + m2.m[1][0];
       
   497     m.m[1][1] = m1.m[1][1] + m2.m[1][1];
       
   498     m.m[1][2] = m1.m[1][2] + m2.m[1][2];
       
   499     m.m[1][3] = m1.m[1][3] + m2.m[1][3];
       
   500     m.m[2][0] = m1.m[2][0] + m2.m[2][0];
       
   501     m.m[2][1] = m1.m[2][1] + m2.m[2][1];
       
   502     m.m[2][2] = m1.m[2][2] + m2.m[2][2];
       
   503     m.m[2][3] = m1.m[2][3] + m2.m[2][3];
       
   504     m.m[3][0] = m1.m[3][0] + m2.m[3][0];
       
   505     m.m[3][1] = m1.m[3][1] + m2.m[3][1];
       
   506     m.m[3][2] = m1.m[3][2] + m2.m[3][2];
       
   507     m.m[3][3] = m1.m[3][3] + m2.m[3][3];
       
   508     return m;
       
   509 }
       
   510 
       
   511 inline QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2)
       
   512 {
       
   513     QMatrix4x4 m(1);
       
   514     m.m[0][0] = m1.m[0][0] - m2.m[0][0];
       
   515     m.m[0][1] = m1.m[0][1] - m2.m[0][1];
       
   516     m.m[0][2] = m1.m[0][2] - m2.m[0][2];
       
   517     m.m[0][3] = m1.m[0][3] - m2.m[0][3];
       
   518     m.m[1][0] = m1.m[1][0] - m2.m[1][0];
       
   519     m.m[1][1] = m1.m[1][1] - m2.m[1][1];
       
   520     m.m[1][2] = m1.m[1][2] - m2.m[1][2];
       
   521     m.m[1][3] = m1.m[1][3] - m2.m[1][3];
       
   522     m.m[2][0] = m1.m[2][0] - m2.m[2][0];
       
   523     m.m[2][1] = m1.m[2][1] - m2.m[2][1];
       
   524     m.m[2][2] = m1.m[2][2] - m2.m[2][2];
       
   525     m.m[2][3] = m1.m[2][3] - m2.m[2][3];
       
   526     m.m[3][0] = m1.m[3][0] - m2.m[3][0];
       
   527     m.m[3][1] = m1.m[3][1] - m2.m[3][1];
       
   528     m.m[3][2] = m1.m[3][2] - m2.m[3][2];
       
   529     m.m[3][3] = m1.m[3][3] - m2.m[3][3];
       
   530     return m;
       
   531 }
       
   532 
       
   533 inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2)
       
   534 {
       
   535     if (m1.flagBits == QMatrix4x4::Identity)
       
   536         return m2;
       
   537     else if (m2.flagBits == QMatrix4x4::Identity)
       
   538         return m1;
       
   539 
       
   540     QMatrix4x4 m(1);
       
   541     m.m[0][0] = m1.m[0][0] * m2.m[0][0] +
       
   542                 m1.m[1][0] * m2.m[0][1] +
       
   543                 m1.m[2][0] * m2.m[0][2] +
       
   544                 m1.m[3][0] * m2.m[0][3];
       
   545     m.m[0][1] = m1.m[0][1] * m2.m[0][0] +
       
   546                 m1.m[1][1] * m2.m[0][1] +
       
   547                 m1.m[2][1] * m2.m[0][2] +
       
   548                 m1.m[3][1] * m2.m[0][3];
       
   549     m.m[0][2] = m1.m[0][2] * m2.m[0][0] +
       
   550                 m1.m[1][2] * m2.m[0][1] +
       
   551                 m1.m[2][2] * m2.m[0][2] +
       
   552                 m1.m[3][2] * m2.m[0][3];
       
   553     m.m[0][3] = m1.m[0][3] * m2.m[0][0] +
       
   554                 m1.m[1][3] * m2.m[0][1] +
       
   555                 m1.m[2][3] * m2.m[0][2] +
       
   556                 m1.m[3][3] * m2.m[0][3];
       
   557     m.m[1][0] = m1.m[0][0] * m2.m[1][0] +
       
   558                 m1.m[1][0] * m2.m[1][1] +
       
   559                 m1.m[2][0] * m2.m[1][2] +
       
   560                 m1.m[3][0] * m2.m[1][3];
       
   561     m.m[1][1] = m1.m[0][1] * m2.m[1][0] +
       
   562                 m1.m[1][1] * m2.m[1][1] +
       
   563                 m1.m[2][1] * m2.m[1][2] +
       
   564                 m1.m[3][1] * m2.m[1][3];
       
   565     m.m[1][2] = m1.m[0][2] * m2.m[1][0] +
       
   566                 m1.m[1][2] * m2.m[1][1] +
       
   567                 m1.m[2][2] * m2.m[1][2] +
       
   568                 m1.m[3][2] * m2.m[1][3];
       
   569     m.m[1][3] = m1.m[0][3] * m2.m[1][0] +
       
   570                 m1.m[1][3] * m2.m[1][1] +
       
   571                 m1.m[2][3] * m2.m[1][2] +
       
   572                 m1.m[3][3] * m2.m[1][3];
       
   573     m.m[2][0] = m1.m[0][0] * m2.m[2][0] +
       
   574                 m1.m[1][0] * m2.m[2][1] +
       
   575                 m1.m[2][0] * m2.m[2][2] +
       
   576                 m1.m[3][0] * m2.m[2][3];
       
   577     m.m[2][1] = m1.m[0][1] * m2.m[2][0] +
       
   578                 m1.m[1][1] * m2.m[2][1] +
       
   579                 m1.m[2][1] * m2.m[2][2] +
       
   580                 m1.m[3][1] * m2.m[2][3];
       
   581     m.m[2][2] = m1.m[0][2] * m2.m[2][0] +
       
   582                 m1.m[1][2] * m2.m[2][1] +
       
   583                 m1.m[2][2] * m2.m[2][2] +
       
   584                 m1.m[3][2] * m2.m[2][3];
       
   585     m.m[2][3] = m1.m[0][3] * m2.m[2][0] +
       
   586                 m1.m[1][3] * m2.m[2][1] +
       
   587                 m1.m[2][3] * m2.m[2][2] +
       
   588                 m1.m[3][3] * m2.m[2][3];
       
   589     m.m[3][0] = m1.m[0][0] * m2.m[3][0] +
       
   590                 m1.m[1][0] * m2.m[3][1] +
       
   591                 m1.m[2][0] * m2.m[3][2] +
       
   592                 m1.m[3][0] * m2.m[3][3];
       
   593     m.m[3][1] = m1.m[0][1] * m2.m[3][0] +
       
   594                 m1.m[1][1] * m2.m[3][1] +
       
   595                 m1.m[2][1] * m2.m[3][2] +
       
   596                 m1.m[3][1] * m2.m[3][3];
       
   597     m.m[3][2] = m1.m[0][2] * m2.m[3][0] +
       
   598                 m1.m[1][2] * m2.m[3][1] +
       
   599                 m1.m[2][2] * m2.m[3][2] +
       
   600                 m1.m[3][2] * m2.m[3][3];
       
   601     m.m[3][3] = m1.m[0][3] * m2.m[3][0] +
       
   602                 m1.m[1][3] * m2.m[3][1] +
       
   603                 m1.m[2][3] * m2.m[3][2] +
       
   604                 m1.m[3][3] * m2.m[3][3];
       
   605     return m;
       
   606 }
       
   607 
       
   608 #ifndef QT_NO_VECTOR3D
       
   609 
       
   610 inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix)
       
   611 {
       
   612     qreal x, y, z, w;
       
   613     x = vector.x() * matrix.m[0][0] +
       
   614         vector.y() * matrix.m[0][1] +
       
   615         vector.z() * matrix.m[0][2] +
       
   616         matrix.m[0][3];
       
   617     y = vector.x() * matrix.m[1][0] +
       
   618         vector.y() * matrix.m[1][1] +
       
   619         vector.z() * matrix.m[1][2] +
       
   620         matrix.m[1][3];
       
   621     z = vector.x() * matrix.m[2][0] +
       
   622         vector.y() * matrix.m[2][1] +
       
   623         vector.z() * matrix.m[2][2] +
       
   624         matrix.m[2][3];
       
   625     w = vector.x() * matrix.m[3][0] +
       
   626         vector.y() * matrix.m[3][1] +
       
   627         vector.z() * matrix.m[3][2] +
       
   628         matrix.m[3][3];
       
   629     if (w == 1.0f)
       
   630         return QVector3D(x, y, z);
       
   631     else
       
   632         return QVector3D(x / w, y / w, z / w);
       
   633 }
       
   634 
       
   635 inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector)
       
   636 {
       
   637     qreal x, y, z, w;
       
   638     if (matrix.flagBits == QMatrix4x4::Identity) {
       
   639         return vector;
       
   640     } else if (matrix.flagBits == QMatrix4x4::Translation) {
       
   641         return QVector3D(vector.x() + matrix.m[3][0],
       
   642                          vector.y() + matrix.m[3][1],
       
   643                          vector.z() + matrix.m[3][2]);
       
   644     } else if (matrix.flagBits ==
       
   645                     (QMatrix4x4::Translation | QMatrix4x4::Scale)) {
       
   646         return QVector3D(vector.x() * matrix.m[0][0] + matrix.m[3][0],
       
   647                          vector.y() * matrix.m[1][1] + matrix.m[3][1],
       
   648                          vector.z() * matrix.m[2][2] + matrix.m[3][2]);
       
   649     } else if (matrix.flagBits == QMatrix4x4::Scale) {
       
   650         return QVector3D(vector.x() * matrix.m[0][0],
       
   651                          vector.y() * matrix.m[1][1],
       
   652                          vector.z() * matrix.m[2][2]);
       
   653     } else {
       
   654         x = vector.x() * matrix.m[0][0] +
       
   655             vector.y() * matrix.m[1][0] +
       
   656             vector.z() * matrix.m[2][0] +
       
   657             matrix.m[3][0];
       
   658         y = vector.x() * matrix.m[0][1] +
       
   659             vector.y() * matrix.m[1][1] +
       
   660             vector.z() * matrix.m[2][1] +
       
   661             matrix.m[3][1];
       
   662         z = vector.x() * matrix.m[0][2] +
       
   663             vector.y() * matrix.m[1][2] +
       
   664             vector.z() * matrix.m[2][2] +
       
   665             matrix.m[3][2];
       
   666         w = vector.x() * matrix.m[0][3] +
       
   667             vector.y() * matrix.m[1][3] +
       
   668             vector.z() * matrix.m[2][3] +
       
   669             matrix.m[3][3];
       
   670         if (w == 1.0f)
       
   671             return QVector3D(x, y, z);
       
   672         else
       
   673             return QVector3D(x / w, y / w, z / w);
       
   674     }
       
   675 }
       
   676 
       
   677 #endif
       
   678 
       
   679 #ifndef QT_NO_VECTOR4D
       
   680 
       
   681 inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix)
       
   682 {
       
   683     qreal x, y, z, w;
       
   684     x = vector.x() * matrix.m[0][0] +
       
   685         vector.y() * matrix.m[0][1] +
       
   686         vector.z() * matrix.m[0][2] +
       
   687         vector.w() * matrix.m[0][3];
       
   688     y = vector.x() * matrix.m[1][0] +
       
   689         vector.y() * matrix.m[1][1] +
       
   690         vector.z() * matrix.m[1][2] +
       
   691         vector.w() * matrix.m[1][3];
       
   692     z = vector.x() * matrix.m[2][0] +
       
   693         vector.y() * matrix.m[2][1] +
       
   694         vector.z() * matrix.m[2][2] +
       
   695         vector.w() * matrix.m[2][3];
       
   696     w = vector.x() * matrix.m[3][0] +
       
   697         vector.y() * matrix.m[3][1] +
       
   698         vector.z() * matrix.m[3][2] +
       
   699         vector.w() * matrix.m[3][3];
       
   700     return QVector4D(x, y, z, w);
       
   701 }
       
   702 
       
   703 inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector)
       
   704 {
       
   705     qreal x, y, z, w;
       
   706     x = vector.x() * matrix.m[0][0] +
       
   707         vector.y() * matrix.m[1][0] +
       
   708         vector.z() * matrix.m[2][0] +
       
   709         vector.w() * matrix.m[3][0];
       
   710     y = vector.x() * matrix.m[0][1] +
       
   711         vector.y() * matrix.m[1][1] +
       
   712         vector.z() * matrix.m[2][1] +
       
   713         vector.w() * matrix.m[3][1];
       
   714     z = vector.x() * matrix.m[0][2] +
       
   715         vector.y() * matrix.m[1][2] +
       
   716         vector.z() * matrix.m[2][2] +
       
   717         vector.w() * matrix.m[3][2];
       
   718     w = vector.x() * matrix.m[0][3] +
       
   719         vector.y() * matrix.m[1][3] +
       
   720         vector.z() * matrix.m[2][3] +
       
   721         vector.w() * matrix.m[3][3];
       
   722     return QVector4D(x, y, z, w);
       
   723 }
       
   724 
       
   725 #endif
       
   726 
       
   727 inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix)
       
   728 {
       
   729     qreal xin, yin;
       
   730     qreal x, y, w;
       
   731     xin = point.x();
       
   732     yin = point.y();
       
   733     x = xin * matrix.m[0][0] +
       
   734         yin * matrix.m[0][1] +
       
   735         matrix.m[0][3];
       
   736     y = xin * matrix.m[1][0] +
       
   737         yin * matrix.m[1][1] +
       
   738         matrix.m[1][3];
       
   739     w = xin * matrix.m[3][0] +
       
   740         yin * matrix.m[3][1] +
       
   741         matrix.m[3][3];
       
   742     if (w == 1.0f)
       
   743         return QPoint(qRound(x), qRound(y));
       
   744     else
       
   745         return QPoint(qRound(x / w), qRound(y / w));
       
   746 }
       
   747 
       
   748 inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix)
       
   749 {
       
   750     qreal xin, yin;
       
   751     qreal x, y, w;
       
   752     xin = point.x();
       
   753     yin = point.y();
       
   754     x = xin * matrix.m[0][0] +
       
   755         yin * matrix.m[0][1] +
       
   756         matrix.m[0][3];
       
   757     y = xin * matrix.m[1][0] +
       
   758         yin * matrix.m[1][1] +
       
   759         matrix.m[1][3];
       
   760     w = xin * matrix.m[3][0] +
       
   761         yin * matrix.m[3][1] +
       
   762         matrix.m[3][3];
       
   763     if (w == 1.0f) {
       
   764         return QPointF(qreal(x), qreal(y));
       
   765     } else {
       
   766         return QPointF(qreal(x / w), qreal(y / w));
       
   767     }
       
   768 }
       
   769 
       
   770 inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point)
       
   771 {
       
   772     qreal xin, yin;
       
   773     qreal x, y, w;
       
   774     xin = point.x();
       
   775     yin = point.y();
       
   776     if (matrix.flagBits == QMatrix4x4::Identity) {
       
   777         return point;
       
   778     } else if (matrix.flagBits == QMatrix4x4::Translation) {
       
   779         return QPoint(qRound(xin + matrix.m[3][0]),
       
   780                       qRound(yin + matrix.m[3][1]));
       
   781     } else if (matrix.flagBits ==
       
   782                     (QMatrix4x4::Translation | QMatrix4x4::Scale)) {
       
   783         return QPoint(qRound(xin * matrix.m[0][0] + matrix.m[3][0]),
       
   784                       qRound(yin * matrix.m[1][1] + matrix.m[3][1]));
       
   785     } else if (matrix.flagBits == QMatrix4x4::Scale) {
       
   786         return QPoint(qRound(xin * matrix.m[0][0]),
       
   787                       qRound(yin * matrix.m[1][1]));
       
   788     } else {
       
   789         x = xin * matrix.m[0][0] +
       
   790             yin * matrix.m[1][0] +
       
   791             matrix.m[3][0];
       
   792         y = xin * matrix.m[0][1] +
       
   793             yin * matrix.m[1][1] +
       
   794             matrix.m[3][1];
       
   795         w = xin * matrix.m[0][3] +
       
   796             yin * matrix.m[1][3] +
       
   797             matrix.m[3][3];
       
   798         if (w == 1.0f)
       
   799             return QPoint(qRound(x), qRound(y));
       
   800         else
       
   801             return QPoint(qRound(x / w), qRound(y / w));
       
   802     }
       
   803 }
       
   804 
       
   805 inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point)
       
   806 {
       
   807     qreal xin, yin;
       
   808     qreal x, y, w;
       
   809     xin = point.x();
       
   810     yin = point.y();
       
   811     if (matrix.flagBits == QMatrix4x4::Identity) {
       
   812         return point;
       
   813     } else if (matrix.flagBits == QMatrix4x4::Translation) {
       
   814         return QPointF(xin + matrix.m[3][0],
       
   815                        yin + matrix.m[3][1]);
       
   816     } else if (matrix.flagBits ==
       
   817                     (QMatrix4x4::Translation | QMatrix4x4::Scale)) {
       
   818         return QPointF(xin * matrix.m[0][0] + matrix.m[3][0],
       
   819                        yin * matrix.m[1][1] + matrix.m[3][1]);
       
   820     } else if (matrix.flagBits == QMatrix4x4::Scale) {
       
   821         return QPointF(xin * matrix.m[0][0],
       
   822                        yin * matrix.m[1][1]);
       
   823     } else {
       
   824         x = xin * matrix.m[0][0] +
       
   825             yin * matrix.m[1][0] +
       
   826             matrix.m[3][0];
       
   827         y = xin * matrix.m[0][1] +
       
   828             yin * matrix.m[1][1] +
       
   829             matrix.m[3][1];
       
   830         w = xin * matrix.m[0][3] +
       
   831             yin * matrix.m[1][3] +
       
   832             matrix.m[3][3];
       
   833         if (w == 1.0f) {
       
   834             return QPointF(qreal(x), qreal(y));
       
   835         } else {
       
   836             return QPointF(qreal(x / w), qreal(y / w));
       
   837         }
       
   838     }
       
   839 }
       
   840 
       
   841 inline QMatrix4x4 operator-(const QMatrix4x4& matrix)
       
   842 {
       
   843     QMatrix4x4 m(1);
       
   844     m.m[0][0] = -matrix.m[0][0];
       
   845     m.m[0][1] = -matrix.m[0][1];
       
   846     m.m[0][2] = -matrix.m[0][2];
       
   847     m.m[0][3] = -matrix.m[0][3];
       
   848     m.m[1][0] = -matrix.m[1][0];
       
   849     m.m[1][1] = -matrix.m[1][1];
       
   850     m.m[1][2] = -matrix.m[1][2];
       
   851     m.m[1][3] = -matrix.m[1][3];
       
   852     m.m[2][0] = -matrix.m[2][0];
       
   853     m.m[2][1] = -matrix.m[2][1];
       
   854     m.m[2][2] = -matrix.m[2][2];
       
   855     m.m[2][3] = -matrix.m[2][3];
       
   856     m.m[3][0] = -matrix.m[3][0];
       
   857     m.m[3][1] = -matrix.m[3][1];
       
   858     m.m[3][2] = -matrix.m[3][2];
       
   859     m.m[3][3] = -matrix.m[3][3];
       
   860     return m;
       
   861 }
       
   862 
       
   863 inline QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix)
       
   864 {
       
   865     QMatrix4x4 m(1);
       
   866     m.m[0][0] = matrix.m[0][0] * factor;
       
   867     m.m[0][1] = matrix.m[0][1] * factor;
       
   868     m.m[0][2] = matrix.m[0][2] * factor;
       
   869     m.m[0][3] = matrix.m[0][3] * factor;
       
   870     m.m[1][0] = matrix.m[1][0] * factor;
       
   871     m.m[1][1] = matrix.m[1][1] * factor;
       
   872     m.m[1][2] = matrix.m[1][2] * factor;
       
   873     m.m[1][3] = matrix.m[1][3] * factor;
       
   874     m.m[2][0] = matrix.m[2][0] * factor;
       
   875     m.m[2][1] = matrix.m[2][1] * factor;
       
   876     m.m[2][2] = matrix.m[2][2] * factor;
       
   877     m.m[2][3] = matrix.m[2][3] * factor;
       
   878     m.m[3][0] = matrix.m[3][0] * factor;
       
   879     m.m[3][1] = matrix.m[3][1] * factor;
       
   880     m.m[3][2] = matrix.m[3][2] * factor;
       
   881     m.m[3][3] = matrix.m[3][3] * factor;
       
   882     return m;
       
   883 }
       
   884 
       
   885 inline QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor)
       
   886 {
       
   887     QMatrix4x4 m(1);
       
   888     m.m[0][0] = matrix.m[0][0] * factor;
       
   889     m.m[0][1] = matrix.m[0][1] * factor;
       
   890     m.m[0][2] = matrix.m[0][2] * factor;
       
   891     m.m[0][3] = matrix.m[0][3] * factor;
       
   892     m.m[1][0] = matrix.m[1][0] * factor;
       
   893     m.m[1][1] = matrix.m[1][1] * factor;
       
   894     m.m[1][2] = matrix.m[1][2] * factor;
       
   895     m.m[1][3] = matrix.m[1][3] * factor;
       
   896     m.m[2][0] = matrix.m[2][0] * factor;
       
   897     m.m[2][1] = matrix.m[2][1] * factor;
       
   898     m.m[2][2] = matrix.m[2][2] * factor;
       
   899     m.m[2][3] = matrix.m[2][3] * factor;
       
   900     m.m[3][0] = matrix.m[3][0] * factor;
       
   901     m.m[3][1] = matrix.m[3][1] * factor;
       
   902     m.m[3][2] = matrix.m[3][2] * factor;
       
   903     m.m[3][3] = matrix.m[3][3] * factor;
       
   904     return m;
       
   905 }
       
   906 
       
   907 inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2)
       
   908 {
       
   909     return qFuzzyCompare(m1.m[0][0], m2.m[0][0]) &&
       
   910            qFuzzyCompare(m1.m[0][1], m2.m[0][1]) &&
       
   911            qFuzzyCompare(m1.m[0][2], m2.m[0][2]) &&
       
   912            qFuzzyCompare(m1.m[0][3], m2.m[0][3]) &&
       
   913            qFuzzyCompare(m1.m[1][0], m2.m[1][0]) &&
       
   914            qFuzzyCompare(m1.m[1][1], m2.m[1][1]) &&
       
   915            qFuzzyCompare(m1.m[1][2], m2.m[1][2]) &&
       
   916            qFuzzyCompare(m1.m[1][3], m2.m[1][3]) &&
       
   917            qFuzzyCompare(m1.m[2][0], m2.m[2][0]) &&
       
   918            qFuzzyCompare(m1.m[2][1], m2.m[2][1]) &&
       
   919            qFuzzyCompare(m1.m[2][2], m2.m[2][2]) &&
       
   920            qFuzzyCompare(m1.m[2][3], m2.m[2][3]) &&
       
   921            qFuzzyCompare(m1.m[3][0], m2.m[3][0]) &&
       
   922            qFuzzyCompare(m1.m[3][1], m2.m[3][1]) &&
       
   923            qFuzzyCompare(m1.m[3][2], m2.m[3][2]) &&
       
   924            qFuzzyCompare(m1.m[3][3], m2.m[3][3]);
       
   925 }
       
   926 
       
   927 inline QPoint QMatrix4x4::map(const QPoint& point) const
       
   928 {
       
   929     return *this * point;
       
   930 }
       
   931 
       
   932 inline QPointF QMatrix4x4::map(const QPointF& point) const
       
   933 {
       
   934     return *this * point;
       
   935 }
       
   936 
       
   937 #ifndef QT_NO_VECTOR3D
       
   938 
       
   939 inline QVector3D QMatrix4x4::map(const QVector3D& point) const
       
   940 {
       
   941     return *this * point;
       
   942 }
       
   943 
       
   944 inline QVector3D QMatrix4x4::mapVector(const QVector3D& vector) const
       
   945 {
       
   946     if (flagBits == Identity || flagBits == Translation) {
       
   947         return vector;
       
   948     } else if (flagBits == Scale || flagBits == (Translation | Scale)) {
       
   949         return QVector3D(vector.x() * m[0][0],
       
   950                          vector.y() * m[1][1],
       
   951                          vector.z() * m[2][2]);
       
   952     } else {
       
   953         return QVector3D(vector.x() * m[0][0] +
       
   954                          vector.y() * m[1][0] +
       
   955                          vector.z() * m[2][0],
       
   956                          vector.x() * m[0][1] +
       
   957                          vector.y() * m[1][1] +
       
   958                          vector.z() * m[2][1],
       
   959                          vector.x() * m[0][2] +
       
   960                          vector.y() * m[1][2] +
       
   961                          vector.z() * m[2][2]);
       
   962     }
       
   963 }
       
   964 
       
   965 #endif
       
   966 
       
   967 #ifndef QT_NO_VECTOR4D
       
   968 
       
   969 inline QVector4D QMatrix4x4::map(const QVector4D& point) const
       
   970 {
       
   971     return *this * point;
       
   972 }
       
   973 
       
   974 #endif
       
   975 
       
   976 inline qreal *QMatrix4x4::data()
       
   977 {
       
   978     // We have to assume that the caller will modify the matrix elements,
       
   979     // so we flip it over to "General" mode.
       
   980     flagBits = General;
       
   981     return m[0];
       
   982 }
       
   983 
       
   984 #ifndef QT_NO_DEBUG_STREAM
       
   985 Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m);
       
   986 #endif
       
   987 
       
   988 #ifndef QT_NO_DATASTREAM
       
   989 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QMatrix4x4 &);
       
   990 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix4x4 &);
       
   991 #endif
       
   992 
       
   993 template <int N, int M>
       
   994 QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix)
       
   995 {
       
   996     return QMatrix4x4(matrix.constData(), N, M);
       
   997 }
       
   998 
       
   999 template <int N, int M>
       
  1000 QGenericMatrix<N, M, qreal> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)
       
  1001 {
       
  1002     QGenericMatrix<N, M, qreal> result;
       
  1003     const qreal *m = matrix.constData();
       
  1004     qreal *values = result.data();
       
  1005     for (int col = 0; col < N; ++col) {
       
  1006         for (int row = 0; row < M; ++row) {
       
  1007             if (col < 4 && row < 4)
       
  1008                 values[col * M + row] = m[col * 4 + row];
       
  1009             else if (col == row)
       
  1010                 values[col * M + row] = 1.0f;
       
  1011             else
       
  1012                 values[col * M + row] = 0.0f;
       
  1013         }
       
  1014     }
       
  1015     return result;
       
  1016 }
       
  1017 
       
  1018 #endif
       
  1019 
       
  1020 QT_END_NAMESPACE
       
  1021 
       
  1022 QT_END_HEADER
       
  1023 
       
  1024 #endif