Ticket #4270: fix-visualactor-save-reload.2.patch
File fix-visualactor-save-reload.2.patch, 6.9 KB (added by , 8 years ago) |
---|
-
source/simulation2/components/CCmpVisualActor.cpp
81 81 std::wstring m_SoundGroup; 82 82 fixed m_AnimDesync; 83 83 fixed m_AnimSyncRepeatTime; // 0.0 if not synced 84 fixed m_AnimSyncOffsetTime; 84 85 85 86 std::map<CStr, CStr> m_VariantSelections; 86 87 … … 205 206 206 207 InitModel(paramNode); 207 208 208 // We need to select animation even if graphics are disabled, as this modifies serialized state209 209 SelectAnimation("idle", false, fixed::FromInt(1), L""); 210 210 } 211 211 … … 232 232 serialize.String("sound group", m_SoundGroup, 0, 256); 233 233 serialize.NumberFixed_Unbounded("anim desync", m_AnimDesync); 234 234 serialize.NumberFixed_Unbounded("anim sync repeat time", m_AnimSyncRepeatTime); 235 serialize.NumberFixed_Unbounded("anim sync offset time", m_AnimSyncOffsetTime); 235 236 236 237 SerializeMap<SerializeString, SerializeString>()(serialize, "variation", m_VariantSelections); 237 238 … … 264 265 // If we serialized a different seed or different actor, reload actor 265 266 if (oldSeed != GetActorSeed() || m_BaseActorName != m_ActorName) 266 267 ReloadActor(); 267 else if (m_Unit)268 m_Unit->SetEntitySelection(m_VariantSelections);269 270 fixed repeattime = m_AnimSyncRepeatTime; // save because SelectAnimation overwrites it271 272 if (m_AnimRunThreshold.IsZero())273 SelectAnimation(m_AnimName, m_AnimOnce, m_AnimSpeed, m_SoundGroup);274 268 else 275 SelectMovementAnimation(m_AnimRunThreshold);269 ReloadUnitAnimation(); 276 270 277 SetAnimationSyncRepeat(repeattime);278 279 271 if (m_Unit) 280 272 { 281 273 CmpPtr<ICmpOwnership> cmpOwnership(GetEntityHandle()); … … 287 279 virtual void HandleMessage(const CMessage& msg, bool UNUSED(global)) 288 280 { 289 281 // Quick exit for running in non-graphical mode 290 if ( m_Unit == NULL)282 if (!m_Unit) 291 283 return; 292 284 293 285 switch (msg.GetType()) … … 457 449 458 450 virtual void SelectMovementAnimation(fixed runThreshold) 459 451 { 452 SelectAnimation("walk", false, fixed::FromFloat(1.f), L""); 460 453 m_AnimRunThreshold = runThreshold; 461 462 if (m_Unit)463 {464 SetVariant("animation", "walk");465 if (m_Unit->GetAnimation())466 m_Unit->GetAnimation()->SetAnimationState("walk", false, 1.f, 0.f, L"");467 }468 454 } 469 455 470 456 virtual void SetAnimationSyncRepeat(fixed repeattime) … … 480 466 481 467 virtual void SetAnimationSyncOffset(fixed actiontime) 482 468 { 469 m_AnimSyncOffsetTime = actiontime; 470 483 471 if (m_Unit) 484 472 { 485 473 if (m_Unit->GetAnimation()) 486 m_Unit->GetAnimation()->SetAnimationSyncOffset( actiontime.ToFloat());474 m_Unit->GetAnimation()->SetAnimationSyncOffset(m_AnimSyncOffsetTime.ToFloat()); 487 475 } 488 476 } 489 477 … … 546 534 /// Helper method; initializes the model selection shape descriptor from XML. Factored out for readability of @ref Init. 547 535 void InitSelectionShapeDescriptor(const CParamNode& paramNode); 548 536 537 // ReloadActor is used when the actor or seed changes. 549 538 void ReloadActor(); 539 // ReloadUnitAnimation is used for a minimal reloading upon deserialization, when the actor and seed are identical. 540 // It is also used by ReloadActor. 541 void ReloadUnitAnimation(); 550 542 551 543 void Update(fixed turnLength); 552 544 }; … … 720 712 721 713 InitModel(node->GetChild("VisualActor")); 722 714 723 m_Unit->SetEntitySelection(m_VariantSelections);715 ReloadUnitAnimation(); 724 716 725 if (m_Unit->GetAnimation())726 m_Unit->GetAnimation()->SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed.ToFloat(), m_AnimDesync.ToFloat(), m_SoundGroup.c_str());727 728 // We'll lose the exact synchronisation but we should at least make sure it's going at the correct rate729 if (!m_AnimSyncRepeatTime.IsZero())730 if (m_Unit->GetAnimation())731 m_Unit->GetAnimation()->SetAnimationSyncRepeat(m_AnimSyncRepeatTime.ToFloat());732 733 717 m_Unit->GetModel().SetShadingColor(shading); 734 718 735 719 m_Unit->GetModel().SetPlayerID(playerID); … … 743 727 } 744 728 } 745 729 746 void CCmpVisualActor:: Update(fixed UNUSED(turnLength))730 void CCmpVisualActor::ReloadUnitAnimation() 747 731 { 748 732 if (!m_Unit) 749 733 return; 750 734 751 // If we're in the special movement mode, select an appropriate animation 752 if (!m_AnimRunThreshold.IsZero()) 753 { 754 CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle()); 755 if (!cmpPosition || !cmpPosition->IsInWorld()) 756 return; 735 m_Unit->SetEntitySelection(m_VariantSelections); 757 736 758 CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetEntityHandle()); 759 if (!cmpUnitMotion) 760 return; 737 if (!m_Unit->GetAnimation()) 738 return; 761 739 762 float speed = cmpUnitMotion->GetCurrentSpeed().ToFloat();740 m_Unit->GetAnimation()->SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed.ToFloat(), m_AnimDesync.ToFloat(), m_SoundGroup.c_str()); 763 741 764 std::string name; 765 if (speed == 0.0f) 766 name = "idle"; 767 else 768 name = (speed < m_AnimRunThreshold.ToFloat()) ? "walk" : "run"; 742 // We'll lose the exact synchronisation but we should at least make sure it's going at the correct rate 743 if (!m_AnimSyncRepeatTime.IsZero()) 744 m_Unit->GetAnimation()->SetAnimationSyncRepeat(m_AnimSyncRepeatTime.ToFloat()); 745 if (!m_AnimSyncOffsetTime.IsZero()) 746 m_Unit->GetAnimation()->SetAnimationSyncOffset(m_AnimSyncOffsetTime.ToFloat()); 747 } 769 748 770 std::map<std::string, std::string>::const_iterator it = m_AnimOverride.find(name); 771 if (it != m_AnimOverride.end()) 772 name = it->second; 749 void CCmpVisualActor::Update(fixed UNUSED(turnLength)) 750 { 751 // This function is currently only used to update the animation if the speed in 752 // CCmpUnitMotion changes. This also only happens in the "special movement mode" 753 // triggered by SelectMovementAnimation. 773 754 774 SetVariant("animation", name); 775 if (m_Unit->GetAnimation()) 776 { 777 if (speed == 0.0f) 778 m_Unit->GetAnimation()->SetAnimationState(name, false, 1.f, 0.f, L""); 779 else 780 m_Unit->GetAnimation()->SetAnimationState(name, false, speed, 0.f, L""); 781 } 755 // TODO: This should become event based, in order to save performance and to make the code 756 // far less hacky. We should also take into account the speed when the animation is different 757 // from the "special movement mode" walking animation. 758 759 // If we're not in the special movement mode, nothing to do. 760 if (m_AnimRunThreshold.IsZero()) 761 return; 762 763 CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle()); 764 if (!cmpPosition || !cmpPosition->IsInWorld()) 765 return; 766 767 CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetEntityHandle()); 768 if (!cmpUnitMotion) 769 return; 770 771 fixed speed = cmpUnitMotion->GetCurrentSpeed(); 772 std::string name; 773 774 if (speed.IsZero()) 775 { 776 speed = fixed::FromFloat(1.f); 777 name = "idle"; 782 778 } 779 else 780 name = (speed < m_AnimRunThreshold) ? "walk" : "run"; 781 782 std::map<std::string, std::string>::const_iterator it = m_AnimOverride.find(name); 783 if (it != m_AnimOverride.end()) 784 name = it->second; 785 786 // Selecting the animation is going to reset the anim run threshold, so save it 787 fixed runThreshold = m_AnimRunThreshold; 788 SelectAnimation(name, false, speed, L""); 789 m_AnimRunThreshold = runThreshold; 783 790 }