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

Last change on this file since 603 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 12.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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 index = 0; index < N * M; ++index)
202 m[0][index] += other.m[0][index];
203 return *this;
204}
205
206template <int N, int M, typename T>
207Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator-=(const QGenericMatrix<N, M, T>& other)
208{
209 for (int index = 0; index < N * M; ++index)
210 m[0][index] -= other.m[0][index];
211 return *this;
212}
213
214template <int N, int M, typename T>
215Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator*=(T factor)
216{
217 for (int index = 0; index < N * M; ++index)
218 m[0][index] *= factor;
219 return *this;
220}
221
222template <int N, int M, typename T>
223Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator==(const QGenericMatrix<N, M, T>& other) const
224{
225 for (int index = 0; index < N * M; ++index) {
226 if (m[0][index] != other.m[0][index])
227 return false;
228 }
229 return true;
230}
231
232template <int N, int M, typename T>
233Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator!=(const QGenericMatrix<N, M, T>& other) const
234{
235 for (int index = 0; index < N * M; ++index) {
236 if (m[0][index] != other.m[0][index])
237 return true;
238 }
239 return false;
240}
241
242template <int N, int M, typename T>
243Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator/=(T divisor)
244{
245 for (int index = 0; index < N * M; ++index)
246 m[0][index] /= divisor;
247 return *this;
248}
249
250template <int N, int M, typename T>
251Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator+(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
252{
253 QGenericMatrix<N, M, T> result(1);
254 for (int index = 0; index < N * M; ++index)
255 result.m[0][index] = m1.m[0][index] + m2.m[0][index];
256 return result;
257}
258
259template <int N, int M, typename T>
260Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
261{
262 QGenericMatrix<N, M, T> result(1);
263 for (int index = 0; index < N * M; ++index)
264 result.m[0][index] = m1.m[0][index] - m2.m[0][index];
265 return result;
266}
267
268template <int N, int M1, int M2, typename T>
269Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T> operator*(const QGenericMatrix<N, M2, T>& m1, const QGenericMatrix<M1, N, T>& m2)
270{
271 QGenericMatrix<M1, M2, T> result(1);
272 for (int row = 0; row < M2; ++row) {
273 for (int col = 0; col < M1; ++col) {
274 T sum(0.0f);
275 for (int j = 0; j < N; ++j)
276 sum += m1.m[j][row] * m2.m[col][j];
277 result.m[col][row] = sum;
278 }
279 }
280 return result;
281}
282
283template <int N, int M, typename T>
284Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& matrix)
285{
286 QGenericMatrix<N, M, T> result(1);
287 for (int index = 0; index < N * M; ++index)
288 result.m[0][index] = -matrix.m[0][index];
289 return result;
290}
291
292template <int N, int M, typename T>
293Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix)
294{
295 QGenericMatrix<N, M, T> result(1);
296 for (int index = 0; index < N * M; ++index)
297 result.m[0][index] = matrix.m[0][index] * factor;
298 return result;
299}
300
301template <int N, int M, typename T>
302Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor)
303{
304 QGenericMatrix<N, M, T> result(1);
305 for (int index = 0; index < N * M; ++index)
306 result.m[0][index] = matrix.m[0][index] * factor;
307 return result;
308}
309
310template <int N, int M, typename T>
311Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M, T>& matrix, T divisor)
312{
313 QGenericMatrix<N, M, T> result(1);
314 for (int index = 0; index < N * M; ++index)
315 result.m[0][index] = matrix.m[0][index] / divisor;
316 return result;
317}
318
319template <int N, int M, typename T>
320Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
321{
322 for (int col = 0; col < N; ++col)
323 for (int row = 0; row < M; ++row)
324 values[row * N + col] = T(m[col][row]);
325}
326
327// Define aliases for the useful variants of QGenericMatrix.
328typedef QGenericMatrix<2, 2, qreal> QMatrix2x2;
329typedef QGenericMatrix<2, 3, qreal> QMatrix2x3;
330typedef QGenericMatrix<2, 4, qreal> QMatrix2x4;
331typedef QGenericMatrix<3, 2, qreal> QMatrix3x2;
332typedef QGenericMatrix<3, 3, qreal> QMatrix3x3;
333typedef QGenericMatrix<3, 4, qreal> QMatrix3x4;
334typedef QGenericMatrix<4, 2, qreal> QMatrix4x2;
335typedef QGenericMatrix<4, 3, qreal> QMatrix4x3;
336
337#ifndef QT_NO_DEBUG_STREAM
338
339template <int N, int M, typename T>
340QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
341{
342 dbg.nospace() << "QGenericMatrix<" << N << ", " << M
343 << ", " << QTypeInfo<T>::name()
344 << ">(" << endl << qSetFieldWidth(10);
345 for (int row = 0; row < M; ++row) {
346 for (int col = 0; col < N; ++col)
347 dbg << m(row, col);
348 dbg << endl;
349 }
350 dbg << qSetFieldWidth(0) << ')';
351 return dbg.space();
352}
353
354#endif
355
356#ifndef QT_NO_DATASTREAM
357
358template <int N, int M, typename T>
359QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
360{
361 for (int row = 0; row < M; ++row)
362 for (int col = 0; col < N; ++col)
363 stream << double(matrix(row, col));
364 return stream;
365}
366
367template <int N, int M, typename T>
368QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
369{
370 double x;
371 for (int row = 0; row < M; ++row) {
372 for (int col = 0; col < N; ++col) {
373 stream >> x;
374 matrix(row, col) = T(x);
375 }
376 }
377 return stream;
378}
379
380#endif
381
382QT_END_NAMESPACE
383
384Q_DECLARE_METATYPE(QMatrix2x2)
385Q_DECLARE_METATYPE(QMatrix2x3)
386Q_DECLARE_METATYPE(QMatrix2x4)
387Q_DECLARE_METATYPE(QMatrix3x2)
388Q_DECLARE_METATYPE(QMatrix3x3)
389Q_DECLARE_METATYPE(QMatrix3x4)
390Q_DECLARE_METATYPE(QMatrix4x2)
391Q_DECLARE_METATYPE(QMatrix4x3)
392
393QT_END_HEADER
394
395#endif
Note: See TracBrowser for help on using the repository browser.