mirror of
https://github.com/ValveSoftware/source-sdk-2013.git
synced 2025-04-09 03:24:52 +00:00
Fix jittering when spectating ragdolls
This commit is contained in:
parent
0759e2e8e1
commit
381953159b
3 changed files with 48 additions and 3 deletions
|
@ -1603,7 +1603,25 @@ void C_BaseAnimating::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quater
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if ( m_pRagdoll )
|
||||
{
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( pPlayer )
|
||||
{
|
||||
// When the local player is spectating a ragdoll, they are copying the root physics bone
|
||||
// Afterwards, physics simulation of ragdolls happens and updates the bones
|
||||
// ... But after that, the ragdoll is drawn with the NEW bones
|
||||
// which leads to the camera and rendering being out of sync with each other and causing visible jittering
|
||||
// The workaround for this problem is to render the ragdoll with the last frame's bone data
|
||||
C_BaseEntity* pObserverTarget = pPlayer->GetObserverTarget();
|
||||
if ( pObserverTarget
|
||||
&& pObserverTarget->IsPlayer()
|
||||
&& static_cast< C_BasePlayer* >( pObserverTarget )->GetRepresentativeRagdoll() == m_pRagdoll )
|
||||
{
|
||||
m_pRagdoll->AcquireOrCopyBoneCache( m_CachedBoneData.Base(), m_CachedBoneData.Count() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -28,7 +28,7 @@ CRagdoll::CRagdoll()
|
|||
m_ragdoll.listCount = 0;
|
||||
m_vecLastOrigin.Init();
|
||||
m_flLastOriginChangeTime = - 1.0f;
|
||||
|
||||
m_flBoneCacheTime = -FLT_MAX;
|
||||
m_lastUpdate = -FLT_MAX;
|
||||
}
|
||||
|
||||
|
@ -174,6 +174,31 @@ void CRagdoll::RagdollBone( C_BaseEntity *ent, mstudiobone_t *pbones, int boneCo
|
|||
}
|
||||
}
|
||||
|
||||
void CRagdoll::AcquireOrCopyBoneCache( matrix3x4_t* pOutBonesToWorld, int boneCount )
|
||||
{
|
||||
// acquire cache if not setup
|
||||
if ( m_BoneCache.Count() != boneCount )
|
||||
{
|
||||
m_BoneCache.CopyArray( pOutBonesToWorld, boneCount );
|
||||
m_flBoneCacheTime = gpGlobals->curtime;
|
||||
}
|
||||
// copy cache out if called again in same frame
|
||||
else if ( gpGlobals->curtime == m_flBoneCacheTime )
|
||||
{
|
||||
memcpy( pOutBonesToWorld, m_BoneCache.Base(), boneCount * sizeof(matrix3x4_t) );
|
||||
}
|
||||
// copy out our cache and acquire the old one
|
||||
else
|
||||
{
|
||||
size_t uBoneDataSize = boneCount * sizeof(matrix3x4_t);
|
||||
matrix3x4_t* pTempBoneData = (matrix3x4_t*)stackalloc( uBoneDataSize );
|
||||
memcpy( pTempBoneData, pOutBonesToWorld, uBoneDataSize );
|
||||
memcpy( pOutBonesToWorld, m_BoneCache.Base(), uBoneDataSize );
|
||||
memcpy( m_BoneCache.Base(), pTempBoneData, uBoneDataSize );
|
||||
m_flBoneCacheTime = gpGlobals->curtime;
|
||||
}
|
||||
}
|
||||
|
||||
const Vector& CRagdoll::GetRagdollOrigin( )
|
||||
{
|
||||
m_ragdoll.list[0].pObject->GetPosition( &m_origin, 0 );
|
||||
|
|
|
@ -60,10 +60,10 @@ public:
|
|||
bool bFixedConstraints=false );
|
||||
|
||||
virtual void RagdollBone( C_BaseEntity *ent, mstudiobone_t *pbones, int boneCount, bool *boneSimulated, CBoneAccessor &pBoneToWorld );
|
||||
void AcquireOrCopyBoneCache( matrix3x4_t* pBonesToWorld, int boneCount );
|
||||
virtual const Vector& GetRagdollOrigin( );
|
||||
virtual void GetRagdollBounds( Vector &theMins, Vector &theMaxs );
|
||||
void BuildRagdollBounds( C_BaseEntity *ent );
|
||||
|
||||
virtual IPhysicsObject *GetElement( int elementNum );
|
||||
virtual IPhysicsConstraintGroup *GetConstraintGroup() { return m_ragdoll.pGroup; }
|
||||
virtual void DrawWireframe();
|
||||
|
@ -101,6 +101,8 @@ private:
|
|||
bool m_allAsleep;
|
||||
Vector m_vecLastOrigin;
|
||||
float m_flLastOriginChangeTime;
|
||||
CUtlVector< matrix3x4_t > m_BoneCache;
|
||||
float m_flBoneCacheTime;
|
||||
|
||||
#if RAGDOLL_VISUALIZE
|
||||
matrix3x4_t m_savedBone1[MAXSTUDIOBONES];
|
||||
|
|
Loading…
Reference in a new issue