//Fly around a drawer containing a gun and a levitating color cube // 09/21/01 //Needs the header scene_demo_2.h //All the implementations are included in this file. //The navigation is explained in the function nav_kbd // #include #include #include #include "scene_demo_2.h" GLUquadricObj *p; // Pointer for quadric objects void myinit(); void display(); void idle(); void nav_kbd(unsigned char key, int x, int y); //navigation routine int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(700,700); glutInitWindowPosition(0,0); glutCreateWindow("Toy box"); glutKeyboardFunc(nav_kbd); glutDisplayFunc(display); myinit(); glutMainLoop(); return 0; } void myinit() { glEnable(GL_DEPTH_TEST); glClearColor(1.0,1.0,1.0,0.0); //creates a qudraic object for the cylindric components of the gun //see page 486ff of the Red book p = gluNewQuadric(); gluQuadricDrawStyle(p, GLU_FILL); //Initial CTM setup glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-5.0,5.0,-5.0,5.0,-5.0,5.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); cout << "Depth motion (along the world Z axis)" << endl; cout << "Press y to move forward (i.e. in the -Z direction)" << endl; cout << "Press b to move backward(i.e. in the +Z direction)\n" << endl; cout << "Lateral motion (along the world X axis)" << endl; cout << "Press h to move in the +X direction" << endl; cout << "Press g to move in the -X direction\n" << endl; cout << "Change of altitude (motion along the world Y axis)" << endl; cout << "Press u to go up" << endl; cout << "Press j to go down\n" << endl; cout << "\n\nPress the spacebar to return to default position\n\n" << endl; cout << " May the Scwartz be with you\n" << endl; } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Viewing transformation //position and orient the camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(viewer[0],viewer[1],viewer[2],0,0,0,0,1,0); //Modeling: //draw walls walls(); //draw color cube glPushMatrix(); glTranslated(CUBE_POSX, CUBE_POSY, CUBE_POSZ); glScalef(CUBE_SCALE, CUBE_SCALE, CUBE_SCALE); cubedraw(); glPopMatrix(); //draw a gun glTranslatef(GUN_POSX, GUN_POSY, GUN_POSZ); glRotatef(GUN_ORIENT, 0,1,0); glScalef(GUN_SCALE, GUN_SCALE, GUN_SCALE); draw_gun(); glFlush(); glutSwapBuffers(); } //navigation via the keyboard callback. //Note that we have selected initial view point, and that // the moves (for example, forward and back ) are along the world coord. axis, // which does not coincide sithe the camera frame, on the other hand the camera // always points at 0,0,0, thus we percieve rotational motion void nav_kbd(unsigned char key, int x, int y) { if (key == 'y') viewer[2] -=0.05; //forwrd if (key == 'b') viewer[2] +=0.05; //back if (key == 'g') viewer[0] -=0.05; //left if (key == 'h') viewer[0] +=0.05; //right if (key == 'j') viewer[1] -=0.05;//down if (key == 'u') viewer[1] +=0.05; //up if (key == ' ') { viewer[0] =1.0; viewer[1] =1.2; //return to initial view point viewer[2] =1.2; } glutPostRedisplay(); } //cube drwaing functions void quad(int a, int b, int c, int d) { glBegin(GL_QUADS); glColor3fv(colors[a]); glVertex3fv(vertices[a]); glColor3fv(colors[b]); glVertex3fv(vertices[b]); glColor3fv(colors[c]); glVertex3fv(vertices[c]); glColor3fv(colors[d]); glVertex3fv(vertices[d]); glEnd(); glBegin(GL_LINE_LOOP); glColor3f(0,0,0); glVertex3fv(vertices[a]); glVertex3fv(vertices[b]); glVertex3fv(vertices[c]); glVertex3fv(vertices[d]); glEnd(); } void cubedraw() { quad(0,3,2,1); quad(2,3,5,6); quad(0,4,7,1); quad(1,2,6,7); quad(4,5,6,7); quad(0,3,5,4); } //wall functions // draw a horizontal wall (floor) of given thickness and color (red, green, // or gray). // the lower-bottom corner of the wall is at the origin, the wall is // alligned with the coordinate axis: the wall thickness is along the y axes // void wall(double thickness, char col) { glPushMatrix(); if (col == 'r') glColor3f(1,0,0); else if (col == 'g') glColor3f(0,1,0); else glColor3f(0.6,0.6,0.6); glTranslated(0.5,0.5*thickness, 0.5); // position wall with corner at origin glScaled(1.0,thickness, 1.0); // scale in the "thickness" dimension glutSolidCube(1.0); glPopMatrix(); } // draw the three sides of the box (floor and 2 side walls) void walls() { glPushMatrix(); glPushAttrib(GL_COLOR); //draw floor glPushMatrix(); glTranslated(-1.1,-2,-1.1); glScalef(3,1,3); wall(0.02,'b'); glPopMatrix(); //draw sidewall glPushMatrix(); glTranslated(-1.1,0,-1.1); glScalef(12,1,3.0); glTranslated(0,-2,0); glRotatef(90,0,0,1); wall(0.002,'g'); glPopMatrix(); //draw backwall glTranslated(-1.1,-2,-1.1); glScalef(3,1,1); glRotatef(-90,1,0,0); glScalef(1,6,1); wall(0.02,'r'); glPopMatrix(); glPopAttrib(); } //gun // The tree hierarchy for the gun is as follows // // gun // --------------|--------------------- // | | // |R1 | T2*R2 // cart base barrel // ------------------ -------- // / T3 |T4 \T5 /T6 \Id // cyllinder disk disk cyllinder disk // // The local coordiante systems for the primitives are as follows (See red book pp489-490): // -a disk is centered at the origin at x-y plane (i.e. plane, z=0) // -a cyllinder is an "open" cylinder. It has its base in the x-y, plane, it is // standing up in positive z direction, with z axis as its axis of symmetry // // For the rest of the models the local coordiante systems are as follow // -The cart base consists of a narrow cylinder with two wheels (disks) at both ends. // The local coordiante system for the cart has the origin at the middle of the cyllinder, // and the z axis is the axis of symmetry for the cylinder. // // -The barrel consists of a cyllinder with a disk stuck inside it, 3/4 length from the // base of the barrel. // The origin of the local coordinate system is the center of the disk, with z axis // being the axis of symmetry of the cylinder // // - The gun consists of cart base and a barrel. The origin of the cart base coinsides with // the origin of the disk stuck in the barrel (see descriprions of the parts). // The gun is facing +Z, and up is +Y. The cart base is horizontal (parallel // to xz plane),facing frontally (perpendicular to z axis), The barrel is parralel to // zy-plane, pointing 45 degrees up. The the local coordinate sustem for the // gun is the origin of the cart base, the x axis is the axis of symmetry for the // cart base . // void draw_gun() { // isolate gun instance glPushMatrix(); glPushAttrib(GL_COLOR); // go along left brunch of the tree, from root glPushMatrix(); glRotatef(90,0,1,0); // R1, allign cart rod with x axis // draw cart base glPushMatrix(); glTranslatef(0,0,-BASE_ROD_LEN/2); // T3 glColor3f(0.4, 0.4, 0.4); gluCylinder(p, BASE_ROD_RAD, BASE_ROD_RAD, BASE_ROD_LEN, 10, 1); glPopMatrix(); glPushMatrix(); glColor3f(0.0, 0.0, 0.0); glTranslatef(0.0, 0.0, -BASE_ROD_LEN/2); //T4 gluDisk(p, 0.0, WHEEL_RAD, 20, 5); glPopMatrix(); glTranslatef(0.0, 0.0, BASE_ROD_LEN/2); //T5 gluDisk(p, 0.0, WHEEL_RAD, 20, 5); glPopMatrix(); // now about to start right brunch of tree from root //Barrel glRotatef(-45.0, 1.0, 0.0, 0.0); // point barrel up glColor3f(0.1, 0.1, 0.2); gluDisk(p, 0.0, BARREL_RAD, 25, 5); glTranslatef(0.0,0.0,-0.25*BARREL_LEN); // T6 glColor3f(0.0, 0.0, 1.0); gluCylinder(p, BARREL_RAD, BARREL_RAD, BARREL_LEN, 10, 12); glPopMatrix(); glPopAttrib(); }