OpenCoverage

qmatrix4x4.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/math3d/qmatrix4x4.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
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 The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/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 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qmatrix4x4.h"-
41#include <QtCore/qmath.h>-
42#include <QtCore/qvariant.h>-
43#include <QtGui/qmatrix.h>-
44#include <QtGui/qtransform.h>-
45-
46#include <cmath>-
47-
48QT_BEGIN_NAMESPACE-
49-
50#ifndef QT_NO_MATRIX4X4-
51-
52/*!-
53 \class QMatrix4x4-
54 \brief The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.-
55 \since 4.6-
56 \ingroup painting-3D-
57 \inmodule QtGui-
58-
59 The QMatrix4x4 class in general is treated as a row-major matrix, in that the-
60 constructors and operator() functions take data in row-major format, as is-
61 familiar in C-style usage.-
62-
63 Internally the data is stored as column-major format, so as to be optimal for-
64 passing to OpenGL functions, which expect column-major data.-
65-
66 When using these functions be aware that they return data in \b{column-major}-
67 format:-
68 \list-
69 \li data()-
70 \li constData()-
71 \endlist-
72-
73 \sa QVector3D, QGenericMatrix-
74*/-
75-
76static const float inv_dist_to_plane = 1.0f / 1024.0f;-
77-
78/*!-
79 \fn QMatrix4x4::QMatrix4x4()-
80-
81 Constructs an identity matrix.-
82*/-
83-
84/*!-
85 \fn QMatrix4x4::QMatrix4x4(Qt::Initialization)-
86 \since 5.5-
87 \internal-
88-
89 Constructs a matrix without initializing the contents.-
90*/-
91-
92/*!-
93 Constructs a matrix from the given 16 floating-point \a values.-
94 The contents of the array \a values is assumed to be in-
95 row-major order.-
96-
97 If the matrix has a special type (identity, translate, scale, etc),-
98 the programmer should follow this constructor with a call to-
99 optimize() if they wish QMatrix4x4 to optimize further-
100 calls to translate(), scale(), etc.-
101-
102 \sa copyDataTo(), optimize()-
103*/-
104QMatrix4x4::QMatrix4x4(const float *values)-
105{-
106 for (int row = 0; row < 4; ++row)
row < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
107 for (int col = 0; col < 4; ++col)
col < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
108 m[col][row] = values[row * 4 + col];
never executed: m[col][row] = values[row * 4 + col];
0
109 flagBits = General;-
110}
never executed: end of block
0
111-
112/*!-
113 \fn QMatrix4x4::QMatrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)-
114-
115 Constructs a matrix from the 16 elements \a m11, \a m12, \a m13, \a m14,-
116 \a m21, \a m22, \a m23, \a m24, \a m31, \a m32, \a m33, \a m34,-
117 \a m41, \a m42, \a m43, and \a m44. The elements are specified in-
118 row-major order.-
119-
120 If the matrix has a special type (identity, translate, scale, etc),-
121 the programmer should follow this constructor with a call to-
122 optimize() if they wish QMatrix4x4 to optimize further-
123 calls to translate(), scale(), etc.-
124-
125 \sa optimize()-
126*/-
127-
128/*!-
129 \fn QMatrix4x4::QMatrix4x4(const QGenericMatrix<N, M, float>& matrix)-
130-
131 Constructs a 4x4 matrix from the left-most 4 columns and top-most-
132 4 rows of \a matrix. If \a matrix has less than 4 columns or rows,-
133 the remaining elements are filled with elements from the identity-
134 matrix.-
135-
136 \sa toGenericMatrix()-
137*/-
138-
139/*!-
140 \fn QGenericMatrix<N, M, float> QMatrix4x4::toGenericMatrix() const-
141-
142 Constructs a NxM generic matrix from the left-most N columns and-
143 top-most M rows of this 4x4 matrix. If N or M is greater than 4,-
144 then the remaining elements are filled with elements from the-
145 identity matrix.-
146*/-
147-
148/*!-
149 \fn QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix<N, M, float>& matrix)-
150 \relates QMatrix4x4-
151 \obsolete-
152-
153 Returns a 4x4 matrix constructed from the left-most 4 columns and-
154 top-most 4 rows of \a matrix. If \a matrix has less than 4 columns-
155 or rows, the remaining elements are filled with elements from the-
156 identity matrix.-
157*/-
158-
159/*!-
160 \fn QGenericMatrix<N, M, float> qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix)-
161 \relates QMatrix4x4-
162 \obsolete-
163-
164 Returns a NxM generic matrix constructed from the left-most N columns-
165 and top-most M rows of \a matrix. If N or M is greater than 4,-
166 then the remaining elements are filled with elements from the-
167 identity matrix.-
168-
169 \sa QMatrix4x4::toGenericMatrix()-
170*/-
171-
172/*!-
173 \internal-
174*/-
175QMatrix4x4::QMatrix4x4(const float *values, int cols, int rows)-
176{-
177 for (int col = 0; col < 4; ++col) {
col < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
178 for (int row = 0; row < 4; ++row) {
row < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
179 if (col < cols && row < rows)
col < colsDescription
TRUEnever evaluated
FALSEnever evaluated
row < rowsDescription
TRUEnever evaluated
FALSEnever evaluated
0
180 m[col][row] = values[col * rows + row];
never executed: m[col][row] = values[col * rows + row];
0
181 else if (col == row)
col == rowDescription
TRUEnever evaluated
FALSEnever evaluated
0
182 m[col][row] = 1.0f;
never executed: m[col][row] = 1.0f;
0
183 else-
184 m[col][row] = 0.0f;
never executed: m[col][row] = 0.0f;
0
185 }-
186 }
never executed: end of block
0
187 flagBits = General;-
188}
never executed: end of block
0
189-
190/*!-
191 Constructs a 4x4 matrix from a conventional Qt 2D affine-
192 transformation \a matrix.-
193-
194 If \a matrix has a special type (identity, translate, scale, etc),-
195 the programmer should follow this constructor with a call to-
196 optimize() if they wish QMatrix4x4 to optimize further-
197 calls to translate(), scale(), etc.-
198-
199 \sa toAffine(), optimize()-
200*/-
201QMatrix4x4::QMatrix4x4(const QMatrix& matrix)-
202{-
203 m[0][0] = matrix.m11();-
204 m[0][1] = matrix.m12();-
205 m[0][2] = 0.0f;-
206 m[0][3] = 0.0f;-
207 m[1][0] = matrix.m21();-
208 m[1][1] = matrix.m22();-
209 m[1][2] = 0.0f;-
210 m[1][3] = 0.0f;-
211 m[2][0] = 0.0f;-
212 m[2][1] = 0.0f;-
213 m[2][2] = 1.0f;-
214 m[2][3] = 0.0f;-
215 m[3][0] = matrix.dx();-
216 m[3][1] = matrix.dy();-
217 m[3][2] = 0.0f;-
218 m[3][3] = 1.0f;-
219 flagBits = Translation | Scale | Rotation2D;-
220}
never executed: end of block
0
221-
222/*!-
223 Constructs a 4x4 matrix from the conventional Qt 2D-
224 transformation matrix \a transform.-
225-
226 If \a transform has a special type (identity, translate, scale, etc),-
227 the programmer should follow this constructor with a call to-
228 optimize() if they wish QMatrix4x4 to optimize further-
229 calls to translate(), scale(), etc.-
230-
231 \sa toTransform(), optimize()-
232*/-
233QMatrix4x4::QMatrix4x4(const QTransform& transform)-
234{-
235 m[0][0] = transform.m11();-
236 m[0][1] = transform.m12();-
237 m[0][2] = 0.0f;-
238 m[0][3] = transform.m13();-
239 m[1][0] = transform.m21();-
240 m[1][1] = transform.m22();-
241 m[1][2] = 0.0f;-
242 m[1][3] = transform.m23();-
243 m[2][0] = 0.0f;-
244 m[2][1] = 0.0f;-
245 m[2][2] = 1.0f;-
246 m[2][3] = 0.0f;-
247 m[3][0] = transform.dx();-
248 m[3][1] = transform.dy();-
249 m[3][2] = 0.0f;-
250 m[3][3] = transform.m33();-
251 flagBits = General;-
252}
never executed: end of block
0
253-
254/*!-
255 \fn const float& QMatrix4x4::operator()(int row, int column) const-
256-
257 Returns a constant reference to the element at position-
258 (\a row, \a column) in this matrix.-
259-
260 \sa column(), row()-
261*/-
262-
263/*!-
264 \fn float& QMatrix4x4::operator()(int row, int column)-
265-
266 Returns a reference to the element at position (\a row, \a column)-
267 in this matrix so that the element can be assigned to.-
268-
269 \sa optimize(), setColumn(), setRow()-
270*/-
271-
272/*!-
273 \fn QVector4D QMatrix4x4::column(int index) const-
274-
275 Returns the elements of column \a index as a 4D vector.-
276-
277 \sa setColumn(), row()-
278*/-
279-
280/*!-
281 \fn void QMatrix4x4::setColumn(int index, const QVector4D& value)-
282-
283 Sets the elements of column \a index to the components of \a value.-
284-
285 \sa column(), setRow()-
286*/-
287-
288/*!-
289 \fn QVector4D QMatrix4x4::row(int index) const-
290-
291 Returns the elements of row \a index as a 4D vector.-
292-
293 \sa setRow(), column()-
294*/-
295-
296/*!-
297 \fn void QMatrix4x4::setRow(int index, const QVector4D& value)-
298-
299 Sets the elements of row \a index to the components of \a value.-
300-
301 \sa row(), setColumn()-
302*/-
303-
304/*!-
305 \fn bool QMatrix4x4::isAffine() const-
306 \since 5.5-
307-
308 Returns \c true if this matrix is affine matrix; false otherwise.-
309-
310 An affine matrix is a 4x4 matrix with row 3 equal to (0, 0, 0, 1),-
311 e.g. no projective coefficients.-
312-
313 \sa isIdentity()-
314*/-
315-
316/*!-
317 \fn bool QMatrix4x4::isIdentity() const-
318-
319 Returns \c true if this matrix is the identity; false otherwise.-
320-
321 \sa setToIdentity()-
322*/-
323-
324/*!-
325 \fn void QMatrix4x4::setToIdentity()-
326-
327 Sets this matrix to the identity.-
328-
329 \sa isIdentity()-
330*/-
331-
332/*!-
333 \fn void QMatrix4x4::fill(float value)-
334-
335 Fills all elements of this matrx with \a value.-
336*/-
337-
338static inline double matrixDet2(const double m[4][4], int col0, int col1, int row0, int row1)-
339{-
340 return m[col0][row0] * m[col1][row1] - m[col0][row1] * m[col1][row0];
never executed: return m[col0][row0] * m[col1][row1] - m[col0][row1] * m[col1][row0];
0
341}-
342-
343-
344// The 4x4 matrix inverse algorithm is based on that described at:-
345// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q24-
346// Some optimization has been done to avoid making copies of 3x3-
347// sub-matrices and to unroll the loops.-
348-
349// Calculate the determinant of a 3x3 sub-matrix.-
350// | A B C |-
351// M = | D E F | det(M) = A * (EI - HF) - B * (DI - GF) + C * (DH - GE)-
352// | G H I |-
353static inline double matrixDet3-
354 (const double m[4][4], int col0, int col1, int col2,-
355 int row0, int row1, int row2)-
356{-
357 return m[col0][row0] * matrixDet2(m, col1, col2, row1, row2)
never executed: return m[col0][row0] * matrixDet2(m, col1, col2, row1, row2) - m[col1][row0] * matrixDet2(m, col0, col2, row1, row2) + m[col2][row0] * matrixDet2(m, col0, col1, row1, row2);
0
358 - m[col1][row0] * matrixDet2(m, col0, col2, row1, row2)
never executed: return m[col0][row0] * matrixDet2(m, col1, col2, row1, row2) - m[col1][row0] * matrixDet2(m, col0, col2, row1, row2) + m[col2][row0] * matrixDet2(m, col0, col1, row1, row2);
0
359 + m[col2][row0] * matrixDet2(m, col0, col1, row1, row2);
never executed: return m[col0][row0] * matrixDet2(m, col1, col2, row1, row2) - m[col1][row0] * matrixDet2(m, col0, col2, row1, row2) + m[col2][row0] * matrixDet2(m, col0, col1, row1, row2);
0
360}-
361-
362// Calculate the determinant of a 4x4 matrix.-
363static inline double matrixDet4(const double m[4][4])-
364{-
365 double det;-
366 det = m[0][0] * matrixDet3(m, 1, 2, 3, 1, 2, 3);-
367 det -= m[1][0] * matrixDet3(m, 0, 2, 3, 1, 2, 3);-
368 det += m[2][0] * matrixDet3(m, 0, 1, 3, 1, 2, 3);-
369 det -= m[3][0] * matrixDet3(m, 0, 1, 2, 1, 2, 3);-
370 return det;
never executed: return det;
0
371}-
372-
373static inline void copyToDoubles(const float m[4][4], double mm[4][4])-
374{-
375 for (int i = 0; i < 4; ++i)
i < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
376 for (int j = 0; j < 4; ++j)
j < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
377 mm[i][j] = double(m[i][j]);
never executed: mm[i][j] = double(m[i][j]);
0
378}
never executed: end of block
0
379-
380/*!-
381 Returns the determinant of this matrix.-
382*/-
383double QMatrix4x4::determinant() const-
384{-
385 if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity)
(flagBits & ~(...)) == IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
0
386 return 1.0;
never executed: return 1.0;
0
387-
388 double mm[4][4];-
389 copyToDoubles(m, mm);-
390 if (flagBits < Rotation2D)
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
391 return mm[0][0] * mm[1][1] * mm[2][2]; // Translation | Scale
never executed: return mm[0][0] * mm[1][1] * mm[2][2];
0
392 if (flagBits < Perspective)
flagBits < PerspectiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
393 return matrixDet3(mm, 0, 1, 2, 0, 1, 2);
never executed: return matrixDet3(mm, 0, 1, 2, 0, 1, 2);
0
394 return matrixDet4(mm);
never executed: return matrixDet4(mm);
0
395}-
396-
397/*!-
398 Returns the inverse of this matrix. Returns the identity if-
399 this matrix cannot be inverted; i.e. determinant() is zero.-
400 If \a invertible is not null, then true will be written to-
401 that location if the matrix can be inverted; false otherwise.-
402-
403 If the matrix is recognized as the identity or an orthonormal-
404 matrix, then this function will quickly invert the matrix-
405 using optimized routines.-
406-
407 \sa determinant(), normalMatrix()-
408*/-
409QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const-
410{-
411 // Handle some of the easy cases first.-
412 if (flagBits == Identity) {
flagBits == IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
0
413 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
414 *invertible = true;
never executed: *invertible = true;
0
415 return QMatrix4x4();
never executed: return QMatrix4x4();
0
416 } else if (flagBits == Translation) {
flagBits == TranslationDescription
TRUEnever evaluated
FALSEnever evaluated
0
417 QMatrix4x4 inv;-
418 inv.m[3][0] = -m[3][0];-
419 inv.m[3][1] = -m[3][1];-
420 inv.m[3][2] = -m[3][2];-
421 inv.flagBits = Translation;-
422 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
423 *invertible = true;
never executed: *invertible = true;
0
424 return inv;
never executed: return inv;
0
425 } else if (flagBits < Rotation2D) {
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
426 // Translation | Scale-
427 if (m[0][0] == 0 || m[1][1] == 0 || m[2][2] == 0) {
m[0][0] == 0Description
TRUEnever evaluated
FALSEnever evaluated
m[1][1] == 0Description
TRUEnever evaluated
FALSEnever evaluated
m[2][2] == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
428 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
429 *invertible = false;
never executed: *invertible = false;
0
430 return QMatrix4x4();
never executed: return QMatrix4x4();
0
431 }-
432 QMatrix4x4 inv;-
433 inv.m[0][0] = 1.0f / m[0][0];-
434 inv.m[1][1] = 1.0f / m[1][1];-
435 inv.m[2][2] = 1.0f / m[2][2];-
436 inv.m[3][0] = -m[3][0] * inv.m[0][0];-
437 inv.m[3][1] = -m[3][1] * inv.m[1][1];-
438 inv.m[3][2] = -m[3][2] * inv.m[2][2];-
439 inv.flagBits = flagBits;-
440-
441 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
442 *invertible = true;
never executed: *invertible = true;
0
443 return inv;
never executed: return inv;
0
444 } else if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) {
(flagBits & ~(...)) == IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
0
445 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
446 *invertible = true;
never executed: *invertible = true;
0
447 return orthonormalInverse();
never executed: return orthonormalInverse();
0
448 } else if (flagBits < Perspective) {
flagBits < PerspectiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
449 QMatrix4x4 inv(1); // The "1" says to not load the identity.-
450-
451 double mm[4][4];-
452 copyToDoubles(m, mm);-
453-
454 double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);-
455 if (det == 0.0f) {
det == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
456 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
457 *invertible = false;
never executed: *invertible = false;
0
458 return QMatrix4x4();
never executed: return QMatrix4x4();
0
459 }-
460 det = 1.0f / det;-
461-
462 inv.m[0][0] = matrixDet2(mm, 1, 2, 1, 2) * det;-
463 inv.m[0][1] = -matrixDet2(mm, 0, 2, 1, 2) * det;-
464 inv.m[0][2] = matrixDet2(mm, 0, 1, 1, 2) * det;-
465 inv.m[0][3] = 0;-
466 inv.m[1][0] = -matrixDet2(mm, 1, 2, 0, 2) * det;-
467 inv.m[1][1] = matrixDet2(mm, 0, 2, 0, 2) * det;-
468 inv.m[1][2] = -matrixDet2(mm, 0, 1, 0, 2) * det;-
469 inv.m[1][3] = 0;-
470 inv.m[2][0] = matrixDet2(mm, 1, 2, 0, 1) * det;-
471 inv.m[2][1] = -matrixDet2(mm, 0, 2, 0, 1) * det;-
472 inv.m[2][2] = matrixDet2(mm, 0, 1, 0, 1) * det;-
473 inv.m[2][3] = 0;-
474 inv.m[3][0] = -inv.m[0][0] * m[3][0] - inv.m[1][0] * m[3][1] - inv.m[2][0] * m[3][2];-
475 inv.m[3][1] = -inv.m[0][1] * m[3][0] - inv.m[1][1] * m[3][1] - inv.m[2][1] * m[3][2];-
476 inv.m[3][2] = -inv.m[0][2] * m[3][0] - inv.m[1][2] * m[3][1] - inv.m[2][2] * m[3][2];-
477 inv.m[3][3] = 1;-
478 inv.flagBits = flagBits;-
479-
480 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
481 *invertible = true;
never executed: *invertible = true;
0
482 return inv;
never executed: return inv;
0
483 }-
484-
485 QMatrix4x4 inv(1); // The "1" says to not load the identity.-
486-
487 double mm[4][4];-
488 copyToDoubles(m, mm);-
489-
490 double det = matrixDet4(mm);-
491 if (det == 0.0f) {
det == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
492 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
493 *invertible = false;
never executed: *invertible = false;
0
494 return QMatrix4x4();
never executed: return QMatrix4x4();
0
495 }-
496 det = 1.0f / det;-
497-
498 inv.m[0][0] = matrixDet3(mm, 1, 2, 3, 1, 2, 3) * det;-
499 inv.m[0][1] = -matrixDet3(mm, 0, 2, 3, 1, 2, 3) * det;-
500 inv.m[0][2] = matrixDet3(mm, 0, 1, 3, 1, 2, 3) * det;-
501 inv.m[0][3] = -matrixDet3(mm, 0, 1, 2, 1, 2, 3) * det;-
502 inv.m[1][0] = -matrixDet3(mm, 1, 2, 3, 0, 2, 3) * det;-
503 inv.m[1][1] = matrixDet3(mm, 0, 2, 3, 0, 2, 3) * det;-
504 inv.m[1][2] = -matrixDet3(mm, 0, 1, 3, 0, 2, 3) * det;-
505 inv.m[1][3] = matrixDet3(mm, 0, 1, 2, 0, 2, 3) * det;-
506 inv.m[2][0] = matrixDet3(mm, 1, 2, 3, 0, 1, 3) * det;-
507 inv.m[2][1] = -matrixDet3(mm, 0, 2, 3, 0, 1, 3) * det;-
508 inv.m[2][2] = matrixDet3(mm, 0, 1, 3, 0, 1, 3) * det;-
509 inv.m[2][3] = -matrixDet3(mm, 0, 1, 2, 0, 1, 3) * det;-
510 inv.m[3][0] = -matrixDet3(mm, 1, 2, 3, 0, 1, 2) * det;-
511 inv.m[3][1] = matrixDet3(mm, 0, 2, 3, 0, 1, 2) * det;-
512 inv.m[3][2] = -matrixDet3(mm, 0, 1, 3, 0, 1, 2) * det;-
513 inv.m[3][3] = matrixDet3(mm, 0, 1, 2, 0, 1, 2) * det;-
514 inv.flagBits = flagBits;-
515-
516 if (invertible)
invertibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
517 *invertible = true;
never executed: *invertible = true;
0
518 return inv;
never executed: return inv;
0
519}-
520-
521/*!-
522 Returns the normal matrix corresponding to this 4x4 transformation.-
523 The normal matrix is the transpose of the inverse of the top-left-
524 3x3 part of this 4x4 matrix. If the 3x3 sub-matrix is not invertible,-
525 this function returns the identity.-
526-
527 \sa inverted()-
528*/-
529QMatrix3x3 QMatrix4x4::normalMatrix() const-
530{-
531 QMatrix3x3 inv;-
532-
533 // Handle the simple cases first.-
534 if (flagBits < Scale) {
flagBits < ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
535 // Translation-
536 return inv;
never executed: return inv;
0
537 } else if (flagBits < Rotation2D) {
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
538 // Translation | Scale-
539 if (m[0][0] == 0.0f || m[1][1] == 0.0f || m[2][2] == 0.0f)
m[0][0] == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
m[1][1] == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
m[2][2] == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
540 return inv;
never executed: return inv;
0
541 inv.data()[0] = 1.0f / m[0][0];-
542 inv.data()[4] = 1.0f / m[1][1];-
543 inv.data()[8] = 1.0f / m[2][2];-
544 return inv;
never executed: return inv;
0
545 } else if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) {
(flagBits & ~(...)) == IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
0
546 float *invm = inv.data();-
547 invm[0 + 0 * 3] = m[0][0];-
548 invm[1 + 0 * 3] = m[0][1];-
549 invm[2 + 0 * 3] = m[0][2];-
550 invm[0 + 1 * 3] = m[1][0];-
551 invm[1 + 1 * 3] = m[1][1];-
552 invm[2 + 1 * 3] = m[1][2];-
553 invm[0 + 2 * 3] = m[2][0];-
554 invm[1 + 2 * 3] = m[2][1];-
555 invm[2 + 2 * 3] = m[2][2];-
556 return inv;
never executed: return inv;
0
557 }-
558-
559 double mm[4][4];-
560 copyToDoubles(m, mm);-
561 double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);-
562 if (det == 0.0f)
det == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
563 return inv;
never executed: return inv;
0
564 det = 1.0f / det;-
565-
566 float *invm = inv.data();-
567-
568 // Invert and transpose in a single step.-
569 invm[0 + 0 * 3] = (mm[1][1] * mm[2][2] - mm[2][1] * mm[1][2]) * det;-
570 invm[1 + 0 * 3] = -(mm[1][0] * mm[2][2] - mm[1][2] * mm[2][0]) * det;-
571 invm[2 + 0 * 3] = (mm[1][0] * mm[2][1] - mm[1][1] * mm[2][0]) * det;-
572 invm[0 + 1 * 3] = -(mm[0][1] * mm[2][2] - mm[2][1] * mm[0][2]) * det;-
573 invm[1 + 1 * 3] = (mm[0][0] * mm[2][2] - mm[0][2] * mm[2][0]) * det;-
574 invm[2 + 1 * 3] = -(mm[0][0] * mm[2][1] - mm[0][1] * mm[2][0]) * det;-
575 invm[0 + 2 * 3] = (mm[0][1] * mm[1][2] - mm[0][2] * mm[1][1]) * det;-
576 invm[1 + 2 * 3] = -(mm[0][0] * mm[1][2] - mm[0][2] * mm[1][0]) * det;-
577 invm[2 + 2 * 3] = (mm[0][0] * mm[1][1] - mm[1][0] * mm[0][1]) * det;-
578-
579 return inv;
never executed: return inv;
0
580}-
581-
582/*!-
583 Returns this matrix, transposed about its diagonal.-
584*/-
585QMatrix4x4 QMatrix4x4::transposed() const-
586{-
587 QMatrix4x4 result(1); // The "1" says to not load the identity.-
588 for (int row = 0; row < 4; ++row) {
row < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
589 for (int col = 0; col < 4; ++col) {
col < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
590 result.m[col][row] = m[row][col];-
591 }
never executed: end of block
0
592 }
never executed: end of block
0
593 // When a translation is transposed, it becomes a perspective transformation.-
594 result.flagBits = (flagBits & Translation ? General : flagBits);
flagBits & TranslationDescription
TRUEnever evaluated
FALSEnever evaluated
0
595 return result;
never executed: return result;
0
596}-
597-
598/*!-
599 \fn QMatrix4x4& QMatrix4x4::operator+=(const QMatrix4x4& other)-
600-
601 Adds the contents of \a other to this matrix.-
602*/-
603-
604/*!-
605 \fn QMatrix4x4& QMatrix4x4::operator-=(const QMatrix4x4& other)-
606-
607 Subtracts the contents of \a other from this matrix.-
608*/-
609-
610/*!-
611 \fn QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& other)-
612-
613 Multiplies the contents of \a other by this matrix.-
614*/-
615-
616/*!-
617 \fn QMatrix4x4& QMatrix4x4::operator*=(float factor)-
618 \overload-
619-
620 Multiplies all elements of this matrix by \a factor.-
621*/-
622-
623/*!-
624 \overload-
625-
626 Divides all elements of this matrix by \a divisor.-
627*/-
628QMatrix4x4& QMatrix4x4::operator/=(float divisor)-
629{-
630 m[0][0] /= divisor;-
631 m[0][1] /= divisor;-
632 m[0][2] /= divisor;-
633 m[0][3] /= divisor;-
634 m[1][0] /= divisor;-
635 m[1][1] /= divisor;-
636 m[1][2] /= divisor;-
637 m[1][3] /= divisor;-
638 m[2][0] /= divisor;-
639 m[2][1] /= divisor;-
640 m[2][2] /= divisor;-
641 m[2][3] /= divisor;-
642 m[3][0] /= divisor;-
643 m[3][1] /= divisor;-
644 m[3][2] /= divisor;-
645 m[3][3] /= divisor;-
646 flagBits = General;-
647 return *this;
never executed: return *this;
0
648}-
649-
650/*!-
651 \fn bool QMatrix4x4::operator==(const QMatrix4x4& other) const-
652-
653 Returns \c true if this matrix is identical to \a other; false otherwise.-
654 This operator uses an exact floating-point comparison.-
655*/-
656-
657/*!-
658 \fn bool QMatrix4x4::operator!=(const QMatrix4x4& other) const-
659-
660 Returns \c true if this matrix is not identical to \a other; false otherwise.-
661 This operator uses an exact floating-point comparison.-
662*/-
663-
664/*!-
665 \fn QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2)-
666 \relates QMatrix4x4-
667-
668 Returns the sum of \a m1 and \a m2.-
669*/-
670-
671/*!-
672 \fn QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2)-
673 \relates QMatrix4x4-
674-
675 Returns the difference of \a m1 and \a m2.-
676*/-
677-
678/*!-
679 \fn QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2)-
680 \relates QMatrix4x4-
681-
682 Returns the product of \a m1 and \a m2.-
683*/-
684-
685#ifndef QT_NO_VECTOR3D-
686-
687/*!-
688 \fn QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix)-
689 \relates QMatrix4x4-
690-
691 Returns the result of transforming \a vector according to \a matrix,-
692 with the matrix applied post-vector.-
693*/-
694-
695/*!-
696 \fn QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector)-
697 \relates QMatrix4x4-
698-
699 Returns the result of transforming \a vector according to \a matrix,-
700 with the matrix applied pre-vector.-
701*/-
702-
703#endif-
704-
705#ifndef QT_NO_VECTOR4D-
706-
707/*!-
708 \fn QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix)-
709 \relates QMatrix4x4-
710-
711 Returns the result of transforming \a vector according to \a matrix,-
712 with the matrix applied post-vector.-
713*/-
714-
715/*!-
716 \fn QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector)-
717 \relates QMatrix4x4-
718-
719 Returns the result of transforming \a vector according to \a matrix,-
720 with the matrix applied pre-vector.-
721*/-
722-
723#endif-
724-
725/*!-
726 \fn QPoint operator*(const QPoint& point, const QMatrix4x4& matrix)-
727 \relates QMatrix4x4-
728-
729 Returns the result of transforming \a point according to \a matrix,-
730 with the matrix applied post-point.-
731*/-
732-
733/*!-
734 \fn QPointF operator*(const QPointF& point, const QMatrix4x4& matrix)-
735 \relates QMatrix4x4-
736-
737 Returns the result of transforming \a point according to \a matrix,-
738 with the matrix applied post-point.-
739*/-
740-
741/*!-
742 \fn QPoint operator*(const QMatrix4x4& matrix, const QPoint& point)-
743 \relates QMatrix4x4-
744-
745 Returns the result of transforming \a point according to \a matrix,-
746 with the matrix applied pre-point.-
747*/-
748-
749/*!-
750 \fn QPointF operator*(const QMatrix4x4& matrix, const QPointF& point)-
751 \relates QMatrix4x4-
752-
753 Returns the result of transforming \a point according to \a matrix,-
754 with the matrix applied pre-point.-
755*/-
756-
757/*!-
758 \fn QMatrix4x4 operator-(const QMatrix4x4& matrix)-
759 \overload-
760 \relates QMatrix4x4-
761-
762 Returns the negation of \a matrix.-
763*/-
764-
765/*!-
766 \fn QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix)-
767 \relates QMatrix4x4-
768-
769 Returns the result of multiplying all elements of \a matrix by \a factor.-
770*/-
771-
772/*!-
773 \fn QMatrix4x4 operator*(const QMatrix4x4& matrix, float factor)-
774 \relates QMatrix4x4-
775-
776 Returns the result of multiplying all elements of \a matrix by \a factor.-
777*/-
778-
779/*!-
780 \relates QMatrix4x4-
781-
782 Returns the result of dividing all elements of \a matrix by \a divisor.-
783*/-
784QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor)-
785{-
786 QMatrix4x4 m(1); // The "1" says to not load the identity.-
787 m.m[0][0] = matrix.m[0][0] / divisor;-
788 m.m[0][1] = matrix.m[0][1] / divisor;-
789 m.m[0][2] = matrix.m[0][2] / divisor;-
790 m.m[0][3] = matrix.m[0][3] / divisor;-
791 m.m[1][0] = matrix.m[1][0] / divisor;-
792 m.m[1][1] = matrix.m[1][1] / divisor;-
793 m.m[1][2] = matrix.m[1][2] / divisor;-
794 m.m[1][3] = matrix.m[1][3] / divisor;-
795 m.m[2][0] = matrix.m[2][0] / divisor;-
796 m.m[2][1] = matrix.m[2][1] / divisor;-
797 m.m[2][2] = matrix.m[2][2] / divisor;-
798 m.m[2][3] = matrix.m[2][3] / divisor;-
799 m.m[3][0] = matrix.m[3][0] / divisor;-
800 m.m[3][1] = matrix.m[3][1] / divisor;-
801 m.m[3][2] = matrix.m[3][2] / divisor;-
802 m.m[3][3] = matrix.m[3][3] / divisor;-
803 m.flagBits = QMatrix4x4::General;-
804 return m;
never executed: return m;
0
805}-
806-
807/*!-
808 \fn bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2)-
809 \relates QMatrix4x4-
810-
811 Returns \c true if \a m1 and \a m2 are equal, allowing for a small-
812 fuzziness factor for floating-point comparisons; false otherwise.-
813*/-
814-
815#ifndef QT_NO_VECTOR3D-
816-
817/*!-
818 Multiplies this matrix by another that scales coordinates by-
819 the components of \a vector.-
820-
821 \sa translate(), rotate()-
822*/-
823void QMatrix4x4::scale(const QVector3D& vector)-
824{-
825 float vx = vector.x();-
826 float vy = vector.y();-
827 float vz = vector.z();-
828 if (flagBits < Scale) {
flagBits < ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
829 m[0][0] = vx;-
830 m[1][1] = vy;-
831 m[2][2] = vz;-
832 } else if (flagBits < Rotation2D) {
never executed: end of block
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
833 m[0][0] *= vx;-
834 m[1][1] *= vy;-
835 m[2][2] *= vz;-
836 } else if (flagBits < Rotation) {
never executed: end of block
flagBits < RotationDescription
TRUEnever evaluated
FALSEnever evaluated
0
837 m[0][0] *= vx;-
838 m[0][1] *= vx;-
839 m[1][0] *= vy;-
840 m[1][1] *= vy;-
841 m[2][2] *= vz;-
842 } else {
never executed: end of block
0
843 m[0][0] *= vx;-
844 m[0][1] *= vx;-
845 m[0][2] *= vx;-
846 m[0][3] *= vx;-
847 m[1][0] *= vy;-
848 m[1][1] *= vy;-
849 m[1][2] *= vy;-
850 m[1][3] *= vy;-
851 m[2][0] *= vz;-
852 m[2][1] *= vz;-
853 m[2][2] *= vz;-
854 m[2][3] *= vz;-
855 }
never executed: end of block
0
856 flagBits |= Scale;-
857}
never executed: end of block
0
858-
859#endif-
860-
861/*!-
862 \overload-
863-
864 Multiplies this matrix by another that scales coordinates by the-
865 components \a x, and \a y.-
866-
867 \sa translate(), rotate()-
868*/-
869void QMatrix4x4::scale(float x, float y)-
870{-
871 if (flagBits < Scale) {
flagBits < ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
872 m[0][0] = x;-
873 m[1][1] = y;-
874 } else if (flagBits < Rotation2D) {
never executed: end of block
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
875 m[0][0] *= x;-
876 m[1][1] *= y;-
877 } else if (flagBits < Rotation) {
never executed: end of block
flagBits < RotationDescription
TRUEnever evaluated
FALSEnever evaluated
0
878 m[0][0] *= x;-
879 m[0][1] *= x;-
880 m[1][0] *= y;-
881 m[1][1] *= y;-
882 } else {
never executed: end of block
0
883 m[0][0] *= x;-
884 m[0][1] *= x;-
885 m[0][2] *= x;-
886 m[0][3] *= x;-
887 m[1][0] *= y;-
888 m[1][1] *= y;-
889 m[1][2] *= y;-
890 m[1][3] *= y;-
891 }
never executed: end of block
0
892 flagBits |= Scale;-
893}
never executed: end of block
0
894-
895/*!-
896 \overload-
897-
898 Multiplies this matrix by another that scales coordinates by the-
899 components \a x, \a y, and \a z.-
900-
901 \sa translate(), rotate()-
902*/-
903void QMatrix4x4::scale(float x, float y, float z)-
904{-
905 if (flagBits < Scale) {
flagBits < ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
906 m[0][0] = x;-
907 m[1][1] = y;-
908 m[2][2] = z;-
909 } else if (flagBits < Rotation2D) {
never executed: end of block
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
910 m[0][0] *= x;-
911 m[1][1] *= y;-
912 m[2][2] *= z;-
913 } else if (flagBits < Rotation) {
never executed: end of block
flagBits < RotationDescription
TRUEnever evaluated
FALSEnever evaluated
0
914 m[0][0] *= x;-
915 m[0][1] *= x;-
916 m[1][0] *= y;-
917 m[1][1] *= y;-
918 m[2][2] *= z;-
919 } else {
never executed: end of block
0
920 m[0][0] *= x;-
921 m[0][1] *= x;-
922 m[0][2] *= x;-
923 m[0][3] *= x;-
924 m[1][0] *= y;-
925 m[1][1] *= y;-
926 m[1][2] *= y;-
927 m[1][3] *= y;-
928 m[2][0] *= z;-
929 m[2][1] *= z;-
930 m[2][2] *= z;-
931 m[2][3] *= z;-
932 }
never executed: end of block
0
933 flagBits |= Scale;-
934}
never executed: end of block
0
935-
936/*!-
937 \overload-
938-
939 Multiplies this matrix by another that scales coordinates by the-
940 given \a factor.-
941-
942 \sa translate(), rotate()-
943*/-
944void QMatrix4x4::scale(float factor)-
945{-
946 if (flagBits < Scale) {
flagBits < ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
947 m[0][0] = factor;-
948 m[1][1] = factor;-
949 m[2][2] = factor;-
950 } else if (flagBits < Rotation2D) {
never executed: end of block
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
951 m[0][0] *= factor;-
952 m[1][1] *= factor;-
953 m[2][2] *= factor;-
954 } else if (flagBits < Rotation) {
never executed: end of block
flagBits < RotationDescription
TRUEnever evaluated
FALSEnever evaluated
0
955 m[0][0] *= factor;-
956 m[0][1] *= factor;-
957 m[1][0] *= factor;-
958 m[1][1] *= factor;-
959 m[2][2] *= factor;-
960 } else {
never executed: end of block
0
961 m[0][0] *= factor;-
962 m[0][1] *= factor;-
963 m[0][2] *= factor;-
964 m[0][3] *= factor;-
965 m[1][0] *= factor;-
966 m[1][1] *= factor;-
967 m[1][2] *= factor;-
968 m[1][3] *= factor;-
969 m[2][0] *= factor;-
970 m[2][1] *= factor;-
971 m[2][2] *= factor;-
972 m[2][3] *= factor;-
973 }
never executed: end of block
0
974 flagBits |= Scale;-
975}
never executed: end of block
0
976-
977#ifndef QT_NO_VECTOR3D-
978/*!-
979 Multiplies this matrix by another that translates coordinates by-
980 the components of \a vector.-
981-
982 \sa scale(), rotate()-
983*/-
984-
985void QMatrix4x4::translate(const QVector3D& vector)-
986{-
987 float vx = vector.x();-
988 float vy = vector.y();-
989 float vz = vector.z();-
990 if (flagBits == Identity) {
flagBits == IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
0
991 m[3][0] = vx;-
992 m[3][1] = vy;-
993 m[3][2] = vz;-
994 } else if (flagBits == Translation) {
never executed: end of block
flagBits == TranslationDescription
TRUEnever evaluated
FALSEnever evaluated
0
995 m[3][0] += vx;-
996 m[3][1] += vy;-
997 m[3][2] += vz;-
998 } else if (flagBits == Scale) {
never executed: end of block
flagBits == ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
999 m[3][0] = m[0][0] * vx;-
1000 m[3][1] = m[1][1] * vy;-
1001 m[3][2] = m[2][2] * vz;-
1002 } else if (flagBits == (Translation | Scale)) {
never executed: end of block
flagBits == (T...ation | Scale)Description
TRUEnever evaluated
FALSEnever evaluated
0
1003 m[3][0] += m[0][0] * vx;-
1004 m[3][1] += m[1][1] * vy;-
1005 m[3][2] += m[2][2] * vz;-
1006 } else if (flagBits < Rotation) {
never executed: end of block
flagBits < RotationDescription
TRUEnever evaluated
FALSEnever evaluated
0
1007 m[3][0] += m[0][0] * vx + m[1][0] * vy;-
1008 m[3][1] += m[0][1] * vx + m[1][1] * vy;-
1009 m[3][2] += m[2][2] * vz;-
1010 } else {
never executed: end of block
0
1011 m[3][0] += m[0][0] * vx + m[1][0] * vy + m[2][0] * vz;-
1012 m[3][1] += m[0][1] * vx + m[1][1] * vy + m[2][1] * vz;-
1013 m[3][2] += m[0][2] * vx + m[1][2] * vy + m[2][2] * vz;-
1014 m[3][3] += m[0][3] * vx + m[1][3] * vy + m[2][3] * vz;-
1015 }
never executed: end of block
0
1016 flagBits |= Translation;-
1017}
never executed: end of block
0
1018#endif-
1019-
1020/*!-
1021 \overload-
1022-
1023 Multiplies this matrix by another that translates coordinates-
1024 by the components \a x, and \a y.-
1025-
1026 \sa scale(), rotate()-
1027*/-
1028void QMatrix4x4::translate(float x, float y)-
1029{-
1030 if (flagBits == Identity) {
flagBits == IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
0
1031 m[3][0] = x;-
1032 m[3][1] = y;-
1033 } else if (flagBits == Translation) {
never executed: end of block
flagBits == TranslationDescription
TRUEnever evaluated
FALSEnever evaluated
0
1034 m[3][0] += x;-
1035 m[3][1] += y;-
1036 } else if (flagBits == Scale) {
never executed: end of block
flagBits == ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1037 m[3][0] = m[0][0] * x;-
1038 m[3][1] = m[1][1] * y;-
1039 } else if (flagBits == (Translation | Scale)) {
never executed: end of block
flagBits == (T...ation | Scale)Description
TRUEnever evaluated
FALSEnever evaluated
0
1040 m[3][0] += m[0][0] * x;-
1041 m[3][1] += m[1][1] * y;-
1042 } else if (flagBits < Rotation) {
never executed: end of block
flagBits < RotationDescription
TRUEnever evaluated
FALSEnever evaluated
0
1043 m[3][0] += m[0][0] * x + m[1][0] * y;-
1044 m[3][1] += m[0][1] * x + m[1][1] * y;-
1045 } else {
never executed: end of block
0
1046 m[3][0] += m[0][0] * x + m[1][0] * y;-
1047 m[3][1] += m[0][1] * x + m[1][1] * y;-
1048 m[3][2] += m[0][2] * x + m[1][2] * y;-
1049 m[3][3] += m[0][3] * x + m[1][3] * y;-
1050 }
never executed: end of block
0
1051 flagBits |= Translation;-
1052}
never executed: end of block
0
1053-
1054/*!-
1055 \overload-
1056-
1057 Multiplies this matrix by another that translates coordinates-
1058 by the components \a x, \a y, and \a z.-
1059-
1060 \sa scale(), rotate()-
1061*/-
1062void QMatrix4x4::translate(float x, float y, float z)-
1063{-
1064 if (flagBits == Identity) {
flagBits == IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
0
1065 m[3][0] = x;-
1066 m[3][1] = y;-
1067 m[3][2] = z;-
1068 } else if (flagBits == Translation) {
never executed: end of block
flagBits == TranslationDescription
TRUEnever evaluated
FALSEnever evaluated
0
1069 m[3][0] += x;-
1070 m[3][1] += y;-
1071 m[3][2] += z;-
1072 } else if (flagBits == Scale) {
never executed: end of block
flagBits == ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1073 m[3][0] = m[0][0] * x;-
1074 m[3][1] = m[1][1] * y;-
1075 m[3][2] = m[2][2] * z;-
1076 } else if (flagBits == (Translation | Scale)) {
never executed: end of block
flagBits == (T...ation | Scale)Description
TRUEnever evaluated
FALSEnever evaluated
0
1077 m[3][0] += m[0][0] * x;-
1078 m[3][1] += m[1][1] * y;-
1079 m[3][2] += m[2][2] * z;-
1080 } else if (flagBits < Rotation) {
never executed: end of block
flagBits < RotationDescription
TRUEnever evaluated
FALSEnever evaluated
0
1081 m[3][0] += m[0][0] * x + m[1][0] * y;-
1082 m[3][1] += m[0][1] * x + m[1][1] * y;-
1083 m[3][2] += m[2][2] * z;-
1084 } else {
never executed: end of block
0
1085 m[3][0] += m[0][0] * x + m[1][0] * y + m[2][0] * z;-
1086 m[3][1] += m[0][1] * x + m[1][1] * y + m[2][1] * z;-
1087 m[3][2] += m[0][2] * x + m[1][2] * y + m[2][2] * z;-
1088 m[3][3] += m[0][3] * x + m[1][3] * y + m[2][3] * z;-
1089 }
never executed: end of block
0
1090 flagBits |= Translation;-
1091}
never executed: end of block
0
1092-
1093#ifndef QT_NO_VECTOR3D-
1094/*!-
1095 Multiples this matrix by another that rotates coordinates through-
1096 \a angle degrees about \a vector.-
1097-
1098 \sa scale(), translate()-
1099*/-
1100-
1101void QMatrix4x4::rotate(float angle, const QVector3D& vector)-
1102{-
1103 rotate(angle, vector.x(), vector.y(), vector.z());-
1104}
never executed: end of block
0
1105-
1106#endif-
1107-
1108/*!-
1109 \overload-
1110-
1111 Multiplies this matrix by another that rotates coordinates through-
1112 \a angle degrees about the vector (\a x, \a y, \a z).-
1113-
1114 \sa scale(), translate()-
1115*/-
1116void QMatrix4x4::rotate(float angle, float x, float y, float z)-
1117{-
1118 if (angle == 0.0f)
angle == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1119 return;
never executed: return;
0
1120 float c, s;-
1121 if (angle == 90.0f || angle == -270.0f) {
angle == 90.0fDescription
TRUEnever evaluated
FALSEnever evaluated
angle == -270.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1122 s = 1.0f;-
1123 c = 0.0f;-
1124 } else if (angle == -90.0f || angle == 270.0f) {
never executed: end of block
angle == -90.0fDescription
TRUEnever evaluated
FALSEnever evaluated
angle == 270.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1125 s = -1.0f;-
1126 c = 0.0f;-
1127 } else if (angle == 180.0f || angle == -180.0f) {
never executed: end of block
angle == 180.0fDescription
TRUEnever evaluated
FALSEnever evaluated
angle == -180.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1128 s = 0.0f;-
1129 c = -1.0f;-
1130 } else {
never executed: end of block
0
1131 float a = angle * M_PI / 180.0f;-
1132 c = std::cos(a);-
1133 s = std::sin(a);-
1134 }
never executed: end of block
0
1135 if (x == 0.0f) {
x == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1136 if (y == 0.0f) {
y == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1137 if (z != 0.0f) {
z != 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1138 // Rotate around the Z axis.-
1139 if (z < 0)
z < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1140 s = -s;
never executed: s = -s;
0
1141 float tmp;-
1142 m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s;-
1143 m[1][0] = m[1][0] * c - tmp * s;-
1144 m[0][1] = (tmp = m[0][1]) * c + m[1][1] * s;-
1145 m[1][1] = m[1][1] * c - tmp * s;-
1146 m[0][2] = (tmp = m[0][2]) * c + m[1][2] * s;-
1147 m[1][2] = m[1][2] * c - tmp * s;-
1148 m[0][3] = (tmp = m[0][3]) * c + m[1][3] * s;-
1149 m[1][3] = m[1][3] * c - tmp * s;-
1150-
1151 flagBits |= Rotation2D;-
1152 return;
never executed: return;
0
1153 }-
1154 } else if (z == 0.0f) {
never executed: end of block
z == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1155 // Rotate around the Y axis.-
1156 if (y < 0)
y < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1157 s = -s;
never executed: s = -s;
0
1158 float tmp;-
1159 m[2][0] = (tmp = m[2][0]) * c + m[0][0] * s;-
1160 m[0][0] = m[0][0] * c - tmp * s;-
1161 m[2][1] = (tmp = m[2][1]) * c + m[0][1] * s;-
1162 m[0][1] = m[0][1] * c - tmp * s;-
1163 m[2][2] = (tmp = m[2][2]) * c + m[0][2] * s;-
1164 m[0][2] = m[0][2] * c - tmp * s;-
1165 m[2][3] = (tmp = m[2][3]) * c + m[0][3] * s;-
1166 m[0][3] = m[0][3] * c - tmp * s;-
1167-
1168 flagBits |= Rotation;-
1169 return;
never executed: return;
0
1170 }-
1171 } else if (y == 0.0f && z == 0.0f) {
never executed: end of block
y == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
z == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1172 // Rotate around the X axis.-
1173 if (x < 0)
x < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1174 s = -s;
never executed: s = -s;
0
1175 float tmp;-
1176 m[1][0] = (tmp = m[1][0]) * c + m[2][0] * s;-
1177 m[2][0] = m[2][0] * c - tmp * s;-
1178 m[1][1] = (tmp = m[1][1]) * c + m[2][1] * s;-
1179 m[2][1] = m[2][1] * c - tmp * s;-
1180 m[1][2] = (tmp = m[1][2]) * c + m[2][2] * s;-
1181 m[2][2] = m[2][2] * c - tmp * s;-
1182 m[1][3] = (tmp = m[1][3]) * c + m[2][3] * s;-
1183 m[2][3] = m[2][3] * c - tmp * s;-
1184-
1185 flagBits |= Rotation;-
1186 return;
never executed: return;
0
1187 }-
1188-
1189 double len = double(x) * double(x) +-
1190 double(y) * double(y) +-
1191 double(z) * double(z);-
1192 if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) {
!qFuzzyCompare(len, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
!qFuzzyIsNull(len)Description
TRUEnever evaluated
FALSEnever evaluated
0
1193 len = std::sqrt(len);-
1194 x = float(double(x) / len);-
1195 y = float(double(y) / len);-
1196 z = float(double(z) / len);-
1197 }
never executed: end of block
0
1198 float ic = 1.0f - c;-
1199 QMatrix4x4 rot(1); // The "1" says to not load the identity.-
1200 rot.m[0][0] = x * x * ic + c;-
1201 rot.m[1][0] = x * y * ic - z * s;-
1202 rot.m[2][0] = x * z * ic + y * s;-
1203 rot.m[3][0] = 0.0f;-
1204 rot.m[0][1] = y * x * ic + z * s;-
1205 rot.m[1][1] = y * y * ic + c;-
1206 rot.m[2][1] = y * z * ic - x * s;-
1207 rot.m[3][1] = 0.0f;-
1208 rot.m[0][2] = x * z * ic - y * s;-
1209 rot.m[1][2] = y * z * ic + x * s;-
1210 rot.m[2][2] = z * z * ic + c;-
1211 rot.m[3][2] = 0.0f;-
1212 rot.m[0][3] = 0.0f;-
1213 rot.m[1][3] = 0.0f;-
1214 rot.m[2][3] = 0.0f;-
1215 rot.m[3][3] = 1.0f;-
1216 rot.flagBits = Rotation;-
1217 *this *= rot;-
1218}
never executed: end of block
0
1219-
1220/*!-
1221 \internal-
1222*/-
1223void QMatrix4x4::projectedRotate(float angle, float x, float y, float z)-
1224{-
1225 // Used by QGraphicsRotation::applyTo() to perform a rotation-
1226 // and projection back to 2D in a single step.-
1227 if (angle == 0.0f)
angle == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1228 return;
never executed: return;
0
1229 float c, s;-
1230 if (angle == 90.0f || angle == -270.0f) {
angle == 90.0fDescription
TRUEnever evaluated
FALSEnever evaluated
angle == -270.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1231 s = 1.0f;-
1232 c = 0.0f;-
1233 } else if (angle == -90.0f || angle == 270.0f) {
never executed: end of block
angle == -90.0fDescription
TRUEnever evaluated
FALSEnever evaluated
angle == 270.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1234 s = -1.0f;-
1235 c = 0.0f;-
1236 } else if (angle == 180.0f || angle == -180.0f) {
never executed: end of block
angle == 180.0fDescription
TRUEnever evaluated
FALSEnever evaluated
angle == -180.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1237 s = 0.0f;-
1238 c = -1.0f;-
1239 } else {
never executed: end of block
0
1240 float a = angle * M_PI / 180.0f;-
1241 c = std::cos(a);-
1242 s = std::sin(a);-
1243 }
never executed: end of block
0
1244 if (x == 0.0f) {
x == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1245 if (y == 0.0f) {
y == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1246 if (z != 0.0f) {
z != 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1247 // Rotate around the Z axis.-
1248 if (z < 0)
z < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1249 s = -s;
never executed: s = -s;
0
1250 float tmp;-
1251 m[0][0] = (tmp = m[0][0]) * c + m[1][0] * s;-
1252 m[1][0] = m[1][0] * c - tmp * s;-
1253 m[0][1] = (tmp = m[0][1]) * c + m[1][1] * s;-
1254 m[1][1] = m[1][1] * c - tmp * s;-
1255 m[0][2] = (tmp = m[0][2]) * c + m[1][2] * s;-
1256 m[1][2] = m[1][2] * c - tmp * s;-
1257 m[0][3] = (tmp = m[0][3]) * c + m[1][3] * s;-
1258 m[1][3] = m[1][3] * c - tmp * s;-
1259-
1260 flagBits |= Rotation2D;-
1261 return;
never executed: return;
0
1262 }-
1263 } else if (z == 0.0f) {
never executed: end of block
z == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1264 // Rotate around the Y axis.-
1265 if (y < 0)
y < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1266 s = -s;
never executed: s = -s;
0
1267 m[0][0] = m[0][0] * c + m[3][0] * s * inv_dist_to_plane;-
1268 m[0][1] = m[0][1] * c + m[3][1] * s * inv_dist_to_plane;-
1269 m[0][2] = m[0][2] * c + m[3][2] * s * inv_dist_to_plane;-
1270 m[0][3] = m[0][3] * c + m[3][3] * s * inv_dist_to_plane;-
1271 flagBits = General;-
1272 return;
never executed: return;
0
1273 }-
1274 } else if (y == 0.0f && z == 0.0f) {
never executed: end of block
y == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
z == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1275 // Rotate around the X axis.-
1276 if (x < 0)
x < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1277 s = -s;
never executed: s = -s;
0
1278 m[1][0] = m[1][0] * c - m[3][0] * s * inv_dist_to_plane;-
1279 m[1][1] = m[1][1] * c - m[3][1] * s * inv_dist_to_plane;-
1280 m[1][2] = m[1][2] * c - m[3][2] * s * inv_dist_to_plane;-
1281 m[1][3] = m[1][3] * c - m[3][3] * s * inv_dist_to_plane;-
1282 flagBits = General;-
1283 return;
never executed: return;
0
1284 }-
1285 double len = double(x) * double(x) +-
1286 double(y) * double(y) +-
1287 double(z) * double(z);-
1288 if (!qFuzzyCompare(len, 1.0) && !qFuzzyIsNull(len)) {
!qFuzzyCompare(len, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
!qFuzzyIsNull(len)Description
TRUEnever evaluated
FALSEnever evaluated
0
1289 len = std::sqrt(len);-
1290 x = float(double(x) / len);-
1291 y = float(double(y) / len);-
1292 z = float(double(z) / len);-
1293 }
never executed: end of block
0
1294 float ic = 1.0f - c;-
1295 QMatrix4x4 rot(1); // The "1" says to not load the identity.-
1296 rot.m[0][0] = x * x * ic + c;-
1297 rot.m[1][0] = x * y * ic - z * s;-
1298 rot.m[2][0] = 0.0f;-
1299 rot.m[3][0] = 0.0f;-
1300 rot.m[0][1] = y * x * ic + z * s;-
1301 rot.m[1][1] = y * y * ic + c;-
1302 rot.m[2][1] = 0.0f;-
1303 rot.m[3][1] = 0.0f;-
1304 rot.m[0][2] = 0.0f;-
1305 rot.m[1][2] = 0.0f;-
1306 rot.m[2][2] = 1.0f;-
1307 rot.m[3][2] = 0.0f;-
1308 rot.m[0][3] = (x * z * ic - y * s) * -inv_dist_to_plane;-
1309 rot.m[1][3] = (y * z * ic + x * s) * -inv_dist_to_plane;-
1310 rot.m[2][3] = 0.0f;-
1311 rot.m[3][3] = 1.0f;-
1312 rot.flagBits = General;-
1313 *this *= rot;-
1314}
never executed: end of block
0
1315-
1316#ifndef QT_NO_QUATERNION-
1317-
1318/*!-
1319 Multiples this matrix by another that rotates coordinates according-
1320 to a specified \a quaternion. The \a quaternion is assumed to have-
1321 been normalized.-
1322-
1323 \sa scale(), translate(), QQuaternion-
1324*/-
1325void QMatrix4x4::rotate(const QQuaternion& quaternion)-
1326{-
1327 // Algorithm from:-
1328 // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54-
1329-
1330 QMatrix4x4 m(Qt::Uninitialized);-
1331-
1332 const float f2x = quaternion.x() + quaternion.x();-
1333 const float f2y = quaternion.y() + quaternion.y();-
1334 const float f2z = quaternion.z() + quaternion.z();-
1335 const float f2xw = f2x * quaternion.scalar();-
1336 const float f2yw = f2y * quaternion.scalar();-
1337 const float f2zw = f2z * quaternion.scalar();-
1338 const float f2xx = f2x * quaternion.x();-
1339 const float f2xy = f2x * quaternion.y();-
1340 const float f2xz = f2x * quaternion.z();-
1341 const float f2yy = f2y * quaternion.y();-
1342 const float f2yz = f2y * quaternion.z();-
1343 const float f2zz = f2z * quaternion.z();-
1344-
1345 m.m[0][0] = 1.0f - (f2yy + f2zz);-
1346 m.m[1][0] = f2xy - f2zw;-
1347 m.m[2][0] = f2xz + f2yw;-
1348 m.m[3][0] = 0.0f;-
1349 m.m[0][1] = f2xy + f2zw;-
1350 m.m[1][1] = 1.0f - (f2xx + f2zz);-
1351 m.m[2][1] = f2yz - f2xw;-
1352 m.m[3][1] = 0.0f;-
1353 m.m[0][2] = f2xz - f2yw;-
1354 m.m[1][2] = f2yz + f2xw;-
1355 m.m[2][2] = 1.0f - (f2xx + f2yy);-
1356 m.m[3][2] = 0.0f;-
1357 m.m[0][3] = 0.0f;-
1358 m.m[1][3] = 0.0f;-
1359 m.m[2][3] = 0.0f;-
1360 m.m[3][3] = 1.0f;-
1361 m.flagBits = Rotation;-
1362 *this *= m;-
1363}
never executed: end of block
0
1364-
1365#endif-
1366-
1367/*!-
1368 \overload-
1369-
1370 Multiplies this matrix by another that applies an orthographic-
1371 projection for a window with boundaries specified by \a rect.-
1372 The near and far clipping planes will be -1 and 1 respectively.-
1373-
1374 \sa frustum(), perspective()-
1375*/-
1376void QMatrix4x4::ortho(const QRect& rect)-
1377{-
1378 // Note: rect.right() and rect.bottom() subtract 1 in QRect,-
1379 // which gives the location of a pixel within the rectangle,-
1380 // instead of the extent of the rectangle. We want the extent.-
1381 // QRectF expresses the extent properly.-
1382 ortho(rect.x(), rect.x() + rect.width(), rect.y() + rect.height(), rect.y(), -1.0f, 1.0f);-
1383}
never executed: end of block
0
1384-
1385/*!-
1386 \overload-
1387-
1388 Multiplies this matrix by another that applies an orthographic-
1389 projection for a window with boundaries specified by \a rect.-
1390 The near and far clipping planes will be -1 and 1 respectively.-
1391-
1392 \sa frustum(), perspective()-
1393*/-
1394void QMatrix4x4::ortho(const QRectF& rect)-
1395{-
1396 ortho(rect.left(), rect.right(), rect.bottom(), rect.top(), -1.0f, 1.0f);-
1397}
never executed: end of block
0
1398-
1399/*!-
1400 Multiplies this matrix by another that applies an orthographic-
1401 projection for a window with lower-left corner (\a left, \a bottom),-
1402 upper-right corner (\a right, \a top), and the specified \a nearPlane-
1403 and \a farPlane clipping planes.-
1404-
1405 \sa frustum(), perspective()-
1406*/-
1407void QMatrix4x4::ortho(float left, float right, float bottom, float top, float nearPlane, float farPlane)-
1408{-
1409 // Bail out if the projection volume is zero-sized.-
1410 if (left == right || bottom == top || nearPlane == farPlane)
left == rightDescription
TRUEnever evaluated
FALSEnever evaluated
bottom == topDescription
TRUEnever evaluated
FALSEnever evaluated
nearPlane == farPlaneDescription
TRUEnever evaluated
FALSEnever evaluated
0
1411 return;
never executed: return;
0
1412-
1413 // Construct the projection.-
1414 float width = right - left;-
1415 float invheight = top - bottom;-
1416 float clip = farPlane - nearPlane;-
1417 QMatrix4x4 m(1);-
1418 m.m[0][0] = 2.0f / width;-
1419 m.m[1][0] = 0.0f;-
1420 m.m[2][0] = 0.0f;-
1421 m.m[3][0] = -(left + right) / width;-
1422 m.m[0][1] = 0.0f;-
1423 m.m[1][1] = 2.0f / invheight;-
1424 m.m[2][1] = 0.0f;-
1425 m.m[3][1] = -(top + bottom) / invheight;-
1426 m.m[0][2] = 0.0f;-
1427 m.m[1][2] = 0.0f;-
1428 m.m[2][2] = -2.0f / clip;-
1429 m.m[3][2] = -(nearPlane + farPlane) / clip;-
1430 m.m[0][3] = 0.0f;-
1431 m.m[1][3] = 0.0f;-
1432 m.m[2][3] = 0.0f;-
1433 m.m[3][3] = 1.0f;-
1434 m.flagBits = Translation | Scale;-
1435-
1436 // Apply the projection.-
1437 *this *= m;-
1438}
never executed: end of block
0
1439-
1440/*!-
1441 Multiplies this matrix by another that applies a perspective-
1442 frustum projection for a window with lower-left corner (\a left, \a bottom),-
1443 upper-right corner (\a right, \a top), and the specified \a nearPlane-
1444 and \a farPlane clipping planes.-
1445-
1446 \sa ortho(), perspective()-
1447*/-
1448void QMatrix4x4::frustum(float left, float right, float bottom, float top, float nearPlane, float farPlane)-
1449{-
1450 // Bail out if the projection volume is zero-sized.-
1451 if (left == right || bottom == top || nearPlane == farPlane)
left == rightDescription
TRUEnever evaluated
FALSEnever evaluated
bottom == topDescription
TRUEnever evaluated
FALSEnever evaluated
nearPlane == farPlaneDescription
TRUEnever evaluated
FALSEnever evaluated
0
1452 return;
never executed: return;
0
1453-
1454 // Construct the projection.-
1455 QMatrix4x4 m(1);-
1456 float width = right - left;-
1457 float invheight = top - bottom;-
1458 float clip = farPlane - nearPlane;-
1459 m.m[0][0] = 2.0f * nearPlane / width;-
1460 m.m[1][0] = 0.0f;-
1461 m.m[2][0] = (left + right) / width;-
1462 m.m[3][0] = 0.0f;-
1463 m.m[0][1] = 0.0f;-
1464 m.m[1][1] = 2.0f * nearPlane / invheight;-
1465 m.m[2][1] = (top + bottom) / invheight;-
1466 m.m[3][1] = 0.0f;-
1467 m.m[0][2] = 0.0f;-
1468 m.m[1][2] = 0.0f;-
1469 m.m[2][2] = -(nearPlane + farPlane) / clip;-
1470 m.m[3][2] = -2.0f * nearPlane * farPlane / clip;-
1471 m.m[0][3] = 0.0f;-
1472 m.m[1][3] = 0.0f;-
1473 m.m[2][3] = -1.0f;-
1474 m.m[3][3] = 0.0f;-
1475 m.flagBits = General;-
1476-
1477 // Apply the projection.-
1478 *this *= m;-
1479}
never executed: end of block
0
1480-
1481/*!-
1482 Multiplies this matrix by another that applies a perspective-
1483 projection. The vertical field of view will be \a verticalAngle degrees-
1484 within a window with a given \a aspectRatio that determines the horizontal-
1485 field of view.-
1486 The projection will have the specified \a nearPlane and \a farPlane clipping-
1487 planes which are the distances from the viewer to the corresponding planes.-
1488-
1489 \sa ortho(), frustum()-
1490*/-
1491void QMatrix4x4::perspective(float verticalAngle, float aspectRatio, float nearPlane, float farPlane)-
1492{-
1493 // Bail out if the projection volume is zero-sized.-
1494 if (nearPlane == farPlane || aspectRatio == 0.0f)
nearPlane == farPlaneDescription
TRUEnever evaluated
FALSEnever evaluated
aspectRatio == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1495 return;
never executed: return;
0
1496-
1497 // Construct the projection.-
1498 QMatrix4x4 m(1);-
1499 float radians = (verticalAngle / 2.0f) * M_PI / 180.0f;-
1500 float sine = std::sin(radians);-
1501 if (sine == 0.0f)
sine == 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1502 return;
never executed: return;
0
1503 float cotan = std::cos(radians) / sine;-
1504 float clip = farPlane - nearPlane;-
1505 m.m[0][0] = cotan / aspectRatio;-
1506 m.m[1][0] = 0.0f;-
1507 m.m[2][0] = 0.0f;-
1508 m.m[3][0] = 0.0f;-
1509 m.m[0][1] = 0.0f;-
1510 m.m[1][1] = cotan;-
1511 m.m[2][1] = 0.0f;-
1512 m.m[3][1] = 0.0f;-
1513 m.m[0][2] = 0.0f;-
1514 m.m[1][2] = 0.0f;-
1515 m.m[2][2] = -(nearPlane + farPlane) / clip;-
1516 m.m[3][2] = -(2.0f * nearPlane * farPlane) / clip;-
1517 m.m[0][3] = 0.0f;-
1518 m.m[1][3] = 0.0f;-
1519 m.m[2][3] = -1.0f;-
1520 m.m[3][3] = 0.0f;-
1521 m.flagBits = General;-
1522-
1523 // Apply the projection.-
1524 *this *= m;-
1525}
never executed: end of block
0
1526-
1527#ifndef QT_NO_VECTOR3D-
1528-
1529/*!-
1530 Multiplies this matrix by a viewing matrix derived from an eye-
1531 point. The \a center value indicates the center of the view that-
1532 the \a eye is looking at. The \a up value indicates which direction-
1533 should be considered up with respect to the \a eye.-
1534-
1535 \note The \a up vector must not be parallel to the line of sight-
1536 from \a eye to \a center.-
1537*/-
1538void QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up)-
1539{-
1540 QVector3D forward = center - eye;-
1541 if (qFuzzyIsNull(forward.x()) && qFuzzyIsNull(forward.y()) && qFuzzyIsNull(forward.z()))
qFuzzyIsNull(forward.x())Description
TRUEnever evaluated
FALSEnever evaluated
qFuzzyIsNull(forward.y())Description
TRUEnever evaluated
FALSEnever evaluated
qFuzzyIsNull(forward.z())Description
TRUEnever evaluated
FALSEnever evaluated
0
1542 return;
never executed: return;
0
1543-
1544 forward.normalize();-
1545 QVector3D side = QVector3D::crossProduct(forward, up).normalized();-
1546 QVector3D upVector = QVector3D::crossProduct(side, forward);-
1547-
1548 QMatrix4x4 m(1);-
1549 m.m[0][0] = side.x();-
1550 m.m[1][0] = side.y();-
1551 m.m[2][0] = side.z();-
1552 m.m[3][0] = 0.0f;-
1553 m.m[0][1] = upVector.x();-
1554 m.m[1][1] = upVector.y();-
1555 m.m[2][1] = upVector.z();-
1556 m.m[3][1] = 0.0f;-
1557 m.m[0][2] = -forward.x();-
1558 m.m[1][2] = -forward.y();-
1559 m.m[2][2] = -forward.z();-
1560 m.m[3][2] = 0.0f;-
1561 m.m[0][3] = 0.0f;-
1562 m.m[1][3] = 0.0f;-
1563 m.m[2][3] = 0.0f;-
1564 m.m[3][3] = 1.0f;-
1565 m.flagBits = Rotation;-
1566-
1567 *this *= m;-
1568 translate(-eye);-
1569}
never executed: end of block
0
1570-
1571#endif-
1572-
1573/*!-
1574 \fn void QMatrix4x4::viewport(const QRectF &rect)-
1575 \overload-
1576-
1577 Sets up viewport transform for viewport bounded by \a rect and with near and far set-
1578 to 0 and 1 respectively.-
1579*/-
1580-
1581/*!-
1582 Multiplies this matrix by another that performs the scale and bias-
1583 transformation used by OpenGL to transform from normalized device-
1584 coordinates (NDC) to viewport (window) coordinates. That is it maps-
1585 points from the cube ranging over [-1, 1] in each dimension to the-
1586 viewport with it's near-lower-left corner at (\a left, \a bottom, \a nearPlane)-
1587 and with size (\a width, \a height, \a farPlane - \a nearPlane).-
1588-
1589 This matches the transform used by the fixed function OpenGL viewport-
1590 transform controlled by the functions glViewport() and glDepthRange().-
1591 */-
1592void QMatrix4x4::viewport(float left, float bottom, float width, float height, float nearPlane, float farPlane)-
1593{-
1594 const float w2 = width / 2.0f;-
1595 const float h2 = height / 2.0f;-
1596-
1597 QMatrix4x4 m(1);-
1598 m.m[0][0] = w2;-
1599 m.m[1][0] = 0.0f;-
1600 m.m[2][0] = 0.0f;-
1601 m.m[3][0] = left + w2;-
1602 m.m[0][1] = 0.0f;-
1603 m.m[1][1] = h2;-
1604 m.m[2][1] = 0.0f;-
1605 m.m[3][1] = bottom + h2;-
1606 m.m[0][2] = 0.0f;-
1607 m.m[1][2] = 0.0f;-
1608 m.m[2][2] = (farPlane - nearPlane) / 2.0f;-
1609 m.m[3][2] = (nearPlane + farPlane) / 2.0f;-
1610 m.m[0][3] = 0.0f;-
1611 m.m[1][3] = 0.0f;-
1612 m.m[2][3] = 0.0f;-
1613 m.m[3][3] = 1.0f;-
1614 m.flagBits = General;-
1615-
1616 *this *= m;-
1617}
never executed: end of block
0
1618-
1619/*!-
1620 \deprecated-
1621-
1622 Flips between right-handed and left-handed coordinate systems-
1623 by multiplying the y and z co-ordinates by -1. This is normally-
1624 used to create a left-handed orthographic view without scaling-
1625 the viewport as ortho() does.-
1626-
1627 \sa ortho()-
1628*/-
1629void QMatrix4x4::flipCoordinates()-
1630{-
1631 // Multiplying the y and z coordinates with -1 does NOT flip between right-handed and-
1632 // left-handed coordinate systems, it just rotates 180 degrees around the x axis, so-
1633 // I'm deprecating this function.-
1634 if (flagBits < Rotation2D) {
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
1635 // Translation | Scale-
1636 m[1][1] = -m[1][1];-
1637 m[2][2] = -m[2][2];-
1638 } else {
never executed: end of block
0
1639 m[1][0] = -m[1][0];-
1640 m[1][1] = -m[1][1];-
1641 m[1][2] = -m[1][2];-
1642 m[1][3] = -m[1][3];-
1643 m[2][0] = -m[2][0];-
1644 m[2][1] = -m[2][1];-
1645 m[2][2] = -m[2][2];-
1646 m[2][3] = -m[2][3];-
1647 }
never executed: end of block
0
1648 flagBits |= Scale;-
1649}
never executed: end of block
0
1650-
1651/*!-
1652 Retrieves the 16 items in this matrix and copies them to \a values-
1653 in row-major order.-
1654*/-
1655void QMatrix4x4::copyDataTo(float *values) const-
1656{-
1657 for (int row = 0; row < 4; ++row)
row < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1658 for (int col = 0; col < 4; ++col)
col < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1659 values[row * 4 + col] = float(m[col][row]);
never executed: values[row * 4 + col] = float(m[col][row]);
0
1660}
never executed: end of block
0
1661-
1662/*!-
1663 Returns the conventional Qt 2D affine transformation matrix that-
1664 corresponds to this matrix. It is assumed that this matrix-
1665 only contains 2D affine transformation elements.-
1666-
1667 \sa toTransform()-
1668*/-
1669QMatrix QMatrix4x4::toAffine() const-
1670{-
1671 return QMatrix(m[0][0], m[0][1],
never executed: return QMatrix(m[0][0], m[0][1], m[1][0], m[1][1], m[3][0], m[3][1]);
0
1672 m[1][0], m[1][1],
never executed: return QMatrix(m[0][0], m[0][1], m[1][0], m[1][1], m[3][0], m[3][1]);
0
1673 m[3][0], m[3][1]);
never executed: return QMatrix(m[0][0], m[0][1], m[1][0], m[1][1], m[3][0], m[3][1]);
0
1674}-
1675-
1676/*!-
1677 Returns the conventional Qt 2D transformation matrix that-
1678 corresponds to this matrix.-
1679-
1680 The returned QTransform is formed by simply dropping the-
1681 third row and third column of the QMatrix4x4. This is suitable-
1682 for implementing orthographic projections where the z co-ordinate-
1683 should be dropped rather than projected.-
1684-
1685 \sa toAffine()-
1686*/-
1687QTransform QMatrix4x4::toTransform() const-
1688{-
1689 return QTransform(m[0][0], m[0][1], m[0][3],
never executed: return QTransform(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]);
0
1690 m[1][0], m[1][1], m[1][3],
never executed: return QTransform(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]);
0
1691 m[3][0], m[3][1], m[3][3]);
never executed: return QTransform(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]);
0
1692}-
1693-
1694/*!-
1695 Returns the conventional Qt 2D transformation matrix that-
1696 corresponds to this matrix.-
1697-
1698 If \a distanceToPlane is non-zero, it indicates a projection-
1699 factor to use to adjust for the z co-ordinate. The value of-
1700 1024 corresponds to the projection factor used-
1701 by QTransform::rotate() for the x and y axes.-
1702-
1703 If \a distanceToPlane is zero, then the returned QTransform-
1704 is formed by simply dropping the third row and third column-
1705 of the QMatrix4x4. This is suitable for implementing-
1706 orthographic projections where the z co-ordinate should-
1707 be dropped rather than projected.-
1708-
1709 \sa toAffine()-
1710*/-
1711QTransform QMatrix4x4::toTransform(float distanceToPlane) const-
1712{-
1713 if (distanceToPlane == 1024.0f) {
distanceToPlane == 1024.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1714 // Optimize the common case with constants.-
1715 return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * inv_dist_to_plane,
never executed: return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * inv_dist_to_plane, m[1][0], m[1][1], m[1][3] - m[1][2] * inv_dist_to_plane, m[3][0], m[3][1], m[3][3] - m[3][2] * inv_dist_to_plane);
0
1716 m[1][0], m[1][1], m[1][3] - m[1][2] * inv_dist_to_plane,
never executed: return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * inv_dist_to_plane, m[1][0], m[1][1], m[1][3] - m[1][2] * inv_dist_to_plane, m[3][0], m[3][1], m[3][3] - m[3][2] * inv_dist_to_plane);
0
1717 m[3][0], m[3][1], m[3][3] - m[3][2] * inv_dist_to_plane);
never executed: return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * inv_dist_to_plane, m[1][0], m[1][1], m[1][3] - m[1][2] * inv_dist_to_plane, m[3][0], m[3][1], m[3][3] - m[3][2] * inv_dist_to_plane);
0
1718 } else if (distanceToPlane != 0.0f) {
distanceToPlane != 0.0fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1719 // The following projection matrix is pre-multiplied with "matrix":-
1720 // | 1 0 0 0 |-
1721 // | 0 1 0 0 |-
1722 // | 0 0 1 0 |-
1723 // | 0 0 d 1 |-
1724 // where d = -1 / distanceToPlane. After projection, row 3 and-
1725 // column 3 are dropped to form the final QTransform.-
1726 float d = 1.0f / distanceToPlane;-
1727 return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * d,
never executed: return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * d, m[1][0], m[1][1], m[1][3] - m[1][2] * d, m[3][0], m[3][1], m[3][3] - m[3][2] * d);
0
1728 m[1][0], m[1][1], m[1][3] - m[1][2] * d,
never executed: return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * d, m[1][0], m[1][1], m[1][3] - m[1][2] * d, m[3][0], m[3][1], m[3][3] - m[3][2] * d);
0
1729 m[3][0], m[3][1], m[3][3] - m[3][2] * d);
never executed: return QTransform(m[0][0], m[0][1], m[0][3] - m[0][2] * d, m[1][0], m[1][1], m[1][3] - m[1][2] * d, m[3][0], m[3][1], m[3][3] - m[3][2] * d);
0
1730 } else {-
1731 // Orthographic projection: drop row 3 and column 3.-
1732 return QTransform(m[0][0], m[0][1], m[0][3],
never executed: return QTransform(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]);
0
1733 m[1][0], m[1][1], m[1][3],
never executed: return QTransform(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]);
0
1734 m[3][0], m[3][1], m[3][3]);
never executed: return QTransform(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], m[3][3]);
0
1735 }-
1736}-
1737-
1738/*!-
1739 \fn QPoint QMatrix4x4::map(const QPoint& point) const-
1740-
1741 Maps \a point by multiplying this matrix by \a point.-
1742-
1743 \sa mapRect()-
1744*/-
1745-
1746/*!-
1747 \fn QPointF QMatrix4x4::map(const QPointF& point) const-
1748-
1749 Maps \a point by multiplying this matrix by \a point.-
1750-
1751 \sa mapRect()-
1752*/-
1753-
1754#ifndef QT_NO_VECTOR3D-
1755-
1756/*!-
1757 \fn QVector3D QMatrix4x4::map(const QVector3D& point) const-
1758-
1759 Maps \a point by multiplying this matrix by \a point.-
1760-
1761 \sa mapRect(), mapVector()-
1762*/-
1763-
1764/*!-
1765 \fn QVector3D QMatrix4x4::mapVector(const QVector3D& vector) const-
1766-
1767 Maps \a vector by multiplying the top 3x3 portion of this matrix-
1768 by \a vector. The translation and projection components of-
1769 this matrix are ignored.-
1770-
1771 \sa map()-
1772*/-
1773-
1774#endif-
1775-
1776#ifndef QT_NO_VECTOR4D-
1777-
1778/*!-
1779 \fn QVector4D QMatrix4x4::map(const QVector4D& point) const;-
1780-
1781 Maps \a point by multiplying this matrix by \a point.-
1782-
1783 \sa mapRect()-
1784*/-
1785-
1786#endif-
1787-
1788/*!-
1789 Maps \a rect by multiplying this matrix by the corners-
1790 of \a rect and then forming a new rectangle from the results.-
1791 The returned rectangle will be an ordinary 2D rectangle-
1792 with sides parallel to the horizontal and vertical axes.-
1793-
1794 \sa map()-
1795*/-
1796QRect QMatrix4x4::mapRect(const QRect& rect) const-
1797{-
1798 if (flagBits < Scale) {
flagBits < ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1799 // Translation-
1800 return QRect(qRound(rect.x() + m[3][0]),
never executed: return QRect(qRound(rect.x() + m[3][0]), qRound(rect.y() + m[3][1]), rect.width(), rect.height());
0
1801 qRound(rect.y() + m[3][1]),
never executed: return QRect(qRound(rect.x() + m[3][0]), qRound(rect.y() + m[3][1]), rect.width(), rect.height());
0
1802 rect.width(), rect.height());
never executed: return QRect(qRound(rect.x() + m[3][0]), qRound(rect.y() + m[3][1]), rect.width(), rect.height());
0
1803 } else if (flagBits < Rotation2D) {
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
1804 // Translation | Scale-
1805 float x = rect.x() * m[0][0] + m[3][0];-
1806 float y = rect.y() * m[1][1] + m[3][1];-
1807 float w = rect.width() * m[0][0];-
1808 float h = rect.height() * m[1][1];-
1809 if (w < 0) {
w < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1810 w = -w;-
1811 x -= w;-
1812 }
never executed: end of block
0
1813 if (h < 0) {
h < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1814 h = -h;-
1815 y -= h;-
1816 }
never executed: end of block
0
1817 return QRect(qRound(x), qRound(y), qRound(w), qRound(h));
never executed: return QRect(qRound(x), qRound(y), qRound(w), qRound(h));
0
1818 }-
1819-
1820 QPoint tl = map(rect.topLeft());-
1821 QPoint tr = map(QPoint(rect.x() + rect.width(), rect.y()));-
1822 QPoint bl = map(QPoint(rect.x(), rect.y() + rect.height()));-
1823 QPoint br = map(QPoint(rect.x() + rect.width(),-
1824 rect.y() + rect.height()));-
1825-
1826 int xmin = qMin(qMin(tl.x(), tr.x()), qMin(bl.x(), br.x()));-
1827 int xmax = qMax(qMax(tl.x(), tr.x()), qMax(bl.x(), br.x()));-
1828 int ymin = qMin(qMin(tl.y(), tr.y()), qMin(bl.y(), br.y()));-
1829 int ymax = qMax(qMax(tl.y(), tr.y()), qMax(bl.y(), br.y()));-
1830-
1831 return QRect(xmin, ymin, xmax - xmin, ymax - ymin);
never executed: return QRect(xmin, ymin, xmax - xmin, ymax - ymin);
0
1832}-
1833-
1834/*!-
1835 Maps \a rect by multiplying this matrix by the corners-
1836 of \a rect and then forming a new rectangle from the results.-
1837 The returned rectangle will be an ordinary 2D rectangle-
1838 with sides parallel to the horizontal and vertical axes.-
1839-
1840 \sa map()-
1841*/-
1842QRectF QMatrix4x4::mapRect(const QRectF& rect) const-
1843{-
1844 if (flagBits < Scale) {
flagBits < ScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1845 // Translation-
1846 return rect.translated(m[3][0], m[3][1]);
never executed: return rect.translated(m[3][0], m[3][1]);
0
1847 } else if (flagBits < Rotation2D) {
flagBits < Rotation2DDescription
TRUEnever evaluated
FALSEnever evaluated
0
1848 // Translation | Scale-
1849 float x = rect.x() * m[0][0] + m[3][0];-
1850 float y = rect.y() * m[1][1] + m[3][1];-
1851 float w = rect.width() * m[0][0];-
1852 float h = rect.height() * m[1][1];-
1853 if (w < 0) {
w < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1854 w = -w;-
1855 x -= w;-
1856 }
never executed: end of block
0
1857 if (h < 0) {
h < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1858 h = -h;-
1859 y -= h;-
1860 }
never executed: end of block
0
1861 return QRectF(x, y, w, h);
never executed: return QRectF(x, y, w, h);
0
1862 }-
1863-
1864 QPointF tl = map(rect.topLeft()); QPointF tr = map(rect.topRight());-
1865 QPointF bl = map(rect.bottomLeft()); QPointF br = map(rect.bottomRight());-
1866-
1867 float xmin = qMin(qMin(tl.x(), tr.x()), qMin(bl.x(), br.x()));-
1868 float xmax = qMax(qMax(tl.x(), tr.x()), qMax(bl.x(), br.x()));-
1869 float ymin = qMin(qMin(tl.y(), tr.y()), qMin(bl.y(), br.y()));-
1870 float ymax = qMax(qMax(tl.y(), tr.y()), qMax(bl.y(), br.y()));-
1871-
1872 return QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax));
never executed: return QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax));
0
1873}-
1874-
1875/*!-
1876 \fn float *QMatrix4x4::data()-
1877-
1878 Returns a pointer to the raw data of this matrix.-
1879-
1880 \sa constData(), optimize()-
1881*/-
1882-
1883/*!-
1884 \fn const float *QMatrix4x4::data() const-
1885-
1886 Returns a constant pointer to the raw data of this matrix.-
1887 This raw data is stored in column-major format.-
1888-
1889 \sa constData()-
1890*/-
1891-
1892/*!-
1893 \fn const float *QMatrix4x4::constData() const-
1894-
1895 Returns a constant pointer to the raw data of this matrix.-
1896 This raw data is stored in column-major format.-
1897-
1898 \sa data()-
1899*/-
1900-
1901// Helper routine for inverting orthonormal matrices that consist-
1902// of just rotations and translations.-
1903QMatrix4x4 QMatrix4x4::orthonormalInverse() const-
1904{-
1905 QMatrix4x4 result(1); // The '1' says not to load identity-
1906-
1907 result.m[0][0] = m[0][0];-
1908 result.m[1][0] = m[0][1];-
1909 result.m[2][0] = m[0][2];-
1910-
1911 result.m[0][1] = m[1][0];-
1912 result.m[1][1] = m[1][1];-
1913 result.m[2][1] = m[1][2];-
1914-
1915 result.m[0][2] = m[2][0];-
1916 result.m[1][2] = m[2][1];-
1917 result.m[2][2] = m[2][2];-
1918-
1919 result.m[0][3] = 0.0f;-
1920 result.m[1][3] = 0.0f;-
1921 result.m[2][3] = 0.0f;-
1922-
1923 result.m[3][0] = -(result.m[0][0] * m[3][0] + result.m[1][0] * m[3][1] + result.m[2][0] * m[3][2]);-
1924 result.m[3][1] = -(result.m[0][1] * m[3][0] + result.m[1][1] * m[3][1] + result.m[2][1] * m[3][2]);-
1925 result.m[3][2] = -(result.m[0][2] * m[3][0] + result.m[1][2] * m[3][1] + result.m[2][2] * m[3][2]);-
1926 result.m[3][3] = 1.0f;-
1927-
1928 result.flagBits = flagBits;-
1929-
1930 return result;
never executed: return result;
0
1931}-
1932-
1933/*!-
1934 Optimize the usage of this matrix from its current elements.-
1935-
1936 Some operations such as translate(), scale(), and rotate() can be-
1937 performed more efficiently if the matrix being modified is already-
1938 known to be the identity, a previous translate(), a previous-
1939 scale(), etc.-
1940-
1941 Normally the QMatrix4x4 class keeps track of this special type internally-
1942 as operations are performed. However, if the matrix is modified-
1943 directly with operator()() or data(), then QMatrix4x4 will lose track of-
1944 the special type and will revert to the safest but least efficient-
1945 operations thereafter.-
1946-
1947 By calling optimize() after directly modifying the matrix,-
1948 the programmer can force QMatrix4x4 to recover the special type if-
1949 the elements appear to conform to one of the known optimized types.-
1950-
1951 \sa operator()(), data(), translate()-
1952*/-
1953void QMatrix4x4::optimize()-
1954{-
1955 // If the last row is not (0, 0, 0, 1), the matrix is not a special type.-
1956 flagBits = General;-
1957 if (m[0][3] != 0 || m[1][3] != 0 || m[2][3] != 0 || m[3][3] != 1)
m[0][3] != 0Description
TRUEnever evaluated
FALSEnever evaluated
m[1][3] != 0Description
TRUEnever evaluated
FALSEnever evaluated
m[2][3] != 0Description
TRUEnever evaluated
FALSEnever evaluated
m[3][3] != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1958 return;
never executed: return;
0
1959-
1960 flagBits &= ~Perspective;-
1961-
1962 // If the last column is (0, 0, 0, 1), then there is no translation.-
1963 if (m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0)
m[3][0] == 0Description
TRUEnever evaluated
FALSEnever evaluated
m[3][1] == 0Description
TRUEnever evaluated
FALSEnever evaluated
m[3][2] == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1964 flagBits &= ~Translation;
never executed: flagBits &= ~Translation;
0
1965-
1966 // If the two first elements of row 3 and column 3 are 0, then any rotation must be about Z.-
1967 if (!m[0][2] && !m[1][2] && !m[2][0] && !m[2][1]) {
!m[0][2]Description
TRUEnever evaluated
FALSEnever evaluated
!m[1][2]Description
TRUEnever evaluated
FALSEnever evaluated
!m[2][0]Description
TRUEnever evaluated
FALSEnever evaluated
!m[2][1]Description
TRUEnever evaluated
FALSEnever evaluated
0
1968 flagBits &= ~Rotation;-
1969 // If the six non-diagonal elements in the top left 3x3 matrix are 0, there is no rotation.-
1970 if (!m[0][1] && !m[1][0]) {
!m[0][1]Description
TRUEnever evaluated
FALSEnever evaluated
!m[1][0]Description
TRUEnever evaluated
FALSEnever evaluated
0
1971 flagBits &= ~Rotation2D;-
1972 // Check for identity.-
1973 if (m[0][0] == 1 && m[1][1] == 1 && m[2][2] == 1)
m[0][0] == 1Description
TRUEnever evaluated
FALSEnever evaluated
m[1][1] == 1Description
TRUEnever evaluated
FALSEnever evaluated
m[2][2] == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1974 flagBits &= ~Scale;
never executed: flagBits &= ~Scale;
0
1975 } else {
never executed: end of block
0
1976 // If the columns are orthonormal and form a right-handed system, then there is no scale.-
1977 double mm[4][4];-
1978 copyToDoubles(m, mm);-
1979 double det = matrixDet2(mm, 0, 1, 0, 1);-
1980 double lenX = mm[0][0] * mm[0][0] + mm[0][1] * mm[0][1];-
1981 double lenY = mm[1][0] * mm[1][0] + mm[1][1] * mm[1][1];-
1982 double lenZ = mm[2][2];-
1983 if (qFuzzyCompare(det, 1.0) && qFuzzyCompare(lenX, 1.0)
qFuzzyCompare(det, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
qFuzzyCompare(lenX, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1984 && qFuzzyCompare(lenY, 1.0) && qFuzzyCompare(lenZ, 1.0))
qFuzzyCompare(lenY, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
qFuzzyCompare(lenZ, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1985 {-
1986 flagBits &= ~Scale;-
1987 }
never executed: end of block
0
1988 }
never executed: end of block
0
1989 } else {-
1990 // If the columns are orthonormal and form a right-handed system, then there is no scale.-
1991 double mm[4][4];-
1992 copyToDoubles(m, mm);-
1993 double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);-
1994 double lenX = mm[0][0] * mm[0][0] + mm[0][1] * mm[0][1] + mm[0][2] * mm[0][2];-
1995 double lenY = mm[1][0] * mm[1][0] + mm[1][1] * mm[1][1] + mm[1][2] * mm[1][2];-
1996 double lenZ = mm[2][0] * mm[2][0] + mm[2][1] * mm[2][1] + mm[2][2] * mm[2][2];-
1997 if (qFuzzyCompare(det, 1.0) && qFuzzyCompare(lenX, 1.0)
qFuzzyCompare(det, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
qFuzzyCompare(lenX, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1998 && qFuzzyCompare(lenY, 1.0) && qFuzzyCompare(lenZ, 1.0))
qFuzzyCompare(lenY, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
qFuzzyCompare(lenZ, 1.0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1999 {-
2000 flagBits &= ~Scale;-
2001 }
never executed: end of block
0
2002 }
never executed: end of block
0
2003}-
2004-
2005/*!-
2006 Returns the matrix as a QVariant.-
2007*/-
2008QMatrix4x4::operator QVariant() const-
2009{-
2010 return QVariant(QVariant::Matrix4x4, this);
never executed: return QVariant(QVariant::Matrix4x4, this);
0
2011}-
2012-
2013#ifndef QT_NO_DEBUG_STREAM-
2014-
2015QDebug operator<<(QDebug dbg, const QMatrix4x4 &m)-
2016{-
2017 QDebugStateSaver saver(dbg);-
2018 // Create a string that represents the matrix type.-
2019 QByteArray bits;-
2020 if (m.flagBits == QMatrix4x4::Identity) {
m.flagBits == ...x4x4::IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
0
2021 bits = "Identity";-
2022 } else if (m.flagBits == QMatrix4x4::General) {
never executed: end of block
m.flagBits == ...ix4x4::GeneralDescription
TRUEnever evaluated
FALSEnever evaluated
0
2023 bits = "General";-
2024 } else {
never executed: end of block
0
2025 if ((m.flagBits & QMatrix4x4::Translation) != 0)
(m.flagBits & ...nslation) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2026 bits += "Translation,";
never executed: bits += "Translation,";
0
2027 if ((m.flagBits & QMatrix4x4::Scale) != 0)
(m.flagBits & ...4::Scale) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2028 bits += "Scale,";
never executed: bits += "Scale,";
0
2029 if ((m.flagBits & QMatrix4x4::Rotation2D) != 0)
(m.flagBits & ...tation2D) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2030 bits += "Rotation2D,";
never executed: bits += "Rotation2D,";
0
2031 if ((m.flagBits & QMatrix4x4::Rotation) != 0)
(m.flagBits & ...Rotation) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2032 bits += "Rotation,";
never executed: bits += "Rotation,";
0
2033 if ((m.flagBits & QMatrix4x4::Perspective) != 0)
(m.flagBits & ...spective) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2034 bits += "Perspective,";
never executed: bits += "Perspective,";
0
2035 if (bits.size() > 0)
bits.size() > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2036 bits = bits.left(bits.size() - 1);
never executed: bits = bits.left(bits.size() - 1);
0
2037 }
never executed: end of block
0
2038-
2039 // Output in row-major order because it is more human-readable.-
2040 dbg.nospace() << "QMatrix4x4(type:" << bits.constData() << endl-
2041 << qSetFieldWidth(10)-
2042 << m(0, 0) << m(0, 1) << m(0, 2) << m(0, 3) << endl-
2043 << m(1, 0) << m(1, 1) << m(1, 2) << m(1, 3) << endl-
2044 << m(2, 0) << m(2, 1) << m(2, 2) << m(2, 3) << endl-
2045 << m(3, 0) << m(3, 1) << m(3, 2) << m(3, 3) << endl-
2046 << qSetFieldWidth(0) << ')';-
2047 return dbg;
never executed: return dbg;
0
2048}-
2049-
2050#endif-
2051-
2052#ifndef QT_NO_DATASTREAM-
2053-
2054/*!-
2055 \fn QDataStream &operator<<(QDataStream &stream, const QMatrix4x4 &matrix)-
2056 \relates QMatrix4x4-
2057-
2058 Writes the given \a matrix to the given \a stream and returns a-
2059 reference to the stream.-
2060-
2061 \sa {Serializing Qt Data Types}-
2062*/-
2063-
2064QDataStream &operator<<(QDataStream &stream, const QMatrix4x4 &matrix)-
2065{-
2066 for (int row = 0; row < 4; ++row)
row < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2067 for (int col = 0; col < 4; ++col)
col < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2068 stream << matrix(row, col);
never executed: stream << matrix(row, col);
0
2069 return stream;
never executed: return stream;
0
2070}-
2071-
2072/*!-
2073 \fn QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix)-
2074 \relates QMatrix4x4-
2075-
2076 Reads a 4x4 matrix from the given \a stream into the given \a matrix-
2077 and returns a reference to the stream.-
2078-
2079 \sa {Serializing Qt Data Types}-
2080*/-
2081-
2082QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix)-
2083{-
2084 float x;-
2085 for (int row = 0; row < 4; ++row) {
row < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2086 for (int col = 0; col < 4; ++col) {
col < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2087 stream >> x;-
2088 matrix(row, col) = x;-
2089 }
never executed: end of block
0
2090 }
never executed: end of block
0
2091 matrix.optimize();-
2092 return stream;
never executed: return stream;
0
2093}-
2094-
2095#endif // QT_NO_DATASTREAM-
2096-
2097#endif // QT_NO_MATRIX4X4-
2098-
2099QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9