home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / graphicgems4.lha / GemsIV / outcode / xf2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  2.7 KB  |  121 lines

  1. /* transform, clip test, and project a vertex list */
  2.  
  3. /* oflo and division traps should be disabled, by the way */
  4.  
  5. #define FI(x)    (*(int *)&x)
  6.  
  7. /********************************************************/
  8. xform_ctp(vc, vpi, vpo, visiz, vosiz, mtx, prj, pf, pa)
  9. int vc    ;    /* vertex count */
  10. int visiz;    /* input vertex array stride */
  11. int vosiz;    /* output vertex array stride */
  12. int *pf;    /* flag array */
  13. int *pa;    /* 2 element - global or_flag, and_flag */
  14. float *vpi, *vpo, *mtx, *prj;
  15. {
  16. register int flag, flag_or, flag_and;
  17. register int ti0, s, t, u;
  18. register int sign = 0x80000000;
  19.  
  20. /* flpt registers, total 32 */
  21. register float xx, xy, xz, xw;        /* transformation matrix */
  22. register float yx, yy, yz, yw;
  23. register float zx, zy, zz, zw;
  24. register float wx, wy, wz, ww;
  25. register float xo, yo, zo, wo;        /* output vertex */
  26. register float xs, xt, ys, yt, zs /*zt*/;    /* projection scale and translate */
  27. register float t0, t1, t2, t3, t4, t5;    /* temps */
  28. register float one = 1.0;
  29.  
  30. /* load up local projection matrix */
  31. xs = *(prj+0); xt = *(prj+1);
  32. ys = *(prj+2); yt = *(prj+3);
  33. zs = *(prj+4); /* zt = *(prj+5); later */
  34.  
  35. /* load up local transform matrix */
  36. xx = *(mtx+0 ); xy = *(mtx+1 ); xz = *(mtx+2 ); xw = *(mtx+3 );
  37. yx = *(mtx+4 ); yy = *(mtx+5 ); yz = *(mtx+6 ); yw = *(mtx+7 );
  38. zx = *(mtx+8 ); zy = *(mtx+9 ); zz = *(mtx+10); zw = *(mtx+11);
  39. wx = *(mtx+12); wy = *(mtx+13); wz = *(mtx+14); ww = *(mtx+15);
  40.  
  41. /* initialize accumulated flags */
  42. flag_or = 0;
  43. flag_and = -1;
  44.  
  45. do {
  46. #define wi    t4
  47.     wi = vpi[3];    /* wi */
  48. #define xi    t5
  49.     xi = vpi[0];    /* xi */
  50.  
  51.     /* calculate 4x4 transform, use as few regs as possible */
  52.     wo = wi*ww; xo = wi*wx; yo = wi*wy; zo = wi*wz;
  53. #define yi    t4
  54.     yi = vpi[1];    /* yi */
  55.  
  56.     t0 = xi*xw; t1 = xi*xx; t2 = xi*xy; t3 = xi*xz;
  57. #define zi    t5
  58.     zi = vpi[2];    /* zi */
  59.     wo += t0; xo += t1; yo += t2; zo += t3;
  60.  
  61.     t0 = yi*yw; t1 = yi*yx; t2 = yi*yy; t3 = yi*yz;
  62.     wo += t0; xo += t1; yo += t2; zo += t3;
  63.  
  64.     t0 = zi*zw; t1 = zi*zx; t2 = zi*zy; t3 = zi*zz;
  65.     wo += t0; xo += t1; yo += t2; zo += t3;
  66.  
  67. #define winv    t0
  68.     winv = one / wo;
  69.  
  70. #define zt    t1
  71.     /* ready for this now */
  72.     zt =    prj[5];
  73.  
  74.     /* let's try branches for comparison purposes */
  75.     flag = 0;
  76.  
  77. #define CXMAX    1
  78. #define CXMIN    2
  79. #define CYMAX    4
  80. #define CYMIN    8
  81. #define CZMAX    16
  82. #define CZMIN 32
  83.  
  84.     if (xo >  wo) flag |= CXMAX;
  85.     if (xo < -wo) flag |= CXMIN;
  86.     if (yo >  wo) flag |= CYMAX;
  87.     if (yo < -wo) flag |= CYMIN;
  88.     if (zo >  wo) flag |= CZMAX;
  89.     if (zo < -wo) flag |= CZMIN;
  90.  
  91.     flag_or |= flag;
  92.     flag_and &= flag;
  93.  
  94.     xo *= xs;
  95.     yo *= ys;
  96.     zo *= zs;
  97.  
  98.     xo *= winv;
  99.     yo *= winv;
  100.     zo *= winv;
  101.  
  102.     xo += xt;
  103.     yo += yt;
  104.     zo += zt;
  105.  
  106.     *(vpo+0) = xo;
  107.     *(vpo+1) = yo;
  108.     *(vpo+2) = zo;
  109.     *pf = flag;
  110.  
  111.     vpi += visiz;
  112.     vpo += vosiz;
  113.     pf++;
  114. } while (--vc > 0);
  115.  
  116. *(pa+0) = flag_or;
  117. *(pa+1) = flag_and;
  118.  
  119. return;
  120. }
  121.