VR-Vantage 2.2 API 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(const T rhs[16]);
29  DtMatrix4(T m00, T m01, T m02, T m03
30  , T m10, T m11, T m12, T m13
31  , T m20, T m21, T m22, T m23
32  , T m30, T m31, T m32, T m33);
36  DtMatrix4(const DtMatrix3<T>& rhs);
37 
39  virtual ~DtMatrix4();
40 
42  void operator=(const DtMatrix3<T>& rhs);
43 
45  DtMatrix4 operator*(const DtMatrix4& rhs) const;
46 
48  DtVector4<T> operator*(const DtVector4<T>& rhs) const;
49 
51  void setZero(void);
52 
54  void setIdentity(void);
55 
57  DtMatrix4 getTranspose(void) const;
58 
60  bool isEqual(const DtMatrix4& rhs, T tolerance) const;
61 
62  bool isIdentity(T tolerance = std::numeric_limits<T>::epsilon()) const;
63 
65 
66  const T* operator [](size_t iRow) const;
67  T* operator [](size_t iRow);
68 
69  const void* ptr(void) const;
70 
72 
74  bool isAffine(void) const;
75 
78 
80  DtMatrix4<T> getInverse(void) const;
81 
83  // begin with
84  DtMatrix4<T> getInverseAffine(void) const;
85  private:
86  union
87  {
88  T _m[16];
89  T m[4][4];
90  };
91  };
92 
93  template <class T>
94  DtMatrix4<T> DtMatrix4<T>::theIdentityMatrix = DtMatrix4<T>(1,0,0,0
95  , 0,1,0,0
96  , 0,0,1,0
97  , 0,0,0,1);
98 
101 
102  template<class T>
104  {
105 
106  }
107 
108  template<class T>
109  DtMatrix4<T>::DtMatrix4(const T rhs[4][4])
110  {
111  memcpy(_m, rhs, 16*sizeof(T));
112  }
113 
114  template<class T>
115  DtMatrix4<T>::DtMatrix4(T m00, T m01, T m02, T m03
116  , T m10, T m11, T m12, T m13
117  , T m20, T m21, T m22, T m23
118  , T m30, T m31, T m32, T m33)
119  {
120  m[0][0]=m00;m[0][1]=m01;m[0][2]=m02;m[0][3]=m03;
121  m[1][0]=m10;m[1][1]=m11;m[1][2]=m12;m[1][3]=m13;
122  m[2][0]=m20;m[2][1]=m21;m[2][2]=m22;m[2][3]=m23;
123  m[3][0]=m30;m[3][1]=m31;m[3][2]=m32;m[3][3]=m33;
124  }
125 
126  template<class T>
127  DtMatrix4<T>::DtMatrix4(const T rhs[16])
128  {
129  memcpy(m, rhs, 16*sizeof(T));
130  }
131 
132  template<class T>
134  {
135 
136  }
137  template<class T>
138  const void* DtMatrix4<T>::ptr(void) const
139  {
140  return _m;
141  }
142 
143  template<class T>
144  const T* DtMatrix4<T>::operator [](size_t iRow) const
145  {
147  return m[iRow];
148  }
149  template<class T>
151  {
153  return m[iRow];
154  }
155 
156  template<class T>
158  {
159  /*
160  | lhs.00, lhs.01, lhs.02, lhs.03 | | rhs.00, rhs.01, rhs.02, rhs.03 |
161  | lhs.10, lhs.11, lhs.12, lhs.13 | | rhs.10, rhs.11, rhs.12, rhs.13 |
162  | lhs.20, lhs.21, lhs.22, lhs.23 | | rhs.20, rhs.21, rhs.22, rhs.23 |
163  | lhs.30, lhs.31, lhs.32, lhs.33 | | rhs.30, rhs.31, rhs.32, rhs.33 |
164  */
165  const DtMatrix4& lhs = *this;
166 
168 
169  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];
170  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];
171  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];
172  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];
173 
174  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];
175  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];
176  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];
177  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];
178 
179  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];
180  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];
181  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];
182  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];
183 
184  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];
185  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];
186  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];
187  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];
188 
189  return result;
190  }
191 
192 
193  template<class T>
195  {
196  /*
197  | lhs.00, lhs.01, lhs.02, lhs.03 | | rhs.0 |
198  | lhs.10, lhs.11, lhs.12, lhs.13 | | rhs.1 |
199  | lhs.20, lhs.21, lhs.22, lhs.23 | | rhs.2 |
200  | lhs.30, lhs.31, lhs.32, lhs.33 | | rhs.3 |
201  */
202  DtVector4<T> vResult;
203 
204  const DtMatrix4& lhs = *this;
205 
206  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;
207  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;
208  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;
209  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;
210 
211  return vResult;
212  }
213 
214  template<class T>
216  {
217  memset(_m, 0, 16*sizeof(T));
218  }
219 
220  template<class T>
222  {
224  m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
225  }
226 
227  template<class T>
229  {
230  return DtMatrix4<T>(
231  m[0][0], m[1][0], m[2][0], m[3][0]
232  , m[0][1], m[1][1], m[2][1], m[3][1]
233  , m[0][2], m[1][2], m[2][2], m[3][2]
234  , m[0][3], m[1][3], m[2][3], m[3][3]
235  );
236  }
237 
238  template<class T>
240  {
241  DtMatrix4<T> result = *this;
242  result[2][0] = (result[2][0] + result[3][0])*0.5f;
243  result[2][1] = (result[2][1] + result[3][1])*0.5f;
244  result[2][2] = (result[2][2] + result[3][2])*0.5f;
245  result[2][3] = (result[2][3] + result[3][3])*0.5f;
246  return result;
247  }
248 
249  template<class T>
250  bool DtMatrix4<T>::isEqual(const DtMatrix4<T>& rhs, T tolerance) const
251  {
252  const DtMatrix4& lhs = *this;
253  for(size_t i = 0; i < 4; ++i)
254  {
255  for(size_t j = 0; j < 4; ++j)
256  {
257  if (!DtMath::isEqual(lhs[i][j], rhs[i][j], tolerance))
258  return false;
259  }
260  }
261  return true;
262  }
263 
264  template<class T>
265  bool DtMatrix4<T>::isIdentity(T tolerance) const
266  {
267  DtMatrix4 rhs; rhs.setIdentity();
268  return isEqual(rhs, tolerance);
269  }
270 
271  template<class T>
273  {
274  operator=(rhs);
275  }
276  template<class T>
278  {
279  setIdentity();
280 
281  m[0][0] = rhs[0][0]; m[0][1] = rhs[0][1]; m[0][2] = rhs[0][2];
282  m[1][0] = rhs[1][0]; m[1][1] = rhs[1][1]; m[1][2] = rhs[1][2];
283  m[2][0] = rhs[2][0]; m[2][1] = rhs[2][1]; m[2][2] = rhs[2][2];
284  }
285 
286  template<class T>
287  bool DtMatrix4<T>::isAffine(void) const
288  {
289  return m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0 && m[3][3] == 1;
290  }
291 
292  template<class T>
294  {
295  ASSERT_PREDICATE(IsAffine());
296  if (DtMatrix4<T>::IsAffine()==false)
298 
299  return DtVector3<T>(
300  m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + + m[0][3]
301  , m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + + m[1][3]
302  , m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + + m[2][3]
303  );
304  }
305 
306  template<class T>
308  {
309  ASSERT_PREDICATE(IsAffine());
310  if (DtMatrix4<T>::IsAffine()==false)
311  return DtVector4<T>::ZERO;
312 
313  return DtVector4<T>(
314  m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + + m[0][3]
315  , m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + + m[1][3]
316  , m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + + m[2][3]
317  , v.w
318  );
319  }
320 
321  template<class T>
323  {
324  T m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
325  T m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
326  T m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
327  T m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];
328 
329  T v0 = m20 * m31 - m21 * m30;
330  T v1 = m20 * m32 - m22 * m30;
331  T v2 = m20 * m33 - m23 * m30;
332  T v3 = m21 * m32 - m22 * m31;
333  T v4 = m21 * m33 - m23 * m31;
334  T v5 = m22 * m33 - m23 * m32;
335 
336  T t00 = + (v5 * m11 - v4 * m12 + v3 * m13);
337  T t10 = - (v5 * m10 - v2 * m12 + v1 * m13);
338  T t20 = + (v4 * m10 - v2 * m11 + v0 * m13);
339  T t30 = - (v3 * m10 - v1 * m11 + v0 * m12);
340 
341  T invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);
342 
343  T d00 = t00 * invDet;
344  T d10 = t10 * invDet;
345  T d20 = t20 * invDet;
346  T d30 = t30 * invDet;
347 
348  T d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
349  T d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
350  T d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
351  T d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
352 
353  v0 = m10 * m31 - m11 * m30;
354  v1 = m10 * m32 - m12 * m30;
355  v2 = m10 * m33 - m13 * m30;
356  v3 = m11 * m32 - m12 * m31;
357  v4 = m11 * m33 - m13 * m31;
358  v5 = m12 * m33 - m13 * m32;
359 
360  T d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
361  T d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
362  T d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
363  T d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
364 
365  v0 = m21 * m10 - m20 * m11;
366  v1 = m22 * m10 - m20 * m12;
367  v2 = m23 * m10 - m20 * m13;
368  v3 = m22 * m11 - m21 * m12;
369  v4 = m23 * m11 - m21 * m13;
370  v5 = m23 * m12 - m22 * m13;
371 
372  T d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
373  T d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
374  T d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
375  T d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
376 
377  return DtMatrix4(
378  d00, d01, d02, d03,
379  d10, d11, d12, d13,
380  d20, d21, d22, d23,
381  d30, d31, d32, d33);
382  }
383 
384  template<class T>
386  {
387  ASSERT_PREDICATE(IsAffine());
388 
389  T m10 = m[1][0], m11 = m[1][1], m12 = m[1][2];
390  T m20 = m[2][0], m21 = m[2][1], m22 = m[2][2];
391 
392  T t00 = m22 * m11 - m21 * m12;
393  T t10 = m20 * m12 - m22 * m10;
394  T t20 = m21 * m10 - m20 * m11;
395 
396  T m00 = m[0][0], m01 = m[0][1], m02 = m[0][2];
397 
398  T invDet = 1 / (m00 * t00 + m01 * t10 + m02 * t20);
399 
400  t00 *= invDet; t10 *= invDet; t20 *= invDet;
401 
402  m00 *= invDet; m01 *= invDet; m02 *= invDet;
403 
404  T r00 = t00;
405  T r01 = m02 * m21 - m01 * m22;
406  T r02 = m01 * m12 - m02 * m11;
407 
408  T r10 = t10;
409  T r11 = m00 * m22 - m02 * m20;
410  T r12 = m02 * m10 - m00 * m12;
411 
412  T r20 = t20;
413  T r21 = m01 * m20 - m00 * m21;
414  T r22 = m00 * m11 - m01 * m10;
415 
416  T m03 = m[0][3], m13 = m[1][3], m23 = m[2][3];
417 
418  T r03 = - (r00 * m03 + r01 * m13 + r02 * m23);
419  T r13 = - (r10 * m03 + r11 * m13 + r12 * m23);
420  T r23 = - (r20 * m03 + r21 * m13 + r22 * m23);
421 
422  return DtMatrix4<T>(
423  r00, r01, r02, r03,
424  r10, r11, r12, r13,
425  r20, r21, r22, r23,
426  0, 0, 0, 1);
427  }
428 
429  template<class T>
430  inline std::ostream& operator <<
431  ( std::ostream& o, const DtMatrix4<T>& mat )
432  {
433  for(size_t i = 0; i < 4; ++i)
434  {
435  o<<mat[i][0]<<" "<<mat[i][1]<<" "<<mat[i][2]<<" "<<mat[i][3]<<std::endl;
436  }
437  return o;
438  }
439 
440 } //namespace makVrv


Copyright © 2005-2017 VT MÄK. All Rights Reserved (www.mak.com)