home *** CD-ROM | disk | FTP | other *** search
- /** 3DGPL *************************************************\
- * () *
- * 3-D transformations of coordinates using floats. *
- * *
- * Defines: *
- * T_init_math Creating sin/cos tables; *
- * *
- * T_translation Shifting of coordinates; *
- * T_scaling Scaling coordinates; *
- * *
- * T_set_world_rotation Viewer's rotation; *
- * T_world_rotation Transforming coordinates; *
- * T_set_self_rotation Object rotation; *
- * T_self_rotation Transforming coordinates; *
- * *
- * T_perspective Transform to perspective. *
- * *
- * (6/1995) By Sergei Savchenko. (savs@cs.mcgill.ca). *
- * Copyright (c) 1995 Sergei Savchenko. *
- * THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
- * WITHOUT AUTHORISATION *
- \**********************************************************/
-
- #include <math.h> /* sin & cos */
-
- #ifdef __MWERKS__
- #include "hardware.h" /* fast copy routines */
- #include "trans.h" /* 3D mathematics */
- #else
- #include "../hardware/hardware.h" /* fast copy routines */
- #include "../trans/trans.h" /* 3D mathematics */
- #endif
-
- #define T_RADS 40.7436642 /* pseudo-grads into rads */
-
- float T_wx1,T_wx2,T_wx3,T_wy1,T_wy2,T_wy3,T_wz1,T_wz2,T_wz3;
- float T_sx1,T_sx2,T_sx3,T_sy1,T_sy2,T_sy3,T_sz1,T_sz2,T_sz3;
- float T_sin[256],T_cos[256]; /* precalculated */
-
- /**********************************************************\
- * Initializing tables. *
- \**********************************************************/
-
- void T_init_math(void)
- {
- int i;
-
- for(i=0;i<256;i++)
- {
- T_sin[i]=sin(i/T_RADS);
- T_cos[i]=cos(i/T_RADS);
- }
- }
-
- /**********************************************************\
- * Translation of coordinates. *
- \**********************************************************/
-
- void T_translation(register int *from,register int *to,int length,
- int addx,int addy,int addz
- )
- {
- register int i;
-
- for(i=0;i<length;i++)
- {
- (*to++)=(*from++)+addx;
- (*to++)=(*from++)+addy;
- (*to++)=(*from++)+addz; /* translation */
- }
- }
-
- /**********************************************************\
- * Scaling coordinates. (takes in float parameters). *
- \**********************************************************/
-
- void T_scaling(register int *from,register int *to,int length,
- int mulx,int muly,int mulz
- )
- {
- register int i;
-
- for(i=0;i<length;i++)
- {
- (*to++)=(int)(*from++)*mulx;
- (*to++)=(int)(*from++)*muly;
- (*to++)=(int)(*from++)*mulz;
- } /* scaling */
- }
-
- /**********************************************************\
- * Constructing rotation matrix. (gam-bet-alp), rotation *
- * then pitch then roll sequence. gam-rotation, bet-pitch*
- * alp-roll. *
- * *
- * Y^ Z x'=z*sin(gam)+x*cos(gam) *
- * | / y'=y *
- * | / alp z'=z*cos(gam)-x*sin(gam) *
- * /|<---+ *
- * | |/ | x"=x' *
- * -------|-+-----------> X y"=y'*cos(bet)-z'*sin(bet) *
- * bet | | __ z"=y'*sin(bet)+z'*cos(bet) *
- * V/| /| gam *
- * /----+ x"'=y"*sin(alp)+x"*cos(alp) *
- * / | y"'=y"*cos(alp)-x"*sin(alp) *
- * / | z"'=z" *
- * | *
- \**********************************************************/
-
- void T_set_world_rotation(int alp,int bet,int gam)
- {
- float cosalp,sinalp,cosbet,sinbet,cosgam,singam;
-
- cosalp=T_cos[alp];
- sinalp=T_sin[alp];
- cosbet=T_cos[bet];
- sinbet=T_sin[bet];
- cosgam=T_cos[gam];
- singam=T_sin[gam]; /* initializing */
-
- T_wx1=singam*sinbet*sinalp + cosgam*cosalp;
- T_wy1=cosbet*sinalp;
- T_wz1=singam*cosalp - cosgam*sinbet*sinalp;
-
- T_wx2=singam*sinbet*cosalp - cosgam*sinalp;
- T_wy2=cosbet*cosalp;
- T_wz2=-cosgam*sinbet*cosalp - singam*sinalp;
-
- T_wx3=-singam*cosbet;
- T_wy3=sinbet;
- T_wz3=cosgam*cosbet; /* calculating the matrix */
- }
-
- /**********************************************************\
- * Rotating coordinates. *
- * |wx1 wx2 wx3| *
- * T'=T[W] where: [x' y' z'] = [x y z]*|wy1 wy2 wy3| *
- * |wz1 wz2 wz3| *
- \**********************************************************/
-
- void T_world_rotation(int *from,register int *to,int length)
- {
- register int i;
- register int xt,yt,zt;
-
- for(i=0;i<length;i++)
- {
- xt=*from++;
- yt=*from++;
- zt=*from++;
-
- *to++=(int)(T_wx1*xt+T_wy1*yt+T_wz1*zt);
- *to++=(int)(T_wx2*xt+T_wy2*yt+T_wz2*zt);
- *to++=(int)(T_wx3*xt+T_wy3*yt+T_wz3*zt);
- }
- }
-
- /**********************************************************\
- * Constructing rotation matrix. (alp-bet-gam), roll *
- * then pitch then rotation sequence. gam-rotation, *
- * bet-pitch, alp-roll*
- * *
- * Y^ Z x'=y*sin(alp)+x*cos(alp) *
- * | / y'=y*cos(alp)-x*sin(alp) *
- * | / alp z'=z *
- * /|<---+ *
- * | |/ | x"=x' *
- * -------|-+-----------> X y"=y'*cos(bet)-z'*sin(bet) *
- * bet | | __ z"=y'*sin(bet)+z'*cos(bet) *
- * V/| /| gam *
- * /----+ x"'=z"*sin(gam)+x"*cos(gam) *
- * / | y"'=y" *
- * / | z"'=z"*cos(gam)-x"*sin(gam) *
- * | *
- \**********************************************************/
-
- void T_set_self_rotation(int alp,int bet,int gam)
- {
- float cosalp,sinalp,cosbet,sinbet,cosgam,singam;
-
- cosalp=T_cos[alp];
- sinalp=T_sin[alp];
- cosbet=T_cos[bet];
- sinbet=T_sin[bet];
- cosgam=T_cos[gam];
- singam=T_sin[gam]; /* initializing */
-
- T_sx1=cosalp*cosgam-sinalp*sinbet*singam;
- T_sy1=sinalp*cosgam+cosalp*sinbet*singam;
- T_sz1=cosbet*singam;
-
- T_sx2=-sinalp*cosbet;
- T_sy2=cosalp*cosbet;
- T_sz2=-sinbet;
-
- T_sx3=-cosalp*singam-sinalp*sinbet*cosgam;
- T_sy3=cosalp*sinbet*cosgam-sinalp*singam;
- T_sz3=cosbet*cosgam; /* calculating the matrix */
- }
-
- /**********************************************************\
- * Rotating coordinates. *
- * |sx1 sx2 sx3| *
- * T'=T[S] where: [x' y' z'] = [x y z]*|sy1 sy2 sy3| *
- * |sz1 sz2 sz3| *
- \**********************************************************/
-
- void T_self_rotation(int *from,register int *to,int length)
- {
- register int i;
- register int xt,yt,zt;
-
- for(i=0;i<length;i++)
- {
- xt=*from++;
- yt=*from++;
- zt=*from++;
-
- *to++=(int)(T_sx1*xt+T_sy1*yt+T_sz1*zt);
- *to++=(int)(T_sx2*xt+T_sy2*yt+T_sz2*zt);
- *to++=(int)(T_sx3*xt+T_sy3*yt+T_sz3*zt);
- }
- }
-
- /**********************************************************\
- * Transforming to perspective, coordinates passed ase *
- * supposed to be both volume, and *
- * * Z-clipped, otherwise division *
- * /|X by 0 or overflow can occur. *
- * / | *
- * / | *
- * * | *
- * /|X' | X' X *
- * / | | ------- = --- *
- * / | | focus Z *
- * *---+---+ *
- * 0 ^ Z X'= X*focus/Z *
- * | *
- * focus *
- * *
- * ADDITIONAL FUNCTIONS: 1) changing formats: *
- * --------------------- *
- * source: x, y ,z,a1,...,aN where N==dimension-3*
- * destanation: x',y', a1,...,aN *
- * *
- * 2) performs translation to the screen centre. *
- \**********************************************************/
-
- void T_perspective(register int *from,register int *to,
- int dimension,int length
- )
- {
- register int i;
-
- dimension-=3; /* other then X,Y */
-
- for(i=0;i<length;i++,from+=dimension,to+=dimension)
- { /* Z is not being changed */
- to[0]=((((long)from[0])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_X_CENTRE;
- to[1]=((((long)from[1])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_Y_CENTRE;
- HW_copy_int(from+=3,to+=2,dimension);
- }
- }
-
- /**********************************************************/
-