Project2SP15
Contents |
Project 2: Viewing 3D Scenes
This homework assignment consists of three parts, but only the first two are mandatory to get full credit (100 points). In the first part you will need to implement camera matrices and apply them to a simple scene. In the second part you will need to load 3D model files and display them in your viewer. In the third, optional part you are asked to add additional features.
This assignment is due on Friday, April 10th at 12 noon and needs to be presented to the course staff on the due date.
The project will be discussed on Monday, April 6th at 4pm in CSB 004.
1. The Camera Matrix (50 Points)
1a. Creating the Camera Matrix (25 Points)
As described in the lecture slides, create a camera class Camera with member variables for a 'center of projection' e, a 'look at point' d, and an 'up vector' up (10 points). The class should have an internal camera matrix C, derived from e, d and up (15 points).
1b. Testing (25 Points)
As a basis use your source code from last week. We provide source code to generate a simple scene with a house to test your camera matrix implementation. Add this code to render the house (10 points).
Make sure the OpenGL's projection matrix is set as it was in the Cube example from assignment 1.
In your GLUT Display callback, set OpenGL's model-view matrix to your camera matrix C:
glMatrixMode(GL_MODELVIEW); glLoadMatrixf(camera.getCameraMatrix().getValues());
Render two images of the scene using these two sets of parameters for your camera matrix:
- Image 1:
- Center of projection: 0, 10, 10
- Look at point: 0, 0, 0
- Up vector 0, 1, 0
- Image 2:
- Center of projection: -15, 5, 10
- Look at point: -5, 0, 0
- Up vector 0, 1, 0.5
Add the house to your existing software application and support keyboard keys 'F2' and 'F3' to switch to it. 'F1' should show the cube from project 1. (5 points)
Compare your implementation to the correct result images shown below. If you can accurately re-create the images you will receive 5 points for each image. Note that you need to set OpenGL's lighting to 'off' with glDisable(GL_LIGHTING) to match your results.
Image 1 | Image 2 |
Notes:
- Do not use the gluLookAt function in this homework assignment (you can use it in future projects).
- In addition to glutKeyboardFunc, you will need to use glutSpecialFunc to parse the Function keys. There are pre-defined constants for them, they are named GLUT_KEY_F1 through GLUT_KEY_F12.
2. 3D Model Loader (50 Points)
OBJ files are 3D model files which store the shape of an object with a number of vertices, associated vertex normals, and connectivity information to form triangles. Wikipedia has excellent information on the OBJ file format. The file format is an ASCII text format, which means that the files can be viewed and edited with a any text editor, such as Notepad.
Here are three files for you to work with:
The files provided in this project only use the following three data types (other OBJ files may support more):
- v: 'vertex': followed by six floating point numbers. The first three are for the vertex position (x,y,z coordinate), the next three are for the vertex color (red, green, blue) ranging from 0 to 1. Example:
v 0.145852 0.104651 0.517576 0.2 0.8 0.4
- vn: 'vertex normal': three floating point numbers, separated by white space. The numbers are for a vector which is used as the normal for a triangle. Example:
vn -0.380694 3.839313 4.956321
- f: 'face': lists three sets of indices to vertices and normals, which are the three corners of a triangle. Example:
f 31514//31514 31465//31465 31464//31464
Lines starting with a '#' sign are comments and can safely be ignored.
Write your parser so that it goes through the OBJ file, line by line. It should read in the first character of each line and based on it decide how to proceed. Lines with parameters can be read with the fscanf command. Here is an example for vertices:
FILE* fp; // file pointer float x,y,z; // vertex coordinates float r,g,b; // vertex color int c1,c2; // characters read from file fp = fopen("bunny.obj","rb"); if (fp==NULL) { cerr << "error loading file" << endl; exit(-1); } c1 = fgetc(fp); c2 = fgetc(fp); if (c1=='v') && (c2==' ') fscanf(fp, "%f %f %f %f %f %f", &x, &y, &z, &r, &g, &b); // parse other cases and loop over lines of file fclose(fp); // make sure you don't forget to close the file when done
The starter code at the GitHub repository has been updated with a new Drawable class for OBJ files, which may help you get started on the creation of the OBJ loader.
Use function keys F4, F5 and F6 to load the three models, respectively.
Once a model file has been loaded, the following keyboard commands to manipulate the cube from project 1 should work with it: x/X, y/Y, z/Z, o/O, s/S, r.
Grading:
- -10 if only one data set loads
- -10 if the normals are incorrect
- -10 if the triangle mesh is incorrect
- -2 for each keyboard command from project 1 that doesn't work
3. Optional: Improvements (10 Points)
We offer two options for additional credit. Each counts as 5 points, but they build on each other - you need to implement option 1 first before implementing option 2.
1. Allow loading multiple data sets at once: when one of the OBJ models is loaded when there already is one of the other three models displayed, the displayed model should remain where it is, and the new model should load into the center of the window.
The most recently loaded model should be the selected one, which means that it can be moved around. You need to implement a way to highlight the selected model (examples: wireframe box around it, change the color of its polygons, make it blink).
2. Control the camera with keyboard commands: allow zooming in on the objects, changing the location of the camera, and changing its orientation. You can use function key F7 to switch to camera control mode, then use the usual keyboard commands to move the camera around.