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

  1. /* 
  2.  * "GLmatrix" class template and inlines
  3.  *
  4.  * GLmatrix is objective implementation of OpenGL style matrices.
  5.  */
  6.  
  7. #ifndef __OGL2_GLMATRIX__
  8. #define __OGL2_GLMATRIX__
  9.  
  10. #include <iostream>
  11. #include "types.h"
  12.  
  13. #ifndef PI
  14. #define PI 3.14159265358979324
  15. #endif
  16.  
  17. extern "C++" {
  18.  
  19.    
  20. /* Matrix multiplication
  21.  */
  22. template <class __type> inline void
  23. __glmatrix_multiply (__type* a, __type* b, __type *c) {
  24.   __type b1, b2, b3, b4;
  25.   for(int i=0; i<4; i++) {
  26.     b1 = b[i<<2]; b2 = b[1+(i<<2)]; b3 = b[2+(i<<2)]; b4 = b[3+(i<<2)];
  27.     c[(i<<2)]   = a[0]*b1 + a[4]*b2 +  a[8]*b3 + a[12]*b4;
  28.     c[(i<<2)+1] = a[1]*b1 + a[5]*b2 +  a[9]*b3 + a[13]*b4;
  29.     c[(i<<2)+2] = a[2]*b1 + a[6]*b2 + a[10]*b3 + a[14]*b4;
  30.     c[(i<<2)+3] = a[3]*b1 + a[7]*b2 + a[11]*b3 + a[15]*b4;
  31.   }
  32. }
  33.  
  34.  
  35. /* Rotation matrix generation template, adapted from Mesa3D, the original
  36.  * author of the function is Erich Boleyn (erich@uruk.org).
  37.  */
  38. template <class __type> inline void
  39. __glmatrix_rotation_matrix (__type angle, __type x, __type y, __type z, __type* m) {
  40.  
  41.   __type mag, s, c;
  42.   __type xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
  43.  
  44.   s = (__type)sin( angle * PI/180.0 );
  45.   c = (__type)cos( angle * PI/180.0 );
  46.  
  47.   mag = (__type)sqrt(x*x + y*y + z*z);
  48.  
  49.   if (mag == 0.0) {
  50.      __type *p = m;
  51.      for(int i=16; i; i--)
  52.        *p++ = 0;
  53.      m[0] = 1; m[5] = 1; m[10] = 1; m[15] = 1;
  54.      return;
  55.   }
  56.  
  57.   x /= mag;
  58.   y /= mag;
  59.   z /= mag;
  60.  
  61.   xx = x * x;
  62.   yy = y * y;
  63.   zz = z * z;
  64.   xy = x * y;
  65.   yz = y * z;
  66.   zx = z * x;
  67.   xs = x * s;
  68.   ys = y * s;
  69.   zs = z * s;
  70.   one_c = 1.0 - c;
  71.  
  72.   m[0] = (one_c * xx) + c;
  73.   m[4] = (one_c * xy) - zs;
  74.   m[8] = (one_c * zx) + ys;
  75.   m[12] = 0.0;
  76.  
  77.   m[1] = (one_c * xy) + zs;
  78.   m[5] = (one_c * yy) + c;
  79.   m[9] = (one_c * yz) - xs;
  80.   m[13] = 0.0;
  81.  
  82.   m[2] = (one_c * zx) - ys;
  83.   m[6] = (one_c * yz) + xs;
  84.   m[10] = (one_c * zz) + c;
  85.   m[14] = 0.0;
  86.  
  87.   m[3] = 0.0;
  88.   m[7] = 0.0;
  89.   m[11]= 0.0;
  90.   m[15]= 1.0;
  91. }
  92.  
  93.  
  94. template <class __type>
  95. struct GLmatrix_template
  96. {
  97.   mutable __type M[16];
  98.  
  99.   GLmatrix_template () {
  100.     __type *p = M;
  101.     for(int i=0; i<16; i++)
  102.       *p++ = 0;
  103.   }
  104.   GLmatrix_template (__type *p) {
  105.     __type *d = M;
  106.     for(int i=16; i; i--)
  107.       *d++ = *p++;
  108.   }
  109.  
  110.   __type* operator() () const {
  111.     return M;
  112.   }
  113.   __type& operator[] (int i) const {
  114.     return M[i];
  115.   }
  116.  
  117.   GLmatrix_template& Load (__type *p) {
  118.     __type *d = M;
  119.     for(int i=16; i; i--)
  120.       *d++ = *p++;
  121.     return *this;
  122.   }
  123.   GLmatrix_template& Zero () {
  124.     __type *p = M;
  125.     for(int i=16; i; i--)
  126.       *p++ = 0;
  127.     return *this;
  128.   }
  129.   GLmatrix_template& Identity () {
  130.     __type *p = M;
  131.     for(int i=16; i; i--)
  132.       *p++ = 0;
  133.     M[0] = 1; M[5] = 1; M[10] = 1; M[15] = 1;
  134.     return *this;
  135.   }
  136.   GLmatrix_template& LoadIdentity () {
  137.     return Identity();
  138.   }
  139.   GLmatrix_template& Transpose () {
  140.     __type *u, *v;
  141.     __type a;
  142.     for(int i=0; i<4; i++) {
  143.       u = v = M+i+(i<<2);
  144.       for(int j=3-i; j; j--) {
  145.         u++;
  146.         v+=4;
  147.         a = *u;
  148.         *u = *v;
  149.         *v = a;
  150.       }
  151.     }  
  152.     return *this;
  153.   }
  154.   GLmatrix_template& OrthoInverse () {
  155.     __type a;
  156.     __type x=M[12];
  157.     __type y=M[13];
  158.     __type z=M[14];
  159.     a=M[1]; M[1]=M[4]; M[4]=a;
  160.     a=M[2]; M[2]=M[8]; M[8]=a;
  161.     a=M[6]; M[6]=M[9]; M[9]=a;
  162.     M[12] = -(x*M[0] + y*M[4] + z*M[8]);
  163.     M[13] = -(x*M[1] + y*M[5] + z*M[9]);
  164.     M[14] = -(x*M[2] + y*M[6] + z*M[10]);
  165.     return *this;
  166.   }
  167.   GLmatrix_template& Translate (__type x, __type y, __type z) {
  168.     M[12] = M[0] * x + M[4] * y + M[8]  * z + M[12];
  169.     M[13] = M[1] * x + M[5] * y + M[9]  * z + M[13];
  170.     M[14] = M[2] * x + M[6] * y + M[10] * z + M[14];
  171.     M[15] = M[3] * x + M[7] * y + M[11] * z + M[15];
  172.     return *this;
  173.   }
  174.   GLmatrix_template& Scale (__type x, __type y, __type z) {
  175.     M[0]*=x; M[4]*=y;  M[8]*=z;
  176.     M[1]*=x; M[5]*=y;  M[9]*=z;
  177.     M[2]*=x; M[6]*=y; M[10]*=z;
  178.     M[3]*=x; M[7]*=y; M[11]*=z;
  179.     return *this;
  180.   }
  181.   GLmatrix_template& Rotate (__type angle, __type x, __type y, __type z) {
  182.     __type b[16];
  183.     __type c[16];
  184.     __glmatrix_rotation_matrix(angle, x, y, z, b);
  185.     __glmatrix_multiply(this->M, b, c);
  186.     return Load(c);
  187.   }
  188.   
  189.   GLmatrix_template& operator *=(const GLmatrix_template& B) {
  190.     __type c[16];
  191.     __glmatrix_multiply(this->M, B(), c);
  192.     return Load(c);
  193.   }
  194.   GLmatrix_template& operator +=(const GLmatrix_template& B) {
  195.     __type *d = M;
  196.     const __type *s = B.M;
  197.     for(int i=16; i; i--, d++, s++)
  198.       *d += *s;
  199.     return *this;
  200.   }
  201.   GLmatrix_template& operator -=(const GLmatrix_template& B) {
  202.     __type *d = M;
  203.     const __type *s = B.M;
  204.     for(int i=16; i; i--, d++, s++)
  205.       *d -= *s;
  206.     return *this;
  207.   }
  208.   GLmatrix_template& operator *=(__type scalar) {
  209.     __type *d = M;
  210.     for(int i=16; i; i--, d++)
  211.       *d *= scalar;
  212.     return *this;
  213.   }
  214.   GLmatrix_template& operator /=(__type scalar) {
  215.     __type *d = M;
  216.     for(int i=16; i; i--, d++)
  217.       *d *= scalar;
  218.     return *this;
  219.   }
  220.   void MultVertex4f (__type& _x, __type& _y, __type& _z, __type& _w)
  221.   {
  222.     __type x = _x*M[0] + _y*M[4] + _z*M[8] +  _w*M[12];
  223.     __type y = _x*M[1] + _y*M[5] + _z*M[9] +  _w*M[13];
  224.     __type z = _x*M[2] + _y*M[6] + _z*M[10] + _w*M[14];
  225.     __type w = _x*M[3] + _y*M[7] + _z*M[11] + _w*M[15];
  226.     _x=x; _y=y; _z=z; _w=w;
  227.   }
  228.  
  229. };
  230.  
  231. template class GLmatrix_template<GLfloat>;
  232. template class GLmatrix_template<GLdouble>;
  233. typedef GLmatrix_template<GLfloat> GLmatrix;
  234. typedef GLmatrix_template<GLdouble> GLmatrix_double;
  235.  
  236. // inlines
  237.  
  238. template <class __type> inline ostream&
  239. operator<<(ostream& s, const GLmatrix_template<__type>& A)
  240. {
  241.   __type *p = A();
  242.   for(int i=4; i; i--) {
  243.     for(int j=4; j; j--, p+=4)
  244.       s << (float)(*p) << " ";
  245.     p-=15;
  246.     s << endl;
  247.   }
  248.   return s;
  249. }
  250.  
  251. template <class __type> inline GLmatrix_template<__type>
  252. operator + (const GLmatrix_template<__type>& A)
  253. {
  254.   return A;
  255. }
  256.  
  257. template <class __type> inline GLmatrix_template<__type>
  258. operator - (const GLmatrix_template<__type>& A)
  259. {
  260.   GLmatrix_template<__type> nA;
  261.   __type *d = nA();
  262.   __type *s = A();
  263.   for(int i=16; i; i--)
  264.     *d++ = -(*s++);
  265.   return nA;
  266. }
  267.  
  268. template <class __type> inline GLmatrix_template<__type>
  269. operator + (const GLmatrix_template<__type>& A, const GLmatrix_template<__type>& B)
  270. {
  271.   GLmatrix_template<__type> C;
  272.   __type *d = C();
  273.   __type *sA = A();
  274.   __type *sB = B();
  275.   for(int i=16; i; i--, d++, sA++, sB++)
  276.     *d = *sA + *sB;
  277.   return C;
  278. }
  279.  
  280. template <class __type> inline GLmatrix_template<__type>
  281. operator - (const GLmatrix_template<__type>& A, const GLmatrix_template<__type>& B)
  282. {
  283.   GLmatrix_template<__type> C;
  284.   __type *d = C();
  285.   __type *sA = A();
  286.   __type *sB = B();
  287.   for(int i=16; i; i--, d++, sA++, sB++)
  288.     *d = *sA - *sB;
  289.   return C;
  290. }
  291.  
  292. template <class __type> inline GLmatrix_template<__type>
  293. operator * (const GLmatrix_template<__type>& A, const GLmatrix_template<__type>& B)
  294. {
  295.   GLmatrix_template<__type> C;
  296.   __glmatrix_multiply(A(), B(), C());
  297.   return C;
  298. }
  299.  
  300. template <class __type> inline GLmatrix_template<__type>
  301. operator * (const GLmatrix_template<__type>& A, const __type& scalar)
  302. {
  303.   GLmatrix_template<__type> C;
  304.   __type *d = C();
  305.   __type *s = A();
  306.   for(int i=16; i; i--, d++, s++)
  307.     *d = (*s)*scalar;
  308.   return C;
  309. }
  310.  
  311. template <class __type> inline GLmatrix_template<__type>
  312. operator * (const __type& scalar, const GLmatrix_template<__type>& A)
  313. {
  314.   GLmatrix_template<__type> C;
  315.   __type *d = C();
  316.   __type *s = A();
  317.   for(int i=16; i; i--, d++, s++)
  318.     *d = scalar*(*s);
  319.   return C;
  320. }
  321.  
  322. template <class __type> inline GLmatrix_template<__type>
  323. operator / (const GLmatrix_template<__type>& A, const __type& scalar)
  324. {
  325.   GLmatrix_template<__type> C;
  326.   __type *d = C();
  327.   __type *s = A();
  328.   for(int i=16; i; i--, d++, s++)
  329.     *d = (*s)/scalar;
  330.   return C;
  331. }
  332.  
  333. template <class __type> inline __type
  334. norm (const GLmatrix_template<__type>& A)
  335. {
  336.   __type acc = 0;
  337.   __type *s = A();
  338.   for(int i=16; i; i--, s++)
  339.     acc += (*s)*(*s);
  340.   return sqrt(acc);
  341. }
  342.  
  343. } // extern "C++"
  344.  
  345. #endif
  346.