/* robot3.c based on robot2.c and robot.c and dynamic.c */ /* read robot3.dat and move per commands */ /* Interactive Figure Program from Chapter 8 using cylinders (quadrics) */ /* Style similar to robot program but here we must traverse tree to display */ /* Cylinders are displayed as filled and light/material properties */ /* are set as in sphere approximation program */ /* E. Angel, Interactive Computer Graphics, changes by JSS */ /* This version uses a dynamic tree structure */ /* upper and lower limbs have unique colors */ /* short names for id e.g. TT, TB, HN etc. */ #include #include #include #include #include #include #define TORSO_HEIGHT 5.0 #define UPPER_ARM_HEIGHT 3.0 #define LOWER_ARM_HEIGHT 2.0 #define UPPER_LEG_RADIUS 0.5 #define LOWER_LEG_RADIUS 0.5 #define LOWER_LEG_HEIGHT 2.0 #define UPPER_LEG_HEIGHT 3.0 #define UPPER_LEG_RADIUS 0.5 #define TORSO_RADIUS 1.0 #define UPPER_ARM_RADIUS 0.5 #define LOWER_ARM_RADIUS 0.5 #define HEAD_HEIGHT 1.5 #define HEAD_RADIUS 1.0 #define HAND_HEIGHT 0.6 #define HAND_RADIUS 0.6 #define FOOT_HEIGHT 0.6 #define FOOT_RADIUS 0.6 /* menu select actions id saved in 'angle' */ #define TORSO_TURN 0 #define TORSO_BEND 1 #define HEAD_NOD 2 #define HEAD_TURN 3 #define RIGHT_UPPER_ARM 4 #define RIGHT_BALL_ARM 5 #define RIGHT_LOWER_ARM 6 #define LEFT_UPPER_ARM 7 #define LEFT_BALL_ARM 8 #define LEFT_LOWER_ARM 9 #define RIGHT_UPPER_LEG 10 #define RIGHT_LOWER_LEG 11 #define LEFT_UPPER_LEG 12 #define LEFT_LOWER_LEG 13 /* must be last three */ #define INCREASE_MOVEMENT 14 #define DECREASE_MOVEMENT 15 #define QUIT 16 #define MOVE 0 #define END 1 #define REPEAT 2 typedef struct nid{char nm[4]; int id; } nid; static nid ni[17] = {"TT ", TORSO_TURN, "TB ", TORSO_BEND, "HN ", HEAD_NOD, "HT ", HEAD_TURN, "RUA", RIGHT_UPPER_ARM, "RBA", RIGHT_BALL_ARM, "RLA", RIGHT_LOWER_ARM, "LUA", LEFT_UPPER_ARM, "LBA", LEFT_BALL_ARM, "LLA", LEFT_LOWER_ARM, "RUL", RIGHT_UPPER_LEG, "RLL", RIGHT_LOWER_LEG, "LUL", LEFT_UPPER_LEG, "LLL", LEFT_LOWER_LEG, "IM ", INCREASE_MOVEMENT, "DM ", DECREASE_MOVEMENT, "Q ", QUIT}; /* body part renderers */ static void torso(); static void head(); static void left_upper_arm(); static void right_upper_arm(); static void left_upper_leg(); static void right_upper_leg(); static void hand(); static void foot(); static void move(); typedef float point[3]; typedef struct treenode { GLfloat m[16]; /* 4 by 4 matrix */ void (*f)(); /* function that renders */ struct treenode *sibling; struct treenode *child; } treenode, *t_ptr; static point rpos = {0.0, 0.0, 0.0}; /* robot base position in x,y,z */ static GLfloat theta[QUIT] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0}; /* initial and changed joint angles */ static GLint angle = 0; /* the angle that will change, see menu id */ static GLfloat movement = 5.0; /* can increase or decrease */ static GLUquadricObj *t, *h, *han, *foo, *lua, *lla, *rua, *rla, *lll, *rll, *rul, *lul; static double size=1.0; /* scale for lettering */ static t_ptr torso_ptr, head_ptr, hand_ptr, foot_ptr, lua_ptr, rua_ptr, lll_ptr, rll_ptr, lla_ptr, rla_ptr, rul_ptr, lul_ptr; static FILE *inp; static char buf[100]; /* robot3.dat input */ static int len; /* includes new line */ static double wt; /* waste time */ static void traverse(t_ptr root) { if(root==NULL) return; glPushMatrix(); glMultMatrixf(root->m); /* translation, rotation and scaling */ root->f(); /* execute the function that renders */ if(root->child!=NULL) traverse(root->child); glPopMatrix(); if(root->sibling!=NULL) traverse(root->sibling); } /* end traverse */ static void torso() { GLfloat mat_diffuser[]={1.0, 0.0, 0.0, 1.0}; /* red */ glPushMatrix(); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuser); gluCylinder(t,TORSO_RADIUS, TORSO_RADIUS, TORSO_HEIGHT,10,10); glPopMatrix(); } static void head() { GLfloat mat_diffusep[]={1.0, 0.8, 0.8, 1.0}; /* face */ glPushMatrix(); glTranslatef(0.0, 0.5*HEAD_HEIGHT,0.0); glScalef(HEAD_RADIUS, HEAD_HEIGHT, HEAD_RADIUS); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffusep); gluSphere(h,1.0,16,16); glPopMatrix(); } static void left_upper_arm() { GLfloat mat_diffuseg1[]={0.3, 1.0, 0.3, 1.0}; /* green1 */ glPushMatrix(); glRotatef( 0.0, 0.0, 1.0, 0.0); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseg1); gluCylinder(lua,UPPER_ARM_RADIUS, UPPER_ARM_RADIUS, UPPER_ARM_HEIGHT,10,10); glPopMatrix(); } static void left_lower_arm() { GLfloat mat_diffuseg2[]={0.6, 1.0, 0.6, 1.0}; /* green2 */ glPushMatrix(); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseg2); gluCylinder(lla,LOWER_ARM_RADIUS, LOWER_ARM_RADIUS, LOWER_ARM_HEIGHT,10,10); glPopMatrix(); } static void hand() { GLfloat mat_diffuseh[]={1.0, 0.9, 0.9, 1.0}; /* hand */ glPushMatrix(); glTranslatef(0.0, LOWER_ARM_HEIGHT, 0.0); glScalef(HAND_RADIUS, HAND_HEIGHT, HAND_RADIUS); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseh); gluSphere(han,1.0,16,16); glPopMatrix(); } static void right_upper_arm() { GLfloat mat_diffuseg1[]={0.3, 1.0, 0.3, 1.0}; /* green1 */ glPushMatrix(); glRotatef( 0.0, 0.0, 1.0, 0.0); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseg1); gluCylinder(rua,UPPER_ARM_RADIUS, UPPER_ARM_RADIUS, UPPER_ARM_HEIGHT,10,10); glPopMatrix(); } static void right_lower_arm() { GLfloat mat_diffuseg2[]={0.6, 1.0, 0.6, 1.0}; /* green2 */ glPushMatrix(); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseg2); gluCylinder(rla,LOWER_ARM_RADIUS, LOWER_ARM_RADIUS, LOWER_ARM_HEIGHT,10,10); glPopMatrix(); } static void left_upper_leg() { GLfloat mat_diffuseb2[]={0.3, 0.3, 1.0, 1.0}; /* blue2 */ glPushMatrix(); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseb2); gluCylinder(lul,UPPER_LEG_RADIUS, UPPER_LEG_RADIUS, UPPER_LEG_HEIGHT,10,10); glPopMatrix(); } static void left_lower_leg() { GLfloat mat_diffuseb1[]={0.5, 0.5, 1.0, 1.0}; /* blue1 */ glPushMatrix(); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseb1); gluCylinder(lll,LOWER_LEG_RADIUS, LOWER_LEG_RADIUS, LOWER_LEG_HEIGHT,10,10); glPopMatrix(); } static void foot() { GLfloat mat_diffusef[]={0.7, 0.7, 0.7, 1.0}; /* foot */ glPushMatrix(); glTranslatef(0.0, LOWER_LEG_HEIGHT, 0.0); glScalef(FOOT_RADIUS, FOOT_HEIGHT, 2.0*FOOT_RADIUS); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffusef); gluSphere(foo,1.0,16,16); glPopMatrix(); } static void right_upper_leg() { GLfloat mat_diffuseb2[]={0.3, 0.3, 1.0, 1.0}; /* blue2 */ glPushMatrix(); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseb2); gluCylinder(rul,UPPER_LEG_RADIUS, UPPER_LEG_RADIUS, UPPER_LEG_HEIGHT,10,10); glPopMatrix(); } static void right_lower_leg() { GLfloat mat_diffuseb1[]={0.5, 0.5, 1.0, 1.0}; /* blue */ glPushMatrix(); glRotatef(-90.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuseb1); gluCylinder(rll,LOWER_LEG_RADIUS, LOWER_LEG_RADIUS, LOWER_LEG_HEIGHT,10,10); glPopMatrix(); } static void instructions() { char * p; char msg[] = "middle mouse for menu selection"; char msg2[] = "then right or left click to move"; char msg3[] = "keyboard +, -, x, X, y, Y moves"; GLfloat blk[] = {0.0, 0.0, 0.0, 1.0}; glPushMatrix(); /* display instructions */ glLoadIdentity (); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, blk); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glTranslatef(-8.0, -7.5, 0.0); glScalef(size/150.0, size/150.0, 0.0); for(p=msg; *p; p++) glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); glLoadIdentity (); glTranslatef(-8.0, -8.5, 0.0); glScalef(size/150.0, size/150.0, 0.0); for(p=msg2; *p; p++) glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); glLoadIdentity (); glTranslatef(-8.0, -9.5, 0.0); glScalef(size/150.0, size/150.0, 0.0); for(p=msg3; *p; p++) glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); glPopMatrix(); } /* end instructions */ static void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); traverse(torso_ptr); /* render the robot */ instructions(); glFlush(); glutSwapBuffers(); } /* end display */ static void mouse(int btn, int state, int x, int y) { if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) { theta[angle] += movement; if( theta[angle] > 360.0 ) theta[angle] -= 360.0; } if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { theta[angle] -= movement; if( theta[angle] < 360.0 ) theta[angle] += 360.0; } move(); } /* end mouse */ static void move() { glPushMatrix(); switch(angle) { case TORSO_TURN : case TORSO_BEND : glLoadIdentity(); glRotatef(theta[TORSO_TURN], 0.0, 1.0, 0.0); glRotatef(theta[TORSO_BEND], 1.0, 0.0, 0.0); glTranslatef(rpos[0], rpos[1], rpos[2]); glGetFloatv(GL_MODELVIEW_MATRIX,torso_ptr->m); break; case HEAD_NOD : case HEAD_TURN : glLoadIdentity(); glTranslatef(0.0, TORSO_HEIGHT+0.5*HEAD_HEIGHT, 0.0); glRotatef(theta[HEAD_NOD], 1.0, 0.0, 0.0); glRotatef(theta[HEAD_TURN], 0.0, 1.0, 0.0); glTranslatef(0.0, -0.5*HEAD_HEIGHT, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,head_ptr->m); break; case LEFT_BALL_ARM : case LEFT_UPPER_ARM : glLoadIdentity(); glTranslatef(-(TORSO_RADIUS+UPPER_ARM_RADIUS), 0.9*TORSO_HEIGHT, 0.0); glRotatef(theta[LEFT_BALL_ARM], 0.0, 0.0, 1.0); glRotatef(theta[LEFT_UPPER_ARM], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lua_ptr->m); break; case RIGHT_BALL_ARM : case RIGHT_UPPER_ARM : glLoadIdentity(); glTranslatef(TORSO_RADIUS+UPPER_ARM_RADIUS, 0.9*TORSO_HEIGHT, 0.0); glRotatef(theta[RIGHT_BALL_ARM], 0.0, 0.0, 1.0); glRotatef(theta[RIGHT_UPPER_ARM], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,rua_ptr->m); break; case RIGHT_UPPER_LEG : glLoadIdentity(); glTranslatef(TORSO_RADIUS+UPPER_LEG_RADIUS, 0.1*UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[RIGHT_UPPER_LEG], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,rul_ptr->m); break; case LEFT_UPPER_LEG : glLoadIdentity(); glTranslatef(-(TORSO_RADIUS+UPPER_LEG_RADIUS), 0.1*UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[LEFT_UPPER_LEG], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lul_ptr->m); break; case LEFT_LOWER_ARM : glLoadIdentity(); glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0); glRotatef(theta[LEFT_LOWER_ARM], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lla_ptr->m); break; case LEFT_LOWER_LEG : glLoadIdentity(); glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[LEFT_LOWER_LEG], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lll_ptr->m); break; case RIGHT_LOWER_LEG : glLoadIdentity(); glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[RIGHT_LOWER_LEG], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,rll_ptr->m); break; case RIGHT_LOWER_ARM : glLoadIdentity(); glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0); glRotatef(theta[RIGHT_LOWER_ARM], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,rla_ptr->m); break; default : break; } glPopMatrix(); glutPostRedisplay(); } /* end move */ static void keyboard(unsigned char key, int x, int y) { switch (key) { case '+': theta[angle] += movement; if( theta[angle] > 360.0 ) theta[angle] -= 360.0; break; case '-': theta[angle] -= movement; if( theta[angle] < 360.0 ) theta[angle] += 360.0; break; case 'x': rpos[0] -= movement/10.0; angle=TORSO_TURN; break; case 'X': rpos[0] += movement/10.0; angle=TORSO_TURN; break; case 'y': rpos[1] -= movement/10.0; angle=TORSO_TURN; break; case 'Y': rpos[1] += movement/10.0; angle=TORSO_TURN; break; default : break; } move(); } /* end keyboard */ static void menu(int id) { if(id < INCREASE_MOVEMENT) angle=id; /* set up for next right or left mouse click */ else if(id == INCREASE_MOVEMENT) movement *= 1.5; else if(id == DECREASE_MOVEMENT) movement /= 1.5; else if(id == QUIT) exit(0); } /* end menu */ void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-10.0, 10.0, -10.0 * (GLfloat) h / (GLfloat) w, 10.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-10.0 * (GLfloat) w / (GLfloat) h, 10.0 * (GLfloat) w / (GLfloat) h, 0.0, 10.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* end myReshape */ static void myinit() { int i; GLfloat mat_specular[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_diffuse[]={1.0, 0.0, 0.0, 1.0}; /* red material*/ GLfloat mat_ambient[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_shininess={100.0}; GLfloat light_ambient[]={0.0, 0.0, 0.0, 1.0}; GLfloat light_diffuse[]={1.0, 1.0, 1.0, 1.0}; /* white light */ GLfloat light_specular[]={1.0, 1.0, 1.0, 1.0}; GLfloat light_position[]={10.0, 10.0, 10.0, 0.0}; for(i=0; i<17; i++) theta[i] = 0.0; theta[LEFT_UPPER_LEG] = 180.0; /* legs normally down */ theta[RIGHT_UPPER_LEG] = 180.0; glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); glShadeModel(GL_SMOOTH); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glClearColor(1.0, 1.0, 1.0, 1.0); glColor3f(1.0, 0.0, 0.0); /* allocate quadrics with filled drawing style */ h=gluNewQuadric(); /* head */ gluQuadricDrawStyle(h, GLU_FILL); han=gluNewQuadric(); /* hand */ gluQuadricDrawStyle(h, GLU_FILL); foo=gluNewQuadric(); /* foot */ gluQuadricDrawStyle(h, GLU_FILL); t=gluNewQuadric(); /* torso */ gluQuadricDrawStyle(t, GLU_FILL); lua=gluNewQuadric(); /* left upper arm, etc. */ gluQuadricDrawStyle(lua, GLU_FILL); lla=gluNewQuadric(); gluQuadricDrawStyle(lla, GLU_FILL); rua=gluNewQuadric(); gluQuadricDrawStyle(rua, GLU_FILL); rla=gluNewQuadric(); gluQuadricDrawStyle(rla, GLU_FILL); lul=gluNewQuadric(); gluQuadricDrawStyle(lul, GLU_FILL); lll=gluNewQuadric(); gluQuadricDrawStyle(lll, GLU_FILL); rul=gluNewQuadric(); gluQuadricDrawStyle(rul, GLU_FILL); rll=gluNewQuadric(); gluQuadricDrawStyle(rll, GLU_FILL); /* Set up tree */ torso_ptr = malloc(sizeof(treenode)); head_ptr = malloc(sizeof(treenode)); hand_ptr = malloc(sizeof(treenode)); /* leaf */ foot_ptr = malloc(sizeof(treenode)); /* leaf */ lua_ptr = malloc(sizeof(treenode)); rua_ptr = malloc(sizeof(treenode)); lll_ptr = malloc(sizeof(treenode)); rll_ptr = malloc(sizeof(treenode)); lla_ptr = malloc(sizeof(treenode)); rla_ptr = malloc(sizeof(treenode)); rul_ptr = malloc(sizeof(treenode)); lul_ptr = malloc(sizeof(treenode)); glLoadIdentity(); glRotatef(theta[TORSO_TURN], 0.0, 1.0, 0.0); glRotatef(theta[TORSO_BEND], 1.0, 1.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,torso_ptr->m); torso_ptr->f = torso; torso_ptr->sibling = NULL; torso_ptr->child = head_ptr; glLoadIdentity(); glTranslatef(0.0, TORSO_HEIGHT+0.5*HEAD_HEIGHT, 0.0); glRotatef(theta[HEAD_NOD], 1.0, 0.0, 0.0); glRotatef(theta[HEAD_TURN], 0.0, 1.0, 0.0); glTranslatef(0.0, -0.5*HEAD_HEIGHT, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,head_ptr->m); head_ptr->f = head; head_ptr->sibling = lua_ptr; head_ptr->child = NULL; glLoadIdentity(); glTranslatef(-(TORSO_RADIUS+UPPER_ARM_RADIUS), 0.9*TORSO_HEIGHT, 0.0); glRotatef(theta[LEFT_BALL_ARM], 0.0, 0.0, 1.0); glRotatef(theta[LEFT_UPPER_ARM], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lua_ptr->m); lua_ptr->f = left_upper_arm; lua_ptr->sibling = rua_ptr; lua_ptr->child = lla_ptr; glLoadIdentity(); glTranslatef(TORSO_RADIUS+UPPER_ARM_RADIUS, 0.9*TORSO_HEIGHT, 0.0); glRotatef(theta[RIGHT_BALL_ARM], 0.0, 0.0, 1.0); glRotatef(theta[RIGHT_UPPER_ARM], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,rua_ptr->m); rua_ptr->f = right_upper_arm; rua_ptr->sibling = lul_ptr; rua_ptr->child = rla_ptr; glLoadIdentity(); glTranslatef(-(TORSO_RADIUS+UPPER_LEG_RADIUS), 0.1*UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[LEFT_UPPER_LEG], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lul_ptr->m); lul_ptr->f = left_upper_leg; lul_ptr->sibling = rul_ptr; lul_ptr->child = lll_ptr; glLoadIdentity(); glTranslatef(TORSO_RADIUS+UPPER_LEG_RADIUS, 0.1*UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[RIGHT_UPPER_LEG], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,rul_ptr->m); rul_ptr->f = right_upper_leg; rul_ptr->sibling = NULL; rul_ptr->child = rll_ptr; glLoadIdentity(); glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0); glRotatef(theta[LEFT_LOWER_ARM], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lla_ptr->m); lla_ptr->f = left_lower_arm; lla_ptr->sibling = NULL; lla_ptr->child = hand_ptr; glLoadIdentity(); glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0); glRotatef(theta[RIGHT_LOWER_ARM], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,rla_ptr->m); rla_ptr->f = right_lower_arm; rla_ptr->sibling = NULL; rla_ptr->child = hand_ptr; glLoadIdentity(); glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[LEFT_LOWER_LEG], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,lll_ptr->m); lll_ptr->f = left_lower_leg; lll_ptr->sibling = NULL; lll_ptr->child = foot_ptr; glLoadIdentity(); glTranslatef(0.0, FOOT_HEIGHT, 0.0); glRotatef(0.0, 1.0, 0.0, 0.0); /* ? */ glGetFloatv(GL_MODELVIEW_MATRIX,foot_ptr->m); foot_ptr->f = foot; foot_ptr->sibling = NULL; foot_ptr->child = NULL; glLoadIdentity(); glTranslatef(0.0, HAND_HEIGHT, 0.0); glRotatef(0.0, 1.0, 0.0, 0.0); /* ? */ glGetFloatv(GL_MODELVIEW_MATRIX,hand_ptr->m); hand_ptr->f = hand; hand_ptr->sibling = NULL; hand_ptr->child = NULL; glLoadIdentity(); glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[RIGHT_LOWER_LEG], 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX,rll_ptr->m); rll_ptr->f = right_lower_leg; rll_ptr->sibling = NULL; rll_ptr->child = foot_ptr; glLoadIdentity(); } /* end myinit */ static int get_int(char buff[], int *i) { char num[15]; int j=0, k; if(buff[*i]=='\n') return -99; while(buff[*i]==' ') { (*i)++; } if(buff[*i]=='\n') return -99; while(buff[*i]!=' ') { num[j]=buff[*i]; j++; (*i)++; } num[j]='\0'; /* terminate string */ k= atoi(num); printf("get_int returns %d \n",k); return k; } /* end get_int */ static int get_mode(char buff[], int *i) { char num[15]; int j=0, k; if(buff[*i]=='\n') return -99; while(buff[*i]==' ') {(*i)++;} if(buff[*i]=='\n') return -99; while(buff[*i]!=' ' && buff[*i]!='\n') { num[j]=buff[*i]; j++; (*i)++; } k=-99; if(!strncmp("move",num,4)) k=0; if(!strncmp("end",num,3)) k=1; if(!strncmp("repeat",num,6)) k=2; printf("get_mode returns %d \n",k); return k; } /* end get_mode */ static int get_id(char buff[], int *i) { char num[15]; int j=0, k, m; num[1]=' '; num[2]=' '; if(buff[*i]=='\n') return -99; while(buff[*i]==' ') {(*i)++;} if(buff[*i]=='\n') return -99; while(buff[*i]!=' ') {num[j]=buff[*i]; j++; (*i)++;} for(k=0; k<=QUIT; k++) { if(!strncmp(ni[k].nm,num,3)) {m=ni[k].id; break;} } if(k==QUIT+1) { printf("BAD ID buff=%s \n", buff); /* exit(1); */ } printf("get_id returns %d \n",m); return m; } /* end get_id */ static float get_float(char buff[], int *i) { float x=0.0; int j; if(buff[*i]=='\n') return -99.0; while(buff[*i]==' ') {(*i)++;} if(buff[*i]=='\n') return -99.0; j=*i; while(buff[*i]!=' ') {(*i)++;} sscanf(&buff[j],"%f",&x); printf("get_float returns %f\n", x); return x; } /* end get_float */ static void parse(int* seq, int* mode, float* dt, float* dx, float*dy, int* nj, int* j, float* ang) { static int i; printf("enter parse i=%d, buf=%s \n", i, buf); while(buf[0]=='#') { fgets(buf, 99, inp); printf("fgets %s \n", buf); i=0; *nj=0; } if((*nj)>0) { /* process next j and ang */ printf("parse getting next j,ang \n"); (*nj)--; /* did one */ *j=get_id(buf, &i); *ang=get_float(buf, &i); return; } else { i=0; /* static, must be managed here */ } *seq=get_int(buf, &i); *mode=get_mode(buf, &i); *dt=get_float(buf, &i); *dx=get_float(buf, &i); *dy=get_float(buf, &i); *nj=get_int(buf, &i); (*nj)--; /* did one */ *j=get_id(buf, &i); *ang=get_float(buf, &i); printf("parse returns seq=%d, mode=%d, dt=%f, dx=%f, dy=%f, nj=%d, j=%d, ang=%f \n", *seq, *mode, *dt, *dx, *dy, *nj, *j, *ang); } /* end parse */ static void get_command(void) { int seq, mode, nj, id; float dt, dx, dy, ang; double t; wt=0.0; fgets(buf, 99, inp); printf("buf=%s", buf); nj=0; parse(&seq, &mode, &dt, &dx, &dy, &nj, &id, &ang); printf("about to do mode %d \n", mode); switch(mode) /* very little error checking */ { case MOVE: /* set theta[id]+=ang or rpos[0]+=dx rpos[1]+=dy */ angle=id; theta[angle]+=ang; rpos[0]+=dx; rpos[1]+=dy; move(); /* then this function gets called again, workproc */ glutPostRedisplay(); if((dx!=0.0 || dy!=0.0) && id!=TORSO_TURN && id!=TORSO_BEND) { angle=TORSO_TURN; move(); } break; case END: nj=0; glutPostRedisplay(); glutIdleFunc (NULL); break; case REPEAT: nj=0; break; default: nj=0; break; } while(nj>0) /* possibly more moves */ { parse(&seq, &mode, &dt, &dx, &dy, &nj, &id, &ang); angle=id; /* only nj, id and ang should change */ theta[angle]+=ang; move(); } glutPostRedisplay(); for(t=0.0; t