home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / fermiVogle.tar.Z / fermiVogle.tar / devel / src / matrix.c < prev    next >
C/C++ Source or Header  |  1996-02-07  |  6KB  |  299 lines

  1.  
  2. #include <stdio.h>
  3. #include "vogle.h"
  4.  
  5. static    Mstack    *msfree = (Mstack *)NULL;
  6.  
  7. /*
  8.  * copyvector
  9.  *
  10.  * Copy the 4 vector b to a.
  11.  *
  12.  */
  13. void
  14. copyvector(register Vector a, register Vector b)
  15. {
  16.     a[0] = b[0];
  17.     a[1] = b[1];
  18.     a[2] = b[2];
  19.     a[3] = b[3];
  20. }
  21.  
  22. /*
  23.  * copymatrix
  24.  *
  25.  * Copy the  4 x 4 matrix b to the 4 x 4 matrix a
  26.  *
  27.  */
  28. void
  29. copymatrix(register Matrix a, register Matrix b)
  30. {
  31.     register int    i;
  32.     register float    *pa, *pb;
  33.  
  34.     pa = (float *)a;
  35.     pb = (float *)b;
  36.     for(i = 0; i < 16; i++)
  37.         *(pa++) = *(pb++);
  38. }
  39.  
  40. /*
  41.  * copytranspose
  42.  *
  43.  *    copy the transpose of the 4 x 4 matrix b to the 4 x 4 matrix a.
  44.  */
  45. void
  46. copytranspose(register Matrix a, register Matrix b)
  47. {
  48.     register int    i, j;
  49.  
  50.     for(i = 0; i < 4; i++)
  51.         for(j = 0; j < 4; j++)
  52.             a[i][j] = b[j][i];
  53. }
  54.  
  55. /*
  56.  * Retreive the top matrix on the stack and place it in m
  57.  */
  58. void
  59. getmatrix(Matrix m)
  60. {
  61.     copymatrix(m, vdevice.transmat->m);
  62. }
  63.  
  64. /*
  65.  * pushmatrix
  66.  *
  67.  * Push the top matrix of the stack down, placing a copy
  68.  * of it on the top of the stack.
  69.  *
  70.  */
  71. void
  72. pushmatrix(void)
  73. {
  74.     Mstack    *tmpmat;
  75.     Token    *p;
  76.  
  77.     if (vdevice.inobject) {
  78.         p = newtokens(1);
  79.  
  80.         p->i = PUSHMATRIX;
  81.  
  82.         return;
  83.     }
  84.  
  85.     if (msfree != (Mstack *)NULL) {
  86.         tmpmat = vdevice.transmat;
  87.         vdevice.transmat = msfree;
  88.         msfree = msfree->back;
  89.         vdevice.transmat->back = tmpmat;
  90.         copymatrix(vdevice.transmat->m, tmpmat->m);
  91.     } else {
  92.         tmpmat = (Mstack *)vallocate(sizeof(Mstack));
  93.         tmpmat->back = vdevice.transmat;
  94.         copymatrix(tmpmat->m, vdevice.transmat->m);
  95.         vdevice.transmat = tmpmat;
  96.     }
  97. }
  98.  
  99. /*
  100.  * popmatrix
  101.  *
  102.  * Pop the top matrix from the stack.
  103.  *
  104.  */
  105. void
  106. popmatrix(void)
  107. {
  108.     Token    *p;
  109.     Mstack    *oldtop;
  110.  
  111.     if (vdevice.inobject) {
  112.         p = newtokens(1);
  113.  
  114.         p->i = POPMATRIX;
  115.  
  116.         return;
  117.     }
  118.  
  119.     if (vdevice.transmat->back == (Mstack *)NULL)
  120.         verror("popmatrix: matrix stack empty");
  121.     else {
  122.         oldtop = vdevice.transmat;
  123.         vdevice.transmat = vdevice.transmat->back;
  124.         oldtop->back = msfree;
  125.         msfree = oldtop;
  126.     }
  127.  
  128.     vdevice.cpVvalid = 0;    /* may have changed mapping from world to device coords */
  129. }
  130.  
  131. /*
  132.  * loadmatrix
  133.  *
  134.  * Replace the top matrix on the stack
  135.  *
  136.  */
  137. void
  138. loadmatrix(Matrix mat)
  139. {
  140.     register int    i;
  141.     register float    *cm, *mp;
  142.     Token        *p;
  143.  
  144.     if (!vdevice.initialised)
  145.         verror("loadmatrix: vogle not initialised");
  146.  
  147.     if (vdevice.inobject) {
  148.         p = newtokens(17);
  149.  
  150.         p[0].i = LOADMATRIX;
  151.         cm = (float *)mat;
  152.         for (i = 0; i < 16; i++)
  153.             (++p)->f = *cm++;
  154.  
  155.         return;
  156.     }
  157.  
  158.     cm = (float *)vdevice.transmat->m;
  159.     mp = (float *)mat;
  160.     for (i = 0; i < 16; i++)
  161.         *cm++ = *mp++;
  162.  
  163.     vdevice.cpVvalid = 0;        /* may have changed mapping from world to device coords */
  164. }
  165.  
  166. /*
  167.  * mult4x4
  168.  *
  169.  *    multiply 4 x 4 matrices b and c assigning them into a. Readers are
  170.  * reminded that speed can be important here.
  171.  *
  172.  */
  173. void
  174. mult4x4(register Matrix a, register Matrix b, register Matrix c)
  175. {
  176.     a[0][0] = b[0][0] * c[0][0] + b[0][1] * c[1][0] + b[0][2] * c[2][0] + b[0][3] * c[3][0];
  177.     a[0][1] = b[0][0] * c[0][1] + b[0][1] * c[1][1] + b[0][2] * c[2][1] + b[0][3] * c[3][1];
  178.     a[0][2] = b[0][0] * c[0][2] + b[0][1] * c[1][2] + b[0][2] * c[2][2] + b[0][3] * c[3][2];
  179.     a[0][3] = b[0][0] * c[0][3] + b[0][1] * c[1][3] + b[0][2] * c[2][3] + b[0][3] * c[3][3];
  180.  
  181.     a[1][0] = b[1][0] * c[0][0] + b[1][1] * c[1][0] + b[1][2] * c[2][0] + b[1][3] * c[3][0];
  182.     a[1][1] = b[1][0] * c[0][1] + b[1][1] * c[1][1] + b[1][2] * c[2][1] + b[1][3] * c[3][1];
  183.     a[1][2] = b[1][0] * c[0][2] + b[1][1] * c[1][2] + b[1][2] * c[2][2] + b[1][3] * c[3][2];
  184.     a[1][3] = b[1][0] * c[0][3] + b[1][1] * c[1][3] + b[1][2] * c[2][3] + b[1][3] * c[3][3];
  185.  
  186.     a[2][0] = b[2][0] * c[0][0] + b[2][1] * c[1][0] + b[2][2] * c[2][0] + b[2][3] * c[3][0];
  187.     a[2][1] = b[2][0] * c[0][1] + b[2][1] * c[1][1] + b[2][2] * c[2][1] + b[2][3] * c[3][1];
  188.     a[2][2] = b[2][0] * c[0][2] + b[2][1] * c[1][2] + b[2][2] * c[2][2] + b[2][3] * c[3][2];
  189.     a[2][3] = b[2][0] * c[0][3] + b[2][1] * c[1][3] + b[2][2] * c[2][3] + b[2][3] * c[3][3];
  190.  
  191.     a[3][0] = b[3][0] * c[0][0] + b[3][1] * c[1][0] + b[3][2] * c[2][0] + b[3][3] * c[3][0];
  192.     a[3][1] = b[3][0] * c[0][1] + b[3][1] * c[1][1] + b[3][2] * c[2][1] + b[3][3] * c[3][1];
  193.     a[3][2] = b[3][0] * c[0][2] + b[3][1] * c[1][2] + b[3][2] * c[2][2] + b[3][3] * c[3][2];
  194.     a[3][3] = b[3][0] * c[0][3] + b[3][1] * c[1][3] + b[3][2] * c[2][3] + b[3][3] * c[3][3];
  195. }
  196.  
  197. /*
  198.  * multmatrix
  199.  *
  200.  * Premultipy the top matrix on the stack by "mat"
  201.  *
  202.  */
  203. void
  204. multmatrix(Matrix mat)
  205. {
  206.     Matrix    prod;
  207.     float    *m;
  208.     Token    *p;
  209.     int    i;
  210.  
  211.     if (vdevice.inobject) {
  212.         p = newtokens(17);
  213.  
  214.         p[0].i = MULTMATRIX;
  215.         m = (float *)mat;
  216.         for (i = 0; i < 16; i++)
  217.             (++p)->f = *m++;
  218.  
  219.         return;
  220.     }
  221.  
  222.     mult4x4(prod, mat, vdevice.transmat->m);
  223.     loadmatrix(prod);
  224. }
  225.  
  226. /*
  227.  * identmatrix
  228.  *
  229.  * Return a 4 x 4 identity matrix
  230.  *
  231.  */
  232. void
  233. identmatrix(Matrix a)
  234. {
  235.     register float    *p;
  236.  
  237.     for (p = (float *)a; p != (float *)a + 16; p++)
  238.         *p = 0;
  239.  
  240.     a[0][0] = a[1][1] = a[2][2] = a[3][3] = 1;
  241. }
  242.  
  243. /*
  244.  * multvector
  245.  *
  246.  * Multiply the vector a and the matrix b to form v. Need it to be snappy again.
  247.  * 
  248.  */
  249. void
  250. multvector(register Vector v, register Vector a, register Matrix b)
  251. {
  252.     v[0] = a[0] * b[0][0] + a[1] * b[1][0] + a[2] * b[2][0] + a[3] * b[3][0];
  253.     v[1] = a[0] * b[0][1] + a[1] * b[1][1] + a[2] * b[2][1] + a[3] * b[3][1];
  254.     v[2] = a[0] * b[0][2] + a[1] * b[1][2] + a[2] * b[2][2] + a[3] * b[3][2];
  255.     v[3] = a[0] * b[0][3] + a[1] * b[1][3] + a[2] * b[2][3] + a[3] * b[3][3];
  256. }
  257.  
  258. /*
  259.  * premultvector
  260.  *
  261.  * PreMultiply the vector a and the matrix b to form v. 
  262.  * Need it to be snappy again.
  263.  * 
  264.  */
  265. void
  266. premultvector(Vector v, Vector a, Matrix b)
  267. {
  268.     v[0] = a[0] * b[0][0] + a[1] * b[0][1] + a[2] * b[0][2] + a[3] * b[0][3];
  269.     v[1] = a[0] * b[1][0] + a[1] * b[1][1] + a[2] * b[1][2] + a[3] * b[1][3];
  270.     v[2] = a[0] * b[2][0] + a[1] * b[2][1] + a[2] * b[2][2] + a[3] * b[2][3];
  271.     v[3] = a[0] * b[3][0] + a[1] * b[3][1] + a[2] * b[3][2] + a[3] * b[3][3];
  272. }
  273.  
  274. #ifdef DEBUG 
  275.  
  276. /*
  277.  * printmat
  278.  *
  279.  *    print s and then dump matrix m. Useful for debugging, you get
  280.  * sick of typing in the print loop otherwise.
  281.  */
  282. printmat(char *s, Matrix m)
  283. {
  284.     int    i, j;
  285.  
  286.     printf("%s\n", s);
  287.     for (i = 0; i < 4; i++) {
  288.         for (j = 0; j < 4; j++)
  289.             printf("%f ",m[i][j]);
  290.         printf("\n");
  291.     }
  292. }
  293. printvect(char *s, Vector v)
  294. {
  295.     printf("%s %f %f %f %f\n", s, v[0], v[1], v[2], v[3]);
  296. }
  297.  
  298. #endif
  299.