ViewportNudge.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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 "EditorCommon.h"
  9. #include "ViewportNudge.h"
  10. static const float slowNudgePixelDistance = 1.0f;
  11. static const float fastNudgePixelDistance = 10.0f;
  12. static const float slowNudgeRotationDegrees = 1.0f;
  13. static const float fastNudgeRotationDegrees = 10.0f;
  14. void ViewportNudge::Nudge(
  15. EditorWindow* editorWindow,
  16. ViewportInteraction::InteractionMode interactionMode,
  17. [[maybe_unused]] ViewportWidget* viewport,
  18. ViewportInteraction::NudgeDirection direction,
  19. ViewportInteraction::NudgeSpeed speed,
  20. const QTreeWidgetItemRawPtrQList& selectedItems,
  21. ViewportInteraction::CoordinateSystem coordinateSystem,
  22. const AZ::Uuid& transformComponentType)
  23. {
  24. bool isMoveOrAnchorMode = interactionMode == ViewportInteraction::InteractionMode::MOVE || interactionMode == ViewportInteraction::InteractionMode::ANCHOR;
  25. if (isMoveOrAnchorMode)
  26. {
  27. float translation = slowNudgePixelDistance;
  28. switch (speed)
  29. {
  30. case ViewportInteraction::NudgeSpeed::Fast:
  31. {
  32. translation = fastNudgePixelDistance;
  33. }
  34. break;
  35. case ViewportInteraction::NudgeSpeed::Slow:
  36. {
  37. translation = slowNudgePixelDistance;
  38. }
  39. break;
  40. default:
  41. {
  42. AZ_Assert(0, "Unknown speed");
  43. }
  44. break;
  45. }
  46. // Translate.
  47. {
  48. auto topLevelSelectedElements = SelectionHelpers::GetTopLevelSelectedElementsNotControlledByParent(editorWindow->GetHierarchy(), selectedItems);
  49. if (topLevelSelectedElements.empty())
  50. {
  51. // Nothing to do.
  52. return;
  53. }
  54. SerializeHelpers::SerializedEntryList preChangeState;
  55. HierarchyClipboard::BeginUndoableEntitiesChange(editorWindow, preChangeState);
  56. for (auto element : topLevelSelectedElements)
  57. {
  58. AZ::Vector2 deltaInCanvasSpace(0.0f, 0.0f);
  59. if (direction == ViewportInteraction::NudgeDirection::Up)
  60. {
  61. deltaInCanvasSpace.SetY(-translation);
  62. }
  63. else if (direction == ViewportInteraction::NudgeDirection::Down)
  64. {
  65. deltaInCanvasSpace.SetY(translation);
  66. }
  67. else if (direction == ViewportInteraction::NudgeDirection::Left)
  68. {
  69. deltaInCanvasSpace.SetX(-translation);
  70. }
  71. else if (direction == ViewportInteraction::NudgeDirection::Right)
  72. {
  73. deltaInCanvasSpace.SetX(translation);
  74. }
  75. else
  76. {
  77. AZ_Assert(0, "Unexpected direction.");
  78. }
  79. AZ::EntityId parentEntityId = EntityHelpers::GetParentElement(element->GetId())->GetId();
  80. AZ::Vector2 deltaInLocalSpace;
  81. if (coordinateSystem == ViewportInteraction::CoordinateSystem::LOCAL)
  82. {
  83. deltaInLocalSpace = deltaInCanvasSpace;
  84. }
  85. else // if (coordinateSystem == ViewportInteraction::CoordinateSystem::VIEW)
  86. {
  87. // compute the delta to move in local space (i.e. relative to the parent)
  88. deltaInLocalSpace = EntityHelpers::TransformDeltaFromCanvasToLocalSpace(parentEntityId, deltaInCanvasSpace);
  89. }
  90. if (interactionMode == ViewportInteraction::InteractionMode::MOVE)
  91. {
  92. EntityHelpers::MoveByLocalDeltaUsingOffsets(element->GetId(), deltaInLocalSpace);
  93. }
  94. else if (interactionMode == ViewportInteraction::InteractionMode::ANCHOR)
  95. {
  96. EntityHelpers::MoveByLocalDeltaUsingAnchors(element->GetId(), parentEntityId, deltaInLocalSpace, true);
  97. }
  98. // Update.
  99. UiElementChangeNotificationBus::Event(element->GetId(), &UiElementChangeNotificationBus::Events::UiElementPropertyChanged);
  100. }
  101. // Tell the Properties panel to update
  102. editorWindow->GetProperties()->TriggerRefresh(AzToolsFramework::PropertyModificationRefreshLevel::Refresh_Values, &transformComponentType);
  103. HierarchyClipboard::EndUndoableEntitiesChange(editorWindow, "nudge move", preChangeState);
  104. }
  105. }
  106. else if (interactionMode == ViewportInteraction::InteractionMode::ROTATE)
  107. {
  108. float rotationDirection = 1.0f;
  109. float rotationDeltaInDegrees = slowNudgeRotationDegrees;
  110. switch (speed)
  111. {
  112. case ViewportInteraction::NudgeSpeed::Fast:
  113. {
  114. rotationDeltaInDegrees = fastNudgeRotationDegrees;
  115. }
  116. break;
  117. case ViewportInteraction::NudgeSpeed::Slow:
  118. {
  119. rotationDeltaInDegrees = slowNudgeRotationDegrees;
  120. }
  121. break;
  122. default:
  123. {
  124. AZ_Assert(0, "Unknown speed");
  125. }
  126. break;
  127. }
  128. {
  129. if (direction == ViewportInteraction::NudgeDirection::Up ||
  130. (direction == ViewportInteraction::NudgeDirection::Left))
  131. {
  132. rotationDirection = -1.0f;
  133. }
  134. else if ((direction == ViewportInteraction::NudgeDirection::Down) ||
  135. (direction == ViewportInteraction::NudgeDirection::Right))
  136. {
  137. rotationDirection = 1.0f;
  138. }
  139. else
  140. {
  141. AZ_Assert(0, "Unexpected direction.");
  142. return;
  143. }
  144. }
  145. // Rotate.
  146. {
  147. auto topLevelSelectedElements = SelectionHelpers::GetTopLevelSelectedElements(editorWindow->GetHierarchy(), selectedItems);
  148. if (topLevelSelectedElements.empty())
  149. {
  150. // Nothing to do.
  151. return;
  152. }
  153. SerializeHelpers::SerializedEntryList preChangeState;
  154. HierarchyClipboard::BeginUndoableEntitiesChange(editorWindow, preChangeState);
  155. for (auto element : topLevelSelectedElements)
  156. {
  157. // Get.
  158. float rotation;
  159. UiTransformBus::EventResult(rotation, element->GetId(), &UiTransformBus::Events::GetZRotation);
  160. // Set.
  161. UiTransformBus::Event(
  162. element->GetId(), &UiTransformBus::Events::SetZRotation, (rotation + (rotationDeltaInDegrees * rotationDirection)));
  163. // Update.
  164. UiElementChangeNotificationBus::Event(element->GetId(), &UiElementChangeNotificationBus::Events::UiElementPropertyChanged);
  165. }
  166. // Tell the Properties panel to update
  167. editorWindow->GetProperties()->TriggerRefresh(AzToolsFramework::PropertyModificationRefreshLevel::Refresh_Values, &transformComponentType);
  168. HierarchyClipboard::EndUndoableEntitiesChange(editorWindow, "nudge rotate", preChangeState);
  169. }
  170. }
  171. }