Project2Fall14

From Immersive Visualization Lab Wiki
Revision as of 01:12, 18 October 2014 by Jschulze (Talk | contribs)

Jump to: navigation, search

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 point clouds and display them with your viewer. In the third, optional part you will be asked to improve the visual quality of your point clouds.

This assignment is due on Friday, October 24th at 3:30pm and needs to be presented to the course staff on the due date.

The project will be discussed by the TAs on Monday, October 20th at 5pm in Peterson Hall 102.

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 (10 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 (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).

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). (5 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());

Do not use the gluLookAt function in this homework assignment (this is a one time exception).

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. 3D Point Clouds from Files (50 Points)

The XYZ file format is a very simple ASCII text-based file format for unsorted collections of 3D points. An XYZ file does not have a header, it only consists of a list of point locations, optionally with color or normals. In this exercise we are going to use a point cloud with normals. The first two lines of the file look like this:

-0.037830 0.127940 0.004475 1.223420 6.106969 -0.789864 
-0.044779 0.128887 0.001905 1.351736 5.963559 -1.435807 

The example defines two points. The points are separated by a line break. Within each line are six floating point numbers. The first three are the x, y, and z position of the point, respectively. The next three numbers are the normal's x, y, and z positions.

Write a parser for XYZ files with normals. It should be a simple for loop in which you read each line from the file, for instance with the fscanf command. Your parser does not need to do any error handling - we will assume that we are dealing with proper XYZ files. Add the parser to your code from project 1.

Use your parser to load these point cloud files from Stanford's 3D scanning repository:

Next you need to write the code to display the point cloud. Let us inspire you with this pseudo-code:

glBegin(GL_POINTS);
  for (loop over all points)
  {
    glNormal3d(normal[n].x, normal[n].y, normal[n].z);
    glVertex3d(position[n].x, position[n].y, position[n].z);
  }
glEnd();

Add support for keyboard commands to switch to the point models when the user presses the 'F10' and 'F11' keys. You also need to support at least the keyboard commands for rotation and scale from the first homework project. (10 points)

You can use glPointSize to change the size (in pixels) of a point.

If you want to make the points round instead of square, you can use the following code:

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_POINT_SMOOTH);
  glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

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 the point models will not adequately fill your rendering window when they load. To render the models as large as possible without exceeding the OpenGL window, use the following approach:

  • Calculate the minimum and maximum point 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 and scale the model up or down until it nicely fills 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)

Apply this algorithm whenever you load a point model.