/* Sarah Abraham for Library Metal Gear Rex 11/6/05 #Added bezier surfaces to its feet, making them rounded 11/25/05 #Moved around some of the comments for convenience #Made the drawRex function take three color values as parameters This is based on the mech design Metal Gear Rex from the video game, Metal Gear Solid. */ GLUquadricObj *quadric; //this stores quadric objects, such as cylinders const float rexHeight = 4.5; //on y axis, from leg to head const float rexWidth = 3.5; //on x axis, from leg to leg const float rexLength = 5; //on z axis, from front to back const float legLength = rexLength/2; const float legWidth = rexWidth/3; //also torso width const float lowerlegHeight = rexHeight/5; const float upperlegHeight = rexHeight*0.4; const float torsoHeight = rexHeight*0.8; const float cockpitLength = rexLength*2/3; const float cockpitHeight = rexHeight*0.2; const float rightarmLength = rexLength*0.8; const float sixthWidth = rexWidth/6; //a conveniant proportion //this array contains the points of the bezier surface //used to round off the tips of the feet (used in feet function) static GLfloat curve[16][3] = { {-legWidth/2,-lowerlegHeight/2,legLength/2}, //bottom left point {-legWidth/2,-lowerlegHeight/4,legLength/2}, //bottom left side {-legWidth/2,lowerlegHeight/4,legLength/2}, //top left side {-legWidth/2,lowerlegHeight/2,legLength/2}, //top left point {-legWidth/4,-lowerlegHeight/2,legLength/2}, //bottom left curve {-legWidth/2,-lowerlegHeight/2,legLength*1.5}, //bottom left interior {-legWidth/2,0,legLength*1.5}, //top left interior {-legWidth/4,lowerlegHeight/2,legLength/2}, //top left curve {legWidth/4,-lowerlegHeight/2,legLength/2}, //bottom right curve {legWidth/2,-lowerlegHeight/2,legLength*1.5}, //bottom right interior {legWidth/2,0,legLength*1.5}, //top right interior {legWidth/4,lowerlegHeight/2,legLength/2}, //top right curve {legWidth/2,-lowerlegHeight/2,legLength/2}, //bottom right point {legWidth/2,-lowerlegHeight/4,legLength/2}, //bottom right side {legWidth/2,lowerlegHeight/4,legLength/2}, //top right side {legWidth/2,lowerlegHeight/2,legLength/2}, //top right point }; static void feet(int nsteps, GLfloat* cp) { //This draws the rounded tips on the lower legs. Used in drawlowerLeg. glMap2f(GL_MAP2_VERTEX_3,0,1,3,4,0,1,12,4,cp); glEnable(GL_MAP2_VERTEX_3); glEnable(GL_AUTO_NORMAL); glMapGrid2f(nsteps,0,1,nsteps,0,1); glEvalMesh2(GL_FILL,0,nsteps,0,nsteps); } static void drawlowerLeg(float angle, int x, int y, int z) { //This draws the lower legs. Angle not reset glRotatef(angle,x,y,z); glPushMatrix(); glScalef(legWidth,lowerlegHeight,legLength); glutSolidCube(1); glPopMatrix(); //give the mech cute little footsies. feet(8,curve[0]); } static void drawlegConnector() { //Draws "joint" between lower and upper leg. Translation is reset //it turns out this isn't needed as a separate function, but I'm //keeping it anyway. glPushMatrix(); glTranslatef(0,lowerlegHeight/2,-legLength/2); glutSolidSphere(legWidth/2,20,20); glPopMatrix(); } static void drawupperLeg(float angle, int x, int y, int z) { //This draws the upper legs. Angle and scaling reset after function glPushMatrix(); glRotatef(angle,x,y,z); glScalef(legWidth/1.5,upperlegHeight/2.5,legLength/1.5); glutSolidSphere(1,20,20); glPopMatrix(); } static void drawEllipsoid(float x, float y, float z) { //Creates circles with dimensions defined by x, y and z. Scaling reset glPushMatrix(); glScalef(x,y,z); glutSolidSphere(1,20,20); glPopMatrix(); } void sabrahamRex (twTriple main, twTriple light, twTriple dark) { /* This command draws the actual mech. Takes three twTriples as parameters, which represent the main, light and dark colorings of the mech. -Origin at bottom right corner of its right lower leg. -Rex Size (estimated): Height > 4.5, Width > 3.5, Length < 9 Here is a listing of the parts as referred to in the coding: Lower Right Leg - right leg, bottom part that touches ground Right Leg Extension - back part of right leg that also touches ground Upper Right Leg - right leg, upper part that connects to torso Lower Left Leg - left leg, bottom part that touches ground Upper Left Leg - left leg, upper part that connects to torso Bottom Torso - lower part of torso, where legs connect Upper Torso - upper part of torso, where arms and head connect Right Arm - actually just an incredibly big gun on right side Left Arm - nuke launcher on left side Head - cockpit, placed in the middle of the upper torso */ quadric = gluNewQuadric(); //initializes "quadric" gluQuadricNormals(quadric, GLU_SMOOTH); //makes them smooth shaded glPushMatrix(); //this translate positions the origin at the bottom right corner //of the right lower leg glTranslatef(legWidth/2,sin(15)*legLength/2,cos(15)*legLength/2); twColor(main,0.5,200); //draw right leg glPushMatrix(); drawlowerLeg(15,1,0,0); glPushMatrix(); //creates right leg extension glTranslatef(0,legWidth/2,-legLength/2); glRotatef(90,1,0,0); gluCylinder(quadric,legWidth/2, legWidth/4,sin(15)*legLength,20,20); glTranslatef(0,0,sin(15)*legLength); gluDisk(quadric,0,legWidth/4,20,20); glPopMatrix(); glTranslatef(0,upperlegHeight/2,-legLength/2); twColor(light,0.7,210); drawupperLeg(-15,1,0,0); glPopMatrix(); //draw left leg //begin with point reset to (0,0,0) twColor(main,0.5,200); glPushMatrix(); glTranslatef(legWidth*2,0,0); drawlowerLeg(15,1,0,0); drawlegConnector(); glTranslatef(0,upperlegHeight/2,-legLength/2); twColor(light,0.7,210); drawupperLeg(-15,1,0,0); glPopMatrix(); //draw torso //begin with point reset to (0,0,0) twColor(dark,0.3,150); glTranslatef(legWidth,upperlegHeight/1.5,-legLength/1.7); glPushMatrix(); glScalef(rexWidth,sixthWidth,sixthWidth); glutSolidCube(1); //creates cross beam, connecting legs glPopMatrix(); glPushMatrix(); //this creates spheres on the ends of the cross beam glTranslatef(rexWidth/2,0,0); glutSolidSphere(sixthWidth/2,20,20); glTranslatef(-rexWidth,0,0); glutSolidSphere(sixthWidth/2,20,20); glPopMatrix(); //returns to center of mech's cross beam glPushMatrix(); //creates protrusion on bottom torso glTranslatef(0,0,legLength/4); drawEllipsoid(legWidth/2,upperlegHeight/4,legLength/4); //creates protrusion on upper torso glTranslatef(0,torsoHeight/4,legLength/4); drawEllipsoid(legWidth/2,upperlegHeight/4,legLength/4); glPopMatrix(); //still in center of mech's cross beam, draw main body twColor(main,0.5,200); glPushMatrix(); glTranslatef(0,sixthWidth,0); glRotatef(45,1,0,0); glPushMatrix(); glScalef(legWidth,torsoHeight,legLength/2); glutSolidCube(1); glPopMatrix(); //still rotated by 45 degrees glTranslatef(0,torsoHeight/2,0); drawEllipsoid(legWidth/2,legWidth/2,legLength/4); glPopMatrix(); glTranslatef(0,torsoHeight/1.7,cos(45)*torsoHeight); //draw head //begin around center of top of torso glRotatef(20,1,0,0); glPushMatrix(); glScalef(legWidth,cockpitHeight,cockpitLength); glutSolidCube(1); glPopMatrix(); twColor(main,0.5,200); glPushMatrix(); glScalef(rexWidth,cockpitHeight/1.3,cockpitLength/3); glutSolidCube(1); //creates frame that connects cockpit to the arms glPopMatrix(); //draw the left arm twColor(light,0.7,210); glTranslatef(rexWidth/2,cockpitHeight/2,0); gluCylinder(quadric,sixthWidth,sixthWidth,cockpitLength/3,20,20); glTranslatef(0,0,0); gluDisk(quadric,0,sixthWidth,20,20); //back of left arm //these create the inside parts of the left arm glTranslatef(0,0,cockpitLength/4); twColor(dark,0.3,150); gluDisk(quadric,0,sixthWidth,20,20); gluCylinder(quadric,sixthWidth/2,sixthWidth/2,cockpitLength/12,20,20); glTranslatef(0,0,cockpitLength/12); twColor(light,0.7,210); gluDisk(quadric,sixthWidth/2,sixthWidth,20,20); //draw right arm //begin around center of top of torso, rotated at 20 degrees on x axis glTranslatef(-rexWidth,-cockpitHeight/4,0); glPushMatrix(); //draws butt of rail gun glRotatef(90,0,0,1); glScalef(rexWidth/4,cockpitHeight/2,rightarmLength/2); glutSolidCube(1); glPopMatrix(); glTranslatef(0,cockpitHeight/4,0); //aligns for barrel of gun glPushMatrix(); //this pushMatrix is for drawing the barrel gluCylinder(quadric,cockpitHeight/5,cockpitHeight/5,rightarmLength,20,20); glTranslatef(0,0,rightarmLength); gluDisk(quadric,cockpitHeight/10,cockpitHeight/5,20,20); twColor(dark,0.3,150); glTranslatef(0,0,-rightarmLength/2); gluCylinder(quadric,cockpitHeight/10,cockpitHeight/10,rightarmLength/2,20,20); gluDisk(quadric,0,cockpitHeight/5,20,20); glPopMatrix(); twColor(light,0.7,210); glTranslatef(0,-cockpitHeight/3,0); //aligns for bottom barrel gluCylinder(quadric,cockpitHeight/7,cockpitHeight/7,rightarmLength/1.3,20,20); glTranslatef(0,0,rightarmLength/1.3); gluDisk(quadric,0,cockpitHeight/7,20,20); glPopMatrix(); }