Difference between revisions of "Project2Fall11"
(→2. Virtual Trackball (50 points)) |
(→2. Virtual Trackball (50 points)) |
||
(18 intermediate revisions by one user not shown) | |||
Line 5: | Line 5: | ||
The fourth part is optional. We make suggestions for how to extend your solution with additional features. You can get extra credit for completing those. | The fourth part is optional. We make suggestions for how to extend your solution with additional features. You can get extra credit for completing those. | ||
− | This project is due on <b>Friday October 7, 2011</b>. The assignment will be introduced by TA Jorge on <b>Monday, October 3rd at 3pm</b> in lab | + | This project is due on <b>Friday October 7, 2011</b>. The assignment will be introduced by TA Jorge on <b>Monday, October 3rd at 3pm</b> in lab 250. |
==1. Camera and View Frustum== | ==1. Camera and View Frustum== | ||
Line 17: | Line 17: | ||
Create a class <tt>Frustum</tt> which defines a projection matrix of type <tt>Matrix4</tt>. Create a class method to generate the projection matrix from a <i>near plane</i> <tt>near</tt>, <i>far plane</i> <tt>far</tt>, <i>aspect ratio</i> <tt>aspect</tt>, and a <i>vertical field of view</i> <tt>fov</tt> (<b>6 points</b>). This matrix is referred to in the lecture slides by the name <tt>Ppersp</tt>. Add a method to set OpenGL's projection matrix <tt>GL_PROJECTION</tt> from the class internal projection matrix (<b>4 points</b>). | Create a class <tt>Frustum</tt> which defines a projection matrix of type <tt>Matrix4</tt>. Create a class method to generate the projection matrix from a <i>near plane</i> <tt>near</tt>, <i>far plane</i> <tt>far</tt>, <i>aspect ratio</i> <tt>aspect</tt>, and a <i>vertical field of view</i> <tt>fov</tt> (<b>6 points</b>). This matrix is referred to in the lecture slides by the name <tt>Ppersp</tt>. Add a method to set OpenGL's projection matrix <tt>GL_PROJECTION</tt> from the class internal projection matrix (<b>4 points</b>). | ||
− | <b>Note</b>: Do not use <tt>gluPerspective</tt> or <tt>glFrustum</tt> to implement the projection matrix, but use the equations from the lecture slides instead. | + | <b>Note</b>: Do not use <tt>gluPerspective</tt> or <tt>glFrustum</tt> to implement the projection matrix, but use the equations from the lecture slides instead, and load projection matrix into OpenGL with <tt>glMatrixMode(GL_PROJECTION); glLoadMatrixd(Persp);</tt>. |
===1c. Testing (10 points)=== | ===1c. Testing (10 points)=== | ||
− | We provide [[house.cpp|source code]] | + | We provide [[house.cpp|source code]] to generate a simple scene to test your implementation. Set the object transformation matrix (model matrix) to the identity matrix and render two images of the scene using these two sets of parameters: |
* Image 1: | * Image 1: | ||
Line 38: | Line 38: | ||
** Up vector 0, 1, 0 | ** Up vector 0, 1, 0 | ||
− | Compare your implementation to the test images shown below (<b>5 points</b> for each image). | + | Compare your implementation to the test images shown below (<b>5 points</b> for each image). Note that the images below were rendered with lighting off (<tt>glDisable(GL_LIGHTING)</tt>). |
<table> | <table> | ||
<tr> | <tr> | ||
Line 51: | Line 51: | ||
==2. Virtual Trackball (50 points)== | ==2. Virtual Trackball (50 points)== | ||
− | Implement a <i>virtual trackball</i> that allows a user to rotate an object interactively using the mouse. Your solution should translate clicking and dragging of the mouse into a rotation matrix, which you then use to transform the scene. Rotations around all three coordinate axes should be supported. A sample executable which demonstrates the trackball functionality is available for [[Media: | + | Implement a <i>virtual trackball</i> that allows a user to rotate an object interactively using the mouse. Your solution should translate clicking and dragging of the mouse into a rotation matrix, which you then use to transform the scene. Rotations around all three coordinate axes should be supported. A sample executable which demonstrates the trackball functionality is available for [[Media:trackball.zip|Windows]] and [[Media:trackball-linux.bin|Linux]]. If the executable does not work on your computer, here is a [[Media:cube.mpg|video of it.]] To access the mouse coordinates, you will need to use GLUT's callback functions [http://www.opengl.org/resources/libraries/glut/spec3/node50.html glutMouseFunc()] and [http://www.opengl.org/resources/libraries/glut/spec3/node51.html glutMotionFunc()]. Note that successive trackball rotations must build on the previous ones; at no point should the model snap back to a previous position. |
− | + | The figure below illustrates how to translate a mouse movement into a rotation axis and angle. <tt>m0</tt> and <tt>m1</tt> are consecutive 2D mouse positions. These positions define two locations <tt>v</tt> and <tt>w</tt> on a 3D virtual sphere that fills the rendering window. Use their cross product as the rotation axis <tt>a = v x w</tt>, and the angle between <tt>v</tt> and <tt>w</tt> as the rotation angle. | |
− | The figure below illustrates how to translate a mouse movement into a rotation axis and angle. | + | |
Horizontal mouse movement in the middle of the window should result in a rotation around the y-axis. Vertical mouse movement in the middle of the window should result in a rotation around the x-axis. Mouse movements along the boundary (horizontal and vertical) should result in rotations at least partially around the z-axis. [http://viewport3d.com/trackball.htm Here] you will find a more detailed description of the implementation of a virtual trackball. | Horizontal mouse movement in the middle of the window should result in a rotation around the y-axis. Vertical mouse movement in the middle of the window should result in a rotation around the x-axis. Mouse movements along the boundary (horizontal and vertical) should result in rotations at least partially around the z-axis. [http://viewport3d.com/trackball.htm Here] you will find a more detailed description of the implementation of a virtual trackball. | ||
Line 62: | Line 61: | ||
You get points for the following accomplishments: | You get points for the following accomplishments: | ||
* The object space has to rotate about its origin (<b>20 points</b>). | * The object space has to rotate about its origin (<b>20 points</b>). | ||
− | * The trackball has to rotate correctly with regards to the mouse movement (e.g., mouse to the right -> object rotates to the right) (<b> | + | * The trackball has to rotate correctly with regards to the mouse movement (e.g., mouse to the right -> object rotates to the right) (<b>25 points</b>). |
− | * Clicking and dragging <i>anywhere</i> in the window, including close | + | * Clicking and dragging <i>anywhere</i> in the window, including close to the edge or corners of the window, should not crash the application (<b>5 points</b>). |
[[Image:trackball.jpg]] | [[Image:trackball.jpg]] | ||
Line 69: | Line 68: | ||
==3. Loading Triangle Meshes from Files (20 points)== | ==3. Loading Triangle Meshes from Files (20 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 | + | 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 <tt>v</tt>, and an array of indices to form triangles indicated by the letter <tt>f</tt>. We provide a C++ class that reads .obj files, which you can download [[Media:ObjReader.zip|here]]. You should add this code to your rendering engine. The .zip file also contains a code sample that demonstrates the use of this class. You have to add the routines to create OpenGL geometry out of the 3D data structure (<b>4 points</b>). Add support for a command line parameter to specify the name of the .obj file to load (<b>1 point</b>). |
− | One problem is that you don't know the extent of the object stored in the file. The triangle coordinates may not be suitable for your viewing configuration. To make sure that there is a well defined bounding box for the object, write a utility function | + | One problem is that you don't know the extent of the object stored in the file. The triangle coordinates may not be suitable for your viewing configuration. To make sure that there is a well defined bounding box for the object, write a utility function <tt>normalize()</tt> that uniformly scales and translates all coordinates of the object such that it fills the OpenGL window. This should be achieved by finding the minimum and maximum <i>x</i>, <i>y</i>, and <i>z</i> coordinates of the object (<b>5 points</b>). Based on these values you need to create a translation matrix (<b>5 points</b>) and a uniform scale matrix (<b>5 points</b>) that, together, transform the object so that it fills the rendering window. This may also require a modification to your projection matrix. |
Here are a few sample .obj files for testing: | Here are a few sample .obj files for testing: | ||
− | + | * [http://graphics.ucsd.edu/courses/cse168_s06/ucsd/sphere.obj Sphere] | |
− | + | * [http://graphics.ucsd.edu/courses/cse168_s06/ucsd/teapot.obj Teapot] | |
− | + | * [http://graphics.ucsd.edu/courses/cse168_s06/ucsd/bunny.zip Bunny] | |
− | + | * [http://graphics.ucsd.edu/courses/cse168_s06/ucsd/dragon_smooth.zip Dragon] | |
− | + | * [http://graphics.ucsd.edu/courses/cse168_s06/ucsd/buddha_smooth.zip Buddha] | |
− | ==4. Optional Feature: | + | ==4. Optional Feature: Height Map (10 points)== |
− | Generate and display a 3D mesh out of a 2D | + | Generate and display a 3D mesh out of a 2D height map image. Wikipedia has a [http://en.wikipedia.org/wiki/Heightmap description of this topic]. Allow the user to interactively fly over it, similar to a flight simulator, using keyboard or mouse. As a height map image you can use the one from the Wikipedia page, which you will also find below, along with the resulting 3D terrain. To get full credit you need to implement the following features: |
− | + | * Load the height map image and create a 3D mesh out of it (<b>4 points</b>). | |
− | + | * Use a color gradient from blue (water) over yellow (sand) to green (grass), brown (dirt) and white (snow) to color the terrain polygons, depending on their height (<b>2 points</b>). | |
− | + | * Create a separate navigation mode apart from that of the trackball, in which the user can navigate by steering left/right, up/down, and change the velocity of the flight (<b>4 points</b>). To get all points, the scale of the terrain needs to be appropriately large for a flight simulator scenario. | |
− | + | [[Image:Heightmap.png]] | |
− | + | [[Image:Heightmap_rendered.png]] | |
− | To read the | + | To read the height map image, you can either read the PNG file with your own reader, or read [[Media:Heightmap.pgm|this PGM file]] with [[pgm-loader.cpp|this piece of C++ code]] . |
Latest revision as of 16:54, 7 October 2011
Contents |
Project 2: Interactive Viewing
This project has four parts, but only the first three are mandatory to get full credit (100 points). The number of points you get for each part is indicated below. In the first part you will need to implement camera and view frustum specifications. In the second part you will build a virtual trackball to rotate 3D objects with the mouse. In the third part you will use code that we provide to load triangle meshes from a file into your viewer.
The fourth part is optional. We make suggestions for how to extend your solution with additional features. You can get extra credit for completing those.
This project is due on Friday October 7, 2011. The assignment will be introduced by TA Jorge on Monday, October 3rd at 3pm in lab 250.
1. Camera and View Frustum
1a. Camera (10 points)
Create a camera class Camera with member variables for a center of projection e, a look at point d, and an up vector up, each of type Vector3, as in the lecture slides (4 points). The class should have an internal camera matrix of type Matrix4, derived from e, d and up (see lecture slides) (4 points). Add get and set access methods to the Camera class (1 point each).
1b. View Frustum (10 points)
Create a class Frustum which defines a projection matrix of type Matrix4. Create a class method to generate the projection matrix from a near plane near, far plane far, aspect ratio aspect, and a vertical field of view fov (6 points). This matrix is referred to in the lecture slides by the name Ppersp. Add a method to set OpenGL's projection matrix GL_PROJECTION from the class internal projection matrix (4 points).
Note: Do not use gluPerspective or glFrustum to implement the projection matrix, but use the equations from the lecture slides instead, and load projection matrix into OpenGL with glMatrixMode(GL_PROJECTION); glLoadMatrixd(Persp);.
1c. Testing (10 points)
We provide source code to generate a simple scene to test your implementation. Set the object transformation matrix (model matrix) to the identity matrix and render two images of the scene using these two sets of parameters:
- Image 1:
- Aspect ratio: 1
- Vertical field of view: 60 degrees
- Near, far clip planes: 1, 100
- Center of projection: 0, 0, 40
- Look at point: 0, 0, 0
- Up vector 0, 1, 0
- Image 2:
- Aspect ratio: 1
- Vertical field of view: 60 degrees
- Near, far clip planes: 1, 100
- Center of projection: -10, 40, 40
- Look at point: -5, 0, 0
- Up vector 0, 1, 0
Compare your implementation to the test images shown below (5 points for each image). Note that the images below were rendered with lighting off (glDisable(GL_LIGHTING)).
![]() |
![]() |
2. Virtual Trackball (50 points)
Implement a virtual trackball that allows a user to rotate an object interactively using the mouse. Your solution should translate clicking and dragging of the mouse into a rotation matrix, which you then use to transform the scene. Rotations around all three coordinate axes should be supported. A sample executable which demonstrates the trackball functionality is available for Windows and Linux. If the executable does not work on your computer, here is a video of it. To access the mouse coordinates, you will need to use GLUT's callback functions glutMouseFunc() and glutMotionFunc(). Note that successive trackball rotations must build on the previous ones; at no point should the model snap back to a previous position.
The figure below illustrates how to translate a mouse movement into a rotation axis and angle. m0 and m1 are consecutive 2D mouse positions. These positions define two locations v and w on a 3D virtual sphere that fills the rendering window. Use their cross product as the rotation axis a = v x w, and the angle between v and w as the rotation angle.
Horizontal mouse movement in the middle of the window should result in a rotation around the y-axis. Vertical mouse movement in the middle of the window should result in a rotation around the x-axis. Mouse movements along the boundary (horizontal and vertical) should result in rotations at least partially around the z-axis. Here you will find a more detailed description of the implementation of a virtual trackball.
You will notice that you can either rotate the camera around the object space, or the object space with respect to a stationary camera. It is recommended (but not required) to use a stationary camera and rotate the object space.
You get points for the following accomplishments:
- The object space has to rotate about its origin (20 points).
- The trackball has to rotate correctly with regards to the mouse movement (e.g., mouse to the right -> object rotates to the right) (25 points).
- Clicking and dragging anywhere in the window, including close to the edge or corners of the window, should not crash the application (5 points).
3. Loading Triangle Meshes from Files (20 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, and an array of indices to form triangles indicated by the letter f. We provide a C++ class that reads .obj files, which you can download here. You should add this code to your rendering engine. The .zip file also contains a code sample that demonstrates the use of this class. You have to add the routines to create OpenGL geometry out of the 3D data structure (4 points). Add support for a command line parameter to specify the name of the .obj file to load (1 point).
One problem is that you don't know the extent of the object stored in the file. The triangle coordinates may not be suitable for your viewing configuration. To make sure that there is a well defined bounding box for the object, write a utility function normalize() that uniformly scales and translates all coordinates of the object such that it fills the OpenGL window. This should be achieved by finding the minimum and maximum x, y, and z coordinates of the object (5 points). Based on these values you need to create a translation matrix (5 points) and a uniform scale matrix (5 points) that, together, transform the object so that it fills the rendering window. This may also require a modification to your projection matrix.
Here are a few sample .obj files for testing:
4. Optional Feature: Height Map (10 points)
Generate and display a 3D mesh out of a 2D height map image. Wikipedia has a description of this topic. Allow the user to interactively fly over it, similar to a flight simulator, using keyboard or mouse. As a height map image you can use the one from the Wikipedia page, which you will also find below, along with the resulting 3D terrain. To get full credit you need to implement the following features:
- Load the height map image and create a 3D mesh out of it (4 points).
- Use a color gradient from blue (water) over yellow (sand) to green (grass), brown (dirt) and white (snow) to color the terrain polygons, depending on their height (2 points).
- Create a separate navigation mode apart from that of the trackball, in which the user can navigate by steering left/right, up/down, and change the velocity of the flight (4 points). To get all points, the scale of the terrain needs to be appropriately large for a flight simulator scenario.
To read the height map image, you can either read the PNG file with your own reader, or read this PGM file with this piece of C++ code .