Interactive 3D Graphics and Animation
COSC1186/1187 Assignment Report

Orcoid Army - By Ross Eldridge, 2107726G

Splash Image

Usage

Compiling the Application

To compile the application from the source files under Linux, simply change to the correct directory and type the following:
make

Running the Application And Command Line Options

To execute the now compiled application, simply type:
./orcs

This will run the application with the default platoon size of 3 ranks by 3 columns. If, however, you wish to specify your own platoon size, then use either of the following:
./orcs [number]

Where [number] is an integer between 1 and 10. This will create a square platoon, with [number] ranks and columns. Alternatively:
./orcs [ranks] [columns]

Where [ranks] and [columns] are both integers between 1 and 10. This will create a custom sized platoon, with [ranks] ranks and [columns] columns.
Note: Any values entered in the command line that are outside of 1 to 10 will simply default to 3.

Keyboard Binds

General

Rendering Specific Keys

Camera Keys

Segment Interaction Keys

Stance / Animation Keys

Functionality

Animations

Rendering Settings

Model / Mesh Subsystem

The orc model is loaded dynamically from a file during initialisation. I used a custom file format (that I've dubbed OB2), that expands on and alters the existing OBJ standard to suit the programs needs. It now supports:

The data is saved as plain text. The format is detailed in the source code comments in the loadModel() function.
The data is loaded into a fairly complex data structure, so that all segments can be easily accessed, moved, rotated and drawn. The main storage components are arrays, allocated to the sizes specified by the files. Any cross-model referencing is done with array indices, e.g. face -> vertices, animation keyframes -> segments.

The orcoid model itself was built using Kludge3D, a straightforward polygonal modeller for linux. I modelled each segment individually, as I would otherwise need to implement mesh warping and a bone system, which is more complex. I created the model using the following heirarchy:

     Root
     \_Torso
       |_Head
       | |_Eyes
       | |_Jaw
       | \_Teeth
       |_RightUpperArm
       | \_RightLowerArm
       |   \_RightHand
       |     \_Blade
       |_LeftUpperArm
       | \_LeftLowerArm
       |   \_LeftHand
       |     \_Shield
       \_Hips
         |_RightThigh
         | \_RightCalf
         |   \_RightHindfoot
         |     \_RightToes
         \_LeftThigh
           \_LeftCalf
             \_LeftHindfoot
             \_LeftToes

When drawing the model, it starts with the first segment, and renders each mesh recursively for all of its children. This allows all of the offsets and rotations to be relative to the current segment, which makes positioning segments for stances/animations straightforward.

Animation / Stance Subsystem

As mentioned in the last section, animations / stances are included in the OB2 model format, and hence are loaded at runtime with the rest of the mesh and stance data. Each stance is simply a list of X, Y, Z rotations, one set for each segment of the model. The animations are simply an extrapolation of that, with multiple stances being store per animation. The frames are interpolated linearly in real-time, to smooth the movement.

Additional Graphics

Design and Development

The program was initially designed around the robot-arm example, as it had some good examples of joint manipulation. I then attempted to work on some basic animation functions, with linear interpolation, however this quickly led to my next requirement, being a file format.

Being fairly familiar with polygonal modelling, I decided early on to develop my own file format, one that could be easily converted from existing formats. After fumbling around with Blender, I stumbled upon kludge3d, a free, open-source polygonal modeller for linux. As this supported the .OBJ model format, I decided to modify and expand upon it, as detailed above in the Model / Mesh subsystem section.

After I had modelled all of the segments, I constructed a stance format, and a simple function to save the current stance to disk. Thereby I could easily create new stances, and later, new animations. Once I had the main stances done, I went to work on the 2D "User Interface".

After messing around with the FPS display, I eventually created a simple "wrapper" for rendering all of the 2D elements: a function that accepts a string, and x, y positions as inputs, sets up the correct 2D matrix and renders the text with the (globally) selected font. However it was also around this point that I noticed a significant FPS drop, one that I don't think I successfully fixed. In any case, I then finally moved on to animations.

I designed a simple keyframe animation model, where each frame is simply a stance with a "time" value, that defines how many milliseconds after the initial frame that it occurs. Now a long way into development, I finally implemented the linear interpolation and animation functionality I intended to write at the beginning. This took a lot longer to implement that it should, as I spent hours trying to reason out why my animation was running backwards, or worse, running out of control. After careful analysis it came down to a typo in the interpolation formula that somehow eluded me.

For the final touches, I decided to create a random rocky terrain, and render a platoon of orcs, of variable size. These were fairly easy to implement, as the additional orcs are merely clones, offset and redrawn from the initial orc, and the terrain randomised versions of a single rock model.

Possible Additions

Given more time, here a few additions I would like to have made. These are just the more unique ideas I had, I've left out more generic additions such as texture mapping.

Functional

Graphical / Eye Candy

Back-end

Additional Screenshots

Early blue skinned orcs, simple stance.
Blue orcs again, charge animation.
Blue orcs paused during mid-swing.
100 red orcs on a rocky field - Wireframe.
100 red orcs on a rocky field - Smooth shaded.
Sleeping blue skinned orcs - Wireframe.
Sleeping blue skinned orcs - Flat shaded.
First known screenshot, barely an extension of the robot arm example.
Green skinned orcs during earlier testing.
The first brighter red orcs.
Recent version, showing psuedo-lighting effects on the ground, and a secondary light source.
Latest version, similar to above but with increased ambient lighting.

Valid
          XHTML 1.1!