home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / 3DGPL 1.0 / CODE / TRANS / TRANS-FX.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-08  |  10.8 KB  |  292 lines  |  [TEXT/MACA]

  1. /** 3DGPL *************************************************\
  2.  *  ()                                                    *
  3.  *  3-D transformations of coordinates using fixed point. *
  4.  *                                                        *
  5.  *  Defines:                                              *
  6.  *   T_init_math             Creating sin/cos tables;     *
  7.  *                                                        *
  8.  *   T_translation           Shifting of coordinates;     *
  9.  *   T_scaling               Scaling coordinates;         *
  10.  *                                                        *
  11.  *   T_set_world_rotation    Viewer's rotation;           *
  12.  *   T_world_rotation        Transforming coordinates;    *
  13.  *   T_set_self_rotation     Object rotation;             *
  14.  *   T_self_rotation         Transforming coordinates;    *
  15.  *                                                        *
  16.  *   T_perspective           Transform to perspective.    *
  17.  *                                                        *
  18.  *  Internals:                                            *
  19.  *   TI_float2fixed          Converting float to fixed.   *
  20.  *                                                        *
  21.  *  (6/1995) By Sergei Savchenko. (savs@cs.mcgill.ca).    *
  22.  *  Copyright (c) 1995 Sergei Savchenko.                  *
  23.  *  THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
  24.  *  WITHOUT AUTHORISATION                                 *
  25. \**********************************************************/
  26.  
  27. #include <math.h>                           /* sin & cos */
  28.  
  29. #ifdef __MWERKS__
  30. #include "hardware.h"           /* 32bit int name */
  31. #include "trans.h"                 /* 3D mathematics */
  32. #else
  33. #include "../hardware/hardware.h"           /* 32bit int name */
  34. #include "../trans/trans.h"                 /* 3D mathematics */
  35. #endif
  36.  
  37. typedef signed_32_bit fixed;                /* better be 32bit machine */
  38.  
  39. #define T_RADS                  40.7436642  /* pseudo-grads into rads */
  40. #define T_P                             14  /* fixed math precision */
  41.  
  42. fixed T_wx1,T_wx2,T_wx3,T_wy1,T_wy2,T_wy3,T_wz1,T_wz2,T_wz3;
  43. fixed T_sx1,T_sx2,T_sx3,T_sy1,T_sy2,T_sy3,T_sz1,T_sz2,T_sz3;
  44. fixed T_sin[256],T_cos[256];                /* precalculated */
  45.  
  46. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ 
  47.  *  INTERNAL: Converting [-1,1] float into fixed.        *
  48.  *  ---------                                            *
  49. \* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  50.  
  51. fixed TI_float2fixed(float a)
  52.  fixed res=0;
  53.  int i,dv,sign;
  54.  
  55.  if((sign=a<0.0)==1) a=-a;
  56.  
  57.  for(i=1,dv=2;i<=T_P;i++,dv*=2)
  58.   if(a>=1.0/dv) { a-=1.0/dv; res|=(0x1<<(T_P-i)); };
  59.  
  60.  if(sign==1) res=-res;
  61.  
  62.  return(res);
  63. }
  64.  
  65. /**********************************************************\
  66.  *  Initializing tables.                                  *
  67. \**********************************************************/
  68.  
  69. void T_init_math(void)
  70. {
  71.  int i;
  72.  
  73.  for(i=0;i<256;i++)
  74.  {
  75.   T_sin[i]=TI_float2fixed(sin(i/T_RADS));
  76.   T_cos[i]=TI_float2fixed(cos(i/T_RADS));
  77.  }
  78.  
  79. /**********************************************************\
  80.  *  Translation of coordinates.                           *
  81. \**********************************************************/
  82.  
  83. void T_translation(register int *from,register int *to,int length,
  84.            int addx,int addy,int addz
  85.           )
  86. {
  87.  register int i;
  88.  
  89.  for(i=0;i<length;i++)
  90.  {
  91.   (*to++)=(*from++)+addx;
  92.   (*to++)=(*from++)+addy;
  93.   (*to++)=(*from++)+addz;                   /* translation */
  94.  }
  95. }
  96.  
  97. /**********************************************************\
  98.  *  Scaling coordinates. (takes in float parameters).     *
  99. \**********************************************************/
  100.  
  101. void T_scaling(register int *from,register int *to,int length,
  102.            int mulx,int muly,int mulz
  103.           )
  104. {
  105.  register int i;
  106.  
  107.  for(i=0;i<length;i++)
  108.  {
  109.   (*to++)=(int)(*from++)*mulx;
  110.   (*to++)=(int)(*from++)*muly;
  111.   (*to++)=(int)(*from++)*mulz;
  112.  }                                          /* scaling */
  113. }
  114.  
  115. /**********************************************************\
  116.  *  Constructing rotation matrix. (gam-bet-alp), rotation *
  117.  *  then pitch then roll sequence. gam-rotation, bet-pitch*
  118.  *                                 alp-roll.              *
  119.  *                                                        *
  120.  *          Y^    Z           x'=z*sin(gam)+x*cos(gam)    *
  121.  *           |   /            y'=y                        *
  122.  *           |  / alp         z'=z*cos(gam)-x*sin(gam)    *
  123.  *          /|<---+                                       *
  124.  *         | |/   |           x"=x'                       *
  125.  *  -------|-+-----------> X  y"=y'*cos(bet)-z'*sin(bet)  *
  126.  *     bet | |   __           z"=y'*sin(bet)+z'*cos(bet)  *
  127.  *         V/|   /| gam                                   *
  128.  *         /----+             x"'=y"*sin(alp)+x"*cos(alp) *
  129.  *        /  |                y"'=y"*cos(alp)-x"*sin(alp) *
  130.  *       /   |                z"'=z"                      *
  131.  *           |                                            *
  132. \**********************************************************/
  133.  
  134. void T_set_world_rotation(int alp,int bet,int gam)
  135. {
  136.  fixed cosalp,sinalp,cosbet,sinbet,cosgam,singam;
  137.  
  138.  cosalp=T_cos[alp];
  139.  sinalp=T_sin[alp];
  140.  cosbet=T_cos[bet];
  141.  sinbet=T_sin[bet];
  142.  cosgam=T_cos[gam];
  143.  singam=T_sin[gam];                         /* initializing */
  144.  
  145.  T_wx1=((singam*((sinbet*sinalp)>>T_P))>>T_P) + ((cosgam*cosalp)>>T_P);
  146.  T_wy1=((cosbet*sinalp)>>T_P);
  147.  T_wz1=((singam*cosalp)>>T_P) - ((cosgam*((sinbet*sinalp)>>T_P))>>T_P);
  148.  
  149.  T_wx2=((singam*((sinbet*cosalp)>>T_P))>>T_P) - ((cosgam*sinalp)>>T_P);
  150.  T_wy2=((cosbet*cosalp)>>T_P);
  151.  T_wz2=-((cosgam*((sinbet*cosalp)>>T_P))>>T_P) - ((singam*sinalp)>>T_P);
  152.  
  153.  T_wx3=-((singam*cosbet)>>T_P);
  154.  T_wy3=sinbet;
  155.  T_wz3=((cosgam*cosbet)>>T_P);              /* calculating the matrix */
  156. }
  157.  
  158. /**********************************************************\
  159.  *  Rotating coordinates.                                 *
  160.  *                                        |wx1 wx2 wx3|   *
  161.  *  T'=T[W]  where:  [x' y' z'] = [x y z]*|wy1 wy2 wy3|   *
  162.  *                                        |wz1 wz2 wz3|   *
  163. \**********************************************************/
  164.  
  165. void T_world_rotation(int *from,register int *to,int length)
  166. {
  167.  register int i;
  168.  register int xt,yt,zt;
  169.  
  170.  for(i=0;i<length;i++)
  171.  {
  172.   xt=*from++;
  173.   yt=*from++;
  174.   zt=*from++;
  175.  
  176.   *to++=((T_wx1*xt)>>T_P) + ((T_wy1*yt)>>T_P) + ((T_wz1*zt)>>T_P);
  177.   *to++=((T_wx2*xt)>>T_P) + ((T_wy2*yt)>>T_P) + ((T_wz2*zt)>>T_P);
  178.   *to++=((T_wx3*xt)>>T_P) + ((T_wy3*yt)>>T_P) + ((T_wz3*zt)>>T_P); 
  179.  }
  180. }
  181.  
  182. /**********************************************************\
  183.  *  Constructing rotation matrix. (alp-bet-gam), roll     *
  184.  *  then pitch then rotation sequence. gam-rotation,      *
  185.  *                                     bet-pitch, alp-roll*
  186.  *                                                        *
  187.  *          Y^    Z           x'=y*sin(alp)+x*cos(alp)    *
  188.  *           |   /            y'=y*cos(alp)-x*sin(alp)    *
  189.  *           |  / alp         z'=z                        *
  190.  *          /|<---+                                       *
  191.  *         | |/   |           x"=x'                       *
  192.  *  -------|-+-----------> X  y"=y'*cos(bet)-z'*sin(bet)  *
  193.  *     bet | |   __           z"=y'*sin(bet)+z'*cos(bet)  *
  194.  *         V/|   /| gam                                   *
  195.  *         /----+             x"'=z"*sin(gam)+x"*cos(gam) *
  196.  *        /  |                y"'=y"                      *
  197.  *       /   |                z"'=z"*cos(gam)-x"*sin(gam) *
  198.  *           |                                            *
  199. \**********************************************************/
  200.  
  201. void T_set_self_rotation(int alp,int bet,int gam)
  202.  fixed cosalp,sinalp,cosbet,sinbet,cosgam,singam;
  203.  
  204.  cosalp=T_cos[alp];
  205.  sinalp=T_sin[alp];
  206.  cosbet=T_cos[bet];
  207.  sinbet=T_sin[bet];
  208.  cosgam=T_cos[gam];
  209.  singam=T_sin[gam];                         /* initializing */
  210.  
  211.  T_sx1=((cosalp*cosgam)>>T_P)-((sinalp*((sinbet*singam)>>T_P))>>T_P);
  212.  T_sy1=((sinalp*cosgam)>>T_P)+((cosalp*((sinbet*singam)>>T_P))>>T_P);
  213.  T_sz1=((cosbet*singam)>>T_P);
  214.  
  215.  T_sx2=-((sinalp*cosbet)>>T_P);
  216.  T_sy2=((cosalp*cosbet)>>T_P);
  217.  T_sz2=-sinbet;
  218.  
  219.  T_sx3=-((cosalp*singam)>>T_P)-((sinalp*((sinbet*cosgam)>>T_P))>>T_P);
  220.  T_sy3=((cosalp*((sinbet*cosgam)>>T_P))>>T_P)-((sinalp*singam)>>T_P);
  221.  T_sz3=((cosbet*cosgam)>>T_P);              /* calculating the matrix */
  222. }
  223.  
  224. /**********************************************************\
  225.  *  Rotating coordinates.                                 *
  226.  *                                        |sx1 sx2 sx3|   *
  227.  *  T'=T[S]  where:  [x' y' z'] = [x y z]*|sy1 sy2 sy3|   *
  228.  *                                        |sz1 sz2 sz3|   *
  229. \**********************************************************/
  230.  
  231. void T_self_rotation(int *from,register int *to,int length)
  232. {
  233.  register int i;
  234.  register int xt,yt,zt;
  235.  
  236.  for(i=0;i<length;i++)
  237.  {
  238.   xt=*from++;
  239.   yt=*from++;
  240.   zt=*from++;
  241.  
  242.   *to++=((T_sx1*xt)>>T_P) + ((T_sy1*yt)>>T_P) + ((T_sz1*zt)>>T_P);
  243.   *to++=((T_sx2*xt)>>T_P) + ((T_sy2*yt)>>T_P) + ((T_sz2*zt)>>T_P);
  244.   *to++=((T_sx3*xt)>>T_P) + ((T_sy3*yt)>>T_P) + ((T_sz3*zt)>>T_P); 
  245.  }
  246. }
  247.  
  248. /**********************************************************\
  249.  *  Transforming to perspective, coordinates passed ase   *
  250.  *                        supposed to be both volume, and *
  251.  *                *       Z-clipped, otherwise division   *
  252.  *               /|X      by 0 or overflow can occur.     *
  253.  *              / |                                       *
  254.  *             /  |                                       *
  255.  *            *   |                                       *
  256.  *           /|X' |       X'      X                       *
  257.  *          / |   |    ------- = ---                      *
  258.  *         /  |   |     focus     Z                       *
  259.  *        *---+---+                                       *
  260.  *        0   ^   Z    X'= X*focus/Z                      *
  261.  *            |                                           *
  262.  *          focus                                         *
  263.  *                                                        *
  264.  *  ADDITIONAL FUNCTIONS: 1) changing formats:            *
  265.  *  ---------------------                                 *
  266.  *    source:       x, y ,z,a1,...,aN where N==dimension-3*
  267.  *    destanation:  x',y',  a1,...,aN                     *   
  268.  *                                                        *
  269.  *  2) performs translation to the screen centre.         *
  270. \**********************************************************/
  271.  
  272. void T_perspective(register int *from,register int *to,
  273.            int dimension,int length
  274.           )
  275. {
  276.  register int i;
  277.  
  278.  dimension-=3;                              /* other then X,Y */
  279.  
  280.  for(i=0;i<length;i++,from+=dimension,to+=dimension) 
  281.  {                                          /* Z is not being changed */
  282.   to[0]=((((long)from[0])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_X_CENTRE;
  283.   to[1]=((((long)from[1])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_Y_CENTRE;
  284.   HW_copy_int(from+=3,to+=2,dimension);
  285.  }
  286. }
  287.  
  288. /**********************************************************/
  289.