home *** CD-ROM | disk | FTP | other *** search
- /* TC-14.C */
- /* This program demonstrates high-speed frame
- animation of a 3d intuitively-shaded object
-
- Supports VGA and EGA graphics adapters and
- monitors. The software uses 4 pages in the 640*200
- 16-color mode.
-
- The speed of the microprocessor has a dramatic affect
- uppon the required animation speed.
-
- The radial pre-sort method of hidden surface removal is
- used */
-
- /* ----------------------------------------------------------------------- */
- /* INCLUDE FILES */
- #include <process.h>
- #include <bios.h>
- #include <stdio.h>
- #include <graphics.h>
- #include <math.h>
-
- /* ----------------------------------------------------------------------- */
- /* DECLARATIONS */
- void keyboard(void);void quit_pgm(void);
- void notice(int x,int y);void coords(void);
- void graphics_setup(void);void labels(void);void draw_object(void);
- void calc_3d(void);void rotation(void);void window(void);
- void get_coords(void);void draw_poly(void);void animVGAEGA(void);
-
- int t1=1,t2=2,t3=1; /* loop counters */
- float x_res,y_res; /* used by compatibility mapping routines */
- int C0=0,C1=1,C2=2,C3=3,C4=4,C5=5,C6=6,C7=7,C8=8, /* color varariables */
- C9=9,C10=10,C11=11,C12=12,C13=13,C14=14,C15=15,
- mode_flag=0;
- int CLR,CLR1,CLR2,CLR3,EDGE;
-
- int p1=0,p2=0; /* pointer into arrays */
- float x=0.0,y=0.0,z=0.0; /* world coordinates */
- float sx=0.0,sy=0.0; /* output of 3d perspective formula */
- float xa=0.0,ya=0.0,za=0.0; /* temporary values in 3d formulas */
- float sxa=0.0,sya=0.0,sxb=0.0,syb=0.0; /* 2d line endpoints */
- float sxs=0.0,sys=0.0; /* temp storage od 2d line endpoint */
- float d=1200.0; /* angular perspective value */
- double r1=.48539; /* yaw angle in radians */
- double r2=6.28319; /* roll angle in radians */
- double r3=5.79778; /* pitch angle in radians */
- double sr1=0.0,sr2=0.0,sr3=0.0; /* sine rotation factors */
- double cr1=0.0,cr2=0.0,cr3=0.0; /* cosine rotation factors */
- float mx=0.0,my=-5.0,mz=-250.0; /* viewpoint position */
- int maxx=639,minx=0,maxy=199,miny=0; /* scaling viewport */
- float screen_x=639,screen_y=199; /* dimensions of screen mode */
- float rx=0.0,ry=0.0; /* scaling values used in mapping routine */
-
- int array_xyz[][3]={
- 20,-20,-30, 20,20,-30, 20,20,-20, 20,-20,-20, 20,-20,-30, 20,0,-25,
- 20,-20,-30, -20,-20,-30, -20,-20,-20, 20,-20,-20, 20,-20,-30, 0,-20,-25,
-
- -30,30,-30, 30,30,-30, 30,30,-20, -30,30,-20, -30,30,-30, 0,30,-25,
- -30,30,-30, -30,30,-20, -30,-30,-20, -30,-30,-30, -30,30,-30, -30,0,-25,
- -30,30,-20, 30,30,-20, 30,20,-20, -30,20,-20, -30,30,-20, 0,25,-20,
- 30,30,-20, 30,-30,-20, 20,-30,-20, 20,30,-20, 30,30,-20, 25,0,-20,
- 30,-30,-20, -30,-30,-20, -30,-20,-20, 30,-20,-20, 30,-30,-20, 0,-25,-20,
- -30,-30,-20, -30,30,-20, -20,30,-20, -20,-30,-20, -30,-30,-20, -25,0,-20,
-
- 20,-30,-20, 20,-20,-20, 20,-20,20, 20,-30,20, 20,-30,-20, 20,-25,0,
-
- -30,-30,30, -30,-20,30, 30,-20,30, 30,-30,30, -30,-30,30, 0,-25,30,
- -30,-30,-30, -30,-20,-30, -30,-20,30, -30,-30,30, -30,-30,-30, -30,-25,0,
- -30,-20,-20, -20,-20,-20, -20,-20,30, -30,-20,30, -30,-20,-20, -25,-20,0,
- 30,-20,-20, 30,-20,30, 20,-20,30, 20,-20,-20, 30,-20,-20, 25,-20,0,
- -30,-20,30, -30,-20,20, 30,-20,20, 30,-20,30, -30,-20,30, 0,-20,25,
-
- 20,30,-20, 20,30,30, 20,20,30, 20,20,-20, 20,30,-20, 20,25,0,
- 20,30,30, 20,-20,30, 20,-20,20, 20,30,20, 20,30,30, 20,0,25,
-
- -30,30,-30, -20,30,-30, -20,30,30, -30,30,30, -30,30,-30, -25,30,0,
- 20,30,-30, 30,30,-30, 30,30,30, 20,30,30, 20,30,-30, 25,30,0,
- -30,30,30, -30,30,20, 30,30,20, 30,30,30, -30,30,30, 0,30,25,
-
- -30,-30,30, -30,30,30, -20,30,30, -20,-30,30, -30,-30,30, -25,0,30,
- 20,-30,30, 20,30,30, 30,30,30, 30,-30,30, 20,-30,30, 25,0,30,
- -30,30,30, 30,30,30, 30,20,30, -30,20,30, -30,30,30, 0,25,30,
- -30,20,-30, -30,30,-30, -30,30,30, -30,20,30, -30,20,-30, -30,25,0,
- -30,-30,20, -30,30,20, -30,30,30, -30,-30,30, -30,-30,20, -30,0,25};
-
- /* ----------------------------------------------------------------------- */
- /* MAIN ROUTINE */
-
- main(){
- graphics_setup();
- setviewport(0,0,maxx,maxy,1);
- CLR1=C15;CLR2=C8;CLR3=C7;EDGE=C7; /* color scheme for rendering */
-
- setvisualpage(0);setactivepage(0);cleardevice();
- r1=.58539;r2=6.28319;r3=5.79778;labels();draw_object();keyboard();
-
- setvisualpage(1);setactivepage(1);cleardevice();
- r1=r1+.08727;r2=6.28319;r3=5.79778;labels();draw_object();keyboard();
-
- setvisualpage(2);setactivepage(2);cleardevice();
- r1=r1+.08727;r2=6.28319;r3=5.79778;labels();draw_object();keyboard();
-
- setvisualpage(3);setactivepage(3);cleardevice();
- r1=r1+.08727;r2=6.28319;r3=5.79778;labels();draw_object();keyboard();
-
- setvisualpage(0);setactivepage(0); /* reset to frame 0 */
- for (t1=1;t1<=30000;t1++); /* puase */
- animVGAEGA();
- quit_pgm();
- }
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: DISPLAY ALPHANUMERIC LABELS */
-
- void labels(void){
- setcolor(C7);moveto(0,192);
- outtext("Revisions by A. Helder");
- moveto(168,0);setcolor(C12);
- outtext("USING C FOR HIGH-SPEED FRAME ANIMATION");
- moveto(464,192);outtext("Press any key to stop.");
- moveto(176,16);setcolor(C14);
- outtext("Animated rotation of solid 3d model");
- setcolor(C7);return;
- }
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: DRAW THE GRAPHICS */
-
- void draw_object(void){
-
- rotation();
- p1=0;
-
- CLR=CLR3;EDGE=CLR3;draw_poly(); /* step 1 */
- CLR=CLR1;EDGE=CLR1;draw_poly();
-
- draw_poly(); /* step 2 */
- CLR=CLR3;EDGE=CLR3;draw_poly();
- CLR=CLR2;EDGE=CLR2;for (t3=1;t3<=4;t3++)
- {
- draw_poly();
- }
-
- CLR=CLR3;EDGE=CLR3;draw_poly(); /* step 3 */
-
- CLR=CLR2;EDGE=CLR2;draw_poly(); /* step 4 */
- CLR=CLR3;EDGE=CLR3;draw_poly();
- CLR=CLR1;EDGE=CLR1;for (t3=1;t3<=3;t3++)
- {
- draw_poly();
- }
-
- CLR=CLR3;EDGE=CLR3;for (t3=1;t3<=2;t3++) /* step 5 */
- {
- draw_poly();
- }
-
- CLR=CLR1;EDGE=CLR1;for (t3=1;t3<=3;t3++) /* step 6 */
- {
- draw_poly();
- }
-
- CLR=CLR2;EDGE=CLR2;for (t3=1;t3<=3;t3++){draw_poly();}
- CLR=CLR3;EDGE=CLR3;for (t3=1;t3<=2;t3++){draw_poly();}
-
- setcolor(C7);sx=5;sy=400;coords();notice(sx,sy);return;} /* for faster animation, delete ";notice (sx,sy)"
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: DRAW AND FILL POLYGON IN 3D SPACE */
-
- void draw_poly(void){
-
- setcolor(C13);
- setfillstyle(SOLID_FILL,C13);
- get_coords(); /* retrieve xyz vertex coords from database */
- calc_3d(); /* 3d rotation,translation,projection */
- window(); /* map display coords to fil 4:3 screen */
- sxa=sx;sya=sy; /* line start point */
- for (t1=1;t1<=4;t1++){ /* draw 4 lines in 3d */
- get_coords(); /* retrieve xyz vertex coordinates from database */
- calc_3d(); /* 3d rotation, translation, projection */
- window(); /* map diaplsy coordinates to fit 4:3 screen */
- sxs=sx;sys=sy;sxb=sx;syb=sy; /* line is sxa,sya to sxb,syb */
- moveto(sxa,sya);lineto(sxb,syb); /* draw line in 3d */
- sxa=sxs;sya=sys; /* define next start point */
- }
-
- get_coords(); /* retrieve xyz area fill from database */
- calc_3d();window();floodfill(sx,sy,C13); /* area fill */
-
- setcolor(CLR);EDGE+CLR;p1=p1-6; /* reset index pointer */
- setfillstyle(SOLID_FILL,CLR);
- get_coords();calc_3d();window();sxa=sx;sya=sy;
- for (t1=1;t1<=4;t1++){
- get_coords();calc_3d();window();sxs=sx;sys=sy;sxb=sx;syb=sy;
- moveto(sxa,sya);lineto(sxb,syb);sxa=sxs;sya=sys;
- }
-
- get_coords();calc_3d();window();floodfill(sx,sy,EDGE);
- keyboard();
- return;
- }
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: FRAME ANIMATION MANAGER FOR VGA AND EGA */
-
- void animVGAEGA(void){
- for (t1=1;t1!=2;){
- setvisualpage(1);for (t2=1;t2<=30000;t2++);
- setvisualpage(2);for (t2=1;t2<=30000;t2++);
- setvisualpage(3);for (t2=1;t2<=30000;t2++);
- setvisualpage(2);for (t2=1;t2<=30000;t2++);keyboard();
- setvisualpage(1);for (t2=1;t2<=30000;t2++);
- setvisualpage(0);for (t2=1;t2<=30000;t2++);
- /* setvisualpage(1);for (t2=1;t2<=10000;t2++);keyboard();};*/
- }
-
- return;
- }
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: RETRIEVE XYZ WORLD COORDINATES DROM DATABASE */
-
- void get_coords(void){
- x=array_xyz[p1][0];y=array_xyz[p1][1];z=array_xyz[p1][2];
- p1++;return;}
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: CALCULATE SIN,COS FACTORS */
-
- void rotation(void){
- sr1=sin(r1);sr2=sin(r2);sr3=sin(r3);cr1=cos(r1);cr2=cos(r2);
- cr3=cos(r3);return;}
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: STANDARD 3D FORMULAS */
- /* Pass: x,y,z cartesian world coordinates.
- Returns: sx,sy cartesian display coordinates.
- x,y,z catesian view coordinates */
-
- void calc_3d(void){
- x=(-1)*x;xa=cr1*x-sr1*z;za=sr1*x+cr1*z;x=cr2*xa+sr2*y;
- ya=cr2*y-sr2*xa;z=cr3*za-sr3*ya;y=sr3*za+cr3*ya;x=x+mx;y=y+my;
- z=z+mz;sx=d*x/z;sy=d*y/z;return;}
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: MAP CARTESIAN COORDS TO PHYSICAL SCREEN COORDS */
-
- void window(void){
- sx=sx+399;sy=sy+299;rx=screen_x/799;ry=screen_y/599;sx=sx*rx;
- sy=sy*ry;return;}
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: CHACK THE KEYBOARD BUFFER */
- void keyboard(void){
- if (bioskey(1)==0) return; else quit_pgm();}
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: GRACEFUL EXIT FROM PROGRAM */
-
- void quit_pgm(void){
- cleardevice();restorecrtmode();exit(0);}
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: VGA/EGA/MCGA/CGA COMPATIBILITY MODULE */
-
- void graphics_setup(void){
- int graphics_adapter,graphics_mode;
- detectgraph(&graphics_adapter,&graphics_mode);
- if (graphics_adapter==VGA) goto EGA_SCD_mode;
- if (graphics_mode==EGAHI) goto EGA_SCD_mode;
- if (graphics_mode==EGALO) goto EGA_SCD_mode;
- if (graphics_adapter==CGA) goto abort_message;
- if (graphics_adapter==MCGA) goto abort_message;
- goto abort_message;
-
- EGA_SCD_mode:
- graphics_adapter=EGA;graphics_mode=EGALO;
- initgraph(&graphics_adapter,&graphics_mode,"");
- x_res=640;y_res=200;mode_flag=3;
- maxx=639;minx=0;maxy=199;miny=0;screen_x=639;screen_y=199;
- return;
-
- abort_message:
- printf("\n\nUnable to proceed - Requires VGA,EGA,CGA or MCGA adapter");
- printf("\nWith appropriate monitor");
- exit(0);
- }
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: MAP 640*480 TEMPLATE TO 2D SCREEN */
- void coords(void)
- {
- sx=sx*(x_res/640);sy=sy*(y_res/480);return;
- }
-
- /* ----------------------------------------------------------------------- */
- /* SUBROUTINE: COPYRIGHT NOTICE */
-
- int copyright[][3]={0x7c00,0x0000,0x0000,0x8231,
- 0x819c,0x645e,0xba4a,0x4252,0x96d0,0xa231,0x8252,0x955e,0xba4a,
- 0x43d2,0xf442,0x8231,0x825c,0x945e,0x7c00,0x0000,0x0000};
-
- void notice(int x, int y){
- int a,b,c; int t1=0;
-
- for (t1=0;t1<=6;t1++)
- {
- a=copyright[t1][0];b=copyright[t1][1];
- c=copyright[t1][2];
- setlinestyle(USERBIT_LINE,a,NORM_WIDTH);
- moveto(x,y);lineto(x+15,y);
- setlinestyle(USERBIT_LINE,b,NORM_WIDTH);
- moveto(x+16,y);lineto(x+31,y);
- setlinestyle(USERBIT_LINE,c,NORM_WIDTH);
- moveto(x+32,y);lineto(x+47,y);y++;
- };
- setlinestyle(USERBIT_LINE,0xFFFF,NORM_WIDTH);
- return;}
-