This tutorial intends to make the chase camera a little more intelligent. You can stand with a back to the wall
and the camera will
zoom nearer. You can stand on top of something and look down while the camera changes to some kind of first person
perspective.
! It is based on the first chase camera tutorial and assumes you have made the changes notified
in it !
The changes all take place again in Client.c in Function BuildClientViewXForm
static void BuildClientViewXForm(Client_Client *Client)
{
float xtrans;
float ztrans;
geVec3d Pos;
GPlayer *Player;
float Ydistance,distance; //Distance between Actor and camera
GE_Collision Collision;
geVec3d Front, Back, In, Help;
geVec3d Mins = {-1.0f, -1.0f, -1.0f};
geVec3d Maxs = { 1.0f, 1.0f, 1.0f};
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;
geXForm3d_GetIn(&Client->ViewXForm, &In);
//Send ray to examine if player is looking up or down by determining
the height difference
//(300.0f = max camera distance)
geVec3d_AddScaled(&Pos, &In, -1000.0f, &Help);
Ydistance=300.0f-(float)fabs(Pos.Y-Help.Y);
//Start sending ray 20.0f from behind Actor, or it will collide with
the Actor self
geVec3d_AddScaled(&Pos, &In, -20.0f, &Front);
//Start sending ray in View-Height
Front.Y = Front.Y +180.0f;
Back.Y = Back.Y +180.0f;
//Look 10000.0f behind
geVec3d_AddScaled(&Front, &In, -100000.0f, &Back);
//if backward ray collides with wall decrease camera distance
if (geWorld_Collision(Client->Host->World, NULL, NULL, &Front,
&Back, GE_COLLIDE_ALL, 0xffffffff, &Collision))
{
//Get Distance behind Actor and Wall
distance=(float)fabs(geVec3d_DistanceBetween(&Collision.Impact,&Front));
//Minimum between looking up/down and Wall behind
distance=min(distance,Ydistance);
//distance ranges:
if (distance<1.0f) distance=-20.0f;
if (distance>300.0f) distance=300.0f;
}
// 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);
//changed to variable camera distance
xtrans = (float) (sin(Client->Angles.Y)*distance);
ztrans = (float) (cos(Client->Angles.Y)*distance);
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...
// Set the viewheight from 140 to 180 else her big head will be in the
way ;-)
Client->ViewXForm.Translation.Y += 180.0f;
Client->ViewXForm.Translation.X += xtrans;
Client->ViewXForm.Translation.Z += ztrans;
}
This chase camera is quite away from being perfect (especially in the complex demo level) but it gives some nice
effects.
Problems to solve are:
- Clipping problems when jumping in rooms with low ceiling.
- perhaps too fast changes of the camera view
- aiming crosshair has become false (since we changed view height i guess, must be easy to correct ...)
Send comments and suggestions to Mark or to the Forum at Genesis3D
Greetings,
Mark Müller