AnimGraphRefCountTests.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 <AzCore/Serialization/SerializeContext.h>
  9. #include <AzCore/Serialization/Utils.h>
  10. #include <EMotionFX/Source/EventHandler.h>
  11. #include <EMotionFX/Source/AnimGraph.h>
  12. #include <EMotionFX/Source/AnimGraphInstance.h>
  13. #include <EMotionFX/Source/AnimGraphBindPoseNode.h>
  14. #include <EMotionFX/Source/AnimGraphEntryNode.h>
  15. #include <EMotionFX/Source/AnimGraphExitNode.h>
  16. #include <EMotionFX/Source/AnimGraphStateMachine.h>
  17. #include <Tests/AnimGraphFixture.h>
  18. namespace EMotionFX
  19. {
  20. class AnimGraphRefCountFixture
  21. : public AnimGraphFixture
  22. {
  23. public:
  24. void Run()
  25. {
  26. Simulate(/*simulationTime*/10.0f, /*expectedFps*/60.0f, /*fpsVariance*/0.0f,
  27. /*preCallback*/[this](AnimGraphInstance*)
  28. {
  29. this->m_animGraphInstance->SetAutoReleaseRefDatas(false);
  30. this->m_animGraphInstance->SetAutoReleasePoses(false);
  31. },
  32. /*postCallback*/[](AnimGraphInstance*){},
  33. /*preUpdateCallback*/[](AnimGraphInstance*, float, float, int){},
  34. /*postUpdateCallback*/[this](AnimGraphInstance*, float, float, int)
  35. {
  36. // Check if data and pose ref counts are back to 0 for all nodes.
  37. const size_t numNodes = this->m_animGraph->GetNumNodes();
  38. for (size_t i = 0; i < numNodes; ++i)
  39. {
  40. const AnimGraphNode* node = this->m_animGraph->GetNode(i);
  41. // Check the ref counts only for unique datas that got allocated. Lazy-init of the unique datas does not allocate unique datas for unused or unvisted nodes.
  42. AnimGraphNodeData* nodeData = static_cast<AnimGraphNodeData*>(this->m_animGraphInstance->GetUniqueObjectData(node->GetObjectIndex()));
  43. if (nodeData)
  44. {
  45. EXPECT_EQ(0, nodeData->GetRefDataRefCount()) << "Expected the data ref count to be 0 post update.";
  46. EXPECT_EQ(0, nodeData->GetPoseRefCount()) << "Expected the pose ref count to be 0 post update.";
  47. }
  48. }
  49. this->m_animGraphInstance->ReleaseRefDatas();
  50. this->m_animGraphInstance->ReleasePoses();
  51. });
  52. }
  53. };
  54. ///////////////////////////////////////////////////////////////////////////
  55. struct AnimGraphRefCountData_SimpleChain
  56. {
  57. int m_numStates;
  58. float m_blendTime;
  59. float m_countDownTime;
  60. };
  61. class AnimGraphRefCountTest_SimpleChain
  62. : public AnimGraphRefCountFixture
  63. , public ::testing::WithParamInterface<AnimGraphRefCountData_SimpleChain>
  64. {
  65. public:
  66. void ConstructGraph() override
  67. {
  68. const AnimGraphRefCountData_SimpleChain& param = GetParam();
  69. AnimGraphFixture::ConstructGraph();
  70. /*
  71. +-------+ +---+ +---+ +---+
  72. | Start |--->| A |--->| B |---> ... --->| N |
  73. +-------+ +---+ +---+ +---+
  74. */
  75. AnimGraphBindPoseNode* stateStart = aznew AnimGraphBindPoseNode();
  76. m_rootStateMachine->AddChildNode(stateStart);
  77. m_rootStateMachine->SetEntryState(stateStart);
  78. const char startChar = 'A';
  79. AnimGraphNode* prevState = stateStart;
  80. for (int i = 0; i < param.m_numStates; ++i)
  81. {
  82. AnimGraphBindPoseNode* state = aznew AnimGraphBindPoseNode();
  83. state->SetName(AZStd::string(1, static_cast<char>(startChar + i)).c_str());
  84. m_rootStateMachine->AddChildNode(state);
  85. AddTransitionWithTimeCondition(prevState, state, /*blendTime*/param.m_blendTime, /*countDownTime*/param.m_countDownTime);
  86. prevState = state;
  87. }
  88. }
  89. };
  90. TEST_P(AnimGraphRefCountTest_SimpleChain, AnimGraphRefCountTest_SimpleChain)
  91. {
  92. Run();
  93. }
  94. std::vector<AnimGraphRefCountData_SimpleChain> animGraphRefCountTest_SimpleChainTestData
  95. {
  96. {
  97. /*m_numStates*/3,
  98. /*m_blendTime*/1.0,
  99. /*m_countDownTime*/1.0
  100. },
  101. {
  102. 3,
  103. 0.0,
  104. 1.0
  105. },
  106. {
  107. 3,
  108. 0.0,
  109. 0.0
  110. },
  111. {
  112. 8,
  113. 0.5,
  114. 0.5
  115. },
  116. {
  117. 16,
  118. 0.2,
  119. 0.2
  120. }
  121. };
  122. INSTANTIATE_TEST_CASE_P(AnimGraphRefCountTest_SimpleChain,
  123. AnimGraphRefCountTest_SimpleChain,
  124. ::testing::ValuesIn(animGraphRefCountTest_SimpleChainTestData)
  125. );
  126. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  127. class AnimGraphRefCountTest_SimpleEntryExit
  128. : public AnimGraphRefCountFixture
  129. {
  130. public:
  131. void ConstructGraph() override
  132. {
  133. AnimGraphFixture::ConstructGraph();
  134. AnimGraphBindPoseNode* stateStart = aznew AnimGraphBindPoseNode();
  135. stateStart->SetName("Start");
  136. m_rootStateMachine->AddChildNode(stateStart);
  137. m_rootStateMachine->SetEntryState(stateStart);
  138. AnimGraphStateMachine* stateMachine = aznew AnimGraphStateMachine();
  139. stateMachine->SetName("Sub SM");
  140. m_rootStateMachine->AddChildNode(stateMachine);
  141. AddTransitionWithTimeCondition(stateStart, stateMachine, 1.0, 1.0);
  142. {
  143. AnimGraphEntryNode* subEntryNode = aznew AnimGraphEntryNode();
  144. subEntryNode->SetName("Entry");
  145. stateMachine->AddChildNode(subEntryNode);
  146. stateMachine->SetEntryState(subEntryNode);
  147. AnimGraphBindPoseNode* subBetweenNode = aznew AnimGraphBindPoseNode();
  148. subBetweenNode->SetName("Sub In-between");
  149. stateMachine->AddChildNode(subBetweenNode);
  150. AddTransitionWithTimeCondition(subEntryNode, subBetweenNode, 0.0, 0.3);
  151. AnimGraphExitNode* exitNode = aznew AnimGraphExitNode();
  152. exitNode->SetName("Exit");
  153. stateMachine->AddChildNode(exitNode);
  154. AddTransitionWithTimeCondition(subBetweenNode, exitNode, 1.0, 1.0);
  155. }
  156. AnimGraphBindPoseNode* stateEnd = aznew AnimGraphBindPoseNode();
  157. stateEnd->SetName("End");
  158. m_rootStateMachine->AddChildNode(stateEnd);
  159. AddTransitionWithTimeCondition(stateMachine, stateEnd, 1.0, 3.0);
  160. }
  161. };
  162. TEST_F(AnimGraphRefCountTest_SimpleEntryExit, AnimGraphRefCountTest_SimpleEntryExit)
  163. {
  164. Run();
  165. }
  166. } // namespace EMotionFX