home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 February / Chip_2001-02_cd1.bin / bonus / demos / CS / exp / SOURCES / GLENGINE / miscmath.h < prev    next >
C/C++ Source or Header  |  2000-08-17  |  5KB  |  146 lines

  1. /*
  2.  * Miscellaneous useful math functions' templates
  3.  */
  4.  
  5. #ifndef __OGL2_MISCELLANEOUS_MATH__
  6. #define __OGL2_MISCELLANEOUS_MATH__
  7.  
  8. #include "vector3.h"
  9. #include "glmatrix.h"
  10. #include "quaternion.h"
  11.  
  12. #ifndef PI
  13. #define PI 3.14159265358979324
  14. #endif
  15.  
  16. extern "C++" {
  17.  
  18.  
  19. /*
  20.  * Converts an angle&axis representation of rotations to corresponding
  21.  * quaternion representation.
  22.  */
  23.  
  24. template <class __type> inline quaternion<__type>
  25. AngleAxis2Quaternion (__type angle, __type x, __type y, __type z) {
  26.   __type s = (__type)sin(angle/2.0);
  27.   return quaternion<__type> ((__type)cos(angle/2.0), x*s, y*s, z*s);
  28. }
  29.  
  30. /*
  31.  * Converts euler angles to its corresponding matrix representation, where
  32.  * the result represents a rotation about the x-axis by the angle 'alpha'
  33.  * followed by rotation about the y-axis by the angle 'beta' concluded by
  34.  * rotation about the z-axis by the angle 'gamma'.
  35.  */
  36.  
  37. template <class __type> inline GLmatrix_template<__type>
  38. Euler2Matrix (__type alpha, __type beta, __type gamma) {
  39.   GLmatrix_template<__type> M;
  40.   __type* m = M();
  41.   __type sin_alpha = (__type)(sin(alpha));
  42.   __type cos_alpha = (__type)(cos(alpha));
  43.   __type sin_beta = (__type)(sin(beta));
  44.   __type cos_beta = (__type)(cos(beta));
  45.   __type sin_gamma = (__type)(sin(gamma));
  46.   __type cos_gamma = (__type)(cos(gamma));
  47.  
  48.   *m = (__type)(cos(beta)*cos(gamma)); m++;
  49.   *m = (__type)(cos(beta)*sin(gamma)); m++;
  50.   *m = (__type)(-sin(beta)); m++;
  51.   *m = (__type)0; m++;
  52.  
  53.   *m = (__type)(cos_gamma*sin_alpha*sin_beta - cos_alpha*sin_gamma); m++;
  54.   *m = (__type)(cos_alpha*cos_gamma + sin_alpha*sin_beta*sin_gamma); m++;
  55.   *m = (__type)(cos_beta*sin_alpha); m++;
  56.   *m = (__type)0; m++;
  57.  
  58.   *m = (__type)(cos_alpha*cos_gamma*sin_beta + sin_alpha*sin_gamma); m++;
  59.   *m = (__type)(cos_alpha*sin_beta*sin_gamma - cos_gamma*sin_alpha); m++;
  60.   *m = (__type)(cos_alpha*cos_beta); m++;
  61.   *m = (__type)0; m++;
  62.  
  63.   *m = (__type)0; m++;
  64.   *m = (__type)0; m++;
  65.   *m = (__type)0; m++;
  66.   *m = (__type)1;
  67.  
  68.   return M;
  69. }
  70.  
  71. /*
  72.  * Converts a rotation matrix to the corresponding unit quaternion.
  73.  * The matrix argument must not represent nothing more than a rotation,
  74.  * except for translation data which will be left unnoticed.
  75.  */
  76.  
  77. template <class __type> inline quaternion<__type>
  78. Matrix2Quaternion (const GLmatrix_template<__type>& mat) {
  79.   __type* m = mat();
  80.   __type s, x, y, z;
  81.   s = (__type)(-0.5*sqrt(m[0] + m[5] + m[10] + m[15]));
  82.   __type c = (__type)(0.25/s);
  83.   x = (m[6] - m[9])*c;
  84.   y = (m[8] - m[2])*c;
  85.   z = (m[1] - m[4])*c;
  86.   return quaternion<__type> (s, x, y, z);
  87. }
  88.  
  89. /*
  90.  * Converts an unit quaternion to the corresponding rotation matrix.
  91.  */
  92.  
  93. template <class __type> inline GLmatrix_template<__type>
  94. Quaternion2Matrix(const quaternion<__type>& q) {
  95.   __type w = re(q);
  96.   __type x = im1(q);
  97.   __type y = im2(q);
  98.   __type z = im3(q);
  99.  
  100.   __type wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
  101.   x2 = x + x; y2 = y + y; 
  102.   z2 = z + z;
  103.   xx = x * x2;   xy = x * y2;   xz = x * z2;
  104.   yy = y * y2;   yz = y * z2;   zz = z * z2;
  105.   wx = w * x2;   wy = w * y2;   wz = w * z2;
  106.  
  107.   GLmatrix_template<__type> m;
  108.   m[0] = 1.0 - (yy + zz); m[4] = xy - wz;         m[8] = xz + wy;          m[12] = 0.0;
  109.   m[1] = xy + wz;         m[5] = 1.0 - (xx + zz); m[9] = yz - wx;          m[13] = 0.0;
  110.   m[2] = xz - wy;         m[6] = yz + wx;         m[10] = 1.0 - (xx + yy); m[14] = 0.0;
  111.   m[3] = 0.0;             m[7] = 0.0;             m[11] = 0.0;             m[15] = 1.0;
  112.  
  113.   return m; 
  114. }
  115.  
  116.  
  117. /*
  118.  * Linear matrix interpolation. The input matrices must not represent
  119.  * anything more than a rotation and a translation. The result is a matrix
  120.  * representing the rotation and the translation on the way from 'm1' to 'm2'
  121.  * according to the time parameter 't' which should lie between [0,1]
  122.  * boundaries. Internally, the matrices are converted to the corresponding
  123.  * quaternions, then they are interpolated through the slerp function and
  124.  * finally the result is converted back to a matrix, where the translation
  125.  * is computed using linear interpolation on the translation vectors from
  126.  * the original two matrices.
  127.  */
  128. template <class __type> inline GLmatrix_template<__type>
  129. Mslerp (__type t, const GLmatrix_template<__type>& m1,
  130.                   const GLmatrix_template<__type>& m2)
  131. {
  132.   quaternion<__type> q = slerp(t, Matrix2Quaternion(m1), Matrix2Quaternion(m2));
  133.   GLmatrix_template<__type> m = Quaternion2Matrix(q);
  134.  
  135.   m[12] = m1[12] + t*(m2[12]-m1[12]);
  136.   m[13] = m1[13] + t*(m2[13]-m1[13]);
  137.   m[14] = m1[14] + t*(m2[14]-m1[14]);
  138.  
  139.   return m;
  140. }
  141.  
  142.  
  143. } // extern "C++"
  144.  
  145. #endif
  146.