MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
matrix4x4.cpp
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _matrix4x4_cpp
41 #define _matrix4x4_cpp
42 
43 #include "matrix4x4.h"
44 #include "mathtool.h"
45 #include "serialization.h"
46 #include "entresol.h"
47 
48 #include <OgreMatrix3.h>
49 #include <OgreMatrix4.h>
50 
51 namespace Mezzanine
52 {
53  ///////////////////////////////////////////////////////////////////////////////
54  // Construction and Destruction
55 
57  { this->SetIdentity(); }
58 
59  Matrix4x4::Matrix4x4(const Real& XX, const Real& XY, const Real& XZ, const Real& XW, const Real& YX, const Real& YY, const Real& YZ, const Real& YW,
60  const Real& ZX, const Real& ZY, const Real& ZZ, const Real& ZW, const Real& WX, const Real& WY, const Real& WZ, const Real& WW)
61  { this->SetValues(XX,XY,XZ,XW,YX,YY,YZ,YW,ZX,ZY,ZZ,ZW,WX,WY,WZ,WW); }
62 
63  Matrix4x4::Matrix4x4(const Ogre::Matrix4& Mat)
64  { this->ExtractOgreMatrix4x4(Mat); }
65 
66  Matrix4x4::Matrix4x4(const Vector3& Position, const Vector3& Scale, const Quaternion& Rotation)
67  { this->SetTransform(Position,Scale,Rotation); }
68 
70  { }
71 
72  ///////////////////////////////////////////////////////////////////////////////
73  // Set From Other Data Functions
74 
75  void Matrix4x4::SetValues(const Real& XX, const Real& XY, const Real& XZ, const Real& XW, const Real& YX, const Real& YY, const Real& YZ, const Real& YW,
76  const Real& ZX, const Real& ZY, const Real& ZZ, const Real& ZW, const Real& WX, const Real& WY, const Real& WZ, const Real& WW)
77  {
78  this->Matrix[0][0] = XX; this->Matrix[0][1] = XY; this->Matrix[0][2] = XZ; this->Matrix[0][3] = XW;
79  this->Matrix[1][0] = YX; this->Matrix[1][1] = YY; this->Matrix[1][2] = YZ; this->Matrix[1][3] = YW;
80  this->Matrix[2][0] = ZX; this->Matrix[2][1] = ZY; this->Matrix[2][2] = ZZ; this->Matrix[2][3] = ZW;
81  this->Matrix[3][0] = WX; this->Matrix[3][1] = WY; this->Matrix[3][2] = WZ; this->Matrix[3][3] = WW;
82  }
83 
84  void Matrix4x4::SetTransform(const Vector3& Position, const Vector3& Scale, const Quaternion& Rotation)
85  {
86  Matrix3x3 Mat3x3(Rotation);
87 
88  this->Matrix[0][0] = Scale.X * Mat3x3.Matrix[0][0]; this->Matrix[0][1] = Scale.Y * Mat3x3.Matrix[0][1]; this->Matrix[0][2] = Scale.Z * Mat3x3.Matrix[0][2]; this->Matrix[0][3] = Position.X;
89  this->Matrix[1][0] = Scale.X * Mat3x3.Matrix[1][0]; this->Matrix[1][1] = Scale.Y * Mat3x3.Matrix[1][1]; this->Matrix[1][2] = Scale.Z * Mat3x3.Matrix[1][2]; this->Matrix[1][3] = Position.Y;
90  this->Matrix[2][0] = Scale.X * Mat3x3.Matrix[2][0]; this->Matrix[2][1] = Scale.Y * Mat3x3.Matrix[2][1]; this->Matrix[2][2] = Scale.Z * Mat3x3.Matrix[2][2]; this->Matrix[2][3] = Position.Z;
91 
92  this->Matrix[3][0] = 0; this->Matrix[3][1] = 0; this->Matrix[3][2] = 0; this->Matrix[3][3] = 1;
93  }
94 
96  {
97  this->SetValues(1,0,0,0,
98  0,1,0,0,
99  0,0,1,0,
100  0,0,0,1);
101  }
102 
104  {
105  this->SetValues(0,0,0,0,
106  0,0,0,0,
107  0,0,0,0,
108  0,0,0,0);
109  }
110 
111  ///////////////////////////////////////////////////////////////////////////////
112  // Utility and Conversion Functions
113 
115  {
116  return this->Matrix[0][0] * Minor(1,2,3,1,2,3) -
117  this->Matrix[0][1] * Minor(1,2,3,0,2,3) +
118  this->Matrix[0][2] * Minor(1,2,3,0,1,3) -
119  this->Matrix[0][3] * Minor(1,2,3,0,1,2);
120  }
121 
122  /*void Matrix4x4::Decompose(Vector3& Position, Vector3& Scale, Quaternion& Rotation) const
123  {
124 
125  }// */
126 
128  {
129  Matrix3x3 Convert = this->GetRotationAsMatrix3x3();
130  return Convert.GetAsQuaternion();
131  }
132 
134  {
135  Matrix3x3 Ret;
136 
137  Ret.Matrix[0][0] = this->Matrix[0][0];
138  Ret.Matrix[0][1] = this->Matrix[0][1];
139  Ret.Matrix[0][2] = this->Matrix[0][2];
140  Ret.Matrix[1][0] = this->Matrix[1][0];
141  Ret.Matrix[1][1] = this->Matrix[1][1];
142  Ret.Matrix[1][2] = this->Matrix[1][2];
143  Ret.Matrix[2][0] = this->Matrix[2][0];
144  Ret.Matrix[2][1] = this->Matrix[2][1];
145  Ret.Matrix[2][2] = this->Matrix[2][2];
146 
147  return Ret;
148  }
149 
150  void Matrix4x4::ExtractOgreMatrix4x4(const Ogre::Matrix4& temp)
151  {
152  this->Matrix[0][0] = temp[0][0]; this->Matrix[0][1] = temp[0][1]; this->Matrix[0][2] = temp[0][2]; this->Matrix[0][3] = temp[0][3];
153  this->Matrix[1][0] = temp[1][0]; this->Matrix[1][1] = temp[1][1]; this->Matrix[1][2] = temp[1][2]; this->Matrix[1][3] = temp[1][3];
154  this->Matrix[2][0] = temp[2][0]; this->Matrix[2][1] = temp[2][1]; this->Matrix[2][2] = temp[2][2]; this->Matrix[2][3] = temp[2][3];
155  this->Matrix[3][0] = temp[3][0]; this->Matrix[3][1] = temp[3][1]; this->Matrix[3][2] = temp[3][2]; this->Matrix[3][3] = temp[3][3];
156  }
157 
158  Ogre::Matrix4 Matrix4x4::GetOgreMatrix4x4() const
159  {
160  return Ogre::Matrix4(this->Matrix[0][0], this->Matrix[1][0], this->Matrix[2][0], this->Matrix[3][0],
161  this->Matrix[0][1], this->Matrix[1][1], this->Matrix[2][1], this->Matrix[3][1],
162  this->Matrix[0][2], this->Matrix[1][2], this->Matrix[2][2], this->Matrix[3][2],
163  this->Matrix[0][3], this->Matrix[1][3], this->Matrix[2][3], this->Matrix[3][3]);
164  }
165 
166  ///////////////////////////////////////////////////////////////////////////////
167  // Comparison Operators
168 
169  bool Matrix4x4::operator==(const Matrix4x4& Other) const
170  {
171  for( Whole Row = 0 ; Row < 4 ; ++Row )
172  {
173  for( Whole Col = 0 ; Col < 4 ; ++Col )
174  {
175  if(this->Matrix[Row][Col] != Other.Matrix[Row][Col])
176  return false;
177  }
178  }
179  return true;
180  }
181 
182  bool Matrix4x4::operator!=(const Matrix4x4& Other) const
183  {
184  for( Whole Row = 0 ; Row < 4 ; ++Row )
185  {
186  for( Whole Col = 0 ; Col < 4 ; ++Col )
187  {
188  if(this->Matrix[Row][Col] != Other.Matrix[Row][Col])
189  return true;
190  }
191  }
192  return false;
193  }
194 
195  ///////////////////////////////////////////////////////////////////////////////
196  // Arithmetic Operators With Matrix4x4
197 
199  {
200  Matrix4x4 Ret;
201 
202  Ret.Matrix[0][0] = this->Matrix[0][0] + Other.Matrix[0][0];
203  Ret.Matrix[0][1] = this->Matrix[0][1] + Other.Matrix[0][1];
204  Ret.Matrix[0][2] = this->Matrix[0][2] + Other.Matrix[0][2];
205  Ret.Matrix[0][3] = this->Matrix[0][3] + Other.Matrix[0][3];
206 
207  Ret.Matrix[1][0] = this->Matrix[1][0] + Other.Matrix[1][0];
208  Ret.Matrix[1][1] = this->Matrix[1][1] + Other.Matrix[1][1];
209  Ret.Matrix[1][2] = this->Matrix[1][2] + Other.Matrix[1][2];
210  Ret.Matrix[1][3] = this->Matrix[1][3] + Other.Matrix[1][3];
211 
212  Ret.Matrix[2][0] = this->Matrix[2][0] + Other.Matrix[2][0];
213  Ret.Matrix[2][1] = this->Matrix[2][1] + Other.Matrix[2][1];
214  Ret.Matrix[2][2] = this->Matrix[2][2] + Other.Matrix[2][2];
215  Ret.Matrix[2][3] = this->Matrix[2][3] + Other.Matrix[2][3];
216 
217  Ret.Matrix[3][0] = this->Matrix[3][0] + Other.Matrix[3][0];
218  Ret.Matrix[3][1] = this->Matrix[3][1] + Other.Matrix[3][1];
219  Ret.Matrix[3][2] = this->Matrix[3][2] + Other.Matrix[3][2];
220  Ret.Matrix[3][3] = this->Matrix[3][3] + Other.Matrix[3][3];
221 
222  return Ret;
223  }
224 
226  {
227  Matrix4x4 Ret;
228 
229  Ret.Matrix[0][0] = this->Matrix[0][0] - Other.Matrix[0][0];
230  Ret.Matrix[0][1] = this->Matrix[0][1] - Other.Matrix[0][1];
231  Ret.Matrix[0][2] = this->Matrix[0][2] - Other.Matrix[0][2];
232  Ret.Matrix[0][3] = this->Matrix[0][3] - Other.Matrix[0][3];
233 
234  Ret.Matrix[1][0] = this->Matrix[1][0] - Other.Matrix[1][0];
235  Ret.Matrix[1][1] = this->Matrix[1][1] - Other.Matrix[1][1];
236  Ret.Matrix[1][2] = this->Matrix[1][2] - Other.Matrix[1][2];
237  Ret.Matrix[1][3] = this->Matrix[1][3] - Other.Matrix[1][3];
238 
239  Ret.Matrix[2][0] = this->Matrix[2][0] - Other.Matrix[2][0];
240  Ret.Matrix[2][1] = this->Matrix[2][1] - Other.Matrix[2][1];
241  Ret.Matrix[2][2] = this->Matrix[2][2] - Other.Matrix[2][2];
242  Ret.Matrix[2][3] = this->Matrix[2][3] - Other.Matrix[2][3];
243 
244  Ret.Matrix[3][0] = this->Matrix[3][0] - Other.Matrix[3][0];
245  Ret.Matrix[3][1] = this->Matrix[3][1] - Other.Matrix[3][1];
246  Ret.Matrix[3][2] = this->Matrix[3][2] - Other.Matrix[3][2];
247  Ret.Matrix[3][3] = this->Matrix[3][3] - Other.Matrix[3][3];
248 
249  return Ret;
250  }
251 
253  {
254  return this->Concatenate(Other);
255  }
256 
258  {
259  this->Matrix[0][0] += Other.Matrix[0][0];
260  this->Matrix[0][1] += Other.Matrix[0][1];
261  this->Matrix[0][2] += Other.Matrix[0][2];
262  this->Matrix[0][3] += Other.Matrix[0][3];
263 
264  this->Matrix[1][0] += Other.Matrix[1][0];
265  this->Matrix[1][1] += Other.Matrix[1][1];
266  this->Matrix[1][2] += Other.Matrix[1][2];
267  this->Matrix[1][3] += Other.Matrix[1][3];
268 
269  this->Matrix[2][0] += Other.Matrix[2][0];
270  this->Matrix[2][1] += Other.Matrix[2][1];
271  this->Matrix[2][2] += Other.Matrix[2][2];
272  this->Matrix[2][3] += Other.Matrix[2][3];
273 
274  this->Matrix[3][0] += Other.Matrix[3][0];
275  this->Matrix[3][1] += Other.Matrix[3][1];
276  this->Matrix[3][2] += Other.Matrix[3][2];
277  this->Matrix[3][3] += Other.Matrix[3][3];
278 
279  return *this;
280  }
281 
283  {
284  this->Matrix[0][0] -= Other.Matrix[0][0];
285  this->Matrix[0][1] -= Other.Matrix[0][1];
286  this->Matrix[0][2] -= Other.Matrix[0][2];
287  this->Matrix[0][3] -= Other.Matrix[0][3];
288 
289  this->Matrix[1][0] -= Other.Matrix[1][0];
290  this->Matrix[1][1] -= Other.Matrix[1][1];
291  this->Matrix[1][2] -= Other.Matrix[1][2];
292  this->Matrix[1][3] -= Other.Matrix[1][3];
293 
294  this->Matrix[2][0] -= Other.Matrix[2][0];
295  this->Matrix[2][1] -= Other.Matrix[2][1];
296  this->Matrix[2][2] -= Other.Matrix[2][2];
297  this->Matrix[2][3] -= Other.Matrix[2][3];
298 
299  this->Matrix[3][0] -= Other.Matrix[3][0];
300  this->Matrix[3][1] -= Other.Matrix[3][1];
301  this->Matrix[3][2] -= Other.Matrix[3][2];
302  this->Matrix[3][3] -= Other.Matrix[3][3];
303 
304  return *this;
305  }
306 
308  {
309  *this = this->Concatenate(Other);
310  return *this;
311  }
312 
313  ///////////////////////////////////////////////////////////////////////////////
314  // Arithmetic Operators With Other Datatypes
315 
317  {
318  Vector3 Ret;
319 
320  Real InvW = 1.0f / ( this->Matrix[3][0] * Vec.X + this->Matrix[3][1] * Vec.Y + this->Matrix[3][2] * Vec.Z + this->Matrix[3][3] );
321 
322  Ret.X = ( this->Matrix[0][0] * Vec.X + this->Matrix[0][1] * Vec.Y + this->Matrix[0][2] * Vec.Z + this->Matrix[0][3] ) * InvW;
323  Ret.Y = ( this->Matrix[1][0] * Vec.X + this->Matrix[1][1] * Vec.Y + this->Matrix[1][2] * Vec.Z + this->Matrix[1][3] ) * InvW;
324  Ret.Z = ( this->Matrix[2][0] * Vec.X + this->Matrix[2][1] * Vec.Y + this->Matrix[2][2] * Vec.Z + this->Matrix[2][3] ) * InvW;
325 
326  return Ret;
327  }
328 
329  Matrix4x4 Matrix4x4::operator*(const Real& Scalar) const
330  {
331  return Matrix4x4(
332  Scalar * this->Matrix[0][0], Scalar * this->Matrix[0][1], Scalar * this->Matrix[0][2], Scalar * this->Matrix[0][3],
333  Scalar * this->Matrix[1][0], Scalar * this->Matrix[1][1], Scalar * this->Matrix[1][2], Scalar * this->Matrix[1][3],
334  Scalar * this->Matrix[2][0], Scalar * this->Matrix[2][1], Scalar * this->Matrix[2][2], Scalar * this->Matrix[2][3],
335  Scalar * this->Matrix[3][0], Scalar * this->Matrix[3][1], Scalar * this->Matrix[3][2], Scalar * this->Matrix[3][3]);
336  }
337 
339  {
340  this->Matrix[0][0] *= Scalar; this->Matrix[0][1] *= Scalar; this->Matrix[0][2] *= Scalar; this->Matrix[0][3] *= Scalar;
341  this->Matrix[1][0] *= Scalar; this->Matrix[1][1] *= Scalar; this->Matrix[1][2] *= Scalar; this->Matrix[1][3] *= Scalar;
342  this->Matrix[2][0] *= Scalar; this->Matrix[2][1] *= Scalar; this->Matrix[2][2] *= Scalar; this->Matrix[2][3] *= Scalar;
343  this->Matrix[3][0] *= Scalar; this->Matrix[3][1] *= Scalar; this->Matrix[3][2] *= Scalar; this->Matrix[3][3] *= Scalar;
344  return *this;
345  }
346 
347  ///////////////////////////////////////////////////////////////////////////////
348  // Other Operators
349 
350  void Matrix4x4::operator=(const Matrix4x4& Other)
351  {
352  for( Whole Row = 0 ; Row < 4 ; ++Row )
353  {
354  for( Whole Col = 0 ; Col < 4 ; ++Col )
355  {
356  this->Matrix[Row][Col] = Other.Matrix[Row][Col];
357  }
358  }
359  }
360 
361  void Matrix4x4::operator=(const Matrix3x3& Other)
362  {
363  this->Matrix[0][0] = Other.Matrix[0][0]; this->Matrix[0][1] = Other.Matrix[0][1]; this->Matrix[0][2] = Other.Matrix[0][2];
364  this->Matrix[1][0] = Other.Matrix[1][0]; this->Matrix[1][1] = Other.Matrix[1][1]; this->Matrix[1][2] = Other.Matrix[1][2];
365  this->Matrix[2][0] = Other.Matrix[2][0]; this->Matrix[2][1] = Other.Matrix[2][1]; this->Matrix[2][2] = Other.Matrix[2][2];
366  }
367 
368  ///////////////////////////////////////////////////////////////////////////////
369  // Fancy Math
370 
372  {
373  return Matrix4x4(this->Matrix[0][0], this->Matrix[1][0], this->Matrix[2][0], this->Matrix[3][0],
374  this->Matrix[0][1], this->Matrix[1][1], this->Matrix[2][1], this->Matrix[3][1],
375  this->Matrix[0][2], this->Matrix[1][2], this->Matrix[2][2], this->Matrix[3][2],
376  this->Matrix[0][3], this->Matrix[1][3], this->Matrix[2][3], this->Matrix[3][3]);
377  }
378 
380  {
381  return Matrix4x4( Minor(1,2,3,1,2,3),-Minor(0,2,3,1,2,3),Minor(0,1,3,1,2,3),-Minor(0,1,2,1,2,3),
382  -Minor(1,2,3,0,2,3),Minor(0,2,3,0,2,3),-Minor(0,1,3,0,2,3),Minor(0,1,2,0,2,3),
383  Minor(1,2,3,0,1,3),-Minor(0,2,3,0,1,3),Minor(0,1,3,0,1,3),-Minor(0,1,2,0,1,3),
384  -Minor(1,2,3,0,1,2),Minor(0,2,3,0,1,2),-Minor(0,1,3,0,1,2),Minor(0,1,2,0,1,2));
385  }
386 
388  {
389  Real m00 = this->Matrix[0][0], m01 = this->Matrix[0][1], m02 = this->Matrix[0][2], m03 = this->Matrix[0][3];
390  Real m10 = this->Matrix[1][0], m11 = this->Matrix[1][1], m12 = this->Matrix[1][2], m13 = this->Matrix[1][3];
391  Real m20 = this->Matrix[2][0], m21 = this->Matrix[2][1], m22 = this->Matrix[2][2], m23 = this->Matrix[2][3];
392  Real m30 = this->Matrix[3][0], m31 = this->Matrix[3][1], m32 = this->Matrix[3][2], m33 = this->Matrix[3][3];
393 
394  Real v0 = m20 * m31 - m21 * m30;
395  Real v1 = m20 * m32 - m22 * m30;
396  Real v2 = m20 * m33 - m23 * m30;
397  Real v3 = m21 * m32 - m22 * m31;
398  Real v4 = m21 * m33 - m23 * m31;
399  Real v5 = m22 * m33 - m23 * m32;
400 
401  Real t00 = + (v5 * m11 - v4 * m12 + v3 * m13);
402  Real t10 = - (v5 * m10 - v2 * m12 + v1 * m13);
403  Real t20 = + (v4 * m10 - v2 * m11 + v0 * m13);
404  Real t30 = - (v3 * m10 - v1 * m11 + v0 * m12);
405 
406  Real invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);
407 
408  Real d00 = t00 * invDet;
409  Real d10 = t10 * invDet;
410  Real d20 = t20 * invDet;
411  Real d30 = t30 * invDet;
412 
413  Real d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
414  Real d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
415  Real d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
416  Real d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
417 
418  v0 = m10 * m31 - m11 * m30;
419  v1 = m10 * m32 - m12 * m30;
420  v2 = m10 * m33 - m13 * m30;
421  v3 = m11 * m32 - m12 * m31;
422  v4 = m11 * m33 - m13 * m31;
423  v5 = m12 * m33 - m13 * m32;
424 
425  Real d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
426  Real d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
427  Real d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
428  Real d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
429 
430  v0 = m21 * m10 - m20 * m11;
431  v1 = m22 * m10 - m20 * m12;
432  v2 = m23 * m10 - m20 * m13;
433  v3 = m22 * m11 - m21 * m12;
434  v4 = m23 * m11 - m21 * m13;
435  v5 = m23 * m12 - m22 * m13;
436 
437  Real d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
438  Real d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
439  Real d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
440  Real d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
441 
442  return Matrix4x4(
443  d00, d01, d02, d03,
444  d10, d11, d12, d13,
445  d20, d21, d22, d23,
446  d30, d31, d32, d33);
447  }
448 
450  {
451  Matrix4x4 Ret;
452  Ret.Matrix[0][0] = this->Matrix[0][0] * Mat.Matrix[0][0] + this->Matrix[0][1] * Mat.Matrix[1][0] + this->Matrix[0][2] * Mat.Matrix[2][0] + this->Matrix[0][3] * Mat.Matrix[3][0];
453  Ret.Matrix[0][1] = this->Matrix[0][0] * Mat.Matrix[0][1] + this->Matrix[0][1] * Mat.Matrix[1][1] + this->Matrix[0][2] * Mat.Matrix[2][1] + this->Matrix[0][3] * Mat.Matrix[3][1];
454  Ret.Matrix[0][2] = this->Matrix[0][0] * Mat.Matrix[0][2] + this->Matrix[0][1] * Mat.Matrix[1][2] + this->Matrix[0][2] * Mat.Matrix[2][2] + this->Matrix[0][3] * Mat.Matrix[3][2];
455  Ret.Matrix[0][3] = this->Matrix[0][0] * Mat.Matrix[0][3] + this->Matrix[0][1] * Mat.Matrix[1][3] + this->Matrix[0][2] * Mat.Matrix[2][3] + this->Matrix[0][3] * Mat.Matrix[3][3];
456 
457  Ret.Matrix[1][0] = this->Matrix[1][0] * Mat.Matrix[0][0] + this->Matrix[1][1] * Mat.Matrix[1][0] + this->Matrix[1][2] * Mat.Matrix[2][0] + this->Matrix[1][3] * Mat.Matrix[3][0];
458  Ret.Matrix[1][1] = this->Matrix[1][0] * Mat.Matrix[0][1] + this->Matrix[1][1] * Mat.Matrix[1][1] + this->Matrix[1][2] * Mat.Matrix[2][1] + this->Matrix[1][3] * Mat.Matrix[3][1];
459  Ret.Matrix[1][2] = this->Matrix[1][0] * Mat.Matrix[0][2] + this->Matrix[1][1] * Mat.Matrix[1][2] + this->Matrix[1][2] * Mat.Matrix[2][2] + this->Matrix[1][3] * Mat.Matrix[3][2];
460  Ret.Matrix[1][3] = this->Matrix[1][0] * Mat.Matrix[0][3] + this->Matrix[1][1] * Mat.Matrix[1][3] + this->Matrix[1][2] * Mat.Matrix[2][3] + this->Matrix[1][3] * Mat.Matrix[3][3];
461 
462  Ret.Matrix[2][0] = this->Matrix[2][0] * Mat.Matrix[0][0] + this->Matrix[2][1] * Mat.Matrix[1][0] + this->Matrix[2][2] * Mat.Matrix[2][0] + this->Matrix[2][3] * Mat.Matrix[3][0];
463  Ret.Matrix[2][1] = this->Matrix[2][0] * Mat.Matrix[0][1] + this->Matrix[2][1] * Mat.Matrix[1][1] + this->Matrix[2][2] * Mat.Matrix[2][1] + this->Matrix[2][3] * Mat.Matrix[3][1];
464  Ret.Matrix[2][2] = this->Matrix[2][0] * Mat.Matrix[0][2] + this->Matrix[2][1] * Mat.Matrix[1][2] + this->Matrix[2][2] * Mat.Matrix[2][2] + this->Matrix[2][3] * Mat.Matrix[3][2];
465  Ret.Matrix[2][3] = this->Matrix[2][0] * Mat.Matrix[0][3] + this->Matrix[2][1] * Mat.Matrix[1][3] + this->Matrix[2][2] * Mat.Matrix[2][3] + this->Matrix[2][3] * Mat.Matrix[3][3];
466 
467  Ret.Matrix[3][0] = this->Matrix[3][0] * Mat.Matrix[0][0] + this->Matrix[3][1] * Mat.Matrix[1][0] + this->Matrix[3][2] * Mat.Matrix[2][0] + this->Matrix[3][3] * Mat.Matrix[3][0];
468  Ret.Matrix[3][1] = this->Matrix[3][0] * Mat.Matrix[0][1] + this->Matrix[3][1] * Mat.Matrix[1][1] + this->Matrix[3][2] * Mat.Matrix[2][1] + this->Matrix[3][3] * Mat.Matrix[3][1];
469  Ret.Matrix[3][2] = this->Matrix[3][0] * Mat.Matrix[0][2] + this->Matrix[3][1] * Mat.Matrix[1][2] + this->Matrix[3][2] * Mat.Matrix[2][2] + this->Matrix[3][3] * Mat.Matrix[3][2];
470  Ret.Matrix[3][3] = this->Matrix[3][0] * Mat.Matrix[0][3] + this->Matrix[3][1] * Mat.Matrix[1][3] + this->Matrix[3][2] * Mat.Matrix[2][3] + this->Matrix[3][3] * Mat.Matrix[3][3];
471 
472  return Ret;
473  }
474 
475  Real Matrix4x4::Minor(const Whole& Row1, const Whole& Row2, const Whole& Row3, const Whole& Col1, const Whole& Col2, const Whole& Col3) const
476  {
477  return this->Matrix[Row1][Col1] * (this->Matrix[Row2][Col2] * this->Matrix[Row3][Col3] - this->Matrix[Row3][Col2] * this->Matrix[Row2][Col3]) -
478  this->Matrix[Row1][Col2] * (this->Matrix[Row2][Col1] * this->Matrix[Row3][Col3] - this->Matrix[Row3][Col1] * this->Matrix[Row2][Col3]) +
479  this->Matrix[Row1][Col3] * (this->Matrix[Row2][Col1] * this->Matrix[Row3][Col2] - this->Matrix[Row3][Col1] * this->Matrix[Row2][Col2]);
480  }
481 
482  ///////////////////////////////////////////////////////////////////////////////
483  // Serialization
484 
485  void Matrix4x4::ProtoSerialize(XML::Node& CurrentRoot) const
486  {
487  XML::Node MatrixNode = CurrentRoot.AppendChild( this->GetSerializableName() );
488 
489  if( MatrixNode.AppendAttribute("Version").SetValue("1") &&
490  MatrixNode.AppendAttribute("XX").SetValue( this->Matrix[0][0] ) &&
491  MatrixNode.AppendAttribute("XY").SetValue( this->Matrix[0][1] ) &&
492  MatrixNode.AppendAttribute("XZ").SetValue( this->Matrix[0][2] ) &&
493  MatrixNode.AppendAttribute("XW").SetValue( this->Matrix[0][3] ) &&
494  MatrixNode.AppendAttribute("YX").SetValue( this->Matrix[1][0] ) &&
495  MatrixNode.AppendAttribute("YY").SetValue( this->Matrix[1][1] ) &&
496  MatrixNode.AppendAttribute("YZ").SetValue( this->Matrix[1][2] ) &&
497  MatrixNode.AppendAttribute("YW").SetValue( this->Matrix[1][3] ) &&
498  MatrixNode.AppendAttribute("ZX").SetValue( this->Matrix[2][0] ) &&
499  MatrixNode.AppendAttribute("ZY").SetValue( this->Matrix[2][1] ) &&
500  MatrixNode.AppendAttribute("ZZ").SetValue( this->Matrix[2][2] ) &&
501  MatrixNode.AppendAttribute("ZW").SetValue( this->Matrix[2][3] ) &&
502  MatrixNode.AppendAttribute("WX").SetValue( this->Matrix[3][0] ) &&
503  MatrixNode.AppendAttribute("WY").SetValue( this->Matrix[3][1] ) &&
504  MatrixNode.AppendAttribute("WZ").SetValue( this->Matrix[3][2] ) &&
505  MatrixNode.AppendAttribute("WW").SetValue( this->Matrix[3][3] ) )
506  {
507  return;
508  }else{
509  SerializeError("Create XML Attributes", this->GetSerializableName(),true);
510  }
511  }
512 
514  {
515  XML::Attribute CurrAttrib;
516  if( String(OneNode.Name()) == this->GetSerializableName() ) {
517  if( OneNode.GetAttribute("Version").AsInt() == 1 ) {
518  CurrAttrib = OneNode.GetAttribute("XX");
519  if( !CurrAttrib.Empty() )
520  this->Matrix[0][0] = CurrAttrib.AsReal();
521 
522  CurrAttrib = OneNode.GetAttribute("XY");
523  if( !CurrAttrib.Empty() )
524  this->Matrix[0][1] = CurrAttrib.AsReal();
525 
526  CurrAttrib = OneNode.GetAttribute("XZ");
527  if( !CurrAttrib.Empty() )
528  this->Matrix[0][2] = CurrAttrib.AsReal();
529 
530  CurrAttrib = OneNode.GetAttribute("XW");
531  if( !CurrAttrib.Empty() )
532  this->Matrix[0][3] = CurrAttrib.AsReal();
533 
534  CurrAttrib = OneNode.GetAttribute("YX");
535  if( !CurrAttrib.Empty() )
536  this->Matrix[1][0] = CurrAttrib.AsReal();
537 
538  CurrAttrib = OneNode.GetAttribute("YY");
539  if( !CurrAttrib.Empty() )
540  this->Matrix[1][1] = CurrAttrib.AsReal();
541 
542  CurrAttrib = OneNode.GetAttribute("YZ");
543  if( !CurrAttrib.Empty() )
544  this->Matrix[1][2] = CurrAttrib.AsReal();
545 
546  CurrAttrib = OneNode.GetAttribute("YW");
547  if( !CurrAttrib.Empty() )
548  this->Matrix[1][3] = CurrAttrib.AsReal();
549 
550  CurrAttrib = OneNode.GetAttribute("ZX");
551  if( !CurrAttrib.Empty() )
552  this->Matrix[2][0] = CurrAttrib.AsReal();
553 
554  CurrAttrib = OneNode.GetAttribute("ZY");
555  if( !CurrAttrib.Empty() )
556  this->Matrix[2][1] = CurrAttrib.AsReal();
557 
558  CurrAttrib = OneNode.GetAttribute("ZZ");
559  if( !CurrAttrib.Empty() )
560  this->Matrix[2][2] = CurrAttrib.AsReal();
561 
562  CurrAttrib = OneNode.GetAttribute("ZW");
563  if( !CurrAttrib.Empty() )
564  this->Matrix[2][3] = CurrAttrib.AsReal();
565 
566  CurrAttrib = OneNode.GetAttribute("WX");
567  if( !CurrAttrib.Empty() )
568  this->Matrix[3][0] = CurrAttrib.AsReal();
569 
570  CurrAttrib = OneNode.GetAttribute("WY");
571  if( !CurrAttrib.Empty() )
572  this->Matrix[3][1] = CurrAttrib.AsReal();
573 
574  CurrAttrib = OneNode.GetAttribute("WZ");
575  if( !CurrAttrib.Empty() )
576  this->Matrix[3][2] = CurrAttrib.AsReal();
577 
578  CurrAttrib = OneNode.GetAttribute("WW");
579  if( !CurrAttrib.Empty() )
580  this->Matrix[3][3] = CurrAttrib.AsReal();
581  }else{
582  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + this->GetSerializableName() + ": Not Version 1.");
583  }
584  }else{
585  MEZZ_EXCEPTION(Exception::II_IDENTITY_INVALID_EXCEPTION,"Attempting to deserialize a " + this->GetSerializableName() + ", found a " + String(OneNode.Name()) + ".");
586  }
587  }
588 
590  {
591  return "Matrix4x4";
592  }
593 }//Mezzanine
594 
595 #endif