Skip to content

Commit b029747

Browse files
authored
Merge pull request #86 from Andreas-W/animation_blending
Animation blending memory leak fixes
2 parents bb83868 + 856a79b commit b029747

2 files changed

Lines changed: 129 additions & 103 deletions

File tree

  • Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw
  • GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2

Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,47 +2396,47 @@ void W3DModelDraw::adjustAnimation(const ModelConditionInfo* prevState, Real pre
23962396

23972397
// ANIMATION BLENDING
23982398
if (prevState &&
2399-
m_curState->m_animBlendTime > 0 &&
2400-
prevState->m_animations[0].getAnimHandle() &&
2401-
m_renderObject->Class_ID() == RenderObjClass::CLASSID_HLOD) {
2399+
m_curState->m_animBlendTime > 0) {
24022400

2403-
//DEBUG_LOG((">>>>BLEND ANIMS!!"));
2401+
const W3DAnimationInfo& animInfoPrev = prevState->m_animations[m_whichAnimInPrevState];
2402+
HAnimClass* animHandlePrev = animInfoPrev.getAnimHandle();
24042403

2405-
HLodClass* hlod = (HLodClass*)m_renderObject;
2404+
if (animHandlePrev != nullptr && m_renderObject->Class_ID() == RenderObjClass::CLASSID_HLOD) {
24062405

2407-
const W3DAnimationInfo& animInfoPrev = prevState->m_animations[m_whichAnimInPrevState];
2406+
//DEBUG_LOG((">>>>BLEND ANIMS!!"));
24082407

2409-
HAnimClass* animHandlePrev = animInfoPrev.getAnimHandle();
2408+
HLodClass* hlod = (HLodClass*)m_renderObject;
24102409

2411-
Real factor = GameClientRandomValueReal(m_curState->m_animMinSpeedFactor, m_curState->m_animMaxSpeedFactor);
2410+
Real factor = GameClientRandomValueReal(m_curState->m_animMinSpeedFactor, m_curState->m_animMaxSpeedFactor);
24122411

2413-
Int startFramePrev = REAL_TO_INT(prevAnimFraction * m_prevAnimHelper.numFrames - 1);
2412+
Int startFramePrev = REAL_TO_INT(prevAnimFraction * m_prevAnimHelper.numFrames - 1);
24142413

2415-
// maxBlendTime = currentAnim duration in milliseconds
2416-
Int animBlendTime = m_curState->m_animBlendTime;
2417-
Int curAnimDurMS = REAL_TO_INT((animHandle->Get_Num_Frames() * 1000.0f / animHandle->Get_Frame_Rate()) * factor);
2418-
if (animBlendTime > curAnimDurMS) {
2419-
animBlendTime = curAnimDurMS;
2414+
// maxBlendTime = currentAnim duration in milliseconds
2415+
Int animBlendTime = m_curState->m_animBlendTime;
2416+
Int curAnimDurMS = REAL_TO_INT((animHandle->Get_Num_Frames() * 1000.0f / animHandle->Get_Frame_Rate()) * factor);
2417+
if (animBlendTime > curAnimDurMS) {
2418+
animBlendTime = curAnimDurMS;
2419+
}
2420+
hlod->Set_Animation(
2421+
animHandle,
2422+
startFrame,
2423+
animHandlePrev,
2424+
startFramePrev,
2425+
1.0f, //We start with prev anim and fade into the new anim
2426+
m_curState->m_mode,
2427+
m_prevAnimHelper.mode,
2428+
animBlendTime
2429+
);
2430+
// Let's ignore speed factor for prev anim for now
2431+
// We need to find out when the prev anim is supposed to fade out:
2432+
2433+
hlod->Set_Animation_Frame_Rate_Multiplier(factor); //This might need to be different
24202434
}
2421-
hlod->Set_Animation(
2422-
animHandle,
2423-
startFrame,
2424-
animHandlePrev,
2425-
startFramePrev,
2426-
1.0f, //We start with prev anim and fade into the new anim
2427-
m_curState->m_mode,
2428-
m_prevAnimHelper.mode,
2429-
animBlendTime
2430-
);
2435+
24312436
REF_PTR_RELEASE(animHandle);
24322437
REF_PTR_RELEASE(animHandlePrev);
24332438
animHandle = NULL;
24342439
animHandlePrev = NULL;
2435-
2436-
// Let's ignore speed factor for prev anim for now
2437-
// We need to find out when the prev anim is supposed to fade out:
2438-
2439-
hlod->Set_Animation_Frame_Rate_Multiplier(factor); //This might need to be different
24402440
}
24412441
else {
24422442
m_renderObject->Set_Animation(animHandle, startFrame, m_curState->m_mode);

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/animobj.cpp

Lines changed: 100 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -559,35 +559,47 @@ void Animatable3DObjClass::Set_Animation
559559
float percentage
560560
)
561561
{
562-
Release();
563-
564-
CurMotionMode = DOUBLE_ANIM;
565-
ModeInterp.Motion0 = motion0;
566-
ModeInterp.Motion1 = motion1;
567-
ModeInterp.PrevFrame0 = ModeInterp.Frame0;
568-
ModeInterp.PrevFrame1 = ModeInterp.Frame1;
569-
ModeInterp.Frame0 = frame0;
570-
ModeInterp.Frame1 = frame1;
571-
ModeInterp.Percentage = percentage;
572-
Set_Hierarchy_Valid(false);
562+
if ((motion0) && (motion1)) {
563+
motion0->Add_Ref();
564+
motion1->Add_Ref();
565+
Release();
566+
CurMotionMode = DOUBLE_ANIM;
567+
ModeInterp.Motion0 = motion0;
568+
ModeInterp.Motion1 = motion1;
569+
ModeInterp.PrevFrame0 = ModeInterp.Frame0;
570+
ModeInterp.PrevFrame1 = ModeInterp.Frame1;
571+
ModeInterp.Frame0 = frame0;
572+
ModeInterp.Frame1 = frame1;
573+
ModeInterp.Percentage = percentage;
574+
ModeInterp.LastSyncTime = WW3D::Get_Logic_Time_Milliseconds();
575+
//Set_Hierarchy_Valid(false);
573576

574-
if ( ModeInterp.Motion0 != nullptr ) {
575-
ModeInterp.Motion0->Add_Ref();
576-
const char* sound_name = AnimatedSoundMgrClass::Get_Embedded_Sound_Name(motion0);
577-
if (sound_name) {
578-
int bone_index = Get_Bone_Index(sound_name);
579-
motion0->Set_Embedded_Sound_Bone_Index(bone_index);
577+
//if ( ModeInterp.Motion0 != nullptr )
578+
{
579+
//ModeInterp.Motion0->Add_Ref();
580+
const char* sound_name = AnimatedSoundMgrClass::Get_Embedded_Sound_Name(motion0);
581+
if (sound_name) {
582+
int bone_index = Get_Bone_Index(sound_name);
583+
motion0->Set_Embedded_Sound_Bone_Index(bone_index);
584+
}
580585
}
581-
}
582586

583-
if ( ModeInterp.Motion1 != nullptr ) {
584-
ModeInterp.Motion1->Add_Ref();
585-
const char* sound_name = AnimatedSoundMgrClass::Get_Embedded_Sound_Name(motion1);
586-
if (sound_name) {
587-
int bone_index = Get_Bone_Index(sound_name);
588-
motion1->Set_Embedded_Sound_Bone_Index(bone_index);
587+
//if ( ModeInterp.Motion1 != nullptr )
588+
{
589+
//ModeInterp.Motion1->Add_Ref();
590+
const char* sound_name = AnimatedSoundMgrClass::Get_Embedded_Sound_Name(motion1);
591+
if (sound_name) {
592+
int bone_index = Get_Bone_Index(sound_name);
593+
motion1->Set_Embedded_Sound_Bone_Index(bone_index);
594+
}
589595
}
590596
}
597+
else {
598+
CurMotionMode = BASE_POSE;
599+
Release();
600+
}
601+
602+
Set_Hierarchy_Valid(false);
591603
}
592604

593605

@@ -608,60 +620,72 @@ void Animatable3DObjClass::Set_Animation
608620
//DEBUG_LOG2((">>> animobj.cpp - Set_Animation DOUBLE_ANIM - with mode0 '%d' and mode1 '%d'\n", mode0, mode1));
609621
Release();
610622

611-
CurMotionMode = DOUBLE_ANIM;
612-
ModeInterp.Motion0 = motion0;
613-
ModeInterp.Motion1 = motion1;
614-
ModeInterp.PrevFrame0 = ModeInterp.Frame0;
615-
ModeInterp.PrevFrame1 = ModeInterp.Frame1;
616-
ModeInterp.Frame0 = frame0;
617-
ModeInterp.Frame1 = frame1;
618-
ModeInterp.Percentage = percentage;
619-
ModeInterp.LastSyncTime = WW3D::Get_Sync_Time();
620-
ModeInterp.frameRateMultiplier0 = 1.0;
621-
ModeInterp.animDirection0 = 1.0;
622-
ModeInterp.frameRateMultiplier1 = 1.0;
623-
ModeInterp.animDirection1 = 1.0;
624-
ModeInterp.FadeOutTime = fadeOutTime; // This should be in milliseconds
625-
if (startFadeTime == 0) {
626-
ModeInterp.StartFadeTime = ModeInterp.LastSyncTime;
627-
}
628-
else {
629-
ModeInterp.StartFadeTime = startFadeTime;
630-
}
631-
632-
ModeInterp.AnimMode0 = mode0;
633-
ModeInterp.AnimMode1 = mode1;
634-
635-
if (mode0 < ANIM_MODE_LOOP_BACKWARDS)
636-
ModeInterp.animDirection0 = 1.0f; //assume playing forwards
637-
else
638-
ModeInterp.animDirection0 = -1.0f; //reverse animation playback
623+
if ((motion0) && (motion1)) {
624+
motion0->Add_Ref();
625+
motion1->Add_Ref();
626+
Release();
627+
CurMotionMode = DOUBLE_ANIM;
628+
ModeInterp.Motion0 = motion0;
629+
ModeInterp.Motion1 = motion1;
630+
ModeInterp.PrevFrame0 = ModeInterp.Frame0;
631+
ModeInterp.PrevFrame1 = ModeInterp.Frame1;
632+
ModeInterp.Frame0 = frame0;
633+
ModeInterp.Frame1 = frame1;
634+
ModeInterp.Percentage = percentage;
635+
ModeInterp.LastSyncTime = WW3D::Get_Sync_Time();
636+
ModeInterp.frameRateMultiplier0 = 1.0;
637+
ModeInterp.animDirection0 = 1.0;
638+
ModeInterp.frameRateMultiplier1 = 1.0;
639+
ModeInterp.animDirection1 = 1.0;
640+
ModeInterp.FadeOutTime = fadeOutTime; // This should be in milliseconds
641+
if (startFadeTime == 0) {
642+
ModeInterp.StartFadeTime = ModeInterp.LastSyncTime;
643+
}
644+
else {
645+
ModeInterp.StartFadeTime = startFadeTime;
646+
}
639647

640-
if (mode1 < ANIM_MODE_LOOP_BACKWARDS)
641-
ModeInterp.animDirection1 = 1.0f; //assume playing forwards
642-
else
643-
ModeInterp.animDirection1 = -1.0f; //reverse animation playback
648+
ModeInterp.AnimMode0 = mode0;
649+
ModeInterp.AnimMode1 = mode1;
644650

651+
if (mode0 < ANIM_MODE_LOOP_BACKWARDS)
652+
ModeInterp.animDirection0 = 1.0f; //assume playing forwards
653+
else
654+
ModeInterp.animDirection0 = -1.0f; //reverse animation playback
645655

646-
Set_Hierarchy_Valid(false);
656+
if (mode1 < ANIM_MODE_LOOP_BACKWARDS)
657+
ModeInterp.animDirection1 = 1.0f; //assume playing forwards
658+
else
659+
ModeInterp.animDirection1 = -1.0f; //reverse animation playback
647660

648-
if (ModeInterp.Motion0 != NULL) {
649-
ModeInterp.Motion0->Add_Ref();
650-
const char* sound_name = AnimatedSoundMgrClass::Get_Embedded_Sound_Name(motion0);
651-
if (sound_name) {
652-
int bone_index = Get_Bone_Index(sound_name);
653-
motion0->Set_Embedded_Sound_Bone_Index(bone_index);
661+
//if (ModeInterp.Motion0 != NULL)
662+
{
663+
//ModeInterp.Motion0->Add_Ref();
664+
const char* sound_name = AnimatedSoundMgrClass::Get_Embedded_Sound_Name(motion0);
665+
if (sound_name) {
666+
int bone_index = Get_Bone_Index(sound_name);
667+
motion0->Set_Embedded_Sound_Bone_Index(bone_index);
668+
}
654669
}
655-
}
656670

657-
if (ModeInterp.Motion1 != NULL) {
658-
ModeInterp.Motion1->Add_Ref();
659-
const char* sound_name = AnimatedSoundMgrClass::Get_Embedded_Sound_Name(motion1);
660-
if (sound_name) {
661-
int bone_index = Get_Bone_Index(sound_name);
662-
motion1->Set_Embedded_Sound_Bone_Index(bone_index);
671+
//if (ModeInterp.Motion1 != NULL)
672+
{
673+
//ModeInterp.Motion1->Add_Ref();
674+
const char* sound_name = AnimatedSoundMgrClass::Get_Embedded_Sound_Name(motion1);
675+
if (sound_name) {
676+
int bone_index = Get_Bone_Index(sound_name);
677+
motion1->Set_Embedded_Sound_Bone_Index(bone_index);
678+
}
663679
}
664680
}
681+
else {
682+
CurMotionMode = BASE_POSE;
683+
Release();
684+
}
685+
686+
687+
Set_Hierarchy_Valid(false);
688+
665689
}
666690

667691

@@ -897,8 +921,8 @@ void Animatable3DObjClass::Update_Sub_Object_Transforms(void)
897921
*/
898922
CompositeRenderObjClass::Update_Sub_Object_Transforms();
899923

900-
HRawAnimClass* motion0 = nullptr;
901-
HRawAnimClass* motion1 = nullptr;
924+
//HRawAnimClass* motion0 = nullptr;
925+
//HRawAnimClass* motion1 = nullptr;
902926

903927
/*
904928
** Update the transforms
@@ -1221,7 +1245,7 @@ float Animatable3DObjClass::Compute_Current_Frame(float* newFrame0, float* newFr
12211245
}
12221246
break;
12231247
}
1224-
1248+
return 0;
12251249
}
12261250

12271251
float Animatable3DObjClass::Compute_Current_Frame_For_Anim(HAnimClass* anim, int animMode, float frame, float& direction) const {
@@ -1284,7 +1308,7 @@ float Animatable3DObjClass::Compute_Current_Frame_For_Anim(HAnimClass* anim, int
12841308
return frame;
12851309
}
12861310

1287-
1311+
// -------------------------
12881312
float Animatable3DObjClass::Compute_Current_Percentage() const
12891313
{
12901314
if (CurMotionMode == SINGLE_ANIM) {
@@ -1305,6 +1329,7 @@ float Animatable3DObjClass::Compute_Current_Percentage() const
13051329
}
13061330
return 0.0f;
13071331
}
1332+
return 0.0f;
13081333
}
13091334

13101335
/***********************************************************************************************
@@ -1459,6 +1484,7 @@ HAnimClass* Animatable3DObjClass::Peek_Animation_And_Info(float& frame0, int& nu
14591484

14601485
return ModeInterp.Motion0;
14611486
}
1487+
return nullptr;
14621488
//DEBUG_LOG2((">>> animobj.cpp - Peek_Animation_And_Info - Done'\n"));
14631489
}
14641490

0 commit comments

Comments
 (0)