From 0c0455eee34870abd4c7cd47fa3cf25fbbe0cc2a Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sun, 23 Feb 2025 19:45:51 +0200 Subject: [PATCH] dca3-style animation compression for miami --- miami/animation/AnimBlendAssocGroup.cpp | 4 +- miami/animation/AnimBlendAssociation.cpp | 9 - miami/animation/AnimBlendClumpData.h | 3 +- miami/animation/AnimBlendHierarchy.cpp | 65 +------ miami/animation/AnimBlendHierarchy.h | 5 - miami/animation/AnimBlendNode.cpp | 211 ++++++--------------- miami/animation/AnimBlendNode.h | 4 - miami/animation/AnimBlendSequence.cpp | 151 ++------------- miami/animation/AnimBlendSequence.h | 163 ++++++++++++----- miami/animation/AnimManager.cpp | 113 +++--------- miami/animation/AnimManager.h | 2 - miami/animation/CutsceneMgr.cpp | 16 +- miami/animation/FrameUpdate.cpp | 224 +---------------------- miami/animation/RpAnimBlend.cpp | 9 - miami/animation/RpAnimBlend.h | 3 - miami/peds/PedAI.cpp | 44 ++--- 16 files changed, 232 insertions(+), 794 deletions(-) diff --git a/miami/animation/AnimBlendAssocGroup.cpp b/miami/animation/AnimBlendAssocGroup.cpp index 935e7fd6..941258f8 100644 --- a/miami/animation/AnimBlendAssocGroup.cpp +++ b/miami/animation/AnimBlendAssocGroup.cpp @@ -67,7 +67,7 @@ CAnimBlendAssocGroup::CopyAnimation(uint32 id) CAnimBlendAssociation *anim = GetAnimation(id); if(anim == nil) return nil; - CAnimManager::UncompressAnimation(anim->hierarchy); + return new CAnimBlendAssociation(*anim); } @@ -77,7 +77,7 @@ CAnimBlendAssocGroup::CopyAnimation(const char *name) CAnimBlendAssociation *anim = GetAnimation(name); if(anim == nil) return nil; - CAnimManager::UncompressAnimation(anim->hierarchy); + return new CAnimBlendAssociation(*anim); } diff --git a/miami/animation/AnimBlendAssociation.cpp b/miami/animation/AnimBlendAssociation.cpp index eb9d63cf..c0dbfea6 100644 --- a/miami/animation/AnimBlendAssociation.cpp +++ b/miami/animation/AnimBlendAssociation.cpp @@ -142,15 +142,6 @@ CAnimBlendAssociation::SetCurrentTime(float time) break; } - CAnimManager::UncompressAnimation(hierarchy); -#ifdef ANIM_COMPRESSION - // strangely PC has this but android doesn't - if(hierarchy->keepCompressed){ - for(i = 0; i < numNodes; i++) - if(nodes[i].sequence) - nodes[i].SetupKeyFrameCompressed(); - }else -#endif { for(i = 0; i < numNodes; i++) if(nodes[i].sequence) diff --git a/miami/animation/AnimBlendClumpData.h b/miami/animation/AnimBlendClumpData.h index bb711b28..60bb783f 100644 --- a/miami/animation/AnimBlendClumpData.h +++ b/miami/animation/AnimBlendClumpData.h @@ -10,8 +10,7 @@ struct AnimBlendFrameData IGNORE_TRANSLATION = 4, VELOCITY_EXTRACTION = 8, VELOCITY_EXTRACTION_3D = 0x10, - UPDATE_KEYFRAMES = 0x20, - COMPRESSED = 0x40 + UPDATE_KEYFRAMES = 0x20 }; uint8 flag; diff --git a/miami/animation/AnimBlendHierarchy.cpp b/miami/animation/AnimBlendHierarchy.cpp index bfa39ef9..b6dccebc 100644 --- a/miami/animation/AnimBlendHierarchy.cpp +++ b/miami/animation/AnimBlendHierarchy.cpp @@ -8,18 +8,14 @@ CAnimBlendHierarchy::CAnimBlendHierarchy(void) { sequences = nil; numSequences = 0; - compressed = 0; totalLength = 0.0f; - linkPtr = nil; } void CAnimBlendHierarchy::Shutdown(void) { - CAnimManager::RemoveFromUncompressedCache(this); RemoveAnimSequences(); totalLength = 0.0f; - compressed = 0; } void @@ -32,7 +28,6 @@ void CAnimBlendHierarchy::CalcTotalTime(void) { int i, j; - totalLength = 0.0f; for(i = 0; i < numSequences; i++){ @@ -40,35 +35,10 @@ CAnimBlendHierarchy::CalcTotalTime(void) if(sequences[i].numFrames == 0) continue; #endif - - totalLength = Max(totalLength, sequences[i].GetKeyFrame(sequences[i].numFrames-1)->deltaTime); - for(j = sequences[i].numFrames-1; j >= 1; j--){ - KeyFrame *kf1 = sequences[i].GetKeyFrame(j); - KeyFrame *kf2 = sequences[i].GetKeyFrame(j-1); - kf1->deltaTime -= kf2->deltaTime; - } - } -} - -void -CAnimBlendHierarchy::CalcTotalTimeCompressed(void) -{ - int i, j; - - totalLength = 0.0f; - - for(i = 0; i < numSequences; i++){ -#ifdef FIX_BUGS - if(sequences[i].numFrames == 0) - continue; -#endif - - totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->GetDeltaTime()); - for(j = sequences[i].numFrames-1; j >= 1; j--){ - KeyFrameCompressed *kf1 = sequences[i].GetKeyFrameCompressed(j); - KeyFrameCompressed *kf2 = sequences[i].GetKeyFrameCompressed(j-1); - kf1->deltaTime -= kf2->deltaTime; - } + float seqTime = 0.0f; + for(j = 0; j < sequences[i].numFrames; j++) + seqTime += sequences[i].GetDeltaTime(j); + totalLength = Max(totalLength, seqTime); } } @@ -89,33 +59,6 @@ CAnimBlendHierarchy::RemoveAnimSequences(void) numSequences = 0; } -void -CAnimBlendHierarchy::Uncompress(void) -{ -#ifdef ANIM_COMPRESSION - int i; - assert(compressed); - for(i = 0; i < numSequences; i++) - sequences[i].Uncompress(); -#endif - compressed = 0; - if(totalLength == 0.0f){ - RemoveQuaternionFlips(); - CalcTotalTime(); - } -} - -void -CAnimBlendHierarchy::RemoveUncompressedData(void) -{ -#ifdef ANIM_COMPRESSION - int i; - assert(!compressed); - for(i = 0; i < numSequences; i++) - sequences[i].RemoveUncompressedData(); -#endif - compressed = 1; -} #ifdef USE_CUSTOM_ALLOCATOR void diff --git a/miami/animation/AnimBlendHierarchy.h b/miami/animation/AnimBlendHierarchy.h index 4838c4f8..ca7b88f2 100644 --- a/miami/animation/AnimBlendHierarchy.h +++ b/miami/animation/AnimBlendHierarchy.h @@ -15,22 +15,17 @@ public: char name[24]; CAnimBlendSequence *sequences; int16 numSequences; - bool compressed; - bool keepCompressed; float totalLength; - CLink *linkPtr; CAnimBlendHierarchy(void); void Shutdown(void); void SetName(char *name); void CalcTotalTime(void); - void CalcTotalTimeCompressed(void); void RemoveQuaternionFlips(void); void RemoveAnimSequences(void); void Uncompress(void); void RemoveUncompressedData(void); void MoveMemory(bool onlyone = false); - bool IsCompressed() { return !!compressed; }; }; VALIDATE_SIZE(CAnimBlendHierarchy, 0x28); \ No newline at end of file diff --git a/miami/animation/AnimBlendNode.cpp b/miami/animation/AnimBlendNode.cpp index 6352c11b..d1ad3f49 100644 --- a/miami/animation/AnimBlendNode.cpp +++ b/miami/animation/AnimBlendNode.cpp @@ -29,53 +29,18 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight) float blend = association->GetBlendAmount(weight); if(blend > 0.0f){ - KeyFrameTrans *kfA = (KeyFrameTrans*)sequence->GetKeyFrame(frameA); - KeyFrameTrans *kfB = (KeyFrameTrans*)sequence->GetKeyFrame(frameB); - float t = kfA->deltaTime == 0.0f ? 0.0f : (kfA->deltaTime - remainingTime)/kfA->deltaTime; + float kfAdt = sequence->GetDeltaTime(frameA); + float t = kfAdt == 0.0f ? 0.0f : (kfAdt - remainingTime)/kfAdt; if(sequence->type & CAnimBlendSequence::KF_TRANS){ - trans = kfB->translation + t*(kfA->translation - kfB->translation); + auto kfAt = sequence->GetTranslation(frameA); + auto kfBt = sequence->GetTranslation(frameB); + trans = kfBt + t*(kfAt - kfBt); trans *= blend; } if(sequence->type & CAnimBlendSequence::KF_ROT){ - rot.Slerp(kfB->rotation, kfA->rotation, theta, invSin, t); - rot *= blend; - } - } - - return looped; -} - -bool -CAnimBlendNode::UpdateCompressed(CVector &trans, CQuaternion &rot, float weight) -{ - bool looped = false; - - trans = CVector(0.0f, 0.0f, 0.0f); - rot = CQuaternion(0.0f, 0.0f, 0.0f, 0.0f); - - if(association->IsRunning()){ - remainingTime -= association->timeStep; - if(remainingTime <= 0.0f) - looped = NextKeyFrameCompressed(); - } - - float blend = association->GetBlendAmount(weight); - if(blend > 0.0f){ - KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA); - KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB); - float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime(); - if(sequence->type & CAnimBlendSequence::KF_TRANS){ - CVector transA, transB; - kfA->GetTranslation(&transA); - kfB->GetTranslation(&transB); - trans = transB + t*(transA - transB); - trans *= blend; - } - if(sequence->type & CAnimBlendSequence::KF_ROT){ - CQuaternion rotA, rotB; - kfA->GetRotation(&rotA); - kfB->GetRotation(&rotB); - rot.Slerp(rotB, rotA, theta, invSin, t); + auto kfAr = sequence->GetRotation(frameA); + auto kfBr = sequence->GetRotation(frameB); + rot.Slerp(kfBr, kfAr, theta, invSin, t); rot *= blend; } } @@ -109,7 +74,7 @@ CAnimBlendNode::NextKeyFrame(void) frameA = 0; } - remainingTime += sequence->GetKeyFrame(frameA)->deltaTime; + remainingTime += sequence->GetDeltaTime(frameA); } frameB = frameA - 1; @@ -120,42 +85,42 @@ CAnimBlendNode::NextKeyFrame(void) return looped; } -bool -CAnimBlendNode::NextKeyFrameCompressed(void) -{ - bool looped; +// bool +// CAnimBlendNode::NextKeyFrameCompressed(void) +// { +// bool looped; - if(sequence->numFrames <= 1) - return false; +// if(sequence->numFrames <= 1) +// return false; - looped = false; - frameB = frameA; +// looped = false; +// frameB = frameA; - // Advance as long as we have to - while(remainingTime <= 0.0f){ - frameA++; +// // Advance as long as we have to +// while(remainingTime <= 0.0f){ +// frameA++; - if(frameA >= sequence->numFrames){ - // reached end of animation - if(!association->IsRepeating()){ - frameA--; - remainingTime = 0.0f; - return false; - } - looped = true; - frameA = 0; - } +// if(frameA >= sequence->numFrames){ +// // reached end of animation +// if(!association->IsRepeating()){ +// frameA--; +// remainingTime = 0.0f; +// return false; +// } +// looped = true; +// frameA = 0; +// } - remainingTime += sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime(); - } +// remainingTime += sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime(); +// } - frameB = frameA - 1; - if(frameB < 0) - frameB += sequence->numFrames; +// frameB = frameA - 1; +// if(frameB < 0) +// frameB += sequence->numFrames; - CalcDeltasCompressed(); - return looped; -} +// CalcDeltasCompressed(); +// return looped; +// } // Set animation to time t bool @@ -171,8 +136,8 @@ CAnimBlendNode::FindKeyFrame(float t) remainingTime = 0.0f; }else{ // advance until t is between frameB and frameA - while (t > sequence->GetKeyFrame(++frameA)->deltaTime) { - t -= sequence->GetKeyFrame(frameA)->deltaTime; + while (t > sequence->GetDeltaTime(++frameA)) { + t -= sequence->GetDeltaTime(frameA); if (frameA + 1 >= sequence->numFrames) { // reached end of animation if (!association->IsRepeating()) { @@ -185,62 +150,21 @@ CAnimBlendNode::FindKeyFrame(float t) frameB = frameA; } - remainingTime = sequence->GetKeyFrame(frameA)->deltaTime - t; + remainingTime = sequence->GetDeltaTime(frameA) - t; } CalcDeltas(); return true; } -bool -CAnimBlendNode::SetupKeyFrameCompressed(void) -{ - if(sequence->numFrames < 1) - return false; - - frameA = 1; - frameB = 0; - - if(sequence->numFrames == 1){ - frameA = 0; - remainingTime = 0.0f; - }else - remainingTime = sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime(); - - CalcDeltasCompressed(); - return true; -} - void CAnimBlendNode::CalcDeltas(void) { if((sequence->type & CAnimBlendSequence::KF_ROT) == 0) return; - KeyFrame *kfA = sequence->GetKeyFrame(frameA); - KeyFrame *kfB = sequence->GetKeyFrame(frameB); - float cos = DotProduct(kfA->rotation, kfB->rotation); - if(cos > 1.0f) - cos = 1.0f; - theta = Acos(cos); - invSin = theta == 0.0f ? 0.0f : 1.0f/Sin(theta); -} - -void -CAnimBlendNode::CalcDeltasCompressed(void) -{ - if((sequence->type & CAnimBlendSequence::KF_ROT) == 0) - return; - KeyFrameCompressed *kfA = sequence->GetKeyFrameCompressed(frameA); - KeyFrameCompressed *kfB = sequence->GetKeyFrameCompressed(frameB); - CQuaternion rotA, rotB; - kfA->GetRotation(&rotA); - kfB->GetRotation(&rotB); - float cos = DotProduct(rotA, rotB); - if(cos < 0.0f){ - rotB *= -1.0f; - kfB->SetRotation(rotB); - } - cos = DotProduct(rotA, rotB); + auto kfAr = sequence->GetRotation(frameA); + auto kfBr = sequence->GetRotation(frameB); + float cos = DotProduct(kfAr, kfBr); if(cos > 1.0f) cos = 1.0f; theta = Acos(cos); @@ -254,35 +178,17 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight) float blend = association->GetBlendAmount(weight); if(blend > 0.0f){ - KeyFrameTrans *kfA = (KeyFrameTrans*)sequence->GetKeyFrame(frameA); - KeyFrameTrans *kfB = (KeyFrameTrans*)sequence->GetKeyFrame(frameB); - float t = kfA->deltaTime == 0.0f ? 0.0f : (kfA->deltaTime - remainingTime)/kfA->deltaTime; + auto kfAdt = sequence->GetDeltaTime(frameA); + float t = kfAdt == 0.0f ? 0.0f : (kfAdt - remainingTime)/kfAdt; if(sequence->type & CAnimBlendSequence::KF_TRANS){ - trans = kfB->translation + t*(kfA->translation - kfB->translation); + auto kfAt = sequence->GetTranslation(frameA); + auto kfBt = sequence->GetTranslation(frameB); + trans = kfBt + t*(kfAt - kfBt); trans *= blend; } } } -void -CAnimBlendNode::GetCurrentTranslationCompressed(CVector &trans, float weight) -{ - trans = CVector(0.0f, 0.0f, 0.0f); - - float blend = association->GetBlendAmount(weight); - if(blend > 0.0f){ - KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA); - KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB); - float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime(); - if(sequence->type & CAnimBlendSequence::KF_TRANS){ - CVector transA, transB; - kfA->GetTranslation(&transA); - kfB->GetTranslation(&transB); - trans = transB + t*(transA - transB); - trans *= blend; - } - } -} void CAnimBlendNode::GetEndTranslation(CVector &trans, float weight) @@ -291,24 +197,9 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight) float blend = association->GetBlendAmount(weight); if(blend > 0.0f){ - KeyFrameTrans *kf = (KeyFrameTrans*)sequence->GetKeyFrame(sequence->numFrames-1); - if(sequence->type & CAnimBlendSequence::KF_TRANS) - trans = kf->translation * blend; - } -} - -void -CAnimBlendNode::GetEndTranslationCompressed(CVector &trans, float weight) -{ - trans = CVector(0.0f, 0.0f, 0.0f); - - float blend = association->GetBlendAmount(weight); - if(blend > 0.0f){ - KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(sequence->numFrames-1); if(sequence->type & CAnimBlendSequence::KF_TRANS){ - CVector pos; - kf->GetTranslation(&pos); + CVector pos = sequence->GetTranslation(sequence->numFrames-1); trans = pos * blend; } } -} +} \ No newline at end of file diff --git a/miami/animation/AnimBlendNode.h b/miami/animation/AnimBlendNode.h index 99a657ac..ec157463 100644 --- a/miami/animation/AnimBlendNode.h +++ b/miami/animation/AnimBlendNode.h @@ -24,13 +24,9 @@ public: bool NextKeyFrame(void); bool NextKeyFrameCompressed(void); bool FindKeyFrame(float t); - bool SetupKeyFrameCompressed(void); void CalcDeltas(void); - void CalcDeltasCompressed(void); void GetCurrentTranslation(CVector &trans, float weight); - void GetCurrentTranslationCompressed(CVector &trans, float weight); void GetEndTranslation(CVector &trans, float weight); - void GetEndTranslationCompressed(CVector &trans, float weight); }; diff --git a/miami/animation/AnimBlendSequence.cpp b/miami/animation/AnimBlendSequence.cpp index 36ac9495..0718f37c 100644 --- a/miami/animation/AnimBlendSequence.cpp +++ b/miami/animation/AnimBlendSequence.cpp @@ -8,16 +8,15 @@ CAnimBlendSequence::CAnimBlendSequence(void) type = 0; numFrames = 0; keyFrames = nil; - keyFramesCompressed = nil; +#ifdef PED_SKIN boneTag = -1; +#endif } CAnimBlendSequence::~CAnimBlendSequence(void) { if(keyFrames) RwFree(keyFrames); - if(keyFramesCompressed) - RwFree(keyFramesCompressed); } void @@ -27,21 +26,23 @@ CAnimBlendSequence::SetName(char *name) } void -CAnimBlendSequence::SetNumFrames(int numFrames, bool translation, bool compressed) +CAnimBlendSequence::SetNumFrames(int numFrames, bool translation, bool compress) { + int sz; + if(translation){ type |= KF_ROT | KF_TRANS; - if(compressed) - keyFramesCompressed = RwMalloc(sizeof(KeyFrameTrans) * numFrames); - else - keyFrames = RwMalloc(sizeof(KeyFrameTrans) * numFrames); + if (compress) { + type |= KF_COMPRESSED; + sz = sizeof(KeyFrameTransCompressed); + } else { + sz = sizeof(KeyFrameTransUncompressed); + } }else{ + sz = sizeof(KeyFrame); type |= KF_ROT; - if(compressed) - keyFramesCompressed = RwMalloc(sizeof(KeyFrame) * numFrames); - else - keyFrames = RwMalloc(sizeof(KeyFrame) * numFrames); } + keyFrames = RwMalloc(sz * numFrames); this->numFrames = numFrames; } @@ -50,134 +51,19 @@ CAnimBlendSequence::RemoveQuaternionFlips(void) { int i; CQuaternion last; - KeyFrame *frame; if(numFrames < 2) return; - frame = GetKeyFrame(0); - last = frame->rotation; + last = GetRotation(0); for(i = 1; i < numFrames; i++){ - frame = GetKeyFrame(i); - if(DotProduct(last, frame->rotation) < 0.0f) - frame->rotation = -frame->rotation; - last = frame->rotation; + auto KFr = GetRotation(i); + if(DotProduct(last, KFr) < 0.0f) + SetRotation(i, -KFr); + last = GetRotation(i); } } -void -CAnimBlendSequence::Uncompress(void) -{ - int i; - - if(numFrames == 0) - return; - - PUSH_MEMID(MEMID_ANIMATION); - - float rotScale = 1.0f/4096.0f; - float timeScale = 1.0f/60.0f; - float transScale = 1.0f/1024.0f; - if(type & KF_TRANS){ - void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTrans)); - KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)keyFramesCompressed; - KeyFrameTrans *kf = (KeyFrameTrans*)newKfs; - for(i = 0; i < numFrames; i++){ - kf->rotation.x = ckf->rot[0]*rotScale; - kf->rotation.y = ckf->rot[1]*rotScale; - kf->rotation.z = ckf->rot[2]*rotScale; - kf->rotation.w = ckf->rot[3]*rotScale; - kf->deltaTime = ckf->deltaTime*timeScale; - kf->translation.x = ckf->trans[0]*transScale; - kf->translation.y = ckf->trans[1]*transScale; - kf->translation.z = ckf->trans[2]*transScale; - kf++; - ckf++; - } - keyFrames = newKfs; - }else{ - void *newKfs = RwMalloc(numFrames * sizeof(KeyFrame)); - KeyFrameCompressed *ckf = (KeyFrameCompressed*)keyFramesCompressed; - KeyFrame *kf = (KeyFrame*)newKfs; - for(i = 0; i < numFrames; i++){ - kf->rotation.x = ckf->rot[0]*rotScale; - kf->rotation.y = ckf->rot[1]*rotScale; - kf->rotation.z = ckf->rot[2]*rotScale; - kf->rotation.w = ckf->rot[3]*rotScale; - kf->deltaTime = ckf->deltaTime*timeScale; - kf++; - ckf++; - } - keyFrames = newKfs; - } - REGISTER_MEMPTR(&keyFrames); - - RwFree(keyFramesCompressed); - keyFramesCompressed = nil; - - POP_MEMID(); -} - -void -CAnimBlendSequence::CompressKeyframes(void) -{ - int i; - - if(numFrames == 0) - return; - - PUSH_MEMID(MEMID_ANIMATION); - - float rotScale = 4096.0f; - float timeScale = 60.0f; - float transScale = 1024.0f; - if(type & KF_TRANS){ - void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTransCompressed)); - KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)newKfs; - KeyFrameTrans *kf = (KeyFrameTrans*)keyFrames; - for(i = 0; i < numFrames; i++){ - ckf->rot[0] = kf->rotation.x*rotScale; - ckf->rot[1] = kf->rotation.y*rotScale; - ckf->rot[2] = kf->rotation.z*rotScale; - ckf->rot[3] = kf->rotation.w*rotScale; - ckf->deltaTime = kf->deltaTime*timeScale + 0.5f; - ckf->trans[0] = kf->translation.x*transScale; - ckf->trans[1] = kf->translation.y*transScale; - ckf->trans[2] = kf->translation.z*transScale; - kf++; - ckf++; - } - keyFramesCompressed = newKfs; - }else{ - void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameCompressed)); - KeyFrameCompressed *ckf = (KeyFrameCompressed*)newKfs; - KeyFrame *kf = (KeyFrame*)keyFrames; - for(i = 0; i < numFrames; i++){ - ckf->rot[0] = kf->rotation.x*rotScale; - ckf->rot[1] = kf->rotation.y*rotScale; - ckf->rot[2] = kf->rotation.z*rotScale; - ckf->rot[3] = kf->rotation.w*rotScale; - ckf->deltaTime = kf->deltaTime*timeScale + 0.5f; - kf++; - ckf++; - } - keyFramesCompressed = newKfs; - } - REGISTER_MEMPTR(&keyFramesCompressed); - - POP_MEMID(); -} - -void -CAnimBlendSequence::RemoveUncompressedData(void) -{ - if(numFrames == 0) - return; - CompressKeyframes(); - RwFree(keyFrames); - keyFrames = nil; -} - #ifdef USE_CUSTOM_ALLOCATOR bool CAnimBlendSequence::MoveMemory(void) @@ -198,3 +84,4 @@ CAnimBlendSequence::MoveMemory(void) return false; } #endif + diff --git a/miami/animation/AnimBlendSequence.h b/miami/animation/AnimBlendSequence.h index 67118b2f..dcc93471 100644 --- a/miami/animation/AnimBlendSequence.h +++ b/miami/animation/AnimBlendSequence.h @@ -7,52 +7,67 @@ #endif // TODO: put them somewhere else? +static int16 checked_f2i16(float f) { + assert(f >= -32768 && f <= 32767); + return f; +} + +static uint16 checked_f2u16(float f) { + assert(f >= 0 && f <= 65535); + return f; +} + +#define KF_MINDELTA (1/256.f) + struct KeyFrame { - CQuaternion rotation; - float deltaTime; // relative to previous key frame -}; - -struct KeyFrameTrans : KeyFrame { - CVector translation; -}; - -struct KeyFrameCompressed { int16 rot[4]; // 4096 - int16 deltaTime; // 60 + uint16 dltTime; // 256 - void GetRotation(CQuaternion *quat){ - float scale = 1.0f/4096.0f; - quat->x = rot[0]*scale; - quat->y = rot[1]*scale; - quat->z = rot[2]*scale; - quat->w = rot[3]*scale; + CQuaternion rotation_() { + return { rot[0] * (1/4096.f), rot[1] * (1/4096.f), rot[2] * (1/4096.f), rot[3] * (1/4096.f) }; } - void SetRotation(const CQuaternion &quat){ - rot[0] = quat.x * 4096.0f; - rot[1] = quat.y * 4096.0f; - rot[2] = quat.z * 4096.0f; - rot[3] = quat.w * 4096.0f; - } - float GetDeltaTime(void) { return deltaTime/60.0f; } - void SetTime(float t) { deltaTime = t*60.0f + 0.5f; } -}; -struct KeyFrameTransCompressed : KeyFrameCompressed { - int16 trans[3]; // 1024 - - void GetTranslation(CVector *vec) { - float scale = 1.0f/1024.0f; - vec->x = trans[0]*scale; - vec->y = trans[1]*scale; - vec->z = trans[2]*scale; + void rotation_(const CQuaternion& q) { + rot[0] = checked_f2i16(q.x * 4096.0f); + rot[1] = checked_f2i16(q.y * 4096.0f); + rot[2] = checked_f2i16(q.z * 4096.0f); + rot[3] = checked_f2i16(q.w * 4096.0f); } - void SetTranslation(const CVector &vec){ - trans[0] = vec.x*1024.0f; - trans[1] = vec.y*1024.0f; - trans[2] = vec.z*1024.0f; + + float deltaTime_() { + return dltTime * (1/256.0f); + } + + void deltaTime_(float t) { + dltTime = checked_f2u16(t * 256); // always round down } }; +struct KeyFrameTransUncompressed : KeyFrame { + // Some animations use bigger range, eg during the intro + CVector trans; + CVector translation_() { + return trans; + } + + void translation_(const CVector &v) { + trans = v; + } +}; + +struct KeyFrameTransCompressed : KeyFrame { + int16 trans[3]; // 128 + + CVector translation_() { + return { trans[0] * (1/128.f), trans[1] * (1/128.f), trans[2] * (1/128.f)}; + } + + void translation_(const CVector &v) { + trans[0] = checked_f2i16(v.x * 128.f); + trans[1] = checked_f2i16(v.y * 128.f); + trans[2] = checked_f2i16(v.z * 128.f); + } +}; // The sequence of key frames of one animated node class CAnimBlendSequence @@ -60,34 +75,82 @@ class CAnimBlendSequence public: enum { KF_ROT = 1, - KF_TRANS = 2 + KF_TRANS = 2, + KF_COMPRESSED = 4, // only applicable for KF_TRANS }; int32 type; char name[24]; int32 numFrames; int16 boneTag; void *keyFrames; - void *keyFramesCompressed; CAnimBlendSequence(void); virtual ~CAnimBlendSequence(void); void SetName(char *name); void SetNumFrames(int numFrames, bool translation, bool compressed); void RemoveQuaternionFlips(void); - KeyFrame *GetKeyFrame(int n) { - return type & KF_TRANS ? - &((KeyFrameTrans*)keyFrames)[n] : - &((KeyFrame*)keyFrames)[n]; + + void SetTranslation(int n, const CVector &v) { + if (type & KF_COMPRESSED) { + ((KeyFrameTransCompressed*)keyFrames)[n].translation_(v); + } else if (type & KF_TRANS) { + ((KeyFrameTransUncompressed*)keyFrames)[n].translation_(v); + } else { + assert(false && "SetTranslation called on sequence without translation"); + } } - KeyFrameCompressed *GetKeyFrameCompressed(int n) { - return type & KF_TRANS ? - &((KeyFrameTransCompressed*)keyFramesCompressed)[n] : - &((KeyFrameCompressed*)keyFramesCompressed)[n]; + + CVector GetTranslation(int n) { + if (type & KF_COMPRESSED) { + return ((KeyFrameTransCompressed*)keyFrames)[n].translation_(); + } else if (type & KF_TRANS) { + return ((KeyFrameTransUncompressed*)keyFrames)[n].translation_(); + } else { + assert(false && "GetTranslation called on sequence without translation"); + } } + + void SetRotation(int n, const CQuaternion &q) { + if (type & KF_COMPRESSED) { + ((KeyFrameTransCompressed*)keyFrames)[n].rotation_(q); + } else if (type & KF_TRANS) { + ((KeyFrameTransUncompressed*)keyFrames)[n].rotation_(q); + } else { + ((KeyFrame*)keyFrames)[n].rotation_(q); + } + } + + CQuaternion GetRotation(int n) { + if (type & KF_COMPRESSED) { + return ((KeyFrameTransCompressed*)keyFrames)[n].rotation_(); + } else if (type & KF_TRANS) { + return ((KeyFrameTransUncompressed*)keyFrames)[n].rotation_(); + } else { + return ((KeyFrame*)keyFrames)[n].rotation_(); + } + } + + void SetDeltaTime(int n, float t) { + if (type & KF_COMPRESSED) { + ((KeyFrameTransCompressed*)keyFrames)[n].deltaTime_(t); + } else if (type & KF_TRANS) { + ((KeyFrameTransUncompressed*)keyFrames)[n].deltaTime_(t); + } else { + ((KeyFrame*)keyFrames)[n].deltaTime_(t); + } + } + + float GetDeltaTime(int n) { + if (type & KF_COMPRESSED) { + return ((KeyFrameTransCompressed*)keyFrames)[n].deltaTime_(); + } else if (type & KF_TRANS) { + return ((KeyFrameTransUncompressed*)keyFrames)[n].deltaTime_(); + } else { + return ((KeyFrame*)keyFrames)[n].deltaTime_(); + } + } + bool HasTranslation(void) { return !!(type & KF_TRANS); } - void Uncompress(void); - void CompressKeyframes(void); - void RemoveUncompressedData(void); bool MoveMemory(void); void SetBoneTag(int tag) { boneTag = tag; } diff --git a/miami/animation/AnimManager.cpp b/miami/animation/AnimManager.cpp index f6ac3eb5..94741141 100644 --- a/miami/animation/AnimManager.cpp +++ b/miami/animation/AnimManager.cpp @@ -17,7 +17,6 @@ CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS]; int32 CAnimManager::ms_numAnimBlocks; int32 CAnimManager::ms_numAnimations; CAnimBlendAssocGroup *CAnimManager::ms_aAnimAssocGroups; -CLinkList CAnimManager::ms_animCache; AnimAssocDesc aStdAnimDescs[] = { { ANIM_STD_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK }, @@ -972,7 +971,6 @@ CAnimManager::Initialise(void) { ms_numAnimations = 0; ms_numAnimBlocks = 0; - ms_animCache.Init(25); } void @@ -986,46 +984,10 @@ CAnimManager::Shutdown(void) for(i = 0; i < ms_numAnimations; i++) ms_aAnimations[i].Shutdown(); - ms_animCache.Shutdown(); delete[] ms_aAnimAssocGroups; } -void -CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier) -{ - if(hier->keepCompressed){ - if(hier->totalLength == 0.0f) - hier->CalcTotalTimeCompressed(); - }else{ - if(!hier->compressed){ - if(hier->linkPtr){ - hier->linkPtr->Remove(); - ms_animCache.head.Insert(hier->linkPtr); - } - }else{ - CLink *link = ms_animCache.Insert(hier); - if(link == nil){ - CAnimBlendHierarchy *lastHier = ms_animCache.tail.prev->item; - lastHier->RemoveUncompressedData(); - ms_animCache.Remove(ms_animCache.tail.prev); - lastHier->linkPtr = nil; - link = ms_animCache.Insert(hier); - } - hier->linkPtr = link; - hier->Uncompress(); - } - } -} - -void -CAnimManager::RemoveFromUncompressedCache(CAnimBlendHierarchy *hier) -{ - if(hier->linkPtr){ - ms_animCache.Remove(hier->linkPtr); - hier->linkPtr = nil; - } -} CAnimBlock* CAnimManager::GetAnimationBlock(const char *name) @@ -1226,7 +1188,6 @@ CAnimManager::BlendAnimation(RpClump *clump, AssocGroupId groupId, AnimationId a found->blendAmount = 0.0f; found->blendDelta = delta; } - UncompressAnimation(found->hierarchy); return found; } @@ -1321,11 +1282,8 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedA RwStreamRead(stream, buf, name.size); hier->SetName(buf); -#ifdef ANIM_COMPRESSION bool compressHier = compress; -#else - bool compressHier = false; -#endif + if (uncompressedAnims) { for (int i = 0; uncompressedAnims[i][0]; i++) { if (!CGeneral::faststricmp(uncompressedAnims[i], hier->name)){ @@ -1334,10 +1292,6 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedA } } } - - hier->compressed = compressHier; - hier->keepCompressed = false; - // DG info has number of nodes/sequences RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader)); ROUNDSIZE(dgan.size); @@ -1377,6 +1331,8 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedA if(strstr(seq->name, "L Toe")) debug("anim %s has toe keyframes\n", hier->name); // BUG: seq->name + float *frameTimes = (float*)RwMalloc(sizeof(float) * numFrames); + for(l = 0; l < numFrames; l++){ if(hasScale){ RwStreamRead(stream, buf, 0x2C); @@ -1384,58 +1340,47 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedA rot.Invert(); CVector trans(fbuf[4], fbuf[5], fbuf[6]); - if(compressHier){ - KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l); - kf->SetRotation(rot); - kf->SetTranslation(trans); - // scaling ignored - kf->SetTime(fbuf[10]); // absolute time here - }else{ - KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l); - kf->rotation = rot; - kf->translation = trans; - // scaling ignored - kf->deltaTime = fbuf[10]; // absolute time here - } + seq->SetRotation(l, rot); + seq->SetTranslation(l, trans); + // scaling ignored + frameTimes[l] = fbuf[10]; // absolute time here }else if(hasTranslation){ RwStreamRead(stream, buf, 0x20); CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); rot.Invert(); CVector trans(fbuf[4], fbuf[5], fbuf[6]); - if(compressHier){ - KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l); - kf->SetRotation(rot); - kf->SetTranslation(trans); - kf->SetTime(fbuf[7]); // absolute time here - }else{ - KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l); - kf->rotation = rot; - kf->translation = trans; - kf->deltaTime = fbuf[7]; // absolute time here - } + seq->SetRotation(l, rot); + seq->SetTranslation(l, trans); + frameTimes[l] = fbuf[7]; // absolute time here }else{ RwStreamRead(stream, buf, 0x14); CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); rot.Invert(); - if(compressHier){ - KeyFrameCompressed *kf = (KeyFrameCompressed*)seq->GetKeyFrameCompressed(l); - kf->SetRotation(rot); - kf->SetTime(fbuf[4]); // absolute time here - }else{ - KeyFrame *kf = (KeyFrame*)seq->GetKeyFrame(l); - kf->rotation = rot; - kf->deltaTime = fbuf[4]; // absolute time here - } + seq->SetRotation(l, rot); + frameTimes[l] = fbuf[4]; // absolute time here } } + + // convert absolute time to deltas + float running_sum = 0.0f; + for (l = 0; l < numFrames; l++) { + auto dt = frameTimes[l] - running_sum; + seq->SetDeltaTime(l, dt); + assert(seq->GetDeltaTime(l) <= dt); + running_sum += seq->GetDeltaTime(l); + // if (seq->GetDeltaTime(l) == 0.0f && dt != 0.0f) { + // seq->SetDeltaTime(l, KF_MINDELTA); + // } + + // assert(seq->GetDeltaTime(l) != 0.0f || dt == 0.0f); + } + RwFree(frameTimes); } - if(!compressHier){ - hier->RemoveQuaternionFlips(); - hier->CalcTotalTime(); - } + hier->RemoveQuaternionFlips(); + hier->CalcTotalTime(); } if(animIndex > ms_numAnimations) ms_numAnimations = animIndex; diff --git a/miami/animation/AnimManager.h b/miami/animation/AnimManager.h index 213326b6..f1a58b1a 100644 --- a/miami/animation/AnimManager.h +++ b/miami/animation/AnimManager.h @@ -116,8 +116,6 @@ public: static void Initialise(void); static void Shutdown(void); - static void UncompressAnimation(CAnimBlendHierarchy *anim); - static void RemoveFromUncompressedCache(CAnimBlendHierarchy *hier); static CAnimBlock *GetAnimationBlock(int32 block) { return &ms_aAnimBlocks[block]; } static CAnimBlock *GetAnimationBlock(const char *name); static int32 GetAnimationBlockIndex(const char *name); diff --git a/miami/animation/CutsceneMgr.cpp b/miami/animation/CutsceneMgr.cpp index 633618b1..49eea137 100644 --- a/miami/animation/CutsceneMgr.cpp +++ b/miami/animation/CutsceneMgr.cpp @@ -289,15 +289,7 @@ CCutsceneMgr::SetupCutsceneToStart(void) if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) { pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION); } else { - if (pAnimBlendAssoc->hierarchy->IsCompressed()){ - KeyFrameTransCompressed *keyFrames = ((KeyFrameTransCompressed*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0)); - CVector trans; - keyFrames->GetTranslation(&trans); - ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + trans); - }else{ - KeyFrameTrans *keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0)); - ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation); - } + ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + pAnimBlendAssoc->hierarchy->sequences[0].GetTranslation(0)); } pAnimBlendAssoc->SetRun(); } else { @@ -331,9 +323,6 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject) return; } - if (pNewAnim->hierarchy->IsCompressed()) - pNewAnim->hierarchy->keepCompressed = true; - CStreaming::ImGonnaUseStreamingMemory(); pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName); CStreaming::IHaveUsedStreamingMemory(); @@ -344,9 +333,6 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject) pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject); pAnimBlendClumpData->link.Prepend(&pNewAnim->link); - - if (pNewAnim->hierarchy->keepCompressed) - pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::COMPRESSED; } void diff --git a/miami/animation/FrameUpdate.cpp b/miami/animation/FrameUpdate.cpp index d3094bb0..727f2692 100644 --- a/miami/animation/FrameUpdate.cpp +++ b/miami/animation/FrameUpdate.cpp @@ -17,9 +17,6 @@ void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg); -void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg); -void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg); - void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg) { @@ -446,223 +443,4 @@ FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg) { if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity2d) FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg); -} - - -void -FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg) -{ - CVector vec, pos(0.0f, 0.0f, 0.0f); - CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f); - float totalBlendAmount = 0.0f; - CVector trans(0.0f, 0.0f, 0.0f); - CVector cur(0.0f, 0.0f, 0.0f); - CVector end(0.0f, 0.0f, 0.0f); - bool looped = false; - RwMatrix *mat = RwFrameGetMatrix(frame->frame); - CAnimBlendNode **node; - AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg; - - if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && - gpAnimBlendClump->velocity2d){ - if(updateData->foobar) - for(node = updateData->nodes; *node; node++) - if((*node)->sequence && (*node)->association->IsPartial()) - totalBlendAmount += (*node)->association->blendAmount; - - for(node = updateData->nodes; *node; node++) - if((*node)->sequence && (*node)->sequence->HasTranslation()){ - if((*node)->association->HasTranslation()){ - (*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount); - cur += vec; - } - } - - for(node = updateData->nodes; *node; node++){ - if((*node)->sequence){ - bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount); -#ifdef FIX_BUGS - if(DotProduct(rot, q) < 0.0f) - rot -= q; - else -#endif - rot += q; - if((*node)->sequence->HasTranslation()){ - pos += vec; - if((*node)->association->HasTranslation()){ - trans += vec; - looped |= nodelooped; - if(nodelooped){ - (*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount); - end += vec; - } - } - } - } - ++*node; - } - - if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ - RwMatrixSetIdentity(mat); - rot.Normalise(); - rot.Get(mat); - } - - if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ - *gpAnimBlendClump->velocity3d = trans - cur; - if(looped) - *gpAnimBlendClump->velocity3d += end; - mat->pos.x = (pos - trans).x + frame->resetPos.x; - mat->pos.y = (pos - trans).y + frame->resetPos.y; - mat->pos.z = (pos - trans).z + frame->resetPos.z; - } - RwMatrixUpdate(mat); - }else{ - if(updateData->foobar) - for(node = updateData->nodes; *node; node++) - if((*node)->sequence && (*node)->association->IsPartial()) - totalBlendAmount += (*node)->association->blendAmount; - - for(node = updateData->nodes; *node; node++){ - if((*node)->sequence){ - (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount); - if((*node)->sequence->HasTranslation()) - pos += vec; -#ifdef FIX_BUGS - if(DotProduct(rot, q) < 0.0f) - rot -= q; - else -#endif - rot += q; - } - ++*node; - } - - if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ - RwMatrixSetIdentity(mat); - rot.Normalise(); - rot.Get(mat); - } - - if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ - mat->pos.x = pos.x; - mat->pos.y = pos.y; - mat->pos.z = pos.z; - mat->pos.x += frame->resetPos.x; - mat->pos.y += frame->resetPos.y; - mat->pos.z += frame->resetPos.z; - } - RwMatrixUpdate(mat); - } -} - -void -FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg) -{ - CVector vec, pos(0.0f, 0.0f, 0.0f); - CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f); - float totalBlendAmount = 0.0f; - CVector trans(0.0f, 0.0f, 0.0f); - CVector cur(0.0f, 0.0f, 0.0f); - CVector end(0.0f, 0.0f, 0.0f); - bool looped = false; - RpHAnimStdInterpFrame *xform = frame->hanimFrame; - CAnimBlendNode **node; - AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg; - - if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && - gpAnimBlendClump->velocity2d){ - if(updateData->foobar) - for(node = updateData->nodes; *node; node++) - if((*node)->sequence && (*node)->association->IsPartial()) - totalBlendAmount += (*node)->association->blendAmount; - - for(node = updateData->nodes; *node; node++) - if((*node)->sequence && (*node)->sequence->HasTranslation()){ - if((*node)->association->HasTranslation()){ - (*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount); - cur += vec; - } - } - - for(node = updateData->nodes; *node; node++){ - if((*node)->sequence){ - bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount); -#ifdef FIX_BUGS - if(DotProduct(rot, q) < 0.0f) - rot -= q; - else -#endif - rot += q; - if((*node)->sequence->HasTranslation()){ - pos += vec; - if((*node)->association->HasTranslation()){ - trans += vec; - looped |= nodelooped; - if(nodelooped){ - (*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount); - end += vec; - } - } - } - } - ++*node; - } - - if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ - rot.Normalise(); - xform->q.imag.x = rot.x; - xform->q.imag.y = rot.y; - xform->q.imag.z = rot.z; - xform->q.real = rot.w; - } - - if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ - *gpAnimBlendClump->velocity3d = trans - cur; - if(looped) - *gpAnimBlendClump->velocity3d += end; - xform->t.x = (pos - trans).x + frame->resetPos.x; - xform->t.y = (pos - trans).y + frame->resetPos.y; - xform->t.z = (pos - trans).z + frame->resetPos.z; - } - }else{ - float transBlendAmount = 0.0f; - - if(updateData->foobar) - for(node = updateData->nodes; *node; node++) - if((*node)->sequence && (*node)->association->IsPartial()) - totalBlendAmount += (*node)->association->blendAmount; - - for(node = updateData->nodes; *node; node++){ - if((*node)->sequence){ - (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount); - if((*node)->sequence->HasTranslation()){ - pos += vec; - transBlendAmount += (*node)->association->blendAmount; - } - if(DotProduct(rot, q) < 0.0f) - rot -= q; - else - rot += q; - } - ++*node; - } - - if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){ - rot.Normalise(); - xform->q.imag.x = rot.x; - xform->q.imag.y = rot.y; - xform->q.imag.z = rot.z; - xform->q.real = rot.w; - } - - if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){ - xform->t.x = transBlendAmount*pos.x; - xform->t.y = transBlendAmount*pos.y; - xform->t.z = transBlendAmount*pos.z; - xform->t.x += (1.0f-transBlendAmount)*frame->resetPos.x; - xform->t.y += (1.0f-transBlendAmount)*frame->resetPos.y; - xform->t.z += (1.0f-transBlendAmount)*frame->resetPos.z; - } - } -} +} \ No newline at end of file diff --git a/miami/animation/RpAnimBlend.cpp b/miami/animation/RpAnimBlend.cpp index 60e2d091..933dac69 100644 --- a/miami/animation/RpAnimBlend.cpp +++ b/miami/animation/RpAnimBlend.cpp @@ -474,7 +474,6 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender) assoc = CAnimBlendAssociation::FromLink(link); if(assoc->UpdateBlend(timeDelta)){ if(assoc->hierarchy->sequences){ - CAnimManager::UncompressAnimation(assoc->hierarchy); if(i < 11) updateData.nodes[i++] = assoc->GetNode(0); if(assoc->flags & ASSOC_MOVEMENT){ @@ -494,14 +493,6 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender) updateData.nodes[i] = nil; -#ifdef ANIM_COMPRESSION - if(clumpData->frames[0].flag & AnimBlendFrameData::COMPRESSED){ - if(IsClumpSkinned(clump)) - clumpData->ForAllFrames(FrameUpdateCallBackSkinnedCompressed, &updateData); - else - clumpData->ForAllFrames(FrameUpdateCallBackNonSkinnedCompressed, &updateData); - }else -#endif if(doRender){ if(clumpData->frames[0].flag & AnimBlendFrameData::UPDATE_KEYFRAMES) RpAnimBlendNodeUpdateKeyframes(clumpData->frames, &updateData, clumpData->numFrames); diff --git a/miami/animation/RpAnimBlend.h b/miami/animation/RpAnimBlend.h index 6e9e0f0f..d0f7a114 100644 --- a/miami/animation/RpAnimBlend.h +++ b/miami/animation/RpAnimBlend.h @@ -43,6 +43,3 @@ extern CAnimBlendClumpData *gpAnimBlendClump; void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg); void FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg); - -void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg); -void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg); diff --git a/miami/peds/PedAI.cpp b/miami/peds/PedAI.cpp index e204dad9..22c7b165 100644 --- a/miami/peds/PedAI.cpp +++ b/miami/peds/PedAI.cpp @@ -4890,133 +4890,111 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) CAnimBlendHierarchy *enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_STD_JACKEDCAR_LHS)->hierarchy; CAnimBlendSequence *seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedDraggedOutCarAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedDraggedOutCarAnimOffset = lastFrame->translation; + vecPedDraggedOutCarAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LHS)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedCarDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedCarDoorAnimOffset = lastFrame->translation; + vecPedCarDoorAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_STD_CAR_GET_IN_LO_LHS)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedCarDoorLoAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedCarDoorLoAnimOffset = lastFrame->translation; + vecPedCarDoorLoAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_STD_QUICKJACKED)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedQuickDraggedOutCarAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedQuickDraggedOutCarAnimOffset = lastFrame->translation; + vecPedQuickDraggedOutCarAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_VAN, ANIM_STD_VAN_GET_IN_REAR_LHS)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedVanRearDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedVanRearDoorAnimOffset = lastFrame->translation; + vecPedVanRearDoorAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_STD_TRAIN_GETOUT)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedTrainDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedTrainDoorAnimOffset = lastFrame->translation; + vecPedTrainDoorAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_STANDARD, ANIM_BIKE_JUMPON_LHS)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedStdBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedStdBikeJumpRhsAnimOffset = lastFrame->translation; + vecPedStdBikeJumpRhsAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_VESPA, ANIM_BIKE_JUMPON_LHS)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedVespaBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedVespaBikeJumpRhsAnimOffset = lastFrame->translation; + vecPedVespaBikeJumpRhsAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_HARLEY, ANIM_BIKE_JUMPON_LHS)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedHarleyBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedHarleyBikeJumpRhsAnimOffset = lastFrame->translation; + vecPedHarleyBikeJumpRhsAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_DIRT, ANIM_BIKE_JUMPON_LHS)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedDirtBikeJumpRhsAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedDirtBikeJumpRhsAnimOffset = lastFrame->translation; + vecPedDirtBikeJumpRhsAnimOffset = seq->GetTranslation(seq->numFrames - 1); } } enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_HARLEY, ANIM_BIKE_KICK)->hierarchy; seq = enterAssoc->sequences; - CAnimManager::UncompressAnimation(enterAssoc); if (seq->numFrames > 0) { if (!seq->HasTranslation()) vecPedBikeKickAnimOffset = CVector(0.0f, 0.0f, 0.0f); else { - KeyFrameTrans* lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1); - vecPedBikeKickAnimOffset = lastFrame->translation; + vecPedBikeKickAnimOffset = seq->GetTranslation(seq->numFrames - 1); } }