Life is a Space Odyssey: Final Report

From EQUIS Lab Wiki

Jump to: navigation, search


Contents

Project Description

Our project is the conversion of Life is a Village (LIAV) into a martian lander simulator. The player will attempt to land a martian lander on a target located on a 3d terrain. They must navigate the terrain to locate the target and avoid crashing while monitoring their fuel usage. The player must be careful to control their speed in order to land on the target at a reasonable speed to prevent crashing. The lander will be subject to gravitational forces, as well as forces exerted by the engines. The user will control the forces exerted by the engines in order to pilot the lander.

Team Members

  • Jason Kurczak
  • John Bolton
  • Cheryl Savery

Changes to the User Interface

The user interface for Life is a Space Odyssey is radically different in appearance from LIAV. The LIAV terrain has been replaced by a Martian terrain, complete with mountains, plains, and deep craters. The regular skybox has also been replaced with a skybox showing a view out into space. All trees and villagers are gone. The robot avatar has been replaced with a lunar lander model from the Google 3d Warehouse and the HUD has changed to show the the current fuel available and the height above the surface.

LIASO1.jpg

Particle effects are used to indicate when the engines are being fired and which engine(s) are being fired. Particle effects were also used to create a spectacular effect when the lander crashes on the martian terrain.

LIASO2.jpg

Sound was also added for ambiance and to simulate the sound of the engines firing.

Project Milestones & Schedule

Initial Stages of Development

Initially we planned a four stage development process as indicated below:

Stage 1 Stage 2 Stage 3 Stage 4
ODE physics engine Add HUD Transition from deep space to planet surface Add obstacles
New terrain Thrusters to handle ship rotation Collision detection with airborne objects
Lander model Sound HUD


Integration of the ODE physics engine with the LIAV software was identified as a key technical issue. As such it was tackled in the first stage so that if unforeseen problems arose there was still adequate time to revise the project. Using an actual lunar lander model was also considered to be crucial to the success of the game. Thus, determining how to convert existing Google SketchUp models to work with Ogre was also completed in the first stage.

Revised Stages of Development

At the mid-point of the term we reviewed and adjusted our initial plan. It was decided the transitioning from deep space to the martian surface would not greatly enhance the game play and this was eliminated from the project. The items in stage 4 of the initial plan were always considered optional extras and these were replaced with features such as joystick controls and particle and sound effects for the lander engines. The revised project plan is shown below.

Stage 1 Stage 2 - March 10th Stage 3 - March 16th Stage 4 - March 19th
ODE physics engine Physics model for lander Keyboard control for in-game thrusters Basically complete! Fun to play? Game-like?
New terrain Camera behaviour Interactive sound with real sounds Crash landings
Lander model Integrate terrain with OGRE Landing target Joystick controls
Working sound in-game HUD for fuel and height Jet thruster flames


As of March 19th, the project was essentially complete.

Technology

Sound in LIAV

The sound in LIAV is handled by the CAXSoundManager and CAXSoundSource classes. These provide a C++ wrapper for OpenAL and the ALUT toolkit, including object representations of sound sources and a sound listener, simplified loading of sound files, and compatibility with some Ogre classes such as vectors.

In simplified terms, sounds are associated with places, and as the user moves through them they are "rendered" to the correct speakers to provide 3D sound. To do this, sound files are loaded into OpenAL sound buffers, which are then tied to a certain location in space where the sound will originate from (a CAXSoundSource). Sound sources are not directional, and will decrease in apparent volume as the user moves away from them in any direction.

The user is represented by a Listener embodied within the CAXSoundManager, which contains a position and an orientation. This represents the user or avatar's "virtual ears" in the space, and so must be kept synchronized with the avatar's position and orientation. It is important to note that orientation includes both a "forward" direction vector and an "up" direction vector, up being required to resolve the ambiguity of an avatar that might be able to perform rolls about the forward axis. In LIAV up is always simply (0, 1, 0); however, in a flying or underwater game this would have to be calculated in each frame.

The only significant work required to get the sound running was to update the CAXGameState's UpdateAvatar method with calls to CAXSoundManager, to update the Listener's position and orientation to match the avatar's. Further information about the fix is available Getting Sound Working In LIAV.

3D sound is not required for Life is a Space Odyssey. The only sources of sound are the rocket engines (location is the same as the avatar, so the sound never changes in relative position) and background music which is not located spatially within the actual game.

OgreODE

In order to add proper physics, we chose to use OgreODE, an Open Dynamics Engine (ODE) wrapper. This physics wrapper supports all ODE primitives and adds prefabricated objects like vehicles, as well as providing rag doll support. The OgreODE download contains three tutorials/demoes, a simple scene that shows all the functions inside OgreODE ( primitives, collisions, joints, rag-doll physics, a car), a landscape showing use of the terrain scene manager in OgreODE, and finally a racing demo.

New Variables

In order to properly incorporate OgreODE into our project we created three new variables.

      OgreOde::World        *mWorld;
      OgreOde::Space        *mSpace;
      OgreOde::StepHandler  *mStepper;

The world is OgreODE’s topmost object, which is comparable to the root in Ogre. Every object is added to that world and must follow that the world’s rules (physics).

Defining the Physics

To define the physics of the world, several parameters are set.

      mWorld->setGravity(Vector3(0,-9.8,0);
      mWorld->setCFM(10e-5);
      mWorld->setERP(0.8);
      mWorld->setAutoSleep(true);
      mWorld->setContactCorrectionVelocity(1.0);
The Space

The space (or collision space) is a collection of all the objects or geometries. Objects can collide within their space, with objects from other spaces, or not collide with anything at all.

The StepHandler

The StepHandler handles the time in the world and is used to update events. It runs every now and then (e.g. once per frame) and determines which body moves where and what collides with what.

There are several options available for how the calculations are done by the StepHandler. The default used in the OgreOde demos was the OgreOde::ForwardFixedStepHandler. Using this step handler with the default time step of 0.5 seconds resulted in visible shaking of the lander and the terrain. Decreasing the size of the time step reduced the shaking, but did not entirely eliminate it. Also as the size of the time step was decreased, it began to impact the frame rate. Changing the stepper choice to OgreOde::ExactVariableStepHandler completely eliminated the shaking problem and allowed us to set the time step back to 0.5 seconds.

CAXWorldODEObject & CAXAvatar

In order to use OgreODE a new class, CAXWorldODEObject, was created to replace CAXWorldObject. As a result, entities now have a mass and geometry. The mass object contains the total mass of the object and the centre of gravity within the body frame, given as a Vector3. The geometry of an object can be one of several types, box, sphere, cylinder, or triangular mesh. If a box geometry is used it must be passed as 3d vector.


The class CAXAvatar now inherits from CAXWorldODEObject, instead of CAXWorldObject. The mass and geometry for the avatar are passed in the constructor. The constructor creates an OgreODE::Body, applies the mass and geometry, and attaches the body to the scene node. CAXWorldODEObject also includes methods to access the OgreODE::Body and apply forces to the body.

FrameListener & Terrain

The StepHandler is included as part of the FrameListener, to update the ODE world’s time steps. The CollisionListener checks for contact between two bodies and applies the appropriate forces as a result of contact. It can set the level of bounciness as well as the friction.


The terrain is added to the world and space objects, which enables collision detection between the lander and the terrain.

Google SketchUp & Ogre

Google SketchUp is a free 3d modeling tool provided by Google. Google SketchUp has access to a large repository of free 3d models through the Google 3d Warehouse. In order to use SketchUp models with Ogre, a SketchUp to Ogre Exporter was installed. This consisted of a ruby based script for exporting a selection from a SketchUp scene to an Ogre .mesh xml file and an Ogre .material file. Following this export, the OgreXML convertor was used to generate an Ogre binary .mesh file which can be used in LIAV.

Changes to LIAV to Use SketchUp Models

In order to use SketchUp models in LIAV several small changes must be made. Most notably, if the default robot avatar is being replaced all animation for the avatar must be removed. The lunar lander model we used is static, does not contain bones, and will not change in-game, making animation unnecessary. As well, we found that the scaling and placement of the origin for the lunar lander model was not consistent between LIAV and SketchUp. As such, the model must be scaled up several times in LIAV and the model must be translated in SketchUp such that the base is at the global SketchUp origin, as expected by LIAV.

Terrain Generation

A custom terrain was necessary for our project to create an appropriate martian landscape. Using existing data available from Google Maps, we were able to create a custom height map based on real Mars mapping data. We generated this height map in Adobe Photoshop. We cropped our initial image to 513 pixels on each side, changed it to a grayscale image, and applied a slight gaussian blur to smooth out the rough transitions the terrain height map would result in. We were easily able to modify the maximum and minimum heights by changing the brightness and contrast values, as well as editing terrain.cfg to change the maximum height. Our resulting image was a grayscale height map useable by Ogre, that when combined with our texture map gave us a nice Martian terrain.

Implementing A Custom Skydome

Our project also required a custom space skydome, giving the users a view of the stars when playing. In order to do this, we first found an appropriate high resolution jpeg image to display on the skydome and created a custom material in the sky.material file in the include directory. To create the custom material we used the following code.

      material CAX/SpaceSkyBox {
         technique {
            pass {
            lighting off
            depth_write off
            texture_unit {
                texture space.jpg 
             }
           }
         }
      }

In order to apply our material to the skydome, we modified CAXApplication. First, we removed the fog, as this was obscuring the visibility of the skydome. Following this, we set the current skydome to our material and tweaked the parameters to ensure it properly wrapped the skydome and tiled the space jpeg image an appropriate number of times.

Particle Effects

Particle effects were added to the lander object in order to give the player a visual indication of when the lander engines were being fired. The effects used were based on two jet engine sample effects that came with Ogre. The particle file used is shown below.

   particle_system Examples/JetEngine3 
   {
       material 		Examples/Flare
       particle_width          15
       particle_height         15
       cull_each		false
       quota			200
       billboard_type	point
  
       emitter Point 
       {
               angle               2
               emission_rate       100
               time_to_live        1
               direction           0 -1 0
               velocity_min        350
               velocity_max        400
               colour_range_start  1 1 0.5
               colour_range_end    1 0.8 0.3		
       }
  
       affector ColourFader 
       {
               red      -0.25
               green    -1
               blue     -1
       }	
   }

Four instances of the particle effect were attached to the lander scene node. When the engines were fired, the particle effects associated with the engine(s) are set to visible and the emitters are enabled.

A second particle effect was created for when the lander crashes on the martian surface.

Architecture

Workspace Architecture

Below is a conceptual-level Workspace Model schematic of the game architecture used in the Life is a Space Odyssey game.

In Life is a Space Odyssey, the bicycle used in LIAV has been replaced by the mouse and keyboard. The joystick is an optional alternative to the mouse and keyboard. The A/I component from LIAV is no longer required and the basic physics used in LIAV has been upgraded to use the OgreOde physics engine.

LIASOarchitecture.png

Implemented Game Design UML

This very high level diagram shows which components own which others. It also shows which namespace a module may be found in. On each frame, the game object gets passed control. It calls its input manager to poll the various game devices being used, tells its various managers to update their sub-objects, and moves the lunar lander and camera inside the OGRE scene.


LIASO_UML.jpg

"World ODE Objects"

The CAXWorldObject class in LIAV has been replaced by the class CAXWorldODEObject.

The original CAXWorldObject stored the following information about each object in the game world

  • position, direction, and scale
  • references an ogre mesh object
  • when the object or person is moved, the corresponding mesh object moves in the game world, too
  • actual data owned by the object is hidden in an OGRE-independent data source (CAXWorldObjectData)

In addition to all of the features from the original CAXWorldObject class, the new class CAXWorldODEObject contains attributes and methods to support the use of OgreOde physics on the objects. The new attributes include:

  • mass
  • geometry

Additional methods were also added to the class CAXWorldODEObject to allow forces to be applied to an object.

In Life is a Space Odyssey, there is only one type of object that inherits from CAXWorldODEObject. The class name of Avatar continues to be used. However, it now represents the lunar lander instead of the robot from LIAV.

Input Manager

The input manager is responsible for:

  • polling the input devices (mouse, keyboard and joystick).
  • mapping the device inputs to the appropriate game control actions
    • apply force to lander
    • camera pitch and rotation
    • restart game
    • program exit

Sound Manager

The CAXSoundManager and CAXSoundSource classes are used to run the sound in LIASO

CAXSoundManager manages:

  • creation of OpenAL sound buffers from .wav files
  • creation of OpenAL sound sources and their mapping to CAXSoundSources
  • movement and orientation of the OpenAL sound listener

Each CAXSoundSource manages (through a mapping to an OpenAL sound source):

  • the location of its sound in the audio space
  • the playback of its sound buffer (play, pause, stop, looping, etc.)
  • the volume and pitch of its sound buffer


Sound Engine UML


LIASOSoundManager.jpg

Interaction With Other Groups

Our interaction with other groups has been limited to providing documentation on:

  • Getting sound working in Ogre;
  • Using OgreODE; and
  • Using the Google SketchUp Ogre Exporter.

This documentation consisted of step-by-step installation, configuration, and building instructions. Links to this documentation can be found on the Main page of the CISC 877 - Equis Lab Wiki and are also provided below:

Who Did What

Jason:

  • Sound
  • Adding ODE properties to the Lander
  • HUD for Fuel and height
  • Joystick Controls
  • Control for restarting game

John:

  • Graphics for all game objects: Lander Module, Landing Target and Tower
  • Terrain and Skybox
  • Camera behavior

Cheryl:

  • Compilation of Ogre Ode source files and demos and integration of Ogre Ode with LIAV
  • Adding ODE properties to the Lander
  • Keyboard control for thrusters on Lander
  • Particle effects for thrusters and crash landings

Lessons Learned

Overall, the entire project went well. We were able to divide the work into areas with as little overlap as possible. This allowed each of us to work on a separate section of the project and there was little difficulty in recombining versions of the code.

To some extent we were able to leverage each person's technical background to our best advantage. John's experience with graphics enabled us to use existing Google SketchUp models for the lunar lander and for the landing target. Jason's experience with sound engines was helpful for tracking down the bugs with the sound in the original LIAV software and for adding sound to the Life is a Space Odyssey game.

We had identified integrating OgreOde with LIAV as one of the key technical issues for the project. Thus, we tackled the integration of OgreOde early on, ensuring that it would not become a show stopper late in the project. By the mid-point of the term, we had a playable demo and all features added since then have merely improved upon the game experience.

If we repeated this project, there are no major changes that we would make to the development process.