From d5868bb85b9b3948760e8901238492ce296f8d2a Mon Sep 17 00:00:00 2001 From: Kamay Xutax Date: Thu, 22 Aug 2024 23:29:34 +0200 Subject: [PATCH] :x --- game/client/c_baseanimating.cpp | 46 ++++- game/client/c_baseanimating.h | 4 +- game/client/c_baseanimatingoverlay.cpp | 6 +- game/client/c_baseentity.cpp | 10 +- game/server/BaseAnimatingOverlay.cpp | 50 +---- game/server/BaseAnimatingOverlay.h | 3 +- game/server/baseanimating.cpp | 251 ++++++++++++++++++------ game/server/baseanimating.h | 17 +- game/server/baseentity.h | 2 +- game/server/cstrike/cs_player.cpp | 35 +++- game/shared/basecombatweapon_shared.cpp | 1 - game/shared/bone_merge_cache.cpp | 8 +- game/shared/bone_merge_cache.h | 4 +- 13 files changed, 302 insertions(+), 135 deletions(-) diff --git a/game/client/c_baseanimating.cpp b/game/client/c_baseanimating.cpp index 5d26f52bbf..a21ae8887d 100644 --- a/game/client/c_baseanimating.cpp +++ b/game/client/c_baseanimating.cpp @@ -1973,8 +1973,10 @@ void C_BaseAnimating::StandardBlendingRules( CStudioHdr *hdr, Vector pos[], Quat // debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), 0, 0, "%30s %6.2f : %6.2f", hdr->pSeqdesc( GetSequence() )->pszLabel( ), fCycle, 1.0 ); // TODO_ENHANCED: Do that only for client side animations - // if (m_bClientSideAnimation) - MaintainSequenceTransitions( boneSetup, fCycle, currentTime, pos, q ); + if (m_bClientSideAnimation) + { + MaintainSequenceTransitions( boneSetup, fCycle, currentTime, pos, q ); + } AccumulateLayers( boneSetup, pos, q, currentTime ); @@ -2946,6 +2948,14 @@ bool C_BaseAnimating::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, i m_pIk->UpdateTargets( pos, q, m_BoneAccessor.GetBoneArrayForWrite(), boneComputed ); CalculateIKLocks( currentTime ); + if (entindex() == 2){ + printf("client:\n"); + for (int i = 0; i < hdr->numbones(); i++) + { + printf("%s: %f %f %f - %f %f %f %f\n", hdr->pBone(i)->pszName(), pos[i].x, pos[i].y, pos[i].z, q[i].x, q[i].y,q[i].z, q[i].w); + } + printf("\n"); + } m_pIk->SolveDependencies( pos, q, m_BoneAccessor.GetBoneArrayForWrite(), boneComputed ); } @@ -2960,7 +2970,37 @@ bool C_BaseAnimating::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, i SetupBones_AttachmentHelper( hdr ); } } - + + int i; + int r = 255; + int g = 255; + int b = 255; + + MDLCACHE_CRITICAL_SECTION(); + + for (i = 0; i < m_pStudioHdr->numbones(); i++) + { + if (m_pStudioHdr->pBone( i )->flags & boneMask) + { + Vector p1; + MatrixPosition( m_CachedBoneData[i], p1 ); + if ( m_pStudioHdr->pBone( i )->parent != -1 ) + { + Vector p2; + MatrixPosition( m_CachedBoneData[m_pStudioHdr->pBone( i )->parent], p2 ); + if (m_pStudioHdr->pBone(i)->flags & BONE_USED_BY_BONE_MERGE) + { + r = 255; + } + else + { + r = 0; + } + debugoverlay->AddLineOverlay( p1, p2, r, g, b, true, gpGlobals->frametime ); + } + } + } + // Do they want to get at the bone transforms? If it's just making sure an aiment has // its bones setup, it doesn't need the transforms yet. if ( pBoneToWorldOut ) diff --git a/game/client/c_baseanimating.h b/game/client/c_baseanimating.h index 4cb2a00bfc..7126e8d897 100644 --- a/game/client/c_baseanimating.h +++ b/game/client/c_baseanimating.h @@ -99,8 +99,8 @@ public: enum { - NUM_POSEPAREMETERS = 24, - NUM_BONECTRLS = 4 + NUM_POSEPAREMETERS = MAXSTUDIOPOSEPARAM, + NUM_BONECTRLS = MAXSTUDIOBONECTRLS }; C_BaseAnimating(); diff --git a/game/client/c_baseanimatingoverlay.cpp b/game/client/c_baseanimatingoverlay.cpp index 1ea6b99062..a92d8b79ff 100644 --- a/game/client/c_baseanimatingoverlay.cpp +++ b/game/client/c_baseanimatingoverlay.cpp @@ -226,11 +226,11 @@ void C_BaseAnimatingOverlay::AccumulateLayers( IBoneSetup &boneSetup, Vector pos { if (layer[i] >= 0 && layer[i] < m_AnimOverlay.Count()) { - CAnimationLayer &pLayer = m_AnimOverlay[layer[i]]; + CAnimationLayer& pLayer = m_AnimOverlay[layer[i]]; // UNDONE: Is it correct to use overlay weight for IK too? - boneSetup.AccumulatePose( pos, q, pLayer.m_nSequence, pLayer.m_flCycle, pLayer.m_flWeight, currentTime, m_pIk ); + boneSetup.AccumulatePose( pos, q, pLayer.m_nSequence.GetRaw(), pLayer.m_flCycle.GetRaw(), pLayer.m_flWeight.GetRaw(), currentTime, m_pIk ); } - } + } } void C_BaseAnimatingOverlay::DoAnimationEvents( CStudioHdr *pStudioHdr ) diff --git a/game/client/c_baseentity.cpp b/game/client/c_baseentity.cpp index bb5a96c68a..b11b83a130 100644 --- a/game/client/c_baseentity.cpp +++ b/game/client/c_baseentity.cpp @@ -4294,11 +4294,11 @@ void C_BaseEntity::CalcAbsolutePosition( ) return; } - if ( IsEffectActive(EF_BONEMERGE) ) - { - MoveToAimEnt(); - return; - } + // if ( IsEffectActive(EF_BONEMERGE) ) + // { + // MoveToAimEnt(); + // return; + // } // Construct the entity-to-world matrix // Start with making an entity-to-parent matrix diff --git a/game/server/BaseAnimatingOverlay.cpp b/game/server/BaseAnimatingOverlay.cpp index 2a969ba9fb..b576983eed 100644 --- a/game/server/BaseAnimatingOverlay.cpp +++ b/game/server/BaseAnimatingOverlay.cpp @@ -7,6 +7,7 @@ //===========================================================================// #include "cbase.h" +#include "BaseAnimatingOverlay.h" #include "animation.h" #include "studio.h" #include "bone_setup.h" @@ -432,36 +433,15 @@ void CAnimationLayer::DispatchAnimEvents( CBaseAnimating *eventHandler, CBaseAni } } - - -void CBaseAnimatingOverlay::GetSkeleton( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], int boneMask ) +void CBaseAnimatingOverlay::AccumulateLayers(CStudioHdr *pStudioHdr, IBoneSetup& boneSetup, Vector pos[], Quaternion q[], float currentTime) { - if(!pStudioHdr) - { - Assert(!"CBaseAnimating::GetSkeleton() without a model"); - return; - } - - if (!pStudioHdr->SequencesAvailable()) - { - return; - } - - float flPoseParams[MAXSTUDIOPOSEPARAM]; - float flEncodedParams[MAXSTUDIOBONECTRLS]; - - GetPoseParameters( pStudioHdr, flPoseParams ); - - IBoneSetup boneSetup( pStudioHdr, boneMask, flPoseParams ); - boneSetup.InitPose( pos, q ); - - boneSetup.AccumulatePose( pos, q, GetSequence(), GetCycle(), 1.0, gpGlobals->curtime, m_pIk ); - + BaseClass::AccumulateLayers(pStudioHdr, boneSetup, pos, q, currentTime); + // sort the layers int layer[MAX_OVERLAYS] = {}; int i; for (i = 0; i < m_AnimOverlay.Count(); i++) - { + { layer[i] = MAX_OVERLAYS; } for (i = 0; i < m_AnimOverlay.Count(); i++) @@ -471,32 +451,18 @@ void CBaseAnimatingOverlay::GetSkeleton( CStudioHdr *pStudioHdr, Vector pos[], Q { layer[pLayer.m_nOrder] = i; } - } + } for (i = 0; i < m_AnimOverlay.Count(); i++) { if (layer[i] >= 0 && layer[i] < m_AnimOverlay.Count()) { - CAnimationLayer &pLayer = m_AnimOverlay[layer[i]]; + CAnimationLayer& pLayer = m_AnimOverlay[layer[i]]; // UNDONE: Is it correct to use overlay weight for IK too? - boneSetup.AccumulatePose( pos, q, pLayer.m_nSequence, pLayer.m_flCycle, pLayer.m_flWeight, gpGlobals->curtime, m_pIk ); + boneSetup.AccumulatePose( pos, q, pLayer.m_nSequence.Get(), pLayer.m_flCycle.Get(), pLayer.m_flWeight.Get(), currentTime, m_pIk ); } - } - - if ( m_pIk ) - { - CIKContext auto_ik; - auto_ik.Init( pStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, 0, boneMask ); - boneSetup.CalcAutoplaySequences( pos, q, gpGlobals->curtime, &auto_ik ); - } - else - { - boneSetup.CalcAutoplaySequences( pos, q, gpGlobals->curtime, NULL ); } - GetEncodedControllers( pStudioHdr, flEncodedParams ); - boneSetup.CalcBoneAdj( pos, q, flEncodedParams ); } - //----------------------------------------------------------------------------- // Purpose: zero's out all non-restore safe fields // Output : diff --git a/game/server/BaseAnimatingOverlay.h b/game/server/BaseAnimatingOverlay.h index ac112cbd0c..2e1e3cb3ac 100644 --- a/game/server/BaseAnimatingOverlay.h +++ b/game/server/BaseAnimatingOverlay.h @@ -143,8 +143,7 @@ public: virtual void StudioFrameAdvance(); virtual void DispatchAnimEvents ( CBaseAnimating *eventHandler ); - virtual void GetSkeleton( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], int boneMask ); - + virtual void AccumulateLayers(CStudioHdr *pStudioHdr, IBoneSetup& boneSetup, Vector pos[], Quaternion q[], float currentTime); int AddGestureSequence( int sequence, bool autokill = true ); int AddGestureSequence( int sequence, float flDuration, bool autokill = true ); int AddGesture( Activity activity, bool autokill = true ); diff --git a/game/server/baseanimating.cpp b/game/server/baseanimating.cpp index 18d7c93ca8..107d270969 100644 --- a/game/server/baseanimating.cpp +++ b/game/server/baseanimating.cpp @@ -1599,6 +1599,34 @@ QAngle CBaseAnimating::GetStepAngles( void ) const return GetLocalAngles(); } +void CBaseAnimating::UpdateIKLocks( float currentTime ) +{ + if (!m_pIk) + return; + + int targetCount = m_pIk->m_target.Count(); + if ( targetCount == 0 ) + return; + + for (int i = 0; i < targetCount; i++) + { + CIKTarget *pTarget = &m_pIk->m_target[i]; + + if (!pTarget->IsActive()) + continue; + + if (pTarget->GetOwner() != -1) + { + CBaseEntity *pOwner = UTIL_EntityByIndex(pTarget->GetOwner()); + if (pOwner != NULL) + { + pTarget->UpdateOwner( pOwner->entindex(), pOwner->GetAbsOrigin(), pOwner->GetAbsAngles() ); + } + } + } +} + + //----------------------------------------------------------------------------- // Purpose: Find IK collisions with world // Input : @@ -1678,7 +1706,39 @@ void CBaseAnimating::CalculateIKLocks( float currentTime ) break; case IK_ATTACHMENT: { - // anything on the server? + CBaseEntity *pEntity = NULL; + float flDist = pTarget->est.radius; + + // FIXME: make entity finding sticky! + // FIXME: what should the radius check be? + for ( CEntitySphereQuery sphere( pTarget->est.pos, 64 ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() ) + { + CBaseAnimating *pAnim = pEntity->GetBaseAnimating( ); + if (!pAnim) + continue; + + int iAttachment = pAnim->LookupAttachment( pTarget->offset.pAttachmentName ); + if (iAttachment <= 0) + continue; + + Vector origin; + QAngle angles; + pAnim->GetAttachment( iAttachment, origin, angles ); + + float d = (pTarget->est.pos - origin).Length(); + + if ( d >= flDist) + continue; + + flDist = d; + pTarget->SetPos( origin ); + pTarget->SetAngles( angles ); + } + + if (flDist >= pTarget->est.radius) + { + pTarget->IKFailed( ); + } } break; } @@ -1792,10 +1852,19 @@ void CBaseAnimating::ApplyBoneMatrixTransform( matrix3x4_t& transform ) void CBaseAnimating::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed, matrix3x4_t pBonesOut[] ) { - mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); - matrix3x4_t bonematrix; + if ( !pStudioHdr ) + return; - bool boneMerge = IsEffectActive(EF_BONEMERGE); + CBoneAccessor boneAccessor(pBonesOut); + + boneAccessor.SetReadableBones(BONE_USED_BY_ANYTHING); + boneAccessor.SetWritableBones(BONE_USED_BY_ANYTHING); + + matrix3x4_t bonematrix; + mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); + + // For EF_BONEMERGE entities, copy the bone matrices for any bones that have matching names. + bool boneMerge = IsEffectActive(EF_BONEMERGE); if ( boneMerge || m_pBoneMergeCache ) { if ( boneMerge ) @@ -1813,7 +1882,7 @@ void CBaseAnimating::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, m_pBoneMergeCache = NULL; } } - + for (int i = 0; i < pStudioHdr->numbones(); i++) { // Only update bones reference by the bone mask. @@ -1825,19 +1894,15 @@ void CBaseAnimating::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, if ( m_pBoneMergeCache && m_pBoneMergeCache->IsBoneMerged( i ) ) continue; - CBoneAccessor boneAccess(pBonesOut); - boneAccess.SetReadableBones(boneMask); - boneAccess.SetWritableBones(boneMask); - // animate all non-simulated bones - if ( CalcProceduralBone( pStudioHdr, i, boneAccess )) + if ( CalcProceduralBone( pStudioHdr, i, boneAccessor )) { continue; } // skip bones that the IK has already setup else if (boneComputed.IsBoneMarked( i )) - { - continue; + { + continue; } else { @@ -1868,7 +1933,7 @@ void CBaseAnimating::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, ConcatTransforms( pBonesOut[pbones[i].parent], bonematrix, goalMX ); } - // get jiggle properties from QC data + // get jiggle properties from QC data mstudiojigglebone_t *jiggleInfo = (mstudiojigglebone_t *)pbones[i].pProcedure( ); if (!m_pJiggleBones) @@ -1894,8 +1959,8 @@ void CBaseAnimating::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, { // Apply client-side effects to the transformation matrix ApplyBoneMatrixTransform( pBonesOut[i] ); - } - } + } + } } ConVar sv_pvsskipanimation( "sv_pvsskipanimation", "0", FCVAR_ARCHIVE, "Skips SetupBones when npc's are outside the PVS" ); @@ -1985,52 +2050,68 @@ void CBaseAnimating::SetupBones( CStudioHdr* pStudioHdr, matrix3x4_t *pBoneToWor AddEFlags( EFL_SETTING_UP_BONES ); + // NOTE: For model scaling, we need to opt out of IK because it will mark the bones as already being calculated + if ( !(( m_flModelScale > 1.0f+FLT_EPSILON || m_flModelScale < 1.0f-FLT_EPSILON )) ) + { + // only allocate an ik block if the npc can use it + if ( !m_pIk && pStudioHdr->numikchains() > 0 ) + { + m_pIk = new CIKContext; + } + } + else + { + // Reset the IK + if ( m_pIk ) + { + delete m_pIk; + m_pIk = NULL; + } + } + + if ( m_pIk ) + { + m_pIk->Init( pStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, m_iIKCounter, boneMask ); + } + Vector pos[MAXSTUDIOBONES]; Quaternion q[MAXSTUDIOBONES]; - // Remove IK to respect more the client hitboxes. - Vector adjOrigin = GetAbsOrigin(); + Vector adjOrigin = GetAbsOrigin() + Vector( 0, 0, m_flEstIkOffset ); CBoneBitList boneComputed; + + StandardBlendingRules( pStudioHdr, pos, q, boneMask ); - if ( CanSkipAnimation() ) - { - IBoneSetup boneSetup( pStudioHdr, boneMask, GetPoseParameterArray() ); - boneSetup.InitPose( pos, q ); - // Msg( "%.03f : %s:%s not in pvs\n", gpGlobals->curtime, GetClassname(), GetEntityName().ToCStr() ); - } - else - { - if ( m_pIk ) - { - // FIXME: pass this into Studio_BuildMatrices to skip transforms - m_iIKCounter++; - m_pIk->Init( pStudioHdr, GetAbsAngles(), adjOrigin, gpGlobals->curtime, m_iIKCounter, boneMask ); - GetSkeleton( pStudioHdr, pos, q, boneMask ); + if ( m_pIk ) + { + UpdateIKLocks( gpGlobals->curtime ); + m_pIk->UpdateTargets( pos, q, pBoneToWorld, boneComputed ); - m_pIk->UpdateTargets( pos, q, pBoneToWorld, boneComputed ); - CalculateIKLocks( gpGlobals->curtime ); - m_pIk->SolveDependencies( pos, q, pBoneToWorld, boneComputed ); - } - else - { - // Msg( "%.03f : %s:%s\n", gpGlobals->curtime, GetClassname(), GetEntityName().ToCStr() ); - GetSkeleton( pStudioHdr, pos, q, boneMask ); - } + CalculateIKLocks( gpGlobals->curtime ); + if (entindex() == 2){ + printf("server:\n"); + for (int i = 0; i < pStudioHdr->numbones(); i++) + { + printf("%s: %f %f %f - %f %f %f %f\n", pStudioHdr->pBone(i)->pszName(), pos[i].x, pos[i].y, pos[i].z, q[i].x, q[i].y,q[i].z, q[i].w); } + printf("\n"); + } + + m_pIk->SolveDependencies( pos, q, pBoneToWorld, boneComputed ); + } matrix3x4_t parentTransform; AngleMatrix( GetAbsAngles(), adjOrigin, parentTransform ); - printf("%f %f %f - %f %f %f\n", GetAbsAngles().x, GetAbsAngles().y, GetAbsAngles().z, adjOrigin.x, adjOrigin.y, adjOrigin.z); BuildTransformations(pStudioHdr, pos, q, parentTransform, boneMask, boneComputed, pBoneToWorld); - m_pBoneCache->UpdateBones(pBoneToWorld, pStudioHdr->numbones(), gpGlobals->curtime); + m_pBoneCache->UpdateBones(pBoneToWorld, pStudioHdr->numbones(), gpGlobals->curtime); if (ai_setupbones_debug.GetBool()) { // Msg("%s:%s:%s (%x)\n", GetClassname(), GetDebugName(), STRING(GetModelName()), boneMask ); - DrawRawSkeleton( pBoneToWorld, boneMask, true, flDebugDuration ); + DrawRawSkeleton( pStudioHdr, pBoneToWorld, boneMask, true, flDebugDuration ); } RemoveEFlags( EFL_SETTING_UP_BONES ); } @@ -2742,13 +2823,42 @@ void CBaseAnimating::UnlockStudioHdr() } } +CBaseAnimating* CBaseAnimating::FindFollowedEntity() +{ + CBaseEntity *follow = GetFollowedEntity(); + + if ( !follow ) + return NULL; + + if ( follow->IsDormant() ) + return NULL; + + if ( !follow->GetModel() ) + { + Warning( "mod_studio: MOVETYPE_FOLLOW with no model.\n" ); + return NULL; + } + + if ( modelinfo->GetModelType( follow->GetModel() ) != mod_studio ) + { + Warning( "Attached %s (mod_studio) to %s (%d)\n", + modelinfo->GetModelName( GetModel() ), + modelinfo->GetModelName( follow->GetModel() ), + modelinfo->GetModelType( follow->GetModel() ) ); + return NULL; + } + + return dynamic_cast< CBaseAnimating* >( follow ); +} + + //----------------------------------------------------------------------------- // Purpose: return the index to the shared bone cache // Output : //----------------------------------------------------------------------------- CBoneCache *CBaseAnimating::GetBoneCache( void ) { - int boneMask = BONE_USED_BY_HITBOX | BONE_USED_BY_ATTACHMENT | BONE_USED_BY_BONE_MERGE; + int boneMask = BONE_USED_BY_ANYTHING; // TF queries these bones to position weapons when players are killed #if defined( TF_DLL ) @@ -2936,40 +3046,62 @@ void CBaseAnimating::GetVelocity(Vector *vVelocity, AngularImpulse *vAngVelocity } } +void CBaseAnimating::AccumulateLayers(CStudioHdr *pStudioHdr, IBoneSetup& boneSetup, Vector pos[], Quaternion q[], float currentTime) +{ +} -//========================================================= -//========================================================= - -void CBaseAnimating::GetSkeleton( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], int boneMask ) +void CBaseAnimating::StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], int boneMask ) { if(!pStudioHdr) { - Assert(!"CBaseAnimating::GetSkeleton() without a model"); + Assert(!"CBaseAnimating::StandardBlendingRules() without a model"); return; } - float flPoseParams[MAXSTUDIOPOSEPARAM]; - float flEncodedParams[MAXSTUDIOBONECTRLS]; + if ( !pStudioHdr ) + return; - GetPoseParameters( pStudioHdr, flPoseParams ); + if ( !pStudioHdr->SequencesAvailable() ) + { + return; + } - IBoneSetup boneSetup( pStudioHdr, boneMask, flPoseParams ); - boneSetup.InitPose( pos, q ); + if (GetSequence() >= pStudioHdr->GetNumSeq() || GetSequence() == -1 ) + { + SetSequence( 0 ); + } - boneSetup.AccumulatePose( pos, q, GetSequence(), GetCycle(), 1.0, gpGlobals->curtime, m_pIk ); + float poseparam[MAXSTUDIOPOSEPARAM]; + GetPoseParameters( pStudioHdr, poseparam ); + + // build root animation + float fCycle = GetCycle(); + + IBoneSetup boneSetup( pStudioHdr, boneMask, poseparam ); + boneSetup.InitPose(pos, q); + + boneSetup.AccumulatePose( pos, q, GetSequence(), fCycle, 1.0, gpGlobals->curtime, m_pIk ); + + AccumulateLayers( pStudioHdr, boneSetup, pos, q, gpGlobals->curtime ); if ( m_pIk ) { CIKContext auto_ik; - auto_ik.Init( pStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, 0, boneMask ); + auto_ik.Init(pStudioHdr, GetAbsAngles(), GetAbsOrigin(), gpGlobals->curtime, m_iIKCounter, boneMask); + m_iIKCounter++; boneSetup.CalcAutoplaySequences( pos, q, gpGlobals->curtime, &auto_ik ); } else { boneSetup.CalcAutoplaySequences( pos, q, gpGlobals->curtime, NULL ); + } + + if ( pStudioHdr->numbonecontrollers() ) + { + float controllers[MAXSTUDIOBONECTRLS]; + GetEncodedControllers( pStudioHdr, controllers); + boneSetup.CalcBoneAdj( pos, q, controllers ); } - GetEncodedControllers( pStudioHdr, flEncodedParams ); - boneSetup.CalcBoneAdj( pos, q, flEncodedParams ); } int CBaseAnimating::DrawDebugTextOverlays(void) @@ -3202,9 +3334,8 @@ void CBaseAnimating::DrawServerHitboxes( float duration /*= 0.0f*/, bool monocol } -void CBaseAnimating::DrawRawSkeleton( matrix3x4_t boneToWorld[], int boneMask, bool noDepthTest, float duration, bool monocolor ) +void CBaseAnimating::DrawRawSkeleton( CStudioHdr* pStudioHdr, matrix3x4_t boneToWorld[], int boneMask, bool noDepthTest, float duration, bool monocolor ) { - CStudioHdr *pStudioHdr = GetModelPtr(); if ( !pStudioHdr ) return; diff --git a/game/server/baseanimating.h b/game/server/baseanimating.h index 5b330d1073..d162e3975d 100644 --- a/game/server/baseanimating.h +++ b/game/server/baseanimating.h @@ -28,6 +28,7 @@ struct animevent_t; struct matrix3x4_t; class CIKContext; class KeyValues; +class IBoneSetup; FORWARD_DECLARE_HANDLE( memhandle_t ); #define BCF_NO_ANIMATION_SKIP ( 1 << 0 ) // Do not allow PVS animation skipping (mostly for attachments being critical to an entity) @@ -45,8 +46,8 @@ public: enum { - NUM_POSEPAREMETERS = 24, - NUM_BONECTRLS = 4 + NUM_POSEPAREMETERS = MAXSTUDIOPOSEPARAM, + NUM_BONECTRLS = MAXSTUDIOBONECTRLS }; DECLARE_DATADESC(); @@ -137,10 +138,12 @@ public: virtual bool IsRagdoll(); virtual bool CanBecomeRagdoll( void ); //Check if this entity will ragdoll when dead. - virtual void GetSkeleton( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], int boneMask ); + virtual void AccumulateLayers( CStudioHdr *pStudioHdr, IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime ); + virtual void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], int boneMask ); virtual void GetBoneTransform( int iBone, matrix3x4_t &pBoneToWorld ); - virtual void SetupBones( CStudioHdr *pStudioHdr, matrix3x4_t *pBoneToWorld, int boneMask ); + virtual void SetupBones(CStudioHdr* pStudioHdr, matrix3x4_t* pBoneToWorld, int boneMask); + virtual void UpdateIKLocks( float currentTime ); virtual void CalculateIKLocks( float currentTime ); virtual void Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity ); @@ -273,7 +276,7 @@ public: // See note in code re: bandwidth usage!!! int GetServerHitboxes( Vector position[MAXSTUDIOBONES], QAngle angles[MAXSTUDIOBONES], int indexes[MAXSTUDIOBONES] ); void DrawServerHitboxes( float duration = 0.0f, bool monocolor = false ); - void DrawRawSkeleton( matrix3x4_t boneToWorld[], int boneMask, bool noDepthTest = true, float duration = 0.0f, bool monocolor = false ); + void DrawRawSkeleton( CStudioHdr* pStudioHdr, matrix3x4_t boneToWorld[], int boneMask, bool noDepthTest = true, float duration = 0.0f, bool monocolor = false ); void SetModelScale( float scale, float change_duration = 0.0f ); float GetModelScale() const { return m_flModelScale; } @@ -342,6 +345,8 @@ public: virtual void LockStudioHdr(); virtual void UnlockStudioHdr(); + CBaseAnimating* FindFollowedEntity(); + private: void StudioFrameAdvanceInternal( CStudioHdr *pStudioHdr, float flInterval ); @@ -385,7 +390,7 @@ public: Vector GetStepOrigin( void ) const; QAngle GetStepAngles( void ) const; -private: +protected: bool m_bSequenceFinished;// flag set when StudioAdvanceFrame moves across a frame boundry bool m_bSequenceLoops; // true if the sequence loops bool m_bResetSequenceInfoOnLoad; // true if a ResetSequenceInfo was queued up during dynamic load diff --git a/game/server/baseentity.h b/game/server/baseentity.h index 96873d3a68..17d3648d80 100644 --- a/game/server/baseentity.h +++ b/game/server/baseentity.h @@ -732,7 +732,7 @@ public: void NetworkStateChanged( void *pVar ); public: - void CalcAbsolutePosition(); + virtual void CalcAbsolutePosition(); // returns the edict index the entity requires when used in save/restore (eg players, world) // -1 means it doesn't require any special index diff --git a/game/server/cstrike/cs_player.cpp b/game/server/cstrike/cs_player.cpp index 3a66c8e4c2..931495c07a 100644 --- a/game/server/cstrike/cs_player.cpp +++ b/game/server/cstrike/cs_player.cpp @@ -58,6 +58,40 @@ #include "holiday_gift.h" #include "../../shared/cstrike/cs_achievement_constants.h" #include "ilagcompensationmanager.h" +#include "bone_accessor.h" +#include "jigglebones.h" +#include "baseanimating.h" +#include "animation.h" +#include "activitylist.h" +#include "dt_common.h" +#include "dt_send.h" +#include "edict.h" +#include "enginecallback.h" +#include "entitylist_base.h" +#include "mathlib/vector.h" +#include "mathlib/vmatrix.h" +#include "player.h" +#include "shareddefs.h" +#include "studio.h" +#include "bone_setup.h" +#include "mathlib/mathlib.h" +#include "model_types.h" +#include "datacache/imdlcache.h" +#include "physics.h" +#include "ndebugoverlay.h" +#include "tier1/strtools.h" +#include "npcevent.h" +#include "isaverestore.h" +#include "KeyValues.h" +#include "tier0/vprof.h" +#include "EntityFlame.h" +#include "EntityDissolve.h" +#include "ai_basenpc.h" +#include "physics_prop_ragdoll.h" +#include "datacache/idatacache.h" +#include "smoke_trail.h" +#include "props.h" +#include "util.h" //============================================================================= // HPE_BEGIN @@ -6658,7 +6692,6 @@ CBaseEntity *CCSPlayer::GiveNamedItem( const char *pszName, int iSubType ) return pent; } - void CCSPlayer::DoAnimationEvent( PlayerAnimEvent_t event, int nData ) { if ( event == PLAYERANIMEVENT_THROW_GRENADE ) diff --git a/game/shared/basecombatweapon_shared.cpp b/game/shared/basecombatweapon_shared.cpp index bafbbaa938..dfed195a56 100644 --- a/game/shared/basecombatweapon_shared.cpp +++ b/game/shared/basecombatweapon_shared.cpp @@ -185,7 +185,6 @@ void CBaseCombatWeapon::UnlockStudioHdr() void CBaseCombatWeapon::SetupBones(CStudioHdr* pStudioHdr, matrix3x4_t* pBoneToWorld, int boneMask) { - // hooked m_pStudioHdr to world model instead (m_pStudioWorldHdr) BaseClass::SetupBones(m_pStudioWorldHdr, pBoneToWorld, boneMask); } #endif diff --git a/game/shared/bone_merge_cache.cpp b/game/shared/bone_merge_cache.cpp index 9487fa6f2d..2abc90db4b 100644 --- a/game/shared/bone_merge_cache.cpp +++ b/game/shared/bone_merge_cache.cpp @@ -58,11 +58,7 @@ void CBoneMergeCache::UpdateCache() return; } -#ifdef CLIENT_DLL - C_BaseAnimating* pTestFollow = m_pOwner->FindFollowedEntity(); -#else - CBaseAnimating* pTestFollow = dynamic_cast(m_pOwner->GetFollowedEntity()); -#endif + CBaseAnimating* pTestFollow = m_pOwner->FindFollowedEntity(); CStudioHdr* pTestHdr = (pTestFollow ? pTestFollow->GetModelPtr() : NULL); // TODO_ENHANCED: We really need a better way to do this ... @@ -152,7 +148,7 @@ void CBoneMergeCache::MergeMatchingBones( int boneMask , matrix3x4_t mergedbones matrix3x4_t bones[MAXSTUDIOBONES]; // Have the entity we're following setup its bones. #ifdef CLIENT_DLL - m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime); + m_pFollow->SetupBones(bones, m_pFollowHdr->numbones(), m_nFollowBoneSetupMask, gpGlobals->curtime); #else m_pFollow->SetupBones(m_pFollowHdr, bones, m_nFollowBoneSetupMask); #endif diff --git a/game/shared/bone_merge_cache.h b/game/shared/bone_merge_cache.h index 522d42a895..16f47e941b 100644 --- a/game/shared/bone_merge_cache.h +++ b/game/shared/bone_merge_cache.h @@ -65,9 +65,7 @@ private: CStudioHdr *m_pFollowHdr; const studiohdr_t *m_pFollowRenderHdr; 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 int m_nFollowBoneSetupMask;