/* Extension of mobile.cc, added animation. You can control the speed of the animation with a command-line argument. */ #include #include // for atof #include float DeltaT = 1.0; // the speed/smoothness of the animation int WinSize = 512; bool Spinning = false; // whether we are spinning bool SaveFrames = false; // whether to save animation frames. //spin variables GLfloat octahedron=0; GLfloat teapot=0; GLfloat rightJoint3=0; GLfloat bear=0; GLfloat rightJoint2=0; GLfloat torus=0; GLfloat rightJoint1=0; GLfloat middleJoint=0; GLfloat icosahedron=0; GLfloat tetrahedron=0; GLfloat leftJoint3=0; GLfloat sphere=0; GLfloat leftJoint2=0; GLfloat barn=0; GLfloat leftJoint1=0; GLfloat part [15] = {octahedron,teapot,rightJoint3,bear,rightJoint2, torus,rightJoint1,middleJoint,icosahedron, tetrahedron,leftJoint3,sphere,leftJoint2,barn, leftJoint1}; GLfloat speeds [15] = {3,4,-5,3,2,5,-2,1,5,4,-3,2,1,-2,1}; //bounding box dimensions GLfloat width = 80; GLfloat height = 60; GLfloat depth2 = 5; // half the depth //bar lengths GLfloat bLength1=35; // length of first bar from top GLfloat bLength2=20; // length of second bar GLfloat bLength3=15; // length of third bar GLfloat bLength4=8; // length of fourth bar //string lengths GLfloat sLength1=10; // length of first string from top GLfloat sLength2=7; // length of second string GLfloat sLength3=15; // length of third string GLfloat sLength4=15; // length of fourth string //draws a "bar" of uniform height and width; takes length as a parameter void drawBar(GLfloat length) { glPushMatrix(); glTranslatef(-length/2,0,0); glRotatef(90,0,0,1); twTriple gray50 = {0.5, 0.5, 0.5}; twColor(gray50,0.7,100); //set color of bar twSolidCylinder(1,1,length,10,10); glPopMatrix(); } //draws a red string; takes length as parameter void drawString(GLfloat length) { glPushMatrix(); twTriple red = {1,0,0}; twColor(red,0,0); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,-length,0); glEnd(); glPopMatrix(); } //resizes twDrawBarn to appropriate dimension void drawBarn() { glPushMatrix(); glRotatef(75,0,1,0); glTranslatef(-2,-5.5,3); //translate so barn is centered at end of string glScalef(4,6,6); twTriple pink = {1, 0.7, 0.7}; twTriple red = {1, 0, 0}; twSolidBarn(pink, pink, red); glPopMatrix(); } void drawRightSide() { glPushMatrix(); glTranslatef((bLength1)/2,0,0); //translate to right end of first bar drawString(sLength1); //draw top right string glTranslatef(0,-sLength1,0); //translate to bottom of first string glRotatef(part[6],0,1,0); //rotation for rightJoint1 spin drawBar(bLength2); glPushMatrix(); //stores location after second bar is drawn glTranslatef((bLength2)/2,0,0); //translate to right end of second bar drawString(sLength2); glTranslatef(0,-sLength2,0); //translate to bottom of second string glRotatef(part[4],0,1,0); //rotation for rightJoint2 spin drawBar(bLength3); glPushMatrix(); //stores location after third bar is drawn glTranslatef((bLength3)/2,0,0); //translate to right end of third bar drawString(sLength3); glTranslatef(0,-sLength3,0); //translate to bottom of third string glRotatef(part[2],0,1,0); //rotation for rightJoint3 spin drawBar(bLength4); glPushMatrix(); //stores location after fourth bar is drawn glTranslatef((bLength4)/2,0,0); //translate to right end of fourth bar drawString(sLength4); glTranslatef(0,-sLength4,0); //translate to bottom of fourth string glRotatef(part[1],0,1,0); //rotation for teapot spin twTriple lightRed = {0.2,0.2,1}; twColor(lightRed,0.7,128); //set color for teapot glutSolidTeapot(1.5); /* TEAPOT */ glPopMatrix(); //return to middle of fourth bar glTranslatef((-bLength4)/2,0,0); drawString(sLength4); glTranslatef(0,-sLength4,0); twTriple orange = {1, 0.5, 0}; twColor(orange,0.6,70); //set color for octahedron glRotatef(part[0],0,1,0); //rotation for octahedron spin glScalef(2,2,2); glutSolidOctahedron(); /* OCTAHEDRON */ glPopMatrix(); //return to middle of third bar glTranslatef((-bLength3)/2,0,0); drawString(sLength3); glTranslatef(0,-sLength3,0); glRotatef(part[3],0,1,0); //rotation for bear spin glScalef(10,10,10); twTeddyBear(); /* BEAR */ glPopMatrix(); // return to middle of second bar glTranslatef((-bLength2)/2,0,0); drawString(sLength2); glTranslatef(0,-sLength2,0); twTriple darkYellow = {0.8, 0.8, 0}; twColor( darkYellow, 0.5, 100); glTranslatef(0,-3,0); //translate down the size of the torus's outer radius glRotatef(part[5],0,1,0); //rotation for torus spin glutSolidTorus(1,3,10,10); /* TORUS */ glPopMatrix(); } void drawLeftSide() { glPushMatrix(); glTranslatef((-bLength1)/2,0,0); //translate to left end of first bar drawString(sLength1); //draw top left string glTranslatef(0,-sLength1,0); //translate to bottom of first string glRotatef(part[14],0,1,0); //rotation for leftJoint1 spin drawBar(bLength2); glPushMatrix(); //stores location after second bar is drawn glTranslatef((-bLength2)/2,0,0); //translate to left end of second bar drawString(sLength2); glTranslatef(0,-sLength2,0); //translate to bottom of second string glRotatef(part[12],0,1,0); //rotation for leftJoint2 spin drawBar(bLength3); glPushMatrix(); //stores location after third bar is drawn glTranslatef((-bLength3)/2,0,0); //translate to left end of third bar drawString(sLength3); glTranslatef(0,-sLength3,0); //translate to bottom of third string glRotatef(part[10],0,1,0); //rotation for leftJoint3 spin drawBar(bLength4); glPushMatrix(); //stores location after fourth bar is drawn glTranslatef((-bLength4)/2,0,0); //translate to left end of fourth bar drawString(sLength4); glTranslatef(0,-sLength4,0); //translate to bottom of fourth string glRotatef(part[8],0,1,0); //rotation for icosahedron spin twTriple greenish = {0.2, 0.8, 0.2}; twColor(greenish,0.5,100); //set color for icosahedron glScalef(2,2,2); glutSolidIcosahedron(); /* ICOSAHEDRON */ glPopMatrix(); //return to middle of fourth bar glTranslatef((bLength4)/2,0,0); //translate to right end of fourth bar drawString(sLength4); glTranslatef(0,-sLength4,0); glRotatef(part[9],0,1,0); //rotation for tetrahedron spin twTriple darkPink = {0.5, 0, 0.5}; twColor(darkPink,0.5,100); //set color for tetrahedron glScalef(2,2,2); glutSolidTetrahedron(); /* TETRAHEDRON */ glPopMatrix(); //return to middle of third bar glTranslatef((bLength3)/2,0,0); //translate to right end of third bar drawString(sLength3); glTranslatef(0,-sLength3,0); twTriple darkBlueGreen = {0, 0.5, 0.5}; twColor( darkBlueGreen, 0.8, 128); glTranslatef(0,-2,0); //translate down the size of the radius of the sphere glRotatef(part[11],0,1,0); //rotation for sphere spin glutSolidSphere(3,20,20); /* SPHERE */ glPopMatrix(); // return to middle of second bar glTranslatef((bLength2)/2,0,0); //translate to right end of second bar drawString(sLength2); glTranslatef(0,-sLength2,0); glRotatef(part[13],0,1,0); //rotation for barn spin drawBarn(); /* BARN */ glPopMatrix(); } int FrameNumber = 1; void saveFrame() { char file[20]; sprintf(file, "MovingMobile%03d.ppm", FrameNumber++); twSaveFrame(WinSize, WinSize, file, 0); } void display(void) { twDisplayInit(); twCamera(); //sets up camera based on bounding box coords. GLfloat pos[] = {1,3,1,1}; twGrayLight(GL_LIGHT0, pos, 0.8, 0.8, 0.7); twAmbient(0.2); glPushMatrix(); glTranslatef(width/2,height,0); drawString(10); //top middle string glTranslatef(0,-10,0); glRotatef(part[7],0,1,0); //rotation for middleJoint spin drawBar(bLength1); //draw top bar drawRightSide(); drawLeftSide(); glPopMatrix(); glFlush(); glutSwapBuffers(); //necessary for animation if(SaveFrames) saveFrame(); } //idle callback for animation void spin() { int i; for(i=0;i<15;i++) { part[i]+=speeds[i]*DeltaT; if(part[i]>360) part[i]-=360; } glutPostRedisplay(); } void keys(unsigned char k, int, int) { switch (k) { case '1': SaveFrames = !SaveFrames; if(SaveFrames) FrameNumber = 1; break; case '2': Spinning = !Spinning; if(Spinning) glutIdleFunc(spin); else glutIdleFunc(NULL); break; case '3': spin(); break; } } int main(int argc, char** argv) { if( argc > 1 ) { DeltaT = atof(argv[1]); } glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(600,600); glutCreateWindow(argv[0]); twBoundingBox(0,width,0,height,-depth2,depth2); twMainInit(); twKeyCallback('1',keys,"toggle saving frames"); twKeyCallback('2',keys,"toggle spinning"); twKeyCallback('3',keys,"just one step"); glutDisplayFunc(display); glutMainLoop(); return 0; }