Coverage Report

Created: 2026-02-10 07:39

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