Updates and fixes to viewport placement (#5712)
* updates to use more modern viewport intersection logic Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * updates to editor viewport ray intersection for object placement Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * make ed_defaultEntityPlacementDistance visible to Viewport.cpp Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * fix link error for AZ_CVAR variable Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * updates following review feedback Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
cf540b6f44
commit
bf4f52e146
+26
-210
@@ -14,14 +14,19 @@
|
||||
// Qt
|
||||
#include <QPainter>
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
|
||||
// AzQtComponents
|
||||
#include <AzQtComponents/DragAndDrop/ViewportDragAndDrop.h>
|
||||
|
||||
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
|
||||
// Editor
|
||||
#include "Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.h"
|
||||
#include "ViewManager.h"
|
||||
#include "Include/ITransformManipulator.h"
|
||||
#include "Include/HitContext.h"
|
||||
@@ -32,22 +37,35 @@
|
||||
#include "GameEngine.h"
|
||||
#include "Settings.h"
|
||||
|
||||
|
||||
#ifdef LoadCursor
|
||||
#undef LoadCursor
|
||||
#endif
|
||||
|
||||
AZ_CVAR(
|
||||
float,
|
||||
ed_defaultEntityPlacementDistance,
|
||||
10.0f,
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"The default distance to place an entity from the camera if no intersection is found");
|
||||
|
||||
float GetDefaultEntityPlacementDistance()
|
||||
{
|
||||
return ed_defaultEntityPlacementDistance;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Viewport drag and drop support
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void QtViewport::BuildDragDropContext(AzQtComponents::ViewportDragContext& context, const QPoint& pt)
|
||||
void QtViewport::BuildDragDropContext(
|
||||
AzQtComponents::ViewportDragContext& context, const AzFramework::ViewportId viewportId, const QPoint& point)
|
||||
{
|
||||
context.m_hitLocation = AZ::Vector3::CreateZero();
|
||||
context.m_hitLocation = GetHitLocation(pt);
|
||||
context.m_hitLocation = AzToolsFramework::FindClosestPickIntersection(
|
||||
viewportId, AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(point), AzToolsFramework::EditorPickRayLength,
|
||||
GetDefaultEntityPlacementDistance());
|
||||
}
|
||||
|
||||
|
||||
void QtViewport::dragEnterEvent(QDragEnterEvent* event)
|
||||
{
|
||||
if (!GetIEditor()->GetGameEngine()->IsLevelLoaded())
|
||||
@@ -66,7 +84,7 @@ void QtViewport::dragEnterEvent(QDragEnterEvent* event)
|
||||
// new bus-based way of doing it (install a listener!)
|
||||
using namespace AzQtComponents;
|
||||
ViewportDragContext context;
|
||||
BuildDragDropContext(context, event->pos());
|
||||
BuildDragDropContext(context, GetViewportId(), event->pos());
|
||||
DragAndDropEventsBus::Event(DragAndDropContexts::EditorViewport, &DragAndDropEvents::DragEnter, event, context);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +107,7 @@ void QtViewport::dragMoveEvent(QDragMoveEvent* event)
|
||||
// new bus-based way of doing it (install a listener!)
|
||||
using namespace AzQtComponents;
|
||||
ViewportDragContext context;
|
||||
BuildDragDropContext(context, event->pos());
|
||||
BuildDragDropContext(context, GetViewportId(), event->pos());
|
||||
DragAndDropEventsBus::Event(DragAndDropContexts::EditorViewport, &DragAndDropEvents::DragMove, event, context);
|
||||
}
|
||||
}
|
||||
@@ -112,7 +130,7 @@ void QtViewport::dropEvent(QDropEvent* event)
|
||||
{
|
||||
// new bus-based way of doing it (install a listener!)
|
||||
ViewportDragContext context;
|
||||
BuildDragDropContext(context, event->pos());
|
||||
BuildDragDropContext(context, GetViewportId(), event->pos());
|
||||
DragAndDropEventsBus::Event(DragAndDropContexts::EditorViewport, &DragAndDropEvents::Drop, event, context);
|
||||
}
|
||||
}
|
||||
@@ -340,13 +358,6 @@ void QtViewport::resizeEvent(QResizeEvent* event)
|
||||
Update();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::leaveEvent(QEvent* event)
|
||||
{
|
||||
QWidget::leaveEvent(event);
|
||||
MouseCallback(eMouseLeave, QPoint(), Qt::KeyboardModifiers(), Qt::MouseButtons());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||
{
|
||||
@@ -581,63 +592,7 @@ void QtViewport::keyReleaseEvent(QKeyEvent* event)
|
||||
OnKeyUp(nativeKey, 1, event->nativeModifiers());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnLButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
// Save the mouse down position
|
||||
m_cMouseDownPos = point;
|
||||
|
||||
if (MouseCallback(eMouseLDown, point, modifiers))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnLButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
// Check Edit Tool.
|
||||
MouseCallback(eMouseLUp, point, modifiers);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnRButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseRDown, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnRButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseRUp, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnMButtonDown(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
// Check Edit Tool.
|
||||
MouseCallback(eMouseMDown, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnMButtonUp(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
// Move the viewer to the mouse location.
|
||||
// Check Edit Tool.
|
||||
MouseCallback(eMouseMUp, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnMButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseMDblClick, point, modifiers);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnMouseMove(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseMove, point, modifiers, buttons);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnSetCursor()
|
||||
@@ -696,44 +651,6 @@ void QtViewport::OnDragSelectRectangle(const QRect& rect, bool bNormalizeRect)
|
||||
GetIEditor()->SetStatusText(szNewStatusText);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnLButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
// Ignore double clicks while in game.
|
||||
return;
|
||||
}
|
||||
|
||||
MouseCallback(eMouseLDblClick, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnRButtonDblClk(Qt::KeyboardModifiers modifiers, const QPoint& point)
|
||||
{
|
||||
MouseCallback(eMouseRDblClick, point, modifiers);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnKeyDown([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags)
|
||||
{
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
// Ignore key downs while in game.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::OnKeyUp([[maybe_unused]] UINT nChar, [[maybe_unused]] UINT nRepCnt, [[maybe_unused]] UINT nFlags)
|
||||
{
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
// Ignore key downs while in game.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::SetCurrentCursor(const QCursor& hCursor, const QString& cursorString)
|
||||
{
|
||||
@@ -1119,29 +1036,6 @@ bool QtViewport::HitTest(const QPoint& point, HitContext& hitInfo)
|
||||
return false;
|
||||
}
|
||||
|
||||
AZ::Vector3 QtViewport::GetHitLocation(const QPoint& point)
|
||||
{
|
||||
Vec3 pos = Vec3(ZERO);
|
||||
HitContext hit;
|
||||
if (HitTest(point, hit))
|
||||
{
|
||||
pos = hit.raySrc + hit.rayDir * hit.dist;
|
||||
pos = SnapToGrid(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool hitTerrain;
|
||||
pos = ViewToWorld(point, &hitTerrain);
|
||||
if (hitTerrain)
|
||||
{
|
||||
pos.z = GetIEditor()->GetTerrainElevation(pos.x, pos.y);
|
||||
}
|
||||
pos = SnapToGrid(pos);
|
||||
}
|
||||
|
||||
return AZ::Vector3(pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::SetZoomFactor(float fZoomFactor)
|
||||
{
|
||||
@@ -1315,84 +1209,6 @@ bool QtViewport::GetAdvancedSelectModeFlag()
|
||||
return m_bAdvancedSelectMode;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool QtViewport::MouseCallback(EMouseEvent event, const QPoint& point, Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Editor);
|
||||
|
||||
// Ignore any mouse events in game mode.
|
||||
if (GetIEditor()->IsInGameMode())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// We must ignore mouse events when we are in the middle of an assert.
|
||||
// Reason: If we have an assert called from an engine module under the editor, if we call this function,
|
||||
// it may call the engine again and cause a deadlock.
|
||||
// Concrete example: CryPhysics called from Trackview causing an assert, and moving the cursor over the viewport
|
||||
// would cause the editor to freeze as it calls CryPhysics again for a raycast while it didn't release the lock.
|
||||
if (gEnv->pSystem->IsAssertDialogVisible())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Hit test gizmo objects.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool bAltClick = (modifiers & Qt::AltModifier);
|
||||
bool bCtrlClick = (modifiers & Qt::ControlModifier);
|
||||
bool bShiftClick = (modifiers & Qt::ShiftModifier);
|
||||
|
||||
int flags = (bCtrlClick ? MK_CONTROL : 0) |
|
||||
(bShiftClick ? MK_SHIFT : 0) |
|
||||
((buttons& Qt::LeftButton) ? MK_LBUTTON : 0) |
|
||||
((buttons& Qt::MiddleButton) ? MK_MBUTTON : 0) |
|
||||
((buttons& Qt::RightButton) ? MK_RBUTTON : 0);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case eMouseMove:
|
||||
|
||||
if (m_nLastUpdateFrame == m_nLastMouseMoveFrame)
|
||||
{
|
||||
// If mouse move event generated in the same frame, ignore it.
|
||||
return false;
|
||||
}
|
||||
m_nLastMouseMoveFrame = m_nLastUpdateFrame;
|
||||
|
||||
// Skip the marker position update if anything is selected, since it is only used
|
||||
// by the info bar which doesn't show the marker when there is an active selection.
|
||||
// This helps a performance issue when calling ViewToWorld (which calls RayWorldIntersection)
|
||||
// on every mouse movement becomes very expensive in scenes with large amounts of entities.
|
||||
CSelectionGroup* selection = GetIEditor()->GetSelection();
|
||||
if (!(buttons & Qt::RightButton) /* && m_nLastUpdateFrame != m_nLastMouseMoveFrame*/ && (selection && selection->IsEmpty()))
|
||||
{
|
||||
//m_nLastMouseMoveFrame = m_nLastUpdateFrame;
|
||||
Vec3 pos = ViewToWorld(point);
|
||||
GetIEditor()->SetMarkerPosition(pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
QPoint tempPoint(point.x(), point.y());
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Handle viewport manipulators.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (!bAltClick)
|
||||
{
|
||||
ITransformManipulator* pManipulator = GetIEditor()->GetTransformManipulator();
|
||||
if (pManipulator)
|
||||
{
|
||||
if (pManipulator->MouseCallback(this, event, tempPoint, flags))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void QtViewport::ProcessRenderLisneters(DisplayContext& rstDisplayContext)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user