From e8c19bcd1e778993cc6c16d13d81363fa3a5b123 Mon Sep 17 00:00:00 2001 From: Kamay Xutax Date: Wed, 21 Aug 2024 08:31:19 +0200 Subject: [PATCH] Added jigglebones --- game/server/baseanimating.cpp | 117 ++++++++++++++++++++----------- game/server/baseanimating.h | 9 +-- game/server/server_base.vpc | 1 + game/shared/bone_merge_cache.cpp | 23 ++++-- public/jigglebones.cpp | 7 +- 5 files changed, 108 insertions(+), 49 deletions(-) diff --git a/game/server/baseanimating.cpp b/game/server/baseanimating.cpp index 746a62b48d..18d7c93ca8 100644 --- a/game/server/baseanimating.cpp +++ b/game/server/baseanimating.cpp @@ -5,6 +5,8 @@ //=============================================================================// #include "cbase.h" +#include "bone_accessor.h" +#include "jigglebones.h" #include "baseanimating.h" #include "animation.h" #include "activitylist.h" @@ -293,6 +295,7 @@ CBaseAnimating::CBaseAnimating() m_fBoneCacheFlags = 0; m_pBoneMergeCache = NULL; m_pBoneCache = NULL; + m_pJiggleBones = NULL; } CBaseAnimating::~CBaseAnimating() @@ -300,7 +303,9 @@ CBaseAnimating::~CBaseAnimating() Studio_DestroyBoneCache( m_boneCacheHandle ); delete m_pIk; UnlockStudioHdr(); - delete m_pStudioHdr; + delete m_pStudioHdr; + delete m_pBoneMergeCache; + delete m_pJiggleBones; } void CBaseAnimating::Precache() @@ -1785,21 +1790,10 @@ void CBaseAnimating::ApplyBoneMatrixTransform( matrix3x4_t& transform ) } -void CBaseAnimating::BuildMatricesWithBoneMerge( - const CStudioHdr *pStudioHdr, - const QAngle& angles, - const Vector& origin, - const Vector pos[MAXSTUDIOBONES], - const Quaternion q[MAXSTUDIOBONES], - matrix3x4_t bonetoworld[MAXSTUDIOBONES], - int boneMask - ) +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; - matrix3x4_t rotationmatrix; // model to world transformation - AngleMatrix( angles, origin, rotationmatrix); bool boneMerge = IsEffectActive(EF_BONEMERGE); if ( boneMerge || m_pBoneMergeCache ) @@ -1811,7 +1805,7 @@ void CBaseAnimating::BuildMatricesWithBoneMerge( m_pBoneMergeCache = new CBoneMergeCache; m_pBoneMergeCache->Init( this ); } - m_pBoneMergeCache->MergeMatchingBones( boneMask, bonetoworld ); + m_pBoneMergeCache->MergeMatchingBones( boneMask, pBonesOut ); } else { @@ -1831,38 +1825,75 @@ void CBaseAnimating::BuildMatricesWithBoneMerge( if ( m_pBoneMergeCache && m_pBoneMergeCache->IsBoneMerged( i ) ) continue; - QuaternionMatrix( q[i], pos[i], bonematrix ); + CBoneAccessor boneAccess(pBonesOut); + boneAccess.SetReadableBones(boneMask); + boneAccess.SetWritableBones(boneMask); - if ( (pStudioHdr->boneFlags( i ) & BONE_ALWAYS_PROCEDURAL) && - (pStudioHdr->pBone( i )->proctype & STUDIO_PROC_JIGGLE) ) + // animate all non-simulated bones + if ( CalcProceduralBone( pStudioHdr, i, boneAccess )) { - matrix3x4_t goalMX; + continue; + } + // skip bones that the IK has already setup + else if (boneComputed.IsBoneMarked( i )) + { + continue; + } + else + { + QuaternionMatrix( q[i], pos[i], bonematrix ); - if (pbones[i].parent == -1) + Assert( fabs( pos[i].x ) < 100000 ); + Assert( fabs( pos[i].y ) < 100000 ); + Assert( fabs( pos[i].z ) < 100000 ); + + if ( (pStudioHdr->boneFlags( i ) & BONE_ALWAYS_PROCEDURAL) && + (pStudioHdr->pBone( i )->proctype & STUDIO_PROC_JIGGLE) ) { - ConcatTransforms( rotationmatrix, bonematrix, goalMX ); + // + // Physics-based "jiggle" bone + // Bone is assumed to be along the Z axis + // Pitch around X, yaw around Y + // + + // compute desired bone orientation + matrix3x4_t goalMX; + + if (pbones[i].parent == -1) + { + ConcatTransforms( cameraTransform, bonematrix, goalMX ); + } + else + { + ConcatTransforms( pBonesOut[pbones[i].parent], bonematrix, goalMX ); + } + + // get jiggle properties from QC data + mstudiojigglebone_t *jiggleInfo = (mstudiojigglebone_t *)pbones[i].pProcedure( ); + + if (!m_pJiggleBones) + { + m_pJiggleBones = new CJiggleBones; + } + + // do jiggle physics + m_pJiggleBones->BuildJiggleTransformations( i, gpGlobals->curtime, jiggleInfo, goalMX, pBonesOut[i] ); + + } + else if (pStudioHdr->boneParent(i) == -1) + { + ConcatTransforms( cameraTransform, bonematrix, pBonesOut[i] ); } else { - ConcatTransforms( bonetoworld[pbones[i].parent], bonematrix, goalMX ); - } - - // TODO_ENHANCED: jiggles. - - } - else if (pStudioHdr->boneParent(i) == -1) - { - ConcatTransforms( rotationmatrix, bonematrix, bonetoworld[i] ); - } - else - { - ConcatTransforms( bonetoworld[pStudioHdr->boneParent(i)], bonematrix, bonetoworld[i] ); + ConcatTransforms( pBonesOut[pStudioHdr->boneParent(i)], bonematrix, pBonesOut[i] ); + } } if (pStudioHdr->boneParent(i) == -1) { // Apply client-side effects to the transformation matrix - ApplyBoneMatrixTransform( bonetoworld[i] ); + ApplyBoneMatrixTransform( pBonesOut[i] ); } } } @@ -1960,6 +1991,8 @@ void CBaseAnimating::SetupBones( CStudioHdr* pStudioHdr, matrix3x4_t *pBoneToWor // Remove IK to respect more the client hitboxes. Vector adjOrigin = GetAbsOrigin(); + CBoneBitList boneComputed; + if ( CanSkipAnimation() ) { IBoneSetup boneSetup( pStudioHdr, boneMask, GetPoseParameterArray() ); @@ -1971,7 +2004,6 @@ void CBaseAnimating::SetupBones( CStudioHdr* pStudioHdr, matrix3x4_t *pBoneToWor if ( m_pIk ) { // FIXME: pass this into Studio_BuildMatrices to skip transforms - CBoneBitList boneComputed; m_iIKCounter++; m_pIk->Init( pStudioHdr, GetAbsAngles(), adjOrigin, gpGlobals->curtime, m_iIKCounter, boneMask ); GetSkeleton( pStudioHdr, pos, q, boneMask ); @@ -1987,7 +2019,11 @@ void CBaseAnimating::SetupBones( CStudioHdr* pStudioHdr, matrix3x4_t *pBoneToWor } } - BuildMatricesWithBoneMerge(pStudioHdr, GetAbsAngles(), adjOrigin, pos, q, pBoneToWorld, boneMask); + 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); @@ -2712,9 +2748,6 @@ void CBaseAnimating::UnlockStudioHdr() //----------------------------------------------------------------------------- CBoneCache *CBaseAnimating::GetBoneCache( void ) { - CStudioHdr *pStudioHdr = GetModelPtr( ); - Assert(pStudioHdr); - int boneMask = BONE_USED_BY_HITBOX | BONE_USED_BY_ATTACHMENT | BONE_USED_BY_BONE_MERGE; // TF queries these bones to position weapons when players are killed @@ -3730,6 +3763,12 @@ CStudioHdr *CBaseAnimating::OnNewModel() { (void) BaseClass::OnNewModel(); + if (m_pJiggleBones) + { + delete m_pJiggleBones; + m_pJiggleBones = NULL; + } + if ( m_pBoneMergeCache ) { delete m_pBoneMergeCache; diff --git a/game/server/baseanimating.h b/game/server/baseanimating.h index f4c9c80136..5b330d1073 100644 --- a/game/server/baseanimating.h +++ b/game/server/baseanimating.h @@ -6,6 +6,7 @@ #ifndef BASEANIMATING_H #define BASEANIMATING_H +#include "jigglebones.h" #include "mathlib/vector.h" #include "networkvar.h" #include "shareddefs.h" @@ -20,6 +21,8 @@ #include "tier0/threadtools.h" #include "bone_merge_cache.h" +class CJiggleBones; +class CBoneBitList; class CBasePlayer; struct animevent_t; struct matrix3x4_t; @@ -326,9 +329,7 @@ public: const float* GetPoseParameterArray() { return m_flPoseParameter.Base(); } const float *GetEncodedControllerArray() { return m_flEncodedController.Base(); } - void BuildMatricesWithBoneMerge( const CStudioHdr *pStudioHdr, const QAngle& angles, - const Vector& origin, const Vector pos[MAXSTUDIOBONES], - const Quaternion q[MAXSTUDIOBONES], matrix3x4_t bonetoworld[MAXSTUDIOBONES], int boneMask ); + void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed, matrix3x4_t pBonesOut[] ); virtual void ApplyBoneMatrixTransform(matrix3x4_t& transform); void SetFadeDistance( float minFadeDist, float maxFadeDist ); @@ -430,7 +431,7 @@ public: CThreadFastMutex m_BoneSetupMutex; CBoneCache *m_pBoneCache; CBoneMergeCache *m_pBoneMergeCache; - + CJiggleBones *m_pJiggleBones; // FIXME: necessary so that cyclers can hack m_bSequenceFinished friend class CFlexCycler; friend class CCycler; diff --git a/game/server/server_base.vpc b/game/server/server_base.vpc index cfa14816be..58bd1615ae 100644 --- a/game/server/server_base.vpc +++ b/game/server/server_base.vpc @@ -78,6 +78,7 @@ $Project $Folder "Source Files" { + $File "$SRCDIR\public\jigglebones.cpp" $File "$SRCDIR\game\shared\bone_merge_cache.cpp" $File "$SRCDIR\game\shared\achievement_saverestore.cpp" $File "$SRCDIR\game\shared\achievement_saverestore.h" diff --git a/game/shared/bone_merge_cache.cpp b/game/shared/bone_merge_cache.cpp index 23ca311210..9487fa6f2d 100644 --- a/game/shared/bone_merge_cache.cpp +++ b/game/shared/bone_merge_cache.cpp @@ -154,7 +154,7 @@ void CBoneMergeCache::MergeMatchingBones( int boneMask , matrix3x4_t mergedbones #ifdef CLIENT_DLL m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime); #else - m_pFollow->SetupBones(m_pFollow->GetModelPtr(), bones, m_nFollowBoneSetupMask); + m_pFollow->SetupBones(m_pFollowHdr, bones, m_nFollowBoneSetupMask); #endif // Now copy the bone matrices. @@ -166,7 +166,22 @@ void CBoneMergeCache::MergeMatchingBones( int boneMask , matrix3x4_t mergedbones // Only update bones reference by the bone mask. if ( !( m_pOwnerHdr->boneFlags( iOwnerBone ) & boneMask ) ) continue; - +// #ifdef CLIENT_DLL +// printf("client bone attach: (%i - %i) %i", m_pFollow->entindex(), m_pOwner->entindex(), i); +// for (int j = 0; j < 12; j++) +// { +// printf(" %f ", bones[iParentBone].Base()[i]); +// } +// printf("\n"); +// #else +// printf("server bone attach: (%i - %i) %i", m_pFollow->entindex(), m_pOwner->entindex(), i); +// for (int j = 0; j < 12; j++) +// { +// printf(" %f ", bones[iParentBone].Base()[i]); +// } +// printf("\n"); +// #endif + #ifdef CLIENT_DLL MatrixCopy( bones[ iParentBone ], mergedbones[ iOwnerBone ] ); #else @@ -253,7 +268,7 @@ bool CBoneMergeCache::GetAimEntOrigin( Vector *pAbsOrigin, QAngle *pAbsAngles ) #ifdef CLIENT_DLL m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime); #else - m_pFollow->SetupBones(m_pFollow->GetModelPtr(), bones, m_nFollowBoneSetupMask); + m_pFollow->SetupBones(m_pFollowHdr, bones, m_nFollowBoneSetupMask); #endif const matrix3x4_t &mFollowBone = bones[ m_MergedBones[0].m_iParentBone ]; @@ -284,7 +299,7 @@ bool CBoneMergeCache::GetRootBone( matrix3x4_t &rootBone ) #ifdef CLIENT_DLL m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime); #else - m_pFollow->SetupBones(m_pFollow->GetModelPtr(), bones, m_nFollowBoneSetupMask); + m_pFollow->SetupBones(m_pFollowHdr, bones, m_nFollowBoneSetupMask); #endif rootBone = bones[ m_MergedBones[0].m_iParentBone ]; return true; diff --git a/public/jigglebones.cpp b/public/jigglebones.cpp index d0351ae0a9..8a5d78bf7e 100644 --- a/public/jigglebones.cpp +++ b/public/jigglebones.cpp @@ -11,8 +11,11 @@ #ifdef CLIENT_DLL #include "engine/ivdebugoverlay.h" #include "cdll_client_int.h" -#endif // CLIENT_DLL - +#else // CLIENT_DLL +#include "shareddefs.h" +#include "mathlib/vmatrix.h" +#include "util.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h"