Respecting more BuildTransformations on client

This commit is contained in:
Kamay Xutax 2024-08-21 05:30:48 +02:00
parent 95146c3867
commit 6e9520277f
5 changed files with 123 additions and 25 deletions

View file

@ -1726,6 +1726,64 @@ void CBaseAnimating::GetEncodedControllers(CStudioHdr* pStudioHdr, float encoded
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: build matrices first from the parent, then from the passed in arrays if the bone doesn't exist on the parent // Purpose: build matrices first from the parent, then from the passed in arrays if the bone doesn't exist on the parent
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CBaseAnimating::ApplyBoneMatrixTransform( matrix3x4_t& transform )
{
switch( m_nRenderFX )
{
case kRenderFxDistort:
case kRenderFxHologram:
if ( RandomInt(0,49) == 0 )
{
int axis = RandomInt(0,1);
if ( axis == 1 ) // Choose between x & z
axis = 2;
VectorScale( transform[axis], RandomFloat(1,1.484), transform[axis] );
}
else if ( RandomInt(0,49) == 0 )
{
float offset;
int axis = RandomInt(0,1);
if ( axis == 1 ) // Choose between x & z
axis = 2;
offset = RandomFloat(-10,10);
transform[RandomInt(0,2)][3] += offset;
}
break;
case kRenderFxExplode:
{
float scale;
scale = 1.0 + (gpGlobals->curtime - m_flAnimTime) * 10.0;
if ( scale > 2 ) // Don't blow up more than 200%
scale = 2;
transform[0][1] *= scale;
transform[1][1] *= scale;
transform[2][1] *= scale;
}
break;
default:
break;
}
if ( ( m_flModelScale > 1.0f+FLT_EPSILON || m_flModelScale < 1.0f-FLT_EPSILON ) )
{
// The bone transform is in worldspace, so to scale this, we need to translate it back
float scale = GetModelScale();
Vector pos;
MatrixGetColumn( transform, 3, pos );
pos -= GetAbsOrigin();
pos *= scale;
pos += GetAbsOrigin();
MatrixSetColumn( pos, 3, transform );
VectorScale( transform[0], scale, transform[0] );
VectorScale( transform[1], scale, transform[1] );
VectorScale( transform[2], scale, transform[2] );
}
}
void CBaseAnimating::BuildMatricesWithBoneMerge( void CBaseAnimating::BuildMatricesWithBoneMerge(
const CStudioHdr *pStudioHdr, const CStudioHdr *pStudioHdr,
@ -1739,6 +1797,7 @@ void CBaseAnimating::BuildMatricesWithBoneMerge(
{ {
mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); mstudiobone_t *pbones = pStudioHdr->pBone( 0 );
matrix3x4_t bonematrix;
matrix3x4_t rotationmatrix; // model to world transformation matrix3x4_t rotationmatrix; // model to world transformation
AngleMatrix( angles, origin, rotationmatrix); AngleMatrix( angles, origin, rotationmatrix);
@ -1761,29 +1820,49 @@ void CBaseAnimating::BuildMatricesWithBoneMerge(
} }
} }
for ( int i=0; i < pStudioHdr->numbones(); i++ ) for (int i = 0; i < pStudioHdr->numbones(); i++)
{ {
if (!(pStudioHdr->boneFlags(i) & boneMask)) // Only update bones reference by the bone mask.
{ if ( !( pStudioHdr->boneFlags( i ) & boneMask ) )
continue; {
} continue;
}
if (m_pBoneMergeCache && m_pBoneMergeCache->IsBoneMerged(i))
{ if ( m_pBoneMergeCache && m_pBoneMergeCache->IsBoneMerged( i ) )
continue; continue;
}
// If we get down here, then the bone wasn't merged.
matrix3x4_t bonematrix;
QuaternionMatrix( q[i], pos[i], bonematrix ); QuaternionMatrix( q[i], pos[i], bonematrix );
if (pbones[i].parent == -1) if ( (pStudioHdr->boneFlags( i ) & BONE_ALWAYS_PROCEDURAL) &&
(pStudioHdr->pBone( i )->proctype & STUDIO_PROC_JIGGLE) )
{ {
ConcatTransforms (rotationmatrix, bonematrix, bonetoworld[i]); matrix3x4_t goalMX;
if (pbones[i].parent == -1)
{
ConcatTransforms( rotationmatrix, bonematrix, goalMX );
}
else
{
ConcatTransforms( bonetoworld[pbones[i].parent], bonematrix, goalMX );
}
// TODO_ENHANCED: jiggles.
}
else if (pStudioHdr->boneParent(i) == -1)
{
ConcatTransforms( rotationmatrix, bonematrix, bonetoworld[i] );
} }
else else
{ {
ConcatTransforms (bonetoworld[pbones[i].parent], bonematrix, bonetoworld[i]); ConcatTransforms( bonetoworld[pStudioHdr->boneParent(i)], bonematrix, bonetoworld[i] );
}
if (pStudioHdr->boneParent(i) == -1)
{
// Apply client-side effects to the transformation matrix
ApplyBoneMatrixTransform( bonetoworld[i] );
} }
} }
} }
@ -1822,6 +1901,14 @@ void CBaseAnimating::SetupBones( CStudioHdr* pStudioHdr, matrix3x4_t *pBoneToWor
MDLCACHE_CRITICAL_SECTION(); MDLCACHE_CRITICAL_SECTION();
matrix3x4_t bones[MAXSTUDIOBONES];
// This is fine now.
if (!pBoneToWorld)
{
pBoneToWorld = bones;
}
m_pBoneCache = Studio_GetBoneCache(m_boneCacheHandle); m_pBoneCache = Studio_GetBoneCache(m_boneCacheHandle);
if ( m_pBoneCache ) if ( m_pBoneCache )
@ -2635,8 +2722,7 @@ CBoneCache *CBaseAnimating::GetBoneCache( void )
boneMask |= BONE_USED_BY_BONE_MERGE; boneMask |= BONE_USED_BY_BONE_MERGE;
#endif #endif
matrix3x4_t bonetoworld[MAXSTUDIOBONES]; SetupBones( GetModelPtr(), NULL, boneMask );
SetupBones( GetModelPtr(), bonetoworld, boneMask );
for (auto pChild = FirstMoveChild(); pChild; pChild = pChild->NextMovePeer()) for (auto pChild = FirstMoveChild(); pChild; pChild = pChild->NextMovePeer())
{ {
@ -2647,10 +2733,7 @@ CBoneCache *CBaseAnimating::GetBoneCache( void )
continue; continue;
} }
printf("animating: %i %s %s\n", pChildAnimating->entindex(), pChildAnimating->GetDebugName(), pChildAnimating->GetModelName().ToCStr()); pChildAnimating->SetupBones(pChildAnimating->GetModelPtr(), NULL, boneMask);
matrix3x4_t childbones[MAXSTUDIOBONES];
pChildAnimating->SetupBones(pChildAnimating->GetModelPtr(), childbones, boneMask);
} }
Assert(m_pBoneCache); Assert(m_pBoneCache);

View file

@ -329,6 +329,7 @@ public:
void BuildMatricesWithBoneMerge( const CStudioHdr *pStudioHdr, const QAngle& angles, void BuildMatricesWithBoneMerge( const CStudioHdr *pStudioHdr, const QAngle& angles,
const Vector& origin, const Vector pos[MAXSTUDIOBONES], const Vector& origin, const Vector pos[MAXSTUDIOBONES],
const Quaternion q[MAXSTUDIOBONES], matrix3x4_t bonetoworld[MAXSTUDIOBONES], int boneMask ); const Quaternion q[MAXSTUDIOBONES], matrix3x4_t bonetoworld[MAXSTUDIOBONES], int boneMask );
virtual void ApplyBoneMatrixTransform(matrix3x4_t& transform);
void SetFadeDistance( float minFadeDist, float maxFadeDist ); void SetFadeDistance( float minFadeDist, float maxFadeDist );

View file

@ -619,6 +619,7 @@ private:
float m_flHudHintMinDisplayTime; // if the hint is squelched before this, reset my counter so we'll display it again. float m_flHudHintMinDisplayTime; // if the hint is squelched before this, reset my counter so we'll display it again.
// Server only // Server only
#if !defined( CLIENT_DLL ) #if !defined( CLIENT_DLL )
public:
CStudioHdr *m_pStudioWorldHdr; CStudioHdr *m_pStudioWorldHdr;
// Outputs // Outputs

View file

@ -63,7 +63,16 @@ void CBoneMergeCache::UpdateCache()
#else #else
CBaseAnimating* pTestFollow = dynamic_cast<CBaseAnimating*>(m_pOwner->GetFollowedEntity()); CBaseAnimating* pTestFollow = dynamic_cast<CBaseAnimating*>(m_pOwner->GetFollowedEntity());
#endif #endif
CStudioHdr *pTestHdr = (pTestFollow ? pTestFollow->GetModelPtr() : NULL); CStudioHdr* pTestHdr = (pTestFollow ? pTestFollow->GetModelPtr() : NULL);
// TODO_ENHANCED: We really need a better way to do this ...
#ifndef CLIENT_DLL
CBaseCombatWeapon* pWeapon = dynamic_cast<CBaseCombatWeapon*>(pTestFollow);
pTestHdr = pWeapon ? pWeapon->m_pStudioWorldHdr : pTestHdr;
pWeapon = dynamic_cast<CBaseCombatWeapon*>(m_pOwner);
pOwnerHdr = pWeapon ? pWeapon->m_pStudioWorldHdr : pOwnerHdr;
#endif
const studiohdr_t *pTestStudioHDR = (pTestHdr ? pTestHdr->GetRenderHdr() : NULL); const studiohdr_t *pTestStudioHDR = (pTestHdr ? pTestHdr->GetRenderHdr() : NULL);
if ( pTestFollow != m_pFollow || pTestHdr != m_pFollowHdr || pTestStudioHDR != m_pFollowRenderHdr || pOwnerHdr != m_pOwnerHdr ) if ( pTestFollow != m_pFollow || pTestHdr != m_pFollowHdr || pTestStudioHDR != m_pFollowRenderHdr || pOwnerHdr != m_pOwnerHdr )
{ {
@ -90,7 +99,9 @@ void CBoneMergeCache::UpdateCache()
if ( parentBoneIndex < 0 ) if ( parentBoneIndex < 0 )
continue; continue;
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
printf("bone attach: (%i - %i) (%s - %s) (%s - %s)\n", m_pFollow->entindex(), m_pOwner->entindex(), m_pFollow->GetDebugName(), m_pOwner->GetDebugName(), m_pFollow->GetModelName(), m_pOwner->GetModelName()); printf("client bone attach: (%i - %i) %s %s %i %s\n", m_pFollow->entindex(), m_pOwner->entindex(), m_pFollowHdr->pszName(), m_pOwnerHdr->pszName(), i, m_pFollowHdr->pBone(i)->pszName());
#else
printf("server bone attach: (%i - %i) %s %s %i %s\n", m_pFollow->entindex(), m_pOwner->entindex(), m_pFollowHdr->pszName(), m_pOwnerHdr->pszName(), i, m_pFollowHdr->pBone(i)->pszName());
#endif #endif
// Add a merged bone here. // Add a merged bone here.
CMergedBone mergedBone; CMergedBone mergedBone;

View file

@ -65,7 +65,9 @@ private:
CStudioHdr *m_pFollowHdr; CStudioHdr *m_pFollowHdr;
const studiohdr_t *m_pFollowRenderHdr; const studiohdr_t *m_pFollowRenderHdr;
CStudioHdr *m_pOwnerHdr; CStudioHdr *m_pOwnerHdr;
#ifndef CLIENT_DLL
CStudioHdr *m_pFollowWorldHdr;
#endif
// This is the mask we need to use to set up bones on the followed entity to do the bone merge // This is the mask we need to use to set up bones on the followed entity to do the bone merge
int m_nFollowBoneSetupMask; int m_nFollowBoneSetupMask;