MotionLayerSystemTests.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzTest/AzTest.h>
  9. #include <Tests/SystemComponentFixture.h>
  10. #include <TestAssetCode/ActorFactory.h>
  11. #include <TestAssetCode/SimpleActors.h>
  12. #include <EMotionFX/Source/Motion.h>
  13. #include <EMotionFX/Source/MotionData/UniformMotionData.h>
  14. #include <EMotionFX/Source/MotionSystem.h>
  15. namespace EMotionFX
  16. {
  17. using MotionLayerSystemFixture = SystemComponentFixture;
  18. TEST_F(MotionLayerSystemFixture, MotionInstanceDestroyedAfterMotionEnds)
  19. {
  20. auto actor = ActorFactory::CreateAndInit<SimpleJointChainActor>(5);
  21. ActorInstance* actorInstance = ActorInstance::Create(actor.get());
  22. Motion* motion1 = aznew Motion("motion1");
  23. motion1->SetMotionData(aznew UniformMotionData());
  24. motion1->GetMotionData()->SetDuration(10.0f);
  25. Motion* motion2 = aznew Motion("motion2");
  26. motion2->SetMotionData(aznew UniformMotionData());
  27. motion2->GetMotionData()->SetDuration(10.0f);
  28. MotionSystem* motionSystem = actorInstance->GetMotionSystem();
  29. PlayBackInfo playBackInfo;
  30. playBackInfo.m_blendInTime = 1.0f;
  31. playBackInfo.m_blendOutTime = 1.0f;
  32. playBackInfo.m_numLoops = 1;
  33. playBackInfo.m_playNow = false;
  34. playBackInfo.m_freezeAtLastFrame = false;
  35. // Add 2 motions to the queue
  36. const MotionInstance* motionInstance1 = motionSystem->PlayMotion(motion1, &playBackInfo);
  37. const MotionInstance* motionInstance2 = motionSystem->PlayMotion(motion2, &playBackInfo);
  38. GetEMotionFX().Update(0.0f);
  39. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 1);
  40. EXPECT_FLOAT_EQ(motionInstance1->GetWeight(), 0.0f);
  41. EXPECT_FLOAT_EQ(motionInstance2->GetWeight(), 0.0f);
  42. EXPECT_FLOAT_EQ(motionInstance1->GetCurrentTime(), 0.0f);
  43. EXPECT_FLOAT_EQ(motionInstance2->GetCurrentTime(), 0.0f);
  44. GetEMotionFX().Update(1.0f);
  45. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 1);
  46. EXPECT_FLOAT_EQ(motionInstance1->GetWeight(), 1.0f);
  47. EXPECT_FLOAT_EQ(motionInstance2->GetWeight(), 0.0f);
  48. EXPECT_FLOAT_EQ(motionInstance1->GetCurrentTime(), 1.0f);
  49. EXPECT_FLOAT_EQ(motionInstance2->GetCurrentTime(), 0.0f);
  50. GetEMotionFX().Update(8.0f); // time = 9.0f
  51. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 2);
  52. EXPECT_FLOAT_EQ(motionInstance1->GetWeight(), 1.0f);
  53. EXPECT_FLOAT_EQ(motionInstance2->GetWeight(), 0.0f);
  54. EXPECT_FLOAT_EQ(motionInstance1->GetCurrentTime(), 9.0f);
  55. EXPECT_FLOAT_EQ(motionInstance2->GetCurrentTime(), 0.0f);
  56. GetEMotionFX().Update(0.5f); // time = 9.5f
  57. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 2);
  58. EXPECT_FLOAT_EQ(motionInstance1->GetWeight(), 0.5f); // motion 1 started blending out at time 9.0f
  59. EXPECT_FLOAT_EQ(motionInstance2->GetWeight(), 0.5f);
  60. EXPECT_FLOAT_EQ(motionInstance1->GetCurrentTime(), 9.5f);
  61. EXPECT_FLOAT_EQ(motionInstance2->GetCurrentTime(), 0.5f);
  62. GetEMotionFX().Update(0.5f);
  63. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 1);
  64. EXPECT_FLOAT_EQ(motionInstance2->GetWeight(), 1.0f);
  65. EXPECT_FLOAT_EQ(motionInstance2->GetCurrentTime(), 1.0f);
  66. GetEMotionFX().Update(8.0f);
  67. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 1);
  68. EXPECT_FLOAT_EQ(motionInstance2->GetWeight(), 1.0f);
  69. EXPECT_FLOAT_EQ(motionInstance2->GetCurrentTime(), 9.0f);
  70. GetEMotionFX().Update(1.0f);
  71. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 0);
  72. motion2->Destroy();
  73. motion1->Destroy();
  74. actorInstance->Destroy();
  75. }
  76. TEST_F(MotionLayerSystemFixture, TransitionsBetweenMotions)
  77. {
  78. auto actor = ActorFactory::CreateAndInit<SimpleJointChainActor>(5);
  79. ActorInstance* actorInstance = ActorInstance::Create(actor.get());
  80. Motion* walk = aznew Motion("walk");
  81. walk->SetMotionData(aznew UniformMotionData());
  82. walk->GetMotionData()->SetDuration(10.0f);
  83. Motion* run = aznew Motion("run");
  84. run->SetMotionData(aznew UniformMotionData());
  85. run->GetMotionData()->SetDuration(10.0f);
  86. MotionSystem* motionSystem = actorInstance->GetMotionSystem();
  87. PlayBackInfo playBackInfo;
  88. playBackInfo.m_blendInTime = 1.0f;
  89. playBackInfo.m_blendOutTime = 1.0f;
  90. playBackInfo.m_numLoops = EMFX_LOOPFOREVER;
  91. playBackInfo.m_playNow = true;
  92. const MotionInstance* walkInstance = motionSystem->PlayMotion(walk, &playBackInfo);
  93. GetEMotionFX().Update(0.5f);
  94. GetEMotionFX().Update(0.5f);
  95. GetEMotionFX().Update(0.5f);
  96. GetEMotionFX().Update(0.5f);
  97. GetEMotionFX().Update(0.5f);
  98. GetEMotionFX().Update(0.5f);
  99. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 1);
  100. EXPECT_FLOAT_EQ(walkInstance->GetWeight(), 1.0f);
  101. const MotionInstance* runInstance = motionSystem->PlayMotion(run, &playBackInfo);
  102. GetEMotionFX().Update(0.25f);
  103. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 2);
  104. EXPECT_FLOAT_EQ(walkInstance->GetWeight(), 1.0f);
  105. EXPECT_FLOAT_EQ(runInstance->GetWeight(), 0.25f);
  106. GetEMotionFX().Update(0.25f);
  107. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 2);
  108. EXPECT_FLOAT_EQ(walkInstance->GetWeight(), 1.0f);
  109. EXPECT_FLOAT_EQ(runInstance->GetWeight(), 0.5f);
  110. GetEMotionFX().Update(0.25f);
  111. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 2);
  112. EXPECT_FLOAT_EQ(walkInstance->GetWeight(), 1.0f);
  113. EXPECT_FLOAT_EQ(runInstance->GetWeight(), 0.75f);
  114. GetEMotionFX().Update(0.25f);
  115. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 1);
  116. EXPECT_FLOAT_EQ(runInstance->GetWeight(), 1.0f);
  117. run->Destroy();
  118. walk->Destroy();
  119. actorInstance->Destroy();
  120. }
  121. TEST_F(MotionLayerSystemFixture, StopAllMotionsRemovesAllMotionInstances)
  122. {
  123. auto actor = ActorFactory::CreateAndInit<SimpleJointChainActor>(5);
  124. ActorInstance* actorInstance = ActorInstance::Create(actor.get());
  125. Motion* motion1 = aznew Motion("motion1");
  126. motion1->SetMotionData(aznew UniformMotionData());
  127. motion1->GetMotionData()->SetDuration(10.0f);
  128. Motion* motion2 = aznew Motion("motion2");
  129. motion2->SetMotionData(aznew UniformMotionData());
  130. motion2->GetMotionData()->SetDuration(10.0f);
  131. MotionSystem* motionSystem = actorInstance->GetMotionSystem();
  132. PlayBackInfo playBackInfo;
  133. playBackInfo.m_blendInTime = 1.0f;
  134. playBackInfo.m_blendOutTime = 1.0f;
  135. playBackInfo.m_numLoops = 1;
  136. playBackInfo.m_playNow = false;
  137. playBackInfo.m_freezeAtLastFrame = false;
  138. // Add 2 motions to the queue
  139. const MotionInstance* motionInstance1 = motionSystem->PlayMotion(motion1, &playBackInfo);
  140. const MotionInstance* motionInstance2 = motionSystem->PlayMotion(motion2, &playBackInfo);
  141. GetEMotionFX().Update(0.0f);
  142. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 1);
  143. GetEMotionFX().Update(9.0f);
  144. GetEMotionFX().Update(0.5f);
  145. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 2);
  146. EXPECT_FLOAT_EQ(motionInstance1->GetWeight(), 0.5f); // motion 1 started blending out at time 9.0f
  147. EXPECT_FLOAT_EQ(motionInstance2->GetWeight(), 0.5f);
  148. motionSystem->StopAllMotions();
  149. // Wait for them to blend out
  150. GetEMotionFX().Update(1.0f);
  151. EXPECT_EQ(motionSystem->GetNumMotionInstances(), 0);
  152. motion2->Destroy();
  153. motion1->Destroy();
  154. actorInstance->Destroy();
  155. }
  156. } // namespace EMotionFX