CPSC 324, Spring 2004
Lab 12: Object-Oriented Graphics
WE HAVE ALREADY LOOKED in class at the simple object-oriented hierarchical graphics system defined in Models.h. This lab is a tutorial on using this system to construct a model "solar system." You should complete this tutorial in lab and show me the result by the end of the lab. The exercise for the lab asks you to write a more complicated program using this system.
For this lab, you will need copies of the files Models.h, Models.cc, and starter.cc, which can be found in the directory /home/cs324/gl_models. This directory contains several sample programs that you can run, including car.cc and the corresponding compiled program car.
Exercise: Design a more complex animation based on Models.h/Models.cc. The animation that you create should be hierarchical. That is, it should have moving parts that are contained in other moving parts. One possibility is to create a mobile, as discussed in class. Turn in a printout of your program, and put screen shots of one or two frames from the animation on your Web site. (If you like, you can add a screen shot of your solar system, but that is not required.)
For the tutorial part of the lab, you will need copies of Models.cc, Models.h, and starter.cc. You will only have to edit starter.cc, which contains the main program. (You could rename starter.cc if you want.) To compile your program, you can saymesacomp -o solar_system starter.cc Models.cc
(or leave out the "-o solar_system" if you're happy with a program named "a.out"). You can run my solar system program, in /home/cs324/gl_models. Hit the "A" key to start and stop the animation. Other control keys are printed in the console window when you run the program from the command line.
Edit the main program, starter.cc. You will have to add a few global variables to this program, change the createWorld function that sets up the scene graph data structure, and change the animation in the timer function. You can follow the following steps to make your solar system:
Step 1: You will want to be able to animate the rotation of the moon around the earth and of the earth around the sun. In order to do this, you will need two variables of type Rotate*. Declare global variables of this type named moonRotate and sunRotate.
Step 2: In the createWorld method, you can delete the two lines that add a teapot and a light to the world. Also, the size of the model that you will be building is different from the one in the sample program, so delete the line "worldView->setViewEye(0,0,5);" near the end of the function and change the line that sets the view volume to "worldView->setViewVolume(-7,7,-7,7,-7,7)". Note that in this program, the parameters of setViewVolume are xmin, xmax, ymin, ymax, zmin, and zmax. These parameters determine a box around the view reference point. This is different from (and more convenient than) OpenGL, where you have to specify the near and far clipping planes with respect to the eye rather than with respect to the view reference point.
Step 3: There will be a sun at the center of the world. You can represent the sun with a yellow sphere. Since the sun emits light, you will want to use some emissive color. I also scaled up the sun by a factor of 1.5. You can add the sun to the world with one statement:world->addObject( (new BasicObject(SPHERE)) ->addTransform(new Scale(1.5)) ->setColor(0.3,0.3,0.3) ->setEmissiveColor(0.8,0.8,0.6) );
If you want the sun to actually cast light, you also need to put a Light at the same position as the sun. This light can simply be added to the world with the statement:world->addObject( (new Light(0,0,0,1)) ->setColor(.8,.8,.5) );
Step 4: The earth will go around the sun, and will carry the moon with it. The earth/moon system will be represented as a Model. Declare a variable named earth of type Model*, and set earth = new Model(). First, we will add the earth to this model:earth->addObject( (new BasicObject(SPHERE)) ->setColor(0.7,0.7,1) );
This puts the earth at the origin (inside the sun). We have to translate it away from the origin to the position of the earth's orbit. This can be done by adding a Translate transformation to the earth:earth->addTransform( new Translate(4,0,0) );
Furthermore, we want to be able to rotate the earth in its orbit. This can be done by adding a Rotate transformation to the earth after adding the translation. Because we will want to change the amount of rotation during the animation, use the global variable earthRotate for the rotation:earthRotate = new Rotate(0,0,1,0); earth->addTransformation( earthRotate );
If you compile and run the program at this point, you should see the sun in the center of the screen, with the earth a little off to its right. The sun should illuminate the side of the earth that faces it.
Step 5: To animate the earth, it's necessary to change the timer function. Take the lines out of this function that change the xWorldRotate and yWorldRotate values, and replace them with the line:earthRotate->setAngle( earthRotate->getAngle() + 2 );
This will make the earth rotate two degrees in each frame. If you run the program now, pressing the "A" key should make the earth go around the sun.
Step 6: Finally, make a moon that goes around the sun. Create the moon as a Model. This model should contain a small sphere and a light. Add these to the moon model in the same way as you added the sun to the world. You will then add the moon model to the earth in the same way that you added the earth to the world. That is, you have to apply a small translation to the moon to move it away from the origin. (I used a translation of 1.3 units in the x direction.) And you have to use the moonRotate variable to animate the rotation of the moon around the earth. Finally, update the moon rotation in the timer method by adding 15 degrees to the angle. If you did everything right, when you run the animation, you will see the moon going around the earth at the same time that the earth is going around the sun.
Note: I also modified the initial value of xWorldRotate so that a 15 degree rotation is applied to the world when the program first starts. If you don't do this, you will be viewing the solar system directly edge-on instead from a slight angle.