CS248 Programming Assignment 3 - 3D Video Game
----------------------------------------------

Game title: Fantastic Voyage

Team members: Gek Siong Low
              Arthur Amezcua

Platform: Firebirds with plib sound support

Resources:

 - Textures - Free ones from www.zoorender.com, one for the cancer
cells, and one for the walls of the room.

 - Sounds - The background music and sound effects are from Gek's
personal collection (accumulated over the years, so sources are
unknown). The breathing sound you hear in the background is Gek
trying to breath heavily into the microphone.

 - External models - None. All models are generated
mathematically.

 - Code - We built upon the example files and used only the
texture.cc supplied to us. No code was borrowed or consulted from
other sources. We tried to implement some of the pseudocode from
Moller's textbook, but none of them seem to work for us, so we
wrote our own algorithms.


Compiling
---------

The game is developed on and for the firebirds, just type "gmake"
to compile on a firebird. The plib sound library is assumed to be
in the default places.


Description of Game
-------------------

Fantastic Voyage is a first-person submarine-type shooter based on
the novel "Fantastic Voyage" by Isaac Asimov. You are placed in a
nano-craft and injected into an eminent scientist's body in a bid
to save him from cancer. Your mission is to zap all the cancer
cells while avoiding red blood cells, and white blood cells which
will attack you.

The time limit is represented by gradually decreasing patient's
health. Your ship energy is gradually decreasing too. If any of
these drop to zero, you lose.

In addition to zapping cancer cells, you can also choose to zap
red blood cells for extra energy (if you find yourself running low
on energy), but at a cost to the patient's health and your overall
score. Zapping white blood cells gets you a score penalty and
decreases the patient's health, so the best policy is to try to
avoid them.

The objective of the game is to complete the game (zap all cancer
cells) with the highest score. As a secondary goal, the player can
also try to improve his accuracy percentage.


Screenshots
-----------

We didn't participate in the game competition, but we have 6 screenshots
here for your viewing pleasure: fantastic1.jpg to fantastic6.jpg.

As for the accompanying paragraph for the screenshots, you can use the
introduction below.


Game Manual
-----------

The instructions here are also displayed on our intro splash
screen. Controlling the ship is similar to controlling a
submarine. Also, please note that if you don't do anything and the
ship nose is pointing up or down, the ship will gradually return
to the level position (zero pitch angle).


INTRODUCTION

We have a crisis and we need your help!

An eminent scientist is dying of a rare cancer and the only way to
save him is to miniaturize you and put you in a nano-sub which is
injected into his body. Your mission is to zap all the cancer
cells while at the same time avoiding red blood cells, and the
vigilant while blood cells which will attack you at first sight.
Time will be of the essence. Remember, if the patient dies while
you are inside his body, you will perish as well! Good luck!

HOW TO PLAY

    Game controls               Game engine settings
         Up                     u   Toggle status display
         w                      l   Toggle lighting
         |                      p   Toggle polygon fill
Left a --+-- d Right            t   Toggle texturing
         |                      b   Toggle bounding boxes
         s                      v   Toggle view frustum culling
        Down                    o   Toggle level of detail
                                h   Toggle alpha blending LOD
Press spacebar to fire lasers   k   Toggle collision engine speed-up

           Right-click on the screen for menu, ESC to quit


GAME INFORMATION

Object          Damage  Score  Remarks
Cancer cell       1       10   That's your objective!
Red blood cell    3      -20   Ship energy +10   Patient's health -5
White blood cell  5      -40   Patient's health -10 (avoid them!
Walls             2        0   Don't hit your head on the way out!

Press spacebar to start game


Advanced Techniques
-------------------

We believe we have fulfilled all requirements for the advanced
techniques and perhaps even more.

1. Control Panel

The patient's health and ship energy are shown as colored bars at
the bottom of the screen. The ship speed is shown at the top left
corner, and the scores shown at the bottom right. There is also a
status display showing the status of all the various toggles
(lighting, view frustum culling, collision detection speed-up,
etc) and the frame rate and number of room partitions displayed.

There is also a radar at the bottom left corner showing where all
the objects are, and the view frustum, all projected onto the
xz-plane.


2. Level of Detail control

Our objects are modelled procedurally, so we are able to control
the density of the polygon mesh. Three levels of detail are
provided for each object (placed in display lists), and the
appropriate LOD is chosen depending on the distance from the
player.

We also implemented alpha blending to reduce the "popping effect" -- a
sudden change in appearance of the object -- as we change from one LOD to
the next. While it doesn't do much for the smooth objects (the red and
white blood cells) whose overall appearances don't change much between
LODs, it does improve the "popping" effect for the rough cancer cells.

The fog does help somewhat to reduce this "popping" effect too,
although it is strictly not an LOD technique.

LOD and alpha blending can be toggled from within the game.


3. View Frustum Culling

Each vertex of the object bounding boxes is compared against the
view frustum (6 planes). If any vertex lies within the view
frustum the object is then displayed. To handle the case when all
vertices are outside but the object is really inside, we "enlarge"
the view frustum by adding a "border" around the view frustum, the
size of which depending on the object's size, as described in
Moller's book.

To show that our view frustum culling really works, we use the
radar display. Objects are dimmed when they go out of view. Note
that the view frustum shown on the radar is only for when the
pitch of the craft is zero (that is, not pointing up or down), and
the radar is just a projection onto the xz-plane, so it does not
mean that objects are in view when they lie between the lines of
the displayed view frustum.

For the room polygons, we divided the room into 128 partitions. A
partition is displayed only when it lies within the view frustum.
The effect of this is shown on the status display at the bottom of
the screen. As the number of displayed partitions go down, the
frame rate goes up. We are able to maintain a frame rate of at
least 37 fps and it can go up to above 100 fps as the player
approach the walls.

View frustum culling can be toggled on or off. For this game, we
found that view frustum culling does not give us any noticeable
improvement in speed, although the room partitioning technique
does give us a big speed-up in collision detection. The firebirds
are simply too fast at rendering polygons.


4. Collision Detection

This turned out to be our hardest feature to implement. We surrounded our
objects (cancer cells, red blood cells, white blood cells, and the player)
with axis-aligned bounding boxes for the purpose of collision detection.
An intersection of bounding volumes was considered a collision.  We have
full collision detection between every object, the player and the walls of
the room. The main difficulty is in getting everything to bounce
correctly, and getting the damage delivered to the player correctly. The
intersection tests are surprisingly the easy part.

We also have collision detection in the laser zapping the objects. For
efficiency, we only attempt laser intersection with the objects in view,
as returned by our view frustum culling algorithm.

We also combined collision detection with the room partitions, when
calculating collision with walls. The object's current partition is first
determined and collision detection is performed only with the wall
polygons in that partition.  We projected rays from an object to check for
intersections with wall polygons.  This technique actually speeds up the
intersection calculations tremendously. If we turn it off, the frame rate
drops to less than 10 fps (which sucks).

The collision speed-up technique can be toggled from within the game.


Other features worth mentioning
-------------------------------

1. Sound

A soundtrack (notice the heartbeat sound in the background) and
sound effects for lasers and impacts are added. The only "fancy"
thing we did with the sound is that the volume of the laser hits
are adjusted depending on distance from the player.


2. White blood cells movement

If you come too close to a white blood cell, it will start to come
towards you (just some simple "AI"). You must get out of range or
it will suck the life out of you!


3. Modelling

Everything is modelled procedurally. The basic shape is an
ellipsoid, with deformations applied to it, resulting in the
distinctive shape of the red and white blood cells. The room is a
fractal landscape applied to a huge ellipsoid.


4. Partitioning of environment

Not quite your scene graph, and not quite an octtree either
(either would be overkill for this game), but we feel that this is
so important to our game that we want to mention it again.
