Video comparising camera implementation and original BFP camera:
https://streamable.com/4gee0d
Code of the camera implementation in CG_OffsetThirdPersonView:
Code: Select all
/*
===============
CG_OffsetThirdPersonView
===============
*/
#define FOCUS_DISTANCE 512
static void CG_OffsetThirdPersonView( void ) {
vec3_t forward, right, up;
vec3_t view;
vec3_t focusAngles;
trace_t trace;
static vec3_t mins = { -4, -4, -4 };
static vec3_t maxs = { 4, 4, 4 };
vec3_t focusPoint;
float focusDist;
float forwardScale, sideScale;
// BFP - TODO: Improve camera, when player looks at the ground, the view should
// be adjusted where the player position, in the screen, is further down like BFP does.
// The camera isn't using a fixed view
cg.refdef.vieworg[2] += cg.predictedPlayerState.viewheight;
VectorCopy( cg.refdefViewAngles, focusAngles );
// if dead, look at killer
if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
focusAngles[YAW] = cg.predictedPlayerState.stats[STAT_DEAD_YAW];
cg.refdefViewAngles[YAW] = cg.predictedPlayerState.stats[STAT_DEAD_YAW];
}
// if ( focusAngles[PITCH] > 45 ) {
// focusAngles[PITCH] = 45; // don't go too far overhead
// }
AngleVectors( focusAngles, forward, NULL, NULL );
VectorMA( cg.refdef.vieworg, FOCUS_DISTANCE, forward, focusPoint );
VectorCopy( cg.refdef.vieworg, view );
// view[2] += 8;
// BFP - Third person camera height
view[2] += cg_thirdPersonHeight.value + 92;
// BFP - Keep the looking on the ground at the same main focus position
// if ( !( cg.predictedPlayerState.pm_flags & PMF_FLYING ) ) {
cg.refdefViewAngles[PITCH] *= 1.55;
// }
AngleVectors( cg.refdefViewAngles, forward, right, up );
forwardScale = cos( cg_thirdPersonAngle.value / 180 * M_PI );
sideScale = sin( cg_thirdPersonAngle.value / 180 * M_PI );
VectorMA( view, -cg_thirdPersonRange.value * forwardScale, forward, view );
VectorMA( view, -cg_thirdPersonRange.value * sideScale, right, view );
// trace a ray from the origin to the viewpoint to make sure the view isn't
// in a solid block. Use an 8 by 8 block to prevent the view from near clipping anything
// if (!cg_cameraMode.integer) {
CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID );
if ( trace.fraction != 1.0 ) {
VectorCopy( trace.endpos, view );
view[2] += (1.0 - trace.fraction) * 32;
// try another trace to this position, because a tunnel may have the ceiling
// close enogh that this is poking out
CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID );
VectorCopy( trace.endpos, view );
}
// }
VectorCopy( view, cg.refdef.vieworg );
// select pitch to look at focus point from vieword
VectorSubtract( focusPoint, cg.refdef.vieworg, focusPoint );
focusDist = sqrt( focusPoint[0] * focusPoint[0] + focusPoint[1] * focusPoint[1] );
if ( focusDist < 1 ) {
focusDist = 1; // should never happen
}
// cg.refdefViewAngles[PITCH] = -180 / M_PI * atan2( focusPoint[2], focusDist );
cg.refdefViewAngles[PITCH] = focusAngles[PITCH];
cg.refdefViewAngles[YAW] -= cg_thirdPersonAngle.value;
//cg.refdefViewAngles[YAW] = focusAngles[YAW];
}