BFP camera code implementation
Posted: Sun Feb 05, 2023 2:23 pm
I'm implementing BFP camera view, but it doesn't do the same like original Bid For Power (BFP). But AFAIK, the code uses modified Q3 camera parts, it doesn't do the same as ZEQ2-Lite (nothing to do). The camera does a pretty wild flip when flying upside down, have less zoom/more distance than BFP, ... That's badly implemented. Just asking, what should be correct to be the same as BFP camera view?
Video comparising camera implementation and original BFP camera:
https://streamable.com/4gee0d
Code of the camera implementation in CG_OffsetThirdPersonView:
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];
}