VR-Forces Development_Version Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DtMatrix4.h
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright (c) 2014 MAK Technologies, Inc.
3 ** All rights reserved.
4 ******************************************************************************/
5 
9 #pragma once
10 
11 #include "DtAssert.h"
12 #include "DtMatrix3.h"
13 
14 namespace makVrv {
15 
18  template<class T>
19  class DtMatrix4
20  {
21  public:
23  DtMatrix4();
25  DtMatrix4(const T rhs[4][4]);
27  DtMatrix4(T m00, T m01, T m02, T m03
28  , T m10, T m11, T m12, T m13
29  , T m20, T m21, T m22, T m23
30  , T m30, T m31, T m32, T m33);
31 
35  DtMatrix4(const DtMatrix3<T>& rhs);
36 
38  virtual ~DtMatrix4();
39 
41  void operator=(const DtMatrix3<T>& rhs);
42 
44  DtMatrix4 operator*(const DtMatrix4& rhs) const;
45 
47  DtVector4<T> operator*(const DtVector4<T>& rhs) const;
48 
50  void setZero(void);
51 
53  void setIdentity(void);
54 
56  DtMatrix4 getTranspose(void) const;
57 
59  bool isEqual(const DtMatrix4& rhs, T tolerance) const;
60 
62 
63  const T* operator [](size_t iRow) const;
64  T* operator [](size_t iRow);
65 
66  const void* ptr(void) const;
67 
69 
71  bool isAffine(void) const;
72 
75 
77  DtMatrix4<T> getInverse(void) const;
78 
80  // begin with
81  DtMatrix4<T> getInverseAffine(void) const;
82  private:
83  union
84  {
85  T _m[16];
86  T m[4][4];
87  };
88  };
89 
90  template <class T>
91  DtMatrix4<T> DtMatrix4<T>::theIdentityMatrix = DtMatrix4<T>(1,0,0,0
92  , 0,1,0,0
93  , 0,0,1,0
94  , 0,0,0,1);
95 
98 
99  template<class T>
101  {
102 
103  }
104 
105  template<class T>
106  DtMatrix4<T>::DtMatrix4(const T rhs[4][4])
107  {
108  memcpy(_m, rhs, 16*sizeof(T));
109  }
110 
111  template<class T>
112  DtMatrix4<T>::DtMatrix4(T m00, T m01, T m02, T m03
113  , T m10, T m11, T m12, T m13
114  , T m20, T m21, T m22, T m23
115  , T m30, T m31, T m32, T m33)
116  {
117  m[0][0]=m00;m[0][1]=m01;m[0][2]=m02;m[0][3]=m03;
118  m[1][0]=m10;m[1][1]=m11;m[1][2]=m12;m[1][3]=m13;
119  m[2][0]=m20;m[2][1]=m21;m[2][2]=m22;m[2][3]=m23;
120  m[3][0]=m30;m[3][1]=m31;m[3][2]=m32;m[3][3]=m33;
121  }
122 
123  template<class T>
125  {
126 
127  }
128  template<class T>
129  const void* DtMatrix4<T>::ptr(void) const
130  {
131  return _m;
132  }
133 
134  template<class T>
135  const T* DtMatrix4<T>::operator [](size_t iRow) const
136  {
138  return m[iRow];
139  }
140  template<class T>
142  {
144  return m[iRow];
145  }
146 
147  template<class T>
149  {
150  /*
151  | lhs.00, lhs.01, lhs.02, lhs.03 | | rhs.00, rhs.01, rhs.02, rhs.03 |
152  | lhs.10, lhs.11, lhs.12, lhs.13 | | rhs.10, rhs.11, rhs.12, rhs.13 |
153  | lhs.20, lhs.21, lhs.22, lhs.23 | | rhs.20, rhs.21, rhs.22, rhs.23 |
154  | lhs.30, lhs.31, lhs.32, lhs.33 | | rhs.30, rhs.31, rhs.32, rhs.33 |
155  */
156  const DtMatrix4& lhs = *this;
157 
158  DtMatrix4 result;
159 
160  result.m[0][0] = lhs.m[0][0]*rhs.m[0][0] + lhs.m[0][1]*rhs.m[1][0] + lhs.m[0][2]*rhs.m[2][0] + lhs.m[0][3]*rhs.m[3][0];
161  result.m[0][1] = lhs.m[0][0]*rhs.m[0][1] + lhs.m[0][1]*rhs.m[1][1] + lhs.m[0][2]*rhs.m[2][1] + lhs.m[0][3]*rhs.m[3][1];
162  result.m[0][2] = lhs.m[0][0]*rhs.m[0][2] + lhs.m[0][1]*rhs.m[1][2] + lhs.m[0][2]*rhs.m[2][2] + lhs.m[0][3]*rhs.m[3][2];
163  result.m[0][3] = lhs.m[0][0]*rhs.m[0][3] + lhs.m[0][1]*rhs.m[1][3] + lhs.m[0][2]*rhs.m[2][3] + lhs.m[0][3]*rhs.m[3][3];
164 
165  result.m[1][0] = lhs.m[1][0]*rhs.m[0][0] + lhs.m[1][1]*rhs.m[1][0] + lhs.m[1][2]*rhs.m[2][0] + lhs.m[1][3]*rhs.m[3][0];
166  result.m[1][1] = lhs.m[1][0]*rhs.m[0][1] + lhs.m[1][1]*rhs.m[1][1] + lhs.m[1][2]*rhs.m[2][1] + lhs.m[1][3]*rhs.m[3][1];
167  result.m[1][2] = lhs.m[1][0]*rhs.m[0][2] + lhs.m[1][1]*rhs.m[1][2] + lhs.m[1][2]*rhs.m[2][2] + lhs.m[1][3]*rhs.m[3][2];
168  result.m[1][3] = lhs.m[1][0]*rhs.m[0][3] + lhs.m[1][1]*rhs.m[1][3] + lhs.m[1][2]*rhs.m[2][3] + lhs.m[1][3]*rhs.m[3][3];
169 
170  result.m[2][0] = lhs.m[2][0]*rhs.m[0][0] + lhs.m[2][1]*rhs.m[1][0] + lhs.m[2][2]*rhs.m[2][0] + lhs.m[2][3]*rhs.m[3][0];
171  result.m[2][1] = lhs.m[2][0]*rhs.m[0][1] + lhs.m[2][1]*rhs.m[1][1] + lhs.m[2][2]*rhs.m[2][1] + lhs.m[2][3]*rhs.m[3][1];
172  result.m[2][2] = lhs.m[2][0]*rhs.m[0][2] + lhs.m[2][1]*rhs.m[1][2] + lhs.m[2][2]*rhs.m[2][2] + lhs.m[2][3]*rhs.m[3][2];
173  result.m[2][3] = lhs.m[2][0]*rhs.m[0][3] + lhs.m[2][1]*rhs.m[1][3] + lhs.m[2][2]*rhs.m[2][3] + lhs.m[2][3]*rhs.m[3][3];
174 
175  result.m[3][0] = lhs.m[3][0]*rhs.m[0][0] + lhs.m[3][1]*rhs.m[1][0] + lhs.m[3][2]*rhs.m[2][0] + lhs.m[3][3]*rhs.m[3][0];
176  result.m[3][1] = lhs.m[3][0]*rhs.m[0][1] + lhs.m[3][1]*rhs.m[1][1] + lhs.m[3][2]*rhs.m[2][1] + lhs.m[3][3]*rhs.m[3][1];
177  result.m[3][2] = lhs.m[3][0]*rhs.m[0][2] + lhs.m[3][1]*rhs.m[1][2] + lhs.m[3][2]*rhs.m[2][2] + lhs.m[3][3]*rhs.m[3][2];
178  result.m[3][3] = lhs.m[3][0]*rhs.m[0][3] + lhs.m[3][1]*rhs.m[1][3] + lhs.m[3][2]*rhs.m[2][3] + lhs.m[3][3]*rhs.m[3][3];
179 
180  return result;
181  }
182 
183 
184  template<class T>
186  {
187  /*
188  | lhs.00, lhs.01, lhs.02, lhs.03 | | rhs.0 |
189  | lhs.10, lhs.11, lhs.12, lhs.13 | | rhs.1 |
190  | lhs.20, lhs.21, lhs.22, lhs.23 | | rhs.2 |
191  | lhs.30, lhs.31, lhs.32, lhs.33 | | rhs.3 |
192  */
193  DtVector4<T> vResult;
194 
195  const DtMatrix4& lhs = *this;
196 
197  vResult.x = lhs.m[0][0]*rhs.x + lhs.m[0][1]*rhs.y + lhs.m[0][2]*rhs.z + lhs.m[0][3]*rhs.w;
198  vResult.y = lhs.m[1][0]*rhs.x + lhs.m[1][1]*rhs.y + lhs.m[1][2]*rhs.z + lhs.m[1][3]*rhs.w;
199  vResult.z = lhs.m[2][0]*rhs.x + lhs.m[2][1]*rhs.y + lhs.m[2][2]*rhs.z + lhs.m[2][3]*rhs.w;
200  vResult.w = lhs.m[3][0]*rhs.x + lhs.m[3][1]*rhs.y + lhs.m[3][2]*rhs.z + lhs.m[3][3]*rhs.w;
201 
202  return vResult;
203  }
204 
205  template<class T>
207  {
208  memset(_m, 0, 16*sizeof(T));
209  }
210 
211  template<class T>
213  {
215  m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
216  }
217 
218  template<class T>
220  {
221  return DtMatrix4<T>(
222  m[0][0], m[1][0], m[2][0], m[3][0]
223  , m[0][1], m[1][1], m[2][1], m[3][1]
224  , m[0][2], m[1][2], m[2][2], m[3][2]
225  , m[0][3], m[1][3], m[2][3], m[3][3]
226  );
227  }
228 
229  template<class T>
231  {
232  DtMatrix4<T> result = *this;
233  result[2][0] = (result[2][0] + result[3][0])*0.5f;
234  result[2][1] = (result[2][1] + result[3][1])*0.5f;
235  result[2][2] = (result[2][2] + result[3][2])*0.5f;
236  result[2][3] = (result[2][3] + result[3][3])*0.5f;
237  return result;
238  }
239 
240  template<class T>
241  bool DtMatrix4<T>::isEqual(const DtMatrix4<T>& rhs, T tolerance) const
242  {
243  const DtMatrix4& lhs = *this;
244  for(size_t i = 0; i < 4; ++i)
245  {
246  for(size_t j = 0; j < 4; ++j)
247  {
248  if (!DtMath::isEqual(lhs[i][j], rhs[i][j], tolerance))
249  return false;
250  }
251  }
252  return true;
253  }
254 
255  template<class T>
257  {
258  operator=(rhs);
259  }
260  template<class T>
262  {
263  setIdentity();
264 
265  m[0][0] = rhs[0][0]; m[0][1] = rhs[0][1]; m[0][2] = rhs[0][2];
266  m[1][0] = rhs[1][0]; m[1][1] = rhs[1][1]; m[1][2] = rhs[1][2];
267  m[2][0] = rhs[2][0]; m[2][1] = rhs[2][1]; m[2][2] = rhs[2][2];
268  }
269 
270  template<class T>
271  bool DtMatrix4<T>::isAffine(void) const
272  {
273  return m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0 && m[3][3] == 1;
274  }
275 
276  template<class T>
278  {
279  ASSERT_PREDICATE(IsAffine());
280  if (DtMatrix4<T>::IsAffine()==false)
282 
283  return DtVector3<T>(
284  m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + + m[0][3]
285  , m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + + m[1][3]
286  , m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + + m[2][3]
287  );
288  }
289 
290  template<class T>
292  {
293  ASSERT_PREDICATE(IsAffine());
294  if (DtMatrix4<T>::IsAffine()==false)
295  return DtVector4<T>::ZERO;
296 
297  return DtVector4<T>(
298  m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + + m[0][3]
299  , m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + + m[1][3]
300  , m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + + m[2][3]
301  , v.w
302  );
303  }
304 
305  template<class T>
307  {
308  T m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
309  T m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
310  T m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
311  T m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];
312 
313  T v0 = m20 * m31 - m21 * m30;
314  T v1 = m20 * m32 - m22 * m30;
315  T v2 = m20 * m33 - m23 * m30;
316  T v3 = m21 * m32 - m22 * m31;
317  T v4 = m21 * m33 - m23 * m31;
318  T v5 = m22 * m33 - m23 * m32;
319 
320  T t00 = + (v5 * m11 - v4 * m12 + v3 * m13);
321  T t10 = - (v5 * m10 - v2 * m12 + v1 * m13);
322  T t20 = + (v4 * m10 - v2 * m11 + v0 * m13);
323  T t30 = - (v3 * m10 - v1 * m11 + v0 * m12);
324 
325  T invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);
326 
327  T d00 = t00 * invDet;
328  T d10 = t10 * invDet;
329  T d20 = t20 * invDet;
330  T d30 = t30 * invDet;
331 
332  T d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
333  T d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
334  T d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
335  T d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
336 
337  v0 = m10 * m31 - m11 * m30;
338  v1 = m10 * m32 - m12 * m30;
339  v2 = m10 * m33 - m13 * m30;
340  v3 = m11 * m32 - m12 * m31;
341  v4 = m11 * m33 - m13 * m31;
342  v5 = m12 * m33 - m13 * m32;
343 
344  T d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
345  T d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
346  T d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
347  T d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
348 
349  v0 = m21 * m10 - m20 * m11;
350  v1 = m22 * m10 - m20 * m12;
351  v2 = m23 * m10 - m20 * m13;
352  v3 = m22 * m11 - m21 * m12;
353  v4 = m23 * m11 - m21 * m13;
354  v5 = m23 * m12 - m22 * m13;
355 
356  T d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
357  T d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
358  T d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
359  T d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
360 
361  return DtMatrix4(
362  d00, d01, d02, d03,
363  d10, d11, d12, d13,
364  d20, d21, d22, d23,
365  d30, d31, d32, d33);
366  }
367 
368  template<class T>
370  {
371  ASSERT_PREDICATE(IsAffine());
372 
373  T m10 = m[1][0], m11 = m[1][1], m12 = m[1][2];
374  T m20 = m[2][0], m21 = m[2][1], m22 = m[2][2];
375 
376  T t00 = m22 * m11 - m21 * m12;
377  T t10 = m20 * m12 - m22 * m10;
378  T t20 = m21 * m10 - m20 * m11;
379 
380  T m00 = m[0][0], m01 = m[0][1], m02 = m[0][2];
381 
382  T invDet = 1 / (m00 * t00 + m01 * t10 + m02 * t20);
383 
384  t00 *= invDet; t10 *= invDet; t20 *= invDet;
385 
386  m00 *= invDet; m01 *= invDet; m02 *= invDet;
387 
388  T r00 = t00;
389  T r01 = m02 * m21 - m01 * m22;
390  T r02 = m01 * m12 - m02 * m11;
391 
392  T r10 = t10;
393  T r11 = m00 * m22 - m02 * m20;
394  T r12 = m02 * m10 - m00 * m12;
395 
396  T r20 = t20;
397  T r21 = m01 * m20 - m00 * m21;
398  T r22 = m00 * m11 - m01 * m10;
399 
400  T m03 = m[0][3], m13 = m[1][3], m23 = m[2][3];
401 
402  T r03 = - (r00 * m03 + r01 * m13 + r02 * m23);
403  T r13 = - (r10 * m03 + r11 * m13 + r12 * m23);
404  T r23 = - (r20 * m03 + r21 * m13 + r22 * m23);
405 
406  return DtMatrix4<T>(
407  r00, r01, r02, r03,
408  r10, r11, r12, r13,
409  r20, r21, r22, r23,
410  0, 0, 0, 1);
411  }
412 
413  template<class T>
414  inline std::ostream& operator <<
415  ( std::ostream& o, const DtMatrix4<T>& mat )
416  {
417  for(size_t i = 0; i < 4; ++i)
418  {
419  o<<mat[i][0]<<" "<<mat[i][1]<<" "<<mat[i][2]<<" "<<mat[i][3]<<std::endl;
420  }
421  return o;
422  }
423 
424 } //namespace makVrv

Document ID: Generated on Tue Mar 8 22:13:38 EST 2016 from SVN revision 162938
Copyright © 2005-2015 VT MÄK. All Rights Reserved (www.mak.com)