Project2Fall13

From Immersive Visualization Lab Wiki
Jump to: navigation, search

Contents

Project 2: Viewing 3D Models

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 models files and display them with your viewer. The third, optional part requires building a very simple flight simulator.

This assignment is due on Friday, October 11th, but can be graded at any time before by demonstrating it to a TA or tutor in their office hours. Note that the office hours have changed since last week!

The project will be discussed by TA Krishna on Monday, October 7th at 3pm in Center Hall 105.

1. The Camera Matrix (40 Points)

1a. Creating the Camera Matrix (20 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 (5 points).

Add a method called something like getGLMatrix to your camera class to access the components of the camera matrix C as an array of 16 values of type GLdouble in the order OpenGL expects them (column-major). Note that many of your Matrix4 classes use row-major order. You will need this method in part 1b. If your camera matrix already stores the matrix components in column-major order, you do not need to do a conversion but can directly pass the pointer to the matrix array instead. (5 points)

1b. Testing (20 Points)

As a basis you can 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).

Update: If you can, please add the house to your existing software application and support keyboard keys to switch to it (eg, F8 and F9, which are not used in part 2 of this project).

Set OpenGL's projection matrix as it was in the Cube example from assignment 1 with the following code in GLUT's Reshape callback function:

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glFrustum(-10.0, 10.0, -10.0, 10.0, 10, 1000.0);
  glTranslatef(0, 0, -20);

In your GLUT Display callback, set OpenGL's model-view matrix to your camera matrix C. Do not use the gluLookAt function in this homework assignment (this is a one time exception).

  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

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.

House1-half.png House2-half.png
Image 1 Image 2

2. Displaying 3D Models from Files (60 points)

The OBJ file format is a very simple ASCII text based file format for triangle meshes. In its basic form, an OBJ file contains a list of triangle vertices indicated by the letter v, followed by an array of indices to form triangles indicated by the letter f. We provide a C++ class that reads OBJ files. Add this code to your rendering engine. You need to write the necessary code to create OpenGL geometry out of the 3D data structure (20 points). Make the individual polygons of the object visible by using two or more different colors (alternating or random) for different triangles (not all adjacent polygons need to have different colors). (5 points)

Add support for keyboard commands to select and switch between one of five .obj 3D model files. The following 3D models are available for download. Map each of them to one of the keys 'F2' through 'F6'. 'F1' should display the cube like in homework project 1. If you created a soccer ball in homework project 1, you can put it on the 'F7' key and no longer need to support the 'b' key. The two houses from part 1 of this assignment should be accessible through keys 'F8' and 'F9'. You also need to support the rest of the keyboard commands like in the first homework project. Just like the cube, the 3D models need to constantly slowly spin about their up axis. (10 points)

Here are the 3D models:

Note that in addition to glutKeyboardFunc, you will need to use glutSpecialFunc to parse the Function keys. There are pre-defined constants for them, they are GLUT_KEY_F1 through GLUT_KEY_F6.

You will notice that without further processing, the objects in the OBJ files may be too small or too large for your rendering window. To render the objects as large as possible while still completely fitting in the OpenGL window, use the following approach:

  • Calculate the minimum and maximum vertex coordinates in all three dimensions by writing three 'for' loops which traverse all vertices, one for each dimension (x,y,z), storing the smallest and largest values they come across. Display these six values in the console window. (5 points)
  • Your window origin is (0,0,0), so you are going to have to translate the model towards it if its center point is not also the model's origin. Calculate the amount of translation required and create a translation matrix to center the object within the OpenGL window. Show this translation matrix in the console window (5 points)
  • Find out approximately what size objects your rendering window allows, for instance by drawing the sphere model (which is one unit wide) and scaling it up or down until it fits in the window. Based on the amount of scaling necessary, you need to create a uniform scale matrix, which scales the object so that it renders as large as possible in the window, without exceeding the window size. Show this scale matrix in the console window. (5 points)

Allow the user to trigger this "full screen" algorithm by pressing the 'f' key. (5 points)

Make your code robust enough that the user can use the supported key commands in any order (5 points).


3. Optional Project: Height Map (10 points)

Generate and display a 3D mesh out of a 2D height map image. Wikipedia has a great description of this topic. Allow the user to interactively fly over the height map, similar to a simple flight simulator. You can use the height map image from the Wikipedia page, which you will also find below, or create your own with a paint program or another method of your choice.

Heightmap.png
Height map image from Wikipedia

To get full credit you need to implement the following features:

  • Load the height map image and create a 3D mesh out of it. You can either read the Wikipedia PNG image file with your own reader, or read this PGM image file with this piece of C code. Note that this code returns a one dimensional array, which you have to interpret as a two-dimensional array based on the width of the image. Add the mesh to your 3D viewer and allow switching to it with the 'F8' key ('F7' is for the soccer ball if you have it). (5 points)
  • Color the terrain polygons in blue (water), yellow (sand), green (grass), grey (rock) or white (snow), depending on their height. Feel free to add more colors as you see fit. (2 points).
  • Add support for an airplane flight mode, in which the user can use the cursor keys to rotate the camera left or right and tilt it up or down, and change the velocity of the flight ('-' for slower, '=' for faster) (3 points).

If you use the Wikipedia height map, the resulting terrain should look similar to this, except that it needs to be colored as described above:

Heightmap rendered.png
3D terrain generated from height map