JointLimitRotationManipulators.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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 <AzFramework/Viewport/ViewportColors.h>
  9. #include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
  10. #include <EMotionFX/CommandSystem/Source/JointLimitCommands.h>
  11. #include <EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
  12. #include <Editor/Plugins/Ragdoll/JointLimitRotationManipulators.h>
  13. #include <Editor/Plugins/Ragdoll/RagdollJointLimitWidget.h>
  14. namespace EMotionFX
  15. {
  16. JointLimitRotationManipulators::JointLimitRotationManipulators(JointLimitFrame jointLimitFrame)
  17. : m_jointLimitFrame(jointLimitFrame)
  18. {
  19. m_rotationManipulators.SetCircleBoundWidth(AzToolsFramework::ManipulatorCicleBoundWidth());
  20. }
  21. void JointLimitRotationManipulators::Setup(const PhysicsSetupManipulatorData& physicsSetupManipulatorData)
  22. {
  23. m_physicsSetupManipulatorData = physicsSetupManipulatorData;
  24. if (!m_physicsSetupManipulatorData.HasJointLimit())
  25. {
  26. return;
  27. }
  28. Refresh();
  29. m_rotationManipulators.Register(EMStudio::g_animManipulatorManagerId);
  30. m_rotationManipulators.SetLocalAxes(AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
  31. m_rotationManipulators.ConfigureView(
  32. 2.0f, AzFramework::ViewportColors::XAxisColor, AzFramework::ViewportColors::YAxisColor,
  33. AzFramework::ViewportColors::ZAxisColor);
  34. m_rotationManipulators.InstallLeftMouseDownCallback(
  35. [this]([[maybe_unused]] const AzToolsFramework::AngularManipulator::Action& action)
  36. {
  37. BeginEditing();
  38. });
  39. m_rotationManipulators.InstallMouseMoveCallback(
  40. [this](const AzToolsFramework::AngularManipulator::Action& action)
  41. {
  42. OnManipulatorMoved(action.LocalOrientation());
  43. });
  44. m_rotationManipulators.InstallLeftMouseUpCallback(
  45. [this]([[maybe_unused]] const AzToolsFramework::AngularManipulator::Action& action)
  46. {
  47. EndEditing();
  48. });
  49. AZ::TickBus::Handler::BusConnect();
  50. PhysicsSetupManipulatorRequestBus::Handler::BusConnect();
  51. m_adjustJointLimitCallback = AZStd::make_unique<PhysicsSetupManipulatorCommandCallback>(this, false);
  52. EMStudio::GetCommandManager()->RegisterCommandCallback("AdjustJointLimit", m_adjustJointLimitCallback.get());
  53. }
  54. void JointLimitRotationManipulators::Refresh()
  55. {
  56. if (m_physicsSetupManipulatorData.HasJointLimit())
  57. {
  58. if (m_jointLimitFrame == JointLimitFrame::Parent)
  59. {
  60. m_rotationManipulators.SetSpace(AZ::Transform::CreateFromQuaternionAndTranslation(
  61. m_physicsSetupManipulatorData.m_parentWorldTransform.GetRotation(),
  62. m_physicsSetupManipulatorData.m_nodeWorldTransform.GetTranslation()));
  63. }
  64. else
  65. {
  66. m_rotationManipulators.SetSpace(m_physicsSetupManipulatorData.m_nodeWorldTransform);
  67. }
  68. m_rotationManipulators.SetLocalPosition(AZ::Vector3::CreateZero());
  69. m_rotationManipulators.SetLocalOrientation(GetLocalOrientation());
  70. }
  71. }
  72. void JointLimitRotationManipulators::Teardown()
  73. {
  74. if (!m_physicsSetupManipulatorData.HasJointLimit())
  75. {
  76. return;
  77. }
  78. EMStudio::GetCommandManager()->RemoveCommandCallback(m_adjustJointLimitCallback.get(), false);
  79. m_adjustJointLimitCallback.reset();
  80. PhysicsSetupManipulatorRequestBus::Handler::BusDisconnect();
  81. AZ::TickBus::Handler::BusDisconnect();
  82. m_rotationManipulators.Unregister();
  83. }
  84. void JointLimitRotationManipulators::ResetValues()
  85. {
  86. if (m_physicsSetupManipulatorData.HasJointLimit())
  87. {
  88. BeginEditing();
  89. GetLocalOrientation() = AZ::Quaternion::CreateIdentity();
  90. EndEditing();
  91. Refresh();
  92. }
  93. }
  94. void JointLimitRotationManipulators::OnManipulatorMoved(const AZ::Quaternion& rotation)
  95. {
  96. m_rotationManipulators.SetLocalOrientation(rotation);
  97. if (m_physicsSetupManipulatorData.HasJointLimit())
  98. {
  99. GetLocalOrientation() = rotation;
  100. }
  101. InvalidateEditorValues();
  102. }
  103. void JointLimitRotationManipulators::BeginEditing()
  104. {
  105. CreateCommandAdjustJointLimit(m_commandGroup, m_physicsSetupManipulatorData);
  106. }
  107. void JointLimitRotationManipulators::EndEditing()
  108. {
  109. ExecuteCommandAdjustJointLimit(m_commandGroup, m_physicsSetupManipulatorData);
  110. }
  111. void JointLimitRotationManipulators::OnTick([[maybe_unused]] float delta, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
  112. {
  113. const AzFramework::CameraState cameraState = AzToolsFramework::GetCameraState(m_viewportId);
  114. m_rotationManipulators.RefreshView(cameraState.m_position);
  115. }
  116. void JointLimitRotationManipulators::OnUnderlyingPropertiesChanged()
  117. {
  118. Refresh();
  119. }
  120. AZ::Quaternion& JointLimitRotationManipulators::GetLocalOrientation()
  121. {
  122. return const_cast<AZ::Quaternion&>(static_cast<const JointLimitRotationManipulators&>(*this).GetLocalOrientation());
  123. }
  124. const AZ::Quaternion& JointLimitRotationManipulators::GetLocalOrientation() const
  125. {
  126. return m_jointLimitFrame == JointLimitFrame::Parent
  127. ? m_physicsSetupManipulatorData.m_jointConfiguration->m_parentLocalRotation
  128. : m_physicsSetupManipulatorData.m_jointConfiguration->m_childLocalRotation;
  129. }
  130. void JointLimitRotationManipulators::InvalidateEditorValues()
  131. {
  132. if (m_physicsSetupManipulatorData.m_jointLimitWidget)
  133. {
  134. m_physicsSetupManipulatorData.m_jointLimitWidget->InvalidateValues();
  135. }
  136. }
  137. void CreateCommandAdjustJointLimit(MCore::CommandGroup& commandGroup, const PhysicsSetupManipulatorData& physicsSetupManipulatorData)
  138. {
  139. if (!commandGroup.IsEmpty())
  140. {
  141. return;
  142. }
  143. commandGroup.SetGroupName("Adjust joint limit");
  144. const AZ::u32 actorId = physicsSetupManipulatorData.m_actor->GetID();
  145. const AZStd::string& nodeName = physicsSetupManipulatorData.m_node->GetNameString();
  146. CommandAdjustJointLimit* command = aznew CommandAdjustJointLimit(actorId, nodeName);
  147. commandGroup.AddCommand(command);
  148. command->SetOldJointConfiguration(physicsSetupManipulatorData.m_jointConfiguration);
  149. }
  150. void ExecuteCommandAdjustJointLimit(MCore::CommandGroup& commandGroup, const PhysicsSetupManipulatorData& physicsSetupManipulatorData)
  151. {
  152. if (commandGroup.IsEmpty())
  153. {
  154. return;
  155. }
  156. if (auto* command = azdynamic_cast<CommandAdjustJointLimit*>(commandGroup.GetCommand(0)))
  157. {
  158. command->SetJointConfiguration(physicsSetupManipulatorData.m_jointConfiguration);
  159. }
  160. AZStd::string result;
  161. CommandSystem::GetCommandManager()->ExecuteCommandGroup(commandGroup, result);
  162. commandGroup.Clear();
  163. }
  164. } // namespace EMotionFX