Anim.h (20046B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 #ifndef __ANIM_H__ 29 #define __ANIM_H__ 30 31 // 32 // animation channels 33 // these can be changed by modmakers and licensees to be whatever they need. 34 const int ANIM_NumAnimChannels = 5; 35 const int ANIM_MaxAnimsPerChannel = 3; 36 const int ANIM_MaxSyncedAnims = 3; 37 38 // 39 // animation channels. make sure to change script/doom_defs.script if you add any channels, or change their order 40 // 41 const int ANIMCHANNEL_ALL = 0; 42 const int ANIMCHANNEL_TORSO = 1; 43 const int ANIMCHANNEL_LEGS = 2; 44 const int ANIMCHANNEL_HEAD = 3; 45 const int ANIMCHANNEL_EYELIDS = 4; 46 47 // for converting from 24 frames per second to milliseconds 48 ID_INLINE int FRAME2MS( int framenum ) { 49 return ( framenum * 1000 ) / 24; 50 } 51 52 class idRenderModel; 53 class idAnimator; 54 class idAnimBlend; 55 class function_t; 56 class idEntity; 57 class idSaveGame; 58 class idRestoreGame; 59 60 typedef struct { 61 int cycleCount; // how many times the anim has wrapped to the begining (0 for clamped anims) 62 int frame1; 63 int frame2; 64 float frontlerp; 65 float backlerp; 66 } frameBlend_t; 67 68 typedef struct { 69 int nameIndex; 70 int parentNum; 71 int animBits; 72 int firstComponent; 73 } jointAnimInfo_t; 74 75 typedef struct { 76 jointHandle_t num; 77 jointHandle_t parentNum; 78 int channel; 79 } jointInfo_t; 80 81 // 82 // joint modifier modes. make sure to change script/doom_defs.script if you add any, or change their order. 83 // 84 typedef enum { 85 JOINTMOD_NONE, // no modification 86 JOINTMOD_LOCAL, // modifies the joint's position or orientation in joint local space 87 JOINTMOD_LOCAL_OVERRIDE, // sets the joint's position or orientation in joint local space 88 JOINTMOD_WORLD, // modifies joint's position or orientation in model space 89 JOINTMOD_WORLD_OVERRIDE // sets the joint's position or orientation in model space 90 } jointModTransform_t; 91 92 typedef struct { 93 jointHandle_t jointnum; 94 idMat3 mat; 95 idVec3 pos; 96 jointModTransform_t transform_pos; 97 jointModTransform_t transform_axis; 98 } jointMod_t; 99 100 #define ANIM_BIT_TX 0 101 #define ANIM_BIT_TY 1 102 #define ANIM_BIT_TZ 2 103 #define ANIM_BIT_QX 3 104 #define ANIM_BIT_QY 4 105 #define ANIM_BIT_QZ 5 106 107 #define ANIM_TX BIT( ANIM_BIT_TX ) 108 #define ANIM_TY BIT( ANIM_BIT_TY ) 109 #define ANIM_TZ BIT( ANIM_BIT_TZ ) 110 #define ANIM_QX BIT( ANIM_BIT_QX ) 111 #define ANIM_QY BIT( ANIM_BIT_QY ) 112 #define ANIM_QZ BIT( ANIM_BIT_QZ ) 113 114 typedef enum { 115 FC_SCRIPTFUNCTION, 116 FC_SCRIPTFUNCTIONOBJECT, 117 FC_EVENTFUNCTION, 118 FC_SOUND, 119 FC_SOUND_VOICE, 120 FC_SOUND_VOICE2, 121 FC_SOUND_BODY, 122 FC_SOUND_BODY2, 123 FC_SOUND_BODY3, 124 FC_SOUND_WEAPON, 125 FC_SOUND_ITEM, 126 FC_SOUND_GLOBAL, 127 FC_SOUND_CHATTER, 128 FC_SKIN, 129 FC_TRIGGER, 130 FC_TRIGGER_SMOKE_PARTICLE, 131 FC_MELEE, 132 FC_DIRECTDAMAGE, 133 FC_BEGINATTACK, 134 FC_ENDATTACK, 135 FC_MUZZLEFLASH, 136 FC_CREATEMISSILE, 137 FC_LAUNCHMISSILE, 138 FC_FIREMISSILEATTARGET, 139 FC_FOOTSTEP, 140 FC_LEFTFOOT, 141 FC_RIGHTFOOT, 142 FC_ENABLE_EYE_FOCUS, 143 FC_DISABLE_EYE_FOCUS, 144 FC_FX, 145 FC_DISABLE_GRAVITY, 146 FC_ENABLE_GRAVITY, 147 FC_JUMP, 148 FC_ENABLE_CLIP, 149 FC_DISABLE_CLIP, 150 FC_ENABLE_WALK_IK, 151 FC_DISABLE_WALK_IK, 152 FC_ENABLE_LEG_IK, 153 FC_DISABLE_LEG_IK, 154 FC_RECORDDEMO, 155 FC_AVIGAME 156 , FC_LAUNCH_PROJECTILE, 157 FC_TRIGGER_FX, 158 FC_START_EMITTER, 159 FC_STOP_EMITTER, 160 } frameCommandType_t; 161 162 typedef struct { 163 int num; 164 int firstCommand; 165 } frameLookup_t; 166 167 typedef struct { 168 frameCommandType_t type; 169 idStr *string; 170 171 union { 172 const idSoundShader *soundShader; 173 const function_t *function; 174 const idDeclSkin *skin; 175 int index; 176 }; 177 } frameCommand_t; 178 179 typedef struct { 180 bool prevent_idle_override : 1; 181 bool random_cycle_start : 1; 182 bool ai_no_turn : 1; 183 bool anim_turn : 1; 184 } animFlags_t; 185 186 /* 187 ============================================================================================== 188 189 idMD5Anim 190 191 ============================================================================================== 192 */ 193 194 class idMD5Anim { 195 private: 196 int numFrames; 197 int frameRate; 198 int animLength; 199 int numJoints; 200 int numAnimatedComponents; 201 idList<idBounds, TAG_MD5_ANIM> bounds; 202 idList<jointAnimInfo_t, TAG_MD5_ANIM> jointInfo; 203 idList<idJointQuat, TAG_MD5_ANIM> baseFrame; 204 idList<float, TAG_MD5_ANIM> componentFrames; 205 idStr name; 206 idVec3 totaldelta; 207 mutable int ref_count; 208 209 public: 210 idMD5Anim(); 211 ~idMD5Anim(); 212 213 void Free(); 214 bool Reload(); 215 size_t Allocated() const; 216 size_t Size() const { return sizeof( *this ) + Allocated(); }; 217 bool LoadAnim( const char *filename ); 218 bool LoadBinary( idFile * file, ID_TIME_T sourceTimeStamp ); 219 void WriteBinary( idFile * file, ID_TIME_T sourceTimeStamp ); 220 221 void IncreaseRefs() const; 222 void DecreaseRefs() const; 223 int NumRefs() const; 224 225 void CheckModelHierarchy( const idRenderModel *model ) const; 226 void GetInterpolatedFrame( frameBlend_t &frame, idJointQuat *joints, const int *index, int numIndexes ) const; 227 void GetSingleFrame( int framenum, idJointQuat *joints, const int *index, int numIndexes ) const; 228 int Length() const; 229 int NumFrames() const; 230 int NumJoints() const; 231 const idVec3 &TotalMovementDelta() const; 232 const char *Name() const; 233 234 void GetFrameBlend( int framenum, frameBlend_t &frame ) const; // frame 1 is first frame 235 void ConvertTimeToFrame( int time, int cyclecount, frameBlend_t &frame ) const; 236 237 void GetOrigin( idVec3 &offset, int currentTime, int cyclecount ) const; 238 void GetOriginRotation( idQuat &rotation, int time, int cyclecount ) const; 239 void GetBounds( idBounds &bounds, int currentTime, int cyclecount ) const; 240 }; 241 242 /* 243 ============================================================================================== 244 245 idAnim 246 247 ============================================================================================== 248 */ 249 250 class idAnim { 251 private: 252 const class idDeclModelDef *modelDef; 253 const idMD5Anim *anims[ ANIM_MaxSyncedAnims ]; 254 int numAnims; 255 idStr name; 256 idStr realname; 257 idList<frameLookup_t, TAG_ANIM> frameLookup; 258 idList<frameCommand_t, TAG_ANIM> frameCommands; 259 animFlags_t flags; 260 261 public: 262 idAnim(); 263 idAnim( const idDeclModelDef *modelDef, const idAnim *anim ); 264 ~idAnim(); 265 266 void SetAnim( const idDeclModelDef *modelDef, const char *sourcename, const char *animname, int num, const idMD5Anim *md5anims[ ANIM_MaxSyncedAnims ] ); 267 const char *Name() const; 268 const char *FullName() const; 269 const idMD5Anim *MD5Anim( int num ) const; 270 const idDeclModelDef *ModelDef() const; 271 int Length() const; 272 int NumFrames() const; 273 int NumAnims() const; 274 const idVec3 &TotalMovementDelta() const; 275 bool GetOrigin( idVec3 &offset, int animNum, int time, int cyclecount ) const; 276 bool GetOriginRotation( idQuat &rotation, int animNum, int currentTime, int cyclecount ) const; 277 bool GetBounds( idBounds &bounds, int animNum, int time, int cyclecount ) const; 278 const char *AddFrameCommand( const class idDeclModelDef *modelDef, int framenum, idLexer &src, const idDict *def ); 279 void CallFrameCommands( idEntity *ent, int from, int to ) const; 280 bool HasFrameCommands() const; 281 282 // returns first frame (zero based) that command occurs. returns -1 if not found. 283 int FindFrameForFrameCommand( frameCommandType_t framecommand, const frameCommand_t **command ) const; 284 void SetAnimFlags( const animFlags_t &animflags ); 285 const animFlags_t &GetAnimFlags() const; 286 }; 287 288 /* 289 ============================================================================================== 290 291 idDeclModelDef 292 293 ============================================================================================== 294 */ 295 296 class idDeclModelDef : public idDecl { 297 public: 298 idDeclModelDef(); 299 ~idDeclModelDef(); 300 301 virtual size_t Size() const; 302 virtual const char * DefaultDefinition() const; 303 virtual bool Parse( const char *text, const int textLength, bool allowBinaryVersion ); 304 virtual void FreeData(); 305 306 void Touch() const; 307 308 const idDeclSkin * GetDefaultSkin() const; 309 const idJointQuat * GetDefaultPose() const; 310 void SetupJoints( int *numJoints, idJointMat **jointList, idBounds &frameBounds, bool removeOriginOffset ) const; 311 idRenderModel * ModelHandle() const; 312 void GetJointList( const char *jointnames, idList<jointHandle_t> &jointList ) const; 313 const jointInfo_t * FindJoint( const char *name ) const; 314 315 int NumAnims() const; 316 const idAnim * GetAnim( int index ) const; 317 int GetSpecificAnim( const char *name ) const; 318 int GetAnim( const char *name ) const; 319 bool HasAnim( const char *name ) const; 320 const idDeclSkin * GetSkin() const; 321 const char * GetModelName() const; 322 const idList<jointInfo_t> & Joints() const; 323 const int * JointParents() const; 324 int NumJoints() const; 325 const jointInfo_t * GetJoint( int jointHandle ) const; 326 const char * GetJointName( int jointHandle ) const; 327 int NumJointsOnChannel( int channel ) const; 328 const int * GetChannelJoints( int channel ) const; 329 330 const idVec3 & GetVisualOffset() const; 331 332 private: 333 void CopyDecl( const idDeclModelDef *decl ); 334 bool ParseAnim( idLexer &src, int numDefaultAnims ); 335 336 private: 337 idVec3 offset; 338 idList<jointInfo_t, TAG_ANIM> joints; 339 idList<int, TAG_ANIM> jointParents; 340 idList<int, TAG_ANIM> channelJoints[ ANIM_NumAnimChannels ]; 341 idRenderModel * modelHandle; 342 idList<idAnim *, TAG_ANIM> anims; 343 const idDeclSkin * skin; 344 }; 345 346 /* 347 ============================================================================================== 348 349 idAnimBlend 350 351 ============================================================================================== 352 */ 353 354 class idAnimBlend { 355 private: 356 const class idDeclModelDef *modelDef; 357 int starttime; 358 int endtime; 359 int timeOffset; 360 float rate; 361 362 int blendStartTime; 363 int blendDuration; 364 float blendStartValue; 365 float blendEndValue; 366 367 float animWeights[ ANIM_MaxSyncedAnims ]; 368 short cycle; 369 short frame; 370 short animNum; 371 bool allowMove; 372 bool allowFrameCommands; 373 374 friend class idAnimator; 375 376 void Reset( const idDeclModelDef *_modelDef ); 377 void CallFrameCommands( idEntity *ent, int fromtime, int totime ) const; 378 void SetFrame( const idDeclModelDef *modelDef, int animnum, int frame, int currenttime, int blendtime ); 379 void CycleAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime ); 380 void PlayAnim( const idDeclModelDef *modelDef, int animnum, int currenttime, int blendtime ); 381 bool BlendAnim( int currentTime, int channel, int numJoints, idJointQuat *blendFrame, float &blendWeight, bool removeOrigin, bool overrideBlend, bool printInfo ) const; 382 void BlendOrigin( int currentTime, idVec3 &blendPos, float &blendWeight, bool removeOriginOffset ) const; 383 void BlendDelta( int fromtime, int totime, idVec3 &blendDelta, float &blendWeight ) const; 384 void BlendDeltaRotation( int fromtime, int totime, idQuat &blendDelta, float &blendWeight ) const; 385 bool AddBounds( int currentTime, idBounds &bounds, bool removeOriginOffset ) const; 386 387 public: 388 idAnimBlend(); 389 void Save( idSaveGame *savefile ) const; 390 void Restore( idRestoreGame *savefile, const idDeclModelDef *modelDef ); 391 const char *AnimName() const; 392 const char *AnimFullName() const; 393 float GetWeight( int currenttime ) const; 394 float GetFinalWeight() const; 395 void SetWeight( float newweight, int currenttime, int blendtime ); 396 int NumSyncedAnims() const; 397 bool SetSyncedAnimWeight( int num, float weight ); 398 void Clear( int currentTime, int clearTime ); 399 bool IsDone( int currentTime ) const; 400 bool FrameHasChanged( int currentTime ) const; 401 int GetCycleCount() const; 402 void SetCycleCount( int count ); 403 void SetPlaybackRate( int currentTime, float newRate ); 404 float GetPlaybackRate() const; 405 void SetStartTime( int startTime ); 406 int GetStartTime() const; 407 int GetEndTime() const; 408 int GetFrameNumber( int currenttime ) const; 409 int AnimTime( int currenttime ) const; 410 int NumFrames() const; 411 int Length() const; 412 int PlayLength() const; 413 void AllowMovement( bool allow ); 414 void AllowFrameCommands( bool allow ); 415 const idAnim *Anim() const; 416 int AnimNum() const; 417 }; 418 419 /* 420 ============================================================================================== 421 422 idAFPoseJointMod 423 424 ============================================================================================== 425 */ 426 427 typedef enum { 428 AF_JOINTMOD_AXIS, 429 AF_JOINTMOD_ORIGIN, 430 AF_JOINTMOD_BOTH 431 } AFJointModType_t; 432 433 class idAFPoseJointMod { 434 public: 435 idAFPoseJointMod(); 436 437 AFJointModType_t mod; 438 idMat3 axis; 439 idVec3 origin; 440 }; 441 442 ID_INLINE idAFPoseJointMod::idAFPoseJointMod() { 443 mod = AF_JOINTMOD_AXIS; 444 axis.Identity(); 445 origin.Zero(); 446 } 447 448 /* 449 ============================================================================================== 450 451 idAnimator 452 453 ============================================================================================== 454 */ 455 456 class idAnimator { 457 public: 458 idAnimator(); 459 ~idAnimator(); 460 461 size_t Allocated() const; 462 size_t Size() const; 463 464 void Save( idSaveGame *savefile ) const; // archives object for save game file 465 void Restore( idRestoreGame *savefile ); // unarchives object from save game file 466 467 void SetEntity( idEntity *ent ); 468 idEntity *GetEntity() const ; 469 void RemoveOriginOffset( bool remove ); 470 bool RemoveOrigin() const; 471 472 void GetJointList( const char *jointnames, idList<jointHandle_t> &jointList ) const; 473 474 int NumAnims() const; 475 const idAnim *GetAnim( int index ) const; 476 int GetAnim( const char *name ) const; 477 bool HasAnim( const char *name ) const; 478 479 void ServiceAnims( int fromtime, int totime ); 480 bool IsAnimating( int currentTime ) const; 481 482 void GetJoints( int *numJoints, idJointMat **jointsPtr ); 483 int NumJoints() const; 484 jointHandle_t GetFirstChild( jointHandle_t jointnum ) const; 485 jointHandle_t GetFirstChild( const char *name ) const; 486 487 idRenderModel *SetModel( const char *modelname ); 488 idRenderModel *ModelHandle() const; 489 const idDeclModelDef *ModelDef() const; 490 491 void ForceUpdate(); 492 void ClearForceUpdate(); 493 bool CreateFrame( int animtime, bool force ); 494 bool FrameHasChanged( int animtime ) const; 495 void GetDelta( int fromtime, int totime, idVec3 &delta ) const; 496 bool GetDeltaRotation( int fromtime, int totime, idMat3 &delta ) const; 497 void GetOrigin( int currentTime, idVec3 &pos ) const; 498 bool GetBounds( int currentTime, idBounds &bounds ); 499 500 idAnimBlend *CurrentAnim( int channelNum ); 501 void Clear( int channelNum, int currentTime, int cleartime ); 502 void SetFrame( int channelNum, int animnum, int frame, int currenttime, int blendtime ); 503 void CycleAnim( int channelNum, int animnum, int currenttime, int blendtime ); 504 void PlayAnim( int channelNum, int animnum, int currenttime, int blendTime ); 505 506 // copies the current anim from fromChannelNum to channelNum. 507 // the copied anim will have frame commands disabled to avoid executing them twice. 508 void SyncAnimChannels( int channelNum, int fromChannelNum, int currenttime, int blendTime ); 509 510 void SetJointPos( jointHandle_t jointnum, jointModTransform_t transform_type, const idVec3 &pos ); 511 void SetJointAxis( jointHandle_t jointnum, jointModTransform_t transform_type, const idMat3 &mat ); 512 void ClearJoint( jointHandle_t jointnum ); 513 void ClearAllJoints(); 514 515 void InitAFPose(); 516 void SetAFPoseJointMod( const jointHandle_t jointNum, const AFJointModType_t mod, const idMat3 &axis, const idVec3 &origin ); 517 void FinishAFPose( int animnum, const idBounds &bounds, const int time ); 518 void SetAFPoseBlendWeight( float blendWeight ); 519 bool BlendAFPose( idJointQuat *blendFrame ) const; 520 void ClearAFPose(); 521 522 void ClearAllAnims( int currentTime, int cleartime ); 523 524 jointHandle_t GetJointHandle( const char *name ) const; 525 const char * GetJointName( jointHandle_t handle ) const; 526 int GetChannelForJoint( jointHandle_t joint ) const; 527 bool GetJointTransform( jointHandle_t jointHandle, int currenttime, idVec3 &offset, idMat3 &axis ); 528 bool GetJointLocalTransform( jointHandle_t jointHandle, int currentTime, idVec3 &offset, idMat3 &axis ); 529 530 const animFlags_t GetAnimFlags( int animnum ) const; 531 int NumFrames( int animnum ) const; 532 int NumSyncedAnims( int animnum ) const; 533 const char *AnimName( int animnum ) const; 534 const char *AnimFullName( int animnum ) const; 535 int AnimLength( int animnum ) const; 536 const idVec3 &TotalMovementDelta( int animnum ) const; 537 538 private: 539 void FreeData(); 540 void PushAnims( int channel, int currentTime, int blendTime ); 541 542 private: 543 const idDeclModelDef * modelDef; 544 idEntity * entity; 545 546 idAnimBlend channels[ ANIM_NumAnimChannels ][ ANIM_MaxAnimsPerChannel ]; 547 idList<jointMod_t *, TAG_ANIM> jointMods; 548 int numJoints; 549 idJointMat * joints; 550 551 mutable int lastTransformTime; // mutable because the value is updated in CreateFrame 552 mutable bool stoppedAnimatingUpdate; 553 bool removeOriginOffset; 554 bool forceUpdate; 555 556 idBounds frameBounds; 557 558 float AFPoseBlendWeight; 559 idList<int, TAG_ANIM> AFPoseJoints; 560 idList<idAFPoseJointMod, TAG_ANIM> AFPoseJointMods; 561 idList<idJointQuat, TAG_ANIM> AFPoseJointFrame; 562 idBounds AFPoseBounds; 563 int AFPoseTime; 564 }; 565 566 /* 567 ============================================================================================== 568 569 idAnimManager 570 571 ============================================================================================== 572 */ 573 574 class idAnimManager { 575 public: 576 idAnimManager(); 577 ~idAnimManager(); 578 579 static bool forceExport; 580 581 void Shutdown(); 582 idMD5Anim * GetAnim( const char *name ); 583 void Preload( const idPreloadManifest &manifest ); 584 void ReloadAnims(); 585 void ListAnims() const; 586 int JointIndex( const char *name ); 587 const char * JointName( int index ) const; 588 589 void ClearAnimsInUse(); 590 void FlushUnusedAnims(); 591 592 private: 593 idHashTable<idMD5Anim *> animations; 594 idStrList jointnames; 595 idHashIndex jointnamesHash; 596 }; 597 598 #endif /* !__ANIM_H__ */