diff --git a/miami/animation/AnimBlendAssociation.cpp b/miami/animation/AnimBlendAssociation.cpp index 5558f434..4ba1a676 100644 --- a/miami/animation/AnimBlendAssociation.cpp +++ b/miami/animation/AnimBlendAssociation.cpp @@ -41,12 +41,14 @@ CAnimBlendAssociation::~CAnimBlendAssociation(void) link.Remove(); } - +static unsigned ndcount = 0; void CAnimBlendAssociation::AllocateAnimBlendNodeArray(int n) { int i; + ndcount += numNodes; + fprintf(stderr, "ndcount = %d, %lu, %lu\n", ndcount, sizeof(CAnimBlendNode), sizeof(CAnimBlendPlayer)); nodes = (CAnimBlendNode*)RwMallocAlign(n*sizeof(CAnimBlendNode), 64); for(i = 0; i < n; i++) nodes[i].Init(); @@ -55,8 +57,12 @@ CAnimBlendAssociation::AllocateAnimBlendNodeArray(int n) void CAnimBlendAssociation::FreeAnimBlendNodeArray(void) { - if(nodes) + if(nodes) { + ndcount -= numNodes; + for(unsigned i = 0; i < numNodes; i++) + nodes[i].Destroy(); RwFreeAlign(nodes); + } } void diff --git a/miami/animation/AnimBlendNode.cpp b/miami/animation/AnimBlendNode.cpp index a3ce80c9..c6f36b42 100644 --- a/miami/animation/AnimBlendNode.cpp +++ b/miami/animation/AnimBlendNode.cpp @@ -11,16 +11,24 @@ CAnimBlendNode::Init(void) remainingTime = 0.0f; sequence = nil; association = nil; + player = nil; } void CAnimBlendNode::Setup() { - player.Init(sequence->keyFrames, sequence->type, sequence->numFrames); + player = nil; + // player->Init(sequence->keyFrames, sequence->type, sequence->numFrames); +} +void CAnimBlendNode::Destroy() { + if (player) { + delete player; + player = nil; + } } bool CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight) { - assert (player.keyFrames == sequence->keyFrames); + assert (player->keyFrames == sequence->keyFrames); bool looped = false; @@ -35,17 +43,17 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight) float blend = association->GetBlendAmount(weight); if(blend > 0.0f){ - float kfAdt = player.GetDeltaTime(frameA); + float kfAdt = player->GetDeltaTime(frameA); float t = kfAdt == 0.0f ? 0.0f : (kfAdt - remainingTime)/kfAdt; - if(player.type & CAnimBlendSequence::KF_TRANS){ - auto kfAt = player.GetTranslation(frameA); - auto kfBt = player.GetTranslation(frameB); + if(player->type & CAnimBlendSequence::KF_TRANS){ + auto kfAt = player->GetTranslation(frameA); + auto kfBt = player->GetTranslation(frameB); trans = kfBt + t*(kfAt - kfBt); trans *= blend; } - if(player.type & CAnimBlendSequence::KF_ROT){ - auto kfAr = player.GetRotation(frameA); - auto kfBr = player.GetRotation(frameB); + if(player->type & CAnimBlendSequence::KF_ROT){ + auto kfAr = player->GetRotation(frameA); + auto kfBr = player->GetRotation(frameB); rot.Slerp(kfBr, kfAr, theta, invSin, t); rot *= blend; } @@ -58,9 +66,10 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight) bool CAnimBlendNode::NextKeyFrame(void) { + assert(player != nil); bool looped; - if(player.numFrames <= 1) + if(player->numFrames <= 1) return false; looped = false; @@ -70,33 +79,33 @@ CAnimBlendNode::NextKeyFrame(void) while(remainingTime <= 0.0f){ frameA++; - if(frameA >= player.numFrames){ + if(frameA >= player->numFrames){ // reached end of animation if(!association->IsRepeating()){ frameA--; frameB = frameA - 1; if(frameB < 0) - frameB += player.numFrames; + frameB += player->numFrames; remainingTime = 0.0f; // // range chekcs - // auto kfAt = player.GetTranslation(frameA); - // auto kfBt = player.GetTranslation(frameB); + // auto kfAt = player->GetTranslation(frameA); + // auto kfBt = player->GetTranslation(frameB); return false; } looped = true; frameA = 0; } - player.AdvanceFrame(); - remainingTime += player.GetDeltaTime(frameA); + player->AdvanceFrame(); + remainingTime += player->GetDeltaTime(frameA); } frameB = frameA - 1; if(frameB < 0) - frameB += player.numFrames; + frameB += player->numFrames; // // range chekcs - // auto kfAt = player.GetTranslation(frameA); - // auto kfBt = player.GetTranslation(frameB); + // auto kfAt = player->GetTranslation(frameA); + // auto kfBt = player->GetTranslation(frameB); CalcDeltas(); return looped; @@ -106,30 +115,34 @@ CAnimBlendNode::NextKeyFrame(void) bool CAnimBlendNode::FindKeyFrame(float t) { - if(player.numFrames < 1) + if (player == nil) { + player = new CAnimBlendPlayer(); + player->Init(sequence->keyFrames, sequence->type, sequence->numFrames); + } + if(player->numFrames < 1) return false; frameA = 0; frameB = frameA; - player.SeekToStart(); + player->SeekToStart(); - assert (player.keyFrames == sequence->keyFrames); + assert (player->keyFrames == sequence->keyFrames); - if(player.numFrames == 1){ + if(player->numFrames == 1){ remainingTime = 0.0f; }else{ // advance until t is between frameB and frameA frameA++; - player.AdvanceFrame(); - while (t > player.GetDeltaTime(frameA)) { - t -= player.GetDeltaTime(frameA); - if (frameA + 1 >= player.numFrames) { + player->AdvanceFrame(); + while (t > player->GetDeltaTime(frameA)) { + t -= player->GetDeltaTime(frameA); + if (frameA + 1 >= player->numFrames) { // reached end of animation if (!association->IsRepeating()) { frameA --; // // range chekcs - // auto kfAt = player.GetTranslation(frameA); - // auto kfBt = player.GetTranslation(frameB); + // auto kfAt = player->GetTranslation(frameA); + // auto kfBt = player->GetTranslation(frameB); CalcDeltas(); remainingTime = 0.0f; return false; @@ -137,16 +150,16 @@ CAnimBlendNode::FindKeyFrame(float t) frameA = 0; } frameB = frameA; - player.AdvanceFrame(); + player->AdvanceFrame(); frameA++; } - remainingTime = player.GetDeltaTime(frameA) - t; + remainingTime = player->GetDeltaTime(frameA) - t; } // // range chekcs - // auto kfAt = player.GetTranslation(frameA); - // auto kfBt = player.GetTranslation(frameB); + // auto kfAt = player->GetTranslation(frameA); + // auto kfBt = player->GetTranslation(frameB); CalcDeltas(); return true; @@ -155,10 +168,10 @@ CAnimBlendNode::FindKeyFrame(float t) void CAnimBlendNode::CalcDeltas(void) { - if((player.type & CAnimBlendSequence::KF_ROT) == 0) + if((player->type & CAnimBlendSequence::KF_ROT) == 0) return; - auto kfAr = player.GetRotation(frameA); - auto kfBr = player.GetRotation(frameB); + auto kfAr = player->GetRotation(frameA); + auto kfBr = player->GetRotation(frameB); float cos = DotProduct(kfAr, kfBr); if(cos > 1.0f) cos = 1.0f; @@ -173,11 +186,11 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight) float blend = association->GetBlendAmount(weight); if(blend > 0.0f){ - auto kfAdt = player.GetDeltaTime(frameA); + auto kfAdt = player->GetDeltaTime(frameA); float t = kfAdt == 0.0f ? 0.0f : (kfAdt - remainingTime)/kfAdt; - if(player.type & CAnimBlendSequence::KF_TRANS){ - auto kfAt = player.GetTranslation(frameA); - auto kfBt = player.GetTranslation(frameB); + if(player->type & CAnimBlendSequence::KF_TRANS){ + auto kfAt = player->GetTranslation(frameA); + auto kfBt = player->GetTranslation(frameB); trans = kfBt + t*(kfAt - kfBt); trans *= blend; } @@ -192,7 +205,7 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight) float blend = association->GetBlendAmount(weight); if(blend > 0.0f){ - if(player.type & CAnimBlendSequence::KF_TRANS){ + if(player->type & CAnimBlendSequence::KF_TRANS){ CVector pos = sequence->GetEndTranslation(); trans = pos * blend; } diff --git a/miami/animation/AnimBlendNode.h b/miami/animation/AnimBlendNode.h index 2396c913..e9a2cd8d 100644 --- a/miami/animation/AnimBlendNode.h +++ b/miami/animation/AnimBlendNode.h @@ -15,7 +15,7 @@ public: int32 frameA; // next key frame int32 frameB; // previous key frame float remainingTime; // time until frames have to advance - CAnimBlendPlayer player; + CAnimBlendPlayer* player; CAnimBlendSequence *sequence; CAnimBlendAssociation *association; @@ -28,6 +28,7 @@ public: void GetEndTranslation(CVector &trans, float weight); void Setup(); + void Destroy(); }; diff --git a/miami/animation/AnimBlendSequence.cpp b/miami/animation/AnimBlendSequence.cpp index 00b5e0c6..fc0d5a9d 100644 --- a/miami/animation/AnimBlendSequence.cpp +++ b/miami/animation/AnimBlendSequence.cpp @@ -41,6 +41,8 @@ CAnimBlendSequence::SetName(char *name) // } // } +unsigned CAnimBlendPlayer::count = 0; + #ifdef USE_CUSTOM_ALLOCATOR bool CAnimBlendSequence::MoveMemory(void) diff --git a/miami/animation/AnimBlendSequence.h b/miami/animation/AnimBlendSequence.h index cf10bb41..e52883d0 100644 --- a/miami/animation/AnimBlendSequence.h +++ b/miami/animation/AnimBlendSequence.h @@ -41,6 +41,16 @@ struct CAnimBlendPlayer { float predicted_tx = 0, predicted_ty = 0, predicted_tz = 0; float nextDeltaTime; + static unsigned count; + + CAnimBlendPlayer() { + count++; + fprintf(stderr, "CAnimBlendPlayer count %d\n", count); + } + ~CAnimBlendPlayer() { + count--; + } + template T read() { T rv;