Warning: That file was not part of the compilation database. It may have many parsing errors.

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

Warning: That file was not part of the compilation database. It may have many parsing errors.