/* Yacc program which converts v1.0 files to v2.0 files */ /* C pass throughs */ %{ #include #include #include #include #define TRUE 1 #define FALSE 0 #define DEBUG exit(0) #define BOOL int /* Definitions */ /* Used to hold framerate and parameterization time */ typedef float Time; /* Used to hold 3d vectors */ typedef struct _Vector3 { float x,y,z; } Vector3; /* Used to pass back a vpn or at vector */ typedef struct _vpn_at { BOOL vpn_at; Vector3 theVector; } Vpn_At; /* Used to hold a list of spline key frames */ typedef struct _s_node { struct _s_node *next; Time Key_Time; Vector3 Position; BOOL vpn_or_at; BOOL dof; Vector3 vpn; Vector3 vup; } Spline_Node; /* Globals */ Time Frame_Rate; Spline_Node *Animation=NULL; int Num_Nodes=0; /* Function Protos */ void Print_Diagnostic(); void Normalize(Vector3 *vec); %} %token FRAMERATE TIME POSITION VPN AT VUP NUM %token DOF %start File %% File: Framerate Key_Frames { /* Set the spline node list */ Animation=(Spline_Node *)$2; } ; Framerate: FRAMERATE FPV { /* Get the framerate for this animation */ Frame_Rate=(Time)(*((float *)$2)); free((void *)$2); } ; Key_Frames: KeyFrame Key_Frames { /* Add a spline node to the spline node list */ Spline_Node *old=(Spline_Node *)$1; old->next=(Spline_Node *)$2; $$=$1; } | { /* End of the spline node list */ $$=NULL; } ; KeyFrame: Time Position Vpn Vup { /* Create a new spline node */ Spline_Node *new; new=(Spline_Node *)malloc(sizeof(Spline_Node)); new->Key_Time=(Time)(*((float *)$1)); new->Position=*(Vector3 *)($2); if (((Vpn_At *)($3))!=NULL) { new->vpn_or_at=((Vpn_At *)($3))->vpn_at; new->vpn=((Vpn_At *)($3))->theVector; new->dof=FALSE; } else new->dof=TRUE; new->vup=*(Vector3 *)($4); /* Free up the memory we borrowed */ free((void *)$1); free((void *)$2); if (!(new->dof)) free((void *)$3); free((void *)$4); /* Increment the number of nodes */ Num_Nodes++; /* and return the new node */ $$=(int)new; } ; Time: TIME FPV { /* Return the spline node time */ $$=$2; } ; Position: POSITION FPV FPV FPV { /* Return a new vector */ Vector3 *new; new=(Vector3 *)malloc(sizeof(Vector3)); new->x=*((float *)$2); new->y=*((float *)$3); new->z=*((float *)$4); free((void *)$2); free((void *)$3); free((void *)$4); $$=(int)new; } ; Vpn: VPN FPV FPV FPV { /* return a new Vpn_At node with VPN=TRUE */ Vpn_At *new; new=(Vpn_At *)malloc(sizeof(Vpn_At)); new->vpn_at=0; new->theVector.x=*((float *)$2); new->theVector.y=*((float *)$3); new->theVector.z=*((float *)$4); free((void *)$2); free((void *)$3); free((void *)$4); $$=(int)new; } | AT FPV FPV FPV { /* return a new Vpn_At node with AT=TRUE */ Vpn_At *new; new=(Vpn_At *)malloc(sizeof(Vpn_At)); new->vpn_at=1; new->theVector.x=*((float *)$2); new->theVector.y=*((float *)$3); new->theVector.z=*((float *)$4); free((void *)$2); free((void *)$3); free((void *)$4); $$=(int)new; } | DOF { /* return a NULL value which indicates that */ /* the direction of flight should be used */ /* for the VPN vector */ $$=(int)NULL; } ; Vup: VUP FPV FPV FPV { /* return a new VUP vector */ Vector3 *new; new=(Vector3 *)malloc(sizeof(Vector3)); new->x=*((float *)$2); new->y=*((float *)$3); new->z=*((float *)$4); free((void *)$2); free((void *)$3); free((void *)$4); $$=(int)new; } ; FPV: NUM { /* Return floating point value of NUM */ float *new; new=(float *)malloc(sizeof(float)); *new=atof((char *)yylval); $$=(int)new; } ; %% #include "convert.lex" /* Error routine for use by yyparse and my routines */ void yyerror(char *mesg) { fprintf(stderr,"%s\n",mesg); exit(0); } /* MAIN PROGRAM */ void main(int argc,char *argv[]) { yyparse(); fprintf(stderr,"Parse completed successfully.\n"); Print_Diagnostic(); } /* SUBROUTINES */ void Print_Diagnostic() { Spline_Node *top; fprintf(stdout,"%d\n",(int)Frame_Rate); fprintf(stdout,"0\n"); fprintf(stdout,"%d\n",Num_Nodes); top=Animation; while(top!=NULL) { fprintf(stdout,"%f\n",top->Key_Time); fprintf(stdout,"%f %f %f\n", top->Position.x, top->Position.y, top->Position.z); if (top->vpn_or_at) { top->vpn.x-=top->Position.x; top->vpn.y-=top->Position.y; top->vpn.z-=top->Position.z; Normalize(&top->vpn); fprintf(stdout,"%f %f %f\n", top->vpn.x, top->vpn.y, top->vpn.z); } else { if (!top->dof) { Normalize(&top->vpn); fprintf(stdout,"%f %f %f\n", top->vpn.x, top->vpn.y, top->vpn.z); } else fprintf(stdout,"%f %f %f\n",1.0,1.0,1.0); } Normalize(&top->vup); fprintf(stdout,"%f %f %f\n", top->vup.x, top->vup.y, top->vup.z); top=top->next; } } void Normalize(Vector3 *vec) { /* Normalize the given vector */ float length; length=sqrtf((vec->x * vec->x + vec->y * vec->y + vec->z * vec->z)); if (length!=0) { vec->x=vec->x/length; vec->y=vec->y/length; vec->z=vec->z/length; } }