EditorViewportWidget.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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. #pragma once
  9. #if !defined(Q_MOC_RUN)
  10. #include <QSet>
  11. #include "EditorModularViewportCameraComposer.h"
  12. #include "EditorViewportSettings.h"
  13. #include "Objects/DisplayContext.h"
  14. #include "Undo/Undo.h"
  15. #include "Util/PredefinedAspectRatios.h"
  16. #include "Viewport.h"
  17. #include <Atom/RPI.Public/SceneBus.h>
  18. #include <Atom/RPI.Public/ViewportContext.h>
  19. #include <AzCore/Component/EntityId.h>
  20. #include <AzCore/std/optional.h>
  21. #include <AzFramework/Asset/AssetCatalogBus.h>
  22. #include <AzFramework/Components/CameraBus.h>
  23. #include <AzFramework/Input/Buses/Requests/InputSystemCursorRequestBus.h>
  24. #include <AzFramework/Scene/SceneSystemInterface.h>
  25. #include <AzFramework/Viewport/ViewportBus.h>
  26. #include <AzFramework/Visibility/EntityVisibilityQuery.h>
  27. #include <AzFramework/Windowing/WindowBus.h>
  28. #include <AzToolsFramework/API/EditorCameraBus.h>
  29. #include <AzToolsFramework/API/ToolsApplicationAPI.h>
  30. #include <AzToolsFramework/Entity/EditorEntityContextBus.h>
  31. #include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
  32. #include <AzToolsFramework/Viewport/ViewportMessages.h>
  33. #include <MathConversion.h>
  34. #endif
  35. // forward declarations.
  36. class CBaseObject;
  37. class QMenu;
  38. class QKeyEvent;
  39. struct ray_hit;
  40. struct IRenderMesh;
  41. struct IVariable;
  42. namespace AZ::ViewportHelpers
  43. {
  44. class EditorEntityNotifications;
  45. } // namespace AZ::ViewportHelpers
  46. namespace AtomToolsFramework
  47. {
  48. class RenderViewportWidget;
  49. class ModularViewportCameraController;
  50. } // namespace AtomToolsFramework
  51. namespace AzToolsFramework
  52. {
  53. class ManipulatorManager;
  54. }
  55. //! Viewport settings for the EditorViewportWidget
  56. struct EditorViewportSettings : public AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler
  57. {
  58. void Connect(AzFramework::ViewportId viewportId);
  59. void Disconnect();
  60. // ViewportSettingsRequestBus overrides ...
  61. bool GridSnappingEnabled() const override;
  62. float GridSize() const override;
  63. bool ShowGrid() const override;
  64. bool AngleSnappingEnabled() const override;
  65. float AngleStep() const override;
  66. float ManipulatorLineBoundWidth() const override;
  67. float ManipulatorCircleBoundWidth() const override;
  68. bool StickySelectEnabled() const override;
  69. AZ::Vector3 DefaultEditorCameraPosition() const override;
  70. AZ::Vector2 DefaultEditorCameraOrientation() const override;
  71. bool IconsVisible() const override;
  72. bool HelpersVisible() const override;
  73. bool OnlyShowHelpersForSelectedEntities() const override;
  74. };
  75. //! EditorViewportWidget window
  76. AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
  77. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  78. class SANDBOX_API EditorViewportWidget final
  79. : public QtViewport
  80. , public AzFramework::ViewportBorderRequestBus::Handler
  81. , private IEditorNotifyListener
  82. , private IUndoManagerListener
  83. , private Camera::EditorCameraRequestBus::Handler
  84. , private Camera::CameraNotificationBus::Handler
  85. , private AzFramework::InputSystemCursorConstraintRequestBus::Handler
  86. , private AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler
  87. , private AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler
  88. , private AzFramework::AssetCatalogEventBus::Handler
  89. , private AZ::RPI::SceneNotificationBus::Handler
  90. , private AzToolsFramework::Prefab::PrefabPublicNotificationBus::Handler
  91. {
  92. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  93. AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
  94. Q_OBJECT
  95. public:
  96. EditorViewportWidget(const QString& name, QWidget* parent = nullptr);
  97. ~EditorViewportWidget() override;
  98. static const GUID& GetClassID()
  99. {
  100. return QtViewport::GetClassID<EditorViewportWidget>();
  101. }
  102. static EditorViewportWidget* GetPrimaryViewport();
  103. // Used by ViewPan in some circumstances
  104. void ConnectViewportInteractionRequestBus();
  105. void DisconnectViewportInteractionRequestBus();
  106. // QtViewport/IDisplayViewport/CViewport
  107. // These methods are made public in the derived class because they are called with an object whose static type is known to be this class
  108. // type.
  109. void SetFOV(float fov) override;
  110. float GetFOV() const override;
  111. // AzFramework::ViewportBorderRequestBus overrides ...
  112. AZStd::optional<AzFramework::ViewportBorderPadding> GetViewportBorderPadding() const override;
  113. private:
  114. ////////////////////////////////////////////////////////////////////////
  115. // Private types ...
  116. enum class ViewSourceType
  117. {
  118. None,
  119. CameraComponent,
  120. ViewSourceTypesCount,
  121. };
  122. enum class PlayInEditorState
  123. {
  124. Editor,
  125. Starting,
  126. Started,
  127. Stopping
  128. };
  129. enum class KeyPressedState
  130. {
  131. AllUp,
  132. PressedThisFrame,
  133. PressedInPreviousFrame,
  134. };
  135. ////////////////////////////////////////////////////////////////////////
  136. // Method overrides ...
  137. // QWidget overrides ...
  138. void focusOutEvent(QFocusEvent* event) override;
  139. void keyPressEvent(QKeyEvent* event) override;
  140. bool event(QEvent* event) override;
  141. void resizeEvent(QResizeEvent* event) override;
  142. void paintEvent(QPaintEvent* event) override;
  143. void mousePressEvent(QMouseEvent* event) override;
  144. // QtViewport/IDisplayViewport/CViewport overrides ...
  145. EViewportType GetType() const override
  146. {
  147. return ET_ViewportCamera;
  148. }
  149. void SetType([[maybe_unused]] EViewportType type) override
  150. {
  151. assert(type == ET_ViewportCamera);
  152. };
  153. AzToolsFramework::ViewportInteraction::MouseInteraction BuildMouseInteraction(
  154. Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, const QPoint& point) override;
  155. void SetViewportId(int id) override;
  156. QPoint WorldToView(const Vec3& wp) const override;
  157. Vec3 WorldToView3D(const Vec3& wp, int nFlags = 0) const override;
  158. Vec3 ViewToWorld(
  159. const QPoint& vp,
  160. bool* collideWithTerrain = nullptr,
  161. bool onlyTerrain = false,
  162. bool bSkipVegetation = false,
  163. bool bTestRenderMesh = false,
  164. bool* collideWithObject = nullptr) const override;
  165. void ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const override;
  166. Vec3 ViewToWorldNormal(const QPoint& vp, bool onlyTerrain, bool bTestRenderMesh = false) override;
  167. float GetScreenScaleFactor(const Vec3& worldPoint) const override;
  168. float GetAspectRatio() const override;
  169. bool HitTest(const QPoint& point, HitContext& hitInfo) override;
  170. bool IsBoundsVisible(const AABB& box) const override;
  171. void CenterOnSelection() override;
  172. void CenterOnAABB(const AABB& aabb) override;
  173. void CenterOnSliceInstance() override;
  174. void OnTitleMenu(QMenu* menu) override;
  175. void SetViewTM(const Matrix34& tm) override;
  176. const Matrix34& GetViewTM() const override;
  177. void Update() override;
  178. void UpdateContent(int flags) override;
  179. // SceneNotificationBus overrides ...
  180. void OnBeginPrepareRender() override;
  181. // Camera::CameraNotificationBus overrides ...
  182. void OnActiveViewChanged(const AZ::EntityId&) override;
  183. // IEditorEventListener overrides ...
  184. void OnEditorNotifyEvent(EEditorNotifyEvent event) override;
  185. // Callback for setting modification
  186. void OnDefaultCameraNearFarChanged();
  187. // AzToolsFramework::EditorEntityContextNotificationBus overrides ...
  188. // note: handler moved to cpp to resolve link issues in unity builds
  189. void OnStartPlayInEditor();
  190. void OnStopPlayInEditor();
  191. void OnStartPlayInEditorBegin();
  192. // IUndoManagerListener
  193. void BeginUndoTransaction() override;
  194. void EndUndoTransaction() override;
  195. // AzFramework::InputSystemCursorConstraintRequestBus overrides ...
  196. void* GetSystemCursorConstraintWindow() const override;
  197. // AzToolsFramework::MainEditorViewportInteractionRequestBus overrides ...
  198. bool ShowingWorldSpace() override;
  199. QWidget* GetWidgetForViewportContextMenu() override;
  200. // EditorEntityViewportInteractionRequestBus overrides ...
  201. void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) override;
  202. // Camera::EditorCameraRequestBus overrides ...
  203. void SetViewFromEntityPerspective(const AZ::EntityId& entityId) override;
  204. AZ::EntityId GetCurrentViewEntityId() override;
  205. bool GetActiveCameraPosition(AZ::Vector3& cameraPos) override;
  206. AZStd::optional<AZ::Transform> GetActiveCameraTransform() override;
  207. AZStd::optional<float> GetCameraFoV() override;
  208. bool GetActiveCameraState(AzFramework::CameraState& cameraState) override;
  209. // AzToolsFramework::Prefab::PrefabPublicNotificationBus overrides ...
  210. void OnRootPrefabInstanceLoaded() override;
  211. ////////////////////////////////////////////////////////////////////////
  212. // Private helpers...
  213. void SetViewTM(const Matrix34& tm, bool bMoveOnly);
  214. void SetDefaultCameraNearFar();
  215. void RenderSnapMarker();
  216. void RenderAll();
  217. bool RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, Vec3& vOutPos, Vec3& vOutNormal) const;
  218. bool AddCameraMenuItems(QMenu* menu);
  219. void ResizeView(int width, int height);
  220. void HideCursor();
  221. void ShowCursor();
  222. double WidgetToViewportFactor() const;
  223. bool ShouldPreviewFullscreen() const;
  224. void StartFullscreenPreview();
  225. void StopFullscreenPreview();
  226. void OnMenuCreateCameraEntityFromCurrentView();
  227. void OnMenuSelectCurrentCamera();
  228. // From a series of input primitives, compose a complete mouse interaction.
  229. AzToolsFramework::ViewportInteraction::MouseInteraction BuildMouseInteractionInternal(
  230. AzToolsFramework::ViewportInteraction::MouseButtons buttons,
  231. AzToolsFramework::ViewportInteraction::KeyboardModifiers modifiers,
  232. const AzToolsFramework::ViewportInteraction::MousePick& mousePick) const;
  233. // Given a point in the viewport, return the pick ray into the scene.
  234. // note: The argument passed to parameter **point**, originating
  235. // from a Qt event, must first be passed to WidgetToViewport before being
  236. // passed to BuildMousePick.
  237. AzToolsFramework::ViewportInteraction::MousePick BuildMousePick(const QPoint& point) const;
  238. bool CheckRespondToInput() const;
  239. void BuildDragDropContext(
  240. AzQtComponents::ViewportDragContext& context, AzFramework::ViewportId viewportId, const QPoint& point) override;
  241. void SetAsActiveViewport();
  242. void PushDisableRendering();
  243. void PopDisableRendering();
  244. bool IsRenderingDisabled() const;
  245. void RestoreViewportAfterGameMode();
  246. void UpdateScene();
  247. void SetDefaultCamera();
  248. void SetSelectedCamera();
  249. bool IsSelectedCamera() const;
  250. void SetEntityAsCamera(const AZ::EntityId& entityId);
  251. void SetFirstComponentCamera();
  252. void PostCameraSet();
  253. // This switches the active camera to the next one in the list of (default, all custom cams).
  254. void CycleCamera();
  255. QPoint WidgetToViewport(const QPoint& point) const;
  256. QPoint ViewportToWidget(const QPoint& point) const;
  257. QSize WidgetToViewport(const QSize& size) const;
  258. const DisplayContext& GetDisplayContext() const
  259. {
  260. return m_displayContext;
  261. }
  262. CBaseObject* GetCameraObject() const;
  263. void UnProjectFromScreen(float sx, float sy, float* px, float* py, float* pz) const;
  264. void ProjectToScreen(float ptx, float pty, float ptz, float* sx, float* sy) const;
  265. AZ::RPI::ViewPtr GetCurrentAtomView() const;
  266. ////////////////////////////////////////////////////////////////////////
  267. // Members ...
  268. friend class AZ::ViewportHelpers::EditorEntityNotifications;
  269. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  270. // Singleton for the primary viewport
  271. static EditorViewportWidget* m_pPrimaryViewport;
  272. // The simulation (play-game in editor) state
  273. PlayInEditorState m_playInEditorState = PlayInEditorState::Editor;
  274. // Whether we are doing a full screen game preview (play-game in editor) or a regular one
  275. bool m_inFullscreenPreview = false;
  276. // The entity ID of the current camera for this viewport, or invalid if the default editor camera
  277. AZ::EntityId m_viewEntityId;
  278. // Determines also if the current camera for this viewport is default editor camera
  279. ViewSourceType m_viewSourceType = ViewSourceType::None;
  280. // During play game in editor, holds the editor entity ID of the last
  281. AZ::EntityId m_viewEntityIdCachedForEditMode;
  282. // The editor camera TM before switching to game mode
  283. Matrix34 m_preGameModeViewTM;
  284. // Disables rendering during some periods of time, e.g. undo/redo, resize events
  285. uint m_disableRenderingCount = 0;
  286. // Determines if the viewport needs updating (false when out of focus for example)
  287. bool m_bUpdateViewport = false;
  288. // Avoid re-entering PostCameraSet->OnActiveViewChanged->PostCameraSet
  289. bool m_sendingOnActiveChanged = false;
  290. // Legacy...
  291. KeyPressedState m_pressedKeyState = KeyPressedState::AllUp;
  292. // The name to use for the default editor camera
  293. const QString m_defaultViewName;
  294. // Note that any attempts to draw anything with this object will crash. Exists here for legacy "reasons"
  295. DisplayContext m_displayContext;
  296. // Reentrancy guard for on paint events
  297. bool m_isOnPaint = false;
  298. // Guard against calling UpdateVisibility multiple times a frame
  299. bool m_hasUpdatedVisibility = false;
  300. // Aspect ratios available in the title bar
  301. CPredefinedAspectRatios m_predefinedAspectRatios;
  302. // Is the cursor hidden or displayed?
  303. bool m_bCursorHidden = false;
  304. // Shim for QtViewport, which used to be responsible for visibility queries in the editor,
  305. // these are now forwarded to EntityVisibilityQuery
  306. AzFramework::EntityVisibilityQuery m_entityVisibilityQuery;
  307. // Handlers for snapping/editor event callbacks
  308. SandboxEditor::AngleSnappingChangedEvent::Handler m_angleSnappingHandler;
  309. SandboxEditor::CameraSpeedScaleChangedEvent::Handler m_cameraSpeedScaleHandler;
  310. SandboxEditor::GridShowingChangedEvent::Handler m_gridShowingHandler;
  311. SandboxEditor::GridSnappingChangedEvent::Handler m_gridSnappingHandler;
  312. SandboxEditor::NearFarPlaneChangedEvent::Handler m_nearPlaneDistanceHandler;
  313. SandboxEditor::NearFarPlaneChangedEvent::Handler m_farPlaneDistanceHandler;
  314. SandboxEditor::PerspectiveChangedEvent::Handler m_perspectiveChangeHandler;
  315. AZStd::unique_ptr<SandboxEditor::EditorViewportSettingsCallbacks> m_editorViewportSettingsCallbacks;
  316. // Used for some legacy logic which lets the widget release a grabbed keyboard at the right times
  317. // Unclear if it's still necessary.
  318. QSet<int> m_keyDown;
  319. // This widget holds a reference to the manipulator manage because its responsible for drawing manipulators
  320. AZStd::shared_ptr<AzToolsFramework::ManipulatorManager> m_manipulatorManager;
  321. AZStd::unique_ptr<SandboxEditor::EditorModularViewportCameraComposer> m_editorModularViewportCameraComposer;
  322. // Helper for getting EditorEntityNotificationBus events
  323. AZStd::unique_ptr<AZ::ViewportHelpers::EditorEntityNotifications> m_editorEntityNotifications;
  324. // The widget to which Atom will actually render
  325. AtomToolsFramework::RenderViewportWidget* m_renderViewport = nullptr;
  326. // Atom debug display
  327. AzFramework::DebugDisplayRequests* m_debugDisplay = nullptr;
  328. // Type to return current state of editor viewport settings
  329. EditorViewportSettings m_editorViewportSettings;
  330. // DO NOT USE THIS! It exists only to satisfy the signature of the base class method GetViewTm
  331. mutable Matrix34 m_viewTmStorage;
  332. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  333. };