Yesterday we posted part one our camera tutorials. Today we tackle how to create a third person chase cam(as seen in games such as Nightmare Creatures). This tutorial was written by J Bone.

All modifications in this tutorial take place in the client.c file.

The first thing we need to do is to let the engine know to render your character all the time(rather than only when you are looking in a mirror). If you have read our Overhead Camera Tutorial, then you know that this requires a simple modification to line 1359, which looks something like the line below:

    Player->Actor = geWorld_CreateActor(Host->World, ActorDef, GE_ACTOR_RENDER_MIRRORS|GE_ACTOR_COLLIDE, 0xffffffff);

We need to change the GE_ACTOR_RENDER_MIRRORS property to GE_ACTOR_RENDER_NORMAL, so that our line will look like this:

    Player->Actor = geWorld_CreateActor(Host->World, ActorDef, GE_ACTOR_RENDER_NORMAL|GE_ACTOR_COLLIDE, 0xffffffff);

All other changes in this tutorial will take place in the BuildClientViewXForm routine, which beings at line 1534, and looks like the code below:

static void BuildClientViewXForm(Client_Client *Client)
{
    geVec3d             Pos;
    GPlayer             *Player;

    assert(Client->ViewPlayer >= 0 && Client->ViewPlayer < HOST_MAX_PLAYERS);
   
    Player = &Client->Players[Client->ViewPlayer];

    Client->ViewXForm = Player->XForm;

    if (Client->Host->Demo.Mode != HOST_DEMO_PLAY && !(Player->ViewFlags & VIEW_TYPE_FORCE_XFORM))
    {
        Pos = Client->ViewXForm.Translation;

        // Clear the matrix
        geXForm3d_SetIdentity(&Client->ViewXForm);

        // Rotate then translate.
        geXForm3d_RotateZ(&Client->ViewXForm, Client->Angles.Z);

        geXForm3d_RotateX(&Client->ViewXForm, Client->Angles.X);
        geXForm3d_RotateY(&Client->ViewXForm, Client->Angles.Y);
   
        geXForm3d_Translate(&Client->ViewXForm, Pos.X, Pos.Y, Pos.Z);
    }

    // HACK the view height till we get it in
    // Just use a vakue that looks good for now...
    Client->ViewXForm.Translation.Y += 140.0f;
}

Adding a chase cam is a little bit more difficult than adding an overhead camera. The obvious solution would be to simply add a line to the bottom of the routine which would look like:

Client->ViewXForm.Translation.Z += 220.0f;

Basically what this line would do is to set the camera behind your model. The problem is that when your player spins to the left or right, your character will become off-centered, and our angle will become incorrect. So we need to write a routine that will cause our camera to turn with us and always remain directly behind our character. Here is the routine that we use to accomplish this feat:

static void BuildClientViewXForm(Client_Client *Client)
{
    float xtrans;   
    float ztrans;    //

   
    geVec3d             Pos;
    GPlayer             *Player;

    assert(Client->ViewPlayer >= 0 && Client->ViewPlayer < HOST_MAX_PLAYERS);
   
    Player = &Client->Players[Client->ViewPlayer];

    Client->ViewXForm = Player->XForm;

    if (Client->Host->Demo.Mode != HOST_DEMO_PLAY && !(Player->ViewFlags & VIEW_TYPE_FORCE_XFORM))
    {
        Pos = Client->ViewXForm.Translation;

        // Clear the matrix
        geXForm3d_SetIdentity(&Client->ViewXForm);

        // Rotate then translate.
        geXForm3d_RotateZ(&Client->ViewXForm, Client->Angles.Z);

        geXForm3d_RotateX(&Client->ViewXForm, Client->Angles.X);
        geXForm3d_RotateY(&Client->ViewXForm, Client->Angles.Y);
   
        xtrans = (float) (sin(Client->Angles.Y)*220.0f);   
        ztrans = (float) (cos(Client->Angles.Y)*220.0f);  

        geXForm3d_Translate(&Client->ViewXForm, Pos.X, Pos.Y, Pos.Z);
    }

    // HACK the view height till we get it in
    // Just use a vakue that looks good for now...
    Client->ViewXForm.Translation.Y += 140.0f;
   Client->ViewXForm.Translation.X += xtrans;
    Client->ViewXForm.Translation.Z += ztrans;

}

The above routine will cause our camera to remain in the proper viewing angle at all times. However there are still problems that occur when using a chase camera. The camera will still remain 220.0f behind your position. This can cause some viewing and clipping problems when your back is against a wall. Games such as Tomb Raider get around this problem by adding multiple camera's throughout their levels. The problem with this approach is that the camera change zones can sometimes leave you with poor views.

I do not want to turn this into an article on the problems of using a third person chase cam. This routine should help get you going, the rest is up to you. You can download the file associated with this tutorial by clicking here. As always you may send comments and suggestions via e-mail by clicking here.