Added jigglebones

This commit is contained in:
Kamay Xutax 2024-08-21 08:31:19 +02:00
parent 6e9520277f
commit e8c19bcd1e
5 changed files with 108 additions and 49 deletions

View file

@ -5,6 +5,8 @@
//=============================================================================// //=============================================================================//
#include "cbase.h" #include "cbase.h"
#include "bone_accessor.h"
#include "jigglebones.h"
#include "baseanimating.h" #include "baseanimating.h"
#include "animation.h" #include "animation.h"
#include "activitylist.h" #include "activitylist.h"
@ -293,6 +295,7 @@ CBaseAnimating::CBaseAnimating()
m_fBoneCacheFlags = 0; m_fBoneCacheFlags = 0;
m_pBoneMergeCache = NULL; m_pBoneMergeCache = NULL;
m_pBoneCache = NULL; m_pBoneCache = NULL;
m_pJiggleBones = NULL;
} }
CBaseAnimating::~CBaseAnimating() CBaseAnimating::~CBaseAnimating()
@ -301,6 +304,8 @@ CBaseAnimating::~CBaseAnimating()
delete m_pIk; delete m_pIk;
UnlockStudioHdr(); UnlockStudioHdr();
delete m_pStudioHdr; delete m_pStudioHdr;
delete m_pBoneMergeCache;
delete m_pJiggleBones;
} }
void CBaseAnimating::Precache() void CBaseAnimating::Precache()
@ -1785,21 +1790,10 @@ void CBaseAnimating::ApplyBoneMatrixTransform( matrix3x4_t& transform )
} }
void CBaseAnimating::BuildMatricesWithBoneMerge( void CBaseAnimating::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed, matrix3x4_t pBonesOut[] )
const CStudioHdr *pStudioHdr,
const QAngle& angles,
const Vector& origin,
const Vector pos[MAXSTUDIOBONES],
const Quaternion q[MAXSTUDIOBONES],
matrix3x4_t bonetoworld[MAXSTUDIOBONES],
int boneMask
)
{ {
mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); mstudiobone_t *pbones = pStudioHdr->pBone( 0 );
matrix3x4_t bonematrix; matrix3x4_t bonematrix;
matrix3x4_t rotationmatrix; // model to world transformation
AngleMatrix( angles, origin, rotationmatrix);
bool boneMerge = IsEffectActive(EF_BONEMERGE); bool boneMerge = IsEffectActive(EF_BONEMERGE);
if ( boneMerge || m_pBoneMergeCache ) if ( boneMerge || m_pBoneMergeCache )
@ -1811,7 +1805,7 @@ void CBaseAnimating::BuildMatricesWithBoneMerge(
m_pBoneMergeCache = new CBoneMergeCache; m_pBoneMergeCache = new CBoneMergeCache;
m_pBoneMergeCache->Init( this ); m_pBoneMergeCache->Init( this );
} }
m_pBoneMergeCache->MergeMatchingBones( boneMask, bonetoworld ); m_pBoneMergeCache->MergeMatchingBones( boneMask, pBonesOut );
} }
else else
{ {
@ -1831,38 +1825,75 @@ void CBaseAnimating::BuildMatricesWithBoneMerge(
if ( m_pBoneMergeCache && m_pBoneMergeCache->IsBoneMerged( i ) ) if ( m_pBoneMergeCache && m_pBoneMergeCache->IsBoneMerged( i ) )
continue; continue;
CBoneAccessor boneAccess(pBonesOut);
boneAccess.SetReadableBones(boneMask);
boneAccess.SetWritableBones(boneMask);
// animate all non-simulated bones
if ( CalcProceduralBone( pStudioHdr, i, boneAccess ))
{
continue;
}
// skip bones that the IK has already setup
else if (boneComputed.IsBoneMarked( i ))
{
continue;
}
else
{
QuaternionMatrix( q[i], pos[i], bonematrix ); QuaternionMatrix( q[i], pos[i], bonematrix );
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) && if ( (pStudioHdr->boneFlags( i ) & BONE_ALWAYS_PROCEDURAL) &&
(pStudioHdr->pBone( i )->proctype & STUDIO_PROC_JIGGLE) ) (pStudioHdr->pBone( i )->proctype & STUDIO_PROC_JIGGLE) )
{ {
//
// 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; matrix3x4_t goalMX;
if (pbones[i].parent == -1) if (pbones[i].parent == -1)
{ {
ConcatTransforms( rotationmatrix, bonematrix, goalMX ); ConcatTransforms( cameraTransform, bonematrix, goalMX );
} }
else else
{ {
ConcatTransforms( bonetoworld[pbones[i].parent], bonematrix, goalMX ); ConcatTransforms( pBonesOut[pbones[i].parent], bonematrix, goalMX );
} }
// TODO_ENHANCED: jiggles. // 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) else if (pStudioHdr->boneParent(i) == -1)
{ {
ConcatTransforms( rotationmatrix, bonematrix, bonetoworld[i] ); ConcatTransforms( cameraTransform, bonematrix, pBonesOut[i] );
} }
else else
{ {
ConcatTransforms( bonetoworld[pStudioHdr->boneParent(i)], bonematrix, bonetoworld[i] ); ConcatTransforms( pBonesOut[pStudioHdr->boneParent(i)], bonematrix, pBonesOut[i] );
}
} }
if (pStudioHdr->boneParent(i) == -1) if (pStudioHdr->boneParent(i) == -1)
{ {
// Apply client-side effects to the transformation matrix // 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. // Remove IK to respect more the client hitboxes.
Vector adjOrigin = GetAbsOrigin(); Vector adjOrigin = GetAbsOrigin();
CBoneBitList boneComputed;
if ( CanSkipAnimation() ) if ( CanSkipAnimation() )
{ {
IBoneSetup boneSetup( pStudioHdr, boneMask, GetPoseParameterArray() ); IBoneSetup boneSetup( pStudioHdr, boneMask, GetPoseParameterArray() );
@ -1971,7 +2004,6 @@ void CBaseAnimating::SetupBones( CStudioHdr* pStudioHdr, matrix3x4_t *pBoneToWor
if ( m_pIk ) if ( m_pIk )
{ {
// FIXME: pass this into Studio_BuildMatrices to skip transforms // FIXME: pass this into Studio_BuildMatrices to skip transforms
CBoneBitList boneComputed;
m_iIKCounter++; m_iIKCounter++;
m_pIk->Init( pStudioHdr, GetAbsAngles(), adjOrigin, gpGlobals->curtime, m_iIKCounter, boneMask ); m_pIk->Init( pStudioHdr, GetAbsAngles(), adjOrigin, gpGlobals->curtime, m_iIKCounter, boneMask );
GetSkeleton( pStudioHdr, pos, q, 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); m_pBoneCache->UpdateBones(pBoneToWorld, pStudioHdr->numbones(), gpGlobals->curtime);
@ -2712,9 +2748,6 @@ void CBaseAnimating::UnlockStudioHdr()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CBoneCache *CBaseAnimating::GetBoneCache( void ) CBoneCache *CBaseAnimating::GetBoneCache( void )
{ {
CStudioHdr *pStudioHdr = GetModelPtr( );
Assert(pStudioHdr);
int boneMask = BONE_USED_BY_HITBOX | BONE_USED_BY_ATTACHMENT | BONE_USED_BY_BONE_MERGE; 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 // TF queries these bones to position weapons when players are killed
@ -3730,6 +3763,12 @@ CStudioHdr *CBaseAnimating::OnNewModel()
{ {
(void) BaseClass::OnNewModel(); (void) BaseClass::OnNewModel();
if (m_pJiggleBones)
{
delete m_pJiggleBones;
m_pJiggleBones = NULL;
}
if ( m_pBoneMergeCache ) if ( m_pBoneMergeCache )
{ {
delete m_pBoneMergeCache; delete m_pBoneMergeCache;

View file

@ -6,6 +6,7 @@
#ifndef BASEANIMATING_H #ifndef BASEANIMATING_H
#define BASEANIMATING_H #define BASEANIMATING_H
#include "jigglebones.h"
#include "mathlib/vector.h" #include "mathlib/vector.h"
#include "networkvar.h" #include "networkvar.h"
#include "shareddefs.h" #include "shareddefs.h"
@ -20,6 +21,8 @@
#include "tier0/threadtools.h" #include "tier0/threadtools.h"
#include "bone_merge_cache.h" #include "bone_merge_cache.h"
class CJiggleBones;
class CBoneBitList;
class CBasePlayer; class CBasePlayer;
struct animevent_t; struct animevent_t;
struct matrix3x4_t; struct matrix3x4_t;
@ -326,9 +329,7 @@ public:
const float* GetPoseParameterArray() { return m_flPoseParameter.Base(); } const float* GetPoseParameterArray() { return m_flPoseParameter.Base(); }
const float *GetEncodedControllerArray() { return m_flEncodedController.Base(); } const float *GetEncodedControllerArray() { return m_flEncodedController.Base(); }
void BuildMatricesWithBoneMerge( const CStudioHdr *pStudioHdr, const QAngle& angles, void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed, matrix3x4_t pBonesOut[] );
const Vector& origin, const Vector pos[MAXSTUDIOBONES],
const Quaternion q[MAXSTUDIOBONES], matrix3x4_t bonetoworld[MAXSTUDIOBONES], int boneMask );
virtual void ApplyBoneMatrixTransform(matrix3x4_t& transform); virtual void ApplyBoneMatrixTransform(matrix3x4_t& transform);
void SetFadeDistance( float minFadeDist, float maxFadeDist ); void SetFadeDistance( float minFadeDist, float maxFadeDist );
@ -430,7 +431,7 @@ public:
CThreadFastMutex m_BoneSetupMutex; CThreadFastMutex m_BoneSetupMutex;
CBoneCache *m_pBoneCache; CBoneCache *m_pBoneCache;
CBoneMergeCache *m_pBoneMergeCache; CBoneMergeCache *m_pBoneMergeCache;
CJiggleBones *m_pJiggleBones;
// FIXME: necessary so that cyclers can hack m_bSequenceFinished // FIXME: necessary so that cyclers can hack m_bSequenceFinished
friend class CFlexCycler; friend class CFlexCycler;
friend class CCycler; friend class CCycler;

View file

@ -78,6 +78,7 @@ $Project
$Folder "Source Files" $Folder "Source Files"
{ {
$File "$SRCDIR\public\jigglebones.cpp"
$File "$SRCDIR\game\shared\bone_merge_cache.cpp" $File "$SRCDIR\game\shared\bone_merge_cache.cpp"
$File "$SRCDIR\game\shared\achievement_saverestore.cpp" $File "$SRCDIR\game\shared\achievement_saverestore.cpp"
$File "$SRCDIR\game\shared\achievement_saverestore.h" $File "$SRCDIR\game\shared\achievement_saverestore.h"

View file

@ -154,7 +154,7 @@ void CBoneMergeCache::MergeMatchingBones( int boneMask , matrix3x4_t mergedbones
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime); m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime);
#else #else
m_pFollow->SetupBones(m_pFollow->GetModelPtr(), bones, m_nFollowBoneSetupMask); m_pFollow->SetupBones(m_pFollowHdr, bones, m_nFollowBoneSetupMask);
#endif #endif
// Now copy the bone matrices. // Now copy the bone matrices.
@ -166,6 +166,21 @@ void CBoneMergeCache::MergeMatchingBones( int boneMask , matrix3x4_t mergedbones
// Only update bones reference by the bone mask. // Only update bones reference by the bone mask.
if ( !( m_pOwnerHdr->boneFlags( iOwnerBone ) & boneMask ) ) if ( !( m_pOwnerHdr->boneFlags( iOwnerBone ) & boneMask ) )
continue; 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 #ifdef CLIENT_DLL
MatrixCopy( bones[ iParentBone ], mergedbones[ iOwnerBone ] ); MatrixCopy( bones[ iParentBone ], mergedbones[ iOwnerBone ] );
@ -253,7 +268,7 @@ bool CBoneMergeCache::GetAimEntOrigin( Vector *pAbsOrigin, QAngle *pAbsAngles )
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime); m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime);
#else #else
m_pFollow->SetupBones(m_pFollow->GetModelPtr(), bones, m_nFollowBoneSetupMask); m_pFollow->SetupBones(m_pFollowHdr, bones, m_nFollowBoneSetupMask);
#endif #endif
const matrix3x4_t &mFollowBone = bones[ m_MergedBones[0].m_iParentBone ]; const matrix3x4_t &mFollowBone = bones[ m_MergedBones[0].m_iParentBone ];
@ -284,7 +299,7 @@ bool CBoneMergeCache::GetRootBone( matrix3x4_t &rootBone )
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime); m_pFollow->SetupBones(bones, MAXSTUDIOBONES, m_nFollowBoneSetupMask, gpGlobals->curtime);
#else #else
m_pFollow->SetupBones(m_pFollow->GetModelPtr(), bones, m_nFollowBoneSetupMask); m_pFollow->SetupBones(m_pFollowHdr, bones, m_nFollowBoneSetupMask);
#endif #endif
rootBone = bones[ m_MergedBones[0].m_iParentBone ]; rootBone = bones[ m_MergedBones[0].m_iParentBone ];
return true; return true;

View file

@ -11,8 +11,11 @@
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
#include "engine/ivdebugoverlay.h" #include "engine/ivdebugoverlay.h"
#include "cdll_client_int.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!!! // memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h" #include "tier0/memdbgon.h"