VR-Vantage 2.3 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) 2017 MAK Technologies, Inc.
3 ** All rights reserved.
4 ******************************************************************************/
5 
9 #pragma once
10 
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  ~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 
87  void zeroOutTranslation(void);
88 
90  void translateBack(const DtVector3<T>& v);
91  private:
92  union
93  {
94  T _m[16];
95  T m[4][4];
96  };
97  };
98 
99  template <class T>
100  DtMatrix4<T> DtMatrix4<T>::theIdentityMatrix = DtMatrix4<T>(1,0,0,0
101  , 0,1,0,0
102  , 0,0,1,0
103  , 0,0,0,1);
104 
107 
108  template<class T>
110  {
111 
112  }
113 
114  template<class T>
115  DtMatrix4<T>::DtMatrix4(const T rhs[4][4])
116  {
117  memcpy(_m, rhs, 16*sizeof(T));
118  }
119 
120  template<class T>
121  DtMatrix4<T>::DtMatrix4(T m00, T m01, T m02, T m03
122  , T m10, T m11, T m12, T m13
123  , T m20, T m21, T m22, T m23
124  , T m30, T m31, T m32, T m33)
125  {
126  m[0][0]=m00;m[0][1]=m01;m[0][2]=m02;m[0][3]=m03;
127  m[1][0]=m10;m[1][1]=m11;m[1][2]=m12;m[1][3]=m13;
128  m[2][0]=m20;m[2][1]=m21;m[2][2]=m22;m[2][3]=m23;
129  m[3][0]=m30;m[3][1]=m31;m[3][2]=m32;m[3][3]=m33;
130  }
131 
132  template<class T>
133  DtMatrix4<T>::DtMatrix4(const T rhs[16])
134  {
135  memcpy(m, rhs, 16*sizeof(T));
136  }
137 
138  template<class T>
140  {
141 
142  }
143  template<class T>
144  const void* DtMatrix4<T>::ptr(void) const
145  {
146  return _m;
147  }
148 
149  template<class T>
150  const T* DtMatrix4<T>::operator [](size_t iRow) const
151  {
153  return m[iRow];
154  }
155  template<class T>
157  {
159  return m[iRow];
160  }
161 
162  template<class T>
164  {
165  /*
166  | lhs.00, lhs.01, lhs.02, lhs.03 | | rhs.00, rhs.01, rhs.02, rhs.03 |
167  | lhs.10, lhs.11, lhs.12, lhs.13 | | rhs.10, rhs.11, rhs.12, rhs.13 |
168  | lhs.20, lhs.21, lhs.22, lhs.23 | | rhs.20, rhs.21, rhs.22, rhs.23 |
169  | lhs.30, lhs.31, lhs.32, lhs.33 | | rhs.30, rhs.31, rhs.32, rhs.33 |
170  */
171  const DtMatrix4& lhs = *this;
172 
174 
175  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];
176  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];
177  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];
178  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];
179 
180  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];
181  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];
182  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];
183  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];
184 
185  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];
186  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];
187  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];
188  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];
189 
190  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];
191  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];
192  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];
193  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];
194 
195  return result;
196  }
197 
198 
199  template<class T>
201  {
202  /*
203  | lhs.00, lhs.01, lhs.02, lhs.03 | | rhs.0 |
204  | lhs.10, lhs.11, lhs.12, lhs.13 | | rhs.1 |
205  | lhs.20, lhs.21, lhs.22, lhs.23 | | rhs.2 |
206  | lhs.30, lhs.31, lhs.32, lhs.33 | | rhs.3 |
207  */
208  DtVector4<T> vResult;
209 
210  const DtMatrix4& lhs = *this;
211 
212  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;
213  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;
214  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;
215  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;
216 
217  return vResult;
218  }
219 
220  template<class T>
222  {
223  memset(_m, 0, 16*sizeof(T));
224  }
225 
226  template<class T>
228  {
230  m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
231  }
232 
233  template<class T>
235  {
236  return DtMatrix4<T>(
237  m[0][0], m[1][0], m[2][0], m[3][0]
238  , m[0][1], m[1][1], m[2][1], m[3][1]
239  , m[0][2], m[1][2], m[2][2], m[3][2]
240  , m[0][3], m[1][3], m[2][3], m[3][3]
241  );
242  }
243 
244  template<class T>
246  {
247  DtMatrix4<T> result = *this;
248  result[2][0] = (result[2][0] + result[3][0])*0.5f;
249  result[2][1] = (result[2][1] + result[3][1])*0.5f;
250  result[2][2] = (result[2][2] + result[3][2])*0.5f;
251  result[2][3] = (result[2][3] + result[3][3])*0.5f;
252  return result;
253  }
254 
255  template<class T>
256  bool DtMatrix4<T>::isEqual(const DtMatrix4<T>& rhs, T tolerance) const
257  {
258  const DtMatrix4& lhs = *this;
259  for(size_t i = 0; i < 4; ++i)
260  {
261  for(size_t j = 0; j < 4; ++j)
262  {
263  if (!DtMath::isEqual(lhs[i][j], rhs[i][j], tolerance))
264  return false;
265  }
266  }
267  return true;
268  }
269 
270  template<class T>
271  bool DtMatrix4<T>::isIdentity(T tolerance) const
272  {
273  DtMatrix4 rhs; rhs.setIdentity();
274  return isEqual(rhs, tolerance);
275  }
276 
277  template<class T>
279  {
280  operator=(rhs);
281  }
282  template<class T>
284  {
285  setIdentity();
286 
287  m[0][0] = rhs[0][0]; m[0][1] = rhs[0][1]; m[0][2] = rhs[0][2];
288  m[1][0] = rhs[1][0]; m[1][1] = rhs[1][1]; m[1][2] = rhs[1][2];
289  m[2][0] = rhs[2][0]; m[2][1] = rhs[2][1]; m[2][2] = rhs[2][2];
290  }
291 
292  template<class T>
293  bool DtMatrix4<T>::isAffine(void) const
294  {
295  return m[3][0] == 0 && m[3][1] == 0 && m[3][2] == 0 && m[3][3] == 1;
296  }
297 
298  template<class T>
300  {
301  ASSERT_PREDICATE(IsAffine());
302  if (DtMatrix4<T>::IsAffine()==false)
304 
305  return DtVector3<T>(
306  m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + + m[0][3]
307  , m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + + m[1][3]
308  , m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + + m[2][3]
309  );
310  }
311 
312  template<class T>
314  {
315  ASSERT_PREDICATE(IsAffine());
316  if (DtMatrix4<T>::IsAffine()==false)
317  return DtVector4<T>::ZERO;
318 
319  return DtVector4<T>(
320  m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + + m[0][3]
321  , m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + + m[1][3]
322  , m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + + m[2][3]
323  , v.w
324  );
325  }
326 
327  template<class T>
329  {
330  T m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
331  T m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
332  T m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
333  T m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];
334 
335  T v0 = m20 * m31 - m21 * m30;
336  T v1 = m20 * m32 - m22 * m30;
337  T v2 = m20 * m33 - m23 * m30;
338  T v3 = m21 * m32 - m22 * m31;
339  T v4 = m21 * m33 - m23 * m31;
340  T v5 = m22 * m33 - m23 * m32;
341 
342  T t00 = + (v5 * m11 - v4 * m12 + v3 * m13);
343  T t10 = - (v5 * m10 - v2 * m12 + v1 * m13);
344  T t20 = + (v4 * m10 - v2 * m11 + v0 * m13);
345  T t30 = - (v3 * m10 - v1 * m11 + v0 * m12);
346 
347  T invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);
348 
349  T d00 = t00 * invDet;
350  T d10 = t10 * invDet;
351  T d20 = t20 * invDet;
352  T d30 = t30 * invDet;
353 
354  T d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
355  T d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
356  T d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
357  T d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
358 
359  v0 = m10 * m31 - m11 * m30;
360  v1 = m10 * m32 - m12 * m30;
361  v2 = m10 * m33 - m13 * m30;
362  v3 = m11 * m32 - m12 * m31;
363  v4 = m11 * m33 - m13 * m31;
364  v5 = m12 * m33 - m13 * m32;
365 
366  T d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
367  T d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
368  T d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
369  T d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
370 
371  v0 = m21 * m10 - m20 * m11;
372  v1 = m22 * m10 - m20 * m12;
373  v2 = m23 * m10 - m20 * m13;
374  v3 = m22 * m11 - m21 * m12;
375  v4 = m23 * m11 - m21 * m13;
376  v5 = m23 * m12 - m22 * m13;
377 
378  T d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
379  T d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
380  T d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
381  T d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;
382 
383  return DtMatrix4(
384  d00, d01, d02, d03,
385  d10, d11, d12, d13,
386  d20, d21, d22, d23,
387  d30, d31, d32, d33);
388  }
389 
390  template<class T>
392  {
393  ASSERT_PREDICATE(IsAffine());
394 
395  T m10 = m[1][0], m11 = m[1][1], m12 = m[1][2];
396  T m20 = m[2][0], m21 = m[2][1], m22 = m[2][2];
397 
398  T t00 = m22 * m11 - m21 * m12;
399  T t10 = m20 * m12 - m22 * m10;
400  T t20 = m21 * m10 - m20 * m11;
401 
402  T m00 = m[0][0], m01 = m[0][1], m02 = m[0][2];
403 
404  T invDet = 1 / (m00 * t00 + m01 * t10 + m02 * t20);
405 
406  t00 *= invDet; t10 *= invDet; t20 *= invDet;
407 
408  m00 *= invDet; m01 *= invDet; m02 *= invDet;
409 
410  T r00 = t00;
411  T r01 = m02 * m21 - m01 * m22;
412  T r02 = m01 * m12 - m02 * m11;
413 
414  T r10 = t10;
415  T r11 = m00 * m22 - m02 * m20;
416  T r12 = m02 * m10 - m00 * m12;
417 
418  T r20 = t20;
419  T r21 = m01 * m20 - m00 * m21;
420  T r22 = m00 * m11 - m01 * m10;
421 
422  T m03 = m[0][3], m13 = m[1][3], m23 = m[2][3];
423 
424  T r03 = - (r00 * m03 + r01 * m13 + r02 * m23);
425  T r13 = - (r10 * m03 + r11 * m13 + r12 * m23);
426  T r23 = - (r20 * m03 + r21 * m13 + r22 * m23);
427 
428  return DtMatrix4<T>(
429  r00, r01, r02, r03,
430  r10, r11, r12, r13,
431  r20, r21, r22, r23,
432  0, 0, 0, 1);
433  }
434 
435  template<class T>
437  {
438  m[0][3] = 0;
439  m[1][3] = 0;
440  m[2][3] = 0;
441  }
442 
443  template<class T>
445  {
446  m[0][3] = m[0][3] - v.x;
447  m[1][3] = m[1][3] - v.y;
448  m[2][3] = m[2][3] - v.z;
449  }
450 
451  template<class T>
452  inline std::ostream& operator <<
453  ( std::ostream& o, const DtMatrix4<T>& mat )
454  {
455  for(size_t i = 0; i < 4; ++i)
456  {
457  o<<mat[i][0]<<" "<<mat[i][1]<<" "<<mat[i][2]<<" "<<mat[i][3]<<std::endl;
458  }
459  return o;
460  }
461 
462 } //namespace makVrv


Copyright © 2005-2018 VT MAK. All Rights Reserved (www.mak.com)