Fixed some edge cases where camera position wouldn't match screen
This commit is contained in:
parent
e12b3581e2
commit
1475964e61
11 changed files with 128 additions and 29 deletions
|
@ -254,8 +254,7 @@ END_RECV_TABLE()
|
||||||
|
|
||||||
RecvPropInt ( RECVINFO( m_nWaterLevel ) ),
|
RecvPropInt ( RECVINFO( m_nWaterLevel ) ),
|
||||||
RecvPropFloat ( RECVINFO( m_flLaggedMovementValue )),
|
RecvPropFloat ( RECVINFO( m_flLaggedMovementValue )),
|
||||||
RecvPropVector(RECVINFO(m_vecPreviouslyPredictedOrigin)),
|
RecvPropVector(RECVINFO(m_vecPreviouslyPredictedOrigin))
|
||||||
RecvPropVector(RECVINFO(m_vecPreviousShootPosition)),
|
|
||||||
END_RECV_TABLE()
|
END_RECV_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
@ -376,7 +375,6 @@ BEGIN_PREDICTION_DATA( C_BasePlayer )
|
||||||
|
|
||||||
DEFINE_PRED_FIELD_TOL( m_vecBaseVelocity, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.05 ),
|
DEFINE_PRED_FIELD_TOL( m_vecBaseVelocity, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.05 ),
|
||||||
DEFINE_PRED_FIELD_TOL(m_vecPreviouslyPredictedOrigin, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, coordTolerance),
|
DEFINE_PRED_FIELD_TOL(m_vecPreviouslyPredictedOrigin, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, coordTolerance),
|
||||||
DEFINE_PRED_FIELD_TOL(m_vecPreviousShootPosition, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, coordTolerance),
|
|
||||||
DEFINE_FIELD( m_nButtons, FIELD_INTEGER ),
|
DEFINE_FIELD( m_nButtons, FIELD_INTEGER ),
|
||||||
DEFINE_FIELD( m_flWaterJumpTime, FIELD_FLOAT ),
|
DEFINE_FIELD( m_flWaterJumpTime, FIELD_FLOAT ),
|
||||||
DEFINE_FIELD( m_nImpulse, FIELD_INTEGER ),
|
DEFINE_FIELD( m_nImpulse, FIELD_INTEGER ),
|
||||||
|
|
|
@ -652,7 +652,6 @@ public:
|
||||||
float m_fLastUpdateServerTime;
|
float m_fLastUpdateServerTime;
|
||||||
int m_nLastUpdateTickBase;
|
int m_nLastUpdateTickBase;
|
||||||
int m_nLastUpdateServerTickCount;
|
int m_nLastUpdateServerTickCount;
|
||||||
Vector m_vecPreviousShootPosition;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN_RECV_TABLE(DT_BasePlayer);
|
EXTERN_RECV_TABLE(DT_BasePlayer);
|
||||||
|
|
|
@ -769,13 +769,14 @@ void CPrediction::StartCommand( C_BasePlayer *player, CUserCmd *cmd )
|
||||||
#if !defined( NO_ENTITY_PREDICTION )
|
#if !defined( NO_ENTITY_PREDICTION )
|
||||||
VPROF( "CPrediction::StartCommand" );
|
VPROF( "CPrediction::StartCommand" );
|
||||||
|
|
||||||
player->m_vecPreviousShootPosition = player->Weapon_ShootPosition();
|
|
||||||
|
|
||||||
CPredictableId::ResetInstanceCounters();
|
CPredictableId::ResetInstanceCounters();
|
||||||
|
|
||||||
player->m_pCurrentCommand = cmd;
|
player->m_pCurrentCommand = cmd;
|
||||||
C_BaseEntity::SetPredictionRandomSeed( cmd );
|
C_BaseEntity::SetPredictionRandomSeed( cmd );
|
||||||
C_BaseEntity::SetPredictionPlayer( player );
|
C_BaseEntity::SetPredictionPlayer( player );
|
||||||
|
|
||||||
|
InterpolationContexts[BEFORE_MOVEMENT].m_vecViewOffset = player->GetViewOffset();
|
||||||
|
InterpolationContexts[BEFORE_MOVEMENT].m_vecAbsOrigin = player->GetAbsOrigin();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,6 +844,40 @@ void CPrediction::RunThink (C_BasePlayer *player, double frametime )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPrediction::StartInterpolatingPlayer( C_BasePlayer *player )
|
||||||
|
{
|
||||||
|
#if !defined( NO_ENTITY_PREDICTION )
|
||||||
|
VPROF( "CPrediction::StartInterpolatingPlayer" );
|
||||||
|
|
||||||
|
// Let's interpolate the local player, this is similar to lag compensation,
|
||||||
|
// except it isn't since local player is always predicted. (except if user didn't want to for some reasons)
|
||||||
|
InterpolationContexts[AFTER_MOVEMENT].m_vecViewOffset = player->GetViewOffset();
|
||||||
|
InterpolationContexts[AFTER_MOVEMENT].m_vecAbsOrigin = player->GetAbsOrigin();
|
||||||
|
|
||||||
|
auto pCmd = player->m_pCurrentCommand;
|
||||||
|
|
||||||
|
Vector vecNewAbsOrigin = VectorLerp( InterpolationContexts[BEFORE_MOVEMENT].m_vecAbsOrigin,
|
||||||
|
InterpolationContexts[AFTER_MOVEMENT].m_vecAbsOrigin,
|
||||||
|
pCmd->interpolated_amount );
|
||||||
|
Vector vecNewViewOffset = VectorLerp( InterpolationContexts[BEFORE_MOVEMENT].m_vecViewOffset,
|
||||||
|
InterpolationContexts[AFTER_MOVEMENT].m_vecViewOffset,
|
||||||
|
pCmd->interpolated_amount );
|
||||||
|
|
||||||
|
player->SetAbsOrigin( vecNewAbsOrigin );
|
||||||
|
player->SetViewOffset( vecNewViewOffset );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPrediction::FinishInterpolatingPlayer( C_BasePlayer *player )
|
||||||
|
{
|
||||||
|
#if !defined( NO_ENTITY_PREDICTION )
|
||||||
|
VPROF( "CPrediction::FinishInterpolatingPlayer" );
|
||||||
|
|
||||||
|
player->SetAbsOrigin( InterpolationContexts[AFTER_MOVEMENT].m_vecAbsOrigin );
|
||||||
|
player->SetViewOffset( InterpolationContexts[AFTER_MOVEMENT].m_vecViewOffset );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: Called after player movement
|
// Purpose: Called after player movement
|
||||||
// Input : *player -
|
// Input : *player -
|
||||||
|
@ -992,8 +1027,12 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper
|
||||||
|
|
||||||
moveHelper->ProcessImpacts();
|
moveHelper->ProcessImpacts();
|
||||||
|
|
||||||
|
StartInterpolatingPlayer( player );
|
||||||
|
|
||||||
RunPostThink( player );
|
RunPostThink( player );
|
||||||
|
|
||||||
|
FinishInterpolatingPlayer( player );
|
||||||
|
|
||||||
ServiceEventQueue( player );
|
ServiceEventQueue( player );
|
||||||
|
|
||||||
g_pGameMovement->FinishTrackPredictionErrors( player );
|
g_pGameMovement->FinishTrackPredictionErrors( player );
|
||||||
|
|
|
@ -96,6 +96,8 @@ protected:
|
||||||
// Helpers to call pre and post think for player, and to call think if a think function is set
|
// Helpers to call pre and post think for player, and to call think if a think function is set
|
||||||
void RunPreThink( C_BasePlayer *player );
|
void RunPreThink( C_BasePlayer *player );
|
||||||
void RunThink (C_BasePlayer *ent, double frametime );
|
void RunThink (C_BasePlayer *ent, double frametime );
|
||||||
|
void StartInterpolatingPlayer( C_BasePlayer* player );
|
||||||
|
void FinishInterpolatingPlayer( C_BasePlayer* player );
|
||||||
void RunPostThink( C_BasePlayer *player );
|
void RunPostThink( C_BasePlayer *player );
|
||||||
void CheckMovingGround( CBasePlayer *player, double frametime );
|
void CheckMovingGround( CBasePlayer *player, double frametime );
|
||||||
private:
|
private:
|
||||||
|
@ -166,6 +168,20 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
TouchedHistory m_touchedHistory[MULTIPLAYER_BACKUP][MAX_EDICTS];
|
TouchedHistory m_touchedHistory[MULTIPLAYER_BACKUP][MAX_EDICTS];
|
||||||
|
|
||||||
|
// TODO_ENHANCED: checks if this affects vehicles properly too! It should.
|
||||||
|
enum INTERPOLATION_CONTEXT
|
||||||
|
{
|
||||||
|
BEFORE_MOVEMENT,
|
||||||
|
AFTER_MOVEMENT,
|
||||||
|
INTERPOLATION_CONTEXT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InterpolationContext
|
||||||
|
{
|
||||||
|
Vector m_vecAbsOrigin;
|
||||||
|
Vector m_vecViewOffset;
|
||||||
|
} InterpolationContexts[INTERPOLATION_CONTEXT_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CPrediction *prediction;
|
extern CPrediction *prediction;
|
||||||
|
|
|
@ -451,8 +451,7 @@ BEGIN_DATADESC( CBasePlayer )
|
||||||
DEFINE_FIELD( m_bDuckToggled, FIELD_BOOLEAN ),
|
DEFINE_FIELD( m_bDuckToggled, FIELD_BOOLEAN ),
|
||||||
DEFINE_FIELD( m_flForwardMove, FIELD_FLOAT ),
|
DEFINE_FIELD( m_flForwardMove, FIELD_FLOAT ),
|
||||||
DEFINE_FIELD( m_flSideMove, FIELD_FLOAT ),
|
DEFINE_FIELD( m_flSideMove, FIELD_FLOAT ),
|
||||||
DEFINE_FIELD( m_vecPreviouslyPredictedOrigin, FIELD_POSITION_VECTOR ),
|
DEFINE_FIELD( m_vecPreviouslyPredictedOrigin, FIELD_POSITION_VECTOR ),
|
||||||
DEFINE_FIELD( m_vecPreviousShootPosition, FIELD_POSITION_VECTOR ),
|
|
||||||
DEFINE_FIELD( m_nNumCrateHudHints, FIELD_INTEGER ),
|
DEFINE_FIELD( m_nNumCrateHudHints, FIELD_INTEGER ),
|
||||||
|
|
||||||
|
|
||||||
|
@ -7971,8 +7970,7 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data)
|
||||||
|
|
||||||
SendPropInt ( SENDINFO( m_nWaterLevel ), 2, SPROP_UNSIGNED ),
|
SendPropInt ( SENDINFO( m_nWaterLevel ), 2, SPROP_UNSIGNED ),
|
||||||
SendPropFloat ( SENDINFO( m_flLaggedMovementValue ), 0, SPROP_NOSCALE ),
|
SendPropFloat ( SENDINFO( m_flLaggedMovementValue ), 0, SPROP_NOSCALE ),
|
||||||
SendPropVector ( SENDINFO( m_vecPreviouslyPredictedOrigin ), 0, SPROP_NOSCALE),
|
SendPropVector ( SENDINFO( m_vecPreviouslyPredictedOrigin ), 0, SPROP_NOSCALE)
|
||||||
SendPropVector ( SENDINFO( m_vecPreviousShootPosition ), 0, SPROP_NOSCALE),
|
|
||||||
END_SEND_TABLE()
|
END_SEND_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1212,7 +1212,6 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const; // returns the solid mask for the given player, so bots can have a more-restrictive set
|
virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const; // returns the solid mask for the given player, so bots can have a more-restrictive set
|
||||||
CNetworkVar(Vector, m_vecPreviousShootPosition);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CHandle<CBasePlayer> CBasePlayerHandle;
|
typedef CHandle<CBasePlayer> CBasePlayerHandle;
|
||||||
|
|
|
@ -48,8 +48,6 @@ void CPlayerMove::StartCommand( CBasePlayer *player, CUserCmd *cmd )
|
||||||
{
|
{
|
||||||
VPROF( "CPlayerMove::StartCommand" );
|
VPROF( "CPlayerMove::StartCommand" );
|
||||||
|
|
||||||
player->m_vecPreviousShootPosition = player->Weapon_ShootPosition();
|
|
||||||
|
|
||||||
#if !defined( NO_ENTITY_PREDICTION )
|
#if !defined( NO_ENTITY_PREDICTION )
|
||||||
CPredictableId::ResetInstanceCounters();
|
CPredictableId::ResetInstanceCounters();
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,7 +55,10 @@ void CPlayerMove::StartCommand( CBasePlayer *player, CUserCmd *cmd )
|
||||||
player->m_pCurrentCommand = cmd;
|
player->m_pCurrentCommand = cmd;
|
||||||
CBaseEntity::SetPredictionRandomSeed( cmd );
|
CBaseEntity::SetPredictionRandomSeed( cmd );
|
||||||
CBaseEntity::SetPredictionPlayer( player );
|
CBaseEntity::SetPredictionPlayer( player );
|
||||||
|
|
||||||
|
InterpolationContexts[BEFORE_MOVEMENT].m_vecViewOffset = player->GetViewOffset();
|
||||||
|
InterpolationContexts[BEFORE_MOVEMENT].m_vecAbsOrigin = player->GetAbsOrigin();
|
||||||
|
|
||||||
#if defined (HL2_DLL)
|
#if defined (HL2_DLL)
|
||||||
// pull out backchannel data and move this out
|
// pull out backchannel data and move this out
|
||||||
|
|
||||||
|
@ -298,6 +299,36 @@ void CPlayerMove::RunThink (CBasePlayer *player, double frametime )
|
||||||
player->Think();
|
player->Think();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPlayerMove::StartInterpolatingPlayer( CBasePlayer *player )
|
||||||
|
{
|
||||||
|
VPROF( "CPlayerMove::StartInterpolatingPlayer" );
|
||||||
|
|
||||||
|
// Let's interpolate the local player, this is similar to lag compensation,
|
||||||
|
// except it isn't since local player is always predicted. (except if user didn't want to for some reasons)
|
||||||
|
InterpolationContexts[AFTER_MOVEMENT].m_vecViewOffset = player->GetViewOffset();
|
||||||
|
InterpolationContexts[AFTER_MOVEMENT].m_vecAbsOrigin = player->GetAbsOrigin();
|
||||||
|
|
||||||
|
auto pCmd = player->m_pCurrentCommand;
|
||||||
|
|
||||||
|
Vector vecNewAbsOrigin = VectorLerp( InterpolationContexts[BEFORE_MOVEMENT].m_vecAbsOrigin,
|
||||||
|
InterpolationContexts[AFTER_MOVEMENT].m_vecAbsOrigin,
|
||||||
|
pCmd->interpolated_amount );
|
||||||
|
Vector vecNewViewOffset = VectorLerp( InterpolationContexts[BEFORE_MOVEMENT].m_vecViewOffset,
|
||||||
|
InterpolationContexts[AFTER_MOVEMENT].m_vecViewOffset,
|
||||||
|
pCmd->interpolated_amount );
|
||||||
|
|
||||||
|
player->SetAbsOrigin( vecNewAbsOrigin );
|
||||||
|
player->SetViewOffset( vecNewViewOffset );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPlayerMove::FinishInterpolatingPlayer( CBasePlayer *player )
|
||||||
|
{
|
||||||
|
VPROF( "CPlayerMove::FinishInterpolatingPlayer" );
|
||||||
|
|
||||||
|
player->SetAbsOrigin( InterpolationContexts[AFTER_MOVEMENT].m_vecAbsOrigin );
|
||||||
|
player->SetViewOffset( InterpolationContexts[AFTER_MOVEMENT].m_vecViewOffset );
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: Called after player movement
|
// Purpose: Called after player movement
|
||||||
// Input : *player -
|
// Input : *player -
|
||||||
|
@ -458,8 +489,12 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper
|
||||||
moveHelper->ProcessImpacts();
|
moveHelper->ProcessImpacts();
|
||||||
VPROF_SCOPE_END();
|
VPROF_SCOPE_END();
|
||||||
|
|
||||||
|
StartInterpolatingPlayer( player );
|
||||||
|
|
||||||
RunPostThink( player );
|
RunPostThink( player );
|
||||||
|
|
||||||
|
FinishInterpolatingPlayer( player );
|
||||||
|
|
||||||
ServiceEventQueue( player );
|
ServiceEventQueue( player );
|
||||||
|
|
||||||
g_pGameMovement->FinishTrackPredictionErrors( player );
|
g_pGameMovement->FinishTrackPredictionErrors( player );
|
||||||
|
|
|
@ -52,6 +52,22 @@ protected:
|
||||||
void RunPreThink( CBasePlayer *player );
|
void RunPreThink( CBasePlayer *player );
|
||||||
void RunThink (CBasePlayer *ent, double frametime );
|
void RunThink (CBasePlayer *ent, double frametime );
|
||||||
void RunPostThink( CBasePlayer *player );
|
void RunPostThink( CBasePlayer *player );
|
||||||
|
void StartInterpolatingPlayer( CBasePlayer* player );
|
||||||
|
void FinishInterpolatingPlayer( CBasePlayer* player );
|
||||||
|
|
||||||
|
// TODO_ENHANCED: checks if this affects vehicles properly too! It should.
|
||||||
|
enum INTERPOLATION_CONTEXT
|
||||||
|
{
|
||||||
|
BEFORE_MOVEMENT,
|
||||||
|
AFTER_MOVEMENT,
|
||||||
|
INTERPOLATION_CONTEXT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InterpolationContext
|
||||||
|
{
|
||||||
|
Vector m_vecAbsOrigin;
|
||||||
|
Vector m_vecViewOffset;
|
||||||
|
} InterpolationContexts[INTERPOLATION_CONTEXT_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ ConVar weapon_accuracy_nospread( "weapon_accuracy_nospread", "0", FCVAR_REPLICAT
|
||||||
|
|
||||||
void DispatchEffect( const char *pName, const CEffectData &data );
|
void DispatchEffect( const char *pName, const CEffectData &data );
|
||||||
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|
||||||
// This is some extra code to collect weapon accuracy stats:
|
// This is some extra code to collect weapon accuracy stats:
|
||||||
|
|
|
@ -154,10 +154,10 @@ void FX_FireBullets(
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( playerCmd )
|
// if ( playerCmd )
|
||||||
{
|
// {
|
||||||
vHookedOrigin = VectorLerp( pPlayer->m_vecPreviousShootPosition, vOrigin, playerCmd->interpolated_amount );
|
// vHookedOrigin = VectorLerp( pPlayer->m_vecPreviousEyePosition, vOrigin, playerCmd->interpolated_amount );
|
||||||
}
|
// }
|
||||||
|
|
||||||
// #ifndef CLIENT_DLL
|
// #ifndef CLIENT_DLL
|
||||||
// DevMsg("server new shoot pos: %f %f %f - %f, has command: %s\n", vHookedOrigin.x, vHookedOrigin.y, vHookedOrigin.z, playerCmd->interpolated_amount, playerCmd ? "true" : "false" );
|
// DevMsg("server new shoot pos: %f %f %f - %f, has command: %s\n", vHookedOrigin.x, vHookedOrigin.y, vHookedOrigin.z, playerCmd->interpolated_amount, playerCmd ? "true" : "false" );
|
||||||
|
|
|
@ -334,18 +334,18 @@ bool CKnife::SwingOrStab( bool bStab )
|
||||||
Vector vForward; AngleVectors( pPlayer->EyeAngles(), &vForward );
|
Vector vForward; AngleVectors( pPlayer->EyeAngles(), &vForward );
|
||||||
|
|
||||||
Vector vecSrc = pPlayer->Weapon_ShootPosition();
|
Vector vecSrc = pPlayer->Weapon_ShootPosition();
|
||||||
CUserCmd* playerCmd = NULL;
|
// CUserCmd* playerCmd = NULL;
|
||||||
|
|
||||||
#ifdef CLIENT_DLL
|
// #ifdef CLIENT_DLL
|
||||||
playerCmd = pPlayer->m_pCurrentCommand;
|
// playerCmd = pPlayer->m_pCurrentCommand;
|
||||||
#else
|
// #else
|
||||||
playerCmd = pPlayer->GetCurrentCommand();
|
// playerCmd = pPlayer->GetCurrentCommand();
|
||||||
#endif
|
// #endif
|
||||||
|
|
||||||
if (playerCmd)
|
// if (playerCmd)
|
||||||
{
|
// {
|
||||||
vecSrc = VectorLerp(pPlayer->m_vecPreviousShootPosition, vecSrc, playerCmd->interpolated_amount);
|
// vecSrc = VectorLerp(pPlayer->m_vecPreviousEyePosition, vecSrc, playerCmd->interpolated_amount);
|
||||||
}
|
// }
|
||||||
|
|
||||||
Vector vecEnd = vecSrc + vForward * fRange;
|
Vector vecEnd = vecSrc + vForward * fRange;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue