This commit is contained in:
Kamay Xutax 2024-08-22 23:29:34 +02:00
parent e8c19bcd1e
commit d5868bb85b
13 changed files with 302 additions and 135 deletions

View file

@ -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 );
}
@ -2961,6 +2971,36 @@ bool C_BaseAnimating::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, i
}
}
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 )

View file

@ -99,8 +99,8 @@ public:
enum
{
NUM_POSEPAREMETERS = 24,
NUM_BONECTRLS = 4
NUM_POSEPAREMETERS = MAXSTUDIOPOSEPARAM,
NUM_BONECTRLS = MAXSTUDIOBONECTRLS
};
C_BaseAnimating();

View file

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

View file

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

View file

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

View file

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

View file

@ -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 )
@ -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 );
Vector pos[MAXSTUDIOBONES];
Quaternion q[MAXSTUDIOBONES];
// Remove IK to respect more the client hitboxes.
Vector adjOrigin = GetAbsOrigin();
CBoneBitList boneComputed;
if ( CanSkipAnimation() )
// 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 )) )
{
IBoneSetup boneSetup( pStudioHdr, boneMask, GetPoseParameterArray() );
boneSetup.InitPose( pos, q );
// Msg( "%.03f : %s:%s not in pvs\n", gpGlobals->curtime, GetClassname(), GetEntityName().ToCStr() );
// 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 )
{
// 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 );
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 );
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];
Vector adjOrigin = GetAbsOrigin() + Vector( 0, 0, m_flEstIkOffset );
CBoneBitList boneComputed;
StandardBlendingRules( pStudioHdr, pos, q, boneMask );
if ( m_pIk )
{
UpdateIKLocks( gpGlobals->curtime );
m_pIk->UpdateTargets( pos, q, pBoneToWorld, boneComputed );
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;

View file

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

View file

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

View file

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

View file

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

View file

@ -58,11 +58,7 @@ void CBoneMergeCache::UpdateCache()
return;
}
#ifdef CLIENT_DLL
C_BaseAnimating* pTestFollow = m_pOwner->FindFollowedEntity();
#else
CBaseAnimating* pTestFollow = dynamic_cast<CBaseAnimating*>(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

View file

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