Viewport.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  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 : interface for the CViewport class.
  9. #pragma once
  10. #if !defined(Q_MOC_RUN)
  11. #include <AzFramework/Viewport/ViewportId.h>
  12. #include <AzToolsFramework/Viewport/ViewportTypes.h>
  13. #include <AzToolsFramework/ViewportUi/ViewportUiManager.h>
  14. #include <Cry_Color.h>
  15. #include "IPostRenderer.h"
  16. #include "Include/IDisplayViewport.h"
  17. #include "Include/SandboxAPI.h"
  18. #include <QPointer>
  19. #include <QMenu>
  20. #if defined(Q_OS_WIN)
  21. #include <QtWinExtras/qwinfunctions.h>
  22. #endif
  23. #include <AzCore/Math/Uuid.h>
  24. #include <IEditor.h>
  25. #endif
  26. namespace AzQtComponents
  27. {
  28. class ViewportDragContext;
  29. }
  30. // forward declarations.
  31. class CCryEditDoc;
  32. class CLayoutViewPane;
  33. class CViewManager;
  34. struct HitContext;
  35. class CImageEx;
  36. class QMenu;
  37. /** Type of viewport.
  38. */
  39. enum EViewportType
  40. {
  41. ET_ViewportUnknown = 0,
  42. ET_ViewportXY,
  43. ET_ViewportXZ,
  44. ET_ViewportYZ,
  45. ET_ViewportCamera,
  46. ET_ViewportMap,
  47. ET_ViewportModel,
  48. ET_ViewportZ, //!< Z Only viewport.
  49. ET_ViewportUI,
  50. ET_ViewportLast,
  51. };
  52. //////////////////////////////////////////////////////////////////////////
  53. // Standart cursors viewport can display.
  54. //////////////////////////////////////////////////////////////////////////
  55. enum EStdCursor
  56. {
  57. STD_CURSOR_DEFAULT,
  58. STD_CURSOR_HIT,
  59. STD_CURSOR_MOVE,
  60. STD_CURSOR_ROTATE,
  61. STD_CURSOR_SCALE,
  62. STD_CURSOR_SEL_PLUS,
  63. STD_CURSOR_SEL_MINUS,
  64. STD_CURSOR_SUBOBJ_SEL,
  65. STD_CURSOR_SUBOBJ_SEL_PLUS,
  66. STD_CURSOR_SUBOBJ_SEL_MINUS,
  67. STD_CURSOR_HAND,
  68. STD_CURSOR_GAME,
  69. STD_CURSOR_LAST,
  70. };
  71. AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
  72. class SANDBOX_API CViewport
  73. : public IDisplayViewport
  74. {
  75. AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
  76. public:
  77. typedef void(* DropCallback)(CViewport* viewport, int ptx, int pty, void* custom);
  78. virtual ~CViewport() {}
  79. virtual void SetActiveWindow() = 0;
  80. // Changed my view manager.
  81. void SetViewManager(CViewManager* viewMgr) { m_viewManager = viewMgr; };
  82. //! Access to view manager.
  83. CViewManager* GetViewManager() const { return m_viewManager; };
  84. virtual void AddPostRenderer(IPostRenderer* pPostRenderer) = 0;
  85. virtual bool RemovePostRenderer(IPostRenderer* pPostRenderer) = 0;
  86. virtual bool DestroyWindow() { return false; }
  87. /** Get type of this viewport.
  88. */
  89. virtual EViewportType GetType() const { return ET_ViewportUnknown; }
  90. /** Must be overriden in derived classes.
  91. */
  92. virtual void SetType(EViewportType type) = 0;
  93. /** Get name of viewport
  94. */
  95. virtual QString GetName() const = 0;
  96. virtual void SetSelected([[maybe_unused]] bool const bSelect){}
  97. //! Resets current selection region.
  98. virtual void ResetSelectionRegion() = 0;
  99. //! Set 2D selection rectangle.
  100. virtual void SetSelectionRectangle(const QRect& rect) = 0;
  101. inline void SetSelectionRectangle(const QPoint& startMousePosition, const QPoint& currentMousePosition)
  102. {
  103. // QRect's bottom/right are width - 1, height - 1, so when specifying the right position
  104. // directly in a QRect, we need to offset it by -1.
  105. SetSelectionRectangle(QRect(startMousePosition, currentMousePosition - QPoint(1, 1)));
  106. }
  107. //! Return 2D selection rectangle.
  108. virtual QRect GetSelectionRectangle() const = 0;
  109. //! Called when dragging selection rectangle.
  110. virtual void OnDragSelectRectangle(const QRect& rect, bool bNormalizeRect = false) = 0;
  111. void OnDragSelectRectangle(const QPoint& startMousePosition, const QPoint& currentMousePosition, bool bNormalizeRect = false)
  112. {
  113. // QRect's bottom/right are width - 1, height - 1, so when specifying the right position
  114. // directly in a QRect, we need to offset it by -1.
  115. OnDragSelectRectangle(QRect(startMousePosition, currentMousePosition - QPoint(1, 1)), bNormalizeRect);
  116. }
  117. virtual void ResetContent() = 0;
  118. virtual void UpdateContent(int flags) = 0;
  119. virtual void SetAxisConstrain(int axis) = 0;
  120. int GetAxisConstrain() const { return GetIEditor()->GetAxisConstrains(); };
  121. virtual Vec3 SnapToGrid(const Vec3& vec) = 0;
  122. //! Get selection precision tolerance.
  123. virtual float GetSelectionTolerance() const = 0;
  124. //////////////////////////////////////////////////////////////////////////
  125. // View matrix.
  126. //////////////////////////////////////////////////////////////////////////
  127. //! Set current view matrix,
  128. //! This is a matrix that transforms from world to view space.
  129. virtual void SetViewTM([[maybe_unused]] const Matrix34& tm)
  130. {
  131. AZ_Error("CryLegacy", false, "QtViewport::SetViewTM not implemented");
  132. }
  133. //! Get current view matrix.
  134. //! This is a matrix that transforms from world space to view space.
  135. const Matrix34& GetViewTM() const override
  136. {
  137. AZ_Error("CryLegacy", false, "QtViewport::GetViewTM not implemented");
  138. static const Matrix34 m;
  139. return m;
  140. };
  141. //////////////////////////////////////////////////////////////////////////
  142. //! Get current screen matrix.
  143. //! Screen matrix transform from World space to Screen space.
  144. const Matrix34& GetScreenTM() const override
  145. {
  146. return m_screenTM;
  147. }
  148. //! Map viewport position to world space position.
  149. Vec3 ViewToWorld(const QPoint& vp, bool* pCollideWithTerrain = nullptr, bool onlyTerrain = false, bool bSkipVegetation = false, bool bTestRenderMesh = false, bool* collideWithObject = nullptr) const override = 0;
  150. //! Convert point on screen to world ray.
  151. void ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const override = 0;
  152. //! Get normal for viewport position
  153. virtual Vec3 ViewToWorldNormal(const QPoint& vp, bool onlyTerrain, bool bTestRenderMesh = false) = 0;
  154. //! Performs hit testing of 2d point in view to find which object hit.
  155. virtual bool HitTest(const QPoint& point, HitContext& hitInfo) = 0;
  156. // Access to the member m_bAdvancedSelectMode so interested modules can know its value.
  157. virtual bool GetAdvancedSelectModeFlag() = 0;
  158. virtual void ToggleCameraObject() {}
  159. virtual bool IsSequenceCamera() const { return false; }
  160. //! Center viewport on selection.
  161. virtual void CenterOnSelection() = 0;
  162. virtual void CenterOnAABB(const AABB& aabb) = 0;
  163. /** Set ID of this viewport
  164. */
  165. virtual void SetViewportId(int id) { m_nCurViewportID = id; };
  166. /** Get ID of this viewport
  167. */
  168. virtual int GetViewportId() const { return m_nCurViewportID; };
  169. // Store final Game Matrix ready for editor
  170. void SetGameTM(const Matrix34& tm) { m_gameTM = tm; };
  171. //////////////////////////////////////////////////////////////////////////
  172. // Drag and drop support on viewports.
  173. // To be overrided in derived classes.
  174. //////////////////////////////////////////////////////////////////////////
  175. virtual void SetGlobalDropCallback(DropCallback dropCallback, void* dropCallbackCustom)
  176. {
  177. m_dropCallback = dropCallback;
  178. m_dropCallbackCustom = dropCallbackCustom;
  179. }
  180. virtual void BeginUndo() = 0;
  181. virtual void AcceptUndo(const QString& undoDescription) = 0;
  182. virtual void CancelUndo() = 0;
  183. virtual void RestoreUndo() = 0;
  184. virtual bool IsUndoRecording() const = 0;
  185. virtual void CaptureMouse() {};
  186. virtual void SetCapture() { CaptureMouse(); }
  187. virtual void ReleaseMouse() {};
  188. virtual void ResetCursor() = 0;
  189. virtual void SetCursor(const QCursor& cursor) = 0;
  190. virtual void SetCurrentCursor(EStdCursor stdCursor) = 0;
  191. virtual void SetCurrentCursor(EStdCursor stdCursor, const QString& str) = 0;
  192. virtual void SetSupplementaryCursorStr(const QString& str) = 0;
  193. virtual void SetCursorString(const QString& str) = 0;
  194. virtual void SetFocus() = 0;
  195. virtual void Invalidate(bool bErase = true) = 0;
  196. // Is overridden by RenderViewport
  197. virtual void SetFOV([[maybe_unused]] float fov) {}
  198. virtual float GetFOV() const;
  199. virtual QObject* qobject() { return nullptr; }
  200. virtual QWidget* widget() { return nullptr; }
  201. virtual void OnTitleMenu([[maybe_unused]] QMenu* menu) {}
  202. void SetViewPane(CLayoutViewPane* viewPane) { m_viewPane = viewPane; }
  203. CViewport *asCViewport() override { return this; }
  204. protected:
  205. CLayoutViewPane* m_viewPane = nullptr;
  206. CViewManager* m_viewManager;
  207. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  208. // Screen Matrix
  209. Matrix34 m_screenTM;
  210. int m_nCurViewportID;
  211. // Final game view matrix before dropping back to editor
  212. Matrix34 m_gameTM;
  213. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  214. // Custom drop callback (Leroy@Conffx)
  215. DropCallback m_dropCallback;
  216. void* m_dropCallbackCustom;
  217. };
  218. template<typename T>
  219. typename std::enable_if<std::is_base_of<QObject, typename std::remove_cv<typename std::remove_pointer<T>::type>::type>::value, T>::type
  220. viewport_cast(CViewport* viewport)
  221. {
  222. if (viewport == nullptr)
  223. {
  224. return nullptr;
  225. }
  226. if (QObject* obj = viewport->qobject())
  227. {
  228. return qobject_cast<T>(obj);
  229. }
  230. else
  231. {
  232. return nullptr;
  233. }
  234. }
  235. /** Base class for all Editor Viewports.
  236. */
  237. class SANDBOX_API QtViewport
  238. : public QWidget
  239. , public CViewport
  240. {
  241. Q_OBJECT
  242. public:
  243. QObject* qobject() override { return this; }
  244. QWidget* widget() override { return this; }
  245. template<typename T>
  246. static const GUID& GetClassID()
  247. {
  248. static GUID guid = [] {
  249. return AZ::Uuid::CreateRandom();
  250. } ();
  251. return guid;
  252. }
  253. QtViewport(QWidget* parent = nullptr);
  254. virtual ~QtViewport();
  255. void SetActiveWindow() override { activateWindow(); }
  256. //! Called while window is idle.
  257. void Update() override;
  258. /** Set name of this viewport.
  259. */
  260. void SetName(const QString& name);
  261. /** Get name of viewport
  262. */
  263. QString GetName() const override;
  264. void SetFocus() override { setFocus(); }
  265. void Invalidate([[maybe_unused]] bool bErase = 1) override { update(); }
  266. // Is overridden by RenderViewport
  267. void SetFOV([[maybe_unused]] float fov) override {}
  268. float GetFOV() const override;
  269. // Must be overridden in derived classes.
  270. // Returns:
  271. // e.g. 4.0/3.0
  272. float GetAspectRatio() const override = 0;
  273. void GetDimensions(int* pWidth, int* pHeight) const override;
  274. void ScreenToClient(QPoint& pPoint) const override;
  275. void ResetContent() override;
  276. void UpdateContent(int flags) override;
  277. //! Set current zoom factor for this viewport.
  278. virtual void SetZoomFactor(float fZoomFactor);
  279. //! Get current zoom factor for this viewport.
  280. virtual float GetZoomFactor() const;
  281. virtual void OnActivate();
  282. virtual void OnDeactivate();
  283. //! Map world space position to viewport position.
  284. QPoint WorldToView(const Vec3& wp) const override;
  285. //! Map world space position to 3D viewport position.
  286. Vec3 WorldToView3D(const Vec3& wp, int nFlags = 0) const override;
  287. //! Map viewport position to world space position.
  288. virtual Vec3 ViewToWorld(const QPoint& vp, bool* pCollideWithTerrain = nullptr, bool onlyTerrain = false, bool bSkipVegetation = false, bool bTestRenderMesh = false, bool* collideWithObject = nullptr) const override;
  289. //! Convert point on screen to world ray.
  290. virtual void ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const override;
  291. //! Get normal for viewport position
  292. virtual Vec3 ViewToWorldNormal(const QPoint& vp, bool onlyTerrain, bool bTestRenderMesh = false) override;
  293. //! Snap any given 3D world position to grid lines if snap is enabled.
  294. Vec3 SnapToGrid(const Vec3& vec) override;
  295. //! Returns the screen scale factor for a point given in world coordinates.
  296. //! This factor gives the width in world-space units at the point's distance of the viewport.
  297. float GetScreenScaleFactor([[maybe_unused]] const Vec3& worldPoint) const override { return 1; };
  298. void SetAxisConstrain(int axis) override;
  299. /// Take raw input and create a final mouse interaction.
  300. /// @attention Do not map **point** from widget to viewport explicitly,
  301. /// this is handled internally by BuildMouseInteraction - just pass directly.
  302. virtual AzToolsFramework::ViewportInteraction::MouseInteraction BuildMouseInteraction(
  303. Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, const QPoint& point);
  304. //////////////////////////////////////////////////////////////////////////
  305. // Selection.
  306. //////////////////////////////////////////////////////////////////////////
  307. //! Resets current selection region.
  308. void ResetSelectionRegion() override;
  309. //! Set 2D selection rectangle.
  310. void SetSelectionRectangle(const QRect& rect) override;
  311. //! Return 2D selection rectangle.
  312. QRect GetSelectionRectangle() const override { return m_selectedRect; };
  313. //! Called when dragging selection rectangle.
  314. void OnDragSelectRectangle(const QRect& rect, bool bNormalizeRect = false) override;
  315. //! Get selection precision tolerance.
  316. float GetSelectionTolerance() const override { return m_selectionTolerance; }
  317. //! Center viewport on selection.
  318. void CenterOnSelection() override {}
  319. void CenterOnAABB([[maybe_unused]] const AABB& aabb) override {}
  320. //! Performs hit testing of 2d point in view to find which object hit.
  321. bool HitTest(const QPoint& point, HitContext& hitInfo) override;
  322. float GetDistanceToLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& point) const override;
  323. // Access to the member m_bAdvancedSelectMode so interested modules can know its value.
  324. bool GetAdvancedSelectModeFlag() override;
  325. void GetPerpendicularAxis(EAxis* pAxis, bool* pIs2D) const override;
  326. void DegradateQuality(bool bEnable);
  327. //////////////////////////////////////////////////////////////////////////
  328. // Undo for viewpot operations.
  329. void BeginUndo() override;
  330. void AcceptUndo(const QString& undoDescription) override;
  331. void CancelUndo() override;
  332. void RestoreUndo() override;
  333. bool IsUndoRecording() const override;
  334. //////////////////////////////////////////////////////////////////////////
  335. //! Get prefered original size for this viewport.
  336. //! if 0, then no preference.
  337. virtual QSize GetIdealSize() const;
  338. //! Check if world space bounding box is visible in this view.
  339. bool IsBoundsVisible(const AABB& box) const override;
  340. //////////////////////////////////////////////////////////////////////////
  341. void SetCursor(const QCursor& cursor) override
  342. {
  343. setCursor(cursor);
  344. }
  345. // Set`s current cursor string.
  346. void SetCurrentCursor(const QCursor& hCursor, const QString& cursorString);
  347. void SetCurrentCursor(EStdCursor stdCursor, const QString& cursorString) override;
  348. void SetCurrentCursor(EStdCursor stdCursor) override;
  349. void SetCursorString(const QString& cursorString) override;
  350. void ResetCursor() override;
  351. void SetSupplementaryCursorStr(const QString& str) override;
  352. void AddPostRenderer(IPostRenderer* pPostRenderer) override;
  353. bool RemovePostRenderer(IPostRenderer* pPostRenderer) override;
  354. void CaptureMouse() override { m_mouseCaptured = true; QWidget::grabMouse(); }
  355. void ReleaseMouse() override { m_mouseCaptured = false; QWidget::releaseMouse(); }
  356. void setRay(QPoint& vp, Vec3& raySrc, Vec3& rayDir) override;
  357. QPoint m_vp;
  358. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  359. Vec3 m_raySrc;
  360. Vec3 m_rayDir;
  361. // Greater than 0 while running MouseCallback() function. It needs to be a counter
  362. // because of recursive calls to MouseCallback(). It's used to make an exception
  363. // during the SScopedCurrentContext count check of m_cameraSetForWidgetRenderingCount.
  364. int m_processingMouseCallbacksCounter = 0;
  365. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  366. protected:
  367. friend class CViewManager;
  368. bool IsVectorInValidRange(const Vec3& v) const { return fabs(v.x) < 1e+8 && fabs(v.y) < 1e+8 && fabs(v.z) < 1e+8; }
  369. void AssignConstructionPlane(const Vec3& p1, const Vec3& p2, const Vec3& p3);
  370. HWND renderOverlayHWND() const;
  371. void setRenderOverlayVisible(bool);
  372. bool isRenderOverlayVisible() const;
  373. void mousePressEvent(QMouseEvent* event) override;
  374. void mouseReleaseEvent(QMouseEvent* event) override;
  375. void mouseDoubleClickEvent(QMouseEvent* event) override;
  376. void mouseMoveEvent(QMouseEvent* event) override;
  377. void wheelEvent(QWheelEvent* event) override;
  378. void keyPressEvent(QKeyEvent* event) override;
  379. void keyReleaseEvent(QKeyEvent* event) override;
  380. void resizeEvent(QResizeEvent* event) override;
  381. void paintEvent(QPaintEvent* event) override;
  382. virtual void OnMouseMove(Qt::KeyboardModifiers, Qt::MouseButtons, const QPoint&) {}
  383. virtual void OnMouseWheel(Qt::KeyboardModifiers, short zDelta, const QPoint&);
  384. virtual void OnLButtonDown(Qt::KeyboardModifiers, const QPoint&) {}
  385. virtual void OnLButtonUp(Qt::KeyboardModifiers, const QPoint&) {}
  386. virtual void OnRButtonDown(Qt::KeyboardModifiers, const QPoint&) {}
  387. virtual void OnRButtonUp(Qt::KeyboardModifiers, const QPoint&) {}
  388. virtual void OnMButtonDblClk(Qt::KeyboardModifiers, const QPoint&) {}
  389. virtual void OnMButtonDown(Qt::KeyboardModifiers, const QPoint&) {}
  390. virtual void OnMButtonUp(Qt::KeyboardModifiers, const QPoint&) {}
  391. virtual void OnLButtonDblClk(Qt::KeyboardModifiers, const QPoint&) {}
  392. virtual void OnRButtonDblClk(Qt::KeyboardModifiers, const QPoint&) {}
  393. virtual void OnKeyDown([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags) {}
  394. virtual void OnKeyUp([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags) {}
  395. #if defined(AZ_PLATFORM_WINDOWS)
  396. void OnRawInput(UINT wParam, HRAWINPUT lParam);
  397. #endif
  398. void OnSetCursor();
  399. virtual void BuildDragDropContext(
  400. AzQtComponents::ViewportDragContext& context, AzFramework::ViewportId viewportId, const QPoint& point);
  401. void dragEnterEvent(QDragEnterEvent* event) override;
  402. void dragMoveEvent(QDragMoveEvent* event) override;
  403. void dragLeaveEvent(QDragLeaveEvent* event) override;
  404. void dropEvent(QDropEvent* event) override;
  405. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  406. AzToolsFramework::ViewportUi::ViewportUiManager m_viewportUi;
  407. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  408. float m_selectionTolerance;
  409. QMenu m_cViewMenu;
  410. mutable float m_fZoomFactor;
  411. QPoint m_cMouseDownPos;
  412. //! Current selected rectangle.
  413. QRect m_selectedRect;
  414. int m_activeAxis;
  415. // When true selection helpers will be shown and hit tested against.
  416. bool m_bAdvancedSelectMode;
  417. //////////////////////////////////////////////////////////////////////////
  418. // Standard cursors.
  419. //////////////////////////////////////////////////////////////////////////
  420. QCursor m_hCursor[STD_CURSOR_LAST];
  421. QCursor m_hCurrCursor;
  422. //! Mouse is over this object.
  423. QString m_cursorStr;
  424. QString m_cursorSupplementaryStr;
  425. static bool m_bDegradateQuality;
  426. // Grid size modifier due to zoom.
  427. float m_fGridZoom;
  428. int m_nLastUpdateFrame;
  429. int m_nLastMouseMoveFrame;
  430. QRect m_rcClient;
  431. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  432. typedef std::vector<_smart_ptr<IPostRenderer> > PostRenderers;
  433. PostRenderers m_postRenderers;
  434. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  435. protected:
  436. bool m_mouseCaptured = false;
  437. private:
  438. QWidget m_renderOverlay;
  439. };