Project 1c - Follow (2D), Fly behind (3D), Draw 3D runner, Lean runner
Goal: The goal of this phase of the project is to transform the dot that represents the
car into a pointed shape whose tip faces the direction of travel. Furthermore, two racing
view modes will be added: a 2D overhead view that has the car always facing up, and a 3D view
that causes the camera to follow the car on its path around the track.
System: My project was written on Windows XP using Processing (http://processing.org). The Java wrapper used by Processing should make it cross-platform compatible.
Car Orientation: While in racing mode the car is oriented so that the blue tipped "hood" is always facing in the same direction. This is achieved by taking a vector from the previous car position to the next car position and calculating the angle between this vector and the vertical. A rotate() command can then be issued to change coordinate systems so the car always appears to be aligned with the vertical. This is done in one simple line of code:
rotate(-PI/2-atan2(c1y[next]-c1y[prev], c1x[next]-c1x[prev]))
Two Dimensional Rotation: Since the car is always facing the same direction, the track needs to be rotated so it appears the car is taking the correct path around the track. Because the car rotation command above also rotates the track, this achieves the desired affect. The online modification was to move the current car position on the road to the center of the screen. This will align the road with the track. The translation command is:
translate(-c1x[car1_step], -c1y[car1_step])
In 2D racing mode there is a bird's eye view with the track rotated so the car is facing straight ahead.
Three Dimensional Rotation: In order to achieve the "follow behind" effect a simple rotation must be performed. Instead of rotating the X/Y plane, a single axis will be used to rotate the plane towards the camera, creating a perspective view effect. Since the X axis passes through the sides of the car, rotating along this axis will bring the camera behind the car. Therefore the desired effect can be achieved with the following command, where car1_camangle is the degree of rotation:
rotateX(car1_camangle*PI/180)
This is the 3D racing mode with the camera following behind the car.
Video Game Comparison: I think that the 3D perspective view does an excellent job of imitating a typical video game. One aspect that needs improvement is the fixed distance and angle of elevation between the camera and the car. In most driving simulations the car will pull away from the camera when it accelerates and vice versa. If a non-linear velocity were applied to the camera's distance and rate of rotation this would cause the side affect of the car possibly escaping the view of the camera from time to time. Finding a solution could prove to be complex.
Leaning: To lean the car I used Professor Rossignac's method demonstrated in his rideCamera program. Basically, lean magnitudes are calculated for left/right and forward/back depending on the length of the previous and next road segments. From there the X and Y axis are rotated in proportion to the calculated lean magnitudes. These magnitudes are multiplied by a constant to make sure that the car does to lean too much "into" the road. These constants were determined with trial and error, but it would certainly be possible to calculate them so the car never leaned beyond a specific angle, although this would add a little complexity to the code. I found that this solution was the best to avoid abrupt lean changes, but only when using a b-spline curve subdivision. When a four-point subdivision is used the car has a tendency to "hit" the road.
Applet Instructions:
Drag the vertices to edit the track.
Drag midpoints (small dots) to create a new vertex.
Press 1 to enable editing mode.
Press 2 to enable 2D racing mode.
Press 3 to enable 3D racing mode.
Press UP ARROW or DOWN ARROW in racing modes to change the camera angle.
Press LEFT ARROW or RIGHT ARROW in racing modes to change the camera distance.
Press + or - in editing mode to create less or more interpolated curves.
Applet:
Source Code: p1c.pde
Demo Video: p1c-demo-divx.avi (4.5 MB, DivX Required)
Demo Pictures:
(click to enlarge)
This is a picture of the track editor.
(see above for pictures of the racing modes)
System: My project was written on Windows XP using Processing (http://processing.org). The Java wrapper used by Processing should make it cross-platform compatible.
Car Orientation: While in racing mode the car is oriented so that the blue tipped "hood" is always facing in the same direction. This is achieved by taking a vector from the previous car position to the next car position and calculating the angle between this vector and the vertical. A rotate() command can then be issued to change coordinate systems so the car always appears to be aligned with the vertical. This is done in one simple line of code:
rotate(-PI/2-atan2(c1y[next]-c1y[prev], c1x[next]-c1x[prev]))
Two Dimensional Rotation: Since the car is always facing the same direction, the track needs to be rotated so it appears the car is taking the correct path around the track. Because the car rotation command above also rotates the track, this achieves the desired affect. The online modification was to move the current car position on the road to the center of the screen. This will align the road with the track. The translation command is:
translate(-c1x[car1_step], -c1y[car1_step])
In 2D racing mode there is a bird's eye view with the track rotated so the car is facing straight ahead.
Three Dimensional Rotation: In order to achieve the "follow behind" effect a simple rotation must be performed. Instead of rotating the X/Y plane, a single axis will be used to rotate the plane towards the camera, creating a perspective view effect. Since the X axis passes through the sides of the car, rotating along this axis will bring the camera behind the car. Therefore the desired effect can be achieved with the following command, where car1_camangle is the degree of rotation:
rotateX(car1_camangle*PI/180)
This is the 3D racing mode with the camera following behind the car.
Video Game Comparison: I think that the 3D perspective view does an excellent job of imitating a typical video game. One aspect that needs improvement is the fixed distance and angle of elevation between the camera and the car. In most driving simulations the car will pull away from the camera when it accelerates and vice versa. If a non-linear velocity were applied to the camera's distance and rate of rotation this would cause the side affect of the car possibly escaping the view of the camera from time to time. Finding a solution could prove to be complex.
Leaning: To lean the car I used Professor Rossignac's method demonstrated in his rideCamera program. Basically, lean magnitudes are calculated for left/right and forward/back depending on the length of the previous and next road segments. From there the X and Y axis are rotated in proportion to the calculated lean magnitudes. These magnitudes are multiplied by a constant to make sure that the car does to lean too much "into" the road. These constants were determined with trial and error, but it would certainly be possible to calculate them so the car never leaned beyond a specific angle, although this would add a little complexity to the code. I found that this solution was the best to avoid abrupt lean changes, but only when using a b-spline curve subdivision. When a four-point subdivision is used the car has a tendency to "hit" the road.
Applet Instructions:
Drag the vertices to edit the track.
Drag midpoints (small dots) to create a new vertex.
Press 1 to enable editing mode.
Press 2 to enable 2D racing mode.
Press 3 to enable 3D racing mode.
Press UP ARROW or DOWN ARROW in racing modes to change the camera angle.
Press LEFT ARROW or RIGHT ARROW in racing modes to change the camera distance.
Press + or - in editing mode to create less or more interpolated curves.
Applet:
Source Code: p1c.pde
Demo Video: p1c-demo-divx.avi (4.5 MB, DivX Required)
Demo Pictures:
(click to enlarge)
This is a picture of the track editor.
(see above for pictures of the racing modes)