diff options
Diffstat (limited to 'src/animation/AnimManager.cpp')
-rw-r--r-- | src/animation/AnimManager.cpp | 453 |
1 files changed, 299 insertions, 154 deletions
diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp index 8fb1576c..c6f84871 100644 --- a/src/animation/AnimManager.cpp +++ b/src/animation/AnimManager.cpp @@ -10,6 +10,9 @@ #include "AnimBlendAssociation.h" #include "AnimBlendAssocGroup.h" #include "AnimManager.h" +#include "Streaming.h" + +//--MIAMI: code done (except for pointless TODO) CAnimBlock CAnimManager::ms_aAnimBlocks[NUMANIMBLOCKS]; CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS]; @@ -78,13 +81,13 @@ AnimAssocDesc aStdAnimDescs[] = { { ANIM_BOMBER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, { ANIM_HGUN_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, { ANIM_AK_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK }, - { ANIM_FPS_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, - { ANIM_FPS_BAT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, - { ANIM_FPS_UZI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, - { ANIM_FPS_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, - { ANIM_FPS_AK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, - { ANIM_FPS_M16, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, - { ANIM_FPS_ROCKET, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, +// { ANIM_FPS_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, +// { ANIM_FPS_BAT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, +// { ANIM_FPS_UZI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, +// { ANIM_FPS_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, +// { ANIM_FPS_AK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, +// { ANIM_FPS_M16, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, +// { ANIM_FPS_ROCKET, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_FIGHT_IDLE, ASSOC_REPEAT }, { ANIM_FIGHT2_IDLE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL }, { ANIM_FIGHT_SH_F, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION }, @@ -260,13 +263,13 @@ char const *aStdAnimations[] = { "bomber", "WEAPON_hgun_rload", "WEAPON_AK_rload", - "FPS_PUNCH", - "FPS_BAT", - "FPS_UZI", - "FPS_PUMP", - "FPS_AK", - "FPS_M16", - "FPS_ROCKET", +// "FPS_PUNCH", +// "FPS_BAT", +// "FPS_UZI", +// "FPS_PUMP", +// "FPS_AK", +// "FPS_M16", +// "FPS_ROCKET", "FIGHTIDLE", "FIGHT2IDLE", "FIGHTsh_F", @@ -410,6 +413,13 @@ char const *aPlayerBBBatAnimations[] = { "IDLE_STANCE", "walk_start", }; +char const *aPlayerChainsawAnimations[] = { + "walk_csaw", + "run_csaw", + "run_csaw", + "IDLE_csaw", + "walk_start_csaw", +}; char const *aShuffleAnimations[] = { "WALK_shuffle", "RUN_civi", @@ -446,6 +456,12 @@ char const *aOldFatAnimations[] = { "woman_runpanic", "idle_stance", }; +char const *aJoggerAnimations[] = { + "JOG_maleA", + "run_civi", + "sprint_civi", + "idle_stance", +}; char const *aStdWomanAnimations[] = { "woman_walknorm", "woman_run", @@ -470,14 +486,20 @@ char const *aSexyWomanAnimations[] = { "woman_runpanic", "woman_idlestance", }; +char const *aFatWomanAnimations[] = { + "walk_fat", + "woman_run", + "woman_runpanic", + "woman_idlestance", +}; char const *aOldWomanAnimations[] = { "woman_walkold", "woman_run", "woman_runpanic", "woman_idlestance", }; -char const *aFatWomanAnimations[] = { - "walk_fat", +char const *aJoggerWomanAnimations[] = { + "JOG_maleB", "woman_run", "woman_runpanic", "woman_idlestance", @@ -488,22 +510,28 @@ char const *aPanicChunkyAnimations[] = { "woman_runpanic", "idle_stance", }; +char const *aSkateAnimations[] = { + "skate_run", + "skate_sprint", + "skate_sprint", + "skate_idle", +}; char const *aPlayerStrafeBackAnimations[] = { - "walk_player_back", - "run_player_back", - "run_player_back", + "walk_back", + "run_back", + "run_back", "IDLE_STANCE", "walk_start_back", }; char const *aPlayerStrafeLeftAnimations[] = { - "walk_player_left", + "walk_left", "run_left", "run_left", "IDLE_STANCE", "walk_start_left", }; char const *aPlayerStrafeRightAnimations[] = { - "walk_player_right", + "walk_right", "run_right", "run_right", "IDLE_STANCE", @@ -530,6 +558,28 @@ char const *aRocketStrafeRightAnimations[] = { "idle_rocket", "walkst_rocket_right", }; +char const *aChainsawStrafeBackAnimations[] = { + "walk_csaw_back", + "run_csaw_back", + "run_csaw_back", + "idle_csaw", + "walkst_csaw_back", +}; +char const *aChainsawStrafeLeftAnimations[] = { + "walk_csaw_left", + "run_csaw_left", + "run_csaw_left", + "idle_csaw", + "walkst_csaw_left", +}; +char const *aChainsawStrafeRightAnimations[] = { + "walk_csaw_right", + "run_csaw_right", + "run_csaw_right", + "idle_csaw", + "walkst_csaw_right", +}; + const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS] = { { "man", "ped", MI_COP, 173, aStdAnimations, aStdAnimDescs }, { "player", "ped", MI_COP, 5, aPlayerAnimations, aStdAnimDescs }, @@ -537,25 +587,32 @@ const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_ { "player1armed", "ped", MI_COP, 5, aPlayer1ArmedAnimations, aStdAnimDescs }, { "player2armed", "ped", MI_COP, 5, aPlayer2ArmedAnimations, aStdAnimDescs }, { "playerBBBat", "ped", MI_COP, 5, aPlayerBBBatAnimations, aStdAnimDescs }, + { "playercsaw", "ped", MI_COP, 5, aPlayerChainsawAnimations, aStdAnimDescs }, { "shuffle", "ped", MI_COP, 4, aShuffleAnimations, aStdAnimDescs }, { "oldman", "ped", MI_COP, 4, aOldAnimations, aStdAnimDescs }, { "gang1", "ped", MI_COP, 4, aGang1Animations, aStdAnimDescs }, { "gang2", "ped", MI_COP, 4, aGang2Animations, aStdAnimDescs }, { "fatman", "ped", MI_COP, 4, aFatAnimations, aStdAnimDescs }, { "oldfatman", "ped", MI_COP, 4, aOldFatAnimations, aStdAnimDescs }, + { "jogger", "ped", MI_COP, 4, aJoggerAnimations, aStdAnimDescs }, { "woman", "ped", MI_COP, 4, aStdWomanAnimations, aStdAnimDescs }, { "shopping", "ped", MI_COP, 4, aWomanShopAnimations, aStdAnimDescs }, { "busywoman", "ped", MI_COP, 4, aBusyWomanAnimations, aStdAnimDescs }, { "sexywoman", "ped", MI_COP, 4, aSexyWomanAnimations, aStdAnimDescs }, - { "oldwoman", "ped", MI_COP, 4, aOldWomanAnimations, aStdAnimDescs }, { "fatwoman", "ped", MI_COP, 4, aFatWomanAnimations, aStdAnimDescs }, + { "oldwoman", "ped", MI_COP, 4, aOldWomanAnimations, aStdAnimDescs }, + { "jogwoman", "ped", MI_COP, 4, aJoggerWomanAnimations, aStdAnimDescs }, { "panicchunky", "ped", MI_COP, 4, aPanicChunkyAnimations, aStdAnimDescs }, + { "skate", "ped", MI_COP, 4, aSkateAnimations, aStdAnimDescs }, { "playerback", "ped", MI_COP, 5, aPlayerStrafeBackAnimations, aStdAnimDescs }, { "playerleft", "ped", MI_COP, 5, aPlayerStrafeLeftAnimations, aStdAnimDescsSide }, { "playerright", "ped", MI_COP, 5, aPlayerStrafeRightAnimations, aStdAnimDescsSide }, { "rocketback", "ped", MI_COP, 5, aRocketStrafeBackAnimations, aStdAnimDescs }, { "rocketleft", "ped", MI_COP, 5, aRocketStrafeLeftAnimations, aStdAnimDescsSide }, { "rocketright", "ped", MI_COP, 5, aRocketStrafeRightAnimations, aStdAnimDescsSide }, + { "csawback", "ped", MI_COP, 5, aChainsawStrafeBackAnimations, aStdAnimDescs }, + { "csawleft", "ped", MI_COP, 5, aChainsawStrafeLeftAnimations, aStdAnimDescsSide }, + { "csawright", "ped", MI_COP, 5, aChainsawStrafeRightAnimations, aStdAnimDescsSide }, }; void @@ -564,8 +621,6 @@ CAnimManager::Initialise(void) ms_numAnimations = 0; ms_numAnimBlocks = 0; ms_animCache.Init(25); - -// dumpanimdata(); } void @@ -573,31 +628,48 @@ CAnimManager::Shutdown(void) { int i; - ms_animCache.Shutdown(); + for(i = 0; i < NUMANIMBLOCKS; i++) + CStreaming::RemoveAnim(i); for(i = 0; i < ms_numAnimations; i++) ms_aAnimations[i].Shutdown(); + ms_animCache.Shutdown(); + delete[] ms_aAnimAssocGroups; } void CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier) { - if(!hier->compressed){ - if(hier->linkPtr){ - hier->linkPtr->Remove(); - ms_animCache.head.Insert(hier->linkPtr); - } + if(hier->compressed2){ + if(hier->totalLength == 0.0f) + hier->CalcTotalTimeCompressed(); }else{ - CLink<CAnimBlendHierarchy*> *link = ms_animCache.Insert(hier); - if(link == nil){ - ms_animCache.tail.prev->item->RemoveUncompressedData(); - ms_animCache.Remove(ms_animCache.tail.prev); - link = ms_animCache.Insert(hier); + if(!hier->compressed){ + if(hier->linkPtr){ + hier->linkPtr->Remove(); + ms_animCache.head.Insert(hier->linkPtr); + } + }else{ + CLink<CAnimBlendHierarchy*> *link = ms_animCache.Insert(hier); + if(link == nil){ + ms_animCache.tail.prev->item->RemoveUncompressedData(); + ms_animCache.Remove(ms_animCache.tail.prev); + link = ms_animCache.Insert(hier); + } + hier->linkPtr = link; + hier->Uncompress(); } - hier->linkPtr = link; - hier->Uncompress(); + } +} + +void +CAnimManager::RemoveFromUncompressedCache(CAnimBlendHierarchy *hier) +{ + if(hier->linkPtr){ + ms_animCache.Remove(hier->linkPtr); + hier->linkPtr = nil; } } @@ -612,6 +684,73 @@ CAnimManager::GetAnimationBlock(const char *name) return nil; } +int32 +CAnimManager::GetAnimationBlockIndex(const char *name) +{ + int i; + + for(i = 0; i < ms_numAnimBlocks; i++) + if(strcasecmp(ms_aAnimBlocks[i].name, name) == 0) + return i; + return -1; +} + +int32 +CAnimManager::RegisterAnimBlock(const char *name) +{ + CAnimBlock *animBlock = GetAnimationBlock(name); + if(animBlock == nil){ + animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++]; + strncpy(animBlock->name, name, MAX_ANIMBLOCK_NAME); + animBlock->numAnims = 0; + assert(animBlock->refCount == 0); + } + return animBlock - ms_aAnimBlocks; +} + +int32 +CAnimManager::GetNumRefsToAnimBlock(int32 block) +{ + return ms_aAnimBlocks[block].refCount; +} + +void +CAnimManager::AddAnimBlockRef(int32 block) +{ + ms_aAnimBlocks[block].refCount++; +} + +void +CAnimManager::RemoveAnimBlockRefWithoutDelete(int32 block) +{ + ms_aAnimBlocks[block].refCount--; +} + +void +CAnimManager::RemoveAnimBlockRef(int32 block) +{ + ms_aAnimBlocks[block].refCount--; + if(ms_aAnimBlocks[block].refCount == 0) + CStreaming::RemoveAnim(block); +} + +void +CAnimManager::RemoveAnimBlock(int32 block) +{ + int i; + CAnimBlock *animblock; + + animblock = &ms_aAnimBlocks[block]; + debug("Removing ANIMS %s\n", animblock->name); + for(i = 0; i < NUM_ANIM_ASSOC_GROUPS; i++) + if(ms_aAnimAssocGroups[i].animBlock == animblock) + ms_aAnimAssocGroups[i].DestroyAssociations(); + for(i = 0; i < animblock->numAnims; i++) + ms_aAnimations[animblock->firstIndex + i].Shutdown(); + animblock->isLoaded = false; + animblock->refCount = 0; +} + CAnimBlendHierarchy* CAnimManager::GetAnimation(const char *name, CAnimBlock *animBlock) { @@ -619,7 +758,7 @@ CAnimManager::GetAnimation(const char *name, CAnimBlock *animBlock) CAnimBlendHierarchy *hier = &ms_aAnimations[animBlock->firstIndex]; for(i = 0; i < animBlock->numAnims; i++){ - if(!CGeneral::faststricmp(hier->name, name)) + if(strcasecmp(hier->name, name) == 0) return hier; hier++; } @@ -740,23 +879,32 @@ CAnimManager::BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId a void CAnimManager::LoadAnimFiles(void) { - int i, j; - LoadAnimFile("ANIM\\PED.IFP"); - - // Create all assoc groups ms_aAnimAssocGroups = new CAnimBlendAssocGroup[NUM_ANIM_ASSOC_GROUPS]; + CreateAnimAssocGroups(); +} + +void +CAnimManager::CreateAnimAssocGroups(void) +{ + int i, j; + for(i = 0; i < NUM_ANIM_ASSOC_GROUPS; i++){ + CAnimBlock *block = GetAnimationBlock(ms_aAnimAssocDefinitions[i].blockName); + if(block == nil || !block->isLoaded || ms_aAnimAssocGroups[i].assocList) + continue; + CBaseModelInfo *mi = CModelInfo::GetModelInfo(ms_aAnimAssocDefinitions[i].modelIndex); RpClump *clump = (RpClump*)mi->CreateInstance(); RpAnimBlendClumpInit(clump); CAnimBlendAssocGroup *group = &ms_aAnimAssocGroups[i]; const AnimAssocDefinition *def = &ms_aAnimAssocDefinitions[i]; + group->groupId = i; + group->firstAnimId = def->animDescs[0].animId; group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims); for(j = 0; j < group->numAssociations; j++) group->GetAnimation(j)->flags |= def->animDescs[j].flags; #ifdef PED_SKIN - // forgot on xbox/android if(IsClumpSkinned(clump)) RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil); #endif @@ -767,15 +915,16 @@ CAnimManager::LoadAnimFiles(void) void CAnimManager::LoadAnimFile(const char *filename) { - int fd; - fd = CFileMgr::OpenFile(filename, "rb"); - assert(fd > 0); - LoadAnimFile(fd, true); - CFileMgr::CloseFile(fd); + RwStream *stream; + stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename); + assert(stream); + LoadAnimFile(stream, true); + RwStreamClose(stream, nil); } +//--MIAMI: done (except maybe implement some unimplemented compression?) void -CAnimManager::LoadAnimFile(int fd, bool compress) +CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32]) { #define ROUNDSIZE(x) if((x) & 3) (x) += 4 - ((x)&3) struct IfpHeader { @@ -783,127 +932,122 @@ CAnimManager::LoadAnimFile(int fd, bool compress) uint32 size; }; IfpHeader anpk, info, name, dgan, cpan, anim; - int numANPK; char buf[256]; - int i, j, k, l; + int j, k, l; float *fbuf = (float*)buf; - CFileMgr::Read(fd, (char*)&anpk, sizeof(IfpHeader)); - if(strncmp(anpk.ident, "ANLF", 4) == 0){ - ROUNDSIZE(anpk.size); - CFileMgr::Read(fd, buf, anpk.size); - numANPK = *(int*)buf; - }else if(strncmp(anpk.ident, "ANPK", 4) == 0){ - CFileMgr::Seek(fd, -8, 1); - numANPK = 1; + // block name + RwStreamRead(stream, &anpk, sizeof(IfpHeader)); + ROUNDSIZE(anpk.size); + RwStreamRead(stream, &info, sizeof(IfpHeader)); + ROUNDSIZE(info.size); + RwStreamRead(stream, buf, info.size); + CAnimBlock *animBlock = GetAnimationBlock(buf+4); + if(animBlock){ + if(animBlock->numAnims == 0){ + animBlock->numAnims = *(int*)buf; + animBlock->firstIndex = ms_numAnimations; + } + }else{ + animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++]; + strncpy(animBlock->name, buf+4, MAX_ANIMBLOCK_NAME); + animBlock->numAnims = *(int*)buf; + animBlock->firstIndex = ms_numAnimations; } - for(i = 0; i < numANPK; i++){ - // block name - CFileMgr::Read(fd, (char*)&anpk, sizeof(IfpHeader)); - ROUNDSIZE(anpk.size); - CFileMgr::Read(fd, (char*)&info, sizeof(IfpHeader)); - ROUNDSIZE(info.size); - CFileMgr::Read(fd, buf, info.size); - CAnimBlock *animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++]; - strncpy(animBlock->name, buf+4, 24); - animBlock->numAnims = *(int*)buf; + debug("Loading ANIMS %s\n", animBlock->name); + animBlock->isLoaded = true; - animBlock->firstIndex = ms_numAnimations; + int animIndex = animBlock->firstIndex; + for(j = 0; j < animBlock->numAnims; j++){ + assert(animIndex < ARRAY_SIZE(ms_aAnimations)); + CAnimBlendHierarchy *hier = &ms_aAnimations[animIndex++]; + + // animation name + RwStreamRead(stream, &name, sizeof(IfpHeader)); + ROUNDSIZE(name.size); + RwStreamRead(stream, buf, name.size); + hier->SetName(buf); - for(j = 0; j < animBlock->numAnims; j++){ - CAnimBlendHierarchy *hier = &ms_aAnimations[ms_numAnimations++]; + // TODO(MIAMI)? some unused crap here + hier->compressed = false; + hier->compressed2 = false; - // animation name - CFileMgr::Read(fd, (char*)&name, sizeof(IfpHeader)); - ROUNDSIZE(name.size); - CFileMgr::Read(fd, buf, name.size); - hier->SetName(buf); + // DG info has number of nodes/sequences + RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader)); + ROUNDSIZE(dgan.size); + RwStreamRead(stream, (char*)&info, sizeof(IfpHeader)); + ROUNDSIZE(info.size); + RwStreamRead(stream, buf, info.size); + hier->numSequences = *(int*)buf; + hier->sequences = new CAnimBlendSequence[hier->numSequences]; - // DG info has number of nodes/sequences - CFileMgr::Read(fd, (char*)&dgan, sizeof(IfpHeader)); + CAnimBlendSequence *seq = hier->sequences; + for(k = 0; k < hier->numSequences; k++, seq++){ + // Each node has a name and key frames + RwStreamRead(stream, &cpan, sizeof(IfpHeader)); ROUNDSIZE(dgan.size); - CFileMgr::Read(fd, (char*)&info, sizeof(IfpHeader)); - ROUNDSIZE(info.size); - CFileMgr::Read(fd, buf, info.size); - hier->numSequences = *(int*)buf; - hier->sequences = new CAnimBlendSequence[hier->numSequences]; - - CAnimBlendSequence *seq = hier->sequences; - for(k = 0; k < hier->numSequences; k++, seq++){ - // Each node has a name and key frames - CFileMgr::Read(fd, (char*)&cpan, sizeof(IfpHeader)); - ROUNDSIZE(dgan.size); - CFileMgr::Read(fd, (char*)&anim, sizeof(IfpHeader)); - ROUNDSIZE(anim.size); - CFileMgr::Read(fd, buf, anim.size); - int numFrames = *(int*)(buf+28); + RwStreamRead(stream, &anim, sizeof(IfpHeader)); + ROUNDSIZE(anim.size); + RwStreamRead(stream, buf, anim.size); + int numFrames = *(int*)(buf+28); #ifdef PED_SKIN - if(anim.size == 44) - seq->SetBoneTag(*(int*)(buf+40)); + if(anim.size == 44) + seq->SetBoneTag(*(int*)(buf+40)); #endif - seq->SetName(buf); - if(numFrames == 0) - continue; - - CFileMgr::Read(fd, (char*)&info, sizeof(info)); - if(strncmp(info.ident, "KR00", 4) == 0){ - seq->SetNumFrames(numFrames, false); - KeyFrame *kf = seq->GetKeyFrame(0); - for(l = 0; l < numFrames; l++, kf++){ - CFileMgr::Read(fd, buf, 0x14); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->deltaTime = fbuf[4]; // absolute time here - } - }else if(strncmp(info.ident, "KRT0", 4) == 0){ - seq->SetNumFrames(numFrames, true); - KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); - for(l = 0; l < numFrames; l++, kf++){ - CFileMgr::Read(fd, buf, 0x20); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->translation.x = fbuf[4]; - kf->translation.y = fbuf[5]; - kf->translation.z = fbuf[6]; - kf->deltaTime = fbuf[7]; // absolute time here - } - }else if(strncmp(info.ident, "KRTS", 4) == 0){ - seq->SetNumFrames(numFrames, true); - KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); - for(l = 0; l < numFrames; l++, kf++){ - CFileMgr::Read(fd, buf, 0x2C); - kf->rotation.x = -fbuf[0]; - kf->rotation.y = -fbuf[1]; - kf->rotation.z = -fbuf[2]; - kf->rotation.w = fbuf[3]; - kf->translation.x = fbuf[4]; - kf->translation.y = fbuf[5]; - kf->translation.z = fbuf[6]; - // scaling ignored - kf->deltaTime = fbuf[10]; // absolute time here - } - } + seq->SetName(buf); + if(numFrames == 0) + continue; - // convert absolute time to deltas - for(l = seq->numFrames-1; l > 0; l--){ - KeyFrame *kf1 = seq->GetKeyFrame(l); - KeyFrame *kf2 = seq->GetKeyFrame(l-1); - kf1->deltaTime -= kf2->deltaTime; + RwStreamRead(stream, &info, sizeof(info)); + if(strncmp(info.ident, "KR00", 4) == 0){ + seq->SetNumFrames(numFrames, false, false); + KeyFrame *kf = seq->GetKeyFrame(0); + for(l = 0; l < numFrames; l++, kf++){ + RwStreamRead(stream, buf, 0x14); + kf->rotation.x = -fbuf[0]; + kf->rotation.y = -fbuf[1]; + kf->rotation.z = -fbuf[2]; + kf->rotation.w = fbuf[3]; + kf->deltaTime = fbuf[4]; // absolute time here + } + }else if(strncmp(info.ident, "KRT0", 4) == 0){ + seq->SetNumFrames(numFrames, true, false); + KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); + for(l = 0; l < numFrames; l++, kf++){ + RwStreamRead(stream, buf, 0x20); + kf->rotation.x = -fbuf[0]; + kf->rotation.y = -fbuf[1]; + kf->rotation.z = -fbuf[2]; + kf->rotation.w = fbuf[3]; + kf->translation.x = fbuf[4]; + kf->translation.y = fbuf[5]; + kf->translation.z = fbuf[6]; + kf->deltaTime = fbuf[7]; // absolute time here + } + }else if(strncmp(info.ident, "KRTS", 4) == 0){ + seq->SetNumFrames(numFrames, true, false); + KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); + for(l = 0; l < numFrames; l++, kf++){ + RwStreamRead(stream, buf, 0x2C); + kf->rotation.x = -fbuf[0]; + kf->rotation.y = -fbuf[1]; + kf->rotation.z = -fbuf[2]; + kf->rotation.w = fbuf[3]; + kf->translation.x = fbuf[4]; + kf->translation.y = fbuf[5]; + kf->translation.z = fbuf[6]; + // scaling ignored + kf->deltaTime = fbuf[10]; // absolute time here } } - - hier->RemoveQuaternionFlips(); - if(compress) - hier->RemoveUncompressedData(); - else - hier->CalcTotalTime(); } + + hier->RemoveQuaternionFlips(); + hier->CalcTotalTime(); } + if(animIndex > ms_numAnimations) + ms_numAnimations = animIndex; } void @@ -913,5 +1057,6 @@ CAnimManager::RemoveLastAnimFile(void) ms_numAnimBlocks--; ms_numAnimations = ms_aAnimBlocks[ms_numAnimBlocks].firstIndex; for(i = 0; i < ms_aAnimBlocks[ms_numAnimBlocks].numAnims; i++) - ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].RemoveAnimSequences(); + ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].firstIndex + i].Shutdown(); + ms_aAnimBlocks[ms_numAnimBlocks].isLoaded = false; } |