1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef RAGDOLL_SHARED_H
#define RAGDOLL_SHARED_H
#ifdef _WIN32
#pragma once
#endif
class IPhysicsObject;
class IPhysicsConstraint;
class IPhysicsConstraintGroup;
class IPhysicsCollision;
class IPhysicsEnvironment;
class IPhysicsSurfaceProps;
struct matrix3x4_t;
struct vcollide_t;
struct studiohdr_t;
class CStudioHdr;
class CBoneAccessor;
#include "mathlib/vector.h"
#include "bone_accessor.h"
// UNDONE: Remove and make dynamic?
#define RAGDOLL_MAX_ELEMENTS 24
#define RAGDOLL_INDEX_BITS 5 // NOTE 1<<RAGDOLL_INDEX_BITS >= RAGDOLL_MAX_ELEMENTS
#define CORE_DISSOLVE_FADE_START 0.2f
#define CORE_DISSOLVE_MODEL_FADE_START 0.1f
#define CORE_DISSOLVE_MODEL_FADE_LENGTH 0.05f
#define CORE_DISSOLVE_FADEIN_LENGTH 0.1f
struct ragdollelement_t
{
Vector originParentSpace;
IPhysicsObject *pObject; // all valid elements have an object
IPhysicsConstraint *pConstraint; // all valid elements have a constraint (except the root)
int parentIndex;
};
struct ragdollanimatedfriction_t
{
float flFrictionTimeIn;
float flFrictionTimeOut;
float flFrictionTimeHold;
int iMinAnimatedFriction;
int iMaxAnimatedFriction;
};
struct ragdoll_t
{
int listCount;
bool allowStretch;
bool unused;
IPhysicsConstraintGroup *pGroup;
// store these in separate arrays for save/load
ragdollelement_t list[RAGDOLL_MAX_ELEMENTS];
int boneIndex[RAGDOLL_MAX_ELEMENTS];
ragdollanimatedfriction_t animfriction;
};
struct ragdollparams_t
{
void *pGameData;
vcollide_t *pCollide;
CStudioHdr *pStudioHdr;
int modelIndex;
Vector forcePosition;
Vector forceVector;
int forceBoneIndex;
const matrix3x4_t *pCurrentBones;
float jointFrictionScale;
bool allowStretch;
bool fixedConstraints;
};
//-----------------------------------------------------------------------------
// This hooks the main game systems callbacks to allow the AI system to manage memory
//-----------------------------------------------------------------------------
class CRagdollLRURetirement : public CAutoGameSystemPerFrame
{
public:
CRagdollLRURetirement( char const *name ) : CAutoGameSystemPerFrame( name )
{
}
// Methods of IGameSystem
virtual void Update( float frametime );
virtual void FrameUpdatePostEntityThink( void );
// Move it to the top of the LRU
void MoveToTopOfLRU( CBaseAnimating *pRagdoll, bool bImportant = false );
void SetMaxRagdollCount( int iMaxCount ){ m_iMaxRagdolls = iMaxCount; }
virtual void LevelInitPreEntity( void );
int CountRagdolls( bool bOnlySimulatingRagdolls ) { return bOnlySimulatingRagdolls ? m_iSimulatedRagdollCount : m_iRagdollCount; }
private:
typedef CHandle<CBaseAnimating> CRagdollHandle;
CUtlLinkedList< CRagdollHandle > m_LRU;
CUtlLinkedList< CRagdollHandle > m_LRUImportantRagdolls;
int m_iMaxRagdolls;
int m_iSimulatedRagdollCount;
int m_iRagdollCount;
};
extern CRagdollLRURetirement s_RagdollLRU;
// Manages ragdolls fading for the low violence versions
class CRagdollLowViolenceManager
{
public:
CRagdollLowViolenceManager(){ m_bLowViolence = false; }
// Turn the low violence ragdoll stuff off if we're in the HL2 Citadel maps because
// the player has the super gravity gun and fading ragdolls will break things.
void SetLowViolence( const char *pMapName );
bool IsLowViolence( void ){ return m_bLowViolence; }
private:
bool m_bLowViolence;
};
extern CRagdollLowViolenceManager g_RagdollLVManager;
bool RagdollCreate( ragdoll_t &ragdoll, const ragdollparams_t ¶ms, IPhysicsEnvironment *pPhysEnv );
void RagdollActivate( ragdoll_t &ragdoll, vcollide_t *pCollide, int modelIndex, bool bForceWake = true );
void RagdollSetupCollisions( ragdoll_t &ragdoll, vcollide_t *pCollide, int modelIndex );
void RagdollDestroy( ragdoll_t &ragdoll );
// Gets the bone matrix for a ragdoll object
// NOTE: This is different than the object's position because it is
// forced to be rigidly attached in parent space
bool RagdollGetBoneMatrix( const ragdoll_t &ragdoll, CBoneAccessor &pBoneToWorld, int objectIndex );
// Parse the ragdoll and obtain the mapping from each physics element index to a bone index
// returns num phys elements
int RagdollExtractBoneIndices( int *boneIndexOut, CStudioHdr *pStudioHdr, vcollide_t *pCollide );
// computes an exact bbox of the ragdoll's physics objects
void RagdollComputeExactBbox( const ragdoll_t &ragdoll, const Vector &origin, Vector &outMins, Vector &outMaxs );
bool RagdollIsAsleep( const ragdoll_t &ragdoll );
void RagdollSetupAnimatedFriction( IPhysicsEnvironment *pPhysEnv, ragdoll_t *ragdoll, int iModelIndex );
void RagdollApplyAnimationAsVelocity( ragdoll_t &ragdoll, const matrix3x4_t *pBoneToWorld );
void RagdollApplyAnimationAsVelocity( ragdoll_t &ragdoll, const matrix3x4_t *pPrevBones, const matrix3x4_t *pCurrentBones, float dt );
void RagdollSolveSeparation( ragdoll_t &ragdoll, CBaseEntity *pEntity );
#endif // RAGDOLL_SHARED_H
|