AnimGraphTransitionConditionTests.cpp 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  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 "AnimGraphTransitionConditionFixture.h"
  9. #include <EMotionFX/Source/EMotionFXManager.h>
  10. #include <EMotionFX/Source/AnimGraph.h>
  11. #include <EMotionFX/Source/AnimGraphManager.h>
  12. #include <EMotionFX/Source/AnimGraphStateMachine.h>
  13. #include <EMotionFX/Source/AnimGraphExitNode.h>
  14. #include <EMotionFX/Source/AnimGraphMotionNode.h>
  15. #include <EMotionFX/Source/AnimGraphMotionCondition.h>
  16. #include <EMotionFX/Source/AnimGraphParameterCondition.h>
  17. #include <EMotionFX/Source/AnimGraphPlayTimeCondition.h>
  18. #include <EMotionFX/Source/AnimGraphStateCondition.h>
  19. #include <EMotionFX/Source/AnimGraphTagCondition.h>
  20. #include <EMotionFX/Source/AnimGraphTimeCondition.h>
  21. #include <EMotionFX/Source/AnimGraphVector2Condition.h>
  22. #include <EMotionFX/Source/Parameter/FloatSliderParameter.h>
  23. #include <EMotionFX/Source/Parameter/TagParameter.h>
  24. #include <EMotionFX/Source/Parameter/Vector2Parameter.h>
  25. #include <EMotionFX/Source/TwoStringEventData.h>
  26. #include <AzCore/Serialization/SerializeContext.h>
  27. #include <AzCore/std/string/conversions.h>
  28. #include <functional>
  29. #include <unordered_map>
  30. namespace EMotionFX
  31. {
  32. // This function controls the way that the Google Test code formats objects
  33. // of type AnimGraphNode*. This causes test failure messages involving
  34. // AnimGraphNode pointers to contain the node name instead of just the
  35. // pointer address.
  36. void PrintTo(AnimGraphNode* const object, ::std::ostream* os)
  37. {
  38. *os << object->GetName();
  39. }
  40. // Google Test does not consider inheritance when calling PrintTo(), so
  41. // multiple functions must be defined for subclasses
  42. void PrintTo(AnimGraphMotionNode* const object, ::std::ostream* os)
  43. {
  44. PrintTo(static_cast<AnimGraphNode*>(object), os);
  45. }
  46. // This is used to map from frame numbers to a list of AnimGraphNodes. Test
  47. // data defines the expected list of active nodes per frame using this
  48. // type.
  49. using ActiveNodesMap = std::unordered_map<int, std::vector<const char*>>;
  50. // This function is defined by test data to allow for modifications to the
  51. // anim graph at each frame. The second parameter is the current frame
  52. // number. It is called with a frame number of -1 as the first thing in the
  53. // test before the first Update() call, to allow for initial values to be
  54. // set.
  55. using FrameCallback = std::function<void(AnimGraphInstance*, int)>;
  56. // The TransitionConditionFixtureP fixture is parameterized
  57. // on this type
  58. template<class ConditionType>
  59. struct ConditionFixtureParams
  60. {
  61. using ConditionSetUpFunc = void(*)(ConditionType*);
  62. ConditionFixtureParams(
  63. const ConditionSetUpFunc& func,
  64. const ActiveNodesMap& activeNodesMap,
  65. const FrameCallback& frameCallback = [] (AnimGraphInstance*, int) {}
  66. ) : m_setUpFunction(func), m_activeNodes(activeNodesMap), m_callback(frameCallback)
  67. {
  68. }
  69. // Function to set up the condition's parameters
  70. const ConditionSetUpFunc m_setUpFunction;
  71. // List of nodes that are active on each frame
  72. const ActiveNodesMap m_activeNodes;
  73. const FrameCallback m_callback;
  74. };
  75. template<class ConditionType>
  76. class TransitionConditionFixtureP : public AnimGraphTransitionConditionFixture,
  77. public ::testing::WithParamInterface<ConditionFixtureParams<ConditionType>>
  78. {
  79. public:
  80. const float m_fps;
  81. const float m_updateInterval;
  82. const int m_numUpdates;
  83. TransitionConditionFixtureP()
  84. : m_fps(60.0f)
  85. , m_updateInterval(1.0f / m_fps)
  86. , m_numUpdates(static_cast<int>(3.0f * m_fps))
  87. {
  88. }
  89. template<class ParameterType, class ValueType>
  90. void AddParameter(const AZStd::string name, const ValueType& defaultValue)
  91. {
  92. ParameterType* parameter = aznew ParameterType();
  93. parameter->SetName(name);
  94. parameter->SetDefaultValue(defaultValue);
  95. m_animGraph->AddParameter(parameter);
  96. }
  97. void AddNodesToAnimGraph() override
  98. {
  99. AddParameter<FloatSliderParameter>("FloatParam", 0.1f);
  100. AddParameter<Vector2Parameter>("Vector2Param", AZ::Vector2(0.1f, 0.1f));
  101. AddParameter<TagParameter>("TagParam1", false);
  102. AddParameter<TagParameter>("TagParam2", false);
  103. // Create the appropriate condition type from this test's parameters
  104. ConditionType* condition = aznew ConditionType();
  105. m_transition->AddCondition(condition);
  106. condition->SetAnimGraph(m_animGraph.get());
  107. this->GetParam().m_setUpFunction(condition);
  108. m_transition->SetBlendTime(0.5f);
  109. }
  110. protected:
  111. void RunEMotionFXUpdateLoop()
  112. {
  113. const ActiveNodesMap& activeNodes = this->GetParam().m_activeNodes;
  114. const FrameCallback& callback = this->GetParam().m_callback;
  115. // Allow tests to set starting values for parameters
  116. callback(m_animGraphInstance, -1);
  117. // Run the EMotionFX update loop for 3 seconds at 60 fps
  118. for (int frameNum = 0; frameNum < m_numUpdates; ++frameNum)
  119. {
  120. // Allow for test-data defined updates to the graph state
  121. callback(m_animGraphInstance, frameNum);
  122. if (frameNum == 0)
  123. {
  124. // Make sure the first frame is initialized correctly
  125. // The EMotion FX update is needed before we can extract
  126. // the currently active nodes from it
  127. // We use an update delta time of zero on the first frame,
  128. // to make sure we have a valid internal state on the first
  129. // frame
  130. GetEMotionFX().Update(0.0f);
  131. }
  132. else
  133. {
  134. GetEMotionFX().Update(m_updateInterval);
  135. }
  136. // Check the state for the current frame
  137. if (activeNodes.count(frameNum))
  138. {
  139. AZStd::vector<AnimGraphNode*> expectedActiveNodes;
  140. for (const char* name : activeNodes.at(frameNum))
  141. {
  142. expectedActiveNodes.push_back(m_animGraph->RecursiveFindNodeByName(name));
  143. }
  144. const AZStd::vector<AnimGraphNode*>& gotActiveNodes = m_stateMachine->GetActiveStates(m_animGraphInstance);
  145. EXPECT_EQ(gotActiveNodes, expectedActiveNodes) << "on frame " << frameNum << ", time " << frameNum * m_updateInterval;
  146. }
  147. }
  148. {
  149. // Ensure that we reached the target state after 3 seconds
  150. const AZStd::vector<AnimGraphNode*>& activeStates = m_stateMachine->GetActiveStates(m_animGraphInstance);
  151. const size_t numActiveStates = activeStates.size();
  152. EXPECT_EQ(numActiveStates, 1) << numActiveStates << " active state detected. Only one state should be active.";
  153. if (numActiveStates > 0)
  154. {
  155. EXPECT_EQ(activeStates[0], m_motionNodeB) << "MotionNode1 is not the single active node";
  156. }
  157. }
  158. }
  159. };
  160. class StateConditionFixture : public TransitionConditionFixtureP<AnimGraphStateCondition>
  161. {
  162. public:
  163. // The base class TransitionConditionFixtureP just sets up a simple
  164. // anim graph with two motion nodes and a transition between them. This
  165. // graph is not sufficient to test the state condition, as there are no
  166. // states available to test against. This fixture creates a slightly
  167. // more complex graph.
  168. void AddNodesToAnimGraph() override
  169. {
  170. // +-------------------+
  171. // | childStateMachine |
  172. // +-------------------+
  173. // 0.5s time ^ \ state condition defined
  174. // condition--->o o<---by test data
  175. // 0.5s blend time-->/ v<--0.5s blend time
  176. //+-------------------+ +-------------------+
  177. //|testSkeletalMotion0|------------------------>|testSkeletalMotion1|
  178. //+-------------------+ ^ +-------------------+
  179. // transition with
  180. // no condition
  181. //
  182. // -------------------+----------------------------------------------
  183. // Child State Machine| 1.0 sec time
  184. // -------------------+ condition
  185. // +---------------+ v +----------+
  186. // entry state-->|ChildMotionNode|----o---->|Exit state|
  187. // +---------------+ ^ +----------+
  188. // transitions to exit states have
  189. // a blend time of 0
  190. AddParameter<FloatSliderParameter>("FloatParam", 0.1f);
  191. AddParameter<Vector2Parameter>("Vector2Param", AZ::Vector2(0.1f, 0.1f));
  192. // Create another state machine inside the top-level one
  193. AnimGraphMotionNode* childMotionNode = aznew AnimGraphMotionNode();
  194. childMotionNode->SetName("ChildMotionNode");
  195. childMotionNode->AddMotionId("testSkeletalMotion0");
  196. AnimGraphExitNode* childExitNode = aznew AnimGraphExitNode();
  197. childExitNode->SetName("ChildExitNode");
  198. AnimGraphTimeCondition* motionToExitCondition = aznew AnimGraphTimeCondition();
  199. motionToExitCondition->SetCountDownTime(1.0f);
  200. AnimGraphStateTransition* motionToExitTransition = aznew AnimGraphStateTransition();
  201. motionToExitTransition->SetSourceNode(childMotionNode);
  202. motionToExitTransition->SetTargetNode(childExitNode);
  203. motionToExitTransition->SetBlendTime(0.0f);
  204. motionToExitTransition->AddCondition(motionToExitCondition);
  205. m_childState = aznew AnimGraphStateMachine();
  206. m_childState->SetName("ChildStateMachine");
  207. m_childState->AddChildNode(childMotionNode);
  208. m_childState->AddChildNode(childExitNode);
  209. m_childState->SetEntryState(childMotionNode);
  210. m_childState->AddTransition(motionToExitTransition);
  211. AnimGraphTimeCondition* motion0ToChildStateCondition = aznew AnimGraphTimeCondition();
  212. motion0ToChildStateCondition->SetCountDownTime(0.5f);
  213. AnimGraphStateTransition* motion0ToChildStateTransition = aznew AnimGraphStateTransition();
  214. motion0ToChildStateTransition->SetSourceNode(m_motionNodeA);
  215. motion0ToChildStateTransition->SetTargetNode(m_childState);
  216. motion0ToChildStateTransition->SetBlendTime(0.5f);
  217. motion0ToChildStateTransition->AddCondition(motion0ToChildStateCondition);
  218. AnimGraphStateTransition* childStateToMotion1Transition = aznew AnimGraphStateTransition();
  219. childStateToMotion1Transition->SetSourceNode(m_childState);
  220. childStateToMotion1Transition->SetTargetNode(m_motionNodeB);
  221. childStateToMotion1Transition->SetBlendTime(0.5f);
  222. m_stateMachine->AddChildNode(m_childState);
  223. m_stateMachine->AddTransition(motion0ToChildStateTransition);
  224. m_stateMachine->AddTransition(childStateToMotion1Transition);
  225. // Create the appropriate condition type from this test's
  226. // parameters
  227. AnimGraphStateCondition* condition = aznew AnimGraphStateCondition();
  228. condition->SetAnimGraph(m_animGraph.get());
  229. childStateToMotion1Transition->AddCondition(condition);
  230. this->GetParam().m_setUpFunction(condition);
  231. }
  232. protected:
  233. AnimGraphStateMachine* m_childState;
  234. };
  235. class RangedMotionEventConditionFixture
  236. : public TransitionConditionFixtureP<AnimGraphMotionCondition>
  237. {
  238. public:
  239. void AddNodesToAnimGraph() override
  240. {
  241. this->TransitionConditionFixtureP<AnimGraphMotionCondition>::AddNodesToAnimGraph();
  242. AnimGraphMotionCondition* rangeMotionCondition = aznew AnimGraphMotionCondition();
  243. rangeMotionCondition->SetTestFunction(AnimGraphMotionCondition::FUNCTION_EVENT);
  244. rangeMotionCondition->SetMotionNodeId(m_motionNodeA->GetId());
  245. const AZStd::shared_ptr<const EventData> eventData = GetEventManager().FindOrCreateEventData<TwoStringEventData>("TestRangeEvent", "TestParameter");
  246. rangeMotionCondition->SetEventDatas({eventData});
  247. this->m_transition->AddCondition(rangeMotionCondition);
  248. rangeMotionCondition->SetAnimGraph(m_animGraph.get());
  249. }
  250. };
  251. // The test data changes various parameters of the conditions being tested,
  252. // but they frequently result in the anim graph changing in an identical
  253. // manner (such as moving from testSkeletalMotionNode0 to
  254. // testSkeletalMotionNode1 at the same point in time). These following
  255. // functions centralize some of the expected behavior.
  256. template<class AttributeType>
  257. void ChangeParamTo(AnimGraphInstance* animGraphInstance, int currentFrame, int testFrame, const char* paramName, void (*changeFunc)(AttributeType* parameter))
  258. {
  259. if (currentFrame == testFrame)
  260. {
  261. AttributeType* parameter = static_cast<AttributeType*>(animGraphInstance->FindParameter(paramName));
  262. changeFunc(parameter);
  263. }
  264. }
  265. void ChangeVector2ParamSpecial(AnimGraphInstance* animGraphInstance, int currentFrame, int testFrame, const AZ::Vector2& frame30Value, const AZ::Vector2& otherValue)
  266. {
  267. if (currentFrame != testFrame)
  268. {
  269. MCore::AttributeVector2* parameter = static_cast<MCore::AttributeVector2*>(animGraphInstance->FindParameter("Vector2Param"));
  270. parameter->SetValue(otherValue);
  271. }
  272. else
  273. {
  274. MCore::AttributeVector2* parameter = static_cast<MCore::AttributeVector2*>(animGraphInstance->FindParameter("Vector2Param"));
  275. parameter->SetValue(frame30Value);
  276. }
  277. }
  278. void ChangeNodeAttribute(AnimGraphInstance* animGraphInstance, int currentFrame, int testFrame, void(*changeFunc)(AnimGraphMotionNode*))
  279. {
  280. if (currentFrame == testFrame)
  281. {
  282. const AnimGraph* animGraph = animGraphInstance->GetAnimGraph();
  283. AnimGraphMotionNode* node = static_cast<AnimGraphMotionNode*>(animGraph->RecursiveFindNodeByName("testSkeletalMotion0"));
  284. AZ_Assert(node, "There is no node named 'testSkeletalMotion0'");
  285. changeFunc(node);
  286. node->InvalidateUniqueData(animGraphInstance);
  287. }
  288. }
  289. static const auto ChangeNodeToLooping = std::bind(
  290. ChangeNodeAttribute,
  291. std::placeholders::_1,
  292. std::placeholders::_2,
  293. -1,
  294. [](AnimGraphMotionNode* node) { node->SetLoop(true); }
  295. );
  296. static const auto ChangeNodeToNonLooping = std::bind(
  297. ChangeNodeAttribute,
  298. std::placeholders::_1,
  299. std::placeholders::_2,
  300. -1,
  301. [](AnimGraphMotionNode* node) { node->SetLoop(false); }
  302. );
  303. static const auto ChangeFloatParamToPointFiveOnFrameThirty = std::bind(
  304. ChangeParamTo<MCore::AttributeFloat>,
  305. std::placeholders::_1,
  306. std::placeholders::_2,
  307. 30,
  308. "FloatParam",
  309. [](MCore::AttributeFloat* parameter) { parameter->SetValue(0.5f); }
  310. );
  311. static const auto ChangeFloatParamToNegativePointFiveOnFrameThirty = std::bind(
  312. ChangeParamTo<MCore::AttributeFloat>,
  313. std::placeholders::_1,
  314. std::placeholders::_2,
  315. 30,
  316. "FloatParam",
  317. [](MCore::AttributeFloat* parameter) { parameter->SetValue(-0.5f); }
  318. );
  319. static const auto ChangeVector2Param = std::bind(
  320. ChangeParamTo<MCore::AttributeVector2>,
  321. std::placeholders::_1,
  322. std::placeholders::_2,
  323. std::placeholders::_3,
  324. "Vector2Param",
  325. std::placeholders::_4
  326. );
  327. static const ActiveNodesMap moveToMotion1AtFrameThirty
  328. {
  329. {0, {"testSkeletalMotion0"}},
  330. {29, {"testSkeletalMotion0"}},
  331. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  332. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  333. {60, {"testSkeletalMotion1"}}
  334. };
  335. // Remember that the test runs the update loop at 60 fps. All the frame
  336. // numbers in the ActiveNodesPerFrameMaps are based on this value.
  337. // testSkeletalMotion0 is exactly 1 second long.
  338. static const std::vector<ConditionFixtureParams<AnimGraphMotionCondition>> motionTransitionConditionData
  339. {
  340. {
  341. [](AnimGraphMotionCondition* condition) {
  342. condition->SetMotionNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  343. condition->SetTestFunction(AnimGraphMotionCondition::FUNCTION_EVENT);
  344. condition->SetEventDatas({GetEventManager().FindOrCreateEventData<TwoStringEventData>("TestEvent", "TestParameter")});
  345. },
  346. ActiveNodesMap {
  347. {0, {"testSkeletalMotion0"}},
  348. {44, {"testSkeletalMotion0"}},
  349. {45, {"testSkeletalMotion0", "testSkeletalMotion1"}}, // The event gets triggered on frame 44, but the condition only will only be reevaluated the next frame, so we have one frame delay.
  350. {46, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  351. {74, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  352. {75, {"testSkeletalMotion1"}}
  353. }
  354. },
  355. {
  356. [](AnimGraphMotionCondition* condition) {
  357. condition->SetMotionNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  358. condition->SetTestFunction(AnimGraphMotionCondition::FUNCTION_HASENDED);
  359. },
  360. ActiveNodesMap {
  361. {0, {"testSkeletalMotion0"}},
  362. {59, {"testSkeletalMotion0"}},
  363. {60, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  364. {89, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  365. {90, {"testSkeletalMotion1"}}
  366. }
  367. },
  368. {
  369. [](AnimGraphMotionCondition* condition) {
  370. condition->SetMotionNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  371. condition->SetTestFunction(AnimGraphMotionCondition::FUNCTION_HASREACHEDMAXNUMLOOPS);
  372. condition->SetNumLoops(1);
  373. },
  374. ActiveNodesMap {
  375. {0, {"testSkeletalMotion0"}},
  376. {59, {"testSkeletalMotion0"}},
  377. {60, {"testSkeletalMotion0"}}, // Motion will not have reached 1.0 as playtime yet, because it lags a frame behind. The actual time value gets updated in PostUpdate which is after the evaluation of the condition.
  378. {61, {"testSkeletalMotion0"}}, // Motion will be at 1.0 play time exactly, the loop is not detected yet.
  379. {62, {"testSkeletalMotion0", "testSkeletalMotion1"}}, // The loop has been detected
  380. {89, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  381. {90, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  382. {91, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  383. {92, {"testSkeletalMotion1"}}
  384. },
  385. ChangeNodeToLooping
  386. },
  387. {
  388. [](AnimGraphMotionCondition* condition) {
  389. condition->SetMotionNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  390. condition->SetTestFunction(AnimGraphMotionCondition::FUNCTION_PLAYTIME);
  391. condition->SetPlayTime(0.2f);
  392. },
  393. ActiveNodesMap {
  394. {0, {"testSkeletalMotion0"}},
  395. {11, {"testSkeletalMotion0"}},
  396. {12, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  397. {41, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  398. {42, {"testSkeletalMotion1"}}
  399. },
  400. ChangeNodeToNonLooping
  401. },
  402. {
  403. [](AnimGraphMotionCondition* condition) {
  404. condition->SetMotionNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  405. condition->SetTestFunction(AnimGraphMotionCondition::FUNCTION_PLAYTIMELEFT);
  406. condition->SetPlayTime(0.2f);
  407. },
  408. ActiveNodesMap {
  409. {0, {"testSkeletalMotion0"}},
  410. {47, {"testSkeletalMotion0"}},
  411. {48, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  412. {77, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  413. {78, {"testSkeletalMotion1"}}
  414. }
  415. },
  416. {
  417. [](AnimGraphMotionCondition* condition) {
  418. condition->SetMotionNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  419. condition->SetTestFunction(AnimGraphMotionCondition::FUNCTION_ISMOTIONASSIGNED);
  420. condition->SetPlayTime(0.2f);
  421. },
  422. ActiveNodesMap {
  423. // This condition will always evaluate to true. The transition
  424. // will start immediately.
  425. {0, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  426. {29, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  427. {30, {"testSkeletalMotion1"}}
  428. }
  429. }
  430. // TODO AnimGraphMotionCondition::FUNCTION_ISMOTIONNOTASSIGNED
  431. };
  432. static const std::vector<ConditionFixtureParams<AnimGraphMotionCondition>> rangedMotionTransitionConditionData
  433. {
  434. {
  435. [](AnimGraphMotionCondition* condition) {
  436. condition->SetMotionNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  437. condition->SetTestFunction(AnimGraphMotionCondition::FUNCTION_EVENT);
  438. condition->SetEventDatas({GetEventManager().FindOrCreateEventData<TwoStringEventData>("TestEvent", "TestParameter")});
  439. },
  440. ActiveNodesMap {
  441. {0, {"testSkeletalMotion0"}},
  442. {44, {"testSkeletalMotion0"}},
  443. {45, {"testSkeletalMotion0", "testSkeletalMotion1"}}, // The event gets triggered on frame 44, but the condition only will only be reevaluated the next frame, so we have one frame delay.
  444. {46, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  445. {74, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  446. {75, {"testSkeletalMotion1"}}
  447. }
  448. },
  449. };
  450. static const std::vector<ConditionFixtureParams<AnimGraphParameterCondition>> parameterTransitionConditionData
  451. {
  452. // FUNCTION_EQUAL tests
  453. {
  454. [](AnimGraphParameterCondition* condition) {
  455. condition->SetParameterName("FloatParam");
  456. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_EQUAL);
  457. condition->SetTestValue(0.1f);
  458. },
  459. ActiveNodesMap {
  460. {0, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  461. {29, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  462. {30, {"testSkeletalMotion1"}}
  463. }
  464. },
  465. {
  466. [](AnimGraphParameterCondition* condition) {
  467. condition->SetParameterName("FloatParam");
  468. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_EQUAL);
  469. condition->SetTestValue(0.5f);
  470. },
  471. ActiveNodesMap {
  472. {0, {"testSkeletalMotion0"}},
  473. {29, {"testSkeletalMotion0"}},
  474. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  475. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  476. {60, {"testSkeletalMotion1"}}
  477. },
  478. ChangeFloatParamToPointFiveOnFrameThirty
  479. },
  480. // FUNCTION_NOTEQUAL tests
  481. {
  482. [](AnimGraphParameterCondition* condition) {
  483. condition->SetParameterName("FloatParam");
  484. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_NOTEQUAL);
  485. condition->SetTestValue(0.1f);
  486. },
  487. ActiveNodesMap {
  488. {0, {"testSkeletalMotion0"}},
  489. {29, {"testSkeletalMotion0"}},
  490. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  491. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  492. {60, {"testSkeletalMotion1"}}
  493. },
  494. ChangeFloatParamToPointFiveOnFrameThirty
  495. },
  496. // FUNCTION_INRANGE tests
  497. {
  498. [](AnimGraphParameterCondition* condition) {
  499. condition->SetParameterName("FloatParam");
  500. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_INRANGE);
  501. condition->SetTestValue(0.4f);
  502. condition->SetRangeValue(0.6f);
  503. },
  504. ActiveNodesMap {
  505. {0, {"testSkeletalMotion0"}},
  506. {29, {"testSkeletalMotion0"}},
  507. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  508. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  509. {60, {"testSkeletalMotion1"}}
  510. },
  511. ChangeFloatParamToPointFiveOnFrameThirty
  512. },
  513. // FUNCTION_NOTINRANGE tests
  514. {
  515. [](AnimGraphParameterCondition* condition) {
  516. condition->SetParameterName("FloatParam");
  517. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_NOTINRANGE);
  518. condition->SetTestValue(-0.2f);
  519. condition->SetRangeValue(0.2f);
  520. },
  521. ActiveNodesMap {
  522. {0, {"testSkeletalMotion0"}},
  523. {29, {"testSkeletalMotion0"}},
  524. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  525. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  526. {60, {"testSkeletalMotion1"}}
  527. },
  528. ChangeFloatParamToPointFiveOnFrameThirty
  529. },
  530. // FUNCTION_LESS tests
  531. {
  532. [](AnimGraphParameterCondition* condition) {
  533. condition->SetParameterName("FloatParam");
  534. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESS);
  535. condition->SetTestValue(0.0f);
  536. },
  537. ActiveNodesMap {
  538. {0, {"testSkeletalMotion0"}},
  539. {29, {"testSkeletalMotion0"}},
  540. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  541. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  542. {60, {"testSkeletalMotion1"}}
  543. },
  544. ChangeFloatParamToNegativePointFiveOnFrameThirty
  545. },
  546. // FUNCTION_GREATER tests
  547. {
  548. [](AnimGraphParameterCondition* condition) {
  549. condition->SetParameterName("FloatParam");
  550. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATER);
  551. condition->SetTestValue(0.1f);
  552. },
  553. ActiveNodesMap {
  554. {0, {"testSkeletalMotion0"}},
  555. {29, {"testSkeletalMotion0"}},
  556. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  557. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  558. {60, {"testSkeletalMotion1"}}
  559. },
  560. ChangeFloatParamToPointFiveOnFrameThirty
  561. },
  562. // FUNCTION_GREATEREQUAL tests
  563. {
  564. [](AnimGraphParameterCondition* condition) {
  565. condition->SetParameterName("FloatParam");
  566. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATEREQUAL);
  567. condition->SetTestValue(0.5f);
  568. },
  569. ActiveNodesMap {
  570. {0, {"testSkeletalMotion0"}},
  571. {29, {"testSkeletalMotion0"}},
  572. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  573. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  574. {60, {"testSkeletalMotion1"}}
  575. },
  576. ChangeFloatParamToPointFiveOnFrameThirty
  577. },
  578. {
  579. [](AnimGraphParameterCondition* condition) {
  580. condition->SetParameterName("FloatParam");
  581. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATEREQUAL);
  582. condition->SetTestValue(0.49f);
  583. },
  584. ActiveNodesMap {
  585. {0, {"testSkeletalMotion0"}},
  586. {29, {"testSkeletalMotion0"}},
  587. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  588. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  589. {60, {"testSkeletalMotion1"}}
  590. },
  591. ChangeFloatParamToPointFiveOnFrameThirty
  592. },
  593. // FUNCTION_LESSEQUAL tests
  594. {
  595. [](AnimGraphParameterCondition* condition) {
  596. condition->SetParameterName("FloatParam");
  597. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESSEQUAL);
  598. condition->SetTestValue(-0.1f);
  599. },
  600. ActiveNodesMap {
  601. {0, {"testSkeletalMotion0"}},
  602. {29, {"testSkeletalMotion0"}},
  603. {30, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  604. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  605. {60, {"testSkeletalMotion1"}}
  606. },
  607. ChangeFloatParamToNegativePointFiveOnFrameThirty
  608. },
  609. // Time requirement test
  610. {
  611. [](AnimGraphParameterCondition* condition) {
  612. condition->SetParameterName("FloatParam");
  613. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATER);
  614. condition->SetTimeRequirement(0.5f);
  615. condition->SetTestValue(0.1f);
  616. },
  617. ActiveNodesMap {
  618. {0, {"testSkeletalMotion0"}},
  619. {29, {"testSkeletalMotion0"}},
  620. {30, {"testSkeletalMotion0"}},
  621. {59, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  622. {88, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  623. {89, {"testSkeletalMotion1"}}
  624. },
  625. ChangeFloatParamToPointFiveOnFrameThirty
  626. }
  627. };
  628. static const std::vector<ConditionFixtureParams<AnimGraphPlayTimeCondition>> playTimeTransitionConditionData
  629. {
  630. {
  631. [](AnimGraphPlayTimeCondition* condition) {
  632. condition->SetNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  633. condition->SetMode(AnimGraphPlayTimeCondition::MODE_REACHEDEND);
  634. },
  635. ActiveNodesMap {
  636. {0, {"testSkeletalMotion0"}},
  637. {59, {"testSkeletalMotion0"}},
  638. {60, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  639. {89, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  640. {90, {"testSkeletalMotion1"}}
  641. }
  642. },
  643. {
  644. [](AnimGraphPlayTimeCondition* condition) {
  645. condition->SetNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  646. condition->SetMode(AnimGraphPlayTimeCondition::MODE_REACHEDTIME);
  647. condition->SetPlayTime(0.3f);
  648. },
  649. ActiveNodesMap {
  650. {0, {"testSkeletalMotion0"}},
  651. {17, {"testSkeletalMotion0"}},
  652. {18, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  653. {47, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  654. {48, {"testSkeletalMotion1"}}
  655. }
  656. },
  657. {
  658. [](AnimGraphPlayTimeCondition* condition) {
  659. condition->SetNodeId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  660. condition->SetMode(AnimGraphPlayTimeCondition::MODE_HASLESSTHAN);
  661. condition->SetPlayTime(0.3f);
  662. },
  663. ActiveNodesMap {
  664. {0, {"testSkeletalMotion0"}},
  665. {41, {"testSkeletalMotion0"}},
  666. {42, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  667. {71, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  668. {72, {"testSkeletalMotion1"}}
  669. }
  670. }
  671. };
  672. static const std::vector<ConditionFixtureParams<AnimGraphStateCondition>> stateTransitionConditionData
  673. {
  674. {
  675. [](AnimGraphStateCondition* condition) {
  676. condition->SetStateId(condition->GetAnimGraph()->RecursiveFindNodeByName("ChildStateMachine")->GetId());
  677. condition->SetTestFunction(AnimGraphStateCondition::FUNCTION_EXITSTATES);
  678. },
  679. ActiveNodesMap {
  680. {0, {"testSkeletalMotion0"}},
  681. {29, {"testSkeletalMotion0"}},
  682. {30, {"testSkeletalMotion0", "ChildStateMachine"}},
  683. {59, {"testSkeletalMotion0", "ChildStateMachine"}},
  684. {60, {"ChildStateMachine"}},
  685. {89, {"ChildStateMachine"}},
  686. {90, {"ChildStateMachine", "testSkeletalMotion1"}},
  687. {119, {"ChildStateMachine", "testSkeletalMotion1"}},
  688. {120, {"testSkeletalMotion1"}}
  689. }
  690. },
  691. {
  692. [](AnimGraphStateCondition* condition) {
  693. condition->SetStateId(condition->GetAnimGraph()->RecursiveFindNodeByName("ChildMotionNode")->GetId());
  694. condition->SetTestFunction(AnimGraphStateCondition::FUNCTION_END);
  695. },
  696. ActiveNodesMap {
  697. {0, {"testSkeletalMotion0"}},
  698. {29, {"testSkeletalMotion0"}},
  699. {30, {"testSkeletalMotion0", "ChildStateMachine"}},
  700. {59, {"testSkeletalMotion0", "ChildStateMachine"}},
  701. // Before the state machine defer update changes.
  702. //{60, {"ChildStateMachine"}},
  703. //{89, {"ChildStateMachine"}},
  704. //{90, {"ChildStateMachine", "testSkeletalMotion1"}},
  705. //{119, {"ChildStateMachine", "testSkeletalMotion1"}},
  706. // After the state machine defer update changes.
  707. #ifdef ENABLE_SINGLEFRAME_MULTISTATETRANSITIONING
  708. {60, {"ChildStateMachine", "testSkeletalMotion1"}},
  709. #else
  710. {61, {"ChildStateMachine", "testSkeletalMotion1"}},
  711. #endif
  712. {89, {"ChildStateMachine", "testSkeletalMotion1"}},
  713. #ifdef ENABLE_SINGLEFRAME_MULTISTATETRANSITIONING
  714. {90, {"testSkeletalMotion1"}},
  715. #else
  716. {91, {"testSkeletalMotion1"}},
  717. #endif
  718. {119, {"testSkeletalMotion1"}},
  719. {120, {"testSkeletalMotion1"}}
  720. }
  721. },
  722. {
  723. [](AnimGraphStateCondition* condition) {
  724. condition->SetStateId(condition->GetAnimGraph()->RecursiveFindNodeByName("ChildStateMachine")->GetId());
  725. condition->SetTestFunction(AnimGraphStateCondition::FUNCTION_ENTERING);
  726. },
  727. ActiveNodesMap {
  728. // Stay in entry state for 0.5s
  729. {0, {"testSkeletalMotion0"}},
  730. {29, {"testSkeletalMotion0"}},
  731. // Transition into ChildStateMachine for 0.5s
  732. // As soon as this transition activates, the state condition to
  733. // move to testSkeletalMotion1 becomes true
  734. {30, {"testSkeletalMotion0", "ChildStateMachine"}},
  735. {59, {"testSkeletalMotion0", "ChildStateMachine"}},
  736. // Even though ChildStateMachine is not yet to the exit state,
  737. // the condition in the root state machine to leave that state
  738. // is true, so the transition to testSkeletalMotion1 starts
  739. #ifdef ENABLE_SINGLEFRAME_MULTISTATETRANSITIONING
  740. {60, {"ChildStateMachine", "testSkeletalMotion1"}},
  741. #else
  742. {61, {"ChildStateMachine", "testSkeletalMotion1"}},
  743. #endif
  744. {89, {"ChildStateMachine", "testSkeletalMotion1"}},
  745. #ifdef ENABLE_SINGLEFRAME_MULTISTATETRANSITIONING
  746. {90, {"testSkeletalMotion1"}}
  747. #else
  748. {91, {"testSkeletalMotion1"}}
  749. #endif
  750. }
  751. },
  752. {
  753. [](AnimGraphStateCondition* condition) {
  754. condition->SetStateId(condition->GetAnimGraph()->RecursiveFindNodeByName("ChildStateMachine")->GetId());
  755. condition->SetTestFunction(AnimGraphStateCondition::FUNCTION_ENTER);
  756. },
  757. ActiveNodesMap {
  758. // Stay in entry state for 0.5s
  759. {0, {"testSkeletalMotion0"}},
  760. {29, {"testSkeletalMotion0"}},
  761. // Transition into ChildStateMachine for 0.5s
  762. // As soon as this transition activates, the state condition to
  763. // move to testSkeletalMotion1 becomes true
  764. {30, {"testSkeletalMotion0", "ChildStateMachine"}},
  765. {59, {"testSkeletalMotion0", "ChildStateMachine"}},
  766. // Even though ChildStateMachine is not yet to the exit state,
  767. // the condition in the root state machine to leave that state
  768. // is true, so the transition to testSkeletalMotion1 starts
  769. #ifdef ENABLE_SINGLEFRAME_MULTISTATETRANSITIONING
  770. {60, {"ChildStateMachine", "testSkeletalMotion1"}},
  771. #else
  772. {61, {"ChildStateMachine", "testSkeletalMotion1"}},
  773. #endif
  774. {89, {"ChildStateMachine", "testSkeletalMotion1"}},
  775. #ifdef ENABLE_SINGLEFRAME_MULTISTATETRANSITIONING
  776. {90, {"testSkeletalMotion1"}}
  777. #else
  778. {91, {"testSkeletalMotion1"}}
  779. #endif
  780. }
  781. },
  782. {
  783. [](AnimGraphStateCondition* condition) {
  784. condition->SetStateId(condition->GetAnimGraph()->RecursiveFindNodeByName("testSkeletalMotion0")->GetId());
  785. condition->SetTestFunction(AnimGraphStateCondition::FUNCTION_END);
  786. },
  787. ActiveNodesMap {
  788. // Stay in entry state for 0.5s
  789. {0, {"testSkeletalMotion0"}},
  790. {29, {"testSkeletalMotion0"}},
  791. // Transition into ChildStateMachine for 0.5s
  792. // As soon as this transition activates, the state condition to
  793. // move to testSkeletalMotion1 becomes true
  794. {30, {"testSkeletalMotion0", "ChildStateMachine"}},
  795. {59, {"testSkeletalMotion0", "ChildStateMachine"}},
  796. // Even though ChildStateMachine is not yet to the exit state,
  797. // the condition in the root state machine to leave that state
  798. // is true, so the transition to testSkeletalMotion1 starts
  799. #ifdef ENABLE_SINGLEFRAME_MULTISTATETRANSITIONING
  800. {60, {"ChildStateMachine", "testSkeletalMotion1"}},
  801. #else
  802. {61, {"ChildStateMachine", "testSkeletalMotion1"}},
  803. #endif
  804. {89, {"ChildStateMachine", "testSkeletalMotion1"}},
  805. #ifdef ENABLE_SINGLEFRAME_MULTISTATETRANSITIONING
  806. {90, {"testSkeletalMotion1"}}
  807. #else
  808. {91, {"testSkeletalMotion1"}}
  809. #endif
  810. }
  811. }
  812. };
  813. static const std::vector<ConditionFixtureParams<AnimGraphTagCondition>> tagTransitionConditionData
  814. {
  815. {
  816. [](AnimGraphTagCondition* condition) {
  817. condition->SetFunction(AnimGraphTagCondition::FUNCTION_ALL);
  818. condition->SetTags({"TagParam1", "TagParam2"});
  819. },
  820. moveToMotion1AtFrameThirty,
  821. [] (AnimGraphInstance* animGraphInstance, int currentFrame) {
  822. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, 30, "TagParam1", [](MCore::AttributeBool* param) { param->SetValue(true); });
  823. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, 15, "TagParam2", [](MCore::AttributeBool* param) { param->SetValue(true); });
  824. }
  825. },
  826. {
  827. [](AnimGraphTagCondition* condition) {
  828. condition->SetFunction(AnimGraphTagCondition::FUNCTION_NOTALL);
  829. condition->SetTags({"TagParam1", "TagParam2"});
  830. },
  831. moveToMotion1AtFrameThirty,
  832. [] (AnimGraphInstance* animGraphInstance, int currentFrame) {
  833. // initialize tags to on
  834. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, -1, "TagParam1", [](MCore::AttributeBool* param) { param->SetValue(true); });
  835. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, -1, "TagParam2", [](MCore::AttributeBool* param) { param->SetValue(true); });
  836. // turn TagParam1 off on frame 30
  837. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, 30, "TagParam1", [](MCore::AttributeBool* param) { param->SetValue(false); });
  838. }
  839. },
  840. {
  841. [](AnimGraphTagCondition* condition) {
  842. condition->SetFunction(AnimGraphTagCondition::FUNCTION_NONE);
  843. condition->SetTags({"TagParam1", "TagParam2"});
  844. },
  845. moveToMotion1AtFrameThirty,
  846. [] (AnimGraphInstance* animGraphInstance, int currentFrame) {
  847. // initialize tags to on
  848. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, -1, "TagParam1", [](MCore::AttributeBool* param) { param->SetValue(true); });
  849. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, -1, "TagParam2", [](MCore::AttributeBool* param) { param->SetValue(true); });
  850. // turn TagParam2 off on frame 15
  851. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, 15, "TagParam2", [](MCore::AttributeBool* param) { param->SetValue(false); });
  852. // turn TagParam1 off on frame 30
  853. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, 30, "TagParam1", [](MCore::AttributeBool* param) { param->SetValue(false); });
  854. }
  855. },
  856. {
  857. [](AnimGraphTagCondition* condition) {
  858. condition->SetFunction(AnimGraphTagCondition::FUNCTION_ONEORMORE);
  859. condition->SetTags({"TagParam1", "TagParam2"});
  860. },
  861. moveToMotion1AtFrameThirty,
  862. [] (AnimGraphInstance* animGraphInstance, int currentFrame) {
  863. ChangeParamTo<MCore::AttributeBool>(animGraphInstance, currentFrame, 30, "TagParam1", [](MCore::AttributeBool* param) { param->SetValue(true); });
  864. }
  865. }
  866. };
  867. static const std::vector<ConditionFixtureParams<AnimGraphTimeCondition>> timeTransitionConditionData
  868. {
  869. {
  870. [](AnimGraphTimeCondition* condition) {
  871. condition->SetCountDownTime(1.3f);
  872. },
  873. ActiveNodesMap {
  874. {0, {"testSkeletalMotion0"}},
  875. {77, {"testSkeletalMotion0"}},
  876. {78, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  877. {107, {"testSkeletalMotion0", "testSkeletalMotion1"}},
  878. {108, {"testSkeletalMotion1"}}
  879. }
  880. }
  881. };
  882. static const std::vector<ConditionFixtureParams<AnimGraphVector2Condition>> vector2TransitionConditionData
  883. {
  884. // --------------------------------------------------------------------
  885. // FUNCTION_EQUAL
  886. {
  887. [](AnimGraphVector2Condition* condition) {
  888. condition->SetParameterName("Vector2Param");
  889. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  890. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_EQUAL);
  891. condition->SetTestValue(0.5f);
  892. },
  893. moveToMotion1AtFrameThirty,
  894. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.5f, 0.0f)); })
  895. },
  896. {
  897. [](AnimGraphVector2Condition* condition) {
  898. condition->SetParameterName("Vector2Param");
  899. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  900. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_EQUAL);
  901. condition->SetTestValue(0.5f);
  902. },
  903. moveToMotion1AtFrameThirty,
  904. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.0f, 0.5f)); })
  905. },
  906. {
  907. [](AnimGraphVector2Condition* condition) {
  908. condition->SetParameterName("Vector2Param");
  909. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  910. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_EQUAL);
  911. condition->SetTestValue(0.5f);
  912. },
  913. moveToMotion1AtFrameThirty,
  914. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(std::sqrt(0.25f / 2.0f), std::sqrt(0.25f / 2.0f))); })
  915. },
  916. // --------------------------------------------------------------------
  917. // FUNCTION_NOTEQUAL
  918. {
  919. [](AnimGraphVector2Condition* condition) {
  920. condition->SetParameterName("Vector2Param");
  921. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  922. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_NOTEQUAL);
  923. condition->SetTestValue(0.1f);
  924. },
  925. moveToMotion1AtFrameThirty,
  926. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.5f, 0.0f)); })
  927. },
  928. {
  929. [](AnimGraphVector2Condition* condition) {
  930. condition->SetParameterName("Vector2Param");
  931. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  932. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_NOTEQUAL);
  933. condition->SetTestValue(0.1f);
  934. },
  935. moveToMotion1AtFrameThirty,
  936. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.0f, 0.5f)); })
  937. },
  938. {
  939. [](AnimGraphVector2Condition* condition) {
  940. condition->SetParameterName("Vector2Param");
  941. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  942. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_NOTEQUAL);
  943. condition->SetTestValue(std::sqrt(0.1f*0.1f + 0.1f*0.1f));
  944. },
  945. moveToMotion1AtFrameThirty,
  946. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(std::sqrt(0.25f / 2.0f), std::sqrt(0.25f / 2.0f))); })
  947. },
  948. // --------------------------------------------------------------------
  949. // FUNCTION_LESS
  950. {
  951. [](AnimGraphVector2Condition* condition) {
  952. condition->SetParameterName("Vector2Param");
  953. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  954. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESS);
  955. condition->SetTestValue(0.1f);
  956. },
  957. moveToMotion1AtFrameThirty,
  958. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.05f, 0.0f)); })
  959. },
  960. {
  961. [](AnimGraphVector2Condition* condition) {
  962. condition->SetParameterName("Vector2Param");
  963. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  964. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESS);
  965. condition->SetTestValue(0.1f);
  966. },
  967. moveToMotion1AtFrameThirty,
  968. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.0f, 0.05f)); })
  969. },
  970. {
  971. [](AnimGraphVector2Condition* condition) {
  972. condition->SetParameterName("Vector2Param");
  973. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  974. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESS);
  975. condition->SetTestValue(0.1f);
  976. },
  977. moveToMotion1AtFrameThirty,
  978. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.05f, 0.05f)); })
  979. },
  980. // --------------------------------------------------------------------
  981. // FUNCTION_GREATER
  982. {
  983. [](AnimGraphVector2Condition* condition) {
  984. condition->SetParameterName("Vector2Param");
  985. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  986. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATER);
  987. condition->SetTestValue(0.1f);
  988. },
  989. moveToMotion1AtFrameThirty,
  990. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.15f, 0.0f)); })
  991. },
  992. {
  993. [](AnimGraphVector2Condition* condition) {
  994. condition->SetParameterName("Vector2Param");
  995. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  996. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATER);
  997. condition->SetTestValue(0.1f);
  998. },
  999. moveToMotion1AtFrameThirty,
  1000. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.0f, 0.15f)); })
  1001. },
  1002. {
  1003. [](AnimGraphVector2Condition* condition) {
  1004. condition->SetParameterName("Vector2Param");
  1005. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  1006. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATER);
  1007. condition->SetTestValue(0.2f);
  1008. },
  1009. moveToMotion1AtFrameThirty,
  1010. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.25f, 0.0f)); })
  1011. },
  1012. // --------------------------------------------------------------------
  1013. // FUNCTION_GREATEREQUAL
  1014. {
  1015. [](AnimGraphVector2Condition* condition) {
  1016. condition->SetParameterName("Vector2Param");
  1017. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  1018. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATEREQUAL);
  1019. condition->SetTestValue(0.2f);
  1020. },
  1021. moveToMotion1AtFrameThirty,
  1022. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.2f, 0.0f)); })
  1023. },
  1024. {
  1025. [](AnimGraphVector2Condition* condition) {
  1026. condition->SetParameterName("Vector2Param");
  1027. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  1028. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATEREQUAL);
  1029. condition->SetTestValue(0.2f);
  1030. },
  1031. moveToMotion1AtFrameThirty,
  1032. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.3f, 0.0f)); })
  1033. },
  1034. {
  1035. [](AnimGraphVector2Condition* condition) {
  1036. condition->SetParameterName("Vector2Param");
  1037. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  1038. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATEREQUAL);
  1039. condition->SetTestValue(0.2f);
  1040. },
  1041. moveToMotion1AtFrameThirty,
  1042. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.0f, 0.2f)); })
  1043. },
  1044. {
  1045. [](AnimGraphVector2Condition* condition) {
  1046. condition->SetParameterName("Vector2Param");
  1047. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  1048. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATEREQUAL);
  1049. condition->SetTestValue(0.2f);
  1050. },
  1051. moveToMotion1AtFrameThirty,
  1052. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.0f, 0.3f)); })
  1053. },
  1054. {
  1055. [](AnimGraphVector2Condition* condition) {
  1056. condition->SetParameterName("Vector2Param");
  1057. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  1058. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATEREQUAL);
  1059. condition->SetTestValue(0.5f);
  1060. },
  1061. moveToMotion1AtFrameThirty,
  1062. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(1.0f, 0.0f)); })
  1063. },
  1064. {
  1065. [](AnimGraphVector2Condition* condition) {
  1066. condition->SetParameterName("Vector2Param");
  1067. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  1068. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_GREATEREQUAL);
  1069. condition->SetTestValue(0.5f);
  1070. },
  1071. moveToMotion1AtFrameThirty,
  1072. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.5f, 0.0f)); })
  1073. },
  1074. // --------------------------------------------------------------------
  1075. // FUNCTION_LESSEQUAL
  1076. {
  1077. [](AnimGraphVector2Condition* condition) {
  1078. condition->SetParameterName("Vector2Param");
  1079. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  1080. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESSEQUAL);
  1081. condition->SetTestValue(0.1f);
  1082. },
  1083. moveToMotion1AtFrameThirty,
  1084. std::bind(ChangeVector2ParamSpecial, std::placeholders::_1, std::placeholders::_2, 30, AZ::Vector2(0.05f, 0.0f), AZ::Vector2(1.0f, 1.0f))
  1085. },
  1086. {
  1087. [](AnimGraphVector2Condition* condition) {
  1088. condition->SetParameterName("Vector2Param");
  1089. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  1090. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESSEQUAL);
  1091. condition->SetTestValue(0.5f);
  1092. },
  1093. moveToMotion1AtFrameThirty,
  1094. std::bind(ChangeVector2ParamSpecial, std::placeholders::_1, std::placeholders::_2, 30, AZ::Vector2(0.5f, 0.0f), AZ::Vector2(1.0f, 1.0f))
  1095. },
  1096. {
  1097. [](AnimGraphVector2Condition* condition) {
  1098. condition->SetParameterName("Vector2Param");
  1099. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  1100. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESSEQUAL);
  1101. condition->SetTestValue(0.1f);
  1102. },
  1103. moveToMotion1AtFrameThirty,
  1104. std::bind(ChangeVector2ParamSpecial, std::placeholders::_1, std::placeholders::_2, 30, AZ::Vector2(0.0f, 0.05f), AZ::Vector2(1.0f, 1.0f))
  1105. },
  1106. {
  1107. [](AnimGraphVector2Condition* condition) {
  1108. condition->SetParameterName("Vector2Param");
  1109. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  1110. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESSEQUAL);
  1111. condition->SetTestValue(0.5f);
  1112. },
  1113. moveToMotion1AtFrameThirty,
  1114. std::bind(ChangeVector2ParamSpecial, std::placeholders::_1, std::placeholders::_2, 30, AZ::Vector2(0.0f, 0.5f), AZ::Vector2(1.0f, 1.0f))
  1115. },
  1116. {
  1117. [](AnimGraphVector2Condition* condition) {
  1118. condition->SetParameterName("Vector2Param");
  1119. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  1120. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESSEQUAL);
  1121. condition->SetTestValue(0.1f);
  1122. },
  1123. moveToMotion1AtFrameThirty,
  1124. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.05f, 0.0f)); })
  1125. },
  1126. {
  1127. [](AnimGraphVector2Condition* condition) {
  1128. condition->SetParameterName("Vector2Param");
  1129. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  1130. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_LESSEQUAL);
  1131. condition->SetTestValue(0.5f);
  1132. },
  1133. moveToMotion1AtFrameThirty,
  1134. std::bind(ChangeVector2ParamSpecial, std::placeholders::_1, std::placeholders::_2, 30, AZ::Vector2(0.5f, 0.0f), AZ::Vector2(1.0f, 1.0f))
  1135. },
  1136. // --------------------------------------------------------------------
  1137. // FUNCTION_INRANGE
  1138. {
  1139. [](AnimGraphVector2Condition* condition) {
  1140. condition->SetParameterName("Vector2Param");
  1141. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  1142. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_INRANGE);
  1143. condition->SetTestValue(0.2f);
  1144. condition->SetRangeValue(0.3f);
  1145. },
  1146. moveToMotion1AtFrameThirty,
  1147. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.25f, 0.0f)); })
  1148. },
  1149. {
  1150. [](AnimGraphVector2Condition* condition) {
  1151. condition->SetParameterName("Vector2Param");
  1152. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  1153. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_INRANGE);
  1154. condition->SetTestValue(0.2f);
  1155. condition->SetRangeValue(0.3f);
  1156. },
  1157. moveToMotion1AtFrameThirty,
  1158. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.0f, 0.25f)); })
  1159. },
  1160. {
  1161. [](AnimGraphVector2Condition* condition) {
  1162. condition->SetParameterName("Vector2Param");
  1163. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  1164. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_INRANGE);
  1165. condition->SetTestValue(0.2f);
  1166. condition->SetRangeValue(0.3f);
  1167. },
  1168. moveToMotion1AtFrameThirty,
  1169. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.15f, 0.15f)); })
  1170. },
  1171. // --------------------------------------------------------------------
  1172. // FUNCTION_NOTINRANGE
  1173. {
  1174. [](AnimGraphVector2Condition* condition) {
  1175. condition->SetParameterName("Vector2Param");
  1176. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETX);
  1177. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_NOTINRANGE);
  1178. condition->SetTestValue(0.05f);
  1179. condition->SetRangeValue(0.15f);
  1180. },
  1181. moveToMotion1AtFrameThirty,
  1182. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.25f, 0.0f)); })
  1183. },
  1184. {
  1185. [](AnimGraphVector2Condition* condition) {
  1186. condition->SetParameterName("Vector2Param");
  1187. condition->SetOperation(AnimGraphVector2Condition::OPERATION_GETY);
  1188. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_NOTINRANGE);
  1189. condition->SetTestValue(0.05f);
  1190. condition->SetRangeValue(0.15f);
  1191. },
  1192. moveToMotion1AtFrameThirty,
  1193. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.0f, 0.25f)); })
  1194. },
  1195. {
  1196. [](AnimGraphVector2Condition* condition) {
  1197. condition->SetParameterName("Vector2Param");
  1198. condition->SetOperation(AnimGraphVector2Condition::OPERATION_LENGTH);
  1199. condition->SetFunction(AnimGraphParameterCondition::FUNCTION_NOTINRANGE);
  1200. condition->SetTestValue(0.05f);
  1201. condition->SetRangeValue(0.15f);
  1202. },
  1203. moveToMotion1AtFrameThirty,
  1204. std::bind(ChangeVector2Param, std::placeholders::_1, std::placeholders::_2, 30, [](MCore::AttributeVector2* vec2) { vec2->SetValue(AZ::Vector2(0.15f, 0.15f)); })
  1205. },
  1206. };
  1207. using MotionConditionFixture = TransitionConditionFixtureP<AnimGraphMotionCondition>;
  1208. TEST_P(MotionConditionFixture, TestTransitionCondition)
  1209. {
  1210. RunEMotionFXUpdateLoop();
  1211. }
  1212. INSTANTIATE_TEST_CASE_P(TestMotionCondition, MotionConditionFixture,
  1213. ::testing::ValuesIn(motionTransitionConditionData)
  1214. );
  1215. TEST_P(RangedMotionEventConditionFixture, TestTransitionCondition)
  1216. {
  1217. RunEMotionFXUpdateLoop();
  1218. }
  1219. INSTANTIATE_TEST_CASE_P(TestRangedMotionCondition, RangedMotionEventConditionFixture,
  1220. ::testing::ValuesIn(rangedMotionTransitionConditionData)
  1221. );
  1222. using ParameterConditionFixture = TransitionConditionFixtureP<AnimGraphParameterCondition>;
  1223. TEST_P(ParameterConditionFixture, TestTransitionCondition)
  1224. {
  1225. RunEMotionFXUpdateLoop();
  1226. }
  1227. INSTANTIATE_TEST_CASE_P(TestParameterCondition, ParameterConditionFixture,
  1228. ::testing::ValuesIn(parameterTransitionConditionData)
  1229. );
  1230. using PlayTimeConditionFixture = TransitionConditionFixtureP<AnimGraphPlayTimeCondition>;
  1231. TEST_P(PlayTimeConditionFixture, TestTransitionCondition)
  1232. {
  1233. RunEMotionFXUpdateLoop();
  1234. }
  1235. INSTANTIATE_TEST_CASE_P(TestPlayTimeCondition, PlayTimeConditionFixture,
  1236. ::testing::ValuesIn(playTimeTransitionConditionData)
  1237. );
  1238. TEST_P(StateConditionFixture, TestTransitionCondition)
  1239. {
  1240. RunEMotionFXUpdateLoop();
  1241. }
  1242. INSTANTIATE_TEST_CASE_P(TestStateCondition, StateConditionFixture,
  1243. ::testing::ValuesIn(stateTransitionConditionData)
  1244. );
  1245. using TagConditionFixture = TransitionConditionFixtureP<AnimGraphTagCondition>;
  1246. TEST_P(TagConditionFixture, TestTransitionCondition)
  1247. {
  1248. RunEMotionFXUpdateLoop();
  1249. }
  1250. INSTANTIATE_TEST_CASE_P(TestTagCondition, TagConditionFixture,
  1251. ::testing::ValuesIn(tagTransitionConditionData)
  1252. );
  1253. using TimeConditionFixture = TransitionConditionFixtureP<AnimGraphTimeCondition>;
  1254. TEST_P(TimeConditionFixture, TestTransitionCondition)
  1255. {
  1256. RunEMotionFXUpdateLoop();
  1257. }
  1258. INSTANTIATE_TEST_CASE_P(TestTimeCondition, TimeConditionFixture,
  1259. ::testing::ValuesIn(timeTransitionConditionData)
  1260. );
  1261. using Vector2ConditionFixture = TransitionConditionFixtureP<AnimGraphVector2Condition>;
  1262. TEST_P(Vector2ConditionFixture, TestTransitionCondition)
  1263. {
  1264. RunEMotionFXUpdateLoop();
  1265. }
  1266. INSTANTIATE_TEST_CASE_P(TestVector2Condition, Vector2ConditionFixture,
  1267. ::testing::ValuesIn(vector2TransitionConditionData)
  1268. );
  1269. } // end namespace EMotionFX