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 "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;

View file

@ -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;

View file

@ -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"

View file

@ -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;

View file

@ -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"