AnimViewportToolBar.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 <QToolButton>
  9. #include <QPushButton>
  10. #include <QMenu>
  11. #include <QSettings>
  12. #include <EMStudio/AtomRenderPlugin.h>
  13. #include <EMStudio/AnimViewportToolBar.h>
  14. #include <EMStudio/AnimViewportRequestBus.h>
  15. #include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
  16. #include <AzCore/std/string/string.h>
  17. #include <AzQtComponents/Components/Widgets/ToolBar.h>
  18. namespace EMStudio
  19. {
  20. AnimViewportToolBar::AnimViewportToolBar(AtomRenderPlugin* plugin, QWidget* parent)
  21. : QToolBar(parent)
  22. , m_plugin(plugin)
  23. {
  24. AzQtComponents::ToolBar::addMainToolBarStyle(this);
  25. // Add the manipulator actions
  26. QActionGroup* manipulatorGroup = new QActionGroup(this);
  27. manipulatorGroup->setExclusive(true);
  28. manipulatorGroup->setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional);
  29. m_manipulatorActions[RenderOptions::TRANSLATE] = addAction(QIcon(":/EMotionFXAtom/Translate.svg"), "Translate");
  30. m_manipulatorActions[RenderOptions::ROTATE] = addAction(QIcon(":/EMotionFXAtom/Rotate.svg"), "Rotate");
  31. m_manipulatorActions[RenderOptions::SCALE] = addAction(QIcon(":/EMotionFXAtom/Scale.svg"), "Scale");
  32. for (size_t i = RenderOptions::ManipulatorMode::TRANSLATE; i < RenderOptions::ManipulatorMode::NUM_MODES; ++i)
  33. {
  34. m_manipulatorActions[i]->setCheckable(true);
  35. connect(
  36. m_manipulatorActions[i], &QAction::triggered, this,
  37. [this, i]()
  38. {
  39. const RenderOptions::ManipulatorMode mode =
  40. m_manipulatorActions[i]->isChecked() ? RenderOptions::ManipulatorMode(i) : RenderOptions::ManipulatorMode::SELECT;
  41. m_plugin->GetRenderOptions()->SetManipulatorMode(mode);
  42. m_plugin->SetManipulatorMode(mode);
  43. });
  44. manipulatorGroup->addAction(m_manipulatorActions[i]);
  45. }
  46. addSeparator();
  47. // Add the render view options button
  48. QToolButton* renderOptionsButton = new QToolButton(this);
  49. {
  50. QMenu* contextMenu = new QMenu(renderOptionsButton);
  51. renderOptionsButton->setText("Render Options");
  52. renderOptionsButton->setMenu(contextMenu);
  53. renderOptionsButton->setPopupMode(QToolButton::InstantPopup);
  54. renderOptionsButton->setVisible(true);
  55. renderOptionsButton->setIcon(QIcon(":/EMotionFXAtom/Visualization.svg"));
  56. addWidget(renderOptionsButton);
  57. CreateViewOptionEntry(contextMenu, "Solid", EMotionFX::ActorRenderFlagIndex::SOLID);
  58. CreateViewOptionEntry(contextMenu, "Wireframe", EMotionFX::ActorRenderFlagIndex::WIREFRAME);
  59. // [EMFX-TODO] Add those option once implemented.
  60. // CreateViewOptionEntry(contextMenu, "Lighting", EMotionFX::ActorRenderFlagIndex::RENDER_LIGHTING);
  61. // CreateViewOptionEntry(contextMenu, "Backface Culling", EMotionFX::ActorRenderFlagIndex::RENDER_BACKFACECULLING);
  62. contextMenu->addSeparator();
  63. CreateViewOptionEntry(contextMenu, "Vertex Normals", EMotionFX::ActorRenderFlagIndex::VERTEXNORMALS);
  64. CreateViewOptionEntry(contextMenu, "Face Normals", EMotionFX::ActorRenderFlagIndex::FACENORMALS);
  65. CreateViewOptionEntry(contextMenu, "Tangents", EMotionFX::ActorRenderFlagIndex::TANGENTS);
  66. CreateViewOptionEntry(contextMenu, "Actor Bounding Boxes", EMotionFX::ActorRenderFlagIndex::AABB);
  67. contextMenu->addSeparator();
  68. CreateViewOptionEntry(contextMenu, "Line Skeleton", EMotionFX::ActorRenderFlagIndex::LINESKELETON);
  69. CreateViewOptionEntry(contextMenu, "Solid Skeleton", EMotionFX::ActorRenderFlagIndex::SKELETON);
  70. CreateViewOptionEntry(contextMenu, "Joint Names", EMotionFX::ActorRenderFlagIndex::NODENAMES);
  71. CreateViewOptionEntry(contextMenu, "Joint Orientations", EMotionFX::ActorRenderFlagIndex::NODEORIENTATION);
  72. // [EMFX-TODO] Add those option once implemented.
  73. // CreateViewOptionEntry(contextMenu, "Actor Bind Pose", EMotionFX::ActorRenderFlagIndex::RENDER_ACTORBINDPOSE);
  74. contextMenu->addSeparator();
  75. CreateViewOptionEntry(contextMenu, "Hit Detection Colliders", EMotionFX::ActorRenderFlagIndex::HITDETECTION_COLLIDERS, true,
  76. ":/EMotionFXAtom/HitDetection.svg");
  77. CreateViewOptionEntry(contextMenu, "Ragdoll Colliders", EMotionFX::ActorRenderFlagIndex::RAGDOLL_COLLIDERS, true,
  78. ":/EMotionFXAtom/RagdollCollider.svg");
  79. CreateViewOptionEntry(contextMenu, "Ragdoll Joint Limits", EMotionFX::ActorRenderFlagIndex::RAGDOLL_JOINTLIMITS, true,
  80. ":/EMotionFXAtom/RagdollJointLimit.svg");
  81. CreateViewOptionEntry(contextMenu, "Cloth Colliders", EMotionFX::ActorRenderFlagIndex::CLOTH_COLLIDERS, true,
  82. ":/EMotionFXAtom/Cloth.svg");
  83. CreateViewOptionEntry(contextMenu, "Simulated Object Colliders", EMotionFX::ActorRenderFlagIndex::SIMULATEDOBJECT_COLLIDERS, true,
  84. ":/EMotionFXAtom/SimulatedObjectCollider.svg");
  85. CreateViewOptionEntry(contextMenu, "Simulated Joints", EMotionFX::ActorRenderFlagIndex::SIMULATEJOINTS);
  86. contextMenu->addSeparator();
  87. CreateViewOptionEntry(contextMenu, "Motion Extraction", EMotionFX::ActorRenderFlagIndex::MOTIONEXTRACTION);
  88. CreateViewOptionEntry(contextMenu, "Root Motion", EMotionFX::ActorRenderFlagIndex::ROOTMOTION);
  89. CreateViewOptionEntry(contextMenu, "Debug Rendering", EMotionFX::ActorRenderFlagIndex::EMFX_DEBUG);
  90. }
  91. // Add the camera button
  92. QToolButton* cameraButton = new QToolButton(this);
  93. {
  94. QMenu* cameraMenu = new QMenu(cameraButton);
  95. // Add the camera option
  96. const AZStd::vector<AZStd::pair<RenderOptions::CameraViewMode, AZStd::string>> cameraOptionNames = {
  97. { RenderOptions::CameraViewMode::FRONT, "Front" },
  98. { RenderOptions::CameraViewMode::BACK, "Back" },
  99. { RenderOptions::CameraViewMode::TOP, "Top" },
  100. { RenderOptions::CameraViewMode::BOTTOM, "Bottom" },
  101. { RenderOptions::CameraViewMode::LEFT, "Left" },
  102. { RenderOptions::CameraViewMode::RIGHT, "Right" },
  103. };
  104. for (const auto& pair : cameraOptionNames)
  105. {
  106. RenderOptions::CameraViewMode mode = pair.first;
  107. cameraMenu->addAction(
  108. pair.second.c_str(),
  109. [this, mode]()
  110. {
  111. m_plugin->GetRenderOptions()->SetCameraViewMode(mode);
  112. AnimViewportRequestBus::Broadcast(&AnimViewportRequestBus::Events::UpdateCameraViewMode, mode);
  113. });
  114. }
  115. cameraMenu->addSeparator();
  116. cameraMenu->addAction(
  117. "Reset Camera",
  118. [this]()
  119. {
  120. m_plugin->GetRenderOptions()->SetCameraViewMode(RenderOptions::CameraViewMode::DEFAULT);
  121. AnimViewportRequestBus::Broadcast(
  122. &AnimViewportRequestBus::Events::UpdateCameraViewMode, RenderOptions::CameraViewMode::DEFAULT);
  123. });
  124. cameraMenu->addSeparator();
  125. m_followCharacterAction = cameraMenu->addAction("Follow Character");
  126. m_followCharacterAction->setCheckable(true);
  127. m_followCharacterAction->setChecked(false);
  128. connect(m_followCharacterAction, &QAction::triggered, this,
  129. [this]()
  130. {
  131. m_plugin->GetRenderOptions()->SetCameraFollowUp(m_followCharacterAction->isChecked());
  132. AnimViewportRequestBus::Broadcast(
  133. &AnimViewportRequestBus::Events::UpdateCameraFollowUp, m_followCharacterAction->isChecked());
  134. ;
  135. });
  136. connect(cameraMenu, &QMenu::aboutToShow, this,
  137. [this]()
  138. {
  139. m_followCharacterAction->setChecked(m_plugin->GetRenderOptions()->GetCameraFollowUp());
  140. });
  141. cameraButton->setMenu(cameraMenu);
  142. cameraButton->setText("Camera Option");
  143. cameraButton->setPopupMode(QToolButton::InstantPopup);
  144. cameraButton->setVisible(true);
  145. cameraButton->setIcon(QIcon(":/EMotionFXAtom/Camera_category.svg"));
  146. addWidget(cameraButton);
  147. }
  148. LoadSettings();
  149. }
  150. AnimViewportToolBar::~AnimViewportToolBar()
  151. {
  152. }
  153. void AnimViewportToolBar::CreateViewOptionEntry(
  154. QMenu* menu, const char* menuEntryName, AZ::u8 actionIndex, bool visible, const char* iconFileName)
  155. {
  156. QAction* action = menu->addAction(
  157. menuEntryName,
  158. [this, actionIndex]()
  159. {
  160. m_plugin->GetRenderOptions()->ToggerRenderFlag(actionIndex);
  161. // Send the reset camera event.
  162. AnimViewportRequestBus::Broadcast(&AnimViewportRequestBus::Events::UpdateRenderFlags, m_plugin->GetRenderOptions()->GetRenderFlags());
  163. });
  164. action->setCheckable(true);
  165. action->setVisible(visible);
  166. if (iconFileName)
  167. {
  168. action->setIcon(QIcon(iconFileName));
  169. }
  170. m_renderActions[actionIndex] = action;
  171. }
  172. void AnimViewportToolBar::LoadSettings()
  173. {
  174. const RenderOptions* renderOptions = m_plugin->GetRenderOptions();
  175. const bool isChecked = renderOptions->GetCameraFollowUp();
  176. m_followCharacterAction->setChecked(isChecked);
  177. AnimViewportRequestBus::Broadcast(&AnimViewportRequestBus::Events::UpdateCameraFollowUp, isChecked);
  178. RenderOptions::ManipulatorMode mode = renderOptions->GetManipulatorMode();
  179. m_plugin->SetManipulatorMode(mode);
  180. if (mode != RenderOptions::ManipulatorMode::SELECT)
  181. {
  182. m_manipulatorActions[mode]->setChecked(true);
  183. }
  184. const EMotionFX::ActorRenderFlags renderFlags = renderOptions->GetRenderFlags();
  185. for (uint8 i = 0; i < EMotionFX::ActorRenderFlagIndex::NUM_RENDERFLAGINDEXES; ++i)
  186. {
  187. QAction* action = m_renderActions[i];
  188. if (action)
  189. {
  190. action->setChecked(EMotionFX::ActorRenderFlagUtil::CheckBit(renderFlags, i));
  191. }
  192. }
  193. }
  194. } // namespace EMStudio