home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / voglw.zip / matrix.c < prev    next >
C/C++ Source or Header  |  1997-02-13  |  6KB  |  315 lines

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