Project 4: Bezier Roller Coaster
In this project, you need to create a Bezier track editor for a simple roller coaster. The roller coaster will consist of a 3D curve representing the track, and a sphere as a car. The track editor should look similar to the one in this video.
Start with code to manipulate the camera with keyboard or mouse. You can use your project 3 for that. We recommend that you use your scene graph engine for this project, it will make the project easier.
This project covers the following topics:
- Textures and sky boxes in Part 1: covered in lecture on Nov 5th
- Environment mapping in Part 2: covered in lecture on Nov 5th
- Parametric curves in Parts 3, 4 and 5: covered in lecture on Nov 7th
- Connected Bezier curves and continuity: covered in lecture on Nov 12th
Note that there is a VR option for extra credit. If you think you want to create the project for VR, you should start your project with starter code that supports the Oculus Rift.
1. Sky Box (15 Points)
Create a sky box for your roller coaster scene. A sky box is a large, square box which is shown around your entire scene, to give it a nice background. The camera is located inside of this box. The inside walls of the box usually consist of pictures of a sky and a horizon, as well as the terrain below. Sky boxes are normally cubic, which means that they consist of six square textures for the six sides of a cube. Here is a great tutorial for sky boxes and how to implement them in modern OpenGL.
Here is is a nice collection of textures for sky boxes, and here is an even bigger one. Make sure the width and height of your sky box textures are powers of two, such as 512x512 or 1024x1024. You are allowed to create your own sky box if you want.
Choose a sky box texture. Then create a cubic sky box and make it very large by giving it coordinates from -500 to +500. Check to see if the textures align correctly at the edges - if not you may need to rotate some of the textures. There should not be any visible seams.
Make sure single-sided rendering (backface culling) is enabled. If your sky box is defined with the triangles' normals facing outward (like the example in the discussion slides), use the following code lines to ensure that the user will never see the outside of the box:
If your normals point inward, you need to use GL_BACK instead of GL_FRONT in the above code.
Use the following settings for your texture after your first
glBindTexture(GL_TEXTURE_CUBE_MAP, id) for correct lighting and filtering settings:
// Make sure no bytes are padded: glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Use bilinear interpolation: glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Use clamp to edge to hide skybox edges: glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- -5 if sky box works but is not seamless
- -3 if backface culling is not enabled, or it is enabled but the wrong faces are culled
2. Sphere with Environment Mapping (20 Points)
Use the sphere code you used for the bounding spheres in project 3 to render a solid sphere. Make sure you are parsing for the vertex normals in addition to the vertices. The sphere will represent the roller coaster car. Its surface should look like polished metal, so you need to use environment mapping on it.
The Cube map tutorial explains how environment mapping is done with a sky box as the environment. Feel free to follow it and use the code from the site to make it work in your code. The goal is to have the sky box reflect on the sphere, to give the impression of the sphere's surface being polished metal (i.e., act like a perfect mirror).
Use the camera controls from project 3, which allow the user to rotate the view from a fixed view point, as well as zoom in. It is important that your camera controls allow you to zoom in on the sphere, so that you can check to see if your environment mapping algorithm works correctly.
- -10 if reflection looks somewhat like the skybox but is off by a lot
- -5 if reflection is upside down but code looks good
3. Track (30 Points)
To create the roller coaster track, you will need to do the following things:
- Come up with control points P for 8 connected cubic Bezier curves (i.e., 4 control points per curve), with C1 continuity.
- Draw the Bezier curves by approximating them with at least 150 straight line segments for each Bezier curve (i.e., 8*150=1200 lines in total).
While we are not going to have a discussion on Nov 11, we are still offering discussion slides, which can help you with the project. We are also going to cover connected Bezier curves and continuity in class on Nov 12.
In a nutshell, you need to use the Bezier curve formula we derived in class to calculate the 150 points along the curve:
Then you can put those values into a buffer and render them using GL_LINES.
Here is an example of what your track could look like:
Your Bezier curves do not need to look exactly like those in the image above (or those below).
- -5 if line is not continuous (eg, dotted, dashed)
- -5 if curve does not loop back to beginning
4. Control Handles (20 Points)
Make your control points editable by the user with the keyboard. You need to support both the interpolating and the approximating control points.
Interpolating control points (5 Points)
These are the control points which the curve goes through, also called anchor points (points p0 and p3 for a given curve).
- Highlight the points with small spheres (such as those from project 3) or otherwise (eg., small cubes) to make it easy to see where they are.
Approximating control points (5 Points)
These control points "pull" on the curve but the curve does not go through them (points p1 and p2 for a given curve).
- Highlight these points in a similar way as the interpolating points.
- Use a different color or shape to distinguish them from the anchor points.
C1 Continuity (5 Points)
To ensure C1 continuity, you will need to support control handles like in the video. They connect the two last control points from one curve with the first two control points of the neighboring curve, and ensure that they lie on a straight line. Draw the control handles as lines.
Control Point Manipulation (5 Points)
- Support keyboard keys to manipulate the control points. Cursor right should switch to the next control point, cursor left goes to the previous point. The x, y, and z keys should move the control point in the respective coordinate axis direction, shift-x/y/z should move them in the opposite direction.
- Highlight the currently active control point in yet another color or shape.
- Update the shape of the Bezier curve in real-time, as you manipulate the control points.
5. Sphere Movement (15 Points)
Unlike in the video, move the sphere along the track at a constant velocity. Pick a speed that makes the sphere go around the track in about 10-20 seconds.
Note that to maintain a constant speed you need to factor in the length of the curve segment the sphere is on. Measure the wall clock time since the last update (delta_time), then move the sphere according to this equation: distance_traveled = current_speed * delta_time. To get delta_time you need to query the computer's clock, for which you can use the glfwGetTime function.
Support keyboard key 'p' to pause/unpause the movement of the sphere.
6. Extra Credit (10 Points max.)
There are multiple options for extra credit. Each will get you up to 10 points, but you can only get a combined maximum of 10 points of extra credit.
- Rider's View: Create a mode in which the camera is located on top of the sphere and always points forward along the track (in the direction of the tangent to the curve), simulating the view from the first row of a rollercoaster car. Support keyboard key 'c' to switch between the regular camera and this special action camera. (5 Points)
- Physics simulation: In addition to constant velocity, implement a mode in which the sphere moves based on a friction-less energy preservation model: the sum of the potential energy (proportional to the height the sphere is at) and the kinetic energy (determined by its velocity) remains constant. In other words: the lower the sphere is the faster it goes. This way, when the sphere starts at the highest point of your roller coaster, it should go through the entire track and end up at the highest point again without getting stuck. The movement should look like the ring in the above mentioned video. Toggle (ie, enable/disable) this mode with the 'v' key (for 'variable velocity'). (5 Points)
- Add friction: Requires that you already created the physics simulation above. Add friction to your physics equation, gradually slowing down the sphere as it moves along the track. To keep it from coming to a standstill, make one of your Bezier curves an "accelerator segment", which gradually adds speed to the sphere as it moves along it. Draw this Bezier segment in a different color than the rest of them. Toggle this mode with the 'f' key. (5 Points)
- Improved Reflections: Make the environment map more realistic by reflecting the track in it, in addition to the sky box. Do this by placing a virtual camera in the middle of the sphere, with a square image and a 90 degree field of view. Then take six pictures with the camera, facing in perpendicular directions to cover all six faces of a cube. These pictures now make up your sky box from this perspective. Then use environment mapping on the sphere using this temporary sky box. This process has to be repeated for every frame rendered. Toggle this mode with the 'r' key. (10 Points)
- Virtual Reality: Render your application to a virtual reality head set, and control the track's control points with the Touch controllers. Support two viewpoints: one from the point of view of the sphere, one from a vantage point that overlooks the entire track. You can use the Oculus Rifts in the CSE VR lab (room B210). Email the instructor to get access to a Rift and controllers. If you choose this option, we will grade your project in room B210. (10 Points)
- Improved interaction: Instead or in addition to keyboard controls, allow moving the control points with the mouse. We recommend using a selection buffer. (5 Points)