Note: This image is not meant to show a representative solution.
In this assignment, you will use Catmull-Rom splines along with OpenGL lighting and texture mapping to create a roller coaster simulation. The simulation will run in a first-person view, allowing the user to "ride" the coaster in an immersive environment. As with the previous assignment, you will create an interesting animation after finishing the program itself. This time, the objective of your animation is to show off both your coaster and the features of your program.
Now that the first programming assignment has familiarized you with working in OpenGL, this assignment asks you to utilize some more interesting features of the library in the design of a more significant and more entertaining application. In addition, this project gives you a great deal more freedom to be creative in the actual design of your program and the features that go into it; you are asked to create your own solutions to issues involved in the making of your simulation, and to render your coaster as you wish in a world of your design.
After completing this assignment, you should have a solid understanding of:
This assignment should be challenging, at least as much as the first assignment and likely more. However, it should also be a lot of fun! Please start early.
In order to create the track for your roller coaster, you'll need to render a spline sequence which represents the entire length of your track. In order to do so, you will need to implement a function that takes four control points (p0 through p3) and a floating point value (u) from 0 to 1, and computes the corresponding position on the spline segment defined by these four control points. Drawing a single spline from four control points isn't that exciting--you'll need to use several control points in sequence and draw spline segments along them, starting from the first four points and proceeding until you draw the final spline for the last four points. This will allow you to represent a long, elaborate curve for your coaster.
We'll be using Catmull-Rom splines for the representation of your coaster. These were defined along with their geometric constraints in lecture, so please see the corresponding slides for information.
An example of a solution, with several extra credit elements (for example, the support structure, double rail, and the textured-mapped crossbars). Of course, this is just an example; your solution will likely differ. This image is not a standard for grading or meant to show what you need to do. The text on this webpage gives the official (and only) rules for the assignment requirements.
Starter code: You can find the starter code and supplementary files here: Visual Studio 2010, Mac, Linux. The Mac and Linux starter codes require the "pic" image library. If you already compiled "pic" in the first assignment, you don't need to download and recompile "pic" again. As a reminder, the "pic" directory has to be located one level above your assignment 2 directory (e.g. if assign2 == /home/MyComputer/assign2, then pic must be in /home/MyComputer/pic). For those who are working on Mac or Linux for the first time, get "pic" here.
Level 1 (spline): First, please implement your spline function and draw some splines to the screen. A point on a single Catmull-Rom spline segment is given by:
p(u) = [u^3 u^2 u 1] M C, (1)
where M is the Catmull-Rom spline basis matrix, C is the control matrix, and parameter u varies on the interval [0,1]. The exact form for M is given in the lecture notes, and also in Angel, p. 629 (for s=1/2). Note, however, that there is a typo in the formula in Angel: The last entry of the first row of M should be 1 instead of 0 (i.e. the first row of M should be [-1 3 -3 1] instead of [-1 3 -3 0]). Also, please do not forget to include the 1/2 factor before the matrix if you are using the formula in Angel.
Please consult the spline lecture notes (slide "How to Draw Spline Curves") for how to render a spline. You may use the simplest, "brute-force" method where you vary the parameter u by some fixed value, for example 0.001. Insert each value of u into equation (1) (above), to obtain the point location p(u). For example: u = 0.0, 0.001, 0.002, ..., 0.999, 1.0. Then, connect consecutive points with lines, for example, by using GL_LINES. You may need to set a proper line width, by using the OpenGL glLineWidth function. Note that in order to see the spline, you must setup your OpenGL camera. For a start, you can just use a stationary camera, similar to the first assignment (we recommend using gluPerspective for this assignment). You may use the keyboard/mouse to view the scene from different angles, or zoom in and out, just like in the first assignment. We provide a set of "track" files containing control points to define some simple splines, and starter code to read in a sequence of these files and convert them to sequences of control points that you can use. You can safely assume that each spline file (i.e. splines/*.sp) has at least 4 control points. You are encouraged to experiment with .sp files, creating your own spline files as needed for your personalized solution (well-documented creativity will be awarded).
Level 2 (ground): Next, add the ground. You can use a plane for the ground. It should be texture-mapped for realism with an image of your choice. There are plenty of free texture sites on the Web, for example mayang textures, or texture forest, (and many others, search for them on Google), so find one that appeals to you. Note that you may need to rescale your texture image to be of dimension that is a power of 2. For example, good choices are 256x256 or 512x512. You can use any software you wish to scale and/or edit your texture image.
Level 3 (sky): After this, create your sky--this should also be texture-mapped, and the method of modeling it is up to you. For example, one way to create the sky is to enclose the entire scene into a cube, and then texture-map the faces of this cube with some sky-like texture. Note, however, that there are issues (e.g., visible seams) with many obvious representations, so you can improve this for extra credit (but don't do it until you are done with all the levels). Make sure that you can still draw the splines as before once you have done levels 2 and 3!
Level 4 (the ride): Now, implement the ability to ride the coaster. You can do so by moving your camera at a constant speed (in u) along the spline (creating physically realistic motion is extra credit). Properly orienting your camera is a challenging problem! You'll want to have your camera facing "forward" (along the tangent to your spline) as it moves. The tangent vector can be computed by differentiating equation (1) with respect to u, that is: t(u) = p'(u) = [3u^2 2u 1 0] M C. Note that you need to normalize this vector to obtain a unit length tangent. Also, you need to make the "up" vector of your camera follow some continuous path of normals to the spline. A cheap method to decide your up vector is to always set it equal to the normal of your ground plane--however, this is very unrealistic for many splines. Another method is described here.
Level 5 (rail cross-section): Modify the appearance of the coaster itself: instead of just a line, make your track look like a track, by rendering a cross-section of the rail. In order to render the cross-section, you can use the tangent, normal and binormal described in Level 4. Suppose p0 and p1 are two consecutive points along the spline. You can then compute vertices v0, v1, ..., v7, and render a tube as described in the following PDF, and further illustrated here. In this example cross-section is a square, but you may change that to other shapes, such as a circle or ellipse.
After this is all done, add some fun extras! Do not attempt extra credit until you have successfully finished everything else, or else you run the risk of running out of time.
Just like with the first assignment, you are required to submit an animation, represented by a series of JPEG images which are screenshots from your program. We allow for more frames this time as your coaster may take more time to demonstrate--please name your JPEG frames 000.jpg, 001.jpg, and so on. Do not exceed 1000 frames. The frame rate for the animation, again, is 15fps.
Please submit your code along with your JPEG images and readme to the Blackboard. After submission, please verify that your zip file has been successfully uploaded.
This assignment is much more open-ended as to what you may choose to implement for extra credit. You may be awarded credit for any creative or interesting solution to an issue in your implementation, as long as it is well-documented in your readme file. Below are some ideas you might want to think about if you have the time:
Please note that the amount of extra credit awarded will not exceed 20% of this assignment's total value.