custom chasecam tutorial
Posted: Sat Sep 20, 2008 4:33 pm
This small tutorial is inspired by the excellent ArcadeQuake project shown in the last QExpo. We will add a customizable 3rd. person chasecam, enabled by the original chase_active cvar using the value = 2 (chase_active 1 stills working as usual). I am assuming vanilla GLQuake / WinQuake source code with the almost mandatory chasecam fix tutorial applied as the base code. If you don't want or can't apply this fix, just skip the commented part in the code, although the camera will "see" through the world geometry.
So, let's start opening up the chase.c. At the begin, you will find this:
After it, add these new cvars:
These will control the fixed angles of our camera. The default values are set to show the player in the same angle as in a side-scroller game.
Below, we have the Chase_Init () function. We paste this at the end of the code:
Now we can access our new cvars by console.
Finally, we will replace the original Chase_Update function with this:
And that's it. Compile the code, start a new single player game, bring down the console and experiment with the cvars values, like this:
So, let's start opening up the chase.c. At the begin, you will find this:
Code: Select all
cvar_t chase_back = {"chase_back", "100"};
cvar_t chase_up = {"chase_up", "16"};
cvar_t chase_right = {"chase_right", "0"};
cvar_t chase_active = {"chase_active", "0"};
Code: Select all
cvar_t chase_roll = {"chase_roll", "0"};
cvar_t chase_yaw = {"chase_yaw", "180"};
cvar_t chase_pitch = {"chase_pitch", "45"};
Below, we have the Chase_Init () function. We paste this at the end of the code:
Code: Select all
Cvar_RegisterVariable (&chase_roll);
Cvar_RegisterVariable (&chase_yaw);
Cvar_RegisterVariable (&chase_pitch);
Finally, we will replace the original Chase_Update function with this:
Code: Select all
void Chase_Update (void)
{
int i;
float dist;
vec3_t forward, up, right;
vec3_t dest, stop;
if ((int)chase_active.value != 2)
{
// if can't see player, reset
AngleVectors (cl.viewangles, forward, right, up);
// calc exact destination
for (i=0 ; i<3 ; i++)
chase_dest[i] = r_refdef.vieworg[i]
- forward[i]*chase_back.value
- right[i]*chase_right.value;
chase_dest[2] = r_refdef.vieworg[2] + chase_up.value;
// find the spot the player is looking at
VectorMA (r_refdef.vieworg, 4096, forward, dest);
TraceLine (r_refdef.vieworg, dest, stop);
// calculate pitch to look at the same spot from camera
VectorSubtract (stop, r_refdef.vieworg, stop);
dist = DotProduct (stop, forward);
if (dist < 1)
dist = 1;
r_refdef.viewangles[PITCH] = -atan(stop[2] / dist) / M_PI * 180;
TraceLine(r_refdef.vieworg, chase_dest, stop);
if (Length(stop) != 0)
VectorCopy(stop, chase_dest);
// move towards destination
VectorCopy (chase_dest, r_refdef.vieworg);
}
else
{
chase_dest[0] = r_refdef.vieworg[0] + chase_back.value;
chase_dest[1] = r_refdef.vieworg[1] + chase_right.value;
chase_dest[2] = r_refdef.vieworg[2] + chase_up.value;
// this is from the chasecam fix - start
TraceLine (r_refdef.vieworg, chase_dest, stop);
if (Length (stop) != 0)
{
VectorCopy (stop, chase_dest);
}
// this is from the chasecam fix - end
VectorCopy (chase_dest, r_refdef.vieworg);
r_refdef.viewangles[ROLL] = chase_roll.value;
r_refdef.viewangles[YAW] = chase_yaw.value;
r_refdef.viewangles[PITCH] = chase_pitch.value;
}
}
Code: Select all
chase_active 2
chase_up 64
chase_pitch 45
chase_back 200
