Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cMatrix.h
Go to the documentation of this file.
1 //
6 //
7 #ifndef _INC_cMatrix_H
8 #define _INC_cMatrix_H
9 #ifndef NO_PRAGMA_ONCE
10 #pragma once
11 #endif
12 
13 #include "cVector.h"
14 #include "cQuaternion.h"
15 
16 namespace GrayLib
17 {
18  UNITTEST2_PREDEF(cMatrix);
19  class cPlanef;
20 
21  template<typename TYPE = DVALUEDEF_t, int _ROWS = 4, int _COLS = 4 >
23  {
27 
29 
30  public:
31  typedef TYPE DVALUE_t;
32  static const int k_nRows = _ROWS; // Dim
33  static const int k_nCols = _COLS;
34 
35  union
36  {
37  TYPE m_a[_ROWS * _COLS];
38  TYPE m[_ROWS][_COLS];
39  };
40 
41  public:
42  cMatrixT() noexcept
43  {
45  }
46  cMatrixT(const THIS_t& v) noexcept
47  {
48  ::memcpy(this->m_a, &v, sizeof(this->m_a));
49  }
50  cMatrixT(const TYPE* pVals) noexcept
51  {
52  ::memcpy(this->m_a, pVals, sizeof(this->m_a));
53  }
54 
55  bool IsNear(const THIS_t& v2, TYPE fDist = (TYPE)k_FLT_MIN2) const
56  {
58  for (UINT i = 0; i < _countof(this->m_a); i++)
59  {
60  if (!Calc::IsNear(this->m_a[i], v2.m_a[i], fDist))
61  return false;
62  }
63  return true;
64  }
65 
66  COMPARE_t Compare(const THIS_t& v2) const
67  {
68  return(::memcmp(this->m_a, v2.m_a, sizeof(this->m_a)));
69  }
70  bool operator == (const THIS_t& v2) const
71  {
72  return(Compare(v2) == 0);
73  }
74  bool operator != (const THIS_t& v2) const
75  {
76  return(Compare(v2) != 0);
77  }
78 
79  template< int _IDN >
81  {
86 
87  ASSERT(this != &m1);
88  ASSERT(this != &m2);
89  for (int nRow = 0; nRow < k_nRows; nRow++)
90  {
91  for (int nCol = 0; nCol < k_nCols; nCol++)
92  {
93  TYPE sum = 0;
94  for (int k = 0; k < _IDN; k++)
95  {
96  sum += m1.m[nRow][k] * m2.m[k][nCol];
97  }
98  this->m[nRow][nCol] = sum;
99  }
100  }
101  }
102 
103  TYPE* RefRow(int nRow)
104  {
107  ASSERT(IS_INDEX_GOOD(nRow, k_nRows));
108  return &(this->m[nRow][0]);
109  }
110  const TYPE* GetRow(int nRow) const
111  {
114  ASSERT(IS_INDEX_GOOD(nRow, k_nRows));
115  return &(this->m[nRow][0]);
116  }
117  const TYPE* GetRow(AXIS_TYPE eAxis) const
118  {
119  return GetRow((int)eAxis);
120  }
121 
122  void SetRow(int nRow, const TYPE* p)
123  {
124  ASSERT(IS_INDEX_GOOD(nRow, k_nRows));
125  memcpy(&(this->m[nRow][0]), p, sizeof(TYPE) * _COLS);
126  }
127 
129  {
130  return *((cVecT<TYPE, _COLS>*)RefRow(nRow));
131  }
132  const cVecT<TYPE, _COLS>& GetRowV(int nRow) const
133  {
134  return *((const cVecT<TYPE, _COLS>*)GetRow(nRow));
135  }
136  void SetRowV(int nRow, const cVecT<TYPE, _COLS>& v)
137  {
138  SetRow(nRow, v);
139  }
140 
141  void CopyColTo(int nCol, TYPE* pV) const
142  {
143  ASSERT(IS_INDEX_GOOD(nCol, k_nCols));
144  for (int nRow = 0; nRow < k_nRows; nRow++, pV++)
145  {
146  *pV = this->m[nRow][nCol];
147  }
148  }
149  void CopyColToV(int nCol, cVecT<TYPE, _ROWS>& v) const
150  {
151  CopyColTo(nCol, (TYPE*)&v);
152  }
153  cVecT<TYPE, _ROWS> GetColV(int nCol) const
154  {
156  CopyColToV(nCol, v);
157  return v;
158  }
159  void SetCol(int nCol, const TYPE* pV)
160  {
161  ASSERT(IS_INDEX_GOOD(nCol, _COLS));
162  for (int nRow = 0; nRow < k_nRows; nRow++, pV++)
163  {
164  this->m[nRow][nCol] = *pV;
165  }
166  }
167  void SetColV(int nCol, const cVecT<TYPE, _ROWS>& v)
168  {
169  SetCol(nCol, (const TYPE*)&v);
170  }
171  };
172 
173  class GRAYLIB_LINK cMatrix3x3f : public cMatrixT<DVALUEDEF_t, 3, 3>
174  {
179  public:
182 
184  {
186  }
188  {}
189  };
190 
191 #pragma pack(push,16) // D3DX_ALIGN16 for better MMX,SSE access.
192 
193  class GRAYLIB_LINK cMatrix4x4f : public cMatrixT<DVALUEDEF_t, 4, 4>
194  {
198 
199  public:
200  static const int k_nDim = 4;
203 
204  static const THIS_t k_Identity; // All zero with scale of 1
205 
206  private:
208  inline THIS_t operator + (const THIS_t& m2) const
209  {
211  ASSERT(0); return *this;
212  }
213  inline const THIS_t& operator += (const THIS_t& m2)
214  {
216  ASSERT(0); return *this;
217  }
218  inline THIS_t operator - (const THIS_t& m2) const
219  {
221  ASSERT(0); return *this;
222  }
223  inline const THIS_t& operator -= (const THIS_t& m2)
224  {
226  ASSERT(0); return *this;
227  }
228  inline THIS_t operator / (const THIS_t& m2) const
229  {
231  ASSERT(0); return *this;
232  }
233  inline const THIS_t& operator /= (const THIS_t& m2)
234  {
236  ASSERT(0); return *this;
237  }
238 
239  public:
241  {
243  }
245  {
247  }
248  cMatrix4x4f(const DVALUE_t* pSrc) : cMatrixT<DVALUE_t, 4, 4>(pSrc)
249  {
251  }
252  cMatrix4x4f(DVALUE_t n11, DVALUE_t n12 = 0, DVALUE_t n13 = 0, DVALUE_t n14 = 0,
253  DVALUE_t n21 = 0, DVALUE_t n22 = 0, DVALUE_t n23 = 0, DVALUE_t n24 = 0,
254  DVALUE_t n31 = 0, DVALUE_t n32 = 0, DVALUE_t n33 = 0, DVALUE_t n34 = 0,
255  DVALUE_t n41 = 0, DVALUE_t n42 = 0, DVALUE_t n43 = 0, DVALUE_t n44 = 0)
256  {
257  m[0][0] = n11; m[0][1] = n12; m[0][2] = n13; m[0][3] = n14;
258  m[1][0] = n21; m[1][1] = n22; m[1][2] = n23; m[1][3] = n24;
259  m[2][0] = n31; m[2][1] = n32; m[2][2] = n33; m[2][3] = n34;
260  m[3][0] = n41; m[3][1] = n42; m[3][2] = n43; m[3][3] = n44;
261  }
262 
263 #ifdef _WIN32
264  // Cast directly to the DirectX equivalent type.
265  cMatrix4x4f(const XMFLOAT4X4& v)
266  : cMatrixT<DVALUE_t, 4, 4>(*(const SUPER_t*)&v)
267  {}
268  inline operator XMFLOAT4X4*()
269  {
270  return (XMFLOAT4X4*) this;
271  }
272  inline operator const XMFLOAT4X4*() const
273  {
274  return (const XMFLOAT4X4*) this;
275  }
276 #endif
277 
278  // Read parts of the matrix
279 
280  const cVector3f& GetAxis3(AXIS_TYPE eAxis) const
281  {
284  return *((const cVector3f*)SUPER_t::GetRow(eAxis));
285  }
286  const cVector4f& GetAxis4(int nRow) const
287  {
291  return *((const cVector4f*)SUPER_t::GetRow(nRow));
292  }
293 
294  const cVector3f& get_XAxis() const
295  {
298  return *((const cVector3f*)SUPER_t::GetRow(AXIS_TYPE::AXIS_X));
299  }
300  const cVector3f& get_YAxis() const
301  {
303  return *((const cVector3f*)SUPER_t::GetRow(AXIS_TYPE::AXIS_Y));
304  }
305  const cVector3f& get_ZAxis() const
306  {
308  return *((const cVector3f*)SUPER_t::GetRow(AXIS_TYPE::AXIS_Z));
309  }
310  const cVector3f& get_Translation() const
311  {
313  return *((const cVector3f*)SUPER_t::GetRow(AXIS_TYPE::AXIS_Trans));
314  }
315 
317  {
321  return m[0][0];
322  }
324  {
327  return cVector3f(m[(int)AXIS_TYPE::AXIS_X][0], m[(int)AXIS_TYPE::AXIS_Y][1], m[(int)AXIS_TYPE::AXIS_Z][2]);
328  }
330  {
332  return cVector3f(get_XAxis().get_Magnitude(), get_YAxis().get_Magnitude(), get_ZAxis().get_Magnitude());
333  }
334 
335  // const get operations.
336  bool isIdentity() const
337  {
340  return !::memcmp(k_Identity.m, m, sizeof(m));
341  }
342 
343  inline THIS_t get_Normalized() const
344  {
347  THIS_t vr = *this;
348  vr.SetNormalized();
349  return vr;
350  }
352  {
354  return cQuaternionf(get_Normalized());
355  }
356 
358  {
360 #if false // def USE_DXM
361  return ::XMMatrixDeterminant(*((XMMATRIX*)this));
362 #else
363  // get transposed vectors.
364  THIS_t mTrans;
365  mTrans.InitTranspose(*this);
366  cVector4f vMinor;
367  vMinor.InitCross4(mTrans.GetAxis4(0), mTrans.GetAxis4(1), mTrans.GetAxis4(2));
368  DVALUE_t fDeterm = -vMinor.GetDot(mTrans.GetAxis4(3));
369  return fDeterm;
370 #endif
371  }
372 
374  {
376  THIS_t mRes;
377  mRes.InitTranspose(*this);
378  return mRes;
379  }
380  THIS_t GetInverse(DVALUE_t* pfDeterminant = nullptr) const
381  {
383  THIS_t mRes;
384  mRes.InitInverse(*this, pfDeterminant);
385  return mRes;
386  }
388  {
390  return GetInverse(nullptr);
391  }
392  THIS_t GetMul(const THIS_t& m2) const
393  {
396  THIS_t mRes;
397  mRes.InitMul(*this, m2);
398  return mRes;
399  }
400  inline THIS_t operator * (const THIS_t& m2) const
401  {
402  return GetMul(m2);
403  }
404 
405  void Decompose(cVector3f& vScale, cQuaternionf& qRot, cVector3f& vTrans) const
406  {
409 #if false // def USE_DXM
410  ::XMMatrixDecompose((XMFLOAT3*)&vScale, (XMVECTOR*)&qRot, (XMFLOAT3*)&vTrans, (const XMFLOAT4X4*) this);
411 #else
412  vTrans = get_Translation();
413  vScale = get_ScalingU();
414 
415  // same as qRot = get_RotationQ(); also like SetNormalized()
416  THIS_t mN;
417  for (int nRow = AXIS_X; nRow <= AXIS_Z; nRow++)
418  {
419  mN.RefAxis3((AXIS_TYPE)nRow) = GetAxis3((AXIS_TYPE)nRow) / vScale[nRow];
420  }
421  qRot.InitRotationMatrix(mN);
422 #endif
423  }
424 
425  // just init the matrix
427  {
430 #if false // def USE_DXM
431  ::D3DXMatrixIdentity((XMFLOAT4X4*) this);
432 #else
433  *this = k_Identity;
434 #endif
435  }
437  {
440 #ifdef USE_DXM
441  ::D3DXMatrixTranslation((XMFLOAT4X4*)this, x, y, z);
442 #else
443  InitIdentity();
444  SetTranslation(x, y, z);
445 #endif
446  }
447  void InitTranslation(const cVector3f& pt)
448  {
450  InitTranslation(pt.x, pt.y, pt.z);
451  }
453  {
456 #ifdef USE_DXM
457  ::D3DXMatrixScaling((XMFLOAT4X4*)this, _x, _y, _z);
458 #else
459  cMem::Zero(m, sizeof(m));
460  this->m[AXIS_X][0] = _x;
461  this->m[AXIS_Y][1] = _y;
462  this->m[AXIS_Z][2] = _z;
463  this->m[AXIS_Trans][3] = 1;
464 #endif
465  }
466  void InitScaling(const cVector3f& pt)
467  {
468  InitScaling(pt.x, pt.y, pt.z);
469  }
470  void InitScaling(DVALUE_t fScale)
471  {
474  InitScaling(fScale, fScale, fScale);
475  }
477  {
480 #ifdef USE_DXM
481  ::D3DXMatrixRotationQuaternion((XMFLOAT4X4*)this, (const D3DXQUATERNION*)&q);
482 #else
483  InitIdentity();
484  this->m[0][0] = 1.0f - 2.0f * (q.y * q.y + q.z * q.z);
485  this->m[0][1] = 2.0f * (q.x *q.y + q.z * q.w);
486  this->m[0][2] = 2.0f * (q.x * q.z - q.y * q.w);
487  this->m[1][0] = 2.0f * (q.x * q.y - q.z * q.w);
488  this->m[1][1] = 1.0f - 2.0f * (q.x * q.x + q.z * q.z);
489  this->m[1][2] = 2.0f * (q.y *q.z + q.x *q.w);
490  this->m[2][0] = 2.0f * (q.x * q.z + q.y * q.w);
491  this->m[2][1] = 2.0f * (q.y *q.z - q.x *q.w);
492  this->m[2][2] = 1.0f - 2.0f * (q.x * q.x + q.y * q.y);
493 #endif
494  }
495  void InitRotationX(RADIANf_t fAngleX)
496  {
499  // http://blogs.msdn.com/mikepelton/archive/2004/10/29/249501.aspx
500  // NOTE: NOT the same as yaw,pitch,roll for OpenGL as http://planning.cs.uiuc.edu/node102.html
501 #ifdef USE_DXM
502  ::D3DXMatrixRotationX((XMFLOAT4X4*)this, fAngleX);
503 #else
504  DVALUE_t s, c;
505  Calc::SinCos(fAngleX, s, c);
506  m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
507  m[1][0] = 0; m[1][1] = c; m[1][2] = s; m[1][3] = 0;
508  m[2][0] = 0; m[2][1] = -s; m[2][2] = c; m[2][3] = 0;
509  m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
510 #endif
511  }
512  void InitRotationY(RADIANf_t fAngleY)
513  {
515  // y = yaw = heading.
516 #ifdef USE_DXM
517  ::D3DXMatrixRotationY((XMFLOAT4X4*)this, fAngleY);
518 #else
519  DVALUE_t s, c;
520  Calc::SinCos(fAngleY, s, c);
521  m[0][0] = c; m[0][1] = 0; m[0][2] = -s; m[0][3] = 0;
522  m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
523  m[2][0] = s; m[2][1] = 0; m[2][2] = c; m[2][3] = 0;
524  m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
525 #endif
526  }
527  void InitRotationZ(RADIANf_t fAngleZ)
528  {
531 #ifdef USE_DXM
532  ::D3DXMatrixRotationZ((XMFLOAT4X4*)this, fAngleZ);
533 #else
534  DVALUE_t s, c;
535  Calc::SinCos(fAngleZ, s, c);
536  m[0][0] = c; m[0][1] = s; m[0][2] = 0; m[0][3] = 0;
537  m[1][0] = -s; m[1][1] = c; m[1][2] = 0; m[1][3] = 0;
538  m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
539  m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
540 #endif
541  }
542 
543  void InitRotationAxis(const cVector3f& vAxis, RADIANf_t fAngle)
544  {
549 #ifdef USE_DXM
550  ::D3DXMatrixRotationAxis((XMFLOAT4X4*)this, (const XMFLOAT3*)&vAxis, fAngle);
551 #else
552  cVector3f v = vAxis.get_Normalized();
553  InitIdentity();
554  DVALUE_t s, c;
555  Calc::SinCos(fAngle, s, c);
556  DVALUE_t c2 = (1.0f - c);
557  this->m[0][0] = c2 * v.x * v.x + c;
558  this->m[1][0] = c2 * v.x * v.y - s * v.z;
559  this->m[2][0] = c2 * v.x * v.z + s * v.y;
560  this->m[0][1] = c2 * v.y * v.x + s * v.z;
561  this->m[1][1] = c2 * v.y * v.y + c;
562  this->m[2][1] = c2 * v.y * v.z - s * v.x;
563  this->m[0][2] = c2 * v.z * v.x - s * v.y;
564  this->m[1][2] = c2 * v.z * v.y + s * v.x;
565  this->m[2][2] = c2 * v.z * v.z + c;
566 #endif
567  }
568  void InitInverse(const THIS_t& m1, DVALUE_t* pfDeterminant = nullptr)
569  {
572  ASSERT(this != &m1);
573 #ifdef USE_DXM
574  XMFLOAT4X4* pmRes = ::D3DXMatrixInverse((XMFLOAT4X4*)this, pfDeterminant, (XMFLOAT4X4*)&m1);
575  UNREFERENCED_PARAMETER(pmRes);
576  // ASSERT(pmRes);
577 #else
578  DVALUE_t fDeterm = m1.GetDeterminant();
579  if (fDeterm == 0)
580  {
581  InitIdentity();
582  return;
583  }
584  if (pfDeterminant != nullptr)
585  {
586  *pfDeterminant = fDeterm;
587  }
588  for (int i = 0; i < k_nDim; i++)
589  {
590  cVector4f vec[3];
591  for (int nRow = 0; nRow < k_nDim; nRow++)
592  {
593  if (nRow != i)
594  {
595  int a = nRow;
596  if (nRow > i)
597  a = a - 1;
598  vec[a].x = m1.m[nRow][0];
599  vec[a].y = m1.m[nRow][1];
600  vec[a].z = m1.m[nRow][2];
601  vec[a].w = m1.m[nRow][3];
602  }
603  }
604  cVector4f v;
605  v.InitCross4(vec[0], vec[1], vec[2]);
606  DVALUE_t fPow = Calc::Pow(-1.0f, (DVALUEDEF_t)i);
607  this->m[0][i] = fPow * v.x / fDeterm;
608  this->m[1][i] = fPow * v.y / fDeterm;
609  this->m[2][i] = fPow * v.z / fDeterm;
610  this->m[3][i] = fPow * v.w / fDeterm;
611  }
612 #endif
613  }
614  void InitTranspose(const THIS_t& m1)
615  {
617  ASSERT(this != &m1);
618 #ifdef USE_DXM
619  XMFLOAT4X4* pmRes = ::D3DXMatrixTranspose((XMFLOAT4X4*)this, (XMFLOAT4X4*)&m1);
620  ASSERT(pmRes != nullptr);
621 #else
622  for (int nRow = 0; nRow < k_nDim; nRow++)
623  {
624  for (int nCol = 0; nCol < k_nDim; nCol++)
625  {
626  this->m[nCol][nRow] = m1.m[nRow][nCol];
627  }
628  }
629 #endif
630  }
631  void InitMul(const THIS_t& m1, const THIS_t& m2)
632  {
637  ASSERT(this != &m1);
638  ASSERT(this != &m2);
639 #ifdef USE_DXM
640  XMFLOAT4X4* pmRes = ::D3DXMatrixMultiply((XMFLOAT4X4*) this, (XMFLOAT4X4*)&m1, (XMFLOAT4X4*)&m2);
641  ASSERT(pmRes != nullptr);
642 #elif defined(USE_SIMD)
643  this->m[0][0] = m1.m[0][0] * m2.m[0][0] + m1.m[0][1] * m2.m[1][0] + m1.m[0][2] * m2.m[2][0] + m1.m[0][3] * m2.m[3][0];
644  this->m[0][1] = m1.m[0][0] * m2.m[0][1] + m1.m[0][1] * m2.m[1][1] + m1.m[0][2] * m2.m[2][1] + m1.m[0][3] * m2.m[3][1];
645  this->m[0][2] = m1.m[0][0] * m2.m[0][2] + m1.m[0][1] * m2.m[1][2] + m1.m[0][2] * m2.m[2][2] + m1.m[0][3] * m2.m[3][2];
646  this->m[0][3] = m1.m[0][0] * m2.m[0][3] + m1.m[0][1] * m2.m[1][3] + m1.m[0][2] * m2.m[2][3] + m1.m[0][3] * m2.m[3][3];
647 
648  this->m[1][0] = m1.m[1][0] * m2.m[0][0] + m1.m[1][1] * m2.m[1][0] + m1.m[1][2] * m2.m[2][0] + m1.m[1][3] * m2.m[3][0];
649  this->m[1][1] = m1.m[1][0] * m2.m[0][1] + m1.m[1][1] * m2.m[1][1] + m1.m[1][2] * m2.m[2][1] + m1.m[1][3] * m2.m[3][1];
650  this->m[1][2] = m1.m[1][0] * m2.m[0][2] + m1.m[1][1] * m2.m[1][2] + m1.m[1][2] * m2.m[2][2] + m1.m[1][3] * m2.m[3][2];
651  this->m[1][3] = m1.m[1][0] * m2.m[0][3] + m1.m[1][1] * m2.m[1][3] + m1.m[1][2] * m2.m[2][3] + m1.m[1][3] * m2.m[3][3];
652 
653  this->m[2][0] = m1.m[2][0] * m2.m[0][0] + m1.m[2][1] * m2.m[1][0] + m1.m[2][2] * m2.m[2][0] + m1.m[2][3] * m2.m[3][0];
654  this->m[2][1] = m1.m[2][0] * m2.m[0][1] + m1.m[2][1] * m2.m[1][1] + m1.m[2][2] * m2.m[2][1] + m1.m[2][3] * m2.m[3][1];
655  this->m[2][2] = m1.m[2][0] * m2.m[0][2] + m1.m[2][1] * m2.m[1][2] + m1.m[2][2] * m2.m[2][2] + m1.m[2][3] * m2.m[3][2];
656  this->m[2][3] = m1.m[2][0] * m2.m[0][3] + m1.m[2][1] * m2.m[1][3] + m1.m[2][2] * m2.m[2][3] + m1.m[2][3] * m2.m[3][3];
657 
658  this->m[3][0] = m1.m[3][0] * m2.m[0][0] + m1.m[3][1] * m2.m[1][0] + m1.m[3][2] * m2.m[2][0] + m1.m[3][3] * m2.m[3][0];
659  this->m[3][1] = m1.m[3][0] * m2.m[0][1] + m1.m[3][1] * m2.m[1][1] + m1.m[3][2] * m2.m[2][1] + m1.m[3][3] * m2.m[3][1];
660  this->m[3][2] = m1.m[3][0] * m2.m[0][2] + m1.m[3][1] * m2.m[1][2] + m1.m[3][2] * m2.m[2][2] + m1.m[3][3] * m2.m[3][2];
661  this->m[3][3] = m1.m[3][0] * m2.m[0][3] + m1.m[3][1] * m2.m[1][3] + m1.m[3][2] * m2.m[2][3] + m1.m[3][3] * m2.m[3][3];
662 #else
663  SUPER_t::InitMul<4>(m1, m2);
664 #endif
665  }
666 
668  {
673 #ifdef USE_DXM
674  XMFLOAT4X4* pmRes = ::D3DXMatrixPerspectiveFovLH((XMFLOAT4X4*) this, fovy, aspect, zn, zf);
675  UNREFERENCED_PARAMETER(pmRes);
676 #else
677  InitIdentity();
678  DVALUE_t ft = Calc::Tan(fovy / 2.0f);
679  this->m[0][0] = 1.0f / (aspect * ft);
680  this->m[1][1] = 1.0f / ft;
681  this->m[2][2] = zf / (zf - zn);
682  this->m[2][3] = 1.0f;
683  this->m[3][2] = (zf * zn) / (zn - zf);
684  this->m[3][3] = 0.0f;
685 #endif
686  }
688  {
690 #ifdef USE_DXM
691  XMFLOAT4X4* pmRes = ::D3DXMatrixOrthoOffCenterLH((XMFLOAT4X4*) this, l, r, b, t, zn, zf);
692  UNREFERENCED_PARAMETER(pmRes);
693 #else
694  this->InitIdentity();
695  m[0][0] = 2.0f / (r - l);
696  m[1][1] = 2.0f / (t - b);
697  m[2][2] = 1.0f / (zf - zn);
698  m[3][0] = -1.0f - 2.0f *l / (r - l);
699  m[3][1] = 1.0f + 2.0f * t / (b - t);
700  m[3][2] = zn / (zn - zf);
701 #endif
702  }
703 
704  void InitYawPitchRoll(RADIANf_t yaw, RADIANf_t pitch, RADIANf_t roll);
705  void InitReflect(const cPlanef& plane);
706  void InitLookAtLH(const cVector3f& vEye, const cVector3f& vAt, const cVector3f& vUp);
707 
708  void InitTransformation(const cVector3f* pvScalingCenter = nullptr, const cQuaternionf* pqScalingRotation = nullptr, const cVector3f* pvScaling = nullptr, const cVector3f* pvRotationcenter = nullptr, const cQuaternionf* pqRotation = nullptr, const cVector3f* pvTranslation = nullptr);
709  void InitTransformation2D(const cVector2f* pvScalingCenter = nullptr, float fScalingRotation = 0, const cVector2f* pvScaling = nullptr, const cVector2f* pvRotationCenter = nullptr, RADIANf_t fRotation = 0, const cVector2f* pvTranslation = nullptr);
710 
711  // Write parts of the matrix
713  {
714  return *((cVector3f*)SUPER_t::RefRow(AXIS_X));
715  }
717  {
718  return *((cVector3f*)SUPER_t::RefRow(AXIS_Y));
719  }
721  {
722  return *((cVector3f*)SUPER_t::RefRow(AXIS_Z));
723  }
725  {
726  return *((cVector3f*)SUPER_t::RefRow(AXIS_Trans));
727  }
729  {
730  ASSERT(IS_INDEX_GOOD(eAxis, AXIS_QTY));
731  return *((cVector3f*)SUPER_t::RefRow(eAxis));
732  }
733  cVector4f& RefAxis4(int nRow)
734  {
736  ASSERT(IS_INDEX_GOOD(nRow, AXIS_QTY));
737  return *((cVector4f*)SUPER_t::RefRow(nRow));
738  }
739 
740  // setters
741 
742  void SetTranslation(DVALUE_t _x = 0, DVALUE_t _y = 0, DVALUE_t _z = 0)
743  {
746  m[AXIS_Trans][0] = _x;
747  m[AXIS_Trans][1] = _y;
748  m[AXIS_Trans][2] = _z;
749  }
750 
752  {
756  ref_XAxis().put_Magnitude(_x);
757  ref_YAxis().put_Magnitude(_y);
758  ref_ZAxis().put_Magnitude(_z);
759  }
760  void put_Scaling1(DVALUE_t fScale = 0)
761  {
763  SetScaling(fScale, fScale, fScale);
764  }
766  {
768  m[0][0] *= _x; m[1][0] *= _x; m[2][0] *= _x;
769  m[0][1] *= _y; m[1][1] *= _y; m[2][1] *= _y;
770  m[0][2] *= _z; m[1][2] *= _z; m[2][2] *= _z;
771  }
772 
774  {
776  for (int nRow = AXIS_X; nRow <= AXIS_Z; nRow++)
777  {
778  RefAxis3((AXIS_TYPE)nRow).SetNormalized();
779  }
780  }
781 
782  void SetInvert(DVALUE_t* pfDeterminant = nullptr)
783  {
785  *this = GetInverse(pfDeterminant);
786  }
788  {
790  *this = GetTranspose();
791  }
792  void SetMul(const THIS_t& m2)
793  {
796  *this = GetMul(m2);
797  }
798  inline const THIS_t& operator *= (const THIS_t& m2)
799  {
800  SetMul(m2);
801  return *this;
802  }
803 
804  UNITTEST_FRIEND(cMatrix);
805 
806  };
807 
808 #pragma pack(pop)
809 
811  {
814 
815  public:
816  // decomposed matrix parts.
819  private:
820  cVector3f m_vScale;
821 
822  public:
824  {
825  }
826 
828  {
829  // compose the matrix.
830  cMatrix4x4f m;
831  m.InitTransformation(nullptr, nullptr, &m_vScale, nullptr, &m_qRot, &m_vTrans);
832  return m;
833  }
834  void put_Matrix(const cMatrix4x4f& m)
835  {
836  // decompose a matrix and store its parts.
837  m.Decompose(m_vScale, m_qRot, m_vTrans);
838  }
839 
840  float get_Scale1() const
841  {
842  // get Uniform scale. ASSUME all the same.
843  ASSERT(m_vScale.m_x == m_vScale.m_y);
844  ASSERT(m_vScale.m_x == m_vScale.m_z);
845  return m_vScale.m_x;
846  }
847  void put_Scale1(float fScale)
848  {
849  // Make Uniform scale.
850  m_vScale.m_x = m_vScale.m_y = m_vScale.m_z = fScale;
851  }
852 
853 #if 0
854  // get/put from string. for scripted storage.
855  StrLen_t GetStr(char* pszStr, int iSizeMax) const;
856  void put_Str(const char* pszStr);
857 #endif
858  };
859 
860 #ifdef _WIN32 // D3DMATRIX_DEFINED
861  inline cMatrix4x4f& Cvt(XMFLOAT4X4& mtx)
862  {
863  return (cMatrix4x4f&)mtx;
864  }
865  inline const cMatrix4x4f& Cvt(const XMFLOAT4X4& mtx)
866  {
867  return *((const cMatrix4x4f*)&mtx);
868  }
869  inline cMatrix4x4f* Cvt(XMFLOAT4X4* mtx)
870  {
871  return (cMatrix4x4f*)mtx;
872  }
873  inline const cMatrix4x4f* Cvt(const XMFLOAT4X4* mtx)
874  {
875  return (const cMatrix4x4f*)mtx;
876  }
877 #endif
878 
879 #ifdef GRAY_DLL // force implementation/instantiate for DLL/SO.
880  template class GRAYLIB_LINK cMatrixT<float, 4, 4>;
881 #endif
882 
883 }
884 #endif // _INC_cMatrix_H
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
#define IS_INDEX_GOOD(i, q)
cast the (likely) int to unsigned to check for negatives.
Definition: Index.h:35
#define TYPE
Definition: StrT.cpp:38
#define UNREFERENCED_PARAMETER(P)
< _WIN32 type thing. get rid of stupid warning.
Definition: SysTypes.h:299
#define UNREFERENCED_REFERENCE(x)
Definition: SysTypes.h:318
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define _countof(a)
Definition: cKernel.h:35
Definition: cMatrix.h:174
cMatrix3x3f()
Definition: cMatrix.h:183
cMatrix3x3f THIS_t
Definition: cMatrix.h:181
cMatrix3x3f(const SUPER_t &src)
Definition: cMatrix.h:187
cMatrixT< DVALUEDEF_t, 3, 3 > SUPER_t
Definition: cMatrix.h:180
Definition: cMatrix.h:194
void SetMul(const THIS_t &m2)
Definition: cMatrix.h:792
void SetScaling(DVALUE_t _x, DVALUE_t _y, DVALUE_t _z)
Definition: cMatrix.h:751
cVector3f & ref_XAxis()
Definition: cMatrix.h:712
cMatrix4x4f(DVALUE_t n11, DVALUE_t n12=0, DVALUE_t n13=0, DVALUE_t n14=0, DVALUE_t n21=0, DVALUE_t n22=0, DVALUE_t n23=0, DVALUE_t n24=0, DVALUE_t n31=0, DVALUE_t n32=0, DVALUE_t n33=0, DVALUE_t n34=0, DVALUE_t n41=0, DVALUE_t n42=0, DVALUE_t n43=0, DVALUE_t n44=0)
Definition: cMatrix.h:252
cMatrix4x4f THIS_t
Definition: cMatrix.h:202
cVector3f & RefAxis3(AXIS_TYPE eAxis)
Definition: cMatrix.h:728
void SetTranspose()
Definition: cMatrix.h:787
void InitTranspose(const THIS_t &m1)
Definition: cMatrix.h:614
const cVector3f & get_XAxis() const
Definition: cMatrix.h:294
void SetScalingT(DVALUE_t _x, DVALUE_t _y, DVALUE_t _z)
Definition: cMatrix.h:765
void InitScaling(DVALUE_t fScale)
Definition: cMatrix.h:470
void InitInverse(const THIS_t &m1, DVALUE_t *pfDeterminant=nullptr)
Definition: cMatrix.h:568
cVector4f & RefAxis4(int nRow)
Definition: cMatrix.h:733
THIS_t GetMul(const THIS_t &m2) const
Definition: cMatrix.h:392
const cVector4f & GetAxis4(int nRow) const
Definition: cMatrix.h:286
THIS_t get_Normalized() const
Definition: cMatrix.h:343
cVector3f & ref_ZAxis()
Definition: cMatrix.h:720
void InitRotationAxis(const cVector3f &vAxis, RADIANf_t fAngle)
Definition: cMatrix.h:543
void InitTranslation(const cVector3f &pt)
Definition: cMatrix.h:447
void InitTranslation(DVALUE_t x, DVALUE_t y, DVALUE_t z)
Definition: cMatrix.h:436
const cVector3f & get_ZAxis() const
Definition: cMatrix.h:305
static const THIS_t k_Identity
Definition: cMatrix.h:204
const cVector3f & get_YAxis() const
Definition: cMatrix.h:300
void InitRotationX(RADIANf_t fAngleX)
Definition: cMatrix.h:495
const cVector3f & get_Translation() const
Definition: cMatrix.h:310
void InitScaling(DVALUE_t _x, DVALUE_t _y, DVALUE_t _z)
Definition: cMatrix.h:452
void InitScaling(const cVector3f &pt)
Definition: cMatrix.h:466
void InitPerspectiveFovLH(DVALUE_t fovy, DVALUE_t aspect, DVALUE_t zn, DVALUE_t zf)
Definition: cMatrix.h:667
bool isIdentity() const
Definition: cMatrix.h:336
cMatrix4x4f(const DVALUE_t *pSrc)
Definition: cMatrix.h:248
cVector3f get_ScalingU() const
Definition: cMatrix.h:329
void InitRotationY(RADIANf_t fAngleY)
Definition: cMatrix.h:512
DVALUE_t GetDeterminant() const
Definition: cMatrix.h:357
void SetInvert(DVALUE_t *pfDeterminant=nullptr)
Definition: cMatrix.h:782
void InitTransformation(const cVector3f *pvScalingCenter=nullptr, const cQuaternionf *pqScalingRotation=nullptr, const cVector3f *pvScaling=nullptr, const cVector3f *pvRotationcenter=nullptr, const cQuaternionf *pqRotation=nullptr, const cVector3f *pvTranslation=nullptr)
Definition: cMatrix.cpp:103
void Decompose(cVector3f &vScale, cQuaternionf &qRot, cVector3f &vTrans) const
Definition: cMatrix.h:405
THIS_t GetInverse(DVALUE_t *pfDeterminant=nullptr) const
Definition: cMatrix.h:380
void InitRotationZ(RADIANf_t fAngleZ)
Definition: cMatrix.h:527
const cVector3f & GetAxis3(AXIS_TYPE eAxis) const
Definition: cMatrix.h:280
void InitReflect(const cPlanef &plane)
cVector3f & ref_YAxis()
Definition: cMatrix.h:716
cQuaternionf get_RotationQ() const
Definition: cMatrix.h:351
void InitRotationQ(const cQuaternionf &q)
Definition: cMatrix.h:476
void InitIdentity()
Definition: cMatrix.h:426
cVector3f & ref_Translation()
Definition: cMatrix.h:724
THIS_t GetTranspose() const
Definition: cMatrix.h:373
cVector3f get_ScalingN() const
Definition: cMatrix.h:323
void InitMul(const THIS_t &m1, const THIS_t &m2)
Definition: cMatrix.h:631
void SetNormalized()
Definition: cMatrix.h:773
cMatrix4x4f()
Definition: cMatrix.h:240
void SetTranslation(DVALUE_t _x=0, DVALUE_t _y=0, DVALUE_t _z=0)
Definition: cMatrix.h:742
cMatrixT< DVALUEDEF_t, k_nDim, k_nDim > SUPER_t
Definition: cMatrix.h:201
void InitOrthoOffCenterLH(DVALUE_t l, DVALUE_t r, DVALUE_t b, DVALUE_t t, DVALUE_t zn, DVALUE_t zf)
Definition: cMatrix.h:687
cMatrix4x4f(const SUPER_t &src)
Definition: cMatrix.h:244
void put_Scaling1(DVALUE_t fScale=0)
Definition: cMatrix.h:760
THIS_t operator-() const
Definition: cMatrix.h:387
DVALUE_t get_Scaling1N() const
Definition: cMatrix.h:316
Definition: cMatrix.h:811
void put_Matrix(const cMatrix4x4f &m)
Definition: cMatrix.h:834
float get_Scale1() const
Definition: cMatrix.h:840
cQuaternionf m_qRot
rotation as a quaternion
Definition: cMatrix.h:818
void put_Scale1(float fScale)
Definition: cMatrix.h:847
cMatrix4x4f get_Matrix() const
Definition: cMatrix.h:827
cVector3f m_vTrans
usually the x,y,z translation from some parent object space.
Definition: cMatrix.h:817
cMatrixDecomp4()
Definition: cMatrix.h:823
Definition: cMatrix.h:23
TYPE * RefRow(int nRow)
Definition: cMatrix.h:103
cMatrixT(const THIS_t &v) noexcept
Definition: cMatrix.h:46
bool IsNear(const THIS_t &v2, TYPE fDist=(TYPE) k_FLT_MIN2) const
Definition: cMatrix.h:55
TYPE DVALUE_t
Definition: cMatrix.h:31
TYPE m[_ROWS][_COLS]
Definition: cMatrix.h:38
TYPE m_a[_ROWS *_COLS]
Definition: cMatrix.h:37
cVecT< TYPE, _COLS > & RefRowV(int nRow)
Definition: cMatrix.h:128
void CopyColTo(int nCol, TYPE *pV) const
Definition: cMatrix.h:141
void SetColV(int nCol, const cVecT< TYPE, _ROWS > &v)
Definition: cMatrix.h:167
const TYPE * GetRow(int nRow) const
Definition: cMatrix.h:110
const cVecT< TYPE, _COLS > & GetRowV(int nRow) const
Definition: cMatrix.h:132
cMatrixT() noexcept
Definition: cMatrix.h:42
const TYPE * GetRow(AXIS_TYPE eAxis) const
Definition: cMatrix.h:117
cVecT< TYPE, _ROWS > GetColV(int nCol) const
Definition: cMatrix.h:153
void SetRow(int nRow, const TYPE *p)
Definition: cMatrix.h:122
void SetCol(int nCol, const TYPE *pV)
Definition: cMatrix.h:159
void CopyColToV(int nCol, cVecT< TYPE, _ROWS > &v) const
Definition: cMatrix.h:149
void InitMul(const cMatrixT< TYPE, _ROWS, _IDN > &m1, const cMatrixT< TYPE, _IDN, _COLS > &m2)
Definition: cMatrix.h:80
cMatrixT(const TYPE *pVals) noexcept
Definition: cMatrix.h:50
COMPARE_t Compare(const THIS_t &v2) const
Definition: cMatrix.h:66
void SetRowV(int nRow, const cVecT< TYPE, _COLS > &v)
Definition: cMatrix.h:136
Definition: cPlane.h:18
Definition: cQuaternion.h:76
void InitRotationMatrix(const cMatrix4x4f &rm)
Definition: cQuaternion.cpp:119
TYPE m_z
Definition: cVecT.h:544
TYPE y
Definition: cVecT.h:545
TYPE z
Definition: cVecT.h:545
TYPE m_x
Definition: cVecT.h:544
TYPE m_y
Definition: cVecT.h:544
TYPE x
Definition: cVecT.h:545
TYPE z
Definition: cVecT.h:676
TYPE x
Definition: cVecT.h:676
TYPE w
Definition: cVecT.h:676
TYPE y
Definition: cVecT.h:676
_TYPE_C get_Normalized() const
Definition: cVecT.h:283
TYPE GetDot(const THIS_t &v2) const
Definition: cVecT.h:255
Definition: cVecT.h:459
Definition: cVector.h:36
Definition: cVector.h:94
Definition: cVector.h:261
void InitCross4(const cVector4f &v1, const cVector4f &v2, const cVector4f &v3)
Definition: cVector.h:323
Definition: cMesh.h:22
cVecT2< TYPE > operator*(const TYPE nVal, const cVecT2< TYPE > &v2)
Definition: cVecT.h:522
float DVALUEDEF_t
similar to D3DVALUE in DX. the basic default dimension type. DVALUEDEF_t
Definition: cVecT.h:34
class __DECL_IMPORT cMatrix4x4f
Definition: cVector.h:22
UNITTEST2_PREDEF(cQuadtree)
float RADIANf_t
type is float radians
Definition: Calc.h:27
AXIS_TYPE
Definition: cVector.h:25
@ AXIS_Trans
position offset.
Definition: cVector.h:31
@ AXIS_Y
Definition: cVector.h:29
@ AXIS_X
Definition: cVector.h:28
@ AXIS_Z
Definition: cVector.h:30
@ AXIS_QTY
Definition: cVector.h:32
int COMPARE_t
result of compare. 0=same, 1=a>b, -1=a<b
Definition: cValT.h:17
int StrLen_t
the length of a string in chars (bytes for UTF8, wchar_t for UNICODE). or offset in characters....
Definition: StrConst.h:32
cStringA operator+(const char *pStr1, const cStringA &s2)
Definition: cString.h:642
bool operator!=(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:254
bool operator==(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:250
static bool IsNear(TYPE n1, TYPE n2, TYPE nDiff=(TYPE) k_FLT_MIN2) noexcept
Definition: Calc.h:135
static TYPE Tan(TYPE a)
static void SinCos(TYPE a, TYPE &s, TYPE &c)
get both sin and cos at one time. a = Euler angle in radians
static TYPE Pow(TYPE nBase, TYPE nExp)
pow(nBase,nExp) = exp( log(nBase) * nExp );
Definition: cDebugAssert.h:29
static void Zero(void *pData, size_t nSizeBlock) noexcept
Definition: cMem.h:100
Definition: MathDX.h:58
Definition: MathDX.h:138
Definition: MathDX.h:155