Fix camera not rotating smoothly

Reducing camera angle in damageYaw to 8-bit caused camera to be limited
to 256 angles and not rotate smoothly.

Restore setting it locally in higher precision as a separate variable
(damageAngles) but still keep it as 8-bit in damagePitch/damageYaw so
it networks correctly.

Issue introduced in "Fix sending angles in damagePitch/damageYaw".
This commit is contained in:
Zack Middleton 2023-12-09 18:18:35 -06:00
parent 226fc030cd
commit 528645fe86
9 changed files with 60 additions and 38 deletions

View file

@ -320,6 +320,10 @@ static void CG_ExtrapolatePlayerState( qboolean grabAngles ) {
if ( !grabAngles ) {
out->damagePitch = prev->ps.damagePitch;
out->damageYaw = prev->ps.damageYaw;
out->damageAngles[PITCH] = BYTE2ANGLE(prev->ps.damagePitch);
out->damageAngles[YAW] = BYTE2ANGLE(prev->ps.damageYaw);
out->damageAngles[ROLL] = 0;
}
for ( i = 0 ; i < 3 ; i++ ) {
@ -420,6 +424,10 @@ static void CG_InterpolatePlayerState( qboolean grabAngles ) {
if ( !grabAngles ) {
out->damagePitch = ANGLE2BYTE(LerpAngle( BYTE2ANGLE(prev->ps.damagePitch), BYTE2ANGLE(next->ps.damagePitch), f ));
out->damageYaw = ANGLE2BYTE(LerpAngle( BYTE2ANGLE(prev->ps.damageYaw), BYTE2ANGLE(next->ps.damageYaw), f ));
out->damageAngles[PITCH] = LerpAngle( BYTE2ANGLE(prev->ps.damagePitch), BYTE2ANGLE(next->ps.damagePitch), f );
out->damageAngles[YAW] = LerpAngle( BYTE2ANGLE(prev->ps.damageYaw), BYTE2ANGLE(next->ps.damageYaw), f );
out->damageAngles[ROLL] = 0;
}
// END
@ -1009,6 +1017,7 @@ void CG_PredictPlayerState( void ) {
// over the net.
// This function overwrites the damageYaw and damagePitch values based on
// the command and the delta_angles of the player
// This also sets damageAngles which is not reduced to 8-bit
PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd, cg_controlMode.integer );
// }
// END

View file

@ -690,9 +690,7 @@ static int CG_CalcViewValues( void ) {
VectorCopy( ps->origin, cg.refdef.vieworg );
// STONELANCE (uses new way of sending view angles)
// VectorCopy( ps->viewangles, cg.refdefViewAngles );
cg.refdefViewAngles[PITCH] = BYTE2ANGLE(ps->damagePitch);
cg.refdefViewAngles[YAW] = BYTE2ANGLE(ps->damageYaw);
cg.refdefViewAngles[ROLL] = 0;
VectorCopy( ps->damageAngles, cg.refdefViewAngles );
// END
AnglesToAxis( cg.refdefViewAngles, cg.refdef.viewaxis );
return CG_CalcFov();
@ -759,9 +757,7 @@ static int CG_CalcViewValues( void ) {
// if( !cg_paused.integer )
// Com_Printf( "5 predictedPlayerState damageYaw %d\n", ps->damageYaw );
cg.refdefViewAngles[PITCH] = BYTE2ANGLE(ps->damagePitch);
cg.refdefViewAngles[YAW] = BYTE2ANGLE(ps->damageYaw);
cg.refdefViewAngles[ROLL] = 0;
VectorCopy( ps->damageAngles, cg.refdefViewAngles );
}
// rear view mirror setup
@ -795,8 +791,8 @@ static int CG_CalcViewValues( void ) {
#else
// Use third-person mouse view (not car viewpoint)
angles[ROLL] = 0;
angles[PITCH] = 0; // BYTE2ANGLE(ps->damagePitch);
angles[YAW] = BYTE2ANGLE(ps->damageYaw);
angles[PITCH] = 0; // ps->damageAngles[PITCH];
angles[YAW] = ps->damageAngles[YAW];
#endif
AnglesToAxis( angles, cg.mmapRefdef.viewaxis );

View file

@ -1938,8 +1938,8 @@ void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean
}
// View Angles
s->angles2[PITCH] = BYTE2ANGLE(ps->damagePitch);
s->angles2[YAW] = BYTE2ANGLE(ps->damageYaw);
s->angles2[PITCH] = ps->damageAngles[PITCH];
s->angles2[YAW] = ps->damageAngles[YAW];
// s->angles2[YAW] = ps->movementDir;
// END
s->legsAnim = ps->legsAnim;
@ -2065,8 +2065,8 @@ void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s
// END
// View Angles
s->angles2[PITCH] = BYTE2ANGLE(ps->damagePitch);
s->angles2[YAW] = BYTE2ANGLE(ps->damageYaw);
s->angles2[PITCH] = ps->damageAngles[PITCH];
s->angles2[YAW] = ps->damageAngles[YAW];
// s->angles2[YAW] = ps->movementDir;
// END
s->legsAnim = ps->legsAnim;

View file

@ -961,7 +961,7 @@ static void PM_NoclipMove( void ) {
VectorMA (pm->ps->origin, pml.frametime, pm->ps->velocity, pm->ps->origin);
// STONELANCE
pm->ps->viewangles[YAW] = BYTE2ANGLE(pm->ps->damageYaw);
pm->ps->viewangles[YAW] = pm->ps->damageAngles[YAW];
PM_InitializeVehicle(pm->car, pm->ps->origin, pm->ps->viewangles, pm->ps->velocity /* , pm->car_frontweight_dist */ );
// END
}
@ -2375,6 +2375,9 @@ void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd, int controlMo
int i;
if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPINTERMISSION) {
ps->damageAngles[PITCH] = BYTE2ANGLE( ps->damagePitch );
ps->damageAngles[YAW] = BYTE2ANGLE( ps->damageYaw );
ps->damageAngles[ROLL] = 0;
return; // no view changes at all
}
@ -2400,18 +2403,24 @@ void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd, int controlMo
}
}
// STONELANCE use damage yaw and pitch for view angles
if (controlMode == CT_MOUSE){
if (i == PITCH){
ps->damagePitch = ANGLE2BYTE( SHORT2ANGLE( temp ) );
}
if (i == YAW){
ps->damageYaw = ANGLE2BYTE( SHORT2ANGLE( temp ) );
}
// Q3Rally
// ps->viewangles[i] = SHORT2ANGLE(temp);
if ( controlMode == CT_MOUSE ) {
ps->damageAngles[i] = SHORT2ANGLE(temp);
}
// END
// SKWID
// ps->viewangles[i] = SHORT2ANGLE(temp);
}
// STONELANCE use damage yaw and pitch for view angles
if ( controlMode == CT_MOUSE ) {
// camera view angle
ps->damagePitch = ANGLE2BYTE( SHORT2ANGLE( ps->damageAngles[PITCH] ) );
ps->damageYaw = ANGLE2BYTE( SHORT2ANGLE( ps->damageAngles[YAW] ) );
} else /* CT_JOYSTICK */ {
// wheel angle
ps->damageAngles[PITCH] = BYTE2ANGLE( ps->damagePitch );
ps->damageAngles[YAW] = BYTE2ANGLE( ps->damageYaw );
ps->damageAngles[ROLL] = 0;
}
// END
}
@ -2427,7 +2436,7 @@ void trap_SnapVector( float *v );
void PmoveSingle (pmove_t *pmove) {
// STONELANCE
vec3_t delta;
//vec3_t delta;
float dot;
// END
@ -2519,10 +2528,7 @@ void PmoveSingle (pmove_t *pmove) {
PM_UpdateViewAngles( pm->ps, &pm->cmd, pm->controlMode );
// AngleVectors (pm->ps->viewangles, pml.forward, pml.right, pml.up);
delta[YAW] = BYTE2ANGLE(pm->ps->damageYaw);
delta[PITCH] = BYTE2ANGLE(pm->ps->damagePitch);
delta[ROLL] = 0;
AngleVectors (delta, pml.forward, pml.right, pml.up);
AngleVectors (pm->ps->damageAngles, pml.forward, pml.right, pml.up);
// END
if ( pm->cmd.upmove < 10 ) {

View file

@ -517,7 +517,7 @@ void PM_AddRoadForces(car_t *car, carBody_t *body, carPoint_t *points, float sec
}
if (pm->controlMode == CT_MOUSE){
car->wheelAngle = WheelAngle(pm->ps->viewangles[YAW], BYTE2ANGLE(pm->ps->damageYaw));
car->wheelAngle = WheelAngle(pm->ps->viewangles[YAW], pm->ps->damageAngles[YAW]);
if (v < 0.5f && v > -0.5f)
car->wheelAngle = 0.0;
@ -561,8 +561,11 @@ void PM_AddRoadForces(car_t *car, carBody_t *body, carPoint_t *points, float sec
if (car->wheelAngle < -20.0f)
car->wheelAngle = -20.0f;
pm->ps->damagePitch = ANGLE2BYTE(0.0f);
pm->ps->damageYaw = ANGLE2BYTE(car->wheelAngle);
pm->ps->damageAngles[PITCH] = 0.0f;
pm->ps->damageAngles[YAW] = car->wheelAngle;
pm->ps->damagePitch = ANGLE2BYTE(pm->ps->damageAngles[PITCH]);
pm->ps->damageYaw = ANGLE2BYTE(pm->ps->damageAngles[YAW]);
}
}
else {

View file

@ -1769,8 +1769,9 @@ void SpectatorClientEndFrame( gentity_t *ent ) {
}
}
ent->client->ps.damagePitch = ANGLE2BYTE(ent->client->ps.viewangles[PITCH]);
ent->client->ps.damageYaw = ANGLE2BYTE(ent->client->ps.viewangles[YAW]);
VectorCopy( ent->client->ps.viewangles, ent->client->ps.damageAngles );
ent->client->ps.damagePitch = ANGLE2BYTE(ent->client->ps.damageAngles[PITCH]);
ent->client->ps.damageYaw = ANGLE2BYTE(ent->client->ps.damageAngles[YAW]);
ent->client->ps.pm_flags |= PMF_OBSERVE;
return;

View file

@ -590,9 +590,10 @@ void SetClientViewAngle( gentity_t *ent, vec3_t angle ) {
VectorCopy( angle, ent->s.angles );
VectorCopy (ent->s.angles, ent->client->ps.viewangles);
// STONELANCE
VectorCopy( angle, ent->s.angles2 );
ent->client->ps.damagePitch = ANGLE2BYTE(ent->s.angles2[PITCH]);
ent->client->ps.damageYaw = ANGLE2BYTE(ent->s.angles2[YAW]);
VectorCopy (ent->s.angles, ent->client->ps.damageAngles);
VectorCopy( angle, ent->s.angles2 ); // FIXME: need this?
ent->client->ps.damagePitch = ANGLE2BYTE(ent->client->ps.damageAngles[PITCH]);
ent->client->ps.damageYaw = ANGLE2BYTE(ent->client->ps.damageAngles[YAW]);
// END
}

View file

@ -1143,9 +1143,10 @@ void MoveClientToIntermission( gentity_t *ent ) {
VectorCopy( level.intermission_origin, ent->client->ps.origin );
// STONELANCE (used for viewing angles client side)
// VectorCopy (level.intermission_angle, ent->client->ps.viewangles);
VectorCopy (level.intermission_angle, ent->client->ps.damageAngles);
VectorCopy( level.intermission_angle, ent->s.angles2 ); // FIXME: need this?
ent->client->ps.damagePitch = ANGLE2BYTE(ent->s.angles2[PITCH]);
ent->client->ps.damageYaw = ANGLE2BYTE(ent->s.angles2[YAW]);
ent->client->ps.damagePitch = ANGLE2BYTE(ent->client->ps.damageAngles[PITCH]);
ent->client->ps.damageYaw = ANGLE2BYTE(ent->client->ps.damageAngles[YAW]);
// END
ent->client->ps.pm_type = PM_INTERMISSION;

View file

@ -1347,6 +1347,11 @@ typedef struct playerState_s {
int pmove_framecount;
int jumppad_frame;
int entityEventSequence;
// float angles for camera view angle (CT_MOUSE) or wheel angle (CT_JOYSTICK)
// they are networked as 8-bit in playerState_t damagePitch and damageYaw
// and float in entityState_t angles2
vec3_t damageAngles;
} playerState_t;