/* ====================================================== */ /* HIERARCHY */ /* ====================================================== */ #include "glut.h" #include "matrix.h" #include "materials.h" #include "forwardKinematics.h" #include "geometry.h" #include /* --------------------------------------------------------------------------- */ /* PROTOTYPES */ void draw_upperrightarm(); void draw_upperleftarm(); void draw_lowerarm(); void draw_upperleg(); void draw_lowerleg(); void draw_foot(); void draw_segment(); void draw_torso(); void draw_head(); void draw_pelvis(); void traverse(link_td *linkPtr); /* --------------------------------------------------------------------------- */ /* GLOBALS */ node_td *torso; node_td *neck,*head; node_td *right_upperarm,*right_lowerarm; node_td *left_upperarm,*left_lowerarm; node_td *right_upper_leg,*left_upper_leg; node_td *right_lower_leg,*left_lower_leg; node_td *left_foot,*right_foot; link_td *rootLink; link_td *neck_base,*head_base; link_td *right_shoulder,*right_elbow; link_td *left_shoulder,*left_elbow; link_td *right_hip,*right_knee; link_td *left_hip,*left_knee; link_td *left_ankle,*right_ankle; float right_shoulder_angle,right_elbow_angle; float left_shoulder_angle,left_elbow_angle; float right_shoulder_pos_limit,right_elbow_pos_limit; float right_shoulder_neg_limit,right_elbow_neg_limit; float left_shoulder_pos_limit,left_elbow_pos_limit; float left_shoulder_neg_limit,left_elbow_neg_limit; float right_shoulder_delta,right_elbow_delta; float left_shoulder_delta,left_elbow_delta; float right_hip_angle,right_knee_angle; float left_hip_angle,left_knee_angle; float right_hip_pos_limit,right_knee_pos_limit; float right_hip_neg_limit,right_knee_neg_limit; float left_hip_pos_limit,left_knee_pos_limit; float left_hip_neg_limit,left_knee_neg_limit; float right_hip_delta,right_knee_delta; float left_hip_delta,left_knee_delta; float right_ankle_delta,left_ankle_delta; float right_ankle_pos_limit,left_ankle_pos_limit; float right_ankle_neg_limit,left_ankle_neg_limit; float right_ankle_angle,left_ankle_angle; float neck_base_angle,head_base_angle; float neck_base_pos_limit,head_base_pos_limit; float neck_base_neg_limit,head_base_neg_limit; float neck_base_delta,head_base_delta; char *redPlasticMaterial = "redPlasticMaterial"; char *greenPlasticMaterial = "greenPlasticMaterial"; char *bluePlasticMaterial = "bluePlasticMaterial"; char *yellowPlasticMaterial = "yellowPlasticMaterial"; char *whiteShinyMaterial = "whiteShinyMaterial"; /* --------------------------------------------------------------------------- */ /* SETUP HIERARCHY */ /* --------------------------------------------------------------------------- */ void *setupHierarchy() { // int i; rootLink = (link_td *)malloc(sizeof(link_td)); torso = (node_td *)malloc(sizeof(node_td)); right_hip = (link_td *)malloc(sizeof(link_td)); right_upper_leg = (node_td *)malloc(sizeof(node_td)); right_knee = (link_td *)malloc(sizeof(link_td)); right_lower_leg = (node_td *)malloc(sizeof(node_td)); left_hip = (link_td *)malloc(sizeof(link_td)); left_upper_leg = (node_td *)malloc(sizeof(node_td)); left_knee = (link_td *)malloc(sizeof(link_td)); left_lower_leg = (node_td *)malloc(sizeof(node_td)); neck_base = (link_td *)malloc(sizeof(link_td)); neck = (node_td *)malloc(sizeof(node_td)); head_base = (link_td *)malloc(sizeof(link_td)); head = (node_td *)malloc(sizeof(node_td)); right_shoulder = (link_td *)malloc(sizeof(link_td)); right_upperarm = (node_td *)malloc(sizeof(node_td)); right_elbow = (link_td *)malloc(sizeof(link_td)); right_lowerarm = (node_td *)malloc(sizeof(node_td)); left_shoulder = (link_td *)malloc(sizeof(link_td)); left_upperarm = (node_td *)malloc(sizeof(node_td)); left_elbow = (link_td *)malloc(sizeof(link_td)); left_lowerarm = (node_td *)malloc(sizeof(node_td)); left_ankle = (link_td *)malloc(sizeof(link_td)); right_ankle = (link_td *)malloc(sizeof(link_td)); left_foot = (node_td *)malloc(sizeof(node_td)); right_foot = (node_td *)malloc(sizeof(node_td)); // TORSO // global link to torso rootLink->nodePtr = torso; // controls the torso rootLink->linkPtr = NULL; // no siblings matrix_set_identity(rootLink->articulator); matrix_set_translate(rootLink->locator,0.0,0.0,0.0); // bends at the bottom // torso node torso->linkPtr = neck_base; // first link is right arm matrix_set_identity(torso->shape); // shape the torso torso->materialPtr = redPlasticMaterial; torso->dataPtr = draw_torso; // from a cube for now // HEAD // neck base link neck_base->nodePtr = neck; // controls the rt upper arm neck_base->linkPtr = right_shoulder; // sibling of left arm matrix_set_translate(neck_base->locator,0.0,1.0,0.0); // put on torso matrix_set_identity(neck_base->articulator); // set to no bend // neck node neck->linkPtr = head_base; matrix_set_scale(neck->shape,0.0625,0.25,0.0625); // shape the torso matrix_concatenate_translate(neck->shape,0.0,0.25,0.0); neck->materialPtr = yellowPlasticMaterial; neck->dataPtr = draw_cube; // from a cube for now // head base link head_base->nodePtr = head; // controls the head head_base->linkPtr = NULL; matrix_set_translate(head_base->locator,0.0,0.25,0.0); // put on torso matrix_set_identity(head_base->articulator); // set to no bend // head node head->linkPtr = NULL; matrix_set_identity(head->shape); // shape the torso head->materialPtr = yellowPlasticMaterial; head->dataPtr = draw_head; // from a cube for now // RIGHT ARM // right shoulder link right_shoulder->nodePtr = right_upperarm; // controls the rt upper arm right_shoulder->linkPtr = left_shoulder; // sibling of left arm matrix_set_translate(right_shoulder->locator,-0.3,1.0,0.0); // put on torso matrix_set_identity(right_shoulder->articulator); // set to no bend // right upper arm node right_upperarm->linkPtr = right_elbow; // first, only link is elbow matrix_set_identity(right_upperarm->shape); // shape the upper arm right_upperarm->materialPtr = redPlasticMaterial; right_upperarm->dataPtr = draw_upperrightarm; // right elbow link right_elbow->nodePtr = right_lowerarm; // controls the lower arm right_elbow->linkPtr = NULL; // no sibling links matrix_set_translate(right_elbow->locator,0.0,-0.5,0.0); // locate wrt upper arm matrix_set_identity(right_elbow->articulator); // set to no bend // right lower arm node right_lowerarm->linkPtr = NULL; // nothing further for now matrix_set_identity(right_lowerarm->shape); // shape the upper arm right_lowerarm->materialPtr = redPlasticMaterial; right_lowerarm->dataPtr = draw_lowerarm; // from a cube for now // LEFT ARM // left shoulder link left_shoulder->nodePtr =left_upperarm; // controls the lft upper arm left_shoulder->linkPtr = right_hip; // no siblings matrix_set_translate(left_shoulder->locator,0.3,1.0,0.0); // locate wrt torso matrix_set_identity(left_shoulder->articulator); // no bend for now // left upper arm node left_upperarm->linkPtr = left_elbow; // first, only link is elbow matrix_set_identity(left_upperarm->shape); // shape the upper arm left_upperarm->materialPtr = redPlasticMaterial; left_upperarm->dataPtr = draw_upperleftarm; // from cube for now // left elbow link left_elbow->nodePtr = left_lowerarm; // controls the lower arm left_elbow->linkPtr = NULL; // no siblings matrix_set_translate(left_elbow->locator,0.0,-0.5,0.0); // locate wrt upper arm matrix_set_identity(left_elbow->articulator); // no bend for now // left lower arm node left_lowerarm->linkPtr = NULL; // nother further for now matrix_set_identity(left_lowerarm->shape); // shape the upper arm left_lowerarm->materialPtr = redPlasticMaterial; left_lowerarm->dataPtr = draw_lowerarm; // from a cube for now // RIGHT LEG // right hip link right_hip->nodePtr = right_upper_leg; // controls the lower arm right_hip->linkPtr = left_hip; // sibling matrix_set_translate(right_hip->locator,-0.1,0.0,0.0); // locate wrt torso matrix_set_identity(right_hip->articulator); // no bend for now // right upper leg node right_upper_leg->linkPtr = right_knee; // nother further for now matrix_set_identity(right_upper_leg->shape); // shape the lower arm right_upper_leg->materialPtr = bluePlasticMaterial; right_upper_leg->dataPtr = draw_upperleg; // from a cube for now // right knee link right_knee->nodePtr = right_lower_leg; // controls the lower arm right_knee->linkPtr = NULL; // sibling matrix_set_translate(right_knee->locator,0.0,-1.0,0.0); // locate wrt upper arm matrix_set_identity(right_knee->articulator); // no bend for now // right lower leg node right_lower_leg->linkPtr = right_ankle; // nother further for now matrix_set_identity(right_lower_leg->shape); // shape the lower arm right_lower_leg->materialPtr = bluePlasticMaterial; right_lower_leg->dataPtr = draw_lowerleg; // from a cube for now // right ankle link right_ankle->nodePtr = right_foot; // controls the lower arm right_ankle->linkPtr = NULL; // sibling matrix_set_translate(right_ankle->locator,0.0,-0.5,0.0); // locate wrt upper arm matrix_set_identity(right_ankle->articulator); // no bend for now // right foot node right_foot->linkPtr = NULL; // nother further for now matrix_set_identity(right_foot->shape); // shape the lower arm right_foot->materialPtr = bluePlasticMaterial; right_foot->dataPtr = draw_foot; // from a cube for now // LEFT LEG // left hip link left_hip->nodePtr = left_upper_leg; // controls the lower arm left_hip->linkPtr = NULL; // no siblings matrix_set_translate(left_hip->locator,0.1,0.0,0.0); // locate wrt upper arm matrix_set_identity(left_hip->articulator); // no bend for now // left upper leg node left_upper_leg->linkPtr = left_knee; // link bellow matrix_set_identity(left_upper_leg->shape); // shape the lower arm left_upper_leg->materialPtr = bluePlasticMaterial; left_upper_leg->dataPtr = draw_upperleg; // from a cube for now // left knee link left_knee->nodePtr = left_lower_leg; // controls the lower arm left_knee->linkPtr = NULL; // sibling matrix_set_translate(left_knee->locator,0.0,-1.0,0.0); // locate wrt upper arm matrix_set_identity(left_knee->articulator); // no bend for now // left lower leg node left_lower_leg->linkPtr = left_ankle; // nother further for now matrix_set_identity(left_lower_leg->shape); // shape the lower arm left_lower_leg->materialPtr = bluePlasticMaterial; left_lower_leg->dataPtr = draw_lowerleg; // from a cube for now // left ankle link left_ankle->nodePtr = left_foot; // controls the lower arm left_ankle->linkPtr = NULL; // sibling matrix_set_translate(left_ankle->locator,0.0,-0.5,0.0); // locate wrt upper arm matrix_set_identity(left_ankle->articulator); // no bend for now // left foot node left_foot->linkPtr = NULL; // nother further for now matrix_set_identity(left_foot->shape); // shape the lower arm left_foot->materialPtr = bluePlasticMaterial; left_foot->dataPtr = draw_foot; // from a cube for now // SET UP ANIMATION PARAMETERS right_shoulder_pos_limit = 50.0; right_shoulder_neg_limit = -10.0; right_shoulder_delta = 1.0; right_shoulder_angle = (right_shoulder_neg_limit + right_shoulder_pos_limit)/2; right_elbow_pos_limit = 60.0; right_elbow_neg_limit = 0.0; right_elbow_delta = 1.0; right_elbow_angle = (right_elbow_pos_limit+right_elbow_neg_limit)/2; left_shoulder_pos_limit = 55.0; left_shoulder_neg_limit = -10.0; left_shoulder_delta = 1.0; left_shoulder_angle = (left_shoulder_pos_limit+left_shoulder_neg_limit)/2; left_elbow_pos_limit = 65.0; left_elbow_neg_limit = 0.0; left_elbow_delta = 1.0; left_elbow_angle = (left_elbow_pos_limit+left_elbow_neg_limit)/2; right_hip_pos_limit = 30.0; right_hip_neg_limit = -30.0; right_hip_delta = 1.0; right_hip_angle = (right_hip_neg_limit + right_hip_pos_limit)/2; right_knee_pos_limit = 0.0; right_knee_neg_limit = -30.0; right_knee_delta = 0.5; right_knee_angle = (right_knee_neg_limit + right_knee_pos_limit)/2; right_ankle_pos_limit = 30.0; right_ankle_neg_limit = -30.0; right_ankle_delta = 1.0; right_ankle_angle = (right_ankle_neg_limit + right_ankle_pos_limit)/2; left_hip_pos_limit = 30.0; left_hip_neg_limit = -30.0; left_hip_delta = -1.0; left_hip_angle = (left_hip_neg_limit + left_hip_pos_limit)/2; left_knee_pos_limit = 0.0; left_knee_neg_limit = -30.0; left_knee_delta = -0.5; left_knee_angle = (left_knee_neg_limit + left_knee_pos_limit)/2; left_ankle_pos_limit = 30.0; left_ankle_neg_limit = -30.0; left_ankle_delta = -1.0; left_ankle_angle = (left_ankle_neg_limit + left_ankle_pos_limit)/2; neck_base_pos_limit = 10.0; neck_base_neg_limit = -25.0; neck_base_delta = -0.5; neck_base_angle = (neck_base_neg_limit + neck_base_pos_limit)/2; head_base_pos_limit = 45.0; head_base_neg_limit = -40.0; head_base_delta = -1.5; head_base_angle = (head_base_neg_limit + head_base_pos_limit)/2; // set up display list for head glNewList(2, GL_COMPILE); glPushMatrix(); glTranslatef(0.0,0.25,0.0); glRotatef(-20.0,1.0,0.0,0.0); glScalef(0.2,0.3,0.2); glBegin(GL_POLYGON); glVertex3f(0.0,0.5,0.0); glVertex3f(0.0,0.0,1.75); glVertex3f(0.5,0.0,0.0); glEnd(); glBegin(GL_POLYGON); glVertex3f(0.0,0.0,1.75); glVertex3f(0.0,0.5,0.0); glVertex3f(-0.5,0.0,0.0); glEnd(); glBegin(GL_POLYGON); glVertex3f(0.0,0.0,1.75); glVertex3f(0.5,0.0,0.0); glVertex3f(-0.5,0.0,0.0); glEnd(); draw_sphere(SMOOTH,4); glPopMatrix(); glEndList(); return(rootLink); } /* --------------------------------------------------------------------------- */ /* TRAVERSE HIERARCHY */ /* --------------------------------------------------------------------------- */ void traverse_hierarchy() { traverse(rootLink); } /* --------------------------------------------------------------------------- */ /* TRAVERSE HIERARCHY */ /* --------------------------------------------------------------------------- */ void traverse(link_td *linkPtr) { node_td *nodePtr; link_td *nextlinkPtr; glMultMatrixf(linkPtr->locator); glMultMatrixf(linkPtr->articulator); nodePtr = linkPtr->nodePtr; glPushMatrix(); glMultMatrixf(nodePtr->shape); set_material(nodePtr->materialPtr); nodePtr->dataPtr(); glPopMatrix(); if (nodePtr->linkPtr != NULL) { nextlinkPtr = nodePtr->linkPtr; while (nextlinkPtr != NULL) { glPushMatrix(); traverse(nextlinkPtr); glPopMatrix(); nextlinkPtr = nextlinkPtr->linkPtr; } } } /* --------------------------------------------------------------------------- */ /* UPDATE HIERARCHY */ /* --------------------------------------------------------------------------- */ void animate_hierarchy() { if ( (right_shoulder_angle >= right_shoulder_pos_limit) || (right_shoulder_angle <= right_shoulder_neg_limit) ) { right_shoulder_delta = -right_shoulder_delta; } right_shoulder_angle += right_shoulder_delta; if ( (right_elbow_angle >= right_elbow_pos_limit) || (right_elbow_angle <= right_elbow_neg_limit) ) { right_elbow_delta = -right_elbow_delta; } right_elbow_angle += right_elbow_delta; if ( (left_shoulder_angle >= left_shoulder_pos_limit) || (left_shoulder_angle <= left_shoulder_neg_limit) ) { left_shoulder_delta = -left_shoulder_delta; } left_shoulder_angle += left_shoulder_delta; if ( (left_elbow_angle >= left_elbow_pos_limit) || (left_elbow_angle <= left_elbow_neg_limit) ) { left_elbow_delta = -left_elbow_delta; } left_elbow_angle += left_elbow_delta; if ( (left_hip_angle >= left_hip_pos_limit) || (left_hip_angle <= left_hip_neg_limit) ) { left_hip_delta = -left_hip_delta; } left_hip_angle += left_hip_delta; if ( (left_knee_angle >= left_knee_pos_limit) || (left_knee_angle <= left_knee_neg_limit) ) { left_knee_delta = -left_knee_delta; } left_knee_angle += left_knee_delta; if ( (left_ankle_angle >= left_ankle_pos_limit) || (left_ankle_angle <= left_ankle_neg_limit) ) { left_ankle_delta = -left_ankle_delta; } left_ankle_angle += left_ankle_delta; if ( (right_hip_angle >= right_hip_pos_limit) || (right_hip_angle <= right_hip_neg_limit) ) { right_hip_delta = -right_hip_delta; } right_hip_angle += right_hip_delta; if ( (right_knee_angle >= right_knee_pos_limit) || (right_knee_angle <= right_knee_neg_limit) ) { right_knee_delta = -right_knee_delta; } right_knee_angle += right_knee_delta; if ( (right_ankle_angle >= right_ankle_pos_limit) || (right_ankle_angle <= right_ankle_neg_limit) ) { right_ankle_delta = -right_ankle_delta; } right_ankle_angle += right_ankle_delta; if ( (neck_base_angle >= neck_base_pos_limit) || (neck_base_angle <= neck_base_neg_limit) ) { neck_base_delta = -neck_base_delta; } neck_base_angle += neck_base_delta; if ( (head_base_angle >= head_base_pos_limit) || (head_base_angle <= head_base_neg_limit) ) { head_base_delta = -head_base_delta; } head_base_angle += head_base_delta; matrix_set_x_rotate(right_shoulder->articulator,-right_shoulder_angle); matrix_set_x_rotate(right_elbow->articulator,-right_elbow_angle); matrix_set_x_rotate(left_shoulder->articulator,-left_shoulder_angle); matrix_set_x_rotate(left_elbow->articulator,-left_elbow_angle); matrix_set_x_rotate(left_hip->articulator,-left_hip_angle); matrix_set_x_rotate(left_knee->articulator,-left_knee_angle); matrix_set_x_rotate(left_ankle->articulator,-left_ankle_angle); matrix_set_x_rotate(right_hip->articulator,-right_hip_angle); matrix_set_x_rotate(right_knee->articulator,-right_knee_angle); matrix_set_x_rotate(right_ankle->articulator,-right_ankle_angle); matrix_set_x_rotate(neck_base->articulator,-neck_base_angle); matrix_set_y_rotate(head_base->articulator,-head_base_angle); } /* --------------------------------------------------------------------------- */ /* DRAW UPPERARM */ /* --------------------------------------------------------------------------- */ void draw_upperrightarm() { glPushMatrix(); glScalef(0.0625,0.25,0.0625); glTranslatef(0.0,-1.0,0.0); glPushMatrix(); glTranslatef(0.5,0.7,0.0); glScalef(1.6,0.5,1.5); draw_sphere(SMOOTH,4); glPopMatrix(); draw_cylinder(SMOOTH,16); glPopMatrix(); } /* --------------------------------------------------------------------------- */ /* DRAW UPPERARM */ /* --------------------------------------------------------------------------- */ void draw_upperleftarm() { glPushMatrix(); glScalef(0.0625,0.25,0.0625); glTranslatef(0.0,-1.0,0.0); glPushMatrix(); glTranslatef(-0.5,0.7,0.0); glScalef(1.6,0.5,1.5); draw_sphere(SMOOTH,4); glPopMatrix(); draw_cylinder(SMOOTH,16); glPopMatrix(); } /* --------------------------------------------------------------------------- */ /* DRAW LOWERARM */ /* --------------------------------------------------------------------------- */ void draw_lowerarm() { glPushMatrix(); glScalef(0.0625,0.25,0.0625); glTranslatef(0.0,-1.0,0.0); glPushMatrix(); glTranslatef(0.0,1.0,0.0); glScalef(1.1,0.3,1.1); draw_sphere(SMOOTH,4); glPopMatrix(); draw_cylinder(SMOOTH,16); glTranslatef(0.0,-1.0,0.0); glScalef(0.6,0.6,0.6); draw_cube(); glPopMatrix(); } /* --------------------------------------------------------------------------- */ /* DRAW SEGMENT */ /* --------------------------------------------------------------------------- */ void draw_segment() { glPushMatrix(); glScalef(0.0625,0.25,0.0625); glTranslatef(0.0,-1.0,0.0); glPushMatrix(); glTranslatef(0.0,1.0,0.0); glScalef(1.5,0.5,1.5); draw_sphere(SMOOTH,4); glPopMatrix(); draw_cylinder(SMOOTH,16); glPopMatrix(); } /* --------------------------------------------------------------------------- */ /* DRAW UPPERLEG */ /* --------------------------------------------------------------------------- */ void draw_upperleg() { glPushMatrix(); glScalef(0.1,0.5,0.08); glTranslatef(0.0,-1.0,-0.3); glPushMatrix(); glTranslatef(0.0,1.0,0.0); glScalef(1.4,0.4,1.4); draw_sphere(SMOOTH,4); glPopMatrix(); draw_cylinder(SMOOTH,16); glPopMatrix(); } /* --------------------------------------------------------------------------- */ /* DRAW LOWERLEG */ /* --------------------------------------------------------------------------- */ void draw_lowerleg() { glPushMatrix(); glScalef(0.1,0.3,0.08); glTranslatef(0.0,-1.0,0.0); glPushMatrix(); glTranslatef(0.0,1.0,0.0); glScalef(1.1,0.2,1.2); draw_sphere(SMOOTH,4); glPopMatrix(); draw_cylinder(SMOOTH,16); glPopMatrix(); } /* --------------------------------------------------------------------------- */ /* DRAW FOOT */ /* --------------------------------------------------------------------------- */ void draw_foot() { glPushMatrix(); glScalef(0.2,0.2,0.4); glTranslatef(0.0,-1.0,0.0); draw_tetrahedron(); glPopMatrix(); } /* --------------------------------------------------------------------------- */ /* DRAW TORS0 */ /* --------------------------------------------------------------------------- */ void draw_torso() { glPushMatrix(); glScalef(0.25,0.5,0.13); glTranslatef(0.0,1.0,0.0); draw_cylinder(SMOOTH,16); glTranslatef(0.0,0.75,0.0); glScalef(1.4,0.5,0.9); draw_sphere(SMOOTH,4); glPopMatrix(); } /* --------------------------------------------------------------------------- */ /* DRAW HEAD */ /* --------------------------------------------------------------------------- */ void draw_head() { glCallList(2); /* glPushMatrix(); glTranslatef(0.0,0.25,0.0); glRotatef(-20.0,1.0,0.0,0.0); glScalef(0.25,0.35,0.25); glBegin(GL_POLYGON); glVertex3f(0.0,0.5,0.0); glVertex3f(0.0,0.0,1.75); glVertex3f(0.5,0.0,0.0); glEnd(); glBegin(GL_POLYGON); glVertex3f(0.0,0.0,1.75); glVertex3f(0.0,0.5,0.0); glVertex3f(-0.5,0.0,0.0); glEnd(); glBegin(GL_POLYGON); glVertex3f(0.0,0.0,1.75); glVertex3f(0.5,0.0,0.0); glVertex3f(-0.5,0.0,0.0); glEnd(); draw_sphere(SMOOTH,4); glPopMatrix(); */ }