Graphics Project 2005
The Interactive Roller-Coaster Ride!!

Files
Lighting
I added a blue light to the scene, as well as some bluish fog to get the underwater affect.
I also added a yellow light for the sun.
Texture mapping
I applied a wooden texture to my tunnel, by just using the automatic texture co-ordinates generated by the glucylindar object which was really nice and easy to work with.
Applying a wooden texture to the slats of the track is very simple since the vertices are created explicitly and so the texture co-ordinates could easily be set up, but i rather implemented a "color spline” which was really nice for smoothly varying between color points – these smooth colors were applied to the track.
Animated objects using hierarchical transformations.
For the hierarchical transformations I used the old bird objects (from prac 18), and just removed one of their wings, and rotated the other around to produce a few schools of fish!
I also created a sun that had beams of light (triangles) rotating around a central disk using a hierarchy.
Extras
With my method of making slats it would be fairly easy to just rotate the points generated for the end of the slat around and so approximate a smooth cylinder- which would be a much better approach than rotating many little cylinders. However I preferred the slats.
I added a very basic gravity feel by varying the position along the spline according to a velocity. I varied the velocity according to an acceleration which I obtained by just using the -z component of the tangent vector. In order to make sure that the rollercoaster didn't scream out of control I also added some friction and limits on the speed.
Screenshots of the Sunny Underwater Ride


Problems
The main difficulty in creating the ride was the track. My early attempts involved hundreds of GLUCylinders that had to be individually rotated so that they lined up with the tangent vector to the spline. This worked, however the cylinders would never quite join up, especially around sharp bends, and a very jagged edge resulted. I therefore decided to instead create a more realistic track by creating slats that crossed the spline. To do this I found the cross product of the tangent and the normal to get a vector pointing at 90 degrees to the 'side' of the spline. Thereafter it was just a matter of adding vertices to the various points of each slat.
There are still many errors with this approach since the spline seems to twist around at random points and so the roller coaster does a quick flip where it should be traveling straight. This is because the spline lies on an infinite number of planes and so there is no explicit 'up' direction. This caused me MANY headaches, and in the end a bit of a weird ride!
The lack of orientation of my spline also caused problems with the implementation of allowing the user to look left and right.
References and extra resources
I used the graphics course prac 18 (created by Shaun Bangay) as a basis for the code which proved extremely useful. To create the entire program from scratch would take me much more time than I had available.
The provided code was really nice to manipulate - for example to get the ride underwater all I had to do was move the water object already created up a bit. The birds were also really easy to turn into fish..
Code
Draw Sun Method
void drawSun() { //my hierarchical
sun
countang ++;
//this is a global variable to rotate the rays around the sun
if (countang >= 360) countang = 0;
glPushMatrix();
glColor3f(1,1,0);
glTranslatef(2,6,-10);
glRotatef(30,0,1,0);
gluDisk(quadratic,0.0f,1.0f,20,20);
//draw a disk for the sun centre
glColor3f(1,0.2,0);
for (int ang = 0; ang <= 360; ang += 60) {
//draw each ray at a new angle
glPushMatrix();
//basically just uses centre of sun a s a pivot, and rotates triangles
around this
glRotatef(ang + countang,0,0,-1);
glTranslatef(0,1,0);
glBegin(GL_TRIANGLES);
glVertex3f(-0.2,0,0);
glVertex3f(0.2,0,0);
glVertex3f(0,1,0);
glEnd();
glPopMatrix();
}
glPopMatrix();
}
Draw Ride Method
void drawRide() {
double step = 0.005;
//amount to increase along spline (this sets where each slat is
possitioned)
float count;
Vector tangent2;
Vector eyedir = Vector (0.0, 0.0, 1.0);
Vector n;
double angle;
int fac = 1;
double col = 0;
for (count = 0; count <= 1; count += step) {
//move all the way along the spline in steps of count
col += fac* step * 10;
// this code varies the color smoothly by using a spline
if (col > 1) fac = -1;
// when the possition on the colour spline is at the end, return
rather than starting at 0 again
if (col < 0) fac = 1;
Point d = colorchange->curveAt (col);
glColor3f(d.coord[0],d.coord[1],d.coord[2]);
Point p = camerapath->curveAt (count);
//current point on spline
Point p2 = camerapath->curveAt (count + step / 2);
//point on the spline a bit later (at the moment slats are half the
step value)
further on
tangent = camerapath->derivativeOfCurveAt (count);
//tangent at those points
tangent2 = camerapath->derivativeOfCurveAt (count+step / 2);
n = crossProduct (eyedir, tangent);
Vector axis;
//axis and axis2 are 2 vectors pointing at 90 degrees to the spline
Vector axis2;
//they don't have any orientation however which causes problems!!!!!!!
axis2 = crossProduct (tangent2, n);
axis = crossProduct (tangent, n);
axis.normalize();
axis2.normalize();
glPushMatrix();
glBegin(GL_POLYGON);
//draw the 4 points of the slat
glVertex3f (p.coord[0] + axis.coord[0] /2, p.coord[1] + axis.coord[1]
/2,p.coord[2] + axis.coord[2] /2);
glVertex3f (p.coord[0] - axis.coord[0] /2, p.coord[1] - axis.coord[1]
/2,p.coord[2] - axis.coord[2] /2);
glVertex3f (p2.coord[0] - axis2.coord[0] /2,p2.coord[1] - axis2.coord[1] /2,
p2.coord[2] - axis2.coord[2] /2);
glVertex3f (p2.coord[0] + axis2.coord[0] /2,p2.coord[1] + axis2.coord[1]
/2,p2.coord[2] + axis2.coord[2] /2);
glEnd();
glPopMatrix();
upRight = crossProduct (axis,tangent);
}
}