home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / avogl.tar.gz / avogl.tar / vogl / src / matrix.c < prev    next >
C/C++ Source or Header  |  1992-09-24  |  6KB  |  323 lines

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