home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 4819 / rage.7z / slMatrix.h < prev    next >
Encoding:
C/C++ Source or Header  |  2011-09-19  |  13.0 KB  |  551 lines

  1. #ifndef __SL_MATRIX_H
  2. #define __SL_MATRIX_H
  3.  
  4. #include<iostream>
  5. #include<cstring>
  6. #include<cmath>
  7.  
  8. #include "slMathTraits.h"
  9. #include "slVector3D.h"
  10.  
  11. namespace sl {
  12.  
  13. template<class T>
  14. class matrix4x4 {
  15.  private :
  16.   T m[16];
  17.  public :
  18.   static const unsigned int M11 =  0;
  19.   static const unsigned int M12 =  1;
  20.   static const unsigned int M13 =  2;
  21.   static const unsigned int M14 =  3;
  22.   static const unsigned int M21 =  4;
  23.   static const unsigned int M22 =  5;
  24.   static const unsigned int M23 =  6;
  25.   static const unsigned int M24 =  7;
  26.   static const unsigned int M31 =  8;
  27.   static const unsigned int M32 =  9;
  28.   static const unsigned int M33 = 10;
  29.   static const unsigned int M34 = 11;
  30.   static const unsigned int M41 = 12;
  31.   static const unsigned int M42 = 13;
  32.   static const unsigned int M43 = 14;
  33.   static const unsigned int M44 = 15;
  34.  public :
  35.   T& operator [](int index);
  36.   const T& operator [](int index)const;
  37.   T& operator ()(int r, int c);
  38.   const T& operator ()(int r, int c)const;
  39.  public :
  40.   matrix4x4<T>& operator +=(const matrix4x4<T>& M);
  41.   matrix4x4<T>& operator -=(const matrix4x4<T>& M);
  42.   matrix4x4<T>& operator *=(const matrix4x4<T>& M);
  43.   matrix4x4<T>& operator *=(T scalar);
  44.   matrix4x4<T>& operator /=(T scalar);
  45.  public :
  46.   matrix4x4<T>& operator =(const matrix4x4<T>& M);
  47.  public :
  48.   const T* c_ptr(void)const;
  49.  public :
  50.   void load_identity(void);
  51.   void load_translation(T x, T y, T z);
  52.   void load_translation(const vector3D<T>& v);
  53.   void load_rotation_x(T radians);
  54.   void load_rotation_y(T radians);
  55.   void load_rotation_z(T radians);
  56.   void load_rotation(T radians, T x, T y, T z);
  57.   void load_euler(T H, T P, T B);
  58.   void load_euler_lw(T H, T P, T B);
  59.  public :
  60.   void translate(T x, T y, T z);
  61.   void translate(const vector3D<T>& v);
  62.   void rotate_x(T radians);
  63.   void rotate_y(T radians);
  64.   void rotate_z(T radians);
  65.   void rotate(T radians, T x, T y, T z);
  66.  public :
  67.   void to_euler(T& H, T& P, T& B);
  68.   void multiply_by(const vector3D<T>& V, vector3D<T>& R);
  69.  public :
  70.   matrix4x4();
  71.   matrix4x4(T* data);
  72.   matrix4x4(const matrix4x4<T>& M);
  73.  ~matrix4x4();
  74. };
  75.  
  76. template<class T>
  77. inline matrix4x4<T>::matrix4x4()
  78. {
  79. }
  80.  
  81. template<class T>
  82. inline matrix4x4<T>::matrix4x4(T* data)
  83. {
  84.  std::memmove(m, data, 16*sizeof(T));
  85. }
  86.  
  87. template<class T>
  88. inline matrix4x4<T>::matrix4x4(const matrix4x4<T>& M)
  89. {
  90.  std::memmove(m, M.m, 16*sizeof(T));
  91. }
  92.  
  93. template<class T>
  94. inline matrix4x4<T>::~matrix4x4()
  95. {
  96. }
  97.  
  98. template<class T>
  99. inline matrix4x4<T>& matrix4x4<T>::operator =(const matrix4x4<T>& M)
  100. {
  101.  if(this == &M) return *this;
  102.  std::memmove(m, M.m, 16*sizeof(T));
  103.  return *this;
  104. }
  105.  
  106. template<class T>
  107. T& matrix4x4<T>::operator [](int index)
  108. {
  109.  return m[index];
  110. }
  111.  
  112. template<class T>
  113. const T& matrix4x4<T>::operator [](int index)const
  114. {
  115.  return m[index];
  116. }
  117.  
  118. template<class T>
  119. inline T& matrix4x4<T>::operator ()(int r, int c)
  120. {
  121.  return m[4*r + c];
  122. }
  123.  
  124. template<class T>
  125. inline const T& matrix4x4<T>::operator ()(int r, int c)const
  126. {
  127.  return m[4*r + c];
  128. }
  129.  
  130. template<class T>
  131. inline const T* matrix4x4<T>::c_ptr(void)const
  132. {
  133.  return &m[0];
  134. }
  135.  
  136. template<class T>
  137. inline void matrix4x4<T>::load_identity(void)
  138. {
  139.  T v0 = math_traits<T>::zero();
  140.  T v1 = math_traits<T>::one();
  141.  m[ 0] = v1; m[ 1] = v0; m[ 2] = v0; m[ 3] = v0;
  142.  m[ 4] = v0; m[ 5] = v1; m[ 6] = v0; m[ 7] = v0;
  143.  m[ 8] = v0; m[ 9] = v0; m[10] = v1; m[11] = v0;
  144.  m[12] = v0; m[13] = v0; m[14] = v0; m[15] = v1;
  145. }
  146.  
  147. template<class T>
  148. inline void matrix4x4<T>::load_translation(T x, T y, T z)
  149. {
  150.  T v0 = math_traits<T>::zero();
  151.  T v1 = math_traits<T>::one();
  152.  m[ 0] = v1; m[ 1] = v0; m[ 2] = v0; m[ 3] = x;
  153.  m[ 4] = v0; m[ 5] = v1; m[ 6] = v0; m[ 7] = y;
  154.  m[ 8] = v0; m[ 9] = v0; m[10] = v1; m[11] = z;
  155.  m[12] = v0; m[13] = v0; m[14] = v0; m[15] = v1;
  156. }
  157.  
  158. template<class T>
  159. inline void matrix4x4<T>::load_translation(const vector3D<T>& v)
  160. {
  161.  T v0 = math_traits<T>::zero();
  162.  T v1 = math_traits<T>::one();
  163.  m[ 0] = v1; m[ 1] = v0; m[ 2] = v0; m[ 3] = v.data[0];
  164.  m[ 4] = v0; m[ 5] = v1; m[ 6] = v0; m[ 7] = v.data[1];
  165.  m[ 8] = v0; m[ 9] = v0; m[10] = v1; m[11] = v.data[2];
  166.  m[12] = v0; m[13] = v0; m[14] = v0; m[15] = v1;
  167. }
  168.  
  169. template<class T>
  170. inline void matrix4x4<T>::load_rotation_x(T radians)
  171. {
  172.  T v0 = math_traits<T>::zero();
  173.  T v1 = math_traits<T>::one();
  174.  T pc = std::cos(radians);
  175.  T ps = std::sin(radians);
  176.  T ns = -ps;
  177.  m[ 0] = v1; m[ 1] = v0; m[ 2] = v0; m[ 3] = v0;
  178.  m[ 4] = v0; m[ 5] = pc; m[ 6] = ns; m[ 7] = v0;
  179.  m[ 8] = v0; m[ 9] = ps; m[10] = pc; m[11] = v0;
  180.  m[12] = v0; m[13] = v0; m[14] = v0; m[15] = v1;
  181. }
  182.  
  183. template<class T>
  184. inline void matrix4x4<T>::load_rotation_y(T radians)
  185. {
  186.  T v0 = math_traits<T>::zero();
  187.  T v1 = math_traits<T>::one();
  188.  T pc = std::cos(radians);
  189.  T ps = std::sin(radians);
  190.  T ns = -ps;
  191.  m[ 0] = pc; m[ 1] = v0; m[ 2] = ps; m[ 3] = v0;
  192.  m[ 4] = v0; m[ 5] = v1; m[ 6] = v0; m[ 7] = v0;
  193.  m[ 8] = ns; m[ 9] = v0; m[10] = pc; m[11] = v0;
  194.  m[12] = v0; m[13] = v0; m[14] = v0; m[15] = v1;
  195. }
  196.  
  197. template<class T>
  198. inline void matrix4x4<T>::load_rotation_z(T radians)
  199. {
  200.  T v0 = math_traits<T>::zero();
  201.  T v1 = math_traits<T>::one();
  202.  T pc = std::cos(radians);
  203.  T ps = std::sin(radians);
  204.  T ns = -ps;
  205.  m[ 0] = pc; m[ 1] = ns; m[ 2] = v0; m[ 3] = v0;
  206.  m[ 4] = ps; m[ 5] = pc; m[ 6] = v0; m[ 7] = v0;
  207.  m[ 8] = v0; m[ 9] = v0; m[10] = v1; m[11] = v0;
  208.  m[12] = v0; m[13] = v0; m[14] = v0; m[15] = v1;
  209. }
  210.  
  211. template<class T>
  212. inline void matrix4x4<T>::load_rotation(T radians, T x, T y, T z)
  213. {
  214.  // pre-calculated values
  215.  T v0 = math_traits<T>::zero();
  216.  T v1 = math_traits<T>::one();
  217.  T pc = std::cos(radians);
  218.  T ps = std::sin(radians);
  219.  T psx = ps*x;
  220.  T psy = ps*y;
  221.  T psz = ps*z;
  222.  T one_minus_pc = v1 - pc;
  223.  T one_minus_pc_xy = one_minus_pc*x*y;
  224.  T one_minus_pc_xz = one_minus_pc*x*z;
  225.  T one_minus_pc_yz = one_minus_pc*y*z;
  226.  
  227.  // r1
  228.  m[M11] = pc + one_minus_pc*x*x;
  229.  m[M12] = one_minus_pc_xy - psz;
  230.  m[M13] = one_minus_pc_xz + psy;
  231.  m[M14] = v0;
  232.  
  233.  // r2
  234.  m[M21] = one_minus_pc_xy + psz;
  235.  m[M22] = pc + one_minus_pc*y*y;
  236.  m[M23] = one_minus_pc_yz - psx;
  237.  m[M24] = v0;
  238.  
  239.  // r3
  240.  m[M31] = one_minus_pc_xz - psy;
  241.  m[M32] = one_minus_pc_yz + psx;
  242.  m[M33] = pc + one_minus_pc*z*z;
  243.  m[M34] = v0;
  244.  
  245.  // r4
  246.  m[M41] = v0;
  247.  m[M42] = v0;
  248.  m[M43] = v0;
  249.  m[M44] = v1;
  250. }
  251.  
  252. template<class T>
  253. inline void matrix4x4<T>::load_euler(T H, T P, T B)
  254. {
  255.  // pre-calculated values
  256.  T v0 = math_traits<T>::zero();
  257.  T v1 = math_traits<T>::one();
  258.  T cH = std::cos(H); T sH = std::sin(H);
  259.  T cP = std::cos(P); T sP = std::sin(P);
  260.  T cB = std::cos(B); T sB = std::sin(B);
  261.  T sPsH = sP*sH;
  262.  T sPcH = sP*cH;
  263.  
  264.  // r1
  265.  m[M11] = cB*cH - sB*sPsH;
  266.  m[M12] = -sB*cP;
  267.  m[M13] = cB*sH + sB*sPcH;
  268.  m[M14] = v0;
  269.  
  270.  // r2
  271.  m[M21] = sB*cH + cB*sPsH;
  272.  m[M22] = cB*cP;
  273.  m[M23] = sB*sH - cB*sPcH;
  274.  m[M24] = v0;
  275.  
  276.  // r3
  277.  m[M31] = -sH*cP;
  278.  m[M32] = sP;
  279.  m[M33] = cP*cH;
  280.  m[M34] = v0;
  281.  
  282.  // r4
  283.  m[M41] = v0;
  284.  m[M42] = v0;
  285.  m[M43] = v0;
  286.  m[M44] = v1;
  287. }
  288.  
  289. template<class T>
  290. inline void matrix4x4<T>::load_euler_lw(T H, T P, T B)
  291. {
  292.  // pre-calculated values
  293.  T v0 = math_traits<T>::zero();
  294.  T v1 = math_traits<T>::one();
  295.  T cH = std::cos(H); T sH = std::sin(H);
  296.  T cP = std::cos(P); T sP = std::sin(P);
  297.  T cB = std::cos(B); T sB = std::sin(B);
  298.  
  299.  // r1
  300.  m[M11] =  cH*cB;
  301.  m[M12] = -cH*sB;
  302.  m[M13] =  sH;
  303.  m[M14] =  v0;
  304.  
  305.  // r2
  306.  m[M21] =  cP*sB + sH*sP*cB;
  307.  m[M22] =  cP*cB - sH*sP*sB;
  308.  m[M23] = -cH*sP;
  309.  m[M24] =  v0;
  310.  
  311.  // r3
  312.  m[M31] = sP*sB - sH*cP*cB;
  313.  m[M32] = sP*cB + sH*cP*sB;
  314.  m[M33] = cH*cP;
  315.  m[M34] = v0;
  316.  
  317.  // r4
  318.  m[M41] = v0;
  319.  m[M42] = v0;
  320.  m[M43] = v0;
  321.  m[M44] = v1;
  322. }
  323.  
  324. template<class T>
  325. inline void matrix4x4<T>::translate(T x, T y, T z)
  326. {
  327.  m[M14] += m[M11]*x + m[M12]*y + m[M13]*z;
  328.  m[M24] += m[M21]*x + m[M22]*y + m[M23]*z;
  329.  m[M34] += m[M31]*x + m[M32]*y + m[M33]*z;
  330.  m[M44] += m[M41]*x + m[M42]*y + m[M43]*z;
  331. }
  332.  
  333. template<class T>
  334. inline void matrix4x4<T>::translate(const vector3D<T>& v)
  335. {
  336.  m[M14] += m[M11]*v.data[0] + m[M12]*v.data[1] + m[M13]*v.data[2];
  337.  m[M24] += m[M21]*v.data[0] + m[M22]*v.data[1] + m[M23]*v.data[2];
  338.  m[M34] += m[M31]*v.data[0] + m[M32]*v.data[1] + m[M33]*v.data[2];
  339.  m[M44] += m[M41]*v.data[0] + m[M42]*v.data[1] + m[M43]*v.data[2];
  340. }
  341.  
  342. template<class T>
  343. inline void matrix4x4<T>::rotate_x(T radians)
  344. {
  345.  // TODO
  346. }
  347.  
  348. template<class T>
  349. inline void matrix4x4<T>::rotate_y(T radians)
  350. {
  351.  // TODO
  352. }
  353.  
  354. template<class T>
  355. inline void matrix4x4<T>::rotate_z(T radians)
  356. {
  357.  // TODO
  358. }
  359.  
  360. template<class T>
  361. inline void matrix4x4<T>::rotate(T radians, T x, T y, T z)
  362. {
  363.  // TODO
  364. }
  365.  
  366. template<class T>
  367. inline void matrix4x4<T>::to_euler(T& H, T& P, T& B)
  368. {
  369.  // sin(P) = +1, cos(P) = 0
  370.  if(m[M32] == math_traits<T>::one())
  371.    {
  372.     H = math_traits<T>::zero();
  373.     P = math_traits<T>::pi_over_2();
  374.     B = std::atan2(-m[M21], -m[M22]);
  375.    }
  376.  // sin(P) = -1, cos(P) = 0
  377.  else if(m[M31] == math_traits<T>::neg_one())
  378.    {
  379.     H = math_traits<T>::zero();
  380.     P = math_traits<T>::neg_pi_over_2();
  381.     B = std::atan2(m[M21], m[M22]);
  382.    }
  383.  // otherwise
  384.  else
  385.    {
  386.     P = asin(m[M32]);
  387.     T temp = cos(P);
  388.     H = atan2(-m[M31]/temp, m[M33]/temp);
  389.     B = atan2(-m[M12]/temp, m[M22]/temp);
  390.    }
  391. }
  392.  
  393. template<class T>
  394. inline void matrix4x4<T>::multiply_by(const vector3D<T>& V, vector3D<T>& R)
  395. {
  396.  R[0] = m[M11]*V[0] + m[M12]*V[1] + m[M13]*V[2];
  397.  R[1] = m[M21]*V[0] + m[M22]*V[1] + m[M23]*V[2];
  398.  R[2] = m[M31]*V[0] + m[M32]*V[1] + m[M33]*V[2];
  399. }
  400.  
  401. template<class T>
  402. inline matrix4x4<T>& matrix4x4<T>::operator +=(const matrix4x4<T>& M)
  403. {
  404.  // r1
  405.  m[M11] += M.m[M11];
  406.  m[M12] += M.m[M12];
  407.  m[M13] += M.m[M13];
  408.  m[M14] += M.m[M14];
  409.  
  410.  // r2
  411.  m[M21] += M.m[M21];
  412.  m[M22] += M.m[M22];
  413.  m[M23] += M.m[M23];
  414.  m[M24] += M.m[M24];
  415.  
  416.  // r3
  417.  m[M31] += M.m[M31];
  418.  m[M32] += M.m[M32];
  419.  m[M33] += M.m[M33];
  420.  m[M34] += M.m[M34];
  421.  
  422.  // r4
  423.  m[M41] += M.m[M41];
  424.  m[M42] += M.m[M42];
  425.  m[M43] += M.m[M43];
  426.  m[M44] += M.m[M44];
  427.  
  428.  return *this;
  429. }
  430.  
  431. template<class T>
  432. inline matrix4x4<T>& matrix4x4<T>::operator -=(const matrix4x4<T>& M)
  433. {
  434.  // r1
  435.  m[M11] -= M.m[M11];
  436.  m[M12] -= M.m[M12];
  437.  m[M13] -= M.m[M13];
  438.  m[M14] -= M.m[M14];
  439.  
  440.  // r2
  441.  m[M21] -= M.m[M21];
  442.  m[M22] -= M.m[M22];
  443.  m[M23] -= M.m[M23];
  444.  m[M24] -= M.m[M24];
  445.  
  446.  // r3
  447.  m[M31] -= M.m[M31];
  448.  m[M32] -= M.m[M32];
  449.  m[M33] -= M.m[M33];
  450.  m[M34] -= M.m[M34];
  451.  
  452.  // r4
  453.  m[M41] -= M.m[M41];
  454.  m[M42] -= M.m[M42];
  455.  m[M43] -= M.m[M43];
  456.  m[M44] -= M.m[M44];
  457.  
  458.  return *this;
  459. }
  460.  
  461. template<class T>
  462. inline matrix4x4<T>& matrix4x4<T>::operator *=(const matrix4x4<T>& M)
  463. {
  464.  // copy this matrix
  465.  T A[16] = {
  466.   m[M11], m[M12], m[M13], m[M14],
  467.   m[M21], m[M22], m[M23], m[M24],
  468.   m[M31], m[M32], m[M33], m[M34],
  469.   m[M41], m[M42], m[M43], m[M44]
  470.  };
  471.  
  472.  // r1
  473.  m[M11] = A[M11]*M.m[M11] + A[M12]*M.m[M21] + A[M13]*M.m[M31] + A[M14]*M.m[M41];
  474.  m[M12] = A[M11]*M.m[M12] + A[M12]*M.m[M22] + A[M13]*M.m[M32] + A[M14]*M.m[M42];
  475.  m[M13] = A[M11]*M.m[M13] + A[M12]*M.m[M23] + A[M13]*M.m[M33] + A[M14]*M.m[M43];
  476.  m[M14] = A[M11]*M.m[M14] + A[M12]*M.m[M24] + A[M13]*M.m[M34] + A[M14]*M.m[M44];
  477.  
  478.  // r2
  479.  m[M21] = A[M21]*M.m[M11] + A[M22]*M.m[M21] + A[M23]*M.m[M31] + A[M24]*M.m[M41];
  480.  m[M22] = A[M21]*M.m[M12] + A[M22]*M.m[M22] + A[M23]*M.m[M32] + A[M24]*M.m[M42];
  481.  m[M23] = A[M21]*M.m[M13] + A[M22]*M.m[M23] + A[M23]*M.m[M33] + A[M24]*M.m[M43];
  482.  m[M24] = A[M21]*M.m[M14] + A[M22]*M.m[M24] + A[M23]*M.m[M34] + A[M24]*M.m[M44];
  483.  
  484.  // r3
  485.  m[M31] = A[M31]*M.m[M11] + A[M32]*M.m[M21] + A[M33]*M.m[M31] + A[M34]*M.m[M41];
  486.  m[M32] = A[M31]*M.m[M12] + A[M32]*M.m[M22] + A[M33]*M.m[M32] + A[M34]*M.m[M42];
  487.  m[M33] = A[M31]*M.m[M13] + A[M32]*M.m[M23] + A[M33]*M.m[M33] + A[M34]*M.m[M43];
  488.  m[M34] = A[M31]*M.m[M14] + A[M32]*M.m[M24] + A[M33]*M.m[M34] + A[M34]*M.m[M44];
  489.  
  490.  // r4
  491.  m[M41] = A[M41]*M.m[M11] + A[M42]*M.m[M21] + A[M43]*M.m[M31] + A[M44]*M.m[M41];
  492.  m[M42] = A[M41]*M.m[M12] + A[M42]*M.m[M22] + A[M43]*M.m[M32] + A[M44]*M.m[M42];
  493.  m[M43] = A[M41]*M.m[M13] + A[M42]*M.m[M23] + A[M43]*M.m[M33] + A[M44]*M.m[M43];
  494.  m[M44] = A[M41]*M.m[M14] + A[M42]*M.m[M24] + A[M43]*M.m[M34] + A[M44]*M.m[M44];
  495.  
  496.  return *this;
  497. }
  498.  
  499. template<class T>
  500. inline matrix4x4<T>& matrix4x4<T>::operator *=(T scalar)
  501. {
  502.  // r1
  503.  m[M11] *= scalar;
  504.  m[M12] *= scalar;
  505.  m[M13] *= scalar;
  506.  m[M14] *= scalar;
  507.  
  508.  // r2
  509.  m[M21] *= scalar;
  510.  m[M22] *= scalar;
  511.  m[M23] *= scalar;
  512.  m[M24] *= scalar;
  513.  
  514.  // r3
  515.  m[M31] *= scalar;
  516.  m[M32] *= scalar;
  517.  m[M33] *= scalar;
  518.  m[M34] *= scalar;
  519.  
  520.  // r4
  521.  m[M41] *= scalar;
  522.  m[M42] *= scalar;
  523.  m[M43] *= scalar;
  524.  m[M44] *= scalar;
  525.  
  526.  return *this;
  527. }
  528.  
  529. template<class T>
  530. inline matrix4x4<T>& matrix4x4<T>::operator /=(T scalar)
  531. {
  532.  scalar = math_traits<T>::one()/scalar;
  533.  return ((*this) *= scalar);
  534. }
  535.  
  536. };
  537.  
  538. template<class T>
  539. inline ostream& operator <<(ostream& os, const sl::matrix4x4<T>& M)
  540. {
  541.  os << "[" <<
  542.     "[" << M[ 0] << "," << M[ 1] << "," << M[ 2] << "," << M[ 3] << "]" << "," <<
  543.     "[" << M[ 4] << "," << M[ 5] << "," << M[ 6] << "," << M[ 7] << "]" << "," <<
  544.     "[" << M[ 8] << "," << M[ 9] << "," << M[10] << "," << M[11] << "]" << "," <<
  545.     "[" << M[12] << "," << M[13] << "," << M[14] << "," << M[15] << "]" << "]";
  546.  return os;
  547. }
  548.  
  549. #endif
  550.  
  551.