/src/ogre/OgreMain/include/OgreMatrix4.h
Line | Count | Source (jump to first uncovered line) |
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-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #ifndef __Matrix4__ |
29 | | #define __Matrix4__ |
30 | | |
31 | | // Precompiler options |
32 | | #include "OgrePrerequisites.h" |
33 | | |
34 | | #include "OgreMatrix3.h" |
35 | | #include "OgreVector.h" |
36 | | |
37 | | namespace Ogre |
38 | | { |
39 | | /** \addtogroup Core |
40 | | * @{ |
41 | | */ |
42 | | /** \addtogroup Math |
43 | | * @{ |
44 | | */ |
45 | | class Matrix4; |
46 | | class Affine3; |
47 | | Matrix4 operator*(const Matrix4 &m, const Matrix4 &m2); |
48 | | /** Class encapsulating a standard 4x4 homogeneous matrix. |
49 | | |
50 | | OGRE uses column vectors when applying matrix multiplications, |
51 | | This means a vector is represented as a single column, 4-row |
52 | | matrix. This has the effect that the transformations implemented |
53 | | by the matrices happens right-to-left e.g. if vector V is to be |
54 | | transformed by M1 then M2 then M3, the calculation would be |
55 | | M3 * M2 * M1 * V. The order that matrices are concatenated is |
56 | | vital since matrix multiplication is not commutative, i.e. you |
57 | | can get a different result if you concatenate in the wrong order. |
58 | | @par |
59 | | The use of column vectors and right-to-left ordering is the |
60 | | standard in most mathematical texts, and is the same as used in |
61 | | OpenGL. It is, however, the opposite of Direct3D, which has |
62 | | inexplicably chosen to differ from the accepted standard and uses |
63 | | row vectors and left-to-right matrix multiplication. |
64 | | @par |
65 | | OGRE deals with the differences between D3D and OpenGL etc. |
66 | | internally when operating through different render systems. OGRE |
67 | | users only need to conform to standard maths conventions, i.e. |
68 | | right-to-left matrix multiplication, (OGRE transposes matrices it |
69 | | passes to D3D to compensate). |
70 | | @par |
71 | | The generic form M * V which shows the layout of the matrix |
72 | | entries is shown below: |
73 | | <pre> |
74 | | [ m[0][0] m[0][1] m[0][2] m[0][3] ] {x} |
75 | | | m[1][0] m[1][1] m[1][2] m[1][3] | * {y} |
76 | | | m[2][0] m[2][1] m[2][2] m[2][3] | {z} |
77 | | [ m[3][0] m[3][1] m[3][2] m[3][3] ] {1} |
78 | | </pre> |
79 | | */ |
80 | | template<int rows, typename T> class TransformBase |
81 | | { |
82 | | protected: |
83 | | /// The matrix entries, indexed by [row][col]. |
84 | | T m[rows][4]; |
85 | | // do not reduce storage for affine for compatibility with SSE, shader mat4 types |
86 | | public: |
87 | | /// Do <b>NOT</b> initialize for efficiency. |
88 | 10 | TransformBase() {} |
89 | | |
90 | | template<typename U> |
91 | | explicit TransformBase(const U* ptr) { |
92 | | for (int i = 0; i < rows; i++) |
93 | | for (int j = 0; j < 4; j++) |
94 | | m[i][j] = T(ptr[i*4 + j]); |
95 | | } |
96 | | |
97 | | template<typename U> |
98 | | explicit TransformBase(const TransformBase<rows, U>& o) : TransformBase(o[0]) {} |
99 | | |
100 | | T* operator[](size_t iRow) |
101 | 0 | { |
102 | 0 | assert(iRow < rows); |
103 | 0 | return m[iRow]; |
104 | 0 | } |
105 | | |
106 | | const T* operator[](size_t iRow) const |
107 | 0 | { |
108 | 0 | assert(iRow < rows); |
109 | 0 | return m[iRow]; |
110 | 0 | } |
111 | | |
112 | | /// Sets the translation transformation part of the matrix. |
113 | | void setTrans( const Vector<3, T>& v ) |
114 | 0 | { |
115 | 0 | assert(rows > 2); |
116 | 0 | m[0][3] = v[0]; |
117 | 0 | m[1][3] = v[1]; |
118 | 0 | m[2][3] = v[2]; |
119 | 0 | } |
120 | | /// Extracts the translation transformation part of the matrix. |
121 | | Vector<3, T> getTrans() const |
122 | | { |
123 | | assert(rows > 2); |
124 | | return Vector<3, T>(m[0][3], m[1][3], m[2][3]); |
125 | | } |
126 | | /// Sets the scale part of the matrix. |
127 | | void setScale( const Vector<3, T>& v ) |
128 | 0 | { |
129 | 0 | assert(rows > 2); |
130 | 0 | m[0][0] = v[0]; |
131 | 0 | m[1][1] = v[1]; |
132 | 0 | m[2][2] = v[2]; |
133 | 0 | } |
134 | | |
135 | | /** Function for writing to a stream. |
136 | | */ |
137 | | inline friend std::ostream& operator<<(std::ostream& o, const TransformBase& mat) |
138 | | { |
139 | | o << "Matrix" << rows << "x4("; |
140 | | for (size_t i = 0; i < rows; ++i) |
141 | | { |
142 | | for (size_t j = 0; j < 4; ++j) |
143 | | { |
144 | | o << mat[i][j]; |
145 | | if(j != 3) |
146 | | o << ", "; |
147 | | } |
148 | | |
149 | | if(i != (rows - 1)) |
150 | | o << "; "; |
151 | | } |
152 | | o << ")"; |
153 | | return o; |
154 | | } |
155 | | }; |
156 | | |
157 | | struct _OgreExport TransformBaseReal : public TransformBase<4, Real> |
158 | | { |
159 | | /// Do <b>NOT</b> initialize for efficiency. |
160 | 10 | TransformBaseReal() {} |
161 | | template<typename U> |
162 | | explicit TransformBaseReal(const U* ptr) : TransformBase(ptr) {} |
163 | | /** Builds a translation matrix |
164 | | */ |
165 | | void makeTrans( const Vector3& v ) |
166 | 0 | { |
167 | 0 | makeTrans(v.x, v.y, v.z); |
168 | 0 | } |
169 | | |
170 | | void makeTrans( Real tx, Real ty, Real tz ) |
171 | 0 | { |
172 | 0 | m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = tx; |
173 | 0 | m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = ty; |
174 | 0 | m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = tz; |
175 | 0 | m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0; |
176 | 0 | } |
177 | | |
178 | | /** Assignment from 3x3 matrix. |
179 | | */ |
180 | | void set3x3Matrix(const Matrix3& mat3) |
181 | 0 | { |
182 | 0 | m[0][0] = mat3[0][0]; m[0][1] = mat3[0][1]; m[0][2] = mat3[0][2]; |
183 | 0 | m[1][0] = mat3[1][0]; m[1][1] = mat3[1][1]; m[1][2] = mat3[1][2]; |
184 | 0 | m[2][0] = mat3[2][0]; m[2][1] = mat3[2][1]; m[2][2] = mat3[2][2]; |
185 | 0 | } |
186 | | |
187 | | /** Extracts the rotation / scaling part of the Matrix as a 3x3 matrix. |
188 | | */ |
189 | | Matrix3 linear() const |
190 | 0 | { |
191 | 0 | return Matrix3(m[0][0], m[0][1], m[0][2], |
192 | 0 | m[1][0], m[1][1], m[1][2], |
193 | 0 | m[2][0], m[2][1], m[2][2]); |
194 | 0 | } |
195 | | |
196 | 0 | OGRE_DEPRECATED void extract3x3Matrix(Matrix3& m3x3) const { m3x3 = linear(); } |
197 | 0 | OGRE_DEPRECATED Quaternion extractQuaternion() const { return Quaternion(linear()); } |
198 | | |
199 | | Real determinant() const; |
200 | | |
201 | | Matrix4 transpose() const; |
202 | | |
203 | | /** Building a Affine3 from orientation / scale / position. |
204 | | |
205 | | Transform is performed in the order scale, rotate, translation, i.e. translation is independent |
206 | | of orientation axes, scale does not affect size of translation, rotation and scaling are always |
207 | | centered on the origin. |
208 | | */ |
209 | | void makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation); |
210 | | |
211 | | /** Building an inverse Affine3 from orientation / scale / position. |
212 | | |
213 | | As makeTransform except it build the inverse given the same data as makeTransform, so |
214 | | performing -translation, -rotate, 1/scale in that order. |
215 | | */ |
216 | | void makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation); |
217 | | }; |
218 | | |
219 | | /// Transform specialization for projective - encapsulating a 4x4 Matrix |
220 | | class _OgreExport Matrix4 : public TransformBaseReal |
221 | | { |
222 | | public: |
223 | | /// Do <b>NOT</b> initialize the matrix for efficiency. |
224 | 0 | Matrix4() {} |
225 | | |
226 | | Matrix4( |
227 | | Real m00, Real m01, Real m02, Real m03, |
228 | | Real m10, Real m11, Real m12, Real m13, |
229 | | Real m20, Real m21, Real m22, Real m23, |
230 | | Real m30, Real m31, Real m32, Real m33 ) |
231 | | { |
232 | | m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; |
233 | | m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; |
234 | | m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; |
235 | | m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; |
236 | | } |
237 | | |
238 | | template<typename U> |
239 | | explicit Matrix4(const U* ptr) : TransformBaseReal(ptr) {} |
240 | | explicit Matrix4 (const Real* arr) |
241 | 0 | { |
242 | 0 | memcpy(m,arr,16*sizeof(Real)); |
243 | 0 | } |
244 | | |
245 | | /** Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling 3x3 matrix. |
246 | | */ |
247 | | |
248 | | explicit Matrix4(const Matrix3& m3x3) |
249 | 0 | { |
250 | 0 | operator=(IDENTITY); |
251 | 0 | operator=(m3x3); |
252 | 0 | } |
253 | | |
254 | | /** Creates a standard 4x4 transformation matrix with a zero translation part from a rotation/scaling Quaternion. |
255 | | */ |
256 | | |
257 | | explicit Matrix4(const Quaternion& rot) |
258 | 0 | { |
259 | 0 | Matrix3 m3x3; |
260 | 0 | rot.ToRotationMatrix(m3x3); |
261 | 0 | *this = IDENTITY; |
262 | 0 | *this = m3x3; |
263 | 0 | } |
264 | | |
265 | 0 | Matrix4& operator=(const Matrix3& mat3) { |
266 | 0 | set3x3Matrix(mat3); |
267 | 0 | return *this; |
268 | 0 | } |
269 | | |
270 | 0 | OGRE_DEPRECATED Matrix4 concatenate(const Matrix4& m2) const { return *this * m2; } |
271 | | |
272 | | /** Tests 2 matrices for equality. |
273 | | */ |
274 | | inline bool operator == ( const Matrix4& m2 ) const |
275 | 0 | { |
276 | 0 | if( |
277 | 0 | 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] || |
278 | 0 | 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] || |
279 | 0 | 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] || |
280 | 0 | 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] ) |
281 | 0 | return false; |
282 | 0 | return true; |
283 | 0 | } |
284 | | |
285 | | /** Tests 2 matrices for inequality. |
286 | | */ |
287 | | inline bool operator != ( const Matrix4& m2 ) const |
288 | 0 | { |
289 | 0 | if( |
290 | 0 | 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] || |
291 | 0 | 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] || |
292 | 0 | 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] || |
293 | 0 | 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] ) |
294 | 0 | return true; |
295 | 0 | return false; |
296 | 0 | } |
297 | | |
298 | | static const Matrix4 ZERO; |
299 | | static const Matrix4 IDENTITY; |
300 | | /** Useful little matrix which takes 2D clipspace {-1, 1} to {0,1} |
301 | | and inverts the Y. */ |
302 | | static const Matrix4 CLIPSPACE2DTOIMAGESPACE; |
303 | | |
304 | | inline Matrix4 operator*(Real scalar) const |
305 | 0 | { |
306 | 0 | return Matrix4( |
307 | 0 | scalar*m[0][0], scalar*m[0][1], scalar*m[0][2], scalar*m[0][3], |
308 | 0 | scalar*m[1][0], scalar*m[1][1], scalar*m[1][2], scalar*m[1][3], |
309 | 0 | scalar*m[2][0], scalar*m[2][1], scalar*m[2][2], scalar*m[2][3], |
310 | 0 | scalar*m[3][0], scalar*m[3][1], scalar*m[3][2], scalar*m[3][3]); |
311 | 0 | } |
312 | | |
313 | | Matrix4 adjoint() const; |
314 | | Matrix4 inverse() const; |
315 | | }; |
316 | | |
317 | | /// Transform specialization for 3D Affine - encapsulating a 3x4 Matrix |
318 | | class _OgreExport Affine3 : public TransformBaseReal |
319 | | { |
320 | | public: |
321 | | /// Do <b>NOT</b> initialize the matrix for efficiency. |
322 | 0 | Affine3() {} |
323 | | |
324 | | /// @copydoc TransformBaseReal::makeTransform |
325 | | Affine3(const Vector3& position, const Quaternion& orientation, const Vector3& scale = Vector3::UNIT_SCALE) |
326 | 0 | { |
327 | 0 | makeTransform(position, scale, orientation); |
328 | 0 | } |
329 | | |
330 | | template<typename U> |
331 | | explicit Affine3(const U* ptr) |
332 | | { |
333 | | for (int i = 0; i < 3; i++) |
334 | | for (int j = 0; j < 4; j++) |
335 | | m[i][j] = Real(ptr[i*4 + j]); |
336 | | m[3][0] = 0, m[3][1] = 0, m[3][2] = 0, m[3][3] = 1; |
337 | | } |
338 | | |
339 | | explicit Affine3(const Real* arr) |
340 | 0 | { |
341 | 0 | memcpy(m, arr, 12 * sizeof(Real)); |
342 | 0 | m[3][0] = 0, m[3][1] = 0, m[3][2] = 0, m[3][3] = 1; |
343 | 0 | } |
344 | | |
345 | | Affine3( |
346 | | Real m00, Real m01, Real m02, Real m03, |
347 | | Real m10, Real m11, Real m12, Real m13, |
348 | | Real m20, Real m21, Real m22, Real m23) |
349 | | { |
350 | | m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; |
351 | | m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; |
352 | | m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; |
353 | | m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; |
354 | | } |
355 | | |
356 | | /// extract the Affine part of a Matrix4 |
357 | | explicit Affine3(const Matrix4& mat) |
358 | 0 | { |
359 | 0 | m[0][0] = mat[0][0]; m[0][1] = mat[0][1]; m[0][2] = mat[0][2]; m[0][3] = mat[0][3]; |
360 | 0 | m[1][0] = mat[1][0]; m[1][1] = mat[1][1]; m[1][2] = mat[1][2]; m[1][3] = mat[1][3]; |
361 | 0 | m[2][0] = mat[2][0]; m[2][1] = mat[2][1]; m[2][2] = mat[2][2]; m[2][3] = mat[2][3]; |
362 | 0 | m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; |
363 | 0 | } |
364 | | |
365 | 0 | Affine3& operator=(const Matrix3& mat3) { |
366 | 0 | set3x3Matrix(mat3); |
367 | 0 | return *this; |
368 | 0 | } |
369 | | |
370 | | /** Tests 2 matrices for equality. |
371 | | */ |
372 | | bool operator==(const Affine3& m2) const |
373 | 0 | { |
374 | 0 | if( |
375 | 0 | 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] || |
376 | 0 | 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] || |
377 | 0 | 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] ) |
378 | 0 | return false; |
379 | 0 | return true; |
380 | 0 | } |
381 | | |
382 | 0 | bool operator!=(const Affine3& m2) const { return !(*this == m2); } |
383 | | |
384 | | Affine3 inverse() const; |
385 | | |
386 | | /** Decompose to orientation / scale / position. |
387 | | */ |
388 | | void decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const; |
389 | | |
390 | | /// every Affine3 transform is also a _const_ Matrix4 |
391 | 0 | operator const Matrix4&() const { return reinterpret_cast<const Matrix4&>(*this); } |
392 | | |
393 | | using TransformBaseReal::getTrans; |
394 | | |
395 | | /** Gets a translation matrix. |
396 | | */ |
397 | | static Affine3 getTrans( const Vector3& v ) |
398 | 0 | { |
399 | 0 | return getTrans(v.x, v.y, v.z); |
400 | 0 | } |
401 | | |
402 | | /** Gets a translation matrix - variation for not using a vector. |
403 | | */ |
404 | | static Affine3 getTrans( Real t_x, Real t_y, Real t_z ) |
405 | 0 | { |
406 | 0 | return Affine3(1, 0, 0, t_x, |
407 | 0 | 0, 1, 0, t_y, |
408 | 0 | 0, 0, 1, t_z); |
409 | 0 | } |
410 | | |
411 | | /** Gets a scale matrix. |
412 | | */ |
413 | | static Affine3 getScale( const Vector3& v ) |
414 | 0 | { |
415 | 0 | return getScale(v.x, v.y, v.z); |
416 | 0 | } |
417 | | |
418 | | /** Gets a scale matrix - variation for not using a vector. |
419 | | */ |
420 | | static Affine3 getScale( Real s_x, Real s_y, Real s_z ) |
421 | 0 | { |
422 | 0 | return Affine3(s_x, 0, 0, 0, |
423 | 0 | 0, s_y, 0, 0, |
424 | 0 | 0, 0, s_z, 0); |
425 | 0 | } |
426 | | |
427 | | |
428 | | static const Affine3 ZERO; |
429 | | static const Affine3 IDENTITY; |
430 | | }; |
431 | | |
432 | | inline Matrix4 TransformBaseReal::transpose() const |
433 | 0 | { |
434 | 0 | return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0], |
435 | 0 | m[0][1], m[1][1], m[2][1], m[3][1], |
436 | 0 | m[0][2], m[1][2], m[2][2], m[3][2], |
437 | 0 | m[0][3], m[1][3], m[2][3], m[3][3]); |
438 | 0 | } |
439 | | |
440 | | /** Matrix addition. |
441 | | */ |
442 | | inline Matrix4 operator+(const Matrix4& m, const Matrix4& m2) |
443 | 0 | { |
444 | 0 | Matrix4 r; |
445 | 0 |
|
446 | 0 | r[0][0] = m[0][0] + m2[0][0]; |
447 | 0 | r[0][1] = m[0][1] + m2[0][1]; |
448 | 0 | r[0][2] = m[0][2] + m2[0][2]; |
449 | 0 | r[0][3] = m[0][3] + m2[0][3]; |
450 | 0 |
|
451 | 0 | r[1][0] = m[1][0] + m2[1][0]; |
452 | 0 | r[1][1] = m[1][1] + m2[1][1]; |
453 | 0 | r[1][2] = m[1][2] + m2[1][2]; |
454 | 0 | r[1][3] = m[1][3] + m2[1][3]; |
455 | 0 |
|
456 | 0 | r[2][0] = m[2][0] + m2[2][0]; |
457 | 0 | r[2][1] = m[2][1] + m2[2][1]; |
458 | 0 | r[2][2] = m[2][2] + m2[2][2]; |
459 | 0 | r[2][3] = m[2][3] + m2[2][3]; |
460 | 0 |
|
461 | 0 | r[3][0] = m[3][0] + m2[3][0]; |
462 | 0 | r[3][1] = m[3][1] + m2[3][1]; |
463 | 0 | r[3][2] = m[3][2] + m2[3][2]; |
464 | 0 | r[3][3] = m[3][3] + m2[3][3]; |
465 | 0 |
|
466 | 0 | return r; |
467 | 0 | } |
468 | | |
469 | | /** Matrix subtraction. |
470 | | */ |
471 | | inline Matrix4 operator-(const Matrix4& m, const Matrix4& m2) |
472 | 0 | { |
473 | 0 | Matrix4 r; |
474 | 0 | r[0][0] = m[0][0] - m2[0][0]; |
475 | 0 | r[0][1] = m[0][1] - m2[0][1]; |
476 | 0 | r[0][2] = m[0][2] - m2[0][2]; |
477 | 0 | r[0][3] = m[0][3] - m2[0][3]; |
478 | 0 |
|
479 | 0 | r[1][0] = m[1][0] - m2[1][0]; |
480 | 0 | r[1][1] = m[1][1] - m2[1][1]; |
481 | 0 | r[1][2] = m[1][2] - m2[1][2]; |
482 | 0 | r[1][3] = m[1][3] - m2[1][3]; |
483 | 0 |
|
484 | 0 | r[2][0] = m[2][0] - m2[2][0]; |
485 | 0 | r[2][1] = m[2][1] - m2[2][1]; |
486 | 0 | r[2][2] = m[2][2] - m2[2][2]; |
487 | 0 | r[2][3] = m[2][3] - m2[2][3]; |
488 | 0 |
|
489 | 0 | r[3][0] = m[3][0] - m2[3][0]; |
490 | 0 | r[3][1] = m[3][1] - m2[3][1]; |
491 | 0 | r[3][2] = m[3][2] - m2[3][2]; |
492 | 0 | r[3][3] = m[3][3] - m2[3][3]; |
493 | 0 |
|
494 | 0 | return r; |
495 | 0 | } |
496 | | |
497 | | inline Matrix4 operator*(const Matrix4 &m, const Matrix4 &m2) |
498 | 0 | { |
499 | 0 | Matrix4 r; |
500 | 0 | r[0][0] = m[0][0] * m2[0][0] + m[0][1] * m2[1][0] + m[0][2] * m2[2][0] + m[0][3] * m2[3][0]; |
501 | 0 | r[0][1] = m[0][0] * m2[0][1] + m[0][1] * m2[1][1] + m[0][2] * m2[2][1] + m[0][3] * m2[3][1]; |
502 | 0 | r[0][2] = m[0][0] * m2[0][2] + m[0][1] * m2[1][2] + m[0][2] * m2[2][2] + m[0][3] * m2[3][2]; |
503 | 0 | r[0][3] = m[0][0] * m2[0][3] + m[0][1] * m2[1][3] + m[0][2] * m2[2][3] + m[0][3] * m2[3][3]; |
504 | 0 |
|
505 | 0 | r[1][0] = m[1][0] * m2[0][0] + m[1][1] * m2[1][0] + m[1][2] * m2[2][0] + m[1][3] * m2[3][0]; |
506 | 0 | r[1][1] = m[1][0] * m2[0][1] + m[1][1] * m2[1][1] + m[1][2] * m2[2][1] + m[1][3] * m2[3][1]; |
507 | 0 | r[1][2] = m[1][0] * m2[0][2] + m[1][1] * m2[1][2] + m[1][2] * m2[2][2] + m[1][3] * m2[3][2]; |
508 | 0 | r[1][3] = m[1][0] * m2[0][3] + m[1][1] * m2[1][3] + m[1][2] * m2[2][3] + m[1][3] * m2[3][3]; |
509 | 0 |
|
510 | 0 | r[2][0] = m[2][0] * m2[0][0] + m[2][1] * m2[1][0] + m[2][2] * m2[2][0] + m[2][3] * m2[3][0]; |
511 | 0 | r[2][1] = m[2][0] * m2[0][1] + m[2][1] * m2[1][1] + m[2][2] * m2[2][1] + m[2][3] * m2[3][1]; |
512 | 0 | r[2][2] = m[2][0] * m2[0][2] + m[2][1] * m2[1][2] + m[2][2] * m2[2][2] + m[2][3] * m2[3][2]; |
513 | 0 | r[2][3] = m[2][0] * m2[0][3] + m[2][1] * m2[1][3] + m[2][2] * m2[2][3] + m[2][3] * m2[3][3]; |
514 | 0 |
|
515 | 0 | r[3][0] = m[3][0] * m2[0][0] + m[3][1] * m2[1][0] + m[3][2] * m2[2][0] + m[3][3] * m2[3][0]; |
516 | 0 | r[3][1] = m[3][0] * m2[0][1] + m[3][1] * m2[1][1] + m[3][2] * m2[2][1] + m[3][3] * m2[3][1]; |
517 | 0 | r[3][2] = m[3][0] * m2[0][2] + m[3][1] * m2[1][2] + m[3][2] * m2[2][2] + m[3][3] * m2[3][2]; |
518 | 0 | r[3][3] = m[3][0] * m2[0][3] + m[3][1] * m2[1][3] + m[3][2] * m2[2][3] + m[3][3] * m2[3][3]; |
519 | 0 |
|
520 | 0 | return r; |
521 | 0 | } |
522 | | inline Affine3 operator*(const Affine3 &m, const Affine3 &m2) |
523 | 0 | { |
524 | 0 | return Affine3( |
525 | 0 | m[0][0] * m2[0][0] + m[0][1] * m2[1][0] + m[0][2] * m2[2][0], |
526 | 0 | m[0][0] * m2[0][1] + m[0][1] * m2[1][1] + m[0][2] * m2[2][1], |
527 | 0 | m[0][0] * m2[0][2] + m[0][1] * m2[1][2] + m[0][2] * m2[2][2], |
528 | 0 | m[0][0] * m2[0][3] + m[0][1] * m2[1][3] + m[0][2] * m2[2][3] + m[0][3], |
529 | 0 |
|
530 | 0 | m[1][0] * m2[0][0] + m[1][1] * m2[1][0] + m[1][2] * m2[2][0], |
531 | 0 | m[1][0] * m2[0][1] + m[1][1] * m2[1][1] + m[1][2] * m2[2][1], |
532 | 0 | m[1][0] * m2[0][2] + m[1][1] * m2[1][2] + m[1][2] * m2[2][2], |
533 | 0 | m[1][0] * m2[0][3] + m[1][1] * m2[1][3] + m[1][2] * m2[2][3] + m[1][3], |
534 | 0 |
|
535 | 0 | m[2][0] * m2[0][0] + m[2][1] * m2[1][0] + m[2][2] * m2[2][0], |
536 | 0 | m[2][0] * m2[0][1] + m[2][1] * m2[1][1] + m[2][2] * m2[2][1], |
537 | 0 | m[2][0] * m2[0][2] + m[2][1] * m2[1][2] + m[2][2] * m2[2][2], |
538 | 0 | m[2][0] * m2[0][3] + m[2][1] * m2[1][3] + m[2][2] * m2[2][3] + m[2][3]); |
539 | 0 | } |
540 | | |
541 | | /** Vector transformation using '*'. |
542 | | |
543 | | Transforms the given 3-D vector by the matrix, projecting the |
544 | | result back into <i>w</i> = 1. |
545 | | @note |
546 | | This means that the initial <i>w</i> is considered to be 1.0, |
547 | | and then all the tree elements of the resulting 3-D vector are |
548 | | divided by the resulting <i>w</i>. |
549 | | */ |
550 | | inline Vector3 operator*(const Matrix4& m, const Vector3& v) |
551 | 0 | { |
552 | 0 | Vector3 r; |
553 | 0 |
|
554 | 0 | Real fInvW = 1.0f / ( m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] ); |
555 | 0 |
|
556 | 0 | r.x = ( m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] ) * fInvW; |
557 | 0 | r.y = ( m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] ) * fInvW; |
558 | 0 | r.z = ( m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] ) * fInvW; |
559 | 0 |
|
560 | 0 | return r; |
561 | 0 | } |
562 | | /// @overload |
563 | | inline Vector3 operator*(const Affine3& m,const Vector3& v) |
564 | 0 | { |
565 | 0 | return Vector3( |
566 | 0 | m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3], |
567 | 0 | m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3], |
568 | 0 | m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]); |
569 | 0 | } |
570 | | |
571 | | inline Vector4 operator*(const Matrix4& m, const Vector4& v) |
572 | 0 | { |
573 | 0 | return Vector4( |
574 | 0 | m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w, |
575 | 0 | m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w, |
576 | 0 | m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w, |
577 | 0 | m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w); |
578 | 0 | } |
579 | | inline Vector4 operator*(const Affine3& m, const Vector4& v) |
580 | 0 | { |
581 | 0 | return Vector4( |
582 | 0 | m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w, |
583 | 0 | m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w, |
584 | 0 | m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w, |
585 | 0 | v.w); |
586 | 0 | } |
587 | | |
588 | | inline Vector4 operator * (const Vector4& v, const Matrix4& mat) |
589 | 0 | { |
590 | 0 | return Vector4( |
591 | 0 | v.x*mat[0][0] + v.y*mat[1][0] + v.z*mat[2][0] + v.w*mat[3][0], |
592 | 0 | v.x*mat[0][1] + v.y*mat[1][1] + v.z*mat[2][1] + v.w*mat[3][1], |
593 | 0 | v.x*mat[0][2] + v.y*mat[1][2] + v.z*mat[2][2] + v.w*mat[3][2], |
594 | 0 | v.x*mat[0][3] + v.y*mat[1][3] + v.z*mat[2][3] + v.w*mat[3][3] |
595 | 0 | ); |
596 | 0 | } |
597 | | /** @} */ |
598 | | /** @} */ |
599 | | |
600 | | } |
601 | | #endif |