-
Notifications
You must be signed in to change notification settings - Fork 3
/
BodyInstance.h
299 lines (253 loc) · 12.3 KB
/
BodyInstance.h
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
// BodyInstance.h: interface for the CBodyInstance class.
//
#ifndef BodyInstanceH
#define BodyInstanceH
#pragma once
#include "fhierrarhyvisual.h"
#include "bone.h"
// consts
const u32 MAX_BONE_PARAMS = 4;
const u32 MAX_BLENDED = 16;
const u32 MAX_PARTS = 4;
const u32 MAX_BLENDED_POOL = (MAX_BLENDED*MAX_PARTS);
const f32 SAMPLE_FPS = 30.f;
const f32 SAMPLE_SPF = (1.f/SAMPLE_FPS);
const u16 BI_NONE = u16(-1);
// refs
class ENGINE_API CKinematics;
struct ENGINE_API CKey;
struct ENGINE_API CKeyQ;
class ENGINE_API CBoneData;
class ENGINE_API CInifile;
class ENGINE_API CBoneInstance;
class ENGINE_API CBlend;
// t-defs
typedef xr_vector<CBoneData*> vecBones;
typedef vecBones::iterator vecBonesIt;
typedef void (__stdcall * BoneCallback) (CBoneInstance* P);
typedef void (__stdcall * PlayCallback) (CBlend* P);
typedef void (__stdcall * UpdateCallback) (CKinematics* P);
//*** Key frame definition ************************************************************************
#pragma pack(push,2)
const float KEY_Quant = 32767.f;
const float KEY_QuantI = 1.f/KEY_Quant;
struct ENGINE_API CKey
{
Fquaternion Q; // rotation
Fvector T; // translation
};
struct ENGINE_API CKeyQ
{
s16 x,y,z,w; // rotation
Fvector t; // translation
};
#pragma pack(pop)
//*** Run-time Blend definition *******************************************************************
class ENGINE_API CBlend {
public:
enum ECurvature
{
eFREE_SLOT=0,
eFixed,
eAccrue,
eFalloff,
eFORCEDWORD = u32(-1)
};
public:
float blendAmount;
float timeCurrent;
float timeTotal;
u16 motionID;
u16 bone_or_part; // startup parameters
ECurvature blend;
float blendAccrue; // increasing
float blendFalloff; // decreasing
float blendPower;
float speed;
BOOL playing;
BOOL stop_at_end;
PlayCallback Callback;
void* CallbackParam;
u32 dwFrame;
};
typedef svector<CBlend*,MAX_BLENDED> BlendList;
typedef BlendList::iterator BlendListIt;
//*** Motion Data *********************************************************************************
class ENGINE_API CMotion
{
public:
CKeyQ* _keys;
u32 _count;
float GetLength() { return float(_count)*SAMPLE_SPF; }
};
//*** Bone Instance *******************************************************************************
#pragma pack(push,8)
class ENGINE_API CBoneInstance
{
public:
// data
Fmatrix mTransform; // final x-form matrix
BlendList Blend;
BoneCallback Callback;
void* Callback_Param;
BOOL Callback_overwrite; // performance hint - don't calc anims
float param [MAX_BONE_PARAMS]; //
// methods
void construct ();
void blend_add (CBlend* H);
void blend_remove (CBlend* H);
void set_callback (BoneCallback C, void* Param);
void set_param (u32 idx, float data);
float get_param (u32 idx);
};
#pragma pack(pop)
//*** Shared Bone Data ****************************************************************************
class ENGINE_API CBoneData
{
public:
typedef svector<int,128> BoneDebug;
public:
u16 SelfID;
vecBones children; // bones which are slaves to this
xr_vector<CMotion> Motions; // all known motions
Fobb obb;
Fvector bind_xyz;
Fvector bind_translate;
SBoneShape shape;
string64 game_mtl;
SJointIKData IK_data;
float mass;
Fvector center_of_mass;
// Motion control
void Motion_Start (CKinematics* K, CBlend* handle); // with recursion
void Motion_Start_IM (CKinematics* K, CBlend* handle);
void Motion_Stop (CKinematics* K, CBlend* handle); // with recursion
void Motion_Stop_IM (CKinematics* K, CBlend* handle);
// Calculation
void Calculate (CKinematics* K, Fmatrix *Parent);
void DebugQuery (BoneDebug& L);
CBoneData(u16 ID) : SelfID (ID) {}
};
//*** Shared motion Data **************************************************************************
class ENGINE_API CMotionDef
{
public:
u16 bone_or_part;
u16 motion;
u16 speed; // quantized: 0..10
u16 power; // quantized: 0..10
u16 accrue; // quantized: 0..10
u16 falloff; // quantized: 0..10
u32 flags;
IC float Dequantize (u16 V) { return float(V)/655.35f; }
IC u16 Quantize (float V) { s32 t = iFloor(V*655.35f); clamp(t,0,65535); return u16(t); }
void Load (CKinematics* P, CInifile* INI, LPCSTR section, BOOL bCycle);
void Load (CKinematics* P, IReader* MP, u32 fl);
CBlend* PlayCycle (CKinematics* P, BOOL bMixIn, PlayCallback Callback, LPVOID Callback_Param);
CBlend* PlayCycle (CKinematics* P, u16 part, BOOL bMixIn, PlayCallback Callback, LPVOID Callback_Param);
CBlend* PlayFX (CKinematics* P, float power_scale);
};
//*** Shared partition Data ***********************************************************************
class ENGINE_API CPartDef
{
public:
ref_str Name;
xr_vector<u32> bones;
CPartDef() : Name(0) {};
};
class ENGINE_API CPartition
{
CPartDef P[MAX_PARTS];
public:
IC CPartDef& operator[] (u16 id) { return P[id]; }
};
//*** The visual itself ***************************************************************************
class ENGINE_API CKinematics : public FHierrarhyVisual
{
typedef FHierrarhyVisual inherited;
friend class CBoneData;
friend class CMotionDef;
friend class CSkeletonX;
private:
struct str_pred : public std::binary_function<ref_str, ref_str, bool> {
IC bool operator()(const ref_str& x, const ref_str& y) const { return strcmp(*x,*y)<0; }
};
public:
typedef xr_map<ref_str,u16,str_pred> accel;
typedef xr_map<ref_str,CMotionDef,str_pred> mdef;
private:
// Globals
CInifile* pUserData;
vecBones* bones; // all bones+motions (shared)
CBoneInstance* bone_instances; // bone instances
u16 iRoot; // Root bone index
// Fast search
accel* motion_map; // motion assotiations (shared)
accel* bone_map; // bones assotiations (shared)
mdef* m_cycle; // motion data itself (shared)
mdef* m_fx; // motion data itself (shared)
// Partition
CPartition* partition;
// Blending
svector<CBlend, MAX_BLENDED_POOL> blend_pool;
BlendList blend_cycles [MAX_PARTS];
BlendList blend_fx;
s32 Update_ID;
u32 Update_LastTime;
u32 Update_Frame;
public:
UpdateCallback Update_Callback;
void* Update_Callback_Param;
protected:
// internal functions
void IBoneInstances_Create ();
void IBoneInstances_Destroy ();
void IBlend_Startup ();
CBlend* IBlend_Create ();
public:
// Low level interface
u16 LL_BoneID (LPCSTR B);
u16 LL_MotionID (LPCSTR B);
u16 LL_PartID (LPCSTR B);
CInifile* LL_UserData (){return pUserData;}
accel* LL_Bones (){return bone_map;}
accel* LL_Motions (){return motion_map;}
CBoneInstance& LL_GetInstance (u16 bone_id) { VERIFY(bone_id<LL_BoneCount()); return bone_instances[bone_id]; }
CBoneData& LL_GetData (u16 bone_id) { VERIFY(bone_id<LL_BoneCount()); return *((*bones)[bone_id]); }
u16 LL_BoneRoot () { return iRoot; }
u16 LL_BoneCount () { return u16(bones->size()); }
Fmatrix& LL_GetTransform (u16 bone_id) { return LL_GetInstance(bone_id).mTransform; }
Fobb& LL_GetBox (u16 bone_id) { VERIFY(bone_id<LL_BoneCount()); return (*bones)[bone_id]->obb; }
CBlend* LL_PlayFX (u16 bone, u16 motion, float blendAccrue, float blendFalloff, float Speed, float Power);
CBlend* LL_PlayCycle (u16 partition, u16 motion, BOOL bMixing, float blendAccrue, float blendFalloff, float Speed, BOOL noloop, PlayCallback Callback, LPVOID Callback_Param);
void LL_FadeCycle (u16 partition, float falloff);
void LL_CloseCycle (u16 partition);
// Main functionality
void Update (); // Update motions
void Calculate (BOOL bLight=FALSE); // Recalculate skeleton (Light mode can be used to avoid interpolation)
void Callback (UpdateCallback C, void* Param) { Update_Callback = C; Update_Callback_Param = Param; }
// cycles
CMotionDef* ID_Cycle (LPCSTR N);
CMotionDef* ID_Cycle_Safe (LPCSTR N);
CBlend* PlayCycle (LPCSTR N, BOOL bMixIn=TRUE, PlayCallback Callback=0, LPVOID CallbackParam=0);
CBlend* PlayCycle (CMotionDef* M, BOOL bMixIn=TRUE, PlayCallback Callback=0, LPVOID CallbackParam=0)
{ VERIFY(M); return M->PlayCycle(this,bMixIn,Callback,CallbackParam); }
void Invalidate ()
{ Update_Frame = 0xffffff; }
// fx'es
CMotionDef* ID_FX (LPCSTR N);
CMotionDef* ID_FX_Safe (LPCSTR N);
CBlend* PlayFX (LPCSTR N, float power_scale);
CBlend* PlayFX (CMotionDef* M, float power_scale)
{ VERIFY(M); return M->PlayFX(this,power_scale); }
// debug
void DebugRender (Fmatrix& XFORM);
// General "Visual" stuff
virtual void Copy (IRender_Visual *pFrom);
virtual void Load (const char* N, IReader *data, u32 dwFlags);
virtual void Release ();
virtual void Spawn ();
virtual ~CKinematics ();
};
IC CKinematics* PKinematics (IRender_Visual* V) { return dynamic_cast<CKinematics*>(V); }
#endif // BodyInstanceH