- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# qmatrix4x4.h

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 **
    00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    00004 ** All rights reserved.
    00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
    00006 **
    00007 ** This file is part of the QtGui module of the Qt Toolkit.
    00008 **
    00009 ** $QT_BEGIN_LICENSE:LGPL$
    00010 ** Commercial Usage
    00011 ** Licensees holding valid Qt Commercial licenses may use this file in
    00012 ** accordance with the Qt Commercial License Agreement provided with the
    00013 ** Software or, alternatively, in accordance with the terms contained in
    00014 ** a written agreement between you and Nokia.
    00015 **
    00016 ** GNU Lesser General Public License Usage
    00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
    00018 ** General Public License version 2.1 as published by the Free Software
    00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
    00020 ** packaging of this file.  Please review the following information to
    00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
    00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    00023 **
    00024 ** In addition, as a special exception, Nokia gives you certain additional
    00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
    00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
    00027 **
    00028 ** GNU General Public License Usage
    00029 ** Alternatively, this file may be used under the terms of the GNU
    00030 ** General Public License version 3.0 as published by the Free Software
    00031 ** Foundation and appearing in the file LICENSE.GPL included in the
    00032 ** packaging of this file.  Please review the following information to
    00033 ** ensure the GNU General Public License version 3.0 requirements will be
    00034 ** met: http://www.gnu.org/copyleft/gpl.html.
    00035 **
    00036 ** If you have questions regarding the use of this file, please contact
    00037 ** Nokia at qt-info@nokia.com.
    00038 ** $QT_END_LICENSE$
    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];          // Column-major order to match OpenGL.
    00191     int flagBits;           // Flag bits from the enum below.
    00192
    00193     enum {
    00194         Identity        = 0x0001,   // Identity matrix
    00195         General         = 0x0002,   // General matrix, unknown contents
    00196         Translation     = 0x0004,   // Contains a simple translation
    00197         Scale           = 0x0008,   // Contains a simple scale
    00198         Rotation        = 0x0010    // Contains a simple rotation
    00199     };
    00200
    00201     // Construct without initializing identity matrix.
    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     // We have to assume that the caller will modify the matrix elements,
    00981     // so we flip it over to "General" mode.
    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