1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://www.ogre3d.org/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software; you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | #ifndef __Matrix4__
|
---|
26 | #define __Matrix4__
|
---|
27 |
|
---|
28 | // Precompiler options
|
---|
29 | #include "OgrePrerequisites.h"
|
---|
30 |
|
---|
31 | #include "OgreVector3.h"
|
---|
32 | #include "OgreMatrix3.h"
|
---|
33 | #include "OgreVector4.h"
|
---|
34 | #include "OgrePlane.h"
|
---|
35 | namespace Ogre
|
---|
36 | {
|
---|
37 | /** Class encapsulating a standard 4x4 homogenous matrix.
|
---|
38 | @remarks
|
---|
39 | OGRE uses column vectors when applying matrix multiplications,
|
---|
40 | This means a vector is represented as a single column, 4-row
|
---|
41 | matrix. This has the effect that the tranformations implemented
|
---|
42 | by the matrices happens right-to-left e.g. if vector V is to be
|
---|
43 | transformed by M1 then M2 then M3, the calculation would be
|
---|
44 | M3 * M2 * M1 * V. The order that matrices are concatenated is
|
---|
45 | vital since matrix multiplication is not cummatative, i.e. you
|
---|
46 | can get a different result if you concatenate in the wrong order.
|
---|
47 | @par
|
---|
48 | The use of column vectors and right-to-left ordering is the
|
---|
49 | standard in most mathematical texts, and id the same as used in
|
---|
50 | OpenGL. It is, however, the opposite of Direct3D, which has
|
---|
51 | inexplicably chosen to differ from the accepted standard and uses
|
---|
52 | row vectors and left-to-right matrix multiplication.
|
---|
53 | @par
|
---|
54 | OGRE deals with the differences between D3D and OpenGL etc.
|
---|
55 | internally when operating through different render systems. OGRE
|
---|
56 | users only need to conform to standard maths conventions, i.e.
|
---|
57 | right-to-left matrix multiplication, (OGRE transposes matrices it
|
---|
58 | passes to D3D to compensate).
|
---|
59 | @par
|
---|
60 | The generic form M * V which shows the layout of the matrix
|
---|
61 | entries is shown below:
|
---|
62 | <pre>
|
---|
63 | [ m[0][0] m[0][1] m[0][2] m[0][3] ] {x}
|
---|
64 | | m[1][0] m[1][1] m[1][2] m[1][3] | * {y}
|
---|
65 | | m[2][0] m[2][1] m[2][2] m[2][3] | {z}
|
---|
66 | [ m[3][0] m[3][1] m[3][2] m[3][3] ] {1}
|
---|
67 | </pre>
|
---|
68 | */
|
---|
69 | class _OgreExport Matrix4
|
---|
70 | {
|
---|
71 | protected:
|
---|
72 | /// The matrix entries, indexed by [row][col].
|
---|
73 | union {
|
---|
74 | Real m[4][4];
|
---|
75 | Real _m[16];
|
---|
76 | };
|
---|
77 | public:
|
---|
78 | /** Default constructor.
|
---|
79 | @note
|
---|
80 | It does <b>NOT</b> initialize the matrix for efficiency.
|
---|
81 | */
|
---|
82 | inline Matrix4()
|
---|
83 | {
|
---|
84 | }
|
---|
85 |
|
---|
86 | inline Matrix4(
|
---|
87 | Real m00, Real m01, Real m02, Real m03,
|
---|
88 | Real m10, Real m11, Real m12, Real m13,
|
---|
89 | Real m20, Real m21, Real m22, Real m23,
|
---|
90 | Real m30, Real m31, Real m32, Real m33 )
|
---|
91 | {
|
---|
92 | m[0][0] = m00;
|
---|
93 | m[0][1] = m01;
|
---|
94 | m[0][2] = m02;
|
---|
95 | m[0][3] = m03;
|
---|
96 | m[1][0] = m10;
|
---|
97 | m[1][1] = m11;
|
---|
98 | m[1][2] = m12;
|
---|
99 | m[1][3] = m13;
|
---|
100 | m[2][0] = m20;
|
---|
101 | m[2][1] = m21;
|
---|
102 | m[2][2] = m22;
|
---|
103 | m[2][3] = m23;
|
---|
104 | m[3][0] = m30;
|
---|
105 | m[3][1] = m31;
|
---|
106 | m[3][2] = m32;
|
---|
107 | m[3][3] = m33;
|
---|
108 | }
|
---|
109 |
|
---|
110 | /** Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling 3x3 matrix.
|
---|
111 | */
|
---|
112 |
|
---|
113 | inline Matrix4(const Matrix3& m3x3)
|
---|
114 | {
|
---|
115 | operator=(IDENTITY);
|
---|
116 | operator=(m3x3);
|
---|
117 | }
|
---|
118 |
|
---|
119 | /** Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling Quaternion.
|
---|
120 | */
|
---|
121 |
|
---|
122 | inline Matrix4(const Quaternion& rot)
|
---|
123 | {
|
---|
124 | Matrix3 m3x3;
|
---|
125 | rot.ToRotationMatrix(m3x3);
|
---|
126 | operator=(IDENTITY);
|
---|
127 | operator=(m3x3);
|
---|
128 | }
|
---|
129 |
|
---|
130 |
|
---|
131 | inline Real* operator [] ( size_t iRow )
|
---|
132 | {
|
---|
133 | assert( iRow < 4 );
|
---|
134 | return m[iRow];
|
---|
135 | }
|
---|
136 |
|
---|
137 | inline const Real *const operator [] ( size_t iRow ) const
|
---|
138 | {
|
---|
139 | assert( iRow < 4 );
|
---|
140 | return m[iRow];
|
---|
141 | }
|
---|
142 |
|
---|
143 | inline Matrix4 concatenate(const Matrix4 &m2) const
|
---|
144 | {
|
---|
145 | Matrix4 r;
|
---|
146 | r.m[0][0] = m[0][0] * m2.m[0][0] + m[0][1] * m2.m[1][0] + m[0][2] * m2.m[2][0] + m[0][3] * m2.m[3][0];
|
---|
147 | r.m[0][1] = m[0][0] * m2.m[0][1] + m[0][1] * m2.m[1][1] + m[0][2] * m2.m[2][1] + m[0][3] * m2.m[3][1];
|
---|
148 | r.m[0][2] = m[0][0] * m2.m[0][2] + m[0][1] * m2.m[1][2] + m[0][2] * m2.m[2][2] + m[0][3] * m2.m[3][2];
|
---|
149 | r.m[0][3] = m[0][0] * m2.m[0][3] + m[0][1] * m2.m[1][3] + m[0][2] * m2.m[2][3] + m[0][3] * m2.m[3][3];
|
---|
150 |
|
---|
151 | r.m[1][0] = m[1][0] * m2.m[0][0] + m[1][1] * m2.m[1][0] + m[1][2] * m2.m[2][0] + m[1][3] * m2.m[3][0];
|
---|
152 | r.m[1][1] = m[1][0] * m2.m[0][1] + m[1][1] * m2.m[1][1] + m[1][2] * m2.m[2][1] + m[1][3] * m2.m[3][1];
|
---|
153 | r.m[1][2] = m[1][0] * m2.m[0][2] + m[1][1] * m2.m[1][2] + m[1][2] * m2.m[2][2] + m[1][3] * m2.m[3][2];
|
---|
154 | r.m[1][3] = m[1][0] * m2.m[0][3] + m[1][1] * m2.m[1][3] + m[1][2] * m2.m[2][3] + m[1][3] * m2.m[3][3];
|
---|
155 |
|
---|
156 | r.m[2][0] = m[2][0] * m2.m[0][0] + m[2][1] * m2.m[1][0] + m[2][2] * m2.m[2][0] + m[2][3] * m2.m[3][0];
|
---|
157 | r.m[2][1] = m[2][0] * m2.m[0][1] + m[2][1] * m2.m[1][1] + m[2][2] * m2.m[2][1] + m[2][3] * m2.m[3][1];
|
---|
158 | r.m[2][2] = m[2][0] * m2.m[0][2] + m[2][1] * m2.m[1][2] + m[2][2] * m2.m[2][2] + m[2][3] * m2.m[3][2];
|
---|
159 | r.m[2][3] = m[2][0] * m2.m[0][3] + m[2][1] * m2.m[1][3] + m[2][2] * m2.m[2][3] + m[2][3] * m2.m[3][3];
|
---|
160 |
|
---|
161 | r.m[3][0] = m[3][0] * m2.m[0][0] + m[3][1] * m2.m[1][0] + m[3][2] * m2.m[2][0] + m[3][3] * m2.m[3][0];
|
---|
162 | r.m[3][1] = m[3][0] * m2.m[0][1] + m[3][1] * m2.m[1][1] + m[3][2] * m2.m[2][1] + m[3][3] * m2.m[3][1];
|
---|
163 | r.m[3][2] = m[3][0] * m2.m[0][2] + m[3][1] * m2.m[1][2] + m[3][2] * m2.m[2][2] + m[3][3] * m2.m[3][2];
|
---|
164 | r.m[3][3] = m[3][0] * m2.m[0][3] + m[3][1] * m2.m[1][3] + m[3][2] * m2.m[2][3] + m[3][3] * m2.m[3][3];
|
---|
165 |
|
---|
166 | return r;
|
---|
167 | }
|
---|
168 |
|
---|
169 | /** Matrix concatenation using '*'.
|
---|
170 | */
|
---|
171 | inline Matrix4 operator * ( const Matrix4 &m2 ) const
|
---|
172 | {
|
---|
173 | return concatenate( m2 );
|
---|
174 | }
|
---|
175 |
|
---|
176 | /** Vector transformation using '*'.
|
---|
177 | @remarks
|
---|
178 | Transforms the given 3-D vector by the matrix, projecting the
|
---|
179 | result back into <i>w</i> = 1.
|
---|
180 | @note
|
---|
181 | This means that the initial <i>w</i> is considered to be 1.0,
|
---|
182 | and then all the tree elements of the resulting 3-D vector are
|
---|
183 | divided by the resulting <i>w</i>.
|
---|
184 | */
|
---|
185 | inline Vector3 operator * ( const Vector3 &v ) const
|
---|
186 | {
|
---|
187 | Vector3 r;
|
---|
188 |
|
---|
189 | Real fInvW = 1.0 / ( m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] );
|
---|
190 |
|
---|
191 | r.x = ( m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] ) * fInvW;
|
---|
192 | r.y = ( m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] ) * fInvW;
|
---|
193 | r.z = ( m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] ) * fInvW;
|
---|
194 |
|
---|
195 | return r;
|
---|
196 | }
|
---|
197 | inline Vector4 operator * (const Vector4& v) const
|
---|
198 | {
|
---|
199 | return Vector4(
|
---|
200 | m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w,
|
---|
201 | m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
|
---|
202 | m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
|
---|
203 | m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w
|
---|
204 | );
|
---|
205 | }
|
---|
206 | inline Plane operator * (const Plane& p) const
|
---|
207 | {
|
---|
208 | Plane ret;
|
---|
209 | Matrix4 invTrans = inverse().transpose();
|
---|
210 | ret.normal.x =
|
---|
211 | invTrans[0][0] * p.normal.x + invTrans[0][1] * p.normal.y + invTrans[0][2] * p.normal.z;
|
---|
212 | ret.normal.y =
|
---|
213 | invTrans[1][0] * p.normal.x + invTrans[1][1] * p.normal.y + invTrans[1][2] * p.normal.z;
|
---|
214 | ret.normal.z =
|
---|
215 | invTrans[2][0] * p.normal.x + invTrans[2][1] * p.normal.y + invTrans[2][2] * p.normal.z;
|
---|
216 | Vector3 pt = p.normal * -p.d;
|
---|
217 | pt = *this * pt;
|
---|
218 | ret.d = - pt.dotProduct(ret.normal);
|
---|
219 | return ret;
|
---|
220 | }
|
---|
221 |
|
---|
222 |
|
---|
223 | /** Matrix addition.
|
---|
224 | */
|
---|
225 | inline Matrix4 operator + ( const Matrix4 &m2 ) const
|
---|
226 | {
|
---|
227 | Matrix4 r;
|
---|
228 |
|
---|
229 | r.m[0][0] = m[0][0] + m2.m[0][0];
|
---|
230 | r.m[0][1] = m[0][1] + m2.m[0][1];
|
---|
231 | r.m[0][2] = m[0][2] + m2.m[0][2];
|
---|
232 | r.m[0][3] = m[0][3] + m2.m[0][3];
|
---|
233 |
|
---|
234 | r.m[1][0] = m[1][0] + m2.m[1][0];
|
---|
235 | r.m[1][1] = m[1][1] + m2.m[1][1];
|
---|
236 | r.m[1][2] = m[1][2] + m2.m[1][2];
|
---|
237 | r.m[1][3] = m[1][3] + m2.m[1][3];
|
---|
238 |
|
---|
239 | r.m[2][0] = m[2][0] + m2.m[2][0];
|
---|
240 | r.m[2][1] = m[2][1] + m2.m[2][1];
|
---|
241 | r.m[2][2] = m[2][2] + m2.m[2][2];
|
---|
242 | r.m[2][3] = m[2][3] + m2.m[2][3];
|
---|
243 |
|
---|
244 | r.m[3][0] = m[3][0] + m2.m[3][0];
|
---|
245 | r.m[3][1] = m[3][1] + m2.m[3][1];
|
---|
246 | r.m[3][2] = m[3][2] + m2.m[3][2];
|
---|
247 | r.m[3][3] = m[3][3] + m2.m[3][3];
|
---|
248 |
|
---|
249 | return r;
|
---|
250 | }
|
---|
251 |
|
---|
252 | /** Matrix subtraction.
|
---|
253 | */
|
---|
254 | inline Matrix4 operator - ( const Matrix4 &m2 ) const
|
---|
255 | {
|
---|
256 | Matrix4 r;
|
---|
257 | r.m[0][0] = m[0][0] - m2.m[0][0];
|
---|
258 | r.m[0][1] = m[0][1] - m2.m[0][1];
|
---|
259 | r.m[0][2] = m[0][2] - m2.m[0][2];
|
---|
260 | r.m[0][3] = m[0][3] - m2.m[0][3];
|
---|
261 |
|
---|
262 | r.m[1][0] = m[1][0] - m2.m[1][0];
|
---|
263 | r.m[1][1] = m[1][1] - m2.m[1][1];
|
---|
264 | r.m[1][2] = m[1][2] - m2.m[1][2];
|
---|
265 | r.m[1][3] = m[1][3] - m2.m[1][3];
|
---|
266 |
|
---|
267 | r.m[2][0] = m[2][0] - m2.m[2][0];
|
---|
268 | r.m[2][1] = m[2][1] - m2.m[2][1];
|
---|
269 | r.m[2][2] = m[2][2] - m2.m[2][2];
|
---|
270 | r.m[2][3] = m[2][3] - m2.m[2][3];
|
---|
271 |
|
---|
272 | r.m[3][0] = m[3][0] - m2.m[3][0];
|
---|
273 | r.m[3][1] = m[3][1] - m2.m[3][1];
|
---|
274 | r.m[3][2] = m[3][2] - m2.m[3][2];
|
---|
275 | r.m[3][3] = m[3][3] - m2.m[3][3];
|
---|
276 |
|
---|
277 | return r;
|
---|
278 | }
|
---|
279 |
|
---|
280 | /** Tests 2 matrices for equality.
|
---|
281 | */
|
---|
282 | inline bool operator == ( const Matrix4& m2 ) const
|
---|
283 | {
|
---|
284 | if(
|
---|
285 | m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
|
---|
286 | m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
|
---|
287 | m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
|
---|
288 | m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
|
---|
289 | return false;
|
---|
290 | return true;
|
---|
291 | }
|
---|
292 |
|
---|
293 | /** Tests 2 matrices for inequality.
|
---|
294 | */
|
---|
295 | inline bool operator != ( const Matrix4& m2 ) const
|
---|
296 | {
|
---|
297 | if(
|
---|
298 | m[0][0] != m2.m[0][0] || m[0][1] != m2.m[0][1] || m[0][2] != m2.m[0][2] || m[0][3] != m2.m[0][3] ||
|
---|
299 | m[1][0] != m2.m[1][0] || m[1][1] != m2.m[1][1] || m[1][2] != m2.m[1][2] || m[1][3] != m2.m[1][3] ||
|
---|
300 | m[2][0] != m2.m[2][0] || m[2][1] != m2.m[2][1] || m[2][2] != m2.m[2][2] || m[2][3] != m2.m[2][3] ||
|
---|
301 | m[3][0] != m2.m[3][0] || m[3][1] != m2.m[3][1] || m[3][2] != m2.m[3][2] || m[3][3] != m2.m[3][3] )
|
---|
302 | return true;
|
---|
303 | return false;
|
---|
304 | }
|
---|
305 |
|
---|
306 | /** Assignment from 3x3 matrix.
|
---|
307 | */
|
---|
308 | inline void operator = ( const Matrix3& mat3 )
|
---|
309 | {
|
---|
310 | m[0][0] = mat3.m[0][0]; m[0][1] = mat3.m[0][1]; m[0][2] = mat3.m[0][2];
|
---|
311 | m[1][0] = mat3.m[1][0]; m[1][1] = mat3.m[1][1]; m[1][2] = mat3.m[1][2];
|
---|
312 | m[2][0] = mat3.m[2][0]; m[2][1] = mat3.m[2][1]; m[2][2] = mat3.m[2][2];
|
---|
313 | }
|
---|
314 |
|
---|
315 | inline Matrix4 transpose(void) const
|
---|
316 | {
|
---|
317 | return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0],
|
---|
318 | m[0][1], m[1][1], m[2][1], m[3][1],
|
---|
319 | m[0][2], m[1][2], m[2][2], m[3][2],
|
---|
320 | m[0][3], m[1][3], m[2][3], m[3][3]);
|
---|
321 | }
|
---|
322 |
|
---|
323 | /*
|
---|
324 | -----------------------------------------------------------------------
|
---|
325 | Translation Transformation
|
---|
326 | -----------------------------------------------------------------------
|
---|
327 | */
|
---|
328 | /** Sets the translation transformation part of the matrix.
|
---|
329 | */
|
---|
330 | inline void setTrans( const Vector3& v )
|
---|
331 | {
|
---|
332 | m[0][3] = v.x;
|
---|
333 | m[1][3] = v.y;
|
---|
334 | m[2][3] = v.z;
|
---|
335 | }
|
---|
336 |
|
---|
337 | /** Extracts the translation transformation part of the matrix.
|
---|
338 | */
|
---|
339 | inline Vector3 getTrans() const
|
---|
340 | {
|
---|
341 | return Vector3(m[0][3], m[1][3], m[2][3]);
|
---|
342 | }
|
---|
343 |
|
---|
344 |
|
---|
345 | /** Builds a translation matrix
|
---|
346 | */
|
---|
347 | inline void makeTrans( const Vector3& v )
|
---|
348 | {
|
---|
349 | m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = v.x;
|
---|
350 | m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = v.y;
|
---|
351 | m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = v.z;
|
---|
352 | m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
|
---|
353 | }
|
---|
354 |
|
---|
355 | inline void makeTrans( Real tx, Real ty, Real tz )
|
---|
356 | {
|
---|
357 | m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = tx;
|
---|
358 | m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = ty;
|
---|
359 | m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = tz;
|
---|
360 | m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
|
---|
361 | }
|
---|
362 |
|
---|
363 | /** Gets a translation matrix.
|
---|
364 | */
|
---|
365 | inline static Matrix4 getTrans( const Vector3& v )
|
---|
366 | {
|
---|
367 | Matrix4 r;
|
---|
368 |
|
---|
369 | r.m[0][0] = 1.0; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = v.x;
|
---|
370 | r.m[1][0] = 0.0; r.m[1][1] = 1.0; r.m[1][2] = 0.0; r.m[1][3] = v.y;
|
---|
371 | r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = 1.0; r.m[2][3] = v.z;
|
---|
372 | r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
|
---|
373 |
|
---|
374 | return r;
|
---|
375 | }
|
---|
376 |
|
---|
377 | /** Gets a translation matrix - variation for not using a vector.
|
---|
378 | */
|
---|
379 | inline static Matrix4 getTrans( Real t_x, Real t_y, Real t_z )
|
---|
380 | {
|
---|
381 | Matrix4 r;
|
---|
382 |
|
---|
383 | r.m[0][0] = 1.0; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = t_x;
|
---|
384 | r.m[1][0] = 0.0; r.m[1][1] = 1.0; r.m[1][2] = 0.0; r.m[1][3] = t_y;
|
---|
385 | r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = 1.0; r.m[2][3] = t_z;
|
---|
386 | r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
|
---|
387 |
|
---|
388 | return r;
|
---|
389 | }
|
---|
390 |
|
---|
391 | /*
|
---|
392 | -----------------------------------------------------------------------
|
---|
393 | Scale Transformation
|
---|
394 | -----------------------------------------------------------------------
|
---|
395 | */
|
---|
396 | /** Sets the scale part of the matrix.
|
---|
397 | */
|
---|
398 | inline void setScale( const Vector3& v )
|
---|
399 | {
|
---|
400 | m[0][0] = v.x;
|
---|
401 | m[1][1] = v.y;
|
---|
402 | m[2][2] = v.z;
|
---|
403 | }
|
---|
404 |
|
---|
405 | /** Gets a scale matrix.
|
---|
406 | */
|
---|
407 | inline static Matrix4 getScale( const Vector3& v )
|
---|
408 | {
|
---|
409 | Matrix4 r;
|
---|
410 | r.m[0][0] = v.x; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = 0.0;
|
---|
411 | r.m[1][0] = 0.0; r.m[1][1] = v.y; r.m[1][2] = 0.0; r.m[1][3] = 0.0;
|
---|
412 | r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = v.z; r.m[2][3] = 0.0;
|
---|
413 | r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
|
---|
414 |
|
---|
415 | return r;
|
---|
416 | }
|
---|
417 |
|
---|
418 | /** Gets a scale matrix - variation for not using a vector.
|
---|
419 | */
|
---|
420 | inline static Matrix4 getScale( Real s_x, Real s_y, Real s_z )
|
---|
421 | {
|
---|
422 | Matrix4 r;
|
---|
423 | r.m[0][0] = s_x; r.m[0][1] = 0.0; r.m[0][2] = 0.0; r.m[0][3] = 0.0;
|
---|
424 | r.m[1][0] = 0.0; r.m[1][1] = s_y; r.m[1][2] = 0.0; r.m[1][3] = 0.0;
|
---|
425 | r.m[2][0] = 0.0; r.m[2][1] = 0.0; r.m[2][2] = s_z; r.m[2][3] = 0.0;
|
---|
426 | r.m[3][0] = 0.0; r.m[3][1] = 0.0; r.m[3][2] = 0.0; r.m[3][3] = 1.0;
|
---|
427 |
|
---|
428 | return r;
|
---|
429 | }
|
---|
430 |
|
---|
431 | /** Extracts the rotation / scaling part of the Matrix as a 3x3 matrix.
|
---|
432 | @param m3x3 Destination Matrix3
|
---|
433 | */
|
---|
434 | inline void extract3x3Matrix(Matrix3& m3x3) const
|
---|
435 | {
|
---|
436 | m3x3.m[0][0] = m[0][0];
|
---|
437 | m3x3.m[0][1] = m[0][1];
|
---|
438 | m3x3.m[0][2] = m[0][2];
|
---|
439 | m3x3.m[1][0] = m[1][0];
|
---|
440 | m3x3.m[1][1] = m[1][1];
|
---|
441 | m3x3.m[1][2] = m[1][2];
|
---|
442 | m3x3.m[2][0] = m[2][0];
|
---|
443 | m3x3.m[2][1] = m[2][1];
|
---|
444 | m3x3.m[2][2] = m[2][2];
|
---|
445 |
|
---|
446 | }
|
---|
447 |
|
---|
448 | /** Extracts the rotation / scaling part as a quaternion from the Matrix.
|
---|
449 | */
|
---|
450 | inline Quaternion extractQuaternion() const
|
---|
451 | {
|
---|
452 | Matrix3 m3x3;
|
---|
453 | extract3x3Matrix(m3x3);
|
---|
454 | return Quaternion(m3x3);
|
---|
455 | }
|
---|
456 |
|
---|
457 | static const Matrix4 ZERO;
|
---|
458 | static const Matrix4 IDENTITY;
|
---|
459 | /** Useful little matrix which takes 2D clipspace {-1, 1} to {0,1}
|
---|
460 | and inverts the Y. */
|
---|
461 | static const Matrix4 CLIPSPACE2DTOIMAGESPACE;
|
---|
462 |
|
---|
463 | inline Matrix4 operator*(Real scalar)
|
---|
464 | {
|
---|
465 | return Matrix4(
|
---|
466 | scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3],
|
---|
467 | scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3],
|
---|
468 | scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3],
|
---|
469 | scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]);
|
---|
470 | }
|
---|
471 |
|
---|
472 | /** Function for writing to a stream.
|
---|
473 | */
|
---|
474 | inline _OgreExport friend std::ostream& operator <<
|
---|
475 | ( std::ostream& o, const Matrix4& m )
|
---|
476 | {
|
---|
477 | o << "Matrix4(";
|
---|
478 | for (size_t i = 0; i < 4; ++i)
|
---|
479 | {
|
---|
480 | o << " row" << (unsigned)i << "{";
|
---|
481 | for(size_t j = 0; j < 4; ++j)
|
---|
482 | {
|
---|
483 | o << m[i][j] << " ";
|
---|
484 | }
|
---|
485 | o << "}";
|
---|
486 | }
|
---|
487 | o << ")";
|
---|
488 | return o;
|
---|
489 | }
|
---|
490 |
|
---|
491 | Matrix4 adjoint() const;
|
---|
492 | Real determinant() const;
|
---|
493 | Matrix4 inverse() const;
|
---|
494 |
|
---|
495 | };
|
---|
496 |
|
---|
497 | /* Removed from Vector4 and made a non-member here because otherwise
|
---|
498 | OgreMatrix4.h and OgreVector4.h have to try to include and inline each
|
---|
499 | other, which frankly doesn't work ;)
|
---|
500 | */
|
---|
501 | inline Vector4 operator * (const Vector4& v, const Matrix4& mat)
|
---|
502 | {
|
---|
503 | return Vector4(
|
---|
504 | v.x*mat[0][0] + v.y*mat[1][0] + v.z*mat[2][0] + v.w*mat[3][0],
|
---|
505 | v.x*mat[0][1] + v.y*mat[1][1] + v.z*mat[2][1] + v.w*mat[3][1],
|
---|
506 | v.x*mat[0][2] + v.y*mat[1][2] + v.z*mat[2][2] + v.w*mat[3][2],
|
---|
507 | v.x*mat[0][3] + v.y*mat[1][3] + v.z*mat[2][3] + v.w*mat[3][3]
|
---|
508 | );
|
---|
509 | }
|
---|
510 |
|
---|
511 | }
|
---|
512 | #endif
|
---|