ViewManager.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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. // Description : implementation of the CViewManager class.
  9. #include "EditorDefs.h"
  10. #include "ViewManager.h"
  11. // AzCore
  12. #include <AzCore/std/smart_ptr/make_shared.h>
  13. // AzToolsFramework
  14. #include <AzToolsFramework/ActionManager/Menu/MenuManagerInterface.h>
  15. #include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
  16. #include <AzToolsFramework/Manipulators/ManipulatorManager.h>
  17. // Editor
  18. #include "Settings.h"
  19. #include "MainWindow.h"
  20. #include "LayoutWnd.h"
  21. #include "EditorViewportWidget.h"
  22. #include "CryEditDoc.h"
  23. #include <AzCore/Console/IConsole.h>
  24. static constexpr AZStd::string_view MultiViewportToggleKey = "/O3DE/Viewport/MultiViewportEnabled";
  25. bool CViewManager::IsMultiViewportEnabled()
  26. {
  27. bool isMultiViewportEnabled = false;
  28. // Retrieve new action manager setting
  29. if (auto* registry = AZ::SettingsRegistry::Get())
  30. {
  31. registry->Get(isMultiViewportEnabled, MultiViewportToggleKey);
  32. }
  33. return isMultiViewportEnabled;
  34. }
  35. //////////////////////////////////////////////////////////////////////
  36. // Construction/Destruction
  37. //////////////////////////////////////////////////////////////////////
  38. CViewManager::CViewManager()
  39. {
  40. m_zoomFactor = 1;
  41. m_origin2D(0, 0, 0);
  42. m_zoom2D = 1.0f;
  43. m_updateRegion.min = Vec3(-100000, -100000, -100000);
  44. m_updateRegion.max = Vec3(100000, 100000, 100000);
  45. m_pSelectedView = nullptr;
  46. m_nGameViewports = 0;
  47. m_bGameViewportsUpdated = false;
  48. QtViewOptions viewportOptions;
  49. viewportOptions.paneRect = QRect(0, 0, 400, 400);
  50. viewportOptions.canHaveMultipleInstances = true;
  51. viewportOptions.viewportType = ET_ViewportCamera;
  52. RegisterQtViewPaneWithName<EditorViewportWidget>(GetIEditor(), "Perspective", LyViewPane::CategoryViewport, viewportOptions);
  53. GetIEditor()->RegisterNotifyListener(this);
  54. }
  55. //////////////////////////////////////////////////////////////////////////
  56. CViewManager::~CViewManager()
  57. {
  58. GetIEditor()->UnregisterNotifyListener(this);
  59. m_viewports.clear();
  60. }
  61. void CViewManager::ReleaseView(CViewport* pViewport)
  62. {
  63. pViewport->DestroyWindow();
  64. }
  65. //////////////////////////////////////////////////////////////////////////
  66. void CViewManager::RegisterViewport(CViewport* pViewport)
  67. {
  68. pViewport->SetViewManager(this);
  69. m_viewports.push_back(pViewport);
  70. // the type of added viewport can be changed later
  71. m_bGameViewportsUpdated = false;
  72. }
  73. //////////////////////////////////////////////////////////////////////////
  74. void CViewManager::UnregisterViewport(CViewport* pViewport)
  75. {
  76. if (m_pSelectedView == pViewport)
  77. {
  78. m_pSelectedView = nullptr;
  79. }
  80. stl::find_and_erase(m_viewports, pViewport);
  81. m_bGameViewportsUpdated = false;
  82. }
  83. //////////////////////////////////////////////////////////////////////////
  84. CViewport* CViewManager::GetViewport(EViewportType type) const
  85. {
  86. ////////////////////////////////////////////////////////////////////////
  87. // Returns the first view which has a render window of a specific
  88. // type attached
  89. ////////////////////////////////////////////////////////////////////////
  90. for (int i = 0; i < m_viewports.size(); i++)
  91. {
  92. if (m_viewports[i]->GetType() == type)
  93. {
  94. return m_viewports[i];
  95. }
  96. }
  97. return nullptr;
  98. }
  99. //////////////////////////////////////////////////////////////////////////
  100. CViewport* CViewManager::GetViewport(const QString& name) const
  101. {
  102. for (int i = 0; i < m_viewports.size(); i++)
  103. {
  104. if (QString::compare(m_viewports[i]->GetName(), name, Qt::CaseInsensitive) == 0)
  105. {
  106. return m_viewports[i];
  107. }
  108. }
  109. return nullptr;
  110. }
  111. //////////////////////////////////////////////////////////////////////////
  112. void CViewManager::SetZoomFactor(float zoom)
  113. {
  114. m_zoomFactor = zoom;
  115. }
  116. //////////////////////////////////////////////////////////////////////////
  117. void CViewManager::UpdateViews(int flags)
  118. {
  119. // Update each attached view,
  120. for (int i = 0; i < m_viewports.size(); i++)
  121. {
  122. m_viewports[i]->UpdateContent(flags);
  123. }
  124. }
  125. //////////////////////////////////////////////////////////////////////////
  126. void CViewManager::ResetViews()
  127. {
  128. // Reset each attached view,
  129. for (int i = 0; i < m_viewports.size(); i++)
  130. {
  131. m_viewports[i]->ResetContent();
  132. }
  133. }
  134. //////////////////////////////////////////////////////////////////////////
  135. void CViewManager::IdleUpdate()
  136. {
  137. // Update each attached view,
  138. for (int i = 0; i < m_viewports.size(); i++)
  139. {
  140. if (m_viewports[i]->GetType() != ET_ViewportCamera || (GetIEditor()->GetDocument() && GetIEditor()->GetDocument()->IsDocumentReady()))
  141. {
  142. m_viewports[i]->Update();
  143. }
  144. }
  145. }
  146. //////////////////////////////////////////////////////////////////////////
  147. void CViewManager::SetAxisConstrain(int axis)
  148. {
  149. for (int i = 0; i < m_viewports.size(); i++)
  150. {
  151. m_viewports[i]->SetAxisConstrain(axis);
  152. }
  153. }
  154. //////////////////////////////////////////////////////////////////////////
  155. CLayoutWnd* CViewManager::GetLayout() const
  156. {
  157. return MainWindow::instance()->GetLayout();
  158. }
  159. void CViewManager::SetZoom2D(float zoom)
  160. {
  161. m_zoom2D = zoom;
  162. if (m_zoom2D > 460.0f)
  163. {
  164. m_zoom2D = 460.0f;
  165. }
  166. };
  167. //////////////////////////////////////////////////////////////////////////
  168. void CViewManager::Cycle2DViewport()
  169. {
  170. GetLayout()->Cycle2DViewport();
  171. }
  172. //////////////////////////////////////////////////////////////////////////
  173. CViewport* CViewManager::GetViewportAtPoint(const QPoint& point) const
  174. {
  175. const auto viewportIter = AZStd::find_if(
  176. m_viewports.begin(),
  177. m_viewports.end(),
  178. [&point](CViewport* viewport) -> bool
  179. {
  180. auto* widget = viewport->widget();
  181. return widget && widget->rect().contains(widget->mapFromGlobal(point));
  182. }
  183. );
  184. return (viewportIter == m_viewports.end()) ? nullptr : *viewportIter;
  185. }
  186. //////////////////////////////////////////////////////////////////////////
  187. AZ::Vector3 CViewManager::GetClickPositionInViewportSpace() const
  188. {
  189. // Retrieve click position.
  190. QPoint clickPos = QCursor::pos();
  191. // If a context menu is active, get its position as the click position.
  192. if (auto menuManagerInterface = AZ::Interface<AzToolsFramework::MenuManagerInterface>::Get())
  193. {
  194. auto outcome = menuManagerInterface->GetLastContextMenuPosition();
  195. if (outcome.IsSuccess())
  196. {
  197. clickPos = outcome.GetValue();
  198. }
  199. }
  200. // If the click position was on a viewport, retrieve the position in world coordinates.
  201. AZ::Vector3 worldPosition = AZ::Vector3::CreateZero();
  202. if (CViewport* view = GetViewportAtPoint(clickPos))
  203. {
  204. QPoint relativeCursor = view->widget()->mapFromGlobal(clickPos);
  205. worldPosition = AzToolsFramework::FindClosestPickIntersection(
  206. view->GetViewportId(),
  207. AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(relativeCursor),
  208. AzToolsFramework::EditorPickRayLength,
  209. AzToolsFramework::GetDefaultEntityPlacementDistance());
  210. }
  211. return worldPosition;
  212. }
  213. //////////////////////////////////////////////////////////////////////////
  214. void CViewManager::SelectViewport(CViewport* pViewport)
  215. {
  216. // Audio: Handle viewport change for listeners
  217. if (m_pSelectedView != nullptr && m_pSelectedView != pViewport)
  218. {
  219. m_pSelectedView->SetSelected(false);
  220. }
  221. m_pSelectedView = pViewport;
  222. if (m_pSelectedView != nullptr)
  223. {
  224. m_pSelectedView->SetSelected(true);
  225. }
  226. }
  227. //////////////////////////////////////////////////////////////////////////
  228. CViewport* CViewManager::GetGameViewport() const
  229. {
  230. return GetViewport(ET_ViewportCamera);;
  231. }
  232. //////////////////////////////////////////////////////////////////////////
  233. int CViewManager::GetNumberOfGameViewports()
  234. {
  235. if (m_bGameViewportsUpdated)
  236. {
  237. return m_nGameViewports;
  238. }
  239. m_nGameViewports = 0;
  240. for (int i = 0; i < m_viewports.size(); ++i)
  241. {
  242. if (m_viewports[i]->GetType() == ET_ViewportCamera)
  243. {
  244. ++m_nGameViewports;
  245. }
  246. }
  247. m_bGameViewportsUpdated = true;
  248. return m_nGameViewports;
  249. }
  250. //////////////////////////////////////////////////////////////////////////
  251. void CViewManager::OnEditorNotifyEvent(EEditorNotifyEvent event)
  252. {
  253. switch (event)
  254. {
  255. case eNotify_OnIdleUpdate:
  256. IdleUpdate();
  257. break;
  258. case eNotify_OnUpdateViewports:
  259. UpdateViews();
  260. break;
  261. }
  262. }
  263. AZStd::shared_ptr<AzToolsFramework::ManipulatorManager> CViewManager::GetManipulatorManager()
  264. {
  265. return m_manipulatorManager;
  266. }