In this project you will implement a scenegraph for hierarchical models. You will also implement a simple geometry class to store a variety of models. This project has several parts. We recommend doing this assignment in the order as listed below, which will make debugging easier for you.
Base Code: proj3.zip
This project will build upon the previous assignment's code. First, be sure to make a copy of your previous assignment.
Files from Proj 1: matrix.h, vector.h, matrix.cpp, vector.cpp, core.h
Files from Proj 2: color.h
New files: geometry.h, geometry.cpp, geomtypes.h, geomtypes.cpp, light.h, light.cpp, main.cpp, openglrenderer.cpp, renderer.h, scenegraph.h, scenegraph.cpp, objfile.h, objfile.cpp
For this assignment you will modify the following files: openglrenderer.cpp, scenegraph.cpp, geomtypes.cpp, main.cpp.
Start this project by implementing the OpenGLRenderer::DrawModel function. This function takes in a pointer to a geometry node, which it renders using OpenGL commands. Geometry nodes are described as a list of vertices, normals and colors, as well as a list of triangles which contain indices to their respective vertices, normals, and colors. Use GL_TRIANGLES as the GL primitive. Every triangle specifies 3 vertices. Render normals for each vertex if the model provides them. If the model contains colors, render those as well on a per vertex basis.
An ObjFile geometry class has also been provided for you, as well as a snippet of test code in the drawScene function in main.cpp. Just uncomment these few lines and you should see a spinning model, provided OpenGLRenderer::DrawModel is implemented correctly.
Fill in the few functions in the scenegraph.cpp file to complete the scenegraph classes. These are fairly simple to implement, but are powerful tools which we'll use to create hierarchical models
Next, in order to render the scene graph, the OpenGLRenderer class, a subclass of Renderer, implements the Render function. It renders the scene it is passed hierarchically. Fill in the OpenGLRenderer::DrawNode function which recursively draws the nodes of the scenegraph. Hierarhically traverse the scenegraph, pushing transforms as they appear, and rendering geometry found in ShapeNodes. When you're finished, you should see the robot model below, spinning in a circle.
Note: The children of each node are implemented using a NodeList, which is constructed from a Stack template. You don't have to be familiar with templates, just think of the NodeList as any other class. The key functions to know are Push(), Size() and Get(i).
In the geomtypes.cpp file, fill in the Sphere constructor. Tesselate the a sphere using the provided theta (which define slices of latitude) and phi slices (slices along lines of longitude), and with the correct radius. The sin and cos functions will be extremely helpful here. It may help to look at the Cube constructor in the same file, to get a good idea of how to initialize a Geometry model. Note that the Cube class does not implement any colors, and consequently will appear black unless you push a color before rendering. Your Sphere can do the same, or specify colors if you wish. When you're through, replace the head of the robot with a sphere.
At the bottom of the main function in main.cpp there are an additional two root nodes. The 's' key toggles between these 3 root scenes: a Robot, your solar system, and a scene of your design. For this last part, you will re-implement your solar system using the scenegraph (just the sun, earth, and moon; you can leave out the Hubble). You will also create a hierarchically based scene of your own. The scene should contain at least one animating object, like a spinning chair. The animation shouldn't leave the field of view of the camera. Below are some suggestions: