source: trunk/src/gui/math3d/qgenericmatrix.h@ 855

Last change on this file since 855 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 13.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QGENERICMATRIX_H
43#define QGENERICMATRIX_H
44
45#include <QtCore/qmetatype.h>
46#include <QtCore/qdebug.h>
47#include <QtCore/qdatastream.h>
48
49QT_BEGIN_HEADER
50
51QT_BEGIN_NAMESPACE
52
53QT_MODULE(Gui)
54
55template <int N, int M, typename T>
56class QGenericMatrix
57{
58public:
59 QGenericMatrix();
60 QGenericMatrix(const QGenericMatrix<N, M, T>& other);
61 explicit QGenericMatrix(const T *values);
62
63 const T& operator()(int row, int column) const;
64 T& operator()(int row, int column);
65
66 bool isIdentity() const;
67 void setToIdentity();
68
69 void fill(T value);
70
71 QGenericMatrix<M, N, T> transposed() const;
72
73 QGenericMatrix<N, M, T>& operator+=(const QGenericMatrix<N, M, T>& other);
74 QGenericMatrix<N, M, T>& operator-=(const QGenericMatrix<N, M, T>& other);
75 QGenericMatrix<N, M, T>& operator*=(T factor);
76 QGenericMatrix<N, M, T>& operator/=(T divisor);
77 bool operator==(const QGenericMatrix<N, M, T>& other) const;
78 bool operator!=(const QGenericMatrix<N, M, T>& other) const;
79
80 void copyDataTo(T *values) const;
81
82 T *data() { return m[0]; }
83 const T *data() const { return m[0]; }
84 const T *constData() const { return m[0]; }
85
86#if !defined(Q_NO_TEMPLATE_FRIENDS)
87 template<int NN, int MM, typename TT>
88 friend QGenericMatrix<NN, MM, TT> operator+(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
89 template<int NN, int MM, typename TT>
90 friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
91 template<int NN, int M1, int M2, typename TT>
92 friend QGenericMatrix<M1, M2, TT> operator*(const QGenericMatrix<NN, M2, TT>& m1, const QGenericMatrix<M1, NN, TT>& m2);
93 template<int NN, int MM, typename TT>
94 friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& matrix);
95 template<int NN, int MM, typename TT>
96 friend QGenericMatrix<NN, MM, TT> operator*(TT factor, const QGenericMatrix<NN, MM, TT>& matrix);
97 template<int NN, int MM, typename TT>
98 friend QGenericMatrix<NN, MM, TT> operator*(const QGenericMatrix<NN, MM, TT>& matrix, TT factor);
99 template<int NN, int MM, typename TT>
100 friend QGenericMatrix<NN, MM, TT> operator/(const QGenericMatrix<NN, MM, TT>& matrix, TT divisor);
101
102private:
103#endif
104 T m[N][M]; // Column-major order to match OpenGL.
105
106 QGenericMatrix(int) {} // Construct without initializing identity matrix.
107
108#if !defined(Q_NO_TEMPLATE_FRIENDS)
109 template <int NN, int MM, typename TT>
110 friend class QGenericMatrix;
111#endif
112};
113
114template <int N, int M, typename T>
115Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix()
116{
117 setToIdentity();
118}
119
120template <int N, int M, typename T>
121Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const QGenericMatrix<N, M, T>& other)
122{
123 for (int col = 0; col < N; ++col)
124 for (int row = 0; row < M; ++row)
125 m[col][row] = other.m[col][row];
126}
127
128template <int N, int M, typename T>
129Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const T *values)
130{
131 for (int col = 0; col < N; ++col)
132 for (int row = 0; row < M; ++row)
133 m[col][row] = values[row * N + col];
134}
135
136template <int N, int M, typename T>
137Q_INLINE_TEMPLATE const T& QGenericMatrix<N, M, T>::operator()(int row, int column) const
138{
139 Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
140 return m[column][row];
141}
142
143template <int N, int M, typename T>
144Q_INLINE_TEMPLATE T& QGenericMatrix<N, M, T>::operator()(int row, int column)
145{
146 Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
147 return m[column][row];
148}
149
150template <int N, int M, typename T>
151Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const
152{
153 for (int col = 0; col < N; ++col) {
154 for (int row = 0; row < M; ++row) {
155 if (row == col) {
156 if (m[col][row] != 1.0f)
157 return false;
158 } else {
159 if (m[col][row] != 0.0f)
160 return false;
161 }
162 }
163 }
164 return true;
165}
166
167template <int N, int M, typename T>
168Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setToIdentity()
169{
170 for (int col = 0; col < N; ++col) {
171 for (int row = 0; row < M; ++row) {
172 if (row == col)
173 m[col][row] = 1.0f;
174 else
175 m[col][row] = 0.0f;
176 }
177 }
178}
179
180template <int N, int M, typename T>
181Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::fill(T value)
182{
183 for (int col = 0; col < N; ++col)
184 for (int row = 0; row < M; ++row)
185 m[col][row] = value;
186}
187
188template <int N, int M, typename T>
189Q_OUTOFLINE_TEMPLATE QGenericMatrix<M, N, T> QGenericMatrix<N, M, T>::transposed() const
190{
191 QGenericMatrix<M, N, T> result(1);
192 for (int row = 0; row < M; ++row)
193 for (int col = 0; col < N; ++col)
194 result.m[row][col] = m[col][row];
195 return result;
196}
197
198template <int N, int M, typename T>
199Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator+=(const QGenericMatrix<N, M, T>& other)
200{
201 for (int row = 0; row < M; ++row)
202 for (int col = 0; col < N; ++col)
203 m[col][row] += other.m[col][row];
204 return *this;
205}
206
207template <int N, int M, typename T>
208Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator-=(const QGenericMatrix<N, M, T>& other)
209{
210 for (int row = 0; row < M; ++row)
211 for (int col = 0; col < N; ++col)
212 m[col][row] -= other.m[col][row];
213 return *this;
214}
215
216template <int N, int M, typename T>
217Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator*=(T factor)
218{
219 for (int row = 0; row < M; ++row)
220 for (int col = 0; col < N; ++col)
221 m[col][row] *= factor;
222 return *this;
223}
224
225template <int N, int M, typename T>
226Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator==(const QGenericMatrix<N, M, T>& other) const
227{
228 for (int row = 0; row < M; ++row)
229 for (int col = 0; col < N; ++col) {
230 if (m[col][row] != other.m[col][row])
231 return false;
232 }
233 return true;
234}
235
236template <int N, int M, typename T>
237Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator!=(const QGenericMatrix<N, M, T>& other) const
238{
239 for (int row = 0; row < M; ++row)
240 for (int col = 0; col < N; ++col) {
241 if (m[col][row] != other.m[col][row])
242 return true;
243 }
244 return false;
245}
246
247template <int N, int M, typename T>
248Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator/=(T divisor)
249{
250 for (int row = 0; row < M; ++row)
251 for (int col = 0; col < N; ++col)
252 m[col][row] /= divisor;
253 return *this;
254}
255
256template <int N, int M, typename T>
257Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator+(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
258{
259 QGenericMatrix<N, M, T> result(1);
260 for (int row = 0; row < M; ++row)
261 for (int col = 0; col < N; ++col)
262 result.m[col][row] = m1.m[col][row] + m2.m[col][row];
263 return result;
264}
265
266template <int N, int M, typename T>
267Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
268{
269 QGenericMatrix<N, M, T> result(1);
270 for (int row = 0; row < M; ++row)
271 for (int col = 0; col < N; ++col)
272 result.m[col][row] = m1.m[col][row] - m2.m[col][row];
273 return result;
274}
275
276template <int N, int M1, int M2, typename T>
277Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T> operator*(const QGenericMatrix<N, M2, T>& m1, const QGenericMatrix<M1, N, T>& m2)
278{
279 QGenericMatrix<M1, M2, T> result(1);
280 for (int row = 0; row < M2; ++row) {
281 for (int col = 0; col < M1; ++col) {
282 T sum(0.0f);
283 for (int j = 0; j < N; ++j)
284 sum += m1.m[j][row] * m2.m[col][j];
285 result.m[col][row] = sum;
286 }
287 }
288 return result;
289}
290
291template <int N, int M, typename T>
292Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& matrix)
293{
294 QGenericMatrix<N, M, T> result(1);
295 for (int row = 0; row < M; ++row)
296 for (int col = 0; col < N; ++col)
297 result.m[col][row] = -matrix.m[col][row];
298 return result;
299}
300
301template <int N, int M, typename T>
302Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix)
303{
304 QGenericMatrix<N, M, T> result(1);
305 for (int row = 0; row < M; ++row)
306 for (int col = 0; col < N; ++col)
307 result.m[col][row] = matrix.m[col][row] * factor;
308 return result;
309}
310
311template <int N, int M, typename T>
312Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor)
313{
314 QGenericMatrix<N, M, T> result(1);
315 for (int row = 0; row < M; ++row)
316 for (int col = 0; col < N; ++col)
317 result.m[col][row] = matrix.m[col][row] * factor;
318 return result;
319}
320
321template <int N, int M, typename T>
322Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M, T>& matrix, T divisor)
323{
324 QGenericMatrix<N, M, T> result(1);
325 for (int row = 0; row < M; ++row)
326 for (int col = 0; col < N; ++col)
327 result.m[col][row] = matrix.m[col][row] / divisor;
328 return result;
329}
330
331template <int N, int M, typename T>
332Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
333{
334 for (int col = 0; col < N; ++col)
335 for (int row = 0; row < M; ++row)
336 values[row * N + col] = T(m[col][row]);
337}
338
339// Define aliases for the useful variants of QGenericMatrix.
340typedef QGenericMatrix<2, 2, qreal> QMatrix2x2;
341typedef QGenericMatrix<2, 3, qreal> QMatrix2x3;
342typedef QGenericMatrix<2, 4, qreal> QMatrix2x4;
343typedef QGenericMatrix<3, 2, qreal> QMatrix3x2;
344typedef QGenericMatrix<3, 3, qreal> QMatrix3x3;
345typedef QGenericMatrix<3, 4, qreal> QMatrix3x4;
346typedef QGenericMatrix<4, 2, qreal> QMatrix4x2;
347typedef QGenericMatrix<4, 3, qreal> QMatrix4x3;
348
349#ifndef QT_NO_DEBUG_STREAM
350
351template <int N, int M, typename T>
352QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
353{
354 dbg.nospace() << "QGenericMatrix<" << N << ", " << M
355 << ", " << QTypeInfo<T>::name()
356 << ">(" << endl << qSetFieldWidth(10);
357 for (int row = 0; row < M; ++row) {
358 for (int col = 0; col < N; ++col)
359 dbg << m(row, col);
360 dbg << endl;
361 }
362 dbg << qSetFieldWidth(0) << ')';
363 return dbg.space();
364}
365
366#endif
367
368#ifndef QT_NO_DATASTREAM
369
370template <int N, int M, typename T>
371QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
372{
373 for (int row = 0; row < M; ++row)
374 for (int col = 0; col < N; ++col)
375 stream << double(matrix(row, col));
376 return stream;
377}
378
379template <int N, int M, typename T>
380QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
381{
382 double x;
383 for (int row = 0; row < M; ++row) {
384 for (int col = 0; col < N; ++col) {
385 stream >> x;
386 matrix(row, col) = T(x);
387 }
388 }
389 return stream;
390}
391
392#endif
393
394QT_END_NAMESPACE
395
396Q_DECLARE_METATYPE(QMatrix2x2)
397Q_DECLARE_METATYPE(QMatrix2x3)
398Q_DECLARE_METATYPE(QMatrix2x4)
399Q_DECLARE_METATYPE(QMatrix3x2)
400Q_DECLARE_METATYPE(QMatrix3x3)
401Q_DECLARE_METATYPE(QMatrix3x4)
402Q_DECLARE_METATYPE(QMatrix4x2)
403Q_DECLARE_METATYPE(QMatrix4x3)
404
405QT_END_HEADER
406
407#endif
Note: See TracBrowser for help on using the repository browser.