TurtleBrains  0.2.1
High quality, portable, C++ API for native application and game development.
tb_matrix.h
1 
9 #ifndef _TurtleBrains_Matrix_h_
10 #define _TurtleBrains_Matrix_h_
11 
12 #include <cmath>
13 #include <cstring> //memcpy / memset
14 
15 #include "../core/tb_configuration.h"
16 #include "../core/tb_error.h"
17 #include "tb_vector.h"
18 
19 namespace TurtleBrains
20 {
21  namespace Math
22  {
23 
30  class Matrix3
31  {
32  public:
36  static const Matrix3 kZero;
37 
45  static const Matrix3 kIdentity;
46 
47  union
48  {
49  float mComponents[9];
50  struct { //May be deprecating!?
51  float m_f11; float m_f21; float m_f31;
52  float m_f12; float m_f22; float m_f32;
53  float m_f13; float m_f23; float m_f33;
54  };
55  };
56 
60  inline explicit Matrix3( float f11 = 0.0f, float f21 = 0.0f, float f31 = 0.0f,
61  float f12 = 0.0f, float f22 = 0.0f, float f32 = 0.0f,
62  float f13 = 0.0f, float f23 = 0.0f, float f33 = 0.0f)
63  {
64  //m_f11 = f11; m_f21 = f21; m_f31 = f31;
65  //m_f12 = f12; m_f22 = f22; m_f32 = f32;
66  //m_f13 = f13; m_f23 = f23; m_f33 = f33;
67 
68  mComponents[0] = f11; mComponents[1] = f21; mComponents[2] = f31;
69  mComponents[3] = f12; mComponents[4] = f22; mComponents[5] = f32;
70  mComponents[6] = f13; mComponents[7] = f23; mComponents[8] = f33;
71  }
72 
78  inline explicit Matrix3(const float * const componentArray)
79  {
80  memcpy(mComponents, componentArray, sizeof(float) * 9);
81  }
82 
89  inline explicit Matrix3(const SkipInitialization& fastAndStupid)
90  {
91  tb_unused(fastAndStupid);
92  }
93 
97  inline Matrix3(const Matrix3& other)
98  {
99  memcpy(mComponents, other.mComponents, sizeof(float) * 9);
100  }
101 
105  inline Matrix3& operator=(const Matrix3& other)
106  {
107  if (this != &other)
108  {
109  memcpy(mComponents, other.mComponents, sizeof(float) * 9);
110  }
111  return (*this);
112  }
113 
118  inline const float& operator[](const size_t& index) const { return mComponents[index]; }
119 
125  inline float& operator[](const size_t& index) { return mComponents[index]; }
126 
131  inline const float& operator()(const size_t& column, const size_t& row) const { return mComponents[column + (row * 3)]; }
132 
138  inline float& operator()(const size_t& column, const size_t& row) { return mComponents[column + (row * 3)]; }
139 
144  inline const float& operator()(int column, int row) const { return mComponents[column + (row * 3)]; }
145 
151  inline float& operator()(int column, int row) { return mComponents[column + (row * 3)]; }
152 
160  inline operator float*(void) { return mComponents; }
161 
165  inline operator const float*(void) const { return mComponents; }
166 
174  inline Vector3* GetBasis(const size_t& basisIndex) { return (Vector3*)&mComponents[basisIndex * 3]; }
175 
183  inline const Vector3* GetBasis(const size_t& basisIndex) const { return (const Vector3*)&mComponents[basisIndex * 3]; }
184 
191  inline void SetBasis(const size_t& basisIndex, const Vector3 &basis) { *((Vector3*)&mComponents[basisIndex * 3]) = basis; }
192 
201  inline void SetBasis(const size_t& basisIndex, float basisX, float basisY, float basisZ)
202  {
203  mComponents[(basisIndex * 3) + 0] = basisX;
204  mComponents[(basisIndex * 3) + 1] = basisY;
205  mComponents[(basisIndex * 3) + 2] = basisZ;
206  }
207  };
208 
212 
217  class Matrix4
218  {
219  public:
220 
224  static const Matrix4 kZero;
225 
234  static const Matrix4 kIdentity;
235 
236  union
237  {
238  float mComponents[16];
239  struct { //May be deprecating!?
240  float m_f11; float m_f21; float m_f31; float m_f41;
241  float m_f12; float m_f22; float m_f32; float m_f42;
242  float m_f13; float m_f23; float m_f33; float m_f43;
243  float m_f14; float m_f24; float m_f34; float m_f44;
244  };
245  };
246 
250  inline explicit Matrix4( float f11 = 0.0f, float f21 = 0.0f, float f31 = 0.0f, float f41 = 0.0f,
251  float f12 = 0.0f, float f22 = 0.0f, float f32 = 0.0f, float f42 = 0.0f,
252  float f13 = 0.0f, float f23 = 0.0f, float f33 = 0.0f, float f43 = 0.0f,
253  float f14 = 0.0f, float f24 = 0.0f, float f34 = 0.0f, float f44 = 0.0f)
254  {
255  //m_f11 = f11; m_f21 = f21; m_f31 = f31; m_f41 = f41;
256  //m_f12 = f12; m_f22 = f22; m_f32 = f32; m_f42 = f42;
257  //m_f13 = f13; m_f23 = f23; m_f33 = f33; m_f43 = f43;
258  //m_f14 = f14; m_f24 = f24; m_f34 = f34; m_f44 = f44;
259 
260  mComponents[0] = f11; mComponents[1] = f21; mComponents[2] = f31; mComponents[3] = f41;
261  mComponents[4] = f12; mComponents[5] = f22; mComponents[6] = f32; mComponents[7] = f42;
262  mComponents[8] = f13; mComponents[9] = f23; mComponents[10]= f33; mComponents[11]= f43;
263  mComponents[12]= f14; mComponents[13]= f24; mComponents[14]= f34; mComponents[15]= f44;
264  }
265 
271  inline explicit Matrix4(const float * const componentArray)
272  {
273  memcpy(mComponents, componentArray, sizeof(float) << 4); //Same as (sizeof(float) * 16)
274  }
275 
282  inline explicit Matrix4(const SkipInitialization& fastAndStupid)
283  {
284  tb_unused(fastAndStupid);
285  }
286 
290  inline Matrix4(const Matrix4& other)
291  {
292  memcpy(mComponents, other.mComponents, sizeof(float) << 4); //Same as (sizeof(float) * 16)
293  }
294 
298  inline Matrix4& operator=(const Matrix4& other)
299  {
300  if (this != &other)
301  {
302  memcpy(mComponents, other.mComponents, sizeof(float) << 4); //Same as (sizeof(float) * 16)
303  }
304  return (*this);
305  }
306 
311  inline const float& operator[](const size_t& index) const { return mComponents[index]; }
312 
318  inline float& operator[](const size_t& index) { return mComponents[index]; }
319 
324  inline const float& operator()(const size_t& column, const size_t& row) const { return mComponents[column + (row << 2)]; }
325 
331  inline float& operator()(const size_t& column, const size_t& row) { return mComponents[column + (row << 2)]; }
332 
337  inline const float& operator()(int column, int row) const { return mComponents[column + (row << 2)]; }
338 
344  inline float& operator()(int column, int row) { return mComponents[column + (row << 2)]; }
345 
346 
354  inline operator float*(void) { return mComponents; }
355 
359  inline operator const float*(void) const { return mComponents; }
360 
361 
369  inline Vector3* GetBasis(const size_t& basisIndex) { return (Vector3*)&mComponents[basisIndex << 2]; }
370 
378  inline const Vector3* GetBasis(const size_t& basisIndex) const { return (const Vector3*)&mComponents[basisIndex<<2]; }
379 
386  inline void SetBasis(const size_t& basisIndex, const Vector3 &basis) { *((Vector3*)&mComponents[basisIndex<<2]) = basis; }
387 
396  inline void SetBasis(const size_t& basisIndex, float basisX, float basisY, float basisZ)
397  {
398  mComponents[(basisIndex<<2) + 0] = basisX;
399  mComponents[(basisIndex<<2) + 1] = basisY;
400  mComponents[(basisIndex<<2) + 2] = basisZ;
401  }
402 
403 #ifndef tb_math_less_operators
404  inline Vector3 GetPosition(void) const { return Vector3(m_f14, m_f24, m_f34); }
410 
415  inline void SetPosition(const Vector3& position)
416  {
417  m_f14 = position.x;
418  m_f24 = position.y;
419  m_f34 = position.z;
420  }
421 
426  inline void SetPosition(float x, float y, float z) { m_f14 = x; m_f24 = y; m_f34 = z; }
427 
431  inline Matrix4 GetTransposed(void) const
432  {
433  //result->m_f11 = input->m_f11; result->m_f12 = input->m_f21; result->m_f13 = input->m_f31; result->m_f14 = input->m_f41;
434  //result->m_f21 = input->m_f12; result->m_f22 = input->m_f22; result->m_f23 = input->m_f32; result->m_f24 = input->m_f42;
435  //result->m_f31 = input->m_f13; result->m_f32 = input->m_f23; result->m_f33 = input->m_f33; result->m_f34 = input->m_f43;
436  //result->m_f41 = input->m_f14; result->m_f42 = input->m_f24; result->m_f43 = input->m_f34; result->m_f44 = input->m_f44;
437 
438  Matrix4 temp;
439  const Matrix4& self(*this);
440  temp(0, 0) = self(0, 0); temp(0, 1) = self(1, 0); temp(0, 2) = self(2, 0); temp(0, 3) = self(3, 0);
441  temp(1, 0) = self(0, 1); temp(1, 1) = self(1, 1); temp(1, 2) = self(2, 1); temp(1, 3) = self(3, 1);
442  temp(2, 0) = self(0, 2); temp(2, 1) = self(1, 2); temp(2, 2) = self(2, 2); temp(2, 3) = self(3, 2);
443  temp(3, 0) = self(0, 3); temp(3, 1) = self(1, 3); temp(3, 2) = self(2, 3); temp(3, 3) = self(3, 3);
444  return temp;
445  }
446 #endif
447  };
448 
452 
459  {
460  //memset(&matR->m_f11, 0, sizeof(float) << 4);
461  //matR->m_f11 = 1.0f;
462  //matR->m_f22 = 1.0f;
463  //matR->m_f33 = 1.0f;
464  //matR->m_f44 = 1.0f;
465  //return matR;
466 
467  *result = Matrix4::kIdentity;
468  return result;
469  }
470 
480  inline Matrix4* MatrixCreateFromForward(Matrix4* result, const Vector3* forward, const Vector3* up = NULL)
481  {
482  tb_error(true, "Not yet implemented / tested.");
483  MatrixCreateIdentity(result);
484 
485  Vector3 realUp((NULL == up) ? Vector3(0.0f, 1.0f, 0.0f) : *up);
486  Vector3 right, finalUp;
487  Vector3CrossProduct(&right, &realUp, forward);
488  Vector3CrossProduct(&finalUp, &right, forward);
489  //TODO: TIM: Implementation: This would be useful, implement it for future usage!
490  return result;
491  }
492 
499  inline Matrix4* MatrixCreateTranslation(Matrix4* result, const Vector3* translation)
500  { //Changed September 19, 2010
501  MatrixCreateIdentity(result);
502  result->m_f14 = translation->x;//matR->m_f41 = vT->x;
503  result->m_f24 = translation->y;//matR->m_f42 = vT->y;
504  result->m_f34 = translation->z;//matR->m_f43 = vT->z;
505  return result;
506  }
507 
517  inline Matrix4* MatrixCreateTranslation(Matrix4* result, const float translationX, const float translationY, const float translationZ)
518  { //Changed September 19, 2010
519  MatrixCreateIdentity(result);
520  result->m_f14 = translationX;//matR->m_f41 = fX;
521  result->m_f24 = translationY;//matR->m_f42 = fY;
522  result->m_f34 = translationZ;//matR->m_f43 = fZ;
523  return result;
524  }
525 
533  inline Matrix4* MatrixCreateScale(Matrix4* result, Vector3* scale)
534  {
535  memset(result->mComponents, 0, sizeof(float) << 4);
536  result->m_f11 = scale->x;
537  result->m_f22 = scale->y;
538  result->m_f33 = scale->z;
539  result->m_f44 = 1.0f;
540  return result;
541  }
542 
552  inline Matrix4* MatrixCreateScale(Matrix4* result, const float scaleX, const float scaleY, const float scaleZ)
553  {
554  memset(result->mComponents, 0, sizeof(float) << 4);
555  result->m_f11 = scaleX;
556  result->m_f22 = scaleY;
557  result->m_f33 = scaleZ;
558  result->m_f44 = 1.0f;
559  return result;
560  }
561 
569  inline Matrix4* MatrixCreateRotationX(Matrix4* result, const float rotationInDegrees)
570  {
571  const float rotationInRadians(tbMath::Convert::DegreesToRadians(rotationInDegrees));
572 
573  MatrixCreateIdentity(result);
574  result->m_f22 = cos(rotationInRadians);
575  result->m_f32 = -sin(rotationInRadians);
576  result->m_f23 = sin(rotationInRadians);
577  result->m_f33 = cos(rotationInRadians);
578  return result;
579  }
580 
588  inline Matrix4* MatrixCreateRotationY(Matrix4* result, const float rotationInDegrees)
589  {
590  const float rotationInRadians(tbMath::Convert::DegreesToRadians(rotationInDegrees));
591 
592  MatrixCreateIdentity(result);
593  result->m_f11 = cos(rotationInRadians);
594  result->m_f31 = sin(rotationInRadians);
595  result->m_f13 = -sin(rotationInRadians);
596  result->m_f33 = cos(rotationInRadians);
597  return result;
598  }
599 
607  inline Matrix4* MatrixCreateRotationZ(Matrix4* result, const float rotationInDegrees)
608  {
609  const float rotationInRadians(tbMath::Convert::DegreesToRadians(rotationInDegrees));
610 
611  MatrixCreateIdentity(result);
612  result->m_f11 = cos(rotationInRadians);
613  result->m_f21 = -sin(rotationInRadians);
614  result->m_f12 = sin(rotationInRadians);
615  result->m_f22 = cos(rotationInRadians);
616  return result;
617  }
618 
627  inline Matrix4* MatrixCreateRotationA(Matrix4* result, const Vector3* rotationAxis, const float rotationInDegrees)
628  {
629  const float rotationInRadians(tbMath::Convert::DegreesToRadians(rotationInDegrees));
630 
631  // Rotations.
632  const float s = sinf(rotationInRadians);
633  const float c = cosf(rotationInRadians);
634  const float t = 1.0f - c;
635 
636  float x = rotationAxis->x;
637  float y = rotationAxis->y;
638  float z = rotationAxis->z;
639 
640  const float tx = t * rotationAxis->x;
641  const float ty = t * rotationAxis->y;
642  const float tz = t * rotationAxis->z;
643  const float sx = s * rotationAxis->x;
644  const float sy = s * rotationAxis->y;
645  const float sz = s * rotationAxis->z;
646 
647  result->mComponents[0] = tx * x + c;
648  result->mComponents[1] = tx * y + sz;
649  result->mComponents[2] = tx * z - sy;
650  result->mComponents[3] = 0.0f;
651 
652  result->mComponents[4] = tx * y - sz;
653  result->mComponents[5] = ty * y + c;
654  result->mComponents[6] = ty * z + sx;
655  result->mComponents[7] = 0.0f;
656 
657  result->mComponents[8] = tx * z + sy;
658  result->mComponents[9] = ty * z - sx;
659  result->mComponents[10] = tz * z + c;
660  result->mComponents[11] = 0.0f;
661 
662  result->mComponents[12] = 0.0f;
663  result->mComponents[13] = 0.0f;
664  result->mComponents[14] = 0.0f;
665  result->mComponents[15] = 1.0f;
666 
667  return result;
668  }
669 
679  inline Matrix4* MatrixCreatePerspectiveRH(Matrix4* result, const float fieldOfView, const float aspectRatio,
680  const float nearPlane, const float farPlane)
681  {
682  memset(result->mComponents, 0, sizeof(float) << 4);
683 
684  const float f = 1.0f / tanf(fieldOfView / 2.0f);
685  result->m_f11 = f / aspectRatio;
686  result->m_f22 = f;
687  result->m_f33 = (farPlane) / (nearPlane - farPlane);
688  result->m_f43 = -1.0f;
689  result->m_f34 = (nearPlane * farPlane) / (nearPlane - farPlane);
690 
691  return result;
692  }
693 
703  inline Matrix4* MatrixCreatePerspectiveLH(Matrix4* result, const float fieldOfView, const float aspectRatio,
704  const float nearPlane, const float farPlane)
705  {
706  memset(result->mComponents, 0, sizeof(float) << 4);
707 
708  const float f = 1.0f / tanf(fieldOfView / 2.0f);
709  result->m_f11 = f / aspectRatio;
710  result->m_f22 = f;
711  result->m_f33 = (farPlane) / (farPlane - nearPlane);
712  result->m_f43 = 1.0f;
713  result->m_f34 = -(nearPlane * farPlane) / (farPlane - nearPlane);
714 
715  return result;
716  }
717 
733  inline Matrix4* MatrixCreateOrthoRH(Matrix4* result, const float width, const float height,
734  const float nearPlane, const float farPlane)
735  {
736  memset(result->mComponents, 0, sizeof(float) << 4);
737 
738  result->m_f11 = 2.0f / width;
739  result->m_f22 = 2.0f / height;
740  result->m_f33 = 1.0f / (nearPlane - farPlane);
741  result->m_f34 = nearPlane / (nearPlane - farPlane);
742  result->m_f44 = 1.0f;
743 
744  return result;
745  }
746 
762  inline Matrix4* MatrixCreateOrthoLH(Matrix4* result, const float width, const float height,
763  const float nearPlane, const float farPlane)
764  {
765  memset(result->mComponents, 0, sizeof(float) << 4);
766 
767  //matR->m_f11 = 2.0f / fWidth;
768  //matR->m_f22 = 2.0f / fHeight;
769  //matR->m_f33 = 1 / (fFar - fNear);
770  //matR->m_f34 = fNear / (fNear - fFar);
771  //matR->m_f44 = 1;
772 
773  result->m_f11 = 2.0f / width;
774  result->m_f22 = 2.0f / height;
775  result->m_f33 = 1.0f / (farPlane - nearPlane);
776  result->m_f34 = nearPlane / (nearPlane - farPlane);
777  result->m_f44 = 1.0f;
778 
779  return result;
780  }
781 
789  inline Matrix4* MatrixAdd(Matrix4 *result, const Matrix4 *leftSide, const Matrix4 *rightSide)
790  {
791  float *r = result->mComponents;
792  const float *m1 = leftSide->mComponents;
793  const float *m2 = rightSide->mComponents;
794 
795  r[0] = m1[0] + m2[0]; r[1] = m1[1] + m2[1]; r[2] = m1[2] + m2[2]; r[3] = m1[3] + m2[3];
796  r[4] = m1[4] + m2[4]; r[5] = m1[5] + m2[5]; r[6] = m1[6] + m2[6]; r[7] = m1[7] + m2[7];
797  r[8] = m1[8] + m2[8]; r[9] = m1[9] + m2[9]; r[10] = m1[10] + m2[10]; r[11] = m1[11] + m2[11];
798  r[12] = m1[12] + m2[12]; r[13] = m1[13] + m2[13]; r[14] = m1[14] + m2[14]; r[15] = m1[15] + m2[15];
799  return result;
800  }
801 
809  inline Matrix4* MatrixSubtract(Matrix4* result, const Matrix4* leftSide, const Matrix4* rightSide)
810  {
811  float *r = result->mComponents;
812  const float *m1 = leftSide->mComponents;
813  const float *m2 = rightSide->mComponents;
814 
815  r[0] = m1[0] - m2[0]; r[1] = m1[1] - m2[1]; r[2] = m1[2] - m2[2]; r[3] = m1[3] - m2[3];
816  r[4] = m1[4] - m2[4]; r[5] = m1[5] - m2[5]; r[6] = m1[6] - m2[6]; r[7] = m1[7] - m2[7];
817  r[8] = m1[8] - m2[8]; r[9] = m1[9] - m2[9]; r[10] = m1[10] - m2[10]; r[11] = m1[11] - m2[11];
818  r[12] = m1[12] - m2[12]; r[13] = m1[13] - m2[13]; r[14] = m1[14] - m2[14]; r[15] = m1[15] - m2[15];
819  return result;
820  }
821 
828  inline Matrix4* MatrixTranspose(Matrix4* result, const Matrix4* input)
829  {
830  tb_error_if(result == input, "tbExternalError: Invalid parameter; expected result to be different than input");
831  result->m_f11 = input->m_f11; result->m_f12 = input->m_f21; result->m_f13 = input->m_f31; result->m_f14 = input->m_f41;
832  result->m_f21 = input->m_f12; result->m_f22 = input->m_f22; result->m_f23 = input->m_f32; result->m_f24 = input->m_f42;
833  result->m_f31 = input->m_f13; result->m_f32 = input->m_f23; result->m_f33 = input->m_f33; result->m_f34 = input->m_f43;
834  result->m_f41 = input->m_f14; result->m_f42 = input->m_f24; result->m_f43 = input->m_f34; result->m_f44 = input->m_f44;
835  return result;
836  }
837 
848  inline Matrix4* MatrixMultiply(Matrix4* result, const Matrix4* leftSide, const Matrix4* rightSide)
849  {
850  tb_error_if(result == leftSide || result == rightSide, "tbExternalError: Invalid parameter; expected result to be different than leftSide and rightSide");
851  result->m_f11 = (leftSide->m_f11 * rightSide->m_f11) + (leftSide->m_f21 * rightSide->m_f12) + (leftSide->m_f31 * rightSide->m_f13) + (leftSide->m_f41 * rightSide->m_f14);
852  result->m_f21 = (leftSide->m_f11 * rightSide->m_f21) + (leftSide->m_f21 * rightSide->m_f22) + (leftSide->m_f31 * rightSide->m_f23) + (leftSide->m_f41 * rightSide->m_f24);
853  result->m_f31 = (leftSide->m_f11 * rightSide->m_f31) + (leftSide->m_f21 * rightSide->m_f32) + (leftSide->m_f31 * rightSide->m_f33) + (leftSide->m_f41 * rightSide->m_f34);
854  result->m_f41 = (leftSide->m_f11 * rightSide->m_f41) + (leftSide->m_f21 * rightSide->m_f42) + (leftSide->m_f31 * rightSide->m_f43) + (leftSide->m_f41 * rightSide->m_f44);
855  result->m_f12 = (leftSide->m_f12 * rightSide->m_f11) + (leftSide->m_f22 * rightSide->m_f12) + (leftSide->m_f32 * rightSide->m_f13) + (leftSide->m_f42 * rightSide->m_f14);
856  result->m_f22 = (leftSide->m_f12 * rightSide->m_f21) + (leftSide->m_f22 * rightSide->m_f22) + (leftSide->m_f32 * rightSide->m_f23) + (leftSide->m_f42 * rightSide->m_f24);
857  result->m_f32 = (leftSide->m_f12 * rightSide->m_f31) + (leftSide->m_f22 * rightSide->m_f32) + (leftSide->m_f32 * rightSide->m_f33) + (leftSide->m_f42 * rightSide->m_f34);
858  result->m_f42 = (leftSide->m_f12 * rightSide->m_f41) + (leftSide->m_f22 * rightSide->m_f42) + (leftSide->m_f32 * rightSide->m_f43) + (leftSide->m_f42 * rightSide->m_f44);
859  result->m_f13 = (leftSide->m_f13 * rightSide->m_f11) + (leftSide->m_f23 * rightSide->m_f12) + (leftSide->m_f33 * rightSide->m_f13) + (leftSide->m_f43 * rightSide->m_f14);
860  result->m_f23 = (leftSide->m_f13 * rightSide->m_f21) + (leftSide->m_f23 * rightSide->m_f22) + (leftSide->m_f33 * rightSide->m_f23) + (leftSide->m_f43 * rightSide->m_f24);
861  result->m_f33 = (leftSide->m_f13 * rightSide->m_f31) + (leftSide->m_f23 * rightSide->m_f32) + (leftSide->m_f33 * rightSide->m_f33) + (leftSide->m_f43 * rightSide->m_f34);
862  result->m_f43 = (leftSide->m_f13 * rightSide->m_f41) + (leftSide->m_f23 * rightSide->m_f42) + (leftSide->m_f33 * rightSide->m_f43) + (leftSide->m_f43 * rightSide->m_f44);
863  result->m_f14 = (leftSide->m_f14 * rightSide->m_f11) + (leftSide->m_f24 * rightSide->m_f12) + (leftSide->m_f34 * rightSide->m_f13) + (leftSide->m_f44 * rightSide->m_f14);
864  result->m_f24 = (leftSide->m_f14 * rightSide->m_f21) + (leftSide->m_f24 * rightSide->m_f22) + (leftSide->m_f34 * rightSide->m_f23) + (leftSide->m_f44 * rightSide->m_f24);
865  result->m_f34 = (leftSide->m_f14 * rightSide->m_f31) + (leftSide->m_f24 * rightSide->m_f32) + (leftSide->m_f34 * rightSide->m_f33) + (leftSide->m_f44 * rightSide->m_f34);
866  result->m_f44 = (leftSide->m_f14 * rightSide->m_f41) + (leftSide->m_f24 * rightSide->m_f42) + (leftSide->m_f34 * rightSide->m_f43) + (leftSide->m_f44 * rightSide->m_f44);
867  return result;
868  }
869 
879  inline Vector4* Vector4MatrixMultiply(Vector4* result, const Vector4* inputVector, const Matrix4* inputMatrix)
880  {
881  tb_error_if(result == inputVector , "tbExternalError: Invalid parameter; expected result to be different than inputVector.");
882  result->x = (inputVector->x * inputMatrix->m_f11) + (inputVector->y * inputMatrix->m_f12) + (inputVector->z * inputMatrix->m_f13) + (inputVector->w * inputMatrix->m_f14);
883  result->y = (inputVector->x * inputMatrix->m_f21) + (inputVector->y * inputMatrix->m_f22) + (inputVector->z * inputMatrix->m_f23) + (inputVector->w * inputMatrix->m_f24);
884  result->z = (inputVector->x * inputMatrix->m_f31) + (inputVector->y * inputMatrix->m_f32) + (inputVector->z * inputMatrix->m_f33) + (inputVector->w * inputMatrix->m_f34);
885  result->w = (inputVector->x * inputMatrix->m_f41) + (inputVector->y * inputMatrix->m_f42) + (inputVector->z * inputMatrix->m_f43) + (inputVector->w * inputMatrix->m_f44);
886  return result;
887  }
888 
889  /*~**********************************************************************************************************************
890  * ~Function: "Vector3TransformCoord" *
891  * ~Modified By: Tim Beaudet *
892  * ~Last Updated: 11/8/2009 *
893  * *
894  * ~Purpose: Multiplies a vector and a matrix and returns the results in vR. This multiplies the 3component *
895  * vector v1 by the matrix. v1 is taken as a coordinate, so its W component is set to 1. *
896  * *
897  * ~In: vR The results of the multiplication of the vector and the matrix. *
898  * mat The matrix to multiply. *
899  * v1 The vector to multiply, can NOT be vR. *
900  * *
901  * ~Out: The resulting transformed coordinate. Notice that W component is set to 1. *
902  **********************************************************************************************************************~*/
903 
914  inline Vector3* Vector3TransformCoord(Vector3* result, const Vector3* inputVector, const Matrix4* inputMatrix)
915  {
916  tb_error_if(result == inputVector, "tbExternalError: Invalid parameter; expected result to be different than inputVector");
917  result->x = (inputVector->x * inputMatrix->m_f11) + (inputVector->y * inputMatrix->m_f12) + (inputVector->z * inputMatrix->m_f13) + inputMatrix->m_f14;
918  result->y = (inputVector->x * inputMatrix->m_f21) + (inputVector->y * inputMatrix->m_f22) + (inputVector->z * inputMatrix->m_f23) + inputMatrix->m_f24;
919  result->z = (inputVector->x * inputMatrix->m_f31) + (inputVector->y * inputMatrix->m_f32) + (inputVector->z * inputMatrix->m_f33) + inputMatrix->m_f34;
920  return result;
921  }
922 
923  /*~**********************************************************************************************************************
924  * ~Function: "Vector3TransformNormal" *
925  * ~Modified By: Tim Beaudet *
926  * ~Last Updated: 11/8/2009 *
927  * *
928  * ~Purpose: Multiplies a vector and a matrix and returns the results in vR. This multiplies the 3component *
929  * vector v1 by the matrix. v1 is taken as a coordinate, so its W component is set to 0. *
930  * *
931  * ~In: vR The results of the multiplication of the vector and the matrix. *
932  * mat The matrix to multiply. *
933  * v1 The vector to multiply, can NOT be vR. *
934  * *
935  * ~Out: The resulting transformed normal or directional vector. Notice that W component is set to 0. *
936  **********************************************************************************************************************~*/
937 
948  inline Vector3* Vector3TransformNormal(Vector3* result, const Vector3* inputVector, const Matrix4* inputMatrix)
949  {
950  tb_error_if(result == inputVector, "tbExternalError: Invalid parameter; expected result to be different than inputVector");
951  result->x = (inputVector->x * inputMatrix->m_f11) + (inputVector->y * inputMatrix->m_f12) + (inputVector->z * inputMatrix->m_f13);
952  result->y = (inputVector->x * inputMatrix->m_f21) + (inputVector->y * inputMatrix->m_f22) + (inputVector->z * inputMatrix->m_f23);
953  result->z = (inputVector->x * inputMatrix->m_f31) + (inputVector->y * inputMatrix->m_f32) + (inputVector->z * inputMatrix->m_f33);
954  return result;
955  }
956 
961  inline float Matrix3x3Determinant(const float f11, const float f12, const float f13, const float f21, const float f22, const float f23, const float f31, const float f32, const float f33)
962  {
963  return f11 * (f22 * f33 - f32 * f23) - f12 * (f21 * f33 - f31 * f23) + f13 * (f21 * f32 - f31 * f22);
964  }
965 
970  inline float MatrixDeterminant(const Matrix4* input)
971  {
972  return input->m_f11 * Matrix3x3Determinant(input->m_f22, input->m_f32, input->m_f42, input->m_f23, input->m_f33, input->m_f43, input->m_f24, input->m_f34, input->m_f44) -
973  input->m_f21 * Matrix3x3Determinant(input->m_f12, input->m_f32, input->m_f42, input->m_f13, input->m_f33, input->m_f43, input->m_f14, input->m_f34, input->m_f44) +
974  input->m_f31 * Matrix3x3Determinant(input->m_f12, input->m_f22, input->m_f42, input->m_f13, input->m_f23, input->m_f43, input->m_f14, input->m_f24, input->m_f44) -
975  input->m_f41 * Matrix3x3Determinant(input->m_f12, input->m_f22, input->m_f32, input->m_f13, input->m_f23, input->m_f33, input->m_f14, input->m_f24, input->m_f34);
976  }
977 
989  inline Matrix4* MatrixComputeInverse(Matrix4* result, const Matrix4* input)
990  {
991  tb_error_if(result == input, "tbExternalError: Invalid parameter, expected result to be different than input.");
992  const float determinant = MatrixDeterminant(input);
993  if (true == IsZero(determinant))
994  {
995  *result = *input;
996  return result;
997  }
998 
999  const float inverseDeterminant = 1.0f / determinant;
1000 
1001  result->m_f11 = (Matrix3x3Determinant (input->m_f22, input->m_f32, input->m_f42, input->m_f23, input->m_f33, input->m_f43, input->m_f24, input->m_f34, input->m_f44)) * inverseDeterminant;
1002  result->m_f21 = (-Matrix3x3Determinant(input->m_f21, input->m_f31, input->m_f41, input->m_f23, input->m_f33, input->m_f43, input->m_f24, input->m_f34, input->m_f44)) * inverseDeterminant;
1003  result->m_f31 = (Matrix3x3Determinant (input->m_f21, input->m_f31, input->m_f41, input->m_f22, input->m_f32, input->m_f42, input->m_f24, input->m_f34, input->m_f44)) * inverseDeterminant;
1004  result->m_f41 = (-Matrix3x3Determinant(input->m_f21, input->m_f31, input->m_f41, input->m_f22, input->m_f32, input->m_f42, input->m_f23, input->m_f33, input->m_f43)) * inverseDeterminant;
1005  result->m_f12 = (-Matrix3x3Determinant(input->m_f12, input->m_f32, input->m_f42, input->m_f13, input->m_f33, input->m_f43, input->m_f14, input->m_f34, input->m_f44)) * inverseDeterminant;
1006  result->m_f22 = (Matrix3x3Determinant (input->m_f11, input->m_f31, input->m_f41, input->m_f13, input->m_f33, input->m_f43, input->m_f14, input->m_f34, input->m_f44)) * inverseDeterminant;
1007  result->m_f32 = (-Matrix3x3Determinant(input->m_f11, input->m_f31, input->m_f41, input->m_f12, input->m_f32, input->m_f42, input->m_f14, input->m_f34, input->m_f44)) * inverseDeterminant;
1008  result->m_f42 = (Matrix3x3Determinant (input->m_f11, input->m_f31, input->m_f41, input->m_f12, input->m_f32, input->m_f42, input->m_f13, input->m_f33, input->m_f43)) * inverseDeterminant;
1009  result->m_f13 = (Matrix3x3Determinant (input->m_f12, input->m_f22, input->m_f42, input->m_f13, input->m_f23, input->m_f43, input->m_f14, input->m_f24, input->m_f44)) * inverseDeterminant;
1010  result->m_f23 = (-Matrix3x3Determinant(input->m_f11, input->m_f21, input->m_f41, input->m_f13, input->m_f23, input->m_f43, input->m_f14, input->m_f24, input->m_f44)) * inverseDeterminant;
1011  result->m_f33 = (Matrix3x3Determinant (input->m_f11, input->m_f21, input->m_f41, input->m_f12, input->m_f22, input->m_f42, input->m_f14, input->m_f24, input->m_f44)) * inverseDeterminant;
1012  result->m_f43 = (-Matrix3x3Determinant(input->m_f11, input->m_f21, input->m_f41, input->m_f12, input->m_f22, input->m_f42, input->m_f13, input->m_f23, input->m_f43)) * inverseDeterminant;
1013  result->m_f14 = (-Matrix3x3Determinant(input->m_f12, input->m_f22, input->m_f32, input->m_f13, input->m_f23, input->m_f33, input->m_f14, input->m_f24, input->m_f34)) * inverseDeterminant;
1014  result->m_f24 = (Matrix3x3Determinant (input->m_f11, input->m_f21, input->m_f31, input->m_f13, input->m_f23, input->m_f33, input->m_f14, input->m_f24, input->m_f34)) * inverseDeterminant;
1015  result->m_f34 = (-Matrix3x3Determinant(input->m_f11, input->m_f21, input->m_f31, input->m_f12, input->m_f22, input->m_f32, input->m_f14, input->m_f24, input->m_f34)) * inverseDeterminant;
1016  result->m_f44 = (Matrix3x3Determinant (input->m_f11, input->m_f21, input->m_f31, input->m_f12, input->m_f22, input->m_f32, input->m_f13, input->m_f24, input->m_f33)) * inverseDeterminant;
1017 
1018  return result;
1019  }
1020 
1021  }; /* namespace Math */
1022 }; /* namespace TurtleBrains */
1023 
1024 namespace tbMath = TurtleBrains::Math;
1025 
1026 #endif /* _TurtleBrains_Matrix_h_ */
Matrix4 * MatrixCreateOrthoLH(Matrix4 *result, const float width, const float height, const float nearPlane, const float farPlane)
Definition: tb_matrix.h:762
Matrix4 * MatrixCreateOrthoRH(Matrix4 *result, const float width, const float height, const float nearPlane, const float farPlane)
Definition: tb_matrix.h:733
const float & operator()(int column, int row) const
Definition: tb_matrix.h:144
Contains objects and functions for dealing with Vector and Matrix math.
float MatrixDeterminant(const Matrix4 *input)
Definition: tb_matrix.h:970
Vector3 * Vector3TransformNormal(Vector3 *result, const Vector3 *inputVector, const Matrix4 *inputMatrix)
Definition: tb_matrix.h:948
#define tb_error(message,...)
Definition: tb_error.h:23
const float & operator()(const size_t &column, const size_t &row) const
Definition: tb_matrix.h:324
Definition: tb_vector.h:296
Matrix3(float f11=0.0f, float f21=0.0f, float f31=0.0f, float f12=0.0f, float f22=0.0f, float f32=0.0f, float f13=0.0f, float f23=0.0f, float f33=0.0f)
Definition: tb_matrix.h:60
Definition: tb_matrix.h:30
Matrix4 * MatrixCreateRotationY(Matrix4 *result, const float rotationInDegrees)
Definition: tb_matrix.h:588
float & operator()(int column, int row)
Definition: tb_matrix.h:344
float Matrix3x3Determinant(const float f11, const float f12, const float f13, const float f21, const float f22, const float f23, const float f31, const float f32, const float f33)
Definition: tb_matrix.h:961
Matrix4 * MatrixCreateFromForward(Matrix4 *result, const Vector3 *forward, const Vector3 *up=NULL)
Definition: tb_matrix.h:480
float & operator[](const size_t &index)
Definition: tb_matrix.h:125
Matrix4 * MatrixMultiply(Matrix4 *result, const Matrix4 *leftSide, const Matrix4 *rightSide)
Definition: tb_matrix.h:848
Matrix4 * MatrixComputeInverse(Matrix4 *result, const Matrix4 *input)
Definition: tb_matrix.h:989
Contains all functions, classes and helpers related to game/application development written by Tim "B...
Definition: tb_application_dialog.h:21
Matrix4 * MatrixCreateTranslation(Matrix4 *result, const Vector3 *translation)
Definition: tb_matrix.h:499
Matrix4 * MatrixCreateRotationA(Matrix4 *result, const Vector3 *rotationAxis, const float rotationInDegrees)
Definition: tb_matrix.h:627
#define tb_unused(parameter)
Definition: tb_defines.h:19
static const Matrix4 kZero
Definition: tb_matrix.h:224
const Vector3 * GetBasis(const size_t &basisIndex) const
Definition: tb_matrix.h:378
Definition: tb_matrix.h:217
SkipInitialization
Definition: tb_vector.h:30
static const Matrix3 kIdentity
Definition: tb_matrix.h:45
float & operator[](const size_t &index)
Definition: tb_matrix.h:318
Matrix3(const Matrix3 &other)
Definition: tb_matrix.h:97
float & operator()(const size_t &column, const size_t &row)
Definition: tb_matrix.h:331
Vector3 GetPosition(void) const
Definition: tb_matrix.h:409
static const Matrix4 kIdentity
Definition: tb_matrix.h:234
Matrix4 * MatrixCreatePerspectiveLH(Matrix4 *result, const float fieldOfView, const float aspectRatio, const float nearPlane, const float farPlane)
Definition: tb_matrix.h:703
static const Matrix3 kZero
Definition: tb_matrix.h:36
Matrix4 * MatrixTranspose(Matrix4 *result, const Matrix4 *input)
Definition: tb_matrix.h:828
Vector4 * Vector4MatrixMultiply(Vector4 *result, const Vector4 *inputVector, const Matrix4 *inputMatrix)
Definition: tb_matrix.h:879
Matrix4(float f11=0.0f, float f21=0.0f, float f31=0.0f, float f41=0.0f, float f12=0.0f, float f22=0.0f, float f32=0.0f, float f42=0.0f, float f13=0.0f, float f23=0.0f, float f33=0.0f, float f43=0.0f, float f14=0.0f, float f24=0.0f, float f34=0.0f, float f44=0.0f)
Definition: tb_matrix.h:250
Matrix4 * MatrixCreatePerspectiveRH(Matrix4 *result, const float fieldOfView, const float aspectRatio, const float nearPlane, const float farPlane)
Definition: tb_matrix.h:679
Matrix4(const float *const componentArray)
Definition: tb_matrix.h:271
Vector3 * GetBasis(const size_t &basisIndex)
Definition: tb_matrix.h:369
void SetBasis(const size_t &basisIndex, float basisX, float basisY, float basisZ)
Definition: tb_matrix.h:201
Vector3 * Vector3TransformCoord(Vector3 *result, const Vector3 *inputVector, const Matrix4 *inputMatrix)
Definition: tb_matrix.h:914
Matrix4 * MatrixCreateScale(Matrix4 *result, Vector3 *scale)
Definition: tb_matrix.h:533
Matrix4 & operator=(const Matrix4 &other)
Definition: tb_matrix.h:298
Matrix4 * MatrixSubtract(Matrix4 *result, const Matrix4 *leftSide, const Matrix4 *rightSide)
Definition: tb_matrix.h:809
Matrix4 * MatrixCreateRotationX(Matrix4 *result, const float rotationInDegrees)
Definition: tb_matrix.h:569
const float & operator[](const size_t &index) const
Definition: tb_matrix.h:118
void SetBasis(const size_t &basisIndex, const Vector3 &basis)
Definition: tb_matrix.h:191
const float & operator()(int column, int row) const
Definition: tb_matrix.h:337
bool IsZero(const float value, const float tolerance=tbMath::kTolerance)
Definition: tb_math.h:41
Matrix3(const SkipInitialization &fastAndStupid)
Definition: tb_matrix.h:89
Vector3 * Vector3CrossProduct(Vector3 *result, const Vector3 *leftSide, const Vector3 *rightSide)
Definition: tb_vector.h:1174
const Vector3 * GetBasis(const size_t &basisIndex) const
Definition: tb_matrix.h:183
void SetPosition(float x, float y, float z)
Definition: tb_matrix.h:426
Matrix3 & operator=(const Matrix3 &other)
Definition: tb_matrix.h:105
Vector3 * GetBasis(const size_t &basisIndex)
Definition: tb_matrix.h:174
float & operator()(const size_t &column, const size_t &row)
Definition: tb_matrix.h:138
Matrix4 GetTransposed(void) const
Definition: tb_matrix.h:431
const float & operator()(const size_t &column, const size_t &row) const
Definition: tb_matrix.h:131
void SetBasis(const size_t &basisIndex, const Vector3 &basis)
Definition: tb_matrix.h:386
void SetBasis(const size_t &basisIndex, float basisX, float basisY, float basisZ)
Definition: tb_matrix.h:396
#define tb_error_if(errorTest, message,...)
Definition: tb_error.h:37
Matrix4(const Matrix4 &other)
Definition: tb_matrix.h:290
Matrix4 * MatrixAdd(Matrix4 *result, const Matrix4 *leftSide, const Matrix4 *rightSide)
Definition: tb_matrix.h:789
Matrix4 * MatrixCreateIdentity(Matrix4 *result)
Definition: tb_matrix.h:458
float & operator()(int column, int row)
Definition: tb_matrix.h:151
const float & operator[](const size_t &index) const
Definition: tb_matrix.h:311
Matrix4 * MatrixCreateRotationZ(Matrix4 *result, const float rotationInDegrees)
Definition: tb_matrix.h:607
void SetPosition(const Vector3 &position)
Definition: tb_matrix.h:415
Matrix3(const float *const componentArray)
Definition: tb_matrix.h:78
Definition: tb_vector.h:587
Matrix4(const SkipInitialization &fastAndStupid)
Definition: tb_matrix.h:282