#########====================------------------------------------ @ ###########======================----------------- @\\\\\\\\\\\\\\\* ##=== Owen Wiggins ====------------------------ @\\\\\\\\* .###== Michael Musson =-------------- @\\\\\\\\\\\\\* .#======== CpSc 314 - Assignment 3 ======-------------- @\\\\\* .####===== Mission to Planet X ==-------------- @\\\\* .#########========================--------- @\\\\\\\\*\\\\* ..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*\\\\\\\\* ...\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* ................................ ................................. ....................... ........................ Instructions - To compile, type 'make'... then wait. To run, either type 'pdriver' (for the particle demo) or 'cdriver' (for the full-world demo). Keys - [a] [d] [q] [e] [pg up] [pg down] [arrow keys] to move camera. [A] [D] [Q] [E] [W] [S] [C] to move spaceman. [o] [p] [l] [;] [,] [.] to move arm goal point - this will change what the arms reach for. Note: Originally the goal is underground. Also, spacemen won't be reaching for anything when they're on fire! [6] activates walking for the player controlled character, otherwise he just slumps around. This was kept in to show off the IK system. Description - This program is of an alien world with a vaguely familiar moon. We have two strange spacemen running around, one constantly pointing at the other. One of the spacemen is controlled with the keyboard, the other by an AI. A mystical fire burns in the center, stars twinkle overhead, and the moon swings by at nauseating speed. Watch out, because that fire isn't just scenery. The majestical fireworks in the sky, however, is. The following advanced features were used in this project over and above what was required: Particle System - The particle system was created with flexiblity and extensibility in mind, therefore it was decided to have a fully independent "Particle" object which could respond to any forces (accelerations) applied to it. Each particle needed to support as vast an array of possible particles as possible, so several different draw methods were implemented including point, line, quads, and triangle strips. It supports transparency and texture mapping. The quads and triangle strips are billboarded - always facing the camera. We felt this was more efficient than rendering spheres or cubes, since it could be done by simply stripping the rotation information from the modelview matrix and loading it. Support for linking the particles was also included, in case we wanted to model flocking behaviour or something similar. The particle system itself would then create several particles in its constructor, and then update their Euler equations and any other properties before every frame is drawn. Each particle system would itself also have Euler equations to control its movement. It was decided to create an interface to handle any objects that need to be affected by physics, and thus BallisticBody was born. A forcefield class was created. Each particle system would contain an array of function pointers to forcefield methods that control how the forces affect a ballistic body. The fireworks system was implemented first to test the system. It is effected by gravity and viscous drag, and has any number of particles with random initial velocity and color. It also used a texture map of a spark, and had a line trailing behind it based on its velocity. Next, a flame effect was created. This effect required the most attention to the texture map, since it determined the final colors in the flame. Most of the time was spent tweeking this texture map. The behaviour of the flame was simply to move in a vertically biased random direction on each frame, and to fade the green and alpha values of the color over time. The main area of improvement here would be to get rid of the function pointers. A simple force class would work much better. Combining the update and draw methods would also allow for some optimization by including all particle modifications and drawing to be done over one iteration instead of two. Detailed Humanoid Model - It was decided to create a spaceman character, since this allowed for more flexiblity in the type of materials we could use - a shiny transparent glass spacehelmet, metal spacesuit, and skin texture (skin texture was never implemented). Although we ran out of time before implementation, a facial animation system based on mesh deformation was planned. This system would have taken a set of meshes, and interpolated the vertices between two of them to create a unique expression. Many of the lessons from assignment 1, the dinosaur project, were used here, and the model was quickly constructed. The nested classes from assignment 1 were done away with in favour of external classes. This makes it much easier to use the same character system for different characters. Support for an inverse kinematic system was built in from the start. Muscles respond to the angle of the joints, making them flex. Since the original game idea had the characters improving over time, a muscle property was included so that increasing the strength of the character would actually increase the size of his/her muscles. A controller class containing animations was also included, and could be used by either the keyboard/mouse or AI. The controller class includes the walking animation, which takes advantage of the physics and IK system. To improve the character model, we would have each limb position be used in collision instead of just the minimum y position of all the points. This would better cope with the steep slopes in our world. Although it would have been easy to add, we never had time to add texture mapping to the characters. A decal system was also considered, but was scrapped due to time constraints. Simply including a greater number of behaviours would also improve the characters. Physics System - From the start, it was decided to include physics in as much as possible. This would greatly reduce the amount of scripting required, and make for much more flexiblity in the actions the characters and particle systems could take. Virtually every moving object has a position, velocity, and acceleration. Collisions with the ground are handled by giving a vertical impulse. This was decided over a hard stop because it created a nice smooth bounce and looked more natural - although cartoony and unrealistic. The biggest area that needs improvement, is the collision detection system. There is great opportunity here to increase the interactivity of the world. The current interactions also need to be tweeked, since the character's walk is a little more bouncy than it should be. Inverse Kinematics - Inverse kinematics was used to control the angles of the character limbs. A goal point was specified for the end of the limb and the joint angles were adjusted so that the end point of the limb was as close as possible to the goal point. The approach taken to find the optimal joint angles was basically a least-path "gradient" approach. Starting from the joints closest to the center of the character, the joints were modified and the new endpoint was tested against the goal point. Transformations were done using OpenGL, and should be done on the GPU. The joint modification that produced the closest distance from the endpoint to the goal point was then kept. This continued down the limb until the optimal reach position was achieved. It was a somewhat quick and dirty approach to IK, but we only had limited experience and was the best we could do with the time frame. The IK could then be used to easily control the limbs. We then used the IK system to create a smooth walking animation and to allow the models to reach for different objects (or each other). To improve this, we would use a better optimization method that is less likely to get stuck in local minima. A novel approach using a genetic algorithm was planned, but scrapped due to time constraints. We would also add a key-frame animation system instead of using the optimization path for moving the limbs. Terrain - A TGA file loader was used to load alpha values from a TGA file and create a height-map from the loaded values. The color of the terrain was loaded from the RGB values of the TGA file as well as texture mapped with a terrain texture file. Since the heightmap only loaded values for integer values on the X-Z plane, height values were interpolated between vertices using a basic (but good) technique learned in class. The whole system was loaded in a display list to improve performance. The result was a surprisingly effective terrain. An area this could be improved, would be to randomly generate the terrain and to allow for different textures on the same terrain to give the impression of areas of grass and dirt. Skybox - The skybox was implemented by simply drawing a cube around the camera and disabling depth testing and lighting. Having the sky move with the camera gave the impressions of great distance. The cube was then texture mapped and different sky textures were created and tested until a desired one was found. A second object with the moon texture mapped on it was then created, masked/blended, and rotated around the camera. The entire skybox was then also rotated around the camera - slowly, and the texture on the cube was translated over the surface to make the sky more dynamic. A really simple and quick improvement to this would to added another cube inside the current one textured with nothing except clouds, and have this transformed slightly faster to give a greater sense of depth due to parallax than the moon could alone. The entire project was done using object-oriented C++ and OpenGL/GLUT. Our original plan was, of course, much grander. Unfortunately, we ran out of time and instead of having a game, we have a simple demo. ------------------------------ Date: Friday, 02 December 2005\ ==============================\\ .\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ .................... ..................... Note: Some code was used from outside sources. However, this is restricted to a few of the utility classes ONLY - math, texture loader, and timer. Please see the header files under './include' for more information and credits. All the above advanced, and all the standard, features were done by *us*.