MotionMatchingSystemComponent.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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/Console/IConsole.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <AzCore/Serialization/EditContext.h>
  11. #include <AzCore/Serialization/EditContextConstants.inl>
  12. #include <EMotionFX/Source/AnimGraphObjectFactory.h>
  13. #include <EMotionFX/Source/EMotionFXManager.h>
  14. #include <EMotionFX/Source/PoseDataFactory.h>
  15. #include <Integration/EMotionFXBus.h>
  16. #include <BlendTreeMotionMatchNode.h>
  17. #include <Feature.h>
  18. #include <FeatureAngularVelocity.h>
  19. #include <FeaturePosition.h>
  20. #include <FeatureTrajectory.h>
  21. #include <FeatureVelocity.h>
  22. #include <EventData.h>
  23. #include <MotionMatchingSystemComponent.h>
  24. #include <PoseDataJointVelocities.h>
  25. namespace EMotionFX::MotionMatching
  26. {
  27. AZ_CVAR(bool, mm_debugDraw, true, nullptr, AZ::ConsoleFunctorFlags::Null,
  28. "Global flag for motion matching debug drawing. Feature-wise debug drawing can be enabled or disabled in the anim graph itself.");
  29. AZ_CVAR(float, mm_debugDrawVelocityScale, 0.1f, nullptr, AZ::ConsoleFunctorFlags::Null,
  30. "Scaling value used for velocity debug rendering.");
  31. AZ_CVAR(bool, mm_debugDrawQueryPose, false, nullptr, AZ::ConsoleFunctorFlags::Null,
  32. "Draw the query skeletal pose used as input pose for the motion matching search.");
  33. AZ_CVAR(bool, mm_debugDrawQueryVelocities, false, nullptr, AZ::ConsoleFunctorFlags::Null,
  34. "Draw the query joint velocities used as input for the motion matching search.");
  35. AZ_CVAR(bool, mm_useKdTree, true, nullptr, AZ::ConsoleFunctorFlags::Null,
  36. "Use Kd-Tree to accelerate the motion matching search for the best next matching frame. "
  37. "Disabling it will heavily slow down performance and should only be done for debugging purposes");
  38. AZ_CVAR(bool, mm_multiThreadedInitialization, true, nullptr, AZ::ConsoleFunctorFlags::Null,
  39. "Use multi-threading to initialize motion matching.");
  40. void MotionMatchingSystemComponent::Reflect(AZ::ReflectContext* context)
  41. {
  42. if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
  43. {
  44. serialize->Class<MotionMatchingSystemComponent, AZ::Component>()
  45. ->Version(0)
  46. ;
  47. if (AZ::EditContext* ec = serialize->GetEditContext())
  48. {
  49. ec->Class<MotionMatchingSystemComponent>("MotionMatching", "[Description of functionality provided by this System Component]")
  50. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  51. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  52. ;
  53. }
  54. }
  55. EMotionFX::MotionMatching::DiscardFrameEventData::Reflect(context);
  56. EMotionFX::MotionMatching::TagEventData::Reflect(context);
  57. EMotionFX::MotionMatching::FeatureSchema::Reflect(context);
  58. EMotionFX::MotionMatching::Feature::Reflect(context);
  59. EMotionFX::MotionMatching::FeaturePosition::Reflect(context);
  60. EMotionFX::MotionMatching::FeatureTrajectory::Reflect(context);
  61. EMotionFX::MotionMatching::FeatureVelocity::Reflect(context);
  62. EMotionFX::MotionMatching::FeatureAngularVelocity::Reflect(context);
  63. EMotionFX::MotionMatching::PoseDataJointVelocities::Reflect(context);
  64. EMotionFX::MotionMatching::BlendTreeMotionMatchNode::Reflect(context);
  65. }
  66. void MotionMatchingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  67. {
  68. provided.push_back(AZ_CRC_CE("MotionMatchingService"));
  69. }
  70. void MotionMatchingSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  71. {
  72. incompatible.push_back(AZ_CRC_CE("MotionMatchingService"));
  73. }
  74. void MotionMatchingSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  75. {
  76. required.push_back(AZ_CRC_CE("EMotionFXAnimationService"));
  77. }
  78. void MotionMatchingSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
  79. {
  80. }
  81. MotionMatchingSystemComponent::MotionMatchingSystemComponent()
  82. {
  83. if (MotionMatchingInterface::Get() == nullptr)
  84. {
  85. MotionMatchingInterface::Register(this);
  86. }
  87. }
  88. MotionMatchingSystemComponent::~MotionMatchingSystemComponent()
  89. {
  90. if (MotionMatchingInterface::Get() == this)
  91. {
  92. MotionMatchingInterface::Unregister(this);
  93. }
  94. }
  95. void MotionMatchingSystemComponent::Init()
  96. {
  97. }
  98. void MotionMatchingSystemComponent::Activate()
  99. {
  100. MotionMatchingRequestBus::Handler::BusConnect();
  101. AZ::TickBus::Handler::BusConnect();
  102. // Register the motion matching anim graph node.
  103. {
  104. EMotionFX::AnimGraphObject* animGraphObject = EMotionFX::AnimGraphObjectFactory::Create(azrtti_typeid<EMotionFX::MotionMatching::BlendTreeMotionMatchNode>());
  105. auto animGraphNode = azdynamic_cast<EMotionFX::MotionMatching::BlendTreeMotionMatchNode*>(animGraphObject);
  106. if (animGraphNode)
  107. {
  108. EMotionFX::Integration::EMotionFXRequestBus::Broadcast(&EMotionFX::Integration::EMotionFXRequests::RegisterAnimGraphObjectType, animGraphNode);
  109. }
  110. delete animGraphObject;
  111. }
  112. // Register the joint velocities pose data.
  113. EMotionFX::GetPoseDataFactory().AddPoseDataType(azrtti_typeid<EMotionFX::MotionMatching::PoseDataJointVelocities>());
  114. }
  115. void MotionMatchingSystemComponent::Deactivate()
  116. {
  117. AZ::TickBus::Handler::BusDisconnect();
  118. MotionMatchingRequestBus::Handler::BusDisconnect();
  119. }
  120. void MotionMatchingSystemComponent::DebugDraw(AZ::s32 debugDisplayId)
  121. {
  122. AZ_PROFILE_SCOPE(Animation, "MotionMatchingSystemComponent::DebugDraw");
  123. if (debugDisplayId == -1)
  124. {
  125. return;
  126. }
  127. AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus;
  128. AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, debugDisplayId);
  129. AzFramework::DebugDisplayRequests* debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
  130. if (debugDisplay)
  131. {
  132. const AZ::u32 prevState = debugDisplay->GetState();
  133. EMotionFX::MotionMatching::DebugDrawRequestBus::Broadcast(&EMotionFX::MotionMatching::DebugDrawRequests::DebugDraw, *debugDisplay);
  134. debugDisplay->SetState(prevState);
  135. }
  136. }
  137. void MotionMatchingSystemComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
  138. {
  139. MotionMatchingSystemComponent::DebugDraw(AzFramework::g_defaultSceneEntityDebugDisplayId);
  140. }
  141. } // namespace EMotionFX::MotionMatching