BlendTreeMirrorPoseNodeTests.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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/Math/Vector3.h>
  9. #include <EMotionFX/Source/AnimGraph.h>
  10. #include <EMotionFX/Source/AnimGraphMotionNode.h>
  11. #include <EMotionFX/Source/AnimGraphStateMachine.h>
  12. #include <EMotionFX/Source/BlendTree.h>
  13. #include <EMotionFX/Source/BlendTreeFinalNode.h>
  14. #include <EMotionFX/Source/BlendTreeFloatConstantNode.h>
  15. #include <EMotionFX/Source/BlendTreeMirrorPoseNode.h>
  16. #include <EMotionFX/Source/EMotionFXManager.h>
  17. #include <EMotionFX/Source/Importer/Importer.h>
  18. #include <EMotionFX/Source/Motion.h>
  19. #include <EMotionFX/Source/MotionInstance.h>
  20. #include <EMotionFX/Source/MotionSet.h>
  21. #include <EMotionFX/Source/Node.h>
  22. #include <EMotionFX/Source/TransformData.h>
  23. #include <EMotionFX/Source/Skeleton.h>
  24. #include <Tests/JackGraphFixture.h>
  25. namespace EMotionFX
  26. {
  27. class BlendTreeMirrorPoseNodeFixture
  28. : public JackGraphFixture
  29. {
  30. public:
  31. void SetupMirrorNodes(const Node* leftNode, const Node* rightNode)
  32. {
  33. m_actor->GetNodeMirrorInfo(leftNode->GetNodeIndex()).m_sourceNode = static_cast<uint16>(rightNode->GetNodeIndex());
  34. m_actor->GetNodeMirrorInfo(rightNode->GetNodeIndex()).m_sourceNode = static_cast<uint16>(leftNode->GetNodeIndex());
  35. }
  36. void ConstructGraph() override
  37. {
  38. JackGraphFixture::ConstructGraph();
  39. // MirrorSetup for essential nodes in tests
  40. m_actor->AllocateNodeMirrorInfos();
  41. m_jackSkeleton = m_actor->GetSkeleton();
  42. const Node* lUpArmNode = m_jackSkeleton->FindNodeByName("l_upArm");
  43. const Node* rUpArmNode = m_jackSkeleton->FindNodeByName("r_upArm");
  44. const Node* lShldrNode = m_jackSkeleton->FindNodeByName("l_shldr");
  45. const Node* rShldrNode = m_jackSkeleton->FindNodeByName("r_shldr");
  46. const Node* lLoArmNode = m_jackSkeleton->FindNodeByName("l_loArm");
  47. const Node* rLoArmNode = m_jackSkeleton->FindNodeByName("r_loArm");
  48. const Node* lHandNode = m_jackSkeleton->FindNodeByName("l_hand");
  49. const Node* rHandNode = m_jackSkeleton->FindNodeByName("r_hand");
  50. SetupMirrorNodes(lUpArmNode, rUpArmNode);
  51. SetupMirrorNodes(lShldrNode, rShldrNode);
  52. SetupMirrorNodes(lLoArmNode, rLoArmNode);
  53. SetupMirrorNodes(lHandNode, rHandNode);
  54. m_actor->AutoDetectMirrorAxes();
  55. // Import a motion of Jack centered in the axis, with right arm raised up
  56. const AZStd::string base64MotionData = "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";
  57. AZStd::vector<AZ::u8> skeletalMotiondata;
  58. AzFramework::StringFunc::Base64::Decode(skeletalMotiondata, base64MotionData.c_str(), base64MotionData.size());
  59. Motion* rightAramUpMotion = EMotionFX::GetImporter().LoadMotion(skeletalMotiondata.begin(), skeletalMotiondata.size());
  60. EMotionFX::MotionSet::MotionEntry* rightAramUpmotionEntry = aznew EMotionFX::MotionSet::MotionEntry();
  61. rightAramUpmotionEntry->SetMotion(rightAramUpMotion);
  62. m_motionSet->AddMotionEntry(rightAramUpmotionEntry);
  63. m_motionSet->SetMotionEntryId(rightAramUpmotionEntry, "jack_right_arm_up");
  64. /*
  65. m_blendtree:
  66. +--------------------+
  67. |m_motionNode +---+
  68. | | |
  69. +--------------------+ | +--------------------+ +--------------------+
  70. +-->+m_mirrorPoseNode +----->+m_finalNode |
  71. +-->+ | | |
  72. +--------------------+ | +--------------------+ +--------------------+
  73. |m_floatConstantNode | |
  74. | +---+
  75. +--------------------+
  76. */
  77. AnimGraphMotionNode* motionNode = aznew AnimGraphMotionNode();
  78. motionNode->AddMotionId( "jack_right_arm_up" );
  79. m_floatConstantNode = aznew BlendTreeFloatConstantNode();
  80. m_mirrorPoseNode = aznew BlendTreeMirrorPoseNode();
  81. BlendTreeFinalNode* finalNode = aznew BlendTreeFinalNode();
  82. m_blendTree = aznew BlendTree();
  83. m_blendTree->AddChildNode(motionNode);
  84. m_blendTree->AddChildNode(m_floatConstantNode);
  85. m_blendTree->AddChildNode(m_mirrorPoseNode);
  86. m_blendTree->AddChildNode(finalNode);
  87. m_animGraph->GetRootStateMachine()->AddChildNode(m_blendTree);
  88. m_animGraph->GetRootStateMachine()->SetEntryState(m_blendTree);
  89. m_mirrorPoseNode->AddConnection(motionNode, AnimGraphMotionNode::OUTPUTPORT_POSE, BlendTreeMirrorPoseNode::INPUTPORT_POSE);
  90. m_mirrorPoseNode->AddConnection(m_floatConstantNode, BlendTreeFloatConstantNode::OUTPUTPORT_RESULT, BlendTreeMirrorPoseNode::INPUTPORT_ENABLED);
  91. finalNode->AddConnection(m_mirrorPoseNode, BlendTreeMirrorPoseNode::OUTPUTPORT_RESULT, BlendTreeFinalNode::INPUTPORT_POSE);
  92. };
  93. protected:
  94. BlendTree* m_blendTree = nullptr;
  95. BlendTreeFloatConstantNode* m_floatConstantNode = nullptr;
  96. BlendTreeMirrorPoseNode* m_mirrorPoseNode = nullptr;
  97. Skeleton* m_jackSkeleton = nullptr;
  98. };
  99. TEST_F(BlendTreeMirrorPoseNodeFixture, OutputsCorrectPose)
  100. {
  101. GetEMotionFX().Update(1.0f / 60.0f);
  102. size_t l_upArmIndex;
  103. size_t r_upArmIndex;
  104. size_t l_loArmIndex;
  105. size_t r_loArmIndex;
  106. size_t l_handIndex;
  107. size_t r_handIndex;
  108. m_jackSkeleton->FindNodeAndIndexByName("l_upArm", l_upArmIndex);
  109. m_jackSkeleton->FindNodeAndIndexByName("r_upArm", r_upArmIndex);
  110. m_jackSkeleton->FindNodeAndIndexByName("l_loArm", l_loArmIndex);
  111. m_jackSkeleton->FindNodeAndIndexByName("r_loArm", r_loArmIndex);
  112. m_jackSkeleton->FindNodeAndIndexByName("l_hand", l_handIndex);
  113. m_jackSkeleton->FindNodeAndIndexByName("r_hand", r_handIndex);
  114. // Mirror Pose Node not enabled
  115. m_floatConstantNode->SetValue(0.0f);
  116. // Remember the original position for comparison later
  117. Pose * jackPose = m_actorInstance->GetTransformData()->GetCurrentPose();
  118. const AZ::Vector3 l_upArmOriginalPos = jackPose->GetModelSpaceTransform(l_upArmIndex).m_position;
  119. const AZ::Vector3 r_upArmOriginalPos = jackPose->GetModelSpaceTransform(r_upArmIndex).m_position;
  120. GetEMotionFX().Update(1.0f / 60.0f);
  121. // Remember mirrored position
  122. const AZ::Vector3 l_upArmMirroredPos = jackPose->GetModelSpaceTransform(l_upArmIndex).m_position;
  123. const AZ::Vector3 r_upArmMirroredPos = jackPose->GetModelSpaceTransform(r_upArmIndex).m_position;
  124. // Expect poses to be at the same position because mirror pose node is off
  125. EXPECT_FALSE(m_mirrorPoseNode->GetIsMirroringEnabled(m_animGraphInstance));
  126. EXPECT_TRUE(l_upArmOriginalPos == l_upArmMirroredPos);
  127. EXPECT_TRUE(r_upArmOriginalPos == r_upArmMirroredPos);
  128. // Mirror Pose Node enabled
  129. m_floatConstantNode->SetValue(1.0f);
  130. const AZ::Vector3 l_upArmPos = jackPose->GetModelSpaceTransform(l_upArmIndex).m_position;
  131. const AZ::Vector3 r_upArmPos = jackPose->GetModelSpaceTransform(r_upArmIndex).m_position;
  132. const AZ::Vector3 l_loArmPos = jackPose->GetModelSpaceTransform(l_loArmIndex).m_position;
  133. const AZ::Vector3 r_loArmPos = jackPose->GetModelSpaceTransform(r_loArmIndex).m_position;
  134. const AZ::Vector3 l_handPos = jackPose->GetModelSpaceTransform(l_handIndex).m_position;
  135. const AZ::Vector3 r_handPos = jackPose->GetModelSpaceTransform(r_handIndex).m_position;
  136. GetEMotionFX().Update(1.0f / 60.0f);
  137. const AZ::Vector3 mirroredl_upArmPos = jackPose->GetModelSpaceTransform(l_upArmIndex).m_position;
  138. const AZ::Vector3 mirroredr_upArmPos = jackPose->GetModelSpaceTransform(r_upArmIndex).m_position;
  139. const AZ::Vector3 mirroredl_loArmPos = jackPose->GetModelSpaceTransform(l_loArmIndex).m_position;
  140. const AZ::Vector3 mirroredr_loArmPos = jackPose->GetModelSpaceTransform(r_loArmIndex).m_position;
  141. const AZ::Vector3 mirroredl_handPos = jackPose->GetModelSpaceTransform(l_handIndex).m_position;
  142. const AZ::Vector3 mirroredr_handPos = jackPose->GetModelSpaceTransform(r_handIndex).m_position;
  143. EXPECT_TRUE(m_mirrorPoseNode->GetIsMirroringEnabled(m_animGraphInstance));
  144. // If mirrored positions correctly changed, then mirror pose node is properly functioning.
  145. // Original position: Vector3(-x,y,z), mirrored across x-axis
  146. // Mirrored position: Vector3(x,y,z)
  147. EXPECT_NEAR(mirroredl_upArmPos.GetX(), -r_upArmPos.GetX(), AZ::Constants::Tolerance);
  148. EXPECT_NEAR(mirroredl_upArmPos.GetY(), r_upArmPos.GetY(), AZ::Constants::Tolerance);
  149. EXPECT_NEAR(mirroredl_upArmPos.GetZ(), r_upArmPos.GetZ(), AZ::Constants::Tolerance);
  150. EXPECT_NEAR(mirroredr_upArmPos.GetX(), -l_upArmPos.GetX(), AZ::Constants::Tolerance);
  151. EXPECT_NEAR(mirroredr_upArmPos.GetY(), l_upArmPos.GetY(), AZ::Constants::Tolerance);
  152. EXPECT_NEAR(mirroredr_upArmPos.GetZ(), l_upArmPos.GetZ(), AZ::Constants::Tolerance);
  153. EXPECT_NEAR(mirroredl_loArmPos.GetX(), -r_loArmPos.GetX(), AZ::Constants::Tolerance);
  154. EXPECT_NEAR(mirroredl_loArmPos.GetY(), r_loArmPos.GetY(), AZ::Constants::Tolerance);
  155. EXPECT_NEAR(mirroredl_loArmPos.GetZ(), r_loArmPos.GetZ(), AZ::Constants::Tolerance);
  156. EXPECT_NEAR(mirroredr_loArmPos.GetX(), -l_loArmPos.GetX(), AZ::Constants::Tolerance);
  157. EXPECT_NEAR(mirroredr_loArmPos.GetY(), l_loArmPos.GetY(), AZ::Constants::Tolerance);
  158. EXPECT_NEAR(mirroredr_loArmPos.GetZ(), l_loArmPos.GetZ(), AZ::Constants::Tolerance);
  159. EXPECT_NEAR(mirroredl_handPos.GetX(), -r_handPos.GetX(), AZ::Constants::Tolerance);
  160. EXPECT_NEAR(mirroredl_handPos.GetY(), r_handPos.GetY(), AZ::Constants::Tolerance);
  161. EXPECT_NEAR(mirroredl_handPos.GetZ(), r_handPos.GetZ(), AZ::Constants::Tolerance);
  162. EXPECT_NEAR(mirroredr_handPos.GetX(), -l_handPos.GetX(), AZ::Constants::Tolerance);
  163. EXPECT_NEAR(mirroredr_handPos.GetY(), l_handPos.GetY(), AZ::Constants::Tolerance);
  164. EXPECT_NEAR(mirroredr_handPos.GetZ(), l_handPos.GetZ(), AZ::Constants::Tolerance);
  165. };
  166. }// end namespace EMotionFX