"Dino 2" Technical Demonstration

Programming: James Russell
Modelling/Animation/Textures: Mark Prettyman
Additional Animation: Barry Scott
Sound: Jason Page
Tools: Mark Breugelmans

Background

The original "Dino" demo, which showed an animated T-Rex walking on a blank background, was one of the first PlayStation programs to show off the power of the PlayStation platform. Years down the track, it was decided to update the demo to showcase the new technologies like the Dual Shock vibrating controller and the HMD file format.

Specification

This demonstration was designed primarily to give new users a Dual Shock experience. In addition, the source would be provided as sample code to help developers use the Dual Shock and give concrete examples of the variety of ways the HMD format can be used.

A rough storyboard of the demo would start off the with the camera facing down into the pond, which is reflecting the sky. A 'thud' would be heard, the vibration of the thud would cause the water in the pond to ripple and the the Dual Shock to vibrate accordingly. More 'thuds' would be heard as the dinosaur approached, until the picture shows its horns reflected in the water. The camera dollys back and pans up to show the dinosaur, which roars, and moves backwards. From this point on, the user has control of both the camera and the dinosaur. The dinosaur's environment is a forest clearing, and the dinosaur can walk around the pond. The user can control whether the dinosaur moves backwards or forwards, can move the dinosaur's head, wag its tail and stomp its foot. When the dinosaur stomps its foot, it causes the ground to shake. The camera can be moved around the clearing, and can be dollied in or out. Periodically, the nearby volcano erupts, which causes the ground to shake.

Originally, the pond was to show a true reflection of the environment and the dinosaur in such a way that the reflection itself could be rippled realistically. Unfortunately CPU constraints meant that this was not feasible in conjunction with a full frame rate. Instead the initial sequence where the user does not have control contains the ripple, and then as the camera pans out the scene is changed so that the reflection looks correct, but without the ripple. For more detail, see below.

After running trial versions of the demo through the DTL-2700 Performance Analyzer, many optimisations were made to increase the speed and resolution of the demo. The demo runs at 50 frames per second at a resolution of 512x256. It processes about 1800 polygons per frame, and draws up to 1300 polygons per frame.

HMD

The HMD (Hierarchical Modelling Format) file format is a general purpose, flexible and versatile format that includes multiple co-ordinate systems, images, skinning (also known as shared polygons) and animation, among other categories. HMD allows you to quickly and easily build programs, and extend the functionality of the format where needed. HMD is used for most of the models in this demonstration in a variety of ways.

Demo coding overview

The general structure of the demo is very simple. There are two 'modes' of operation. The first mode is the initial sequence where the user does not have control, and the application is performing operations like the ripple and moving the dinosaur. This is called the Intro mode. The second mode is where the camera pans back, and the user has control. This is called the Main mode. After the Intro mode has finished, the application switches to the Main mode and stays in that mode until the demo exits. The way drawing is performed depends on which mode is currently active.

Notes:

Intro mode

In Intro mode, the requirement is to draw the reflection of the scene in the pond, rippling it if necessary (the rippling is caused by the dinosaur's footfall), and integrate the rippled pond with the rest of the environment. Because the original specification called for the reflected environment in the pond to be rippled at any time, it was necessary to first render this environment to an off screen buffer, then use this off screen buffer as a texture for the pond, distorting the U/V co-ordinates in such a way as to create the illusion of the water rippling. Initial experiments were promising, but further down the track it was found to be too computationally expensive to get an accurate result from an arbitrary camera position. With this in mind, the specification was altered so that the ripple only occurs in the period of time where the camera is not under the user's control.

The basic loop for the Intro mode is to:

This is very similar to the Main mode's loop, so we just use a flag to change behaviour where the loops differ.

Notes:

Optimisations:

Main mode

The Main mode of the program is slightly different to the Intro mode. The way the drawing is performed is quite different, and even a different Environment HMD is used.

The basic loop for the Main mode is to:

The Main mode differs from the Intro mode in the way the reflection is performed. The Intro mode renders the reflected polygons to the off screen buffer, but the main mode renders them straight to the main screen buffer using a different camera angle and position to give the illusion of reflection. In addition, the semi-trans polygons of the pond in the Intro mode cause the reflection to be darker than the 'real' image. To simulate this in Main mode, the drivers will change the RGB of any reflected polygon to be (32,32,32) instead of (128,128,128).

Animation format

The animation format used was not HMD, because the tools were not available at the time to create the necessary data. Instead, a very simple format that was created by Sony's 1st party publishers was used. This animation format contains a number of keyframes, and for each keyframe it holds the translation of the root node of the model and the rotations of each co-ordinate system in the model's hierarchy. This format suffices for most purposes, but as a downside it is not possible to  'stretch' a bone (alter the translation at any node other than root). However it is a very simple format, and easy to integrate into the demo.

To set the model to a particular animation frame, all that is required is to change the root translation and create the 3x3 matrix (using RotMatrix) for each co-ordinate system based on the 3 Euler angles for that frame/coordinate system (stored in the animation file).

There are 3 animation files in use here. The first is the 'back off' animation, where the dinosaur moves away from the pond and into the starting position. The second and third files are a collection of the animation 'states' that the dinosaur can be in when walking forwards and backwards respectively.

For both forwards and backwards movement, the dinosaur's animation has 3 'state change' positions, and there are animations for moving between these frames. The 3 keyframes could be described as 'stopped' (where the dinosaur is not moving its feet), 'walk1' (the end of the first part of the stride), and 'walk2' (the end of the second part of the stride). There are 6 animations to move between these state change positions, and 2 extra animations for when the dinosaur stomps its foot, and shifts its weight (it performs this after a certain length of inactivity).


In this diagram, the circles represent the foot positions of the dino. They are called Stop, Walk 1, Walk 2, Backwalk 1 and Backwalk 2. The arrows indicate animations between these states. The function AnimNextState() will return the next animation to play given a current state and a desired state.
 

HMD coding

There are 6 HMD files used by the demo:
  1. Dinosaur HMD. Contains 22 co-ordinate systems, and includes skinning.
  2. Shadow HMD. Contains 1 semi-transparent polygon which is the dinosaur's shadow. The reason why this is not integrated into the dinosaur's model is because the co-ordinate system it attaches to is different depending on which animation file is being used. The 'backoff' animation file requires the shadow to be attached to the dinosaur's root node, while the other animation files require the shadow to be attached to the handler node (which is one above the root node).
  3. Environment HMD. Contains the outer cylinder (which are textured with trees), the ground, and the 2 outmost 'real' trees. The bed of the pond consists of normal polygons, as the water will be added on top using semi-trans polygons. This model is used only in Intro Mode.
  4. Environment HMD NP. Identical to the Environment HMD model, except the bed of the pond consists of semi-transparent polygons. This is because in Main mode, the reflection is draw to the main screen before the environment.
  5. Innermost tree HMD. This is the tree that stands next to the pond. It is separated from the environment HMD because it needs to be sorted into a different OT. We can be sure that the dinosaur will always be drawn after the two outermost trees, but not the innermost tree, so we sort this innermost tree into the same OT as the dinosaur.
  6. Trees HMD. This contains the 3 trees in the environment. They are used in the reflection only. The difference between this model's trees and the trees in the Environment HMD files above are that these trees have tops (with leaves and branches). This is because they will be seen in the reflection. The camera constraints in the Environment HMD model mean that the tops of the trees will never be visible, so they have been removed from those models.
These files were created in Alias¦Wavefront, and exported using the CHR exporter and CHR2LAB (available from the SCEE website). Some of the LAB files were manually edited by hand.

With the exception of the dinosaur and it's shadow, standard Gs co-ordinate systems were used for all HMDs.

Controller Pad coding

The demo was designed as a an application to show off the Dual Shock controller pad's features. The demo assumes that a Dual Shock is plugged in, but will function (without the ability to move the head) if a standard controller is not plugged in. Because of this assumption, the program will lock the Dual Shock into analog mode if it is available. If analog is not available, the digital pad will mimic the action of the left analog stick.

The function processController() is run every frame, and handles the pad state changes that can occur when a controller is removed or inserted.

To make the interface simpler for the program, the function maintains two global flags. One states whether there is a controller inserted and the communication with it is stable, and the other indicates whether this controller is in analog mode.

Firstly, the function checks the current state. If the state is stable, but the validController flag indicates that there was no valid controller previously, then a new controller must have been inserted and communication must have been established. Now we know that there is a valid controller, but if it is a Dual Shock then we have to set the alignment so we can send vibration data back to the controller, and lock the mode into analog mode. If the controller is not a Dual Shock, then we cannot lock either the mode nor any digital/analog mode switches.

When a Dual Shock is first inserted and communication becomes stable, it is necessary to set the alignment with PadSetActAlign so that actuator information can be sent to the controller. When this function is called, however, the state changes to "Communicating with Controller", and it is necessary to wait until communcation is stable again before attempting to lock the controller into a different mode.

The analog sticks control the movement of the camera and the movement of the dinosaur's head. If the sticks are left at rest, it is possible for the analog values to jitter between one or two values. To stop this from happening, the analog values returned by getAnalogValues() are only copied verbatim if they lie beyond a certain threshold from the standard rest value of 0x80.