Merge branch 'development' into cmake/warn_virtual
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -44,7 +44,7 @@ enum
|
||||
{
|
||||
// in milliseconds
|
||||
GameModeIdleFrequency = 0,
|
||||
EditorModeIdleFrequency = 1,
|
||||
EditorModeIdleFrequency = 0,
|
||||
InactiveModeFrequency = 10,
|
||||
UninitializedFrequency = 9999,
|
||||
};
|
||||
|
||||
@@ -77,10 +77,6 @@ namespace
|
||||
// This closes the current document (level)
|
||||
currentLevel->OnNewDocument();
|
||||
|
||||
// Then we freeze the viewport's input
|
||||
AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Broadcast(
|
||||
&AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Events::FreezeViewportInput, true);
|
||||
|
||||
// Then we need to tell the game engine there is no level to render anymore
|
||||
if (GetIEditor()->GetGameEngine())
|
||||
{
|
||||
|
||||
@@ -669,16 +669,6 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
|
||||
case eNotify_OnEndSceneSave:
|
||||
PopDisableRendering();
|
||||
break;
|
||||
|
||||
case eNotify_OnBeginLoad: // disables viewport input when starting to load an existing level
|
||||
case eNotify_OnBeginCreate: // disables viewport input when starting to create a new level
|
||||
m_freezeViewportInput = true;
|
||||
break;
|
||||
|
||||
case eNotify_OnEndLoad: // enables viewport input when finished loading an existing level
|
||||
case eNotify_OnEndCreate: // enables viewport input when finished creating a new level
|
||||
m_freezeViewportInput = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,16 +952,6 @@ AzFramework::ScreenPoint EditorViewportWidget::ViewportWorldToScreen(const AZ::V
|
||||
return m_renderViewport->ViewportWorldToScreen(worldPosition);
|
||||
}
|
||||
|
||||
bool EditorViewportWidget::IsViewportInputFrozen()
|
||||
{
|
||||
return m_freezeViewportInput;
|
||||
}
|
||||
|
||||
void EditorViewportWidget::FreezeViewportInput(bool freeze)
|
||||
{
|
||||
m_freezeViewportInput = freeze;
|
||||
}
|
||||
|
||||
QWidget* EditorViewportWidget::GetWidgetForViewportContextMenu()
|
||||
{
|
||||
return this;
|
||||
@@ -1057,9 +1037,9 @@ void EditorViewportWidget::SetViewportId(int id)
|
||||
|
||||
void EditorViewportWidget::ConnectViewportInteractionRequestBus()
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusConnect();
|
||||
m_viewportUi.ConnectViewportUiBus(GetViewportId());
|
||||
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::Handler::BusConnect();
|
||||
@@ -1070,9 +1050,9 @@ void EditorViewportWidget::DisconnectViewportInteractionRequestBus()
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::Handler::BusDisconnect();
|
||||
|
||||
m_viewportUi.DisconnectViewportUiBus();
|
||||
AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
namespace AZ::ViewportHelpers
|
||||
|
||||
@@ -89,7 +89,6 @@ class SANDBOX_API EditorViewportWidget final
|
||||
, private Camera::EditorCameraRequestBus::Handler
|
||||
, private Camera::CameraNotificationBus::Handler
|
||||
, private AzFramework::InputSystemCursorConstraintRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::ViewportFreezeRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler
|
||||
, private AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler
|
||||
@@ -202,10 +201,6 @@ private:
|
||||
// AzFramework::InputSystemCursorConstraintRequestBus overrides ...
|
||||
void* GetSystemCursorConstraintWindow() const override;
|
||||
|
||||
// AzToolsFramework::ViewportFreezeRequestBus overrides ...
|
||||
bool IsViewportInputFrozen() override;
|
||||
void FreezeViewportInput(bool freeze) override;
|
||||
|
||||
// AzToolsFramework::MainEditorViewportInteractionRequestBus overrides ...
|
||||
AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) override;
|
||||
AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) override;
|
||||
@@ -387,9 +382,6 @@ private:
|
||||
// Unclear if it's still necessary.
|
||||
QSet<int> m_keyDown;
|
||||
|
||||
// State for ViewportFreezeRequestBus, currently does nothing
|
||||
bool m_freezeViewportInput = false;
|
||||
|
||||
// This widget holds a reference to the manipulator manage because its responsible for drawing manipulators
|
||||
AZStd::shared_ptr<AzToolsFramework::ManipulatorManager> m_manipulatorManager;
|
||||
|
||||
|
||||
@@ -191,94 +191,4 @@ ConsoleTextEdit:focus,
|
||||
border-width: 0px;
|
||||
border-color: #e9e9e9;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
/* Welcome Screen styling */
|
||||
|
||||
WelcomeScreenDialog QLabel
|
||||
{
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
line-height: 20px;
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
WelcomeScreenDialog QLabel#currentProjectLabel
|
||||
{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
WelcomeScreenDialog QPushButton
|
||||
{
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
WelcomeScreenDialog QWidget#articleViewContainerRoot
|
||||
{
|
||||
background: #444444;
|
||||
}
|
||||
|
||||
WelcomeScreenDialog QWidget#levelViewFTUEContainer
|
||||
{
|
||||
background: #282828;
|
||||
}
|
||||
|
||||
QTableWidget#recentLevelTable::item {
|
||||
background-color: rgb(64,64,64);
|
||||
margin-bottom: 4px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Particle Editor */
|
||||
|
||||
#NumParticlesLabel
|
||||
{
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
#LibrarySearchIcon
|
||||
{
|
||||
max-width: 16px;
|
||||
max-height: 16px;
|
||||
qproperty-iconSize: 16px 16px;
|
||||
}
|
||||
|
||||
|
||||
#ClosePrefabDialog, #SavePrefabDialog
|
||||
{
|
||||
min-width : 640px;
|
||||
}
|
||||
|
||||
#SaveDependentPrefabsCard
|
||||
{
|
||||
margin: 0px 15px 10px 15px;
|
||||
}
|
||||
|
||||
#PrefabSavedMessageFrame{
|
||||
border: 1px solid green;
|
||||
margin: 10px 15px 10px 15px;
|
||||
border-radius: 2px;
|
||||
padding: 5px 2px 5px 2px;
|
||||
}
|
||||
|
||||
#ClosePrefabDialog #PrefabSaveWarningFrame
|
||||
{
|
||||
border: 1px solid orange;
|
||||
margin: 10px 15px 10px 15px;
|
||||
border-radius: 2px;
|
||||
padding: 5px 2px 5px 2px;
|
||||
color : white;
|
||||
}
|
||||
|
||||
#SavePrefabDialog #FooterSeparatorLine
|
||||
{
|
||||
color: gray;
|
||||
}
|
||||
|
||||
#SavePrefabDialog #PrefabSavePreferenceHint
|
||||
{
|
||||
font: italic;
|
||||
color: #999999;
|
||||
}
|
||||
@@ -36,6 +36,9 @@
|
||||
#include "CryEdit.h"
|
||||
#include "Viewport.h"
|
||||
|
||||
// Atom Renderer
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <TrackView/ui_SequenceBatchRenderDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
@@ -1234,6 +1237,13 @@ void CSequenceBatchRenderDialog::OnKickIdleTimout()
|
||||
{
|
||||
componentApplication->TickSystem();
|
||||
}
|
||||
|
||||
// Directly tick the renderer, as it's no longer part of the system tick
|
||||
if (auto rpiSystem = AZ::RPI::RPISystemInterface::Get())
|
||||
{
|
||||
rpiSystem->SimulationTick();
|
||||
rpiSystem->RenderTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,8 @@
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
AZ_CVAR(float, g_simulation_tick_rate, 0, nullptr, AZ::ConsoleFunctorFlags::Null, "The rate at which the game simulation tick loop runs, or 0 for as fast as possible");
|
||||
|
||||
static void PrintEntityName(const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
if (arguments.empty())
|
||||
@@ -1394,6 +1396,23 @@ namespace AZ
|
||||
AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:OnTick");
|
||||
EBUS_EVENT(TickBus, OnTick, m_deltaTime, ScriptTimePoint(now));
|
||||
}
|
||||
|
||||
// If tick rate limiting is on, ensure (1 / g_simulation_tick_rate) ms has elapsed since the last frame,
|
||||
// sleeping if there's still time remaining.
|
||||
if (g_simulation_tick_rate > 0.f)
|
||||
{
|
||||
now = AZStd::chrono::system_clock::now();
|
||||
|
||||
// Work in microsecond durations here as that's the native measurement time for time_point
|
||||
constexpr float microsecondsPerSecond = 1000.f * 1000.f;
|
||||
const AZStd::chrono::microseconds timeBudgetPerTick(static_cast<int>(microsecondsPerSecond / g_simulation_tick_rate));
|
||||
AZStd::chrono::microseconds timeUntilNextTick = m_currentTime + timeBudgetPerTick - now;
|
||||
|
||||
if (timeUntilNextTick.count() > 0)
|
||||
{
|
||||
AZStd::this_thread::sleep_for(timeUntilNextTick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace AZ
|
||||
|
||||
TICK_PRE_RENDER = 750, ///< Suggested tick handler position to update render-related data.
|
||||
|
||||
TICK_RENDER = 800, ///< Suggested tick handler position for rendering.
|
||||
|
||||
TICK_DEFAULT = 1000, ///< Default tick handler position when the handler is constructed.
|
||||
|
||||
TICK_UI = 2000, ///< Suggested tick handler position for UI components.
|
||||
|
||||
+13
-2
@@ -39,6 +39,8 @@ namespace AzManipulatorTestFramework
|
||||
DerivedDispatcherT* MouseLButtonDown();
|
||||
//! Set the left mouse button up.
|
||||
DerivedDispatcherT* MouseLButtonUp();
|
||||
//! Send a double click event.
|
||||
DerivedDispatcherT* MouseLButtonDoubleClick();
|
||||
//! Set the keyboard modifier button down.
|
||||
DerivedDispatcherT* KeyboardModifierDown(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier);
|
||||
//! Set the keyboard modifier button up.
|
||||
@@ -71,6 +73,7 @@ namespace AzManipulatorTestFramework
|
||||
virtual void CameraStateImpl(const AzFramework::CameraState& cameraState) = 0;
|
||||
virtual void MouseLButtonDownImpl() = 0;
|
||||
virtual void MouseLButtonUpImpl() = 0;
|
||||
virtual void MouseLButtonDoubleClickImpl() = 0;
|
||||
virtual void MousePositionImpl(const AzFramework::ScreenPoint& position) = 0;
|
||||
virtual void KeyboardModifierDownImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) = 0;
|
||||
virtual void KeyboardModifierUpImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) = 0;
|
||||
@@ -167,7 +170,7 @@ namespace AzManipulatorTestFramework
|
||||
template<typename DerivedDispatcherT>
|
||||
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseLButtonDown()
|
||||
{
|
||||
Log("%s", "Mouse left button down");
|
||||
Log("Mouse left button down");
|
||||
MouseLButtonDownImpl();
|
||||
return static_cast<DerivedDispatcherT*>(this);
|
||||
}
|
||||
@@ -175,11 +178,19 @@ namespace AzManipulatorTestFramework
|
||||
template<typename DerivedDispatcherT>
|
||||
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseLButtonUp()
|
||||
{
|
||||
Log("%s", "Mouse left button up");
|
||||
Log("Mouse left button up");
|
||||
MouseLButtonUpImpl();
|
||||
return static_cast<DerivedDispatcherT*>(this);
|
||||
}
|
||||
|
||||
template<typename DerivedDispatcherT>
|
||||
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseLButtonDoubleClick()
|
||||
{
|
||||
Log("Mouse left button double click");
|
||||
MouseLButtonDoubleClickImpl();
|
||||
return static_cast<DerivedDispatcherT*>(this);
|
||||
}
|
||||
|
||||
template<typename DerivedDispatcherT>
|
||||
const char* ActionDispatcher<DerivedDispatcherT>::KeyboardModifierString(
|
||||
const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier)
|
||||
|
||||
+1
@@ -58,6 +58,7 @@ namespace AzManipulatorTestFramework
|
||||
void CameraStateImpl(const AzFramework::CameraState& cameraState) override;
|
||||
void MouseLButtonDownImpl() override;
|
||||
void MouseLButtonUpImpl() override;
|
||||
void MouseLButtonDoubleClickImpl() override;
|
||||
void MousePositionImpl(const AzFramework::ScreenPoint& position) override;
|
||||
void KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) override;
|
||||
void KeyboardModifierUpImpl(const KeyboardModifier& keyModifier) override;
|
||||
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
|
||||
#include <AzManipulatorTestFramework/ActionDispatcher.h>
|
||||
#include <AzManipulatorTestFramework/ImmediateModeActionDispatcher.h>
|
||||
#include <AzCore/std/containers/list.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
{
|
||||
//! Buffers actions to be dispatched upon a call to Execute().
|
||||
class RetainedModeActionDispatcher
|
||||
: public ActionDispatcher<RetainedModeActionDispatcher>
|
||||
{
|
||||
public:
|
||||
explicit RetainedModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction);
|
||||
//! Execute the sequence of actions and lock the dispatcher from adding further actions.
|
||||
RetainedModeActionDispatcher* Execute();
|
||||
//! Reset the sequence of actions and unlock the dispatcher from adding further actions.
|
||||
RetainedModeActionDispatcher* ResetSequence();
|
||||
|
||||
protected:
|
||||
// ActionDispatcher ...
|
||||
void EnableSnapToGridImpl() override;
|
||||
void DisableSnapToGridImpl() override;
|
||||
void GridSizeImpl(float size) override;
|
||||
void CameraStateImpl(const AzFramework::CameraState& cameraState) override;
|
||||
void MouseLButtonDownImpl() override;
|
||||
void MouseLButtonUpImpl() override;
|
||||
void MousePositionImpl(const AzFramework::ScreenPoint& position) override;
|
||||
void KeyboardModifierDownImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) override;
|
||||
void KeyboardModifierUpImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) override;
|
||||
void ExpectManipulatorBeingInteractedImpl() override;
|
||||
void ExpectManipulatorNotBeingInteractedImpl() override;
|
||||
void SetEntityWorldTransformImpl(AZ::EntityId entityId, const AZ::Transform& transform) override;
|
||||
void SetSelectedEntityImpl(AZ::EntityId entity) override;
|
||||
void SetSelectedEntitiesImpl(const AzToolsFramework::EntityIdList& entities) override;
|
||||
void EnterComponentModeImpl(const AZ::Uuid& uuid) override;
|
||||
|
||||
private:
|
||||
using Action = AZStd::function<void()>;
|
||||
void AddActionToSequence(Action&& action);
|
||||
ImmediateModeActionDispatcher m_dispatcher;
|
||||
AZStd::list<Action> m_actions;
|
||||
bool m_locked = false;
|
||||
};
|
||||
} // namespace AzManipulatorTestFramework
|
||||
@@ -83,7 +83,17 @@ namespace AzManipulatorTestFramework
|
||||
void ImmediateModeActionDispatcher::MouseLButtonUpImpl()
|
||||
{
|
||||
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up;
|
||||
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*GetMouseInteractionEvent());
|
||||
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
|
||||
ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
|
||||
// the mouse position will be the same as the previous event, thus the delta will be 0
|
||||
MouseMoveAfterButton();
|
||||
}
|
||||
|
||||
void ImmediateModeActionDispatcher::MouseLButtonDoubleClickImpl()
|
||||
{
|
||||
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::DoubleClick;
|
||||
ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
|
||||
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
|
||||
ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
|
||||
// the mouse position will be the same as the previous event, thus the delta will be 0
|
||||
MouseMoveAfterButton();
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzManipulatorTestFramework/RetainedModeActionDispatcher.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
{
|
||||
using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier;
|
||||
|
||||
RetainedModeActionDispatcher::RetainedModeActionDispatcher(
|
||||
ManipulatorViewportInteraction& viewportManipulatorInteraction)
|
||||
: m_dispatcher(viewportManipulatorInteraction)
|
||||
{
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::AddActionToSequence(Action&& action)
|
||||
{
|
||||
if (m_locked)
|
||||
{
|
||||
const char* error = "Couldn't add action to sequence, dispatcher is locked (you must call ResetSequence() \
|
||||
before adding actions to this dispatcher)";
|
||||
Log("%s", error);
|
||||
AZ_Assert(false, "Error: %s", error);
|
||||
}
|
||||
|
||||
m_actions.emplace_back(action);
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::EnableSnapToGridImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.EnableSnapToGrid(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::DisableSnapToGridImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.DisableSnapToGrid(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::GridSizeImpl(float size)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.GridSize(size); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::CameraStateImpl(const AzFramework::CameraState& cameraState)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.CameraState(cameraState); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::MouseLButtonDownImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.MouseLButtonDown(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::MouseLButtonUpImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.MouseLButtonUp(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::MousePositionImpl(const AzFramework::ScreenPoint& position)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.MousePosition(position); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::KeyboardModifierDownImpl(const KeyboardModifier& keyModifier)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.KeyboardModifierDown(keyModifier); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::KeyboardModifierUpImpl(const KeyboardModifier& keyModifier)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.KeyboardModifierUp(keyModifier); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::ExpectManipulatorBeingInteractedImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.ExpectManipulatorBeingInteracted(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::ExpectManipulatorNotBeingInteractedImpl()
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.ExpectManipulatorNotBeingInteracted(); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::SetEntityWorldTransformImpl(AZ::EntityId entityId, const AZ::Transform& transform)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.SetEntityWorldTransform(entityId, transform); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::SetSelectedEntityImpl(AZ::EntityId entity)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.SetSelectedEntity(entity); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::SetSelectedEntitiesImpl(const AzToolsFramework::EntityIdList& entities)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.SetSelectedEntities(entities); });
|
||||
}
|
||||
|
||||
void RetainedModeActionDispatcher::EnterComponentModeImpl(const AZ::Uuid& uuid)
|
||||
{
|
||||
AddActionToSequence([=]() { m_dispatcher.EnterComponentMode(uuid); });
|
||||
}
|
||||
|
||||
RetainedModeActionDispatcher* RetainedModeActionDispatcher::ResetSequence()
|
||||
{
|
||||
Log("%s", "Resetting the action sequence");
|
||||
m_actions.clear();
|
||||
m_dispatcher.ResetEvent();
|
||||
m_locked = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
RetainedModeActionDispatcher* RetainedModeActionDispatcher::Execute()
|
||||
{
|
||||
Log("Executing %u actions", m_actions.size());
|
||||
for (auto& action : m_actions)
|
||||
{
|
||||
action();
|
||||
}
|
||||
m_dispatcher.ResetEvent();
|
||||
m_locked = true;
|
||||
return this;
|
||||
}
|
||||
} // namespace AzManipulatorTestFramework
|
||||
@@ -14,12 +14,10 @@ set(FILES
|
||||
Include/AzManipulatorTestFramework/DirectManipulatorViewportInteraction.h
|
||||
Include/AzManipulatorTestFramework/IndirectManipulatorViewportInteraction.h
|
||||
Include/AzManipulatorTestFramework/ImmediateModeActionDispatcher.h
|
||||
Include/AzManipulatorTestFramework/RetainedModeActionDispatcher.h
|
||||
Include/AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h
|
||||
Source/ViewportInteraction.cpp
|
||||
Source/DirectManipulatorViewportInteraction.cpp
|
||||
Source/IndirectManipulatorViewportInteraction.cpp
|
||||
Source/ImmediateModeActionDispatcher.cpp
|
||||
Source/RetainedModeActionDispatcher.cpp
|
||||
Source/AzManipulatorTestFrameworkUtils.cpp
|
||||
)
|
||||
|
||||
@@ -2461,6 +2461,18 @@ namespace AzQtComponents
|
||||
placeholderRect.translate(0, -margins.bottom());
|
||||
}
|
||||
|
||||
// Also adjust the placeholderRect by the relative dpi change from the original screen, since setGeometry uses the screen's
|
||||
// virtualGeometry!
|
||||
QScreen* fromScreen = dock->screen();
|
||||
QScreen* toScreen = Utilities::ScreenAtPoint(placeholderRect.topLeft());
|
||||
|
||||
if (fromScreen != toScreen)
|
||||
{
|
||||
qreal factorRatio = QHighDpiScaling::factor(fromScreen) / QHighDpiScaling::factor(toScreen);
|
||||
placeholderRect.setWidth(aznumeric_cast<int>(aznumeric_cast<qreal>(placeholderRect.width()) * factorRatio));
|
||||
placeholderRect.setHeight(aznumeric_cast<int>(aznumeric_cast<qreal>(placeholderRect.height()) * factorRatio));
|
||||
}
|
||||
|
||||
// Place the floating dock widget
|
||||
makeDockWidgetFloating(dock, placeholderRect);
|
||||
clearDraggingState();
|
||||
|
||||
@@ -169,6 +169,10 @@ namespace AzQtComponents
|
||||
initializeSearchPaths(application, engineRootPath);
|
||||
initializeFonts();
|
||||
|
||||
QFont defaultFont("Open Sans");
|
||||
defaultFont.setPixelSize(12);
|
||||
QApplication::setFont(defaultFont);
|
||||
|
||||
m_titleBarOverdrawHandler = TitleBarOverdrawHandler::createHandler(application, this);
|
||||
|
||||
// The window decoration wrappers require the titlebar overdraw handler
|
||||
|
||||
@@ -221,24 +221,6 @@ namespace AzToolsFramework
|
||||
|
||||
using ViewportSettingsNotificationBus = AZ::EBus<ViewportSettingNotifications, ViewportEBusTraits>;
|
||||
|
||||
//! Requests to freeze the Viewport Input
|
||||
//! Added to prevent a bug with the legacy CryEngine Viewport code that would
|
||||
//! keep doing raycast tests even when no level is loaded, causing a crash.
|
||||
class ViewportFreezeRequests
|
||||
{
|
||||
public:
|
||||
//! Return if Viewport Input is frozen
|
||||
virtual bool IsViewportInputFrozen() = 0;
|
||||
//! Sets the Viewport Input freeze state
|
||||
virtual void FreezeViewportInput(bool freeze) = 0;
|
||||
|
||||
protected:
|
||||
~ViewportFreezeRequests() = default;
|
||||
};
|
||||
|
||||
//! Type to inherit to implement ViewportFreezeRequests.
|
||||
using ViewportFreezeRequestBus = AZ::EBus<ViewportFreezeRequests, ViewportEBusTraits>;
|
||||
|
||||
//! Viewport requests that are only guaranteed to be serviced by the Main Editor viewport.
|
||||
class MainEditorViewportInteractionRequests
|
||||
{
|
||||
|
||||
+205
-162
@@ -1770,6 +1770,12 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::ChangeSelectedEntity(const AZ::EntityId entityId)
|
||||
{
|
||||
DeselectEntities();
|
||||
SelectDeselect(entityId);
|
||||
}
|
||||
|
||||
bool EditorTransformComponentSelection::HandleMouseInteraction(const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
@@ -1821,202 +1827,239 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
// double click to deselect all
|
||||
if (Input::DeselectAll(mouseInteraction))
|
||||
if (ed_viewportStickySelect)
|
||||
{
|
||||
// note: even if m_selectedEntityIds is technically empty, we
|
||||
// may still have an entity selected that was clicked in the
|
||||
// entity outliner - we still want to make sure the deselect all
|
||||
// action clears the selection
|
||||
DeselectEntities();
|
||||
return false;
|
||||
// double click to deselect all
|
||||
if (Input::DeselectAll(mouseInteraction))
|
||||
{
|
||||
// note: even if m_selectedEntityIds is technically empty, we
|
||||
// may still have an entity selected that was clicked in the
|
||||
// entity outliner - we still want to make sure the deselect all
|
||||
// action clears the selection
|
||||
DeselectEntities();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// select/deselect (add/remove) entities with ctrl held
|
||||
if (Input::AdditiveIndividualSelect(clickOutcome, mouseInteraction))
|
||||
{
|
||||
if (SelectDeselect(entityIdUnderCursor))
|
||||
{
|
||||
if (m_selectedEntityIds.empty())
|
||||
{
|
||||
m_pivotOverrideFrame.Reset();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_selectedEntityIds.empty())
|
||||
{
|
||||
// select/deselect (add/remove) entities with ctrl held
|
||||
if (Input::AdditiveIndividualSelect(clickOutcome, mouseInteraction))
|
||||
{
|
||||
if (SelectDeselect(entityIdUnderCursor))
|
||||
{
|
||||
if (m_selectedEntityIds.empty())
|
||||
{
|
||||
m_pivotOverrideFrame.Reset();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// group copying/alignment to specific entity - 'ditto' position/orientation for group
|
||||
if (Input::GroupDitto(mouseInteraction))
|
||||
if (Input::GroupDitto(mouseInteraction) && PerformGroupDitto(entityIdUnderCursor))
|
||||
{
|
||||
if (entityIdUnderCursor.IsValid())
|
||||
{
|
||||
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM);
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Rotation:
|
||||
CopyOrientationToSelectedEntitiesGroup(QuaternionFromTransformNoScaling(worldFromLocal));
|
||||
break;
|
||||
case Mode::Scale:
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(worldFromLocal.GetUniformScale());
|
||||
break;
|
||||
case Mode::Translation:
|
||||
CopyTranslationToSelectedEntitiesGroup(worldFromLocal.GetTranslation());
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// individual copying/alignment to specific entity - 'ditto' position/orientation for individual
|
||||
if (Input::IndividualDitto(mouseInteraction))
|
||||
if (Input::IndividualDitto(mouseInteraction) && PerformIndividualDitto(entityIdUnderCursor))
|
||||
{
|
||||
if (entityIdUnderCursor.IsValid())
|
||||
{
|
||||
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM);
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Rotation:
|
||||
CopyOrientationToSelectedEntitiesIndividual(QuaternionFromTransformNoScaling(worldFromLocal));
|
||||
break;
|
||||
case Mode::Scale:
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(worldFromLocal.GetUniformScale());
|
||||
break;
|
||||
case Mode::Translation:
|
||||
CopyTranslationToSelectedEntitiesIndividual(worldFromLocal.GetTranslation());
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// try snapping to the terrain (if in Translation mode) and entity wasn't picked
|
||||
if (Input::SnapTerrain(mouseInteraction))
|
||||
{
|
||||
for (AZ::EntityId entityId : m_selectedEntityIds)
|
||||
{
|
||||
ScopedUndoBatch::MarkEntityDirty(entityId);
|
||||
}
|
||||
|
||||
if (m_mode == Mode::Translation)
|
||||
{
|
||||
const AZ::Vector3 finalSurfacePosition = PickTerrainPosition(mouseInteraction.m_mouseInteraction);
|
||||
|
||||
// handle modifier alternatives
|
||||
if (Input::IndividualDitto(mouseInteraction))
|
||||
{
|
||||
CopyTranslationToSelectedEntitiesIndividual(finalSurfacePosition);
|
||||
}
|
||||
else if (Input::GroupDitto(mouseInteraction))
|
||||
{
|
||||
CopyTranslationToSelectedEntitiesGroup(finalSurfacePosition);
|
||||
}
|
||||
}
|
||||
else if (m_mode == Mode::Rotation)
|
||||
{
|
||||
// handle modifier alternatives
|
||||
if (Input::IndividualDitto(mouseInteraction))
|
||||
{
|
||||
CopyOrientationToSelectedEntitiesIndividual(AZ::Quaternion::CreateIdentity());
|
||||
}
|
||||
else if (Input::GroupDitto(mouseInteraction))
|
||||
{
|
||||
CopyOrientationToSelectedEntitiesGroup(AZ::Quaternion::CreateIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
PerformSnapToTerrain(mouseInteraction);
|
||||
return false;
|
||||
}
|
||||
|
||||
// set manipulator pivot override translation or orientation (update manipulators)
|
||||
if (Input::ManipulatorDitto(mouseInteraction))
|
||||
{
|
||||
if (m_entityIdManipulators.m_manipulators)
|
||||
{
|
||||
ScopedUndoBatch undoBatch(s_dittoManipulatorUndoRedoDesc);
|
||||
|
||||
auto manipulatorCommand =
|
||||
AZStd::make_unique<EntityManipulatorCommand>(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName);
|
||||
|
||||
if (entityIdUnderCursor.IsValid())
|
||||
{
|
||||
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(worldFromLocal, entityIdUnderCursor, &AZ::TransformBus::Events::GetWorldTM);
|
||||
|
||||
// set orientation/translation to match picked entity
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Rotation:
|
||||
OverrideManipulatorOrientation(QuaternionFromTransformNoScaling(worldFromLocal));
|
||||
break;
|
||||
case Mode::Translation:
|
||||
OverrideManipulatorTranslation(worldFromLocal.GetTranslation());
|
||||
break;
|
||||
case Mode::Scale:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// only update pivot override when in translation or rotation mode
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Rotation:
|
||||
m_pivotOverrideFrame.m_pickTypes |= OptionalFrame::PickType::Orientation;
|
||||
[[fallthrough]];
|
||||
case Mode::Translation:
|
||||
m_pivotOverrideFrame.m_pickTypes |= OptionalFrame::PickType::Translation;
|
||||
m_pivotOverrideFrame.m_pickedEntityIdOverride = entityIdUnderCursor;
|
||||
break;
|
||||
case Mode::Scale:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// match the same behavior as if we pressed Ctrl+R to reset the manipulator
|
||||
DelegateClearManipulatorOverride();
|
||||
}
|
||||
|
||||
manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State(
|
||||
BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()),
|
||||
m_entityIdManipulators.m_manipulators->GetLocalTransform(), entityIdUnderCursor));
|
||||
|
||||
manipulatorCommand->SetParent(undoBatch.GetUndoBatch());
|
||||
manipulatorCommand.release();
|
||||
}
|
||||
PerformManipulatorDitto(entityIdUnderCursor);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (ed_viewportStickySelect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// standard toggle selection
|
||||
if (Input::IndividualSelect(clickOutcome))
|
||||
{
|
||||
SelectDeselect(entityIdUnderCursor);
|
||||
if (!ed_viewportStickySelect)
|
||||
{
|
||||
ChangeSelectedEntity(entityIdUnderCursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectDeselect(entityIdUnderCursor);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EditorTransformComponentSelection::PerformGroupDitto(const AZ::EntityId entityId)
|
||||
{
|
||||
if (entityId.IsValid())
|
||||
{
|
||||
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM);
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Rotation:
|
||||
CopyOrientationToSelectedEntitiesGroup(QuaternionFromTransformNoScaling(worldFromLocal));
|
||||
break;
|
||||
case Mode::Scale:
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(worldFromLocal.GetUniformScale());
|
||||
break;
|
||||
case Mode::Translation:
|
||||
CopyTranslationToSelectedEntitiesGroup(worldFromLocal.GetTranslation());
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EditorTransformComponentSelection::PerformIndividualDitto(const AZ::EntityId entityId)
|
||||
{
|
||||
if (entityId.IsValid())
|
||||
{
|
||||
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM);
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Rotation:
|
||||
CopyOrientationToSelectedEntitiesIndividual(QuaternionFromTransformNoScaling(worldFromLocal));
|
||||
break;
|
||||
case Mode::Scale:
|
||||
CopyScaleToSelectedEntitiesIndividualWorld(worldFromLocal.GetUniformScale());
|
||||
break;
|
||||
case Mode::Translation:
|
||||
CopyTranslationToSelectedEntitiesIndividual(worldFromLocal.GetTranslation());
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::PerformSnapToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
|
||||
{
|
||||
for (AZ::EntityId entityId : m_selectedEntityIds)
|
||||
{
|
||||
ScopedUndoBatch::MarkEntityDirty(entityId);
|
||||
}
|
||||
|
||||
if (m_mode == Mode::Translation)
|
||||
{
|
||||
const AZ::Vector3 finalSurfacePosition = PickTerrainPosition(mouseInteraction.m_mouseInteraction);
|
||||
|
||||
// handle modifier alternatives
|
||||
if (Input::IndividualDitto(mouseInteraction))
|
||||
{
|
||||
CopyTranslationToSelectedEntitiesIndividual(finalSurfacePosition);
|
||||
}
|
||||
else if (Input::GroupDitto(mouseInteraction))
|
||||
{
|
||||
CopyTranslationToSelectedEntitiesGroup(finalSurfacePosition);
|
||||
}
|
||||
}
|
||||
else if (m_mode == Mode::Rotation)
|
||||
{
|
||||
// handle modifier alternatives
|
||||
if (Input::IndividualDitto(mouseInteraction))
|
||||
{
|
||||
CopyOrientationToSelectedEntitiesIndividual(AZ::Quaternion::CreateIdentity());
|
||||
}
|
||||
else if (Input::GroupDitto(mouseInteraction))
|
||||
{
|
||||
CopyOrientationToSelectedEntitiesGroup(AZ::Quaternion::CreateIdentity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::PerformManipulatorDitto(const AZ::EntityId entityId)
|
||||
{
|
||||
if (m_entityIdManipulators.m_manipulators)
|
||||
{
|
||||
ScopedUndoBatch undoBatch(s_dittoManipulatorUndoRedoDesc);
|
||||
|
||||
auto manipulatorCommand =
|
||||
AZStd::make_unique<EntityManipulatorCommand>(CreateManipulatorCommandStateFromSelf(), s_manipulatorUndoRedoName);
|
||||
|
||||
if (entityId.IsValid())
|
||||
{
|
||||
AZ::Transform worldFromLocal = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(worldFromLocal, entityId, &AZ::TransformBus::Events::GetWorldTM);
|
||||
|
||||
// set orientation/translation to match picked entity
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Rotation:
|
||||
OverrideManipulatorOrientation(QuaternionFromTransformNoScaling(worldFromLocal));
|
||||
break;
|
||||
case Mode::Translation:
|
||||
OverrideManipulatorTranslation(worldFromLocal.GetTranslation());
|
||||
break;
|
||||
case Mode::Scale:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// only update pivot override when in translation or rotation mode
|
||||
switch (m_mode)
|
||||
{
|
||||
case Mode::Rotation:
|
||||
m_pivotOverrideFrame.m_pickTypes |= OptionalFrame::PickType::Orientation;
|
||||
[[fallthrough]];
|
||||
case Mode::Translation:
|
||||
m_pivotOverrideFrame.m_pickTypes |= OptionalFrame::PickType::Translation;
|
||||
m_pivotOverrideFrame.m_pickedEntityIdOverride = entityId;
|
||||
break;
|
||||
case Mode::Scale:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// match the same behavior as if we pressed Ctrl+R to reset the manipulator
|
||||
DelegateClearManipulatorOverride();
|
||||
}
|
||||
|
||||
manipulatorCommand->SetManipulatorAfter(EntityManipulatorCommand::State(
|
||||
BuildPivotOverride(m_pivotOverrideFrame.HasTranslationOverride(), m_pivotOverrideFrame.HasOrientationOverride()),
|
||||
m_entityIdManipulators.m_manipulators->GetLocalTransform(), entityId));
|
||||
|
||||
manipulatorCommand->SetParent(undoBatch.GetUndoBatch());
|
||||
manipulatorCommand.release();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void AddAction(
|
||||
AZStd::vector<AZStd::unique_ptr<QAction>>& actions,
|
||||
|
||||
+6
@@ -207,6 +207,7 @@ namespace AzToolsFramework
|
||||
void SetSelectedEntities(const EntityIdList& entityIds);
|
||||
void DeselectEntities();
|
||||
bool SelectDeselect(AZ::EntityId entityId);
|
||||
void ChangeSelectedEntity(AZ::EntityId entityId);
|
||||
|
||||
void RefreshSelectedEntityIds();
|
||||
void RefreshSelectedEntityIds(const EntityIdList& selectedEntityIds);
|
||||
@@ -298,6 +299,11 @@ namespace AzToolsFramework
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Vector3& localRotation);
|
||||
void SetEntityLocalRotation(AZ::EntityId entityId, const AZ::Quaternion& localRotation);
|
||||
|
||||
bool PerformGroupDitto(AZ::EntityId entityId);
|
||||
bool PerformIndividualDitto(AZ::EntityId entityId);
|
||||
void PerformManipulatorDitto(AZ::EntityId entityId);
|
||||
void PerformSnapToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
|
||||
|
||||
//! Responsible for keeping the space cluster in sync with the current reference frame.
|
||||
void UpdateSpaceCluster(ReferenceFrame referenceFrame);
|
||||
|
||||
|
||||
@@ -614,7 +614,7 @@ namespace UnitTest
|
||||
using EditorTransformComponentSelectionViewportPickingManipulatorTestFixture =
|
||||
IndirectCallManipulatorViewportInteractionFixtureMixin<EditorTransformComponentSelectionViewportPickingFixture>;
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, SingleClickWithNoSelectionWillSelectEntity)
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, StickySingleClickWithNoSelectionWillSelectEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -637,19 +637,44 @@ namespace UnitTest
|
||||
EXPECT_THAT(selectedEntitiesAfter.front(), Eq(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, SingleClickOffEntityWithSelectionWillNotDeselectEntity)
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, UnstickySingleClickWithNoSelectionWillSelectEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
using ::testing::Eq;
|
||||
auto selectedEntitiesBefore = SelectedEntities();
|
||||
EXPECT_TRUE(selectedEntitiesBefore.empty());
|
||||
|
||||
// calculate the position in screen space of the initial entity position
|
||||
const auto entity1ScreenPosition = AzFramework::WorldToScreen(m_entity1WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(entity1ScreenPosition)->MouseLButtonDown()->MouseLButtonUp();
|
||||
|
||||
// entity is selected
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter.size(), Eq(1));
|
||||
EXPECT_THAT(selectedEntitiesAfter.front(), Eq(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
StickySingleClickOffEntityWithSelectionWillNotDeselectEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
// position in space above the entity
|
||||
// position in space above the entities
|
||||
const auto clickOffPositionWorld = AZ::Vector3(5.0f, 15.0f, 12.0f);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the initial position of the entity
|
||||
// calculate the screen space position of the click
|
||||
const auto clickOffPositionScreen = AzFramework::WorldToScreen(clickOffPositionWorld, m_cameraState);
|
||||
|
||||
// click the empty space in the viewport
|
||||
@@ -662,9 +687,32 @@ namespace UnitTest
|
||||
EXPECT_THAT(selectedEntitiesAfter.front(), Eq(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, UnstickySingleClickOffEntityWithSelectionWillDeselectEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// position in space above the entities
|
||||
const auto clickOffPositionWorld = AZ::Vector3(5.0f, 15.0f, 12.0f);
|
||||
// calculate the screen space position of the click
|
||||
const auto clickOffPositionScreen = AzFramework::WorldToScreen(clickOffPositionWorld, m_cameraState);
|
||||
|
||||
// click the empty space in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(clickOffPositionScreen)->MouseLButtonDown()->MouseLButtonUp();
|
||||
|
||||
// entity was deselected
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_TRUE(selectedEntitiesAfter.empty());
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
SingleClickOnNewEntityWithSelectionWillNotChangeSelectedEntity)
|
||||
StickySingleClickOnNewEntityWithSelectionWillNotChangeSelectedEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -688,7 +736,31 @@ namespace UnitTest
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
CtrlSingleClickOnNewEntityWithSelectionWillAppendSelectedEntityToSelection)
|
||||
UnstickySingleClickOnNewEntityWithSelectionWillChangeSelectedEntity)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(entity2ScreenPosition)->MouseLButtonDown()->MouseLButtonUp();
|
||||
|
||||
// entity selection was changed
|
||||
using ::testing::Eq;
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter.size(), Eq(1));
|
||||
EXPECT_THAT(selectedEntitiesAfter.front(), Eq(m_entityId2));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
StickyCtrlSingleClickOnNewEntityWithSelectionWillAppendSelectedEntityToSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -715,7 +787,34 @@ namespace UnitTest
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
CtrlSingleClickOnEntityInSelectionWillRemoveEntityFromSelection)
|
||||
UnstickyCtrlSingleClickOnNewEntityWithSelectionWillAppendSelectedEntityToSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntity(m_entityId1);
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(entity2ScreenPosition)
|
||||
->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Control)
|
||||
->MouseLButtonDown()
|
||||
->MouseLButtonUp();
|
||||
|
||||
// entity selection was changed (one entity selected to two)
|
||||
using ::testing::UnorderedElementsAre;
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter, UnorderedElementsAre(m_entityId1, m_entityId2));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
StickyCtrlSingleClickOnEntityInSelectionWillRemoveEntityFromSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -740,7 +839,36 @@ namespace UnitTest
|
||||
EXPECT_THAT(selectedEntitiesAfter, UnorderedElementsAre(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, BoxSelectWithNoInitialSelectionAddsEntitiesToSelection)
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
UnstickyCtrlSingleClickOnEntityInSelectionWillRemoveEntityFromSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = false;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntities({ m_entityId1, m_entityId2 });
|
||||
|
||||
// calculate the position in screen space of the second entity
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(m_entity2WorldTranslation, m_cameraState);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->CameraState(m_cameraState)
|
||||
->MousePosition(entity2ScreenPosition)
|
||||
->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Control)
|
||||
->MouseLButtonDown()
|
||||
->MouseLButtonUp();
|
||||
|
||||
// entity selection was changed (entity2 was deselected)
|
||||
using ::testing::UnorderedElementsAre;
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesAfter, UnorderedElementsAre(m_entityId1));
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture,
|
||||
BoxSelectWithNoInitialSelectionAddsEntitiesToSelection)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
@@ -835,6 +963,32 @@ namespace UnitTest
|
||||
EXPECT_TRUE(selectedEntitiesAfter.empty());
|
||||
}
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, StickyDoubleClickWithSelectionWillDeselectEntities)
|
||||
{
|
||||
AzToolsFramework::ed_viewportStickySelect = true;
|
||||
|
||||
PositionEntities();
|
||||
PositionCamera(m_cameraState);
|
||||
|
||||
AzToolsFramework::SelectEntities({ m_entityId1, m_entityId2, m_entityId3 });
|
||||
|
||||
using ::testing::UnorderedElementsAre;
|
||||
auto selectedEntitiesBefore = SelectedEntities();
|
||||
EXPECT_THAT(selectedEntitiesBefore, UnorderedElementsAre(m_entityId1, m_entityId2, m_entityId3));
|
||||
|
||||
// position in space above the entities
|
||||
const auto clickOffPositionWorld = AZ::Vector3(5.0f, 15.0f, 12.0f);
|
||||
// calculate the screen space position of the click
|
||||
const auto clickOffPositionScreen = AzFramework::WorldToScreen(clickOffPositionWorld, m_cameraState);
|
||||
|
||||
// double click to deselect entities
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(clickOffPositionScreen)->MouseLButtonDoubleClick();
|
||||
|
||||
// no entities are selected
|
||||
auto selectedEntitiesAfter = SelectedEntities();
|
||||
EXPECT_TRUE(selectedEntitiesAfter.empty());
|
||||
}
|
||||
|
||||
using EditorTransformComponentSelectionManipulatorTestFixture =
|
||||
IndirectCallManipulatorViewportInteractionFixtureMixin<EditorTransformComponentSelectionFixture>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user