merging dev after AR fail
Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com>
This commit is contained in:
@@ -40,11 +40,12 @@ def Menus_EditMenuOptions_Work():
|
||||
("Toggle Pivot Location",),
|
||||
("Reset Entity Transform",),
|
||||
("Reset Manipulator",),
|
||||
("Reset Transform (Local)",),
|
||||
("Reset Transform (World)",),
|
||||
("Hide Selection",),
|
||||
("Show All",),
|
||||
("Modify", "Snap", "Snap angle"),
|
||||
("Lock Selection",),
|
||||
("Unlock All Entities",),
|
||||
("Modify", "Snap", "Angle snapping"),
|
||||
("Modify", "Snap", "Grid snapping"),
|
||||
("Modify", "Transform Mode", "Move"),
|
||||
("Modify", "Transform Mode", "Rotate"),
|
||||
("Modify", "Transform Mode", "Scale"),
|
||||
|
||||
@@ -39,7 +39,8 @@ def Menus_ViewMenuOptions_Work():
|
||||
("Viewport", "Go to Location"),
|
||||
("Viewport", "Remember Location"),
|
||||
("Viewport", "Switch Camera"),
|
||||
("Viewport", "Show/Hide Helpers"),
|
||||
("Viewport", "Show Helpers"),
|
||||
("Viewport", "Show Icons"),
|
||||
("Refresh Style",),
|
||||
]
|
||||
|
||||
|
||||
@@ -538,6 +538,7 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe
|
||||
auto snapMenu = modifyMenu.AddMenu(tr("Snap"));
|
||||
|
||||
snapMenu.AddAction(AzToolsFramework::SnapAngle);
|
||||
snapMenu.AddAction(AzToolsFramework::SnapToGrid);
|
||||
|
||||
auto transformModeMenu = modifyMenu.AddMenu(tr("Transform Mode"));
|
||||
transformModeMenu.AddAction(AzToolsFramework::EditModeMove);
|
||||
@@ -723,7 +724,8 @@ QMenu* LevelEditorMenuHandler::CreateViewMenu()
|
||||
// MISSING AVIRECORDER
|
||||
|
||||
viewportViewsMenuWrapper.AddSeparator();
|
||||
viewportViewsMenuWrapper.AddAction(ID_DISPLAY_SHOWHELPERS);
|
||||
viewportViewsMenuWrapper.AddAction(AzToolsFramework::Helpers);
|
||||
viewportViewsMenuWrapper.AddAction(AzToolsFramework::Icons);
|
||||
|
||||
// Refresh Style
|
||||
viewMenu.AddAction(ID_SKINS_REFRESH);
|
||||
|
||||
@@ -445,7 +445,6 @@ void CCryEditApp::RegisterActionHandlers()
|
||||
ON_COMMAND(ID_OPEN_ASSET_BROWSER, OnOpenAssetBrowserView)
|
||||
ON_COMMAND(ID_OPEN_AUDIO_CONTROLS_BROWSER, OnOpenAudioControlsEditor)
|
||||
|
||||
ON_COMMAND(ID_DISPLAY_SHOWHELPERS, OnShowHelpers)
|
||||
ON_COMMAND(ID_OPEN_TRACKVIEW, OnOpenTrackView)
|
||||
ON_COMMAND(ID_OPEN_UICANVASEDITOR, OnOpenUICanvasEditor)
|
||||
|
||||
@@ -2617,12 +2616,6 @@ void CCryEditApp::OnUpdateSelected(QAction* action)
|
||||
action->setEnabled(!GetIEditor()->GetSelection()->IsEmpty());
|
||||
}
|
||||
|
||||
void CCryEditApp::OnShowHelpers()
|
||||
{
|
||||
GetIEditor()->GetDisplaySettings()->DisplayHelpers(!GetIEditor()->GetDisplaySettings()->IsDisplayHelpers());
|
||||
GetIEditor()->Notify(eNotify_OnDisplayRenderUpdate);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::OnEditLevelData()
|
||||
{
|
||||
|
||||
@@ -237,7 +237,6 @@ public:
|
||||
void OnSyncPlayerUpdate(QAction* action);
|
||||
void OnResourcesReduceworkingset();
|
||||
void OnDummyCommand() {};
|
||||
void OnShowHelpers();
|
||||
void OnFileSave();
|
||||
void OnUpdateDocumentReady(QAction* action);
|
||||
void OnUpdateFileOpen(QAction* action);
|
||||
|
||||
@@ -68,8 +68,6 @@ void CDisplaySettings::SetObjectHideMask(int hideMask)
|
||||
m_objectHideMask = hideMask;
|
||||
|
||||
gSettings.objectHideMask = m_objectHideMask;
|
||||
|
||||
GetIEditor()->Notify(eNotify_OnDisplayRenderUpdate);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <AzToolsFramework/API/EditorCameraBus.h>
|
||||
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportSettings.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h>
|
||||
|
||||
@@ -665,13 +666,7 @@ void EditorViewportWidget::OnBeginPrepareRender()
|
||||
RenderAll();
|
||||
|
||||
// Draw 2D helpers.
|
||||
#ifdef LYSHINE_ATOM_TODO
|
||||
TransformationMatrices backupSceneMatrices;
|
||||
#endif
|
||||
m_debugDisplay->DepthTestOff();
|
||||
#ifdef LYSHINE_ATOM_TODO
|
||||
m_renderer->Set2DMode(m_rcClient.right(), m_rcClient.bottom(), backupSceneMatrices);
|
||||
#endif
|
||||
auto prevState = m_debugDisplay->GetState();
|
||||
m_debugDisplay->SetState(e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn);
|
||||
|
||||
@@ -1627,14 +1622,14 @@ Vec3 EditorViewportWidget::ViewToWorld(
|
||||
auto ray = m_renderViewport->ViewportScreenToWorldRay(AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(vp));
|
||||
|
||||
const float maxDistance = 10000.f;
|
||||
Vec3 v = AZVec3ToLYVec3(ray.direction) * maxDistance;
|
||||
Vec3 v = AZVec3ToLYVec3(ray.m_direction) * maxDistance;
|
||||
|
||||
if (!_finite(v.x) || !_finite(v.y) || !_finite(v.z))
|
||||
{
|
||||
return Vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
Vec3 colp = AZVec3ToLYVec3(ray.origin) + 0.002f * v;
|
||||
Vec3 colp = AZVec3ToLYVec3(ray.m_origin) + 0.002f * v;
|
||||
|
||||
return colp;
|
||||
}
|
||||
@@ -2426,6 +2421,16 @@ AZ::Vector3 EditorViewportSettings::DefaultEditorCameraPosition() const
|
||||
return SandboxEditor::CameraDefaultEditorPosition();
|
||||
}
|
||||
|
||||
bool EditorViewportSettings::IconsVisible() const
|
||||
{
|
||||
return AzToolsFramework::IconsVisible();
|
||||
}
|
||||
|
||||
bool EditorViewportSettings::HelpersVisible() const
|
||||
{
|
||||
return AzToolsFramework::HelpersVisible();
|
||||
}
|
||||
|
||||
AZ_CVAR_EXTERNED(bool, ed_previewGameInFullscreen_once);
|
||||
|
||||
bool EditorViewportWidget::ShouldPreviewFullscreen() const
|
||||
|
||||
@@ -79,6 +79,8 @@ struct EditorViewportSettings : public AzToolsFramework::ViewportInteraction::Vi
|
||||
float ManipulatorCircleBoundWidth() const override;
|
||||
bool StickySelectEnabled() const override;
|
||||
AZ::Vector3 DefaultEditorCameraPosition() const override;
|
||||
bool IconsVisible() const override;
|
||||
bool HelpersVisible() const override;
|
||||
};
|
||||
|
||||
// EditorViewportWidget window
|
||||
|
||||
@@ -168,8 +168,6 @@ enum EEditorNotifyEvent
|
||||
eNotify_OnVegetationObjectSelection, // When vegetation objects selection change.
|
||||
eNotify_OnVegetationPanelUpdate, // When vegetation objects selection change.
|
||||
|
||||
eNotify_OnDisplayRenderUpdate, // Sent when editor finish terrain texture generation.
|
||||
|
||||
eNotify_OnDataBaseUpdate, // DataBase Library was modified.
|
||||
|
||||
eNotify_OnLayerImportBegin, //layer import was started
|
||||
|
||||
+65
-19
@@ -47,6 +47,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <AzToolsFramework/API/EditorAnimationSystemRequestBus.h>
|
||||
#include <AzToolsFramework/SourceControl/QtSourceControlNotificationHandler.h>
|
||||
#include <AzToolsFramework/PythonTerminal/ScriptTermDialog.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportSettings.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h>
|
||||
|
||||
// AzQtComponents
|
||||
@@ -445,11 +446,11 @@ void MainWindow::Initialize()
|
||||
{
|
||||
m_viewPaneManager->SetMainWindow(m_viewPaneHost, &m_settings, /*unused*/ QByteArray());
|
||||
|
||||
InitActions();
|
||||
|
||||
RegisterStdViewClasses();
|
||||
InitCentralWidget();
|
||||
|
||||
InitActions();
|
||||
|
||||
// load toolbars ("shelves") and macros
|
||||
GetIEditor()->GetToolBoxManager()->Load(m_actionManager);
|
||||
|
||||
@@ -798,27 +799,40 @@ void MainWindow::InitActions()
|
||||
EditorTransformComponentSelectionRequests::Mode::Scale);
|
||||
});
|
||||
|
||||
am->AddAction(AzToolsFramework::SnapToGrid, tr("Snap to grid"))
|
||||
am->AddAction(AzToolsFramework::SnapToGrid, tr("Grid snapping"))
|
||||
.SetIcon(Style::icon("Grid"))
|
||||
.SetStatusTip(tr("Toggle grid snapping"))
|
||||
.SetShortcut(tr("G"))
|
||||
.SetToolTip(tr("Snap to grid (G)"))
|
||||
.SetStatusTip(tr("Toggles snap to grid"))
|
||||
.SetCheckable(true)
|
||||
.RegisterUpdateCallback([](QAction* action) {
|
||||
Q_ASSERT(action->isCheckable());
|
||||
action->setChecked(SandboxEditor::GridSnappingEnabled());
|
||||
})
|
||||
.Connect(&QAction::triggered, []() { SandboxEditor::SetGridSnapping(!SandboxEditor::GridSnappingEnabled()); });
|
||||
.RegisterUpdateCallback(
|
||||
[](QAction* action)
|
||||
{
|
||||
Q_ASSERT(action->isCheckable());
|
||||
action->setChecked(SandboxEditor::GridSnappingEnabled());
|
||||
})
|
||||
.Connect(
|
||||
&QAction::triggered,
|
||||
[]
|
||||
{
|
||||
SandboxEditor::SetGridSnapping(!SandboxEditor::GridSnappingEnabled());
|
||||
});
|
||||
|
||||
am->AddAction(AzToolsFramework::SnapAngle, tr("Snap angle"))
|
||||
am->AddAction(AzToolsFramework::SnapAngle, tr("Angle snapping"))
|
||||
.SetIcon(Style::icon("Angle"))
|
||||
.SetStatusTip(tr("Snap angle"))
|
||||
.SetStatusTip(tr("Toggle angle snapping"))
|
||||
.SetCheckable(true)
|
||||
.RegisterUpdateCallback([](QAction* action) {
|
||||
Q_ASSERT(action->isCheckable());
|
||||
action->setChecked(SandboxEditor::AngleSnappingEnabled());
|
||||
})
|
||||
.Connect(&QAction::triggered, []() { SandboxEditor::SetAngleSnapping(!SandboxEditor::AngleSnappingEnabled()); });
|
||||
.RegisterUpdateCallback(
|
||||
[](QAction* action)
|
||||
{
|
||||
Q_ASSERT(action->isCheckable());
|
||||
action->setChecked(SandboxEditor::AngleSnappingEnabled());
|
||||
})
|
||||
.Connect(
|
||||
&QAction::triggered,
|
||||
[]
|
||||
{
|
||||
SandboxEditor::SetAngleSnapping(!SandboxEditor::AngleSnappingEnabled());
|
||||
});
|
||||
|
||||
// Display actions
|
||||
am->AddAction(ID_SWITCHCAMERA_DEFAULTCAMERA, tr("Default Camera")).SetCheckable(true)
|
||||
@@ -918,9 +932,41 @@ void MainWindow::InitActions()
|
||||
.SetStatusTip(tr("Cycle 2D Viewport"))
|
||||
.RegisterUpdateCallback(cryEdit, &CCryEditApp::OnUpdateNonGameMode);
|
||||
#endif
|
||||
am->AddAction(ID_DISPLAY_SHOWHELPERS, tr("Show/Hide Helpers"))
|
||||
am->AddAction(AzToolsFramework::Helpers, tr("Show Helpers"))
|
||||
.SetShortcut(tr("Shift+Space"))
|
||||
.SetToolTip(tr("Show/Hide Helpers (Shift+Space)"));
|
||||
.SetToolTip(tr("Show/Hide Helpers (Shift+Space)"))
|
||||
.SetCheckable(true)
|
||||
.RegisterUpdateCallback(
|
||||
[](QAction* action)
|
||||
{
|
||||
Q_ASSERT(action->isCheckable());
|
||||
action->setChecked(AzToolsFramework::HelpersVisible());
|
||||
})
|
||||
.Connect(
|
||||
&QAction::triggered,
|
||||
[]()
|
||||
{
|
||||
AzToolsFramework::SetHelpersVisible(!AzToolsFramework::HelpersVisible());
|
||||
AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Broadcast(
|
||||
&AzToolsFramework::ViewportInteraction::ViewportSettingNotifications::OnDrawHelpersChanged,
|
||||
AzToolsFramework::HelpersVisible());
|
||||
});
|
||||
am->AddAction(AzToolsFramework::Icons, tr("Show Icons"))
|
||||
.SetShortcut(tr("Ctrl+Space"))
|
||||
.SetToolTip(tr("Show/Hide Icons (Ctrl+Space)"))
|
||||
.SetCheckable(true)
|
||||
.RegisterUpdateCallback(
|
||||
[](QAction* action)
|
||||
{
|
||||
Q_ASSERT(action->isCheckable());
|
||||
action->setChecked(AzToolsFramework::IconsVisible());
|
||||
})
|
||||
.Connect(
|
||||
&QAction::triggered,
|
||||
[]()
|
||||
{
|
||||
AzToolsFramework::SetIconsVisible(!AzToolsFramework::IconsVisible());
|
||||
});
|
||||
|
||||
// Audio actions
|
||||
am->AddAction(ID_SOUND_STOPALLSOUNDS, tr("Stop All Sounds"))
|
||||
|
||||
@@ -1986,8 +1986,3 @@ void SandboxIntegrationManager::BrowseForAssets(AssetSelectionModel& selection)
|
||||
{
|
||||
AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, GetMainWindow());
|
||||
}
|
||||
|
||||
bool SandboxIntegrationManager::DisplayHelpersVisible()
|
||||
{
|
||||
return GetIEditor()->GetDisplaySettings()->IsDisplayHelpers();
|
||||
}
|
||||
|
||||
@@ -165,7 +165,6 @@ private:
|
||||
void InstantiateSliceFromAssetId(const AZ::Data::AssetId& assetId) override;
|
||||
void ClearRedoStack() override;
|
||||
int GetIconTextureIdFromEntityIconPath(const AZStd::string& entityIconPath) override;
|
||||
bool DisplayHelpersVisible() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1281,6 +1281,8 @@ void OutlinerWidget::OnSearchTextChanged(const QString& activeTextFilter)
|
||||
|
||||
m_listModel->SearchStringChanged(filterString);
|
||||
m_proxyModel->UpdateFilter();
|
||||
|
||||
m_gui->m_objectTree->expandAll();
|
||||
}
|
||||
|
||||
void OutlinerWidget::OnFilterChanged(const AzQtComponents::SearchTypeFilterList& activeTypeFilters)
|
||||
|
||||
@@ -191,7 +191,6 @@
|
||||
#define ID_BRUSH_CSGSUBSTRUCT 33837
|
||||
#define ID_MATERIAL_PICKTOOL 33842
|
||||
#define ID_MODIFY_AIPOINT_PICKIMPASSLINK 33865
|
||||
#define ID_DISPLAY_SHOWHELPERS 33871
|
||||
#define ID_FILE_EXPORTSELECTION 33875
|
||||
#define ID_EDIT_PASTE_WITH_LINKS 33893
|
||||
#define ID_FILE_EXPORT_TERRAINAREA 33904
|
||||
|
||||
@@ -129,8 +129,8 @@ namespace SandboxEditor
|
||||
ViewportInteractionRequestBus::EventResult(
|
||||
ray, GetViewportId(), &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint);
|
||||
|
||||
m_mouseInteraction.m_mousePick.m_rayOrigin = ray.origin;
|
||||
m_mouseInteraction.m_mousePick.m_rayDirection = ray.direction;
|
||||
m_mouseInteraction.m_mousePick.m_rayOrigin = ray.m_origin;
|
||||
m_mouseInteraction.m_mousePick.m_rayDirection = ray.m_direction;
|
||||
m_mouseInteraction.m_mousePick.m_screenCoordinates = screenPoint;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : CViewportTitleDlg implementation file
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
@@ -42,38 +41,18 @@
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportSettings.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h>
|
||||
|
||||
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include "ui_ViewportTitleDlg.h"
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#endif //!defined(Q_MOC_RUN)
|
||||
#endif //! defined(Q_MOC_RUN)
|
||||
|
||||
// CViewportTitleDlg dialog
|
||||
|
||||
inline namespace Helpers
|
||||
{
|
||||
void ToggleHelpers()
|
||||
{
|
||||
const bool newValue = !GetIEditor()->GetDisplaySettings()->IsDisplayHelpers();
|
||||
GetIEditor()->GetDisplaySettings()->DisplayHelpers(newValue);
|
||||
GetIEditor()->Notify(eNotify_OnDisplayRenderUpdate);
|
||||
|
||||
if (newValue == false)
|
||||
{
|
||||
GetIEditor()->GetObjectManager()->SendEvent(EVENT_HIDE_HELPER);
|
||||
}
|
||||
AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Broadcast(
|
||||
&AzToolsFramework::ViewportInteraction::ViewportSettingNotifications::OnDrawHelpersChanged, newValue);
|
||||
}
|
||||
|
||||
bool IsHelpersShown()
|
||||
{
|
||||
return GetIEditor()->GetDisplaySettings()->IsDisplayHelpers();
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class CViewportTitleDlgDisplayInfoHelper
|
||||
@@ -98,7 +77,7 @@ namespace
|
||||
emit ViewportInfoStatusUpdated(static_cast<int>(state));
|
||||
}
|
||||
};
|
||||
} //end anonymous namespace
|
||||
} // end anonymous namespace
|
||||
|
||||
CViewportTitleDlg::CViewportTitleDlg(QWidget* pParent)
|
||||
: QWidget(pParent)
|
||||
@@ -215,13 +194,65 @@ void CViewportTitleDlg::SetupViewportInformationMenu()
|
||||
m_ui->m_debugInformationMenu->setMenu(GetViewportInformationMenu());
|
||||
connect(m_ui->m_debugInformationMenu, &QToolButton::clicked, this, &CViewportTitleDlg::OnToggleDisplayInfo);
|
||||
m_ui->m_debugInformationMenu->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::SetupHelpersButton()
|
||||
{
|
||||
connect(m_ui->m_helpers, &QToolButton::clicked, this, &CViewportTitleDlg::OnToggleHelpers);
|
||||
m_ui->m_helpers->setChecked(Helpers::IsHelpersShown());
|
||||
if (m_helpersMenu == nullptr)
|
||||
{
|
||||
m_helpersMenu = new QMenu("Helpers State", this);
|
||||
|
||||
auto helperAction = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::Helpers);
|
||||
connect(
|
||||
helperAction, &QAction::triggered, this,
|
||||
[this]
|
||||
{
|
||||
m_ui->m_helpers->setChecked(AzToolsFramework::HelpersVisible() || AzToolsFramework::IconsVisible());
|
||||
});
|
||||
|
||||
auto iconAction = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::Icons);
|
||||
connect(
|
||||
iconAction, &QAction::triggered, this,
|
||||
[this]
|
||||
{
|
||||
m_ui->m_helpers->setChecked(AzToolsFramework::HelpersVisible() || AzToolsFramework::IconsVisible());
|
||||
});
|
||||
|
||||
m_helpersAction = new QAction(tr("Helpers"), m_helpersMenu);
|
||||
m_helpersAction->setCheckable(true);
|
||||
connect(
|
||||
m_helpersAction, &QAction::triggered, this,
|
||||
[helperAction]
|
||||
{
|
||||
helperAction->trigger();
|
||||
});
|
||||
|
||||
m_iconsAction = new QAction(tr("Icons"), m_helpersMenu);
|
||||
m_iconsAction->setCheckable(true);
|
||||
connect(
|
||||
m_iconsAction, &QAction::triggered, this,
|
||||
[iconAction]
|
||||
{
|
||||
iconAction->trigger();
|
||||
});
|
||||
|
||||
m_helpersMenu->addAction(m_helpersAction);
|
||||
m_helpersMenu->addAction(m_iconsAction);
|
||||
|
||||
connect(
|
||||
m_helpersMenu, &QMenu::aboutToShow, this,
|
||||
[this]
|
||||
{
|
||||
m_helpersAction->setChecked(AzToolsFramework::HelpersVisible());
|
||||
m_iconsAction->setChecked(AzToolsFramework::IconsVisible());
|
||||
});
|
||||
|
||||
m_ui->m_helpers->setCheckable(true);
|
||||
m_ui->m_helpers->setMenu(m_helpersMenu);
|
||||
m_ui->m_helpers->setPopupMode(QToolButton::InstantPopup);
|
||||
}
|
||||
|
||||
m_ui->m_helpers->setChecked(AzToolsFramework::HelpersVisible() || AzToolsFramework::IconsVisible());
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::SetupOverflowMenu()
|
||||
@@ -279,15 +310,20 @@ void CViewportTitleDlg::SetupOverflowMenu()
|
||||
UpdateMuteActionText();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewportTitleDlg::SetViewPane(CLayoutViewPane* pViewPane)
|
||||
{
|
||||
if (m_pViewPane)
|
||||
{
|
||||
m_pViewPane->disconnect(this);
|
||||
}
|
||||
|
||||
m_pViewPane = pViewPane;
|
||||
|
||||
if (m_pViewPane)
|
||||
{
|
||||
connect(this, &QWidget::customContextMenuRequested, m_pViewPane, &CLayoutViewPane::ShowTitleMenu);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -318,7 +354,6 @@ void CViewportTitleDlg::OnInitDialog()
|
||||
m_ui->m_prefabFocusPath->hide();
|
||||
m_ui->m_prefabFocusBackButton->hide();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -336,13 +371,6 @@ void CViewportTitleDlg::OnMaximize()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewportTitleDlg::OnToggleHelpers()
|
||||
{
|
||||
Helpers::ToggleHelpers();
|
||||
m_ui->m_helpers->setChecked(Helpers::IsHelpersShown());
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::SetNoViewportInfo()
|
||||
{
|
||||
AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
|
||||
@@ -367,7 +395,6 @@ void CViewportTitleDlg::SetCompactViewportInfo()
|
||||
&AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState, AZ::AtomBridge::ViewportInfoDisplayState::CompactInfo);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewportTitleDlg::UpdateDisplayInfo()
|
||||
{
|
||||
@@ -783,9 +810,6 @@ void CViewportTitleDlg::OnEditorNotifyEvent(EEditorNotifyEvent event)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case eNotify_OnDisplayRenderUpdate:
|
||||
m_ui->m_helpers->setChecked(Helpers::IsHelpersShown());
|
||||
break;
|
||||
case eNotify_OnBeginGameMode:
|
||||
case eNotify_OnEndGameMode:
|
||||
UpdateMuteActionText();
|
||||
@@ -997,24 +1021,18 @@ void CViewportTitleDlg::UpdateOverFlowMenuState()
|
||||
m_angleSizeActionWidget->setEnabled(angleSnappingActive);
|
||||
}
|
||||
|
||||
namespace
|
||||
namespace
|
||||
{
|
||||
void PyToggleHelpers()
|
||||
{
|
||||
GetIEditor()->GetDisplaySettings()->DisplayHelpers(!GetIEditor()->GetDisplaySettings()->IsDisplayHelpers());
|
||||
GetIEditor()->Notify(eNotify_OnDisplayRenderUpdate);
|
||||
|
||||
if (GetIEditor()->GetDisplaySettings()->IsDisplayHelpers() == false)
|
||||
{
|
||||
GetIEditor()->GetObjectManager()->SendEvent(EVENT_HIDE_HELPER);
|
||||
}
|
||||
AzToolsFramework::SetHelpersVisible(!AzToolsFramework::HelpersVisible());
|
||||
}
|
||||
|
||||
bool PyIsHelpersShown()
|
||||
{
|
||||
return GetIEditor()->GetDisplaySettings()->IsDisplayHelpers();
|
||||
return AzToolsFramework::HelpersVisible();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -1029,11 +1047,12 @@ namespace AzToolsFramework
|
||||
->Attribute(AZ::Script::Attributes::Category, "Legacy/Editor")
|
||||
->Attribute(AZ::Script::Attributes::Module, "legacy.general");
|
||||
};
|
||||
|
||||
addLegacyGeneral(behaviorContext->Method("toggle_helpers", PyToggleHelpers, nullptr, "Toggles the display of helpers."));
|
||||
addLegacyGeneral(behaviorContext->Method("is_helpers_shown", PyIsHelpersShown, nullptr, "Gets the display state of helpers."));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#include "ViewportTitleDlg.moc"
|
||||
#include <moc_ViewportTitleDlg.cpp>
|
||||
|
||||
@@ -80,7 +80,6 @@ protected:
|
||||
void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam) override;
|
||||
|
||||
void OnMaximize();
|
||||
void OnToggleHelpers();
|
||||
void UpdateDisplayInfo();
|
||||
|
||||
void SetupCameraDropdownMenu();
|
||||
@@ -153,6 +152,9 @@ protected:
|
||||
QMenu* m_aspectMenu = nullptr;
|
||||
QMenu* m_resolutionMenu = nullptr;
|
||||
QMenu* m_viewportInformationMenu = nullptr;
|
||||
QMenu* m_helpersMenu = nullptr;
|
||||
QAction* m_helpersAction = nullptr;
|
||||
QAction* m_iconsAction = nullptr;
|
||||
QAction* m_noInformationAction = nullptr;
|
||||
QAction* m_normalInformationAction = nullptr;
|
||||
QAction* m_fullInformationAction = nullptr;
|
||||
|
||||
@@ -105,6 +105,8 @@ void ScriptContextDebug::ConnectHook()
|
||||
void ScriptContextDebug::DisconnectHook()
|
||||
{
|
||||
lua_sethook(m_context.NativeContext(), nullptr, 0, 0);
|
||||
m_currentStackLevel = -1;
|
||||
m_stepStackLevel = -1;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -651,6 +653,11 @@ void AZ::LuaHook(lua_State* l, lua_Debug* ar)
|
||||
context->PopCallstack();
|
||||
}
|
||||
context->m_currentStackLevel--;
|
||||
|
||||
if (context->m_currentStackLevel == -1)
|
||||
{
|
||||
context->m_stepStackLevel = -1;
|
||||
}
|
||||
}
|
||||
else if (ar->event == LUA_HOOKLINE)
|
||||
{
|
||||
@@ -731,7 +738,7 @@ void AZ::LuaHook(lua_State* l, lua_Debug* ar)
|
||||
//}
|
||||
}
|
||||
|
||||
if (doBreak)
|
||||
if (doBreak && bp->m_lineNumber > 0)
|
||||
{
|
||||
context->m_luaDebug = ar;
|
||||
context->m_breakCallback(context, bp);
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace AZ
|
||||
TimeSystem::TimeSystem()
|
||||
{
|
||||
m_lastInvokedTimeUs = static_cast<TimeUs>(AZStd::GetTimeNowMicroSecond());
|
||||
m_realLastInvokedTimeUs = static_cast<TimeUs>(AZStd::GetTimeNowMicroSecond());
|
||||
AZ::Interface<ITime>::Register(this);
|
||||
ITimeRequestBus::Handler::BusConnect();
|
||||
}
|
||||
@@ -101,7 +102,11 @@ namespace AZ
|
||||
|
||||
TimeUs TimeSystem::GetRealElapsedTimeUs() const
|
||||
{
|
||||
return static_cast<TimeUs>(AZStd::GetTimeNowMicroSecond());
|
||||
const TimeUs currentTime = static_cast<TimeUs>(AZStd::GetTimeNowMicroSecond());
|
||||
m_realAccumulatedTimeUs += currentTime - m_realLastInvokedTimeUs;
|
||||
m_realLastInvokedTimeUs = currentTime;
|
||||
|
||||
return m_realAccumulatedTimeUs;
|
||||
}
|
||||
|
||||
TimeUs TimeSystem::GetSimulationTickDeltaTimeUs() const
|
||||
|
||||
@@ -64,6 +64,14 @@ namespace AZ
|
||||
//! Mutable to allow GetElapsedTimeMs/TimeUs() to be a const functions.
|
||||
mutable TimeUs m_accumulatedTimeUs = AZ::Time::ZeroTimeUs;
|
||||
|
||||
//! Used to calculate the delta time between calls to GetRealElapsedTimeMs/TimeUs().
|
||||
//! Mutable to allow GetRealElapsedTimeMs/TimeUs() to be a const functions.
|
||||
mutable TimeUs m_realLastInvokedTimeUs = AZ::Time::ZeroTimeUs;
|
||||
|
||||
//! Accumulates the delta time of GetRealElapsedTimeMs/TimeUs() calls.
|
||||
//! Mutable to allow GetRealElapsedTimeMs/TimeUs() to be a const functions.
|
||||
mutable TimeUs m_realAccumulatedTimeUs = AZ::Time::ZeroTimeUs;
|
||||
|
||||
//! The current game tick delta time.
|
||||
//! Can be affected by time system cvars.
|
||||
//! Updated in AdvanceTickDeltaTimes().
|
||||
|
||||
@@ -213,27 +213,33 @@ namespace AzFramework
|
||||
|
||||
Camera Cameras::StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, const float deltaTime)
|
||||
{
|
||||
for (int i = 0; i < m_idleCameraInputs.size();)
|
||||
for (int idleIndex = 0; idleIndex < m_idleCameraInputs.size();)
|
||||
{
|
||||
auto& cameraInput = m_idleCameraInputs[i];
|
||||
auto& cameraInput = m_idleCameraInputs[idleIndex];
|
||||
const bool canBegin = cameraInput->Beginning() &&
|
||||
AZStd::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(),
|
||||
[](const auto& input)
|
||||
{
|
||||
return !input->Exclusive();
|
||||
}) &&
|
||||
(!cameraInput->Exclusive() || (cameraInput->Exclusive() && m_activeCameraInputs.empty()));
|
||||
(!cameraInput->Exclusive() || m_activeCameraInputs.empty());
|
||||
|
||||
if (canBegin)
|
||||
{
|
||||
m_activeCameraInputs.push_back(cameraInput);
|
||||
using AZStd::swap;
|
||||
swap(m_idleCameraInputs[i], m_idleCameraInputs[m_idleCameraInputs.size() - 1]);
|
||||
swap(m_idleCameraInputs[idleIndex], m_idleCameraInputs[m_idleCameraInputs.size() - 1]);
|
||||
m_idleCameraInputs.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
// if a camera attempted to start but was not allowed to, ensure activation is cancelled
|
||||
if (!cameraInput->Idle())
|
||||
{
|
||||
cameraInput->CancelActivation();
|
||||
}
|
||||
|
||||
idleIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,21 +251,21 @@ namespace AzFramework
|
||||
return acc;
|
||||
});
|
||||
|
||||
for (int i = 0; i < m_activeCameraInputs.size();)
|
||||
for (int activeIndex = 0; activeIndex < m_activeCameraInputs.size();)
|
||||
{
|
||||
auto& cameraInput = m_activeCameraInputs[i];
|
||||
auto& cameraInput = m_activeCameraInputs[activeIndex];
|
||||
if (cameraInput->Ending())
|
||||
{
|
||||
cameraInput->ClearActivation();
|
||||
m_idleCameraInputs.push_back(cameraInput);
|
||||
using AZStd::swap;
|
||||
swap(m_activeCameraInputs[i], m_activeCameraInputs[m_activeCameraInputs.size() - 1]);
|
||||
swap(m_activeCameraInputs[activeIndex], m_activeCameraInputs[m_activeCameraInputs.size() - 1]);
|
||||
m_activeCameraInputs.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraInput->ContinueActivation();
|
||||
i++;
|
||||
activeIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,9 +476,10 @@ namespace AzFramework
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
m_translation |= TranslationFromKey(input->m_channelId, m_translateCameraInputChannelIds);
|
||||
if (m_translation != TranslationType::Nil)
|
||||
if (auto translation = TranslationFromKey(input->m_channelId, m_translateCameraInputChannelIds);
|
||||
translation != TranslationType::Nil)
|
||||
{
|
||||
m_translation |= translation;
|
||||
BeginActivation();
|
||||
}
|
||||
|
||||
@@ -484,11 +491,16 @@ namespace AzFramework
|
||||
// ensure we don't process end events in the idle state
|
||||
else if (input->m_state == InputChannel::State::Ended && !Idle())
|
||||
{
|
||||
m_translation &= ~(TranslationFromKey(input->m_channelId, m_translateCameraInputChannelIds));
|
||||
if (m_translation == TranslationType::Nil)
|
||||
if (auto translation = TranslationFromKey(input->m_channelId, m_translateCameraInputChannelIds);
|
||||
translation != TranslationType::Nil)
|
||||
{
|
||||
EndActivation();
|
||||
m_translation &= ~translation;
|
||||
if (m_translation == TranslationType::Nil)
|
||||
{
|
||||
EndActivation();
|
||||
}
|
||||
}
|
||||
|
||||
if (input->m_channelId == m_translateCameraInputChannelIds.m_boostChannelId)
|
||||
{
|
||||
m_boost = false;
|
||||
|
||||
@@ -185,6 +185,11 @@ namespace AzFramework
|
||||
m_activation = Activation::Ending;
|
||||
}
|
||||
|
||||
void CancelActivation()
|
||||
{
|
||||
m_activation = Activation::Idle;
|
||||
}
|
||||
|
||||
void ContinueActivation()
|
||||
{
|
||||
// continue activation is called after the first step of the camera input,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/RTTI/TypeInfoSimple.h>
|
||||
#include <AzCore/base.h>
|
||||
|
||||
@@ -203,6 +204,12 @@ namespace AzFramework
|
||||
return AZ::Vector2(aznumeric_cast<float>(screenPoint.m_x), aznumeric_cast<float>(screenPoint.m_y));
|
||||
}
|
||||
|
||||
//! Return an AZ::Vector3 from a ScreenPoint (including z/depth value, defaulting to 0.0f).
|
||||
inline AZ::Vector3 Vector3FromScreenPoint(const ScreenPoint& screenPoint, const float z = 0.0f)
|
||||
{
|
||||
return AZ::Vector3(aznumeric_cast<float>(screenPoint.m_x), aznumeric_cast<float>(screenPoint.m_y), z);
|
||||
}
|
||||
|
||||
//! Return an AZ::Vector2 from a ScreenVector.
|
||||
inline AZ::Vector2 Vector2FromScreenVector(const ScreenVector& screenVector)
|
||||
{
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <Psapi.h>
|
||||
|
||||
AZ_CVAR(bool, ap_tether_lifetime, false, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
AZ_CVAR(bool, ap_tether_lifetime, true, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"If enabled, a parent process that launches the AP will terminate the AP on exit");
|
||||
|
||||
namespace AzFramework::AssetSystem::Platform
|
||||
|
||||
@@ -416,4 +416,78 @@ namespace UnitTest
|
||||
using ::testing::FloatNear;
|
||||
EXPECT_THAT(m_camera.m_pitch, FloatNear(expectedPitch, 0.001f));
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, InvalidTranslationInputKeyCannotBeginTranslateCameraInputAgain)
|
||||
{
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
|
||||
const bool consumed =
|
||||
m_cameraSystem->HandleEvents(AzFramework::DiscreteInputEvent{ m_orbitChannelId, AzFramework::InputChannel::State::Began });
|
||||
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
EXPECT_THAT(consumed, IsTrue());
|
||||
EXPECT_THAT(m_firstPersonTranslateCamera->Beginning(), IsFalse());
|
||||
EXPECT_THAT(m_firstPersonTranslateCamera->Active(), IsTrue());
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, InvalidTranslationInputKeyDownCannotBeginTranslateCameraInputAgain)
|
||||
{
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
|
||||
const bool consumed =
|
||||
m_cameraSystem->HandleEvents(AzFramework::DiscreteInputEvent{ m_orbitChannelId, AzFramework::InputChannel::State::Began });
|
||||
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
EXPECT_THAT(consumed, IsTrue());
|
||||
EXPECT_THAT(m_firstPersonTranslateCamera->Beginning(), IsFalse());
|
||||
EXPECT_THAT(m_firstPersonTranslateCamera->Active(), IsTrue());
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, InvalidTranslationInputKeyUpDoesNotAffectTranslateCameraInputEnd)
|
||||
{
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
|
||||
const bool consumed =
|
||||
m_cameraSystem->HandleEvents(AzFramework::DiscreteInputEvent{ m_orbitChannelId, AzFramework::InputChannel::State::Began });
|
||||
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Ended });
|
||||
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
EXPECT_THAT(consumed, IsTrue());
|
||||
EXPECT_THAT(m_firstPersonTranslateCamera->Idle(), IsTrue());
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, OrbitCameraInputCannotBeLeftInInvalidStateIfItCannotFullyBeginAfterInputChannelBegin)
|
||||
{
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_orbitChannelId, AzFramework::InputChannel::State::Began });
|
||||
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
EXPECT_THAT(m_orbitCamera->Beginning(), IsFalse());
|
||||
EXPECT_THAT(m_orbitCamera->Idle(), IsTrue());
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, OrbitCameraInputCannotBeLeftInInvalidStateIfItCannotFullyBeginAfterInputChannelBeginAndEnd)
|
||||
{
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_translateCameraInputChannelIds.m_forwardChannelId,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_orbitChannelId, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_orbitChannelId, AzFramework::InputChannel::State::Ended });
|
||||
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
EXPECT_THAT(m_orbitCamera->Ending(), IsFalse());
|
||||
EXPECT_THAT(m_orbitCamera->Idle(), IsTrue());
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
+14
-10
@@ -26,29 +26,33 @@ namespace AzManipulatorTestFramework
|
||||
{
|
||||
public:
|
||||
virtual ~ViewportInteractionInterface() = default;
|
||||
//! Return the camera state.
|
||||
//! Returns the camera state.
|
||||
virtual AzFramework::CameraState GetCameraState() = 0;
|
||||
//! Set the camera state.
|
||||
//! Sets the camera state.
|
||||
virtual void SetCameraState(const AzFramework::CameraState& cameraState) = 0;
|
||||
//! Retrieve the debug display.
|
||||
//! Retrieves the debug display.
|
||||
virtual AzFramework::DebugDisplayRequests& GetDebugDisplay() = 0;
|
||||
//! Set if grid snapping is enabled or not.
|
||||
//! Sets if grid snapping is enabled or not.
|
||||
virtual void SetGridSnapping(bool enabled) = 0;
|
||||
//! Set if angular snapping is enabled or not.
|
||||
//! Sets if angular snapping is enabled or not.
|
||||
virtual void SetAngularSnapping(bool enabled) = 0;
|
||||
//! Set the grid size.
|
||||
//! Sets the grid size.
|
||||
virtual void SetGridSize(float size) = 0;
|
||||
//! Set the angular step.
|
||||
//! Sets the angular step.
|
||||
virtual void SetAngularStep(float step) = 0;
|
||||
//! Get the viewport id.
|
||||
//! Gets the viewport id.
|
||||
virtual AzFramework::ViewportId GetViewportId() const = 0;
|
||||
//! Updates the visibility state.
|
||||
//! Updates which entities are currently visible given the current camera state.
|
||||
virtual void UpdateVisibility() = 0;
|
||||
//! Set if sticky select is enabled or not.
|
||||
//! Sets if sticky select is enabled or not.
|
||||
virtual void SetStickySelect(bool enabled) = 0;
|
||||
//! Get default Editor Camera Position.
|
||||
//! Gets default Editor Camera Position.
|
||||
virtual AZ::Vector3 DefaultEditorCameraPosition() const = 0;
|
||||
//! Sets if icons are visible in the viewport.
|
||||
virtual void SetIconsVisible(bool visible) = 0;
|
||||
//! Sets if helpers are visible in the viewport.
|
||||
virtual void SetHelpersVisible(bool visible) = 0;
|
||||
};
|
||||
|
||||
//! This interface is used to simulate the manipulator manager while the manipulators are under test.
|
||||
|
||||
+1
-1
@@ -26,6 +26,7 @@ namespace UnitTest
|
||||
using IndirectCallManipulatorViewportInteraction = AzManipulatorTestFramework::IndirectCallManipulatorViewportInteraction;
|
||||
using ImmediateModeActionDispatcher = AzManipulatorTestFramework::ImmediateModeActionDispatcher;
|
||||
|
||||
public:
|
||||
void SetUpEditorFixtureImpl() override
|
||||
{
|
||||
ToolsApplicationFixtureT::SetUpEditorFixtureImpl();
|
||||
@@ -43,7 +44,6 @@ namespace UnitTest
|
||||
ToolsApplicationFixtureT::TearDownEditorFixtureImpl();
|
||||
}
|
||||
|
||||
public:
|
||||
AzFramework::CameraState m_cameraState;
|
||||
AZStd::unique_ptr<ImmediateModeActionDispatcher> m_actionDispatcher;
|
||||
AZStd::unique_ptr<IndirectCallManipulatorViewportInteraction> m_viewportManipulatorInteraction;
|
||||
|
||||
-23
@@ -27,29 +27,6 @@ namespace AzManipulatorTestFramework
|
||||
const AZ::Vector3& position = AZ::Vector3::CreateZero(),
|
||||
float radius = 1.0f);
|
||||
|
||||
//! Create a mouse pick from the specified ray and screen point.
|
||||
AzToolsFramework::ViewportInteraction::MousePick CreateMousePick(
|
||||
const AZ::Vector3& origin, const AZ::Vector3& direction, const AzFramework::ScreenPoint& screenPoint);
|
||||
|
||||
//! Build a mouse pick from the specified mouse position and camera state.
|
||||
AzToolsFramework::ViewportInteraction::MousePick BuildMousePick(
|
||||
const AzFramework::ScreenPoint& screenPoint, const AzFramework::CameraState& cameraState);
|
||||
|
||||
//! Create a mouse interaction from the specified pick, buttons, interaction id and keyboard modifiers.
|
||||
AzToolsFramework::ViewportInteraction::MouseInteraction CreateMouseInteraction(
|
||||
const AzToolsFramework::ViewportInteraction::MousePick& mousePick,
|
||||
AzToolsFramework::ViewportInteraction::MouseButtons buttons,
|
||||
AzToolsFramework::ViewportInteraction::InteractionId interactionId,
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifiers modifiers);
|
||||
|
||||
//! Create a mouse buttons from the specified mouse button.
|
||||
AzToolsFramework::ViewportInteraction::MouseButtons CreateMouseButtons(AzToolsFramework::ViewportInteraction::MouseButton button);
|
||||
|
||||
//! Create a mouse interaction event from the specified interaction and event.
|
||||
AzToolsFramework::ViewportInteraction::MouseInteractionEvent CreateMouseInteractionEvent(
|
||||
const AzToolsFramework::ViewportInteraction::MouseInteraction& mouseInteraction,
|
||||
AzToolsFramework::ViewportInteraction::MouseEvent event);
|
||||
|
||||
//! Dispatch a mouse event to the main manipulator manager via a bus call.
|
||||
void DispatchMouseInteractionEvent(const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& event);
|
||||
|
||||
|
||||
+4
-1
@@ -24,9 +24,12 @@ namespace AzManipulatorTestFramework
|
||||
explicit IndirectCallManipulatorViewportInteraction(AZStd::shared_ptr<AzFramework::DebugDisplayRequests> debugDisplayRequests);
|
||||
~IndirectCallManipulatorViewportInteraction();
|
||||
|
||||
// ManipulatorViewportInteractionInterface ...
|
||||
// ManipulatorViewportInteraction overrides ...
|
||||
const ViewportInteractionInterface& GetViewportInteraction() const override;
|
||||
const ManipulatorManagerInterface& GetManipulatorManager() const override;
|
||||
// make non-const overloads visible
|
||||
using ManipulatorViewportInteraction::GetViewportInteraction;
|
||||
using ManipulatorViewportInteraction::GetManipulatorManager;
|
||||
|
||||
private:
|
||||
AZStd::unique_ptr<ViewportInteraction> m_viewportInteraction;
|
||||
|
||||
+9
-3
@@ -39,7 +39,8 @@ namespace AzManipulatorTestFramework
|
||||
AzFramework::ViewportId GetViewportId() const override;
|
||||
void UpdateVisibility() override;
|
||||
void SetStickySelect(bool enabled) override;
|
||||
AZ::Vector3 DefaultEditorCameraPosition() const override;
|
||||
void SetIconsVisible(bool visible) override;
|
||||
void SetHelpersVisible(bool visible) override;
|
||||
|
||||
// ViewportInteractionRequestBus overrides ...
|
||||
AzFramework::CameraState GetCameraState() override;
|
||||
@@ -58,6 +59,9 @@ namespace AzManipulatorTestFramework
|
||||
float ManipulatorLineBoundWidth() const override;
|
||||
float ManipulatorCircleBoundWidth() const override;
|
||||
bool StickySelectEnabled() const override;
|
||||
AZ::Vector3 DefaultEditorCameraPosition() const override;
|
||||
bool IconsVisible() const override;
|
||||
bool HelpersVisible() const override;
|
||||
|
||||
// EditorEntityViewportInteractionRequestBus overrides ...
|
||||
void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) override;
|
||||
@@ -68,10 +72,12 @@ namespace AzManipulatorTestFramework
|
||||
AzFramework::EntityVisibilityQuery m_entityVisibilityQuery;
|
||||
AZStd::shared_ptr<AzFramework::DebugDisplayRequests> m_debugDisplayRequests;
|
||||
AzFramework::CameraState m_cameraState;
|
||||
float m_gridSize = 1.0f;
|
||||
float m_angularStep = 0.0f;
|
||||
bool m_gridSnapping = false;
|
||||
bool m_angularSnapping = false;
|
||||
bool m_stickySelect = true;
|
||||
float m_gridSize = 1.0f;
|
||||
float m_angularStep = 0.0f;
|
||||
bool m_iconsVisible = true;
|
||||
bool m_helpersVisible = true;
|
||||
};
|
||||
} // namespace AzManipulatorTestFramework
|
||||
|
||||
@@ -82,49 +82,6 @@ namespace AzManipulatorTestFramework
|
||||
return manipulator;
|
||||
}
|
||||
|
||||
AzToolsFramework::ViewportInteraction::MousePick CreateMousePick(
|
||||
const AZ::Vector3& origin, const AZ::Vector3& direction, const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
return { origin, direction, screenPoint };
|
||||
}
|
||||
|
||||
AzToolsFramework::ViewportInteraction::MousePick BuildMousePick(
|
||||
const AzFramework::ScreenPoint& screenPoint, const AzFramework::CameraState& cameraState)
|
||||
{
|
||||
const auto nearPlaneWorldPosition = AzFramework::ScreenToWorld(screenPoint, cameraState);
|
||||
|
||||
AzToolsFramework::ViewportInteraction::MousePick mousePick;
|
||||
mousePick.m_screenCoordinates = screenPoint;
|
||||
mousePick.m_rayOrigin = nearPlaneWorldPosition;
|
||||
mousePick.m_rayDirection = (nearPlaneWorldPosition - cameraState.m_position).GetNormalized();
|
||||
|
||||
return mousePick;
|
||||
}
|
||||
|
||||
MouseInteraction CreateMouseInteraction(
|
||||
const MousePick& mousePick, MouseButtons buttons, InteractionId interactionId, KeyboardModifiers modifiers)
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::MouseInteraction interaction;
|
||||
interaction.m_mousePick = mousePick;
|
||||
interaction.m_mouseButtons = buttons;
|
||||
interaction.m_interactionId = interactionId;
|
||||
interaction.m_keyboardModifiers = modifiers;
|
||||
|
||||
return interaction;
|
||||
}
|
||||
|
||||
MouseButtons CreateMouseButtons(MouseButton button)
|
||||
{
|
||||
MouseButtons buttons;
|
||||
buttons.m_mouseButtons = static_cast<AZ::u32>(button);
|
||||
return buttons;
|
||||
}
|
||||
|
||||
MouseInteractionEvent CreateMouseInteractionEvent(const MouseInteraction& mouseInteraction, MouseEvent event)
|
||||
{
|
||||
return MouseInteractionEvent(mouseInteraction, event, /*captured=*/false);
|
||||
}
|
||||
|
||||
void DispatchMouseInteractionEvent(const MouseInteractionEvent& event)
|
||||
{
|
||||
AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
|
||||
@@ -120,7 +120,8 @@ namespace AzManipulatorTestFramework
|
||||
void ImmediateModeActionDispatcher::MousePositionImpl(const AzFramework::ScreenPoint& position)
|
||||
{
|
||||
const auto cameraState = m_manipulatorViewportInteraction.GetViewportInteraction().GetCameraState();
|
||||
GetMouseInteractionEvent()->m_mouseInteraction.m_mousePick = BuildMousePick(position, cameraState);
|
||||
GetMouseInteractionEvent()->m_mouseInteraction.m_mousePick =
|
||||
AzToolsFramework::ViewportInteraction::BuildMousePick(cameraState, position);
|
||||
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move;
|
||||
m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzManipulatorTestFramework/ViewportInteraction.h>
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorBus.h>
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
|
||||
|
||||
namespace AzManipulatorTestFramework
|
||||
{
|
||||
@@ -19,6 +20,9 @@ namespace AzManipulatorTestFramework
|
||||
AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler::BusConnect(m_viewportId);
|
||||
AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler::BusConnect(m_viewportId);
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusConnect(m_viewportId);
|
||||
|
||||
m_cameraState =
|
||||
AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AzManipulatorTestFramework::DefaultViewportSize);
|
||||
}
|
||||
|
||||
ViewportInteraction::~ViewportInteraction()
|
||||
@@ -113,6 +117,16 @@ namespace AzManipulatorTestFramework
|
||||
m_stickySelect = enabled;
|
||||
}
|
||||
|
||||
void ViewportInteraction::SetIconsVisible(const bool visible)
|
||||
{
|
||||
m_iconsVisible = visible;
|
||||
}
|
||||
|
||||
void ViewportInteraction::SetHelpersVisible(const bool visible)
|
||||
{
|
||||
m_helpersVisible = visible;
|
||||
}
|
||||
|
||||
AZ::Vector3 ViewportInteraction::DefaultEditorCameraPosition() const
|
||||
{
|
||||
return {};
|
||||
@@ -148,4 +162,14 @@ namespace AzManipulatorTestFramework
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
bool ViewportInteraction::IconsVisible() const
|
||||
{
|
||||
return m_iconsVisible;
|
||||
}
|
||||
|
||||
bool ViewportInteraction::HelpersVisible() const
|
||||
{
|
||||
return m_helpersVisible;
|
||||
}
|
||||
} // namespace AzManipulatorTestFramework
|
||||
|
||||
+20
-19
@@ -8,21 +8,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFrameworkUtils.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class LinearManipulatorTestFixture
|
||||
: public ToolsApplicationFixture
|
||||
class LinearManipulatorTestFixture : public ToolsApplicationFixture
|
||||
{
|
||||
protected:
|
||||
LinearManipulatorTestFixture(const AzToolsFramework::ManipulatorManagerId& manipulatorManagerId)
|
||||
: m_manipulatorManagerId(manipulatorManagerId) {}
|
||||
: m_manipulatorManagerId(manipulatorManagerId)
|
||||
{
|
||||
}
|
||||
|
||||
void SetUpEditorFixtureImpl() override
|
||||
{
|
||||
{
|
||||
m_linearManipulator = AzManipulatorTestFramework::CreateLinearManipulator(
|
||||
m_manipulatorManagerId,
|
||||
/*position=*/AZ::Vector3::CreateZero(),
|
||||
@@ -31,21 +32,21 @@ namespace UnitTest
|
||||
// default sanity check call backs
|
||||
m_linearManipulator->InstallLeftMouseDownCallback(
|
||||
[this](const AzToolsFramework::LinearManipulator::Action& /*action*/)
|
||||
{
|
||||
m_receivedLeftMouseDown = true;
|
||||
});
|
||||
{
|
||||
m_receivedLeftMouseDown = true;
|
||||
});
|
||||
|
||||
m_linearManipulator->InstallMouseMoveCallback(
|
||||
[this](const AzToolsFramework::LinearManipulator::Action& /*action*/)
|
||||
{
|
||||
m_receivedMouseMove = true;
|
||||
});
|
||||
{
|
||||
m_receivedMouseMove = true;
|
||||
});
|
||||
|
||||
m_linearManipulator->InstallLeftMouseUpCallback(
|
||||
[this](const AzToolsFramework::LinearManipulator::Action& /*action*/)
|
||||
{
|
||||
m_receivedLeftMouseUp = true;
|
||||
});
|
||||
{
|
||||
m_receivedLeftMouseUp = true;
|
||||
});
|
||||
}
|
||||
|
||||
void TearDownEditorFixtureImpl() override
|
||||
@@ -63,16 +64,16 @@ namespace UnitTest
|
||||
bool m_receivedLeftMouseUp = false;
|
||||
|
||||
// initial world space starting position for mouse interaction
|
||||
const AzToolsFramework::ViewportInteraction::MousePick m_mouseStartingPositionRay =
|
||||
AzManipulatorTestFramework::CreateMousePick(
|
||||
AZ::Vector3(0.0f, -2.0f, 0.0f), AZ::Vector3(0.0f, 1.0f, 0.0f), AzFramework::ScreenPoint( 0,0 ));
|
||||
const AzToolsFramework::ViewportInteraction::MousePick m_mouseStartingPositionRay{ AZ::Vector3(0.0f, -2.0f, 0.0f),
|
||||
AZ::Vector3(0.0f, 1.0f, 0.0f),
|
||||
AzFramework::ScreenPoint(0, 0) };
|
||||
|
||||
// left mouse down ray in world space 2 units back from origin looking down +y axis with a null interaction
|
||||
// id and no keyboard modifiers
|
||||
AzToolsFramework::ViewportInteraction::MouseInteraction m_interaction =
|
||||
AzManipulatorTestFramework::CreateMouseInteraction(
|
||||
AzToolsFramework::ViewportInteraction::BuildMouseInteraction(
|
||||
m_mouseStartingPositionRay,
|
||||
AzManipulatorTestFramework::CreateMouseButtons(AzToolsFramework::ViewportInteraction::MouseButton::Left),
|
||||
AzToolsFramework::ViewportInteraction::BuildMouseButtons(AzToolsFramework::ViewportInteraction::MouseButton::Left),
|
||||
AzToolsFramework::ViewportInteraction::InteractionId(AZ::EntityId(0), 0),
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifiers(0));
|
||||
};
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
*/
|
||||
|
||||
#include "AzManipulatorTestFrameworkTestFixtures.h"
|
||||
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorDefaultSelection.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
|
||||
@@ -34,8 +36,8 @@ namespace UnitTest
|
||||
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportLeftMouseClick)
|
||||
{
|
||||
// given a left mouse down ray in world space
|
||||
auto event =
|
||||
AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
|
||||
auto event = AzToolsFramework::ViewportInteraction::BuildMouseInteractionEvent(
|
||||
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
|
||||
|
||||
// consume the mouse down and up events
|
||||
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
|
||||
@@ -53,8 +55,8 @@ namespace UnitTest
|
||||
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportMouseMoveHover)
|
||||
{
|
||||
// given a left mouse down ray in world space
|
||||
const auto event =
|
||||
AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Move);
|
||||
const auto event = AzToolsFramework::ViewportInteraction::BuildMouseInteractionEvent(
|
||||
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Move);
|
||||
|
||||
// consume the mouse move event
|
||||
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
|
||||
@@ -72,8 +74,8 @@ namespace UnitTest
|
||||
TEST_F(AzManipulatorTestFrameworkBusCallTestFixture, ConsumeViewportMouseMoveActive)
|
||||
{
|
||||
// given a left mouse down ray in world space
|
||||
auto event =
|
||||
AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
|
||||
auto event = AzToolsFramework::ViewportInteraction::BuildMouseInteractionEvent(
|
||||
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
|
||||
|
||||
// consume the mouse down event
|
||||
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
|
||||
@@ -113,8 +115,8 @@ namespace UnitTest
|
||||
});
|
||||
|
||||
// given a left mouse down ray in world space
|
||||
auto event =
|
||||
AzManipulatorTestFramework::CreateMouseInteractionEvent(m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
|
||||
auto event = AzToolsFramework::ViewportInteraction::BuildMouseInteractionEvent(
|
||||
m_interaction, AzToolsFramework::ViewportInteraction::MouseEvent::Down);
|
||||
|
||||
// consume the mouse down event
|
||||
AzManipulatorTestFramework::DispatchMouseInteractionEvent(event);
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#define AZ_TRAIT_DISABLE_FAILED_JOB_BASIC_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_MATH_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_MERGESETTINGSFOLDER_CONFLICTINGSPECIALIZATIONS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_MULTIPLAYER_GRIDMATE_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_PHYSICS_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_SAVE_DATA_TESTS true
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#define AZ_TRAIT_UNIT_TEST_ENTITY_ID_GEN_TEST_COUNT 10000
|
||||
#define AZ_TRAIT_UNIT_TEST_DILLER_TRIGGER_EVENT_COUNT 100000
|
||||
|
||||
#define AZ_TRAIT_DISABLE_FAILED_MULTIPLAYER_GRIDMATE_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_NATIVE_WINDOWS_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_DLL_TESTS true
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <ostream>
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
void PrintTo(const AZ::IO::PathView& path, ::std::ostream* os)
|
||||
@@ -24,4 +27,12 @@ namespace AZ::IO
|
||||
{
|
||||
*os << "path: " << AZ::IO::FixedMaxPath(path.Native(), AZ::IO::PosixPathSeparator).MakePreferred().c_str();
|
||||
}
|
||||
}
|
||||
} // namespace AZ::IO
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
void PrintTo(const AZ::EntityId entityId, ::std::ostream* os)
|
||||
{
|
||||
*os << entityId.ToString().c_str();
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
@@ -37,4 +38,11 @@ namespace AZ::IO
|
||||
void PrintTo(const AZ::IO::FixedMaxPath& path, ::std::ostream* os);
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class EntityId;
|
||||
|
||||
void PrintTo(AZ::EntityId entityId, ::std::ostream* os);
|
||||
}
|
||||
|
||||
#include <AzTest/Printers.inl>
|
||||
|
||||
@@ -878,9 +878,6 @@ namespace AzToolsFramework
|
||||
/// Return the icon texture id (from internal IconManager) for a given entity icon path.
|
||||
/// This can be passed to DrawTextureLabel to draw an entity icon.
|
||||
virtual int GetIconTextureIdFromEntityIconPath(const AZStd::string& entityIconPath) = 0;
|
||||
|
||||
/// Returns if the Display Helpers option is toggled on in the Editor.
|
||||
virtual bool DisplayHelpersVisible() = 0;
|
||||
};
|
||||
|
||||
using EditorRequestBus = AZ::EBus<EditorRequests>;
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (auto serializationContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializationContext->Class<ProceduralPrefabSystemComponent>();
|
||||
serializationContext->Class<ProceduralPrefabSystemComponent, AZ::Component>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+35
-12
@@ -26,7 +26,9 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityTransformBus.h>
|
||||
#include <AzToolsFramework/API/EntityPropertyEditorRequestsBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponentBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponentSerializer.h>
|
||||
@@ -35,9 +37,8 @@
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -662,7 +663,6 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Prevent this from parenting to its own child. Check if this entity is in the new parent's hierarchy.
|
||||
auto potentialParentTransformComponent = GetTransformComponent(parentId);
|
||||
if (potentialParentTransformComponent && potentialParentTransformComponent->IsEntityInHierarchy(GetEntityId()))
|
||||
@@ -931,14 +931,27 @@ namespace AzToolsFramework
|
||||
{
|
||||
return AZ::Failure(AZStd::string("You cannot set an entity's parent to itself!"));
|
||||
}
|
||||
else
|
||||
|
||||
// Don't allow the change if it will result in a cycle hierarchy
|
||||
auto potentialParentTransformComponent = GetTransformComponent(actualValue);
|
||||
if (potentialParentTransformComponent && potentialParentTransformComponent->IsEntityInHierarchy(GetEntityId()))
|
||||
{
|
||||
// Don't allow the change if it will result in a cycle hierarchy
|
||||
auto potentialParentTransformComponent = GetTransformComponent(actualValue);
|
||||
if (potentialParentTransformComponent && potentialParentTransformComponent->IsEntityInHierarchy(GetEntityId()))
|
||||
{
|
||||
return AZ::Failure(AZStd::string("You cannot set an entity to be a child of one of its own children!"));
|
||||
}
|
||||
return AZ::Failure(AZStd::string("You cannot set an entity to be a child of one of its own children!"));
|
||||
}
|
||||
|
||||
// Don't allow read-only entities to be re-parented at all.
|
||||
// Also don't allow entities to be parented under read-only entities.
|
||||
if (auto readOnlyEntityPublicInterface = AZ::Interface<ReadOnlyEntityPublicInterface>::Get();
|
||||
readOnlyEntityPublicInterface->IsReadOnly(GetEntityId()) || readOnlyEntityPublicInterface->IsReadOnly(actualValue))
|
||||
{
|
||||
return AZ::Failure(AZStd::string("You cannot set an entity to be a child of a read-only entity!"));
|
||||
}
|
||||
|
||||
// Don't allow entities to be parented under closed containers.
|
||||
if (auto containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
|
||||
!containerEntityInterface->IsContainerOpen(actualValue))
|
||||
{
|
||||
return AZ::Failure(AZStd::string("You cannot set an entity to be a child of a closed container!"));
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
@@ -1245,6 +1258,15 @@ namespace AzToolsFramework
|
||||
|
||||
void TransformComponent::AddContextMenuActions(QMenu* menu)
|
||||
{
|
||||
bool parentEntityIsReadOnly = false;
|
||||
|
||||
// If the parent entity is marked as read-only, don't allow actions on this transform.
|
||||
if (auto readOnlyEntityPublicInterface = AZ::Interface<ReadOnlyEntityPublicInterface>::Get();
|
||||
readOnlyEntityPublicInterface->IsReadOnly(GetEntityId()))
|
||||
{
|
||||
parentEntityIsReadOnly = true;
|
||||
}
|
||||
|
||||
if (menu)
|
||||
{
|
||||
if (!menu->actions().empty())
|
||||
@@ -1266,10 +1288,10 @@ namespace AzToolsFramework
|
||||
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values);
|
||||
});
|
||||
resetAction->setEnabled(!m_editorTransform.m_locked);
|
||||
resetAction->setEnabled(!m_editorTransform.m_locked && !parentEntityIsReadOnly);
|
||||
|
||||
QString lockString = m_editorTransform.m_locked ? "Unlock transform values" : "Lock transform values";
|
||||
menu->addAction(lockString, [this, lockString]()
|
||||
QAction* lockAction = menu->addAction(lockString, [this, lockString]()
|
||||
{
|
||||
{
|
||||
AzToolsFramework::ScopedUndoBatch undo(lockString.toUtf8().data());
|
||||
@@ -1278,6 +1300,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
|
||||
});
|
||||
lockAction->setEnabled(!parentEntityIsReadOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,8 +89,8 @@ namespace AzToolsFramework
|
||||
const float rayLength)
|
||||
{
|
||||
AZ_Assert(rayLength > 0.0f, "Invalid ray length passed to RefreshRayRequest");
|
||||
rayRequest.m_startWorldPosition = viewportRay.origin;
|
||||
rayRequest.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength;
|
||||
rayRequest.m_startWorldPosition = viewportRay.m_origin;
|
||||
rayRequest.m_endWorldPosition = viewportRay.m_origin + viewportRay.m_direction * rayLength;
|
||||
}
|
||||
|
||||
AZ::Vector3 FindClosestPickIntersection(
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <AzFramework/Viewport/CameraState.h>
|
||||
#include <AzFramework/Viewport/ClickDetector.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
|
||||
@@ -151,13 +150,6 @@ namespace AzToolsFramework
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
};
|
||||
|
||||
//! A ray projection, originating from a point and extending in a direction specified as a normal.
|
||||
struct ProjectedViewportRay
|
||||
{
|
||||
AZ::Vector3 origin;
|
||||
AZ::Vector3 direction;
|
||||
};
|
||||
|
||||
//! Requests that can be made to the viewport to query and modify its state.
|
||||
class ViewportInteractionRequests
|
||||
{
|
||||
@@ -183,15 +175,6 @@ namespace AzToolsFramework
|
||||
//! Type to inherit to implement ViewportInteractionRequests.
|
||||
using ViewportInteractionRequestBus = AZ::EBus<ViewportInteractionRequests, ViewportEBusTraits>;
|
||||
|
||||
//! Utility function to return a viewport ray.
|
||||
inline ProjectedViewportRay ViewportScreenToWorldRay(
|
||||
const AzFramework::CameraState& cameraState, const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
const AZ::Vector3 rayOrigin = AzFramework::ScreenToWorld(screenPoint, cameraState);
|
||||
const AZ::Vector3 rayDirection = (rayOrigin - cameraState.m_position).GetNormalized();
|
||||
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection };
|
||||
}
|
||||
|
||||
//! Utility function to return a viewport ray using the ViewportInteractionRequestBus.
|
||||
inline ProjectedViewportRay ViewportScreenToWorldRay(
|
||||
const AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint)
|
||||
@@ -225,6 +208,10 @@ namespace AzToolsFramework
|
||||
virtual bool StickySelectEnabled() const = 0;
|
||||
//! Returns the default viewport camera position.
|
||||
virtual AZ::Vector3 DefaultEditorCameraPosition() const = 0;
|
||||
//! Returns if icons are visible in the viewport.
|
||||
virtual bool IconsVisible() const = 0;
|
||||
//! Returns if viewport helpers (additional debug drawing) are visible in the viewport.
|
||||
virtual bool HelpersVisible() const = 0;
|
||||
|
||||
protected:
|
||||
~ViewportSettingsRequests() = default;
|
||||
|
||||
@@ -20,6 +20,8 @@ namespace AzToolsFramework
|
||||
constexpr AZStd::string_view ScaleManipulatorBoxHalfExtentSetting = "/Amazon/Preferences/Editor/Manipulator/ScaleManipulatorBoxHalfExtent";
|
||||
constexpr AZStd::string_view RotationManipulatorRadiusSetting = "/Amazon/Preferences/Editor/Manipulator/RotationManipulatorRadius";
|
||||
constexpr AZStd::string_view ManipulatorViewBaseScaleSetting = "/Amazon/Preferences/Editor/Manipulator/ViewBaseScale";
|
||||
constexpr AZStd::string_view IconsVisibleSetting = "/Amazon/Preferences/Editor/IconsVisible";
|
||||
constexpr AZStd::string_view HelpersVisibleSetting = "/Amazon/Preferences/Editor/HelpersVisible";
|
||||
|
||||
bool FlipManipulatorAxesTowardsView()
|
||||
{
|
||||
@@ -120,4 +122,24 @@ namespace AzToolsFramework
|
||||
{
|
||||
SetRegistry(ManipulatorViewBaseScaleSetting, scale);
|
||||
}
|
||||
|
||||
bool IconsVisible()
|
||||
{
|
||||
return GetRegistry(IconsVisibleSetting, true);
|
||||
}
|
||||
|
||||
void SetIconsVisible(const bool visible)
|
||||
{
|
||||
SetRegistry(IconsVisibleSetting, visible);
|
||||
}
|
||||
|
||||
bool HelpersVisible()
|
||||
{
|
||||
return GetRegistry(HelpersVisibleSetting, true);
|
||||
}
|
||||
|
||||
void SetHelpersVisible(const bool visible)
|
||||
{
|
||||
SetRegistry(HelpersVisibleSetting, visible);
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -66,4 +66,10 @@ namespace AzToolsFramework
|
||||
|
||||
float ManipulatorViewBaseScale();
|
||||
void SetManipulatorViewBaseScale(float scale);
|
||||
|
||||
bool IconsVisible();
|
||||
void SetIconsVisible(bool visible);
|
||||
|
||||
bool HelpersVisible();
|
||||
void SetHelpersVisible(bool visible);
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -49,5 +49,22 @@ namespace AzToolsFramework
|
||||
->Field("MouseEvent", &MouseInteractionEvent::m_mouseEvent)
|
||||
->Field("WheelDelta", &MouseInteractionEvent::m_wheelDelta);
|
||||
}
|
||||
|
||||
MouseInteraction BuildMouseInteraction(
|
||||
const MousePick& mousePick, const MouseButtons buttons, const InteractionId interactionId, const KeyboardModifiers modifiers)
|
||||
{
|
||||
MouseInteraction interaction;
|
||||
interaction.m_mousePick = mousePick;
|
||||
interaction.m_mouseButtons = buttons;
|
||||
interaction.m_interactionId = interactionId;
|
||||
interaction.m_keyboardModifiers = modifiers;
|
||||
return interaction;
|
||||
}
|
||||
|
||||
MouseInteractionEvent BuildMouseInteractionEvent(
|
||||
const MouseInteraction& mouseInteraction, const MouseEvent event, const bool cursorCaptured /*= false*/)
|
||||
{
|
||||
return MouseInteractionEvent(mouseInteraction, event, cursorCaptured);
|
||||
}
|
||||
} // namespace ViewportInteraction
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AzFramework/Viewport/ScreenGeometry.h"
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzFramework/Viewport/CameraState.h>
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace AZ
|
||||
{
|
||||
class ReflectContext;
|
||||
class SerializeContext;
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -178,6 +178,12 @@ namespace AzToolsFramework
|
||||
//! @cond
|
||||
AZ_TYPE_INFO(MousePick, "{A69B9562-FC8C-4DE7-9137-0FF867B1513D}");
|
||||
MousePick() = default;
|
||||
MousePick(const AZ::Vector3& rayOrigin, const AZ::Vector3& rayDirection, const AzFramework::ScreenPoint& screenPoint)
|
||||
: m_rayOrigin(rayOrigin)
|
||||
, m_rayDirection(rayDirection)
|
||||
, m_screenCoordinates(screenPoint)
|
||||
{
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
AZ::Vector3 m_rayOrigin = AZ::Vector3::CreateZero(); //!< World space.
|
||||
@@ -249,6 +255,22 @@ namespace AzToolsFramework
|
||||
return mouseInteractionEvent.m_wheelDelta;
|
||||
}
|
||||
|
||||
//! A ray projection, originating from a point and extending in a direction specified as a normal.
|
||||
struct ProjectedViewportRay
|
||||
{
|
||||
AZ::Vector3 m_origin;
|
||||
AZ::Vector3 m_direction;
|
||||
};
|
||||
|
||||
//! Utility function to return a viewport ray.
|
||||
inline ProjectedViewportRay ViewportScreenToWorldRay(
|
||||
const AzFramework::CameraState& cameraState, const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
const AZ::Vector3 rayOrigin = AzFramework::ScreenToWorld(screenPoint, cameraState);
|
||||
const AZ::Vector3 rayDirection = (rayOrigin - cameraState.m_position).GetNormalized();
|
||||
return ProjectedViewportRay{ rayOrigin, rayDirection };
|
||||
}
|
||||
|
||||
//! Return QPoint from AzFramework::ScreenPoint.
|
||||
inline QPoint QPointFromScreenPoint(const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
@@ -301,6 +323,27 @@ namespace AzToolsFramework
|
||||
return mouseButtons;
|
||||
}
|
||||
|
||||
//! Build a mouse pick from the specified mouse position and camera state.
|
||||
inline MousePick BuildMousePick(const AzFramework::CameraState& cameraState, const AzFramework::ScreenPoint& screenPoint)
|
||||
{
|
||||
const auto ray = ViewportScreenToWorldRay(cameraState, screenPoint);
|
||||
return MousePick(ray.m_origin, ray.m_direction, screenPoint);
|
||||
}
|
||||
|
||||
//! Create a mouse interaction from the specified pick, buttons, interaction id and keyboard modifiers.
|
||||
MouseInteraction BuildMouseInteraction(
|
||||
const MousePick& mousePick, MouseButtons buttons, InteractionId interactionId, KeyboardModifiers modifiers);
|
||||
|
||||
//! Create a mouse buttons from the specified mouse button.
|
||||
inline MouseButtons BuildMouseButtons(const MouseButton button)
|
||||
{
|
||||
return MouseButtons(aznumeric_cast<AZ::u32>(button));
|
||||
}
|
||||
|
||||
//! Create a mouse interaction event from the specified interaction and event.
|
||||
MouseInteractionEvent BuildMouseInteractionEvent(
|
||||
const MouseInteraction& mouseInteraction, MouseEvent event, bool cursorCaptured = false);
|
||||
|
||||
//! Reflect all viewport related types.
|
||||
void ViewportInteractionReflect(AZ::ReflectContext* context);
|
||||
} // namespace ViewportInteraction
|
||||
|
||||
+108
-61
@@ -52,34 +52,45 @@ AZ_CVAR(
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"Use a lock icon when the cursor is over entities that cannot be interacted with");
|
||||
|
||||
AZ_CVAR(float, ed_iconMinScale, 0.1f, nullptr, AZ::ConsoleFunctorFlags::Null, "Minimum scale for icons in the distance");
|
||||
AZ_CVAR(float, ed_iconMaxScale, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum scale for icons near the camera");
|
||||
AZ_CVAR(float, ed_iconCloseDist, 3.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "Distance at which icons are at maximum scale");
|
||||
AZ_CVAR(float, ed_iconFarDist, 40.f, nullptr, AZ::ConsoleFunctorFlags::Null, "Distance at which icons are at minimum scale");
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(EditorHelpers, AZ::SystemAllocator, 0)
|
||||
|
||||
static const int s_iconSize = 36; // icon display size (in pixels)
|
||||
static const float s_iconMinScale = 0.1f; // minimum scale for icons in the distance
|
||||
static const float s_iconMaxScale = 1.0f; // maximum scale for icons near the camera
|
||||
static const float s_iconCloseDist = 3.f; // distance at which icons are at maximum scale
|
||||
static const float s_iconFarDist = 40.f; // distance at which icons are at minimum scale
|
||||
static const int IconSize = 36; // icon display size (in pixels)
|
||||
|
||||
// helper function to wrap EBus call to check if helpers are being displayed
|
||||
// note: the ['?'] icon in the top right of the editor
|
||||
static bool HelpersVisible()
|
||||
static bool HelpersVisible(const AzFramework::ViewportId viewportId)
|
||||
{
|
||||
bool helpersVisible = false;
|
||||
EditorRequestBus::BroadcastResult(helpersVisible, &EditorRequests::DisplayHelpersVisible);
|
||||
ViewportInteraction::ViewportSettingsRequestBus::EventResult(
|
||||
helpersVisible, viewportId, &ViewportInteraction::ViewportSettingsRequestBus::Events::HelpersVisible);
|
||||
return helpersVisible;
|
||||
}
|
||||
|
||||
// calculate the icon scale based on how far away it is (distanceSq) from a given point
|
||||
// note: this is mostly likely distance from the camera
|
||||
static float GetIconScale(const float distSq)
|
||||
// helper function to wrap EBus call to check if icons are being displayed
|
||||
static bool IconsVisible(const AzFramework::ViewportId viewportId)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
bool iconsVisible = false;
|
||||
ViewportInteraction::ViewportSettingsRequestBus::EventResult(
|
||||
iconsVisible, viewportId, &ViewportInteraction::ViewportSettingsRequestBus::Events::IconsVisible);
|
||||
return iconsVisible;
|
||||
}
|
||||
|
||||
return s_iconMinScale +
|
||||
(s_iconMaxScale - s_iconMinScale) *
|
||||
(1.0f - AZ::GetClamp(AZ::GetMax(0.0f, sqrtf(distSq) - s_iconCloseDist) / s_iconFarDist, 0.0f, 1.0f));
|
||||
float GetIconScale(const float distance)
|
||||
{
|
||||
return ed_iconMinScale +
|
||||
(ed_iconMaxScale - ed_iconMinScale) *
|
||||
(1.0f - AZ::GetClamp(AZ::GetMax(0.0f, distance - ed_iconCloseDist) / (ed_iconFarDist - ed_iconCloseDist), 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
float GetIconSize(const float distance)
|
||||
{
|
||||
return GetIconScale(distance) * IconSize;
|
||||
}
|
||||
|
||||
static void DisplayComponents(
|
||||
@@ -171,11 +182,14 @@ namespace AzToolsFramework
|
||||
|
||||
const int viewportId = mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId;
|
||||
|
||||
const bool helpersVisible = HelpersVisible();
|
||||
const bool iconsVisible = IconsVisible(viewportId);
|
||||
|
||||
const AZ::Matrix3x4 cameraView = AzFramework::CameraView(cameraState);
|
||||
const AZ::Matrix4x4 cameraProjection = AzFramework::CameraProjection(cameraState);
|
||||
|
||||
// selecting new entities
|
||||
AZ::EntityId entityIdUnderCursor;
|
||||
float closestDistance = std::numeric_limits<float>::max();
|
||||
float closestDistance = AZStd::numeric_limits<float>::max();
|
||||
for (size_t entityCacheIndex = 0; entityCacheIndex < m_entityDataCache->VisibleEntityDataCount(); ++entityCacheIndex)
|
||||
{
|
||||
const AZ::EntityId entityId = m_entityDataCache->GetVisibleEntityId(entityCacheIndex);
|
||||
@@ -185,8 +199,7 @@ namespace AzToolsFramework
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2d screen space selection - did we click an icon
|
||||
if (helpersVisible)
|
||||
if (iconsVisible)
|
||||
{
|
||||
// some components choose to hide their icons (e.g. meshes)
|
||||
// we also do not want to test against icons that may not be showing as they're inside a 'closed' entity container
|
||||
@@ -197,17 +210,23 @@ namespace AzToolsFramework
|
||||
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
|
||||
|
||||
// selecting based on 2d icon - should only do it when visible and not selected
|
||||
const AzFramework::ScreenPoint screenPosition = AzFramework::WorldToScreen(entityPosition, cameraState);
|
||||
const AZ::Vector3 ndcPoint = AzFramework::WorldToScreenNdc(entityPosition, cameraView, cameraProjection);
|
||||
const AzFramework::ScreenPoint screenPosition =
|
||||
AzFramework::ScreenPointFromNdc(AZ::Vector3ToVector2(ndcPoint), cameraState.m_viewportSize);
|
||||
|
||||
const float distSqFromCamera = cameraState.m_position.GetDistanceSq(entityPosition);
|
||||
const auto iconRange = static_cast<float>(GetIconScale(distSqFromCamera) * s_iconSize * 0.5f);
|
||||
const float distanceFromCamera = cameraState.m_position.GetDistance(entityPosition);
|
||||
const auto iconRange = GetIconSize(distanceFromCamera) * 0.5f;
|
||||
const auto screenCoords = mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates;
|
||||
|
||||
// 2d screen space selection - did we click an icon
|
||||
if (screenCoords.m_x >= screenPosition.m_x - iconRange && screenCoords.m_x <= screenPosition.m_x + iconRange &&
|
||||
screenCoords.m_y >= screenPosition.m_y - iconRange && screenCoords.m_y <= screenPosition.m_y + iconRange)
|
||||
screenCoords.m_y >= screenPosition.m_y - iconRange && screenCoords.m_y <= screenPosition.m_y + iconRange &&
|
||||
ndcPoint.GetZ() < closestDistance)
|
||||
{
|
||||
// use ndc z value for distance here which is in 0-1 range so will most likely 'win' when it comes to the
|
||||
// distance check (this is what we want as the cursor should always favor icons if they are hovered)
|
||||
closestDistance = ndcPoint.GetZ();
|
||||
entityIdUnderCursor = entityId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,9 +239,14 @@ namespace AzToolsFramework
|
||||
if (AabbIntersectMouseRay(mouseInteraction.m_mouseInteraction, aabb))
|
||||
{
|
||||
// if success, pick against specific component
|
||||
if (PickEntity(entityId, mouseInteraction.m_mouseInteraction, closestDistance, viewportId))
|
||||
float closestBoundDifference = AZStd::numeric_limits<float>::max();
|
||||
if (PickEntity(entityId, mouseInteraction.m_mouseInteraction, closestBoundDifference, viewportId))
|
||||
{
|
||||
entityIdUnderCursor = entityId;
|
||||
if (closestBoundDifference < closestDistance)
|
||||
{
|
||||
closestDistance = closestBoundDifference;
|
||||
entityIdUnderCursor = entityId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,55 +300,78 @@ namespace AzToolsFramework
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
|
||||
if (HelpersVisible())
|
||||
const bool iconsVisible = IconsVisible(viewportInfo.m_viewportId);
|
||||
const bool helpersVisible = HelpersVisible(viewportInfo.m_viewportId);
|
||||
|
||||
auto displayCheck = [this](const size_t entityCacheIndex, const AZ::EntityId entityId)
|
||||
{
|
||||
if (!m_entityDataCache->IsVisibleEntityVisible(entityCacheIndex) || !IsSelectableInViewport(entityId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (helpersVisible)
|
||||
{
|
||||
for (size_t entityCacheIndex = 0; entityCacheIndex < m_entityDataCache->VisibleEntityDataCount(); ++entityCacheIndex)
|
||||
{
|
||||
const AZ::EntityId entityId = m_entityDataCache->GetVisibleEntityId(entityCacheIndex);
|
||||
|
||||
if (!m_entityDataCache->IsVisibleEntityVisible(entityCacheIndex) || !IsSelectableInViewport(entityId))
|
||||
if (const AZ::EntityId entityId = m_entityDataCache->GetVisibleEntityId(entityCacheIndex);
|
||||
displayCheck(entityCacheIndex, entityId))
|
||||
{
|
||||
continue;
|
||||
// notify components to display
|
||||
DisplayComponents(entityId, viewportInfo, debugDisplay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// notify components to display
|
||||
DisplayComponents(entityId, viewportInfo, debugDisplay);
|
||||
if (iconsVisible)
|
||||
{
|
||||
auto editorViewportIconDisplay = EditorViewportIconDisplay::Get();
|
||||
if (!editorViewportIconDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_entityDataCache->IsVisibleEntityIconHidden(entityCacheIndex) ||
|
||||
(m_entityDataCache->IsVisibleEntitySelected(entityCacheIndex) && !showIconCheck(entityId)))
|
||||
for (size_t entityCacheIndex = 0; entityCacheIndex < m_entityDataCache->VisibleEntityDataCount(); ++entityCacheIndex)
|
||||
{
|
||||
if (const AZ::EntityId entityId = m_entityDataCache->GetVisibleEntityId(entityCacheIndex);
|
||||
displayCheck(entityCacheIndex, entityId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int iconTextureId = 0;
|
||||
EditorEntityIconComponentRequestBus::EventResult(
|
||||
iconTextureId, entityId, &EditorEntityIconComponentRequests::GetEntityIconTextureId);
|
||||
|
||||
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
|
||||
const float distSqFromCamera = cameraState.m_position.GetDistanceSq(entityPosition);
|
||||
|
||||
const float iconScale = GetIconScale(distSqFromCamera);
|
||||
const float iconSize = s_iconSize * iconScale;
|
||||
|
||||
using ComponentEntityAccentType = Components::EditorSelectionAccentSystemComponent::ComponentEntityAccentType;
|
||||
const AZ::Color iconHighlight = [this, entityCacheIndex]()
|
||||
{
|
||||
if (m_entityDataCache->IsVisibleEntityLocked(entityCacheIndex))
|
||||
if (m_entityDataCache->IsVisibleEntityIconHidden(entityCacheIndex) ||
|
||||
(m_entityDataCache->IsVisibleEntitySelected(entityCacheIndex) && !showIconCheck(entityId)))
|
||||
{
|
||||
return AZ::Color(AZ::u8(100), AZ::u8(100), AZ::u8(100), AZ::u8(255));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_entityDataCache->GetVisibleEntityAccent(entityCacheIndex) == ComponentEntityAccentType::Hover)
|
||||
int iconTextureId = 0;
|
||||
EditorEntityIconComponentRequestBus::EventResult(
|
||||
iconTextureId, entityId, &EditorEntityIconComponentRequests::GetEntityIconTextureId);
|
||||
|
||||
using ComponentEntityAccentType = Components::EditorSelectionAccentSystemComponent::ComponentEntityAccentType;
|
||||
const AZ::Color iconHighlight = [this, entityCacheIndex]()
|
||||
{
|
||||
return AZ::Color(AZ::u8(255), AZ::u8(120), AZ::u8(0), AZ::u8(204));
|
||||
}
|
||||
if (m_entityDataCache->IsVisibleEntityLocked(entityCacheIndex))
|
||||
{
|
||||
return AZ::Color(AZ::u8(100), AZ::u8(100), AZ::u8(100), AZ::u8(255));
|
||||
}
|
||||
|
||||
return AZ::Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}();
|
||||
if (m_entityDataCache->GetVisibleEntityAccent(entityCacheIndex) == ComponentEntityAccentType::Hover)
|
||||
{
|
||||
return AZ::Color(AZ::u8(255), AZ::u8(120), AZ::u8(0), AZ::u8(204));
|
||||
}
|
||||
|
||||
EditorViewportIconDisplay::Get()->DrawIcon({ viewportInfo.m_viewportId, iconTextureId, iconHighlight, entityPosition,
|
||||
EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace,
|
||||
AZ::Vector2{ iconSize, iconSize } });
|
||||
return AZ::Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}();
|
||||
|
||||
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
|
||||
const float distanceFromCamera = cameraState.m_position.GetDistance(entityPosition);
|
||||
const float iconSize = GetIconSize(distanceFromCamera);
|
||||
|
||||
editorViewportIconDisplay->DrawIcon({ viewportInfo.m_viewportId, iconTextureId, iconHighlight, entityPosition,
|
||||
EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace,
|
||||
AZ::Vector2{ iconSize, iconSize } });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,4 +106,12 @@ namespace AzToolsFramework
|
||||
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Entity Data queried by the EditorHelpers.
|
||||
const FocusModeInterface* m_focusModeInterface = nullptr; //!< API to interact with focus mode functionality.
|
||||
};
|
||||
|
||||
//! Calculate the icon scale based on how far away it is from a given point.
|
||||
//! @note This is mostly likely distance from the camera.
|
||||
float GetIconScale(float distance);
|
||||
|
||||
//! Calculate the icon size based on how far away it is from a given point.
|
||||
//! @note This is the base icon size multiplied by the icon scale to give a final viewport size.
|
||||
float GetIconSize(float distance);
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+6
-7
@@ -2521,10 +2521,9 @@ namespace AzToolsFramework
|
||||
AZStd::erase_if(
|
||||
m_selectedEntityIds,
|
||||
[readOnlyEntityPublicInterface](auto entityId)
|
||||
{
|
||||
return readOnlyEntityPublicInterface->IsReadOnly(entityId);
|
||||
}
|
||||
);
|
||||
{
|
||||
return readOnlyEntityPublicInterface->IsReadOnly(entityId);
|
||||
});
|
||||
}
|
||||
|
||||
// note: create/destroy pattern to be addressed
|
||||
@@ -3285,9 +3284,9 @@ namespace AzToolsFramework
|
||||
QObject::connect(
|
||||
action, &QAction::triggered, action,
|
||||
[this]
|
||||
{
|
||||
ToggleCenterPivotSelection();
|
||||
});
|
||||
{
|
||||
ToggleCenterPivotSelection();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -32,6 +32,8 @@ namespace AzToolsFramework
|
||||
constexpr inline AZ::Crc32 EditReset = AZ_CRC_CE("com.o3de.action.editortransform.editreset");
|
||||
constexpr inline AZ::Crc32 EditResetManipulator = AZ_CRC_CE("com.o3de.action.editortransform.editresetmanipulator");
|
||||
constexpr inline AZ::Crc32 ViewportUiVisible = AZ_CRC_CE("com.o3de.action.editortransform.viewportuivisible");
|
||||
constexpr inline AZ::Crc32 Helpers = AZ_CRC_CE("com.o3de.action.editor.helpers");
|
||||
constexpr inline AZ::Crc32 Icons = AZ_CRC_CE("com.o3de.action.editor.icons");
|
||||
//@}
|
||||
|
||||
//! Provide interface for EditorTransformComponentSelection requests.
|
||||
|
||||
@@ -40,16 +40,12 @@
|
||||
|
||||
#include <Tests/BoundsTestComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
std::ostream& operator<<(std::ostream& os, const EntityId entityId)
|
||||
{
|
||||
return os << entityId.ToString().c_str();
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
using AzToolsFramework::ViewportInteraction::BuildMouseButtons;
|
||||
using AzToolsFramework::ViewportInteraction::BuildMouseInteraction;
|
||||
using AzToolsFramework::ViewportInteraction::BuildMousePick;
|
||||
|
||||
AzToolsFramework::EntityIdList SelectedEntities()
|
||||
{
|
||||
AzToolsFramework::EntityIdList selectedEntitiesBefore;
|
||||
@@ -137,6 +133,18 @@ namespace UnitTest
|
||||
AzToolsFramework::EntityIdList m_entityIds;
|
||||
};
|
||||
|
||||
AZ::EntityId CreateEntityWithBounds(const char* entityName)
|
||||
{
|
||||
AZ::Entity* entity = nullptr;
|
||||
AZ::EntityId entityId = CreateDefaultEditorEntity(entityName, &entity);
|
||||
|
||||
entity->Deactivate();
|
||||
entity->CreateComponent<BoundsTestComponent>();
|
||||
entity->Activate();
|
||||
|
||||
return entityId;
|
||||
}
|
||||
|
||||
class EditorTransformComponentSelectionViewportPickingFixture : public ToolsApplicationFixture
|
||||
{
|
||||
public:
|
||||
@@ -146,21 +154,9 @@ namespace UnitTest
|
||||
// register a simple component implementing BoundsRequestBus and EditorComponentSelectionRequestsBus
|
||||
app->RegisterComponentDescriptor(BoundsTestComponent::CreateDescriptor());
|
||||
|
||||
auto createEntityWithBoundsFn = [](const char* entityName)
|
||||
{
|
||||
AZ::Entity* entity = nullptr;
|
||||
AZ::EntityId entityId = CreateDefaultEditorEntity(entityName, &entity);
|
||||
|
||||
entity->Deactivate();
|
||||
entity->CreateComponent<BoundsTestComponent>();
|
||||
entity->Activate();
|
||||
|
||||
return entityId;
|
||||
};
|
||||
|
||||
m_entityId1 = createEntityWithBoundsFn("Entity1");
|
||||
m_entityId2 = createEntityWithBoundsFn("Entity2");
|
||||
m_entityId3 = createEntityWithBoundsFn("Entity3");
|
||||
m_entityId1 = CreateEntityWithBounds("Entity1");
|
||||
m_entityId2 = CreateEntityWithBounds("Entity2");
|
||||
m_entityId3 = CreateEntityWithBounds("Entity3");
|
||||
}
|
||||
|
||||
void PositionEntities()
|
||||
@@ -959,6 +955,9 @@ namespace UnitTest
|
||||
|
||||
const auto entity2ScreenPosition = AzFramework::WorldToScreen(AzToolsFramework::GetWorldTranslation(m_entityId2), m_cameraState);
|
||||
|
||||
// ensure icons are not enabled to avoid them interfering with bound detection
|
||||
m_viewportManipulatorInteraction->GetViewportInteraction().SetIconsVisible(false);
|
||||
|
||||
// click the entity in the viewport
|
||||
m_actionDispatcher->SetStickySelect(true)
|
||||
->CameraState(m_cameraState)
|
||||
@@ -974,6 +973,137 @@ namespace UnitTest
|
||||
EXPECT_THAT(selectedEntities, UnorderedElementsAreArray(expectedSelectedEntities));
|
||||
}
|
||||
|
||||
// entity can be selected using icon
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, CursorOverEntityIconReturnsThatEntityId)
|
||||
{
|
||||
const AZ::EntityId boundlessEntityId = CreateDefaultEditorEntity("BoundlessEntity");
|
||||
|
||||
// camera (go to position format) -5.00, -8.00, 5.00, 0.00, 0.00
|
||||
AzFramework::SetCameraTransform(m_cameraState, AZ::Transform::CreateTranslation(AZ::Vector3(-5.0f, -8.0f, 5.0f)));
|
||||
// position entity in the world
|
||||
AZ::TransformBus::Event(boundlessEntityId, &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3(-5.0f, -1.0f, 5.0f));
|
||||
|
||||
const float distanceFromCamera = m_cameraState.m_position.GetDistance(AzToolsFramework::GetWorldTranslation(boundlessEntityId));
|
||||
|
||||
const auto quaterIconSize = AzToolsFramework::GetIconSize(distanceFromCamera) * 0.25f;
|
||||
const auto entity1ScreenPosition =
|
||||
AzFramework::WorldToScreen(AzToolsFramework::GetWorldTranslation(boundlessEntityId), m_cameraState) +
|
||||
AzFramework::ScreenVectorFromVector2(AZ::Vector2(quaterIconSize));
|
||||
|
||||
AzToolsFramework::EditorVisibleEntityDataCache editorVisibleEntityDataCache;
|
||||
AzToolsFramework::EditorHelpers editorHelpers(&editorVisibleEntityDataCache);
|
||||
|
||||
const auto viewportId = m_viewportManipulatorInteraction->GetViewportInteraction().GetViewportId();
|
||||
const auto mousePick = BuildMousePick(m_cameraState, entity1ScreenPosition);
|
||||
const auto mouseInteraction = BuildMouseInteraction(
|
||||
mousePick, BuildMouseButtons(AzToolsFramework::ViewportInteraction::MouseButton::None),
|
||||
AzToolsFramework::ViewportInteraction::InteractionId(AZ::EntityId(), viewportId),
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifiers());
|
||||
const auto mouseInteractionEvent = AzToolsFramework::ViewportInteraction::BuildMouseInteractionEvent(
|
||||
mouseInteraction, AzToolsFramework::ViewportInteraction::MouseEvent::Move, false);
|
||||
|
||||
// mimic mouse move
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(entity1ScreenPosition);
|
||||
|
||||
// simulate hovering over an icon in the viewport
|
||||
editorVisibleEntityDataCache.CalculateVisibleEntityDatas(AzFramework::ViewportInfo{ viewportId });
|
||||
auto entityIdUnderCursor = editorHelpers.FindEntityIdUnderCursor(m_cameraState, mouseInteractionEvent);
|
||||
|
||||
using ::testing::Eq;
|
||||
EXPECT_THAT(entityIdUnderCursor.EntityIdUnderCursor(), Eq(boundlessEntityId));
|
||||
}
|
||||
|
||||
// overlapping icons, nearest is detected
|
||||
TEST_F(EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, CursorOverOverlappingEntityIconsReturnsClosestEntityId)
|
||||
{
|
||||
const AZ::EntityId boundlessEntityId1 = CreateDefaultEditorEntity("BoundlessEntity1");
|
||||
const AZ::EntityId boundlessEntityId2 = CreateDefaultEditorEntity("BoundlessEntity2");
|
||||
|
||||
// camera (go to position format) -5.00, -8.00, 5.00, 0.00, 0.00
|
||||
AzFramework::SetCameraTransform(m_cameraState, AZ::Transform::CreateTranslation(AZ::Vector3(-5.0f, -8.0f, 5.0f)));
|
||||
// position entities in the world
|
||||
AZ::TransformBus::Event(boundlessEntityId1, &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3(-5.0f, -1.0f, 5.0f));
|
||||
// note: boundlessEntityId2 is closer to the camera
|
||||
AZ::TransformBus::Event(boundlessEntityId2, &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3(-5.0f, -3.0f, 5.0f));
|
||||
|
||||
const float distanceFromCamera = m_cameraState.m_position.GetDistance(AzToolsFramework::GetWorldTranslation(boundlessEntityId2));
|
||||
|
||||
const auto quaterIconSize = AzToolsFramework::GetIconSize(distanceFromCamera) * 0.25f;
|
||||
const auto entity2ScreenPosition =
|
||||
AzFramework::WorldToScreen(AzToolsFramework::GetWorldTranslation(boundlessEntityId2), m_cameraState) +
|
||||
AzFramework::ScreenVectorFromVector2(AZ::Vector2(quaterIconSize));
|
||||
|
||||
AzToolsFramework::EditorVisibleEntityDataCache editorVisibleEntityDataCache;
|
||||
AzToolsFramework::EditorHelpers editorHelpers(&editorVisibleEntityDataCache);
|
||||
|
||||
const auto viewportId = m_viewportManipulatorInteraction->GetViewportInteraction().GetViewportId();
|
||||
const auto mousePick = BuildMousePick(m_cameraState, entity2ScreenPosition);
|
||||
const auto mouseInteraction = BuildMouseInteraction(
|
||||
mousePick, BuildMouseButtons(AzToolsFramework::ViewportInteraction::MouseButton::None),
|
||||
AzToolsFramework::ViewportInteraction::InteractionId(AZ::EntityId(), viewportId),
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifiers());
|
||||
const auto mouseInteractionEvent = AzToolsFramework::ViewportInteraction::BuildMouseInteractionEvent(
|
||||
mouseInteraction, AzToolsFramework::ViewportInteraction::MouseEvent::Move, false);
|
||||
|
||||
// mimic mouse move
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(entity2ScreenPosition);
|
||||
|
||||
// simulate hovering over an icon in the viewport
|
||||
editorVisibleEntityDataCache.CalculateVisibleEntityDatas(AzFramework::ViewportInfo{ viewportId });
|
||||
auto entityIdUnderCursor = editorHelpers.FindEntityIdUnderCursor(m_cameraState, mouseInteractionEvent);
|
||||
|
||||
using ::testing::Eq;
|
||||
EXPECT_THAT(entityIdUnderCursor.EntityIdUnderCursor(), Eq(boundlessEntityId2));
|
||||
}
|
||||
|
||||
// if an entity with an icon is behind an entity with a bound, the entity with the icon will be selected
|
||||
// even if the bound is closer (this is because icons are treated as if they are on the near clip plane)
|
||||
TEST_F(
|
||||
EditorTransformComponentSelectionViewportPickingManipulatorTestFixture, FurtherAwayEntityWithIconReturnedWhenBoundEntityIsInFront)
|
||||
{
|
||||
const AZ::EntityId boundEntityId = CreateEntityWithBounds("BoundEntity");
|
||||
const AZ::EntityId boundlessEntityId = CreateDefaultEditorEntity("BoundlessEntity");
|
||||
|
||||
auto* boundTestComponent = AzToolsFramework::GetEntityById(boundEntityId)->FindComponent<BoundsTestComponent>();
|
||||
boundTestComponent->m_localBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-1.5f, -0.5f, -0.5f), AZ::Vector3(1.5f, 0.5, 0.5f));
|
||||
|
||||
// camera (go to position format) -5.00, -8.00, 5.00, 0.00, 0.00
|
||||
AzFramework::SetCameraTransform(m_cameraState, AZ::Transform::CreateTranslation(AZ::Vector3(-5.0f, -8.0f, 5.0f)));
|
||||
// position entities in the world
|
||||
AZ::TransformBus::Event(boundEntityId, &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3(-4.0f, -3.0f, 5.0f));
|
||||
// note: boundlessEntityId2 is closer to the camera
|
||||
AZ::TransformBus::Event(boundlessEntityId, &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3(-5.0f, -1.0f, 5.0f));
|
||||
|
||||
const float distanceFromCamera = m_cameraState.m_position.GetDistance(AzToolsFramework::GetWorldTranslation(boundlessEntityId));
|
||||
|
||||
const auto quaterIconSize = AzToolsFramework::GetIconSize(distanceFromCamera) * 0.25f;
|
||||
const auto entity2ScreenPosition =
|
||||
AzFramework::WorldToScreen(AzToolsFramework::GetWorldTranslation(boundlessEntityId), m_cameraState) +
|
||||
AzFramework::ScreenVectorFromVector2(AZ::Vector2(quaterIconSize));
|
||||
|
||||
AzToolsFramework::EditorVisibleEntityDataCache editorVisibleEntityDataCache;
|
||||
AzToolsFramework::EditorHelpers editorHelpers(&editorVisibleEntityDataCache);
|
||||
|
||||
const auto viewportId = m_viewportManipulatorInteraction->GetViewportInteraction().GetViewportId();
|
||||
const auto mousePick = BuildMousePick(m_cameraState, entity2ScreenPosition);
|
||||
const auto mouseInteraction = BuildMouseInteraction(
|
||||
mousePick, BuildMouseButtons(AzToolsFramework::ViewportInteraction::MouseButton::None),
|
||||
AzToolsFramework::ViewportInteraction::InteractionId(AZ::EntityId(), viewportId),
|
||||
AzToolsFramework::ViewportInteraction::KeyboardModifiers());
|
||||
const auto mouseInteractionEvent = AzToolsFramework::ViewportInteraction::BuildMouseInteractionEvent(
|
||||
mouseInteraction, AzToolsFramework::ViewportInteraction::MouseEvent::Move, false);
|
||||
|
||||
// mimic mouse move
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(entity2ScreenPosition);
|
||||
|
||||
// simulate hovering over an icon in the viewport
|
||||
editorVisibleEntityDataCache.CalculateVisibleEntityDatas(AzFramework::ViewportInfo{ viewportId });
|
||||
auto entityIdUnderCursor = editorHelpers.FindEntityIdUnderCursor(m_cameraState, mouseInteractionEvent);
|
||||
|
||||
using ::testing::Eq;
|
||||
EXPECT_THAT(entityIdUnderCursor.EntityIdUnderCursor(), Eq(boundlessEntityId));
|
||||
}
|
||||
|
||||
class EditorTransformComponentSelectionViewportPickingManipulatorTestFixtureParam
|
||||
: public EditorTransformComponentSelectionViewportPickingManipulatorTestFixture
|
||||
, public ::testing::WithParamInterface<bool>
|
||||
@@ -1709,8 +1839,9 @@ namespace UnitTest
|
||||
using MouseInteractionResult = AzToolsFramework::ViewportInteraction::MouseInteractionResult;
|
||||
|
||||
public:
|
||||
WheelEventWidget(QWidget* parent = nullptr)
|
||||
WheelEventWidget(const AzFramework::ViewportId viewportId, QWidget* parent = nullptr)
|
||||
: QWidget(parent)
|
||||
, m_viewportId(viewportId)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1719,7 +1850,7 @@ namespace UnitTest
|
||||
namespace vi = AzToolsFramework::ViewportInteraction;
|
||||
vi::MouseInteraction mouseInteraction;
|
||||
mouseInteraction.m_interactionId.m_cameraId = AZ::EntityId();
|
||||
mouseInteraction.m_interactionId.m_viewportId = 0;
|
||||
mouseInteraction.m_interactionId.m_viewportId = m_viewportId;
|
||||
mouseInteraction.m_mouseButtons = vi::BuildMouseButtons(ev->buttons());
|
||||
mouseInteraction.m_mousePick = vi::MousePick();
|
||||
mouseInteraction.m_keyboardModifiers = vi::BuildKeyboardModifiers(ev->modifiers());
|
||||
@@ -1731,15 +1862,15 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
MouseInteractionResult m_mouseInteractionResult;
|
||||
AzFramework::ViewportId m_viewportId;
|
||||
};
|
||||
|
||||
TEST_F(EditorTransformComponentSelectionFixture, MouseScrollWheelSwitchesTransformMode)
|
||||
TEST_F(EditorTransformComponentSelectionManipulatorTestFixture, MouseScrollWheelSwitchesTransformMode)
|
||||
{
|
||||
using ::testing::Eq;
|
||||
namespace vi = AzToolsFramework::ViewportInteraction;
|
||||
using AzToolsFramework::EditorTransformComponentSelectionRequestBus;
|
||||
|
||||
const auto transformMode = []()
|
||||
const auto transformMode = []
|
||||
{
|
||||
EditorTransformComponentSelectionRequestBus::Events::Mode transformMode;
|
||||
EditorTransformComponentSelectionRequestBus::EventResult(
|
||||
@@ -1752,7 +1883,7 @@ namespace UnitTest
|
||||
// preconditions
|
||||
EXPECT_THAT(transformMode(), EditorTransformComponentSelectionRequestBus::Events::Mode::Translation);
|
||||
|
||||
auto wheelEventWidget = WheelEventWidget();
|
||||
auto wheelEventWidget = WheelEventWidget(m_viewportManipulatorInteraction->GetViewportInteraction().GetViewportId());
|
||||
// attach the global event filter to the placeholder widget
|
||||
AzQtComponents::GlobalEventFilter globalEventFilter(QApplication::instance());
|
||||
wheelEventWidget.installEventFilter(&globalEventFilter);
|
||||
@@ -1768,6 +1899,7 @@ namespace UnitTest
|
||||
|
||||
// then
|
||||
// transform mode has changed and mouse event was handled
|
||||
using ::testing::Eq;
|
||||
EXPECT_THAT(transformMode(), Eq(EditorTransformComponentSelectionRequestBus::Events::Mode::Rotation));
|
||||
EXPECT_THAT(wheelEventWidget.m_mouseInteractionResult, Eq(vi::MouseInteractionResult::Viewport));
|
||||
}
|
||||
@@ -3100,7 +3232,7 @@ namespace UnitTest
|
||||
const AZ::Transform finalEntityTransform = AzToolsFramework::GetWorldTransform(m_entityIdBox);
|
||||
|
||||
const auto viewportRay = AzToolsFramework::ViewportInteraction::ViewportScreenToWorldRay(m_cameraState, initialPositionScreen);
|
||||
const auto distanceAway = (finalEntityTransform.GetTranslation() - viewportRay.origin).GetLength();
|
||||
const auto distanceAway = (finalEntityTransform.GetTranslation() - viewportRay.m_origin).GetLength();
|
||||
|
||||
// ensure final world positions match
|
||||
EXPECT_THAT(finalEntityTransform, IsCloseTolerance(finalTransformWorld, 0.01f));
|
||||
|
||||
@@ -62,7 +62,6 @@ namespace UnitTest
|
||||
|
||||
void BrowseForAssets(AssetBrowser::AssetSelectionModel& /*selection*/) override {}
|
||||
int GetIconTextureIdFromEntityIconPath(const AZStd::string& entityIconPath) override { AZ_UNUSED(entityIconPath); return 0; }
|
||||
bool DisplayHelpersVisible() override { return false; }
|
||||
|
||||
void GoToSelectedEntitiesInViewports() override
|
||||
{
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#include <Tests/FocusMode/EditorFocusModeSelectionFixture.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
namespace UnitTest
|
||||
{
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionTests_FindHighestSelectableEntityWithNoContainers)
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionFindHighestSelectableEntityWithNoContainers)
|
||||
{
|
||||
// When no containers are in the way, the function will just return the entityId of the entity that was clicked.
|
||||
|
||||
|
||||
// Click on Car Entity
|
||||
ClickAtWorldPositionOnViewport(WorldCarEntityPosition);
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(selectedEntitiesAfter.front(), m_entityMap[CarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionTests_FindHighestSelectableEntityWithClosedContainer)
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionFindHighestSelectableEntityWithClosedContainer)
|
||||
{
|
||||
// If a closed container is an ancestor of the queried entity, the closed container is selected.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]); // Containers are closed by default
|
||||
@@ -40,7 +40,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionTests_FindHighestSelectableEntityWithOpenContainer)
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionFindHighestSelectableEntityWithOpenContainer)
|
||||
{
|
||||
// If a closed container is an ancestor of the queried entity, the closed container is selected.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
@@ -58,7 +58,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionTests_FindHighestSelectableEntityWithMultipleClosedContainers)
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionFindHighestSelectableEntityWithMultipleClosedContainers)
|
||||
{
|
||||
// If multiple closed containers are ancestors of the queried entity, the highest closed container is selected.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
@@ -77,7 +77,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionTests_FindHighestSelectableEntityWithMultipleContainers)
|
||||
TEST_F(EditorFocusModeSelectionFixture, ContainerEntitySelectionFindHighestSelectableEntityWithMultipleContainers)
|
||||
{
|
||||
// If multiple containers are ancestors of the queried entity, the highest closed container is selected.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
@@ -96,4 +96,4 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
}
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#include <Tests/FocusMode/EditorFocusModeFixture.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
namespace UnitTest
|
||||
{
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_Register)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityRegister)
|
||||
{
|
||||
// Registering an entity is successful.
|
||||
auto outcome = m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[CarEntityName]);
|
||||
@@ -20,7 +20,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_RegisterTwice)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityRegisterTwice)
|
||||
{
|
||||
// Registering an entity twice fails.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[CarEntityName]);
|
||||
@@ -31,7 +31,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_Unregister)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityUnregister)
|
||||
{
|
||||
// Unregistering a container entity is successful.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[CarEntityName]);
|
||||
@@ -39,21 +39,21 @@ namespace AzToolsFramework
|
||||
EXPECT_TRUE(outcome.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_UnregisterRegularEntity)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityUnregisterRegularEntity)
|
||||
{
|
||||
// Unregistering an entity that was not previously registered fails.
|
||||
auto outcome = m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CarEntityName]);
|
||||
EXPECT_FALSE(outcome.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_UnregisterTwice)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityUnregisterTwice)
|
||||
{
|
||||
// Unregistering a container entity twice fails.
|
||||
auto outcome = m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CarEntityName]);
|
||||
EXPECT_FALSE(outcome.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_IsContainerOnRegularEntity)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityIsContainerOnRegularEntity)
|
||||
{
|
||||
// If a regular entity is passed, IsContainer returns false.
|
||||
// Note that we use a different entity than the tests above to validate a completely new EntityId.
|
||||
@@ -61,7 +61,7 @@ namespace AzToolsFramework
|
||||
EXPECT_FALSE(isContainer);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_IsContainerOnRegisteredContainer)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityIsContainerOnRegisteredContainer)
|
||||
{
|
||||
// If a container entity is passed, IsContainer returns true.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[SportsCarEntityName]);
|
||||
@@ -72,7 +72,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[SportsCarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_IsContainerOnUnRegisteredContainer)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityIsContainerOnUnRegisteredContainer)
|
||||
{
|
||||
// If an entity that was previously a container but was then unregistered is passed, IsContainer returns false.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[SportsCarEntityName]);
|
||||
@@ -82,14 +82,14 @@ namespace AzToolsFramework
|
||||
EXPECT_FALSE(isContainer);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_SetContainerOpenOnRegularEntity)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntitySetContainerOpenOnRegularEntity)
|
||||
{
|
||||
// Setting a regular entity to open should return a failure.
|
||||
auto outcome = m_containerEntityInterface->SetContainerOpen(m_entityMap[StreetEntityName], true);
|
||||
EXPECT_FALSE(outcome.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_SetContainerOpen)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntitySetContainerOpen)
|
||||
{
|
||||
// Set a container entity to open, and verify the operation was successful.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
@@ -100,7 +100,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_SetContainerOpenTwice)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntitySetContainerOpenTwice)
|
||||
{
|
||||
// Set a container entity to open twice, and verify that does not cause a failure (as intended).
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
@@ -112,7 +112,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_SetContainerClosed)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntitySetContainerClosed)
|
||||
{
|
||||
// Set a container entity to closed, and verify the operation was successful.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
@@ -122,16 +122,16 @@ namespace AzToolsFramework
|
||||
// Restore default state for other tests.
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_IsContainerOpenOnRegularEntity)
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityIsContainerOpenOnRegularEntity)
|
||||
{
|
||||
// Query open state on a regular entity, and verify it returns true.
|
||||
// Open containers behave exactly as regular entities, so this is the expected return value.
|
||||
bool isOpen = m_containerEntityInterface->IsContainerOpen(m_entityMap[CityEntityName]);
|
||||
EXPECT_TRUE(isOpen);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_IsContainerOpenOnDefaultContainerEntity)
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityIsContainerOpenOnDefaultContainerEntity)
|
||||
{
|
||||
// Query open state on a newly registered container entity, and verify it returns false.
|
||||
// Containers are registered closed by default.
|
||||
@@ -142,8 +142,8 @@ namespace AzToolsFramework
|
||||
// Restore default state for other tests.
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_IsContainerOpenOnOpenContainerEntity)
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityIsContainerOpenOnOpenContainerEntity)
|
||||
{
|
||||
// Query open state on a container entity that was opened, and verify it returns true.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
@@ -154,8 +154,8 @@ namespace AzToolsFramework
|
||||
// Restore default state for other tests.
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_IsContainerOpenOnClosedContainerEntity)
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityIsContainerOpenOnClosedContainerEntity)
|
||||
{
|
||||
// Query open state on a container entity that was opened and then closed, and verify it returns false.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
@@ -167,8 +167,8 @@ namespace AzToolsFramework
|
||||
// Restore default state for other tests.
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_ContainerOpenStateIsPreserved)
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityContainerOpenStateIsPreserved)
|
||||
{
|
||||
// Register an entity as container, open it, then unregister it.
|
||||
// When the entity is registered again, the open state should be preserved.
|
||||
@@ -184,15 +184,15 @@ namespace AzToolsFramework
|
||||
// Restore default state for other tests.
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[CityEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_ClearSucceeds)
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityClearSucceeds)
|
||||
{
|
||||
// The Clear function works if no container is registered.
|
||||
auto outcome = m_containerEntityInterface->Clear(m_editorEntityContextId);
|
||||
EXPECT_TRUE(outcome.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_ClearFailsIfContainersAreStillRegistered)
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityClearFailsIfContainersAreStillRegistered)
|
||||
{
|
||||
// The Clear function fails if a container is registered.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[Passenger1EntityName]);
|
||||
@@ -202,8 +202,8 @@ namespace AzToolsFramework
|
||||
// Restore default state for other tests.
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[Passenger1EntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_ClearSucceedsIfContainersAreUnregistered)
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityClearSucceedsIfContainersAreUnregistered)
|
||||
{
|
||||
// The Clear function fails if a container is registered.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[Passenger1EntityName]);
|
||||
@@ -212,7 +212,7 @@ namespace AzToolsFramework
|
||||
EXPECT_TRUE(outcome.IsSuccess());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_ClearDeletesPreservedOpenStates)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityClearDeletesPreservedOpenStates)
|
||||
{
|
||||
// Register an entity as container, open it, unregister it, then call clear.
|
||||
// When the entity is registered again, the open state should not be preserved.
|
||||
@@ -230,14 +230,14 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[Passenger1EntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_FindHighestSelectableEntityWithNoContainers)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityFindHighestSelectableEntityWithNoContainers)
|
||||
{
|
||||
// When no containers are in the way, the function will just return the entityId that was passed to it.
|
||||
AZ::EntityId selectedEntityId = m_containerEntityInterface->FindHighestSelectableEntity(m_entityMap[Passenger2EntityName]);
|
||||
EXPECT_EQ(selectedEntityId, m_entityMap[Passenger2EntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_FindHighestSelectableEntityWithClosedContainer)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityFindHighestSelectableEntityWithClosedContainer)
|
||||
{
|
||||
// If a closed container is an ancestor of the queried entity, the closed container is selected.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[SportsCarEntityName]); // Containers are closed by default
|
||||
@@ -248,7 +248,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[SportsCarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_FindHighestSelectableEntityWithOpenContainer)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityFindHighestSelectableEntityWithOpenContainer)
|
||||
{
|
||||
// If an open container is an ancestor of the queried entity, it is ignored.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[SportsCarEntityName]);
|
||||
@@ -261,7 +261,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[SportsCarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_FindHighestSelectableEntityWithMultipleClosedContainers)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityFindHighestSelectableEntityWithMultipleClosedContainers)
|
||||
{
|
||||
// If multiple closed containers are ancestors of the queried entity, the highest closed container is selected.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
@@ -275,7 +275,7 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[SportsCarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityTests_FindHighestSelectableEntityWithMultipleContainers)
|
||||
TEST_F(EditorFocusModeFixture, ContainerEntityFindHighestSelectableEntityWithMultipleContainers)
|
||||
{
|
||||
// If multiple containers are ancestors of the queried entity, the highest closed container is selected.
|
||||
m_containerEntityInterface->RegisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
@@ -289,5 +289,4 @@ namespace AzToolsFramework
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[StreetEntityName]);
|
||||
m_containerEntityInterface->UnregisterEntityAsContainer(m_entityMap[SportsCarEntityName]);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <Tests/BoundsTestComponent.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
namespace UnitTest
|
||||
{
|
||||
void ClearSelectedEntities()
|
||||
{
|
||||
@@ -31,14 +31,14 @@ namespace AzToolsFramework
|
||||
void EditorFocusModeFixture::SetUpEditorFixtureImpl()
|
||||
{
|
||||
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
// in the unit tests.
|
||||
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
|
||||
|
||||
m_containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
|
||||
m_containerEntityInterface = AZ::Interface<AzToolsFramework::ContainerEntityInterface>::Get();
|
||||
ASSERT_TRUE(m_containerEntityInterface != nullptr);
|
||||
|
||||
m_focusModeInterface = AZ::Interface<FocusModeInterface>::Get();
|
||||
m_focusModeInterface = AZ::Interface<AzToolsFramework::FocusModeInterface>::Get();
|
||||
ASSERT_TRUE(m_focusModeInterface != nullptr);
|
||||
|
||||
// register a simple component implementing BoundsRequestBus and EditorComponentSelectionRequestsBus
|
||||
@@ -68,26 +68,26 @@ namespace AzToolsFramework
|
||||
ClearSelectedEntities();
|
||||
}
|
||||
|
||||
void EditorFocusModeFixture::GenerateTestHierarchy()
|
||||
void EditorFocusModeFixture::GenerateTestHierarchy()
|
||||
{
|
||||
/*
|
||||
* City
|
||||
* |_ Street
|
||||
* |_ Car
|
||||
* | |_ Passenger
|
||||
* |_ SportsCar
|
||||
* |_ Passenger
|
||||
*/
|
||||
* City
|
||||
* |_ Street
|
||||
* |_ Car
|
||||
* | |_ Passenger
|
||||
* |_ SportsCar
|
||||
* |_ Passenger
|
||||
*/
|
||||
|
||||
m_entityMap[CityEntityName] = CreateEditorEntity(CityEntityName, AZ::EntityId());
|
||||
m_entityMap[StreetEntityName] = CreateEditorEntity(StreetEntityName, m_entityMap[CityEntityName]);
|
||||
m_entityMap[CarEntityName] = CreateEditorEntity(CarEntityName, m_entityMap[StreetEntityName]);
|
||||
m_entityMap[Passenger1EntityName] = CreateEditorEntity(Passenger1EntityName, m_entityMap[CarEntityName]);
|
||||
m_entityMap[SportsCarEntityName] = CreateEditorEntity(SportsCarEntityName, m_entityMap[StreetEntityName]);
|
||||
m_entityMap[Passenger2EntityName] = CreateEditorEntity(Passenger2EntityName, m_entityMap[SportsCarEntityName]);
|
||||
m_entityMap[CityEntityName] = CreateEditorEntity(CityEntityName, AZ::EntityId());
|
||||
m_entityMap[StreetEntityName] = CreateEditorEntity(StreetEntityName, m_entityMap[CityEntityName]);
|
||||
m_entityMap[CarEntityName] = CreateEditorEntity(CarEntityName, m_entityMap[StreetEntityName]);
|
||||
m_entityMap[Passenger1EntityName] = CreateEditorEntity(Passenger1EntityName, m_entityMap[CarEntityName]);
|
||||
m_entityMap[SportsCarEntityName] = CreateEditorEntity(SportsCarEntityName, m_entityMap[StreetEntityName]);
|
||||
m_entityMap[Passenger2EntityName] = CreateEditorEntity(Passenger2EntityName, m_entityMap[SportsCarEntityName]);
|
||||
|
||||
// Add a BoundsTestComponent to the Car entity.
|
||||
AZ::Entity* entity = GetEntityById(m_entityMap[CarEntityName]);
|
||||
AZ::Entity* entity = AzToolsFramework::GetEntityById(m_entityMap[CarEntityName]);
|
||||
|
||||
entity->Deactivate();
|
||||
entity->CreateComponent<UnitTest::BoundsTestComponent>();
|
||||
@@ -113,4 +113,4 @@ namespace AzToolsFramework
|
||||
|
||||
return entity->GetId();
|
||||
}
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
namespace UnitTest
|
||||
{
|
||||
class EditorFocusModeFixture
|
||||
: public UnitTest::ToolsApplicationFixture
|
||||
class EditorFocusModeFixture : public ToolsApplicationFixture
|
||||
{
|
||||
protected:
|
||||
void SetUpEditorFixtureImpl() override;
|
||||
@@ -32,8 +31,8 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::unordered_map<AZStd::string, AZ::EntityId> m_entityMap;
|
||||
|
||||
ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
AzToolsFramework::ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
AzToolsFramework::FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
|
||||
public:
|
||||
AzToolsFramework::EntityIdList GetSelectedEntities();
|
||||
@@ -53,4 +52,4 @@ namespace AzToolsFramework
|
||||
inline static AZ::Vector3 WorldCarEntityPosition = AZ::Vector3(5.0f, 15.0f, 0.0f);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -26,11 +26,17 @@
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
namespace UnitTest
|
||||
{
|
||||
class EditorFocusModeSelectionFixture : public UnitTest::IndirectCallManipulatorViewportInteractionFixtureMixin<EditorFocusModeFixture>
|
||||
class EditorFocusModeSelectionFixture : public IndirectCallManipulatorViewportInteractionFixtureMixin<EditorFocusModeFixture>
|
||||
{
|
||||
public:
|
||||
void SetUpEditorFixtureImpl() override
|
||||
{
|
||||
IndirectCallManipulatorViewportInteractionFixtureMixin<EditorFocusModeFixture>::SetUpEditorFixtureImpl();
|
||||
m_viewportManipulatorInteraction->GetViewportInteraction().SetIconsVisible(false);
|
||||
}
|
||||
|
||||
void ClickAtWorldPositionOnViewport(const AZ::Vector3& worldPosition)
|
||||
{
|
||||
// Calculate the world position in screen space
|
||||
@@ -40,4 +46,4 @@ namespace AzToolsFramework
|
||||
m_actionDispatcher->CameraState(m_cameraState)->MousePosition(carScreenPosition)->MouseLButtonDown()->MouseLButtonUp();
|
||||
}
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#include <Tests/FocusMode/EditorFocusModeSelectionFixture.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
namespace UnitTest
|
||||
{
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionTests_SelectEntityWithFocusOnLevel)
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionSelectEntityWithFocusOnLevel)
|
||||
{
|
||||
// Click on Car Entity
|
||||
ClickAtWorldPositionOnViewport(WorldCarEntityPosition);
|
||||
@@ -21,7 +21,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(selectedEntitiesAfter.front(), m_entityMap[CarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionTests_SelectEntityWithFocusOnAncestor)
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionSelectEntityWithFocusOnAncestor)
|
||||
{
|
||||
// Set the focus on the Street Entity (parent of the test entity)
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[StreetEntityName]);
|
||||
@@ -35,7 +35,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(selectedEntitiesAfter.front(), m_entityMap[CarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionTests_SelectEntityWithFocusOnItself)
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionSelectEntityWithFocusOnItself)
|
||||
{
|
||||
// Set the focus on the Car Entity (test entity)
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[CarEntityName]);
|
||||
@@ -49,7 +49,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(selectedEntitiesAfter.front(), m_entityMap[CarEntityName]);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionTests_SelectEntityWithFocusOnSibling)
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionSelectEntityWithFocusOnSibling)
|
||||
{
|
||||
// Set the focus on the SportsCar Entity (sibling of the test entity)
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[SportsCarEntityName]);
|
||||
@@ -62,7 +62,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(selectedEntitiesAfter.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionTests_SelectEntityWithFocusOnDescendant)
|
||||
TEST_F(EditorFocusModeSelectionFixture, EditorFocusModeSelectionSelectEntityWithFocusOnDescendant)
|
||||
{
|
||||
// Set the focus on the Passenger1 Entity (child of the entity)
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[Passenger1EntityName]);
|
||||
@@ -74,4 +74,4 @@ namespace AzToolsFramework
|
||||
auto selectedEntitiesAfter = GetSelectedEntities();
|
||||
EXPECT_EQ(selectedEntitiesAfter.size(), 0);
|
||||
}
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#include <Tests/FocusMode/EditorFocusModeFixture.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
namespace UnitTest
|
||||
{
|
||||
TEST_F(EditorFocusModeFixture, EditorFocusModeTests_SetFocus)
|
||||
TEST_F(EditorFocusModeFixture, SetFocus)
|
||||
{
|
||||
// When an entity is set as the focus root, GetFocusRoot should return its EntityId.
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[CarEntityName]);
|
||||
@@ -20,7 +20,7 @@ namespace AzToolsFramework
|
||||
m_focusModeInterface->ClearFocusRoot(m_editorEntityContextId);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, EditorFocusModeTests_ClearFocus)
|
||||
TEST_F(EditorFocusModeFixture, ClearFocus)
|
||||
{
|
||||
// Change the value from the default.
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[CarEntityName]);
|
||||
@@ -30,7 +30,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(m_focusModeInterface->GetFocusRoot(m_editorEntityContextId), AZ::EntityId());
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, EditorFocusModeTests_IsInFocusSubTree_AncestorsDescendants)
|
||||
TEST_F(EditorFocusModeFixture, IsInFocusSubTreeAncestorsDescendants)
|
||||
{
|
||||
// When the focus is set to an entity, all its descendants are in the focus subtree while the ancestors aren't.
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[StreetEntityName]);
|
||||
@@ -43,7 +43,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(m_focusModeInterface->IsInFocusSubTree(m_entityMap[Passenger2EntityName]), true);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, EditorFocusModeTests_IsInFocusSubTree_Siblings)
|
||||
TEST_F(EditorFocusModeFixture, IsInFocusSubTreeSiblings)
|
||||
{
|
||||
// If the root entity has siblings, they are also outside of the focus subtree.
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[CarEntityName]);
|
||||
@@ -56,7 +56,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(m_focusModeInterface->IsInFocusSubTree(m_entityMap[Passenger2EntityName]), false);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, EditorFocusModeTests_IsInFocusSubTree_Leaf)
|
||||
TEST_F(EditorFocusModeFixture, IsInFocusSubTreeLeaf)
|
||||
{
|
||||
// If the root is a leaf, then the focus subtree will consists of just that entity.
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[Passenger2EntityName]);
|
||||
@@ -69,7 +69,7 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(m_focusModeInterface->IsInFocusSubTree(m_entityMap[Passenger2EntityName]), true);
|
||||
}
|
||||
|
||||
TEST_F(EditorFocusModeFixture, EditorFocusModeTests_IsInFocusSubTree_Clear)
|
||||
TEST_F(EditorFocusModeFixture, IsInFocusSubTreeClear)
|
||||
{
|
||||
// Change the value from the default.
|
||||
m_focusModeInterface->SetFocusRoot(m_entityMap[StreetEntityName]);
|
||||
@@ -84,4 +84,4 @@ namespace AzToolsFramework
|
||||
EXPECT_EQ(m_focusModeInterface->IsInFocusSubTree(m_entityMap[SportsCarEntityName]), true);
|
||||
EXPECT_EQ(m_focusModeInterface->IsInFocusSubTree(m_entityMap[Passenger2EntityName]), true);
|
||||
}
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
-1
@@ -137,7 +137,6 @@ namespace UnitTest
|
||||
void CreateEditorRepresentation(AZ::Entity* entity) override;
|
||||
void BrowseForAssets(AzToolsFramework::AssetBrowser::AssetSelectionModel& selection) override { AZ_UNUSED(selection); }
|
||||
int GetIconTextureIdFromEntityIconPath(const AZStd::string& entityIconPath) override { AZ_UNUSED(entityIconPath); return 0; }
|
||||
bool DisplayHelpersVisible() override { return false; }
|
||||
|
||||
/*
|
||||
* AssetSystemRequestBus
|
||||
|
||||
@@ -243,7 +243,6 @@ namespace UnitTest
|
||||
// These are required by implementing the EditorRequestBus
|
||||
void BrowseForAssets(AssetBrowser::AssetSelectionModel& /*selection*/) override {}
|
||||
int GetIconTextureIdFromEntityIconPath([[maybe_unused]] const AZStd::string& entityIconPath) override { return 0; }
|
||||
bool DisplayHelpersVisible() override { return false; }
|
||||
|
||||
public:
|
||||
EntityPropertyEditor* m_levelEditor;
|
||||
|
||||
@@ -610,7 +610,7 @@ namespace LUAEditor
|
||||
{
|
||||
m_resultList[qAssetName].m_assetId = docInfo.m_assetId;
|
||||
}
|
||||
entry.m_lineNumber = line;
|
||||
entry.m_lineNumber = line + 1;
|
||||
entry.m_lineText = entry.m_lineText.trimmed();
|
||||
|
||||
while (index > -1)
|
||||
|
||||
@@ -28,6 +28,12 @@ namespace AZ
|
||||
{
|
||||
int boneId;
|
||||
float weight;
|
||||
|
||||
bool IsClose(const Link& other, float tolerance) const
|
||||
{
|
||||
return boneId == other.boneId &&
|
||||
AZ::IsClose(weight, other.weight, tolerance);
|
||||
}
|
||||
};
|
||||
|
||||
virtual ~ISkinWeightData() override = default;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"UUID": "{5D9ECB52-4CD9-4CB8-80E3-10CAE5EFB8A2}",
|
||||
"Name": "AlbedoWithGenericAlpha",
|
||||
"RGB_Weight": "CIEXYZ",
|
||||
"PixelFormat": "ASTC_4x4",
|
||||
"PixelFormat": "BC3",
|
||||
"MipMapSetting": {
|
||||
"MipGenType": "Box"
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ namespace ImageProcessingAtom
|
||||
};
|
||||
|
||||
bool IsASTCFormat(EPixelFormat fmt);
|
||||
bool IsHDRFormat(EPixelFormat fmt);
|
||||
} // namespace ImageProcessingAtom
|
||||
|
||||
namespace AZ
|
||||
|
||||
+12
-2
@@ -620,6 +620,7 @@ namespace ImageProcessingAtom
|
||||
{
|
||||
PresetName emptyPreset;
|
||||
|
||||
|
||||
//get file mask of this image file
|
||||
AZStd::string fileMask = GetFileMask(imageFilePath);
|
||||
|
||||
@@ -636,8 +637,17 @@ namespace ImageProcessingAtom
|
||||
}
|
||||
|
||||
if (outPreset == emptyPreset)
|
||||
{
|
||||
outPreset = m_defaultPreset;
|
||||
{
|
||||
auto image = IImageObjectPtr(LoadImageFromFile(imageFilePath));
|
||||
if (image->GetAlphaContent() == EAlphaContent::eAlphaContent_Absent
|
||||
|| image->GetAlphaContent() == EAlphaContent::eAlphaContent_OnlyWhite)
|
||||
{
|
||||
outPreset = m_defaultPreset;
|
||||
}
|
||||
else
|
||||
{
|
||||
outPreset = m_defaultPresetAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
return outPreset;
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace ImageProcessingAtom
|
||||
return true;
|
||||
}
|
||||
|
||||
astcenc_profile GetAstcProfile(bool isSrgb, EPixelFormat pixelFormat)
|
||||
astcenc_profile GetAstcProfile(bool isSrgb, bool isHDR)
|
||||
{
|
||||
// select profile depends on LDR or HDR, SRGB or Linear
|
||||
// ASTCENC_PRF_LDR
|
||||
@@ -86,8 +86,6 @@ namespace ImageProcessingAtom
|
||||
// ASTCENC_PRF_HDR_RGB_LDR_A
|
||||
// ASTCENC_PRF_HDR
|
||||
|
||||
auto formatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormat);
|
||||
bool isHDR = formatInfo->eSampleType == ESampleType::eSampleType_Half || formatInfo->eSampleType == ESampleType::eSampleType_Float;
|
||||
astcenc_profile profile;
|
||||
if (isHDR)
|
||||
{
|
||||
@@ -170,7 +168,7 @@ namespace ImageProcessingAtom
|
||||
auto dstFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtDst);
|
||||
|
||||
const float quality = GetAstcCompressQuality(compressOption->compressQuality);
|
||||
const astcenc_profile profile = GetAstcProfile(srcImage->HasImageFlags(EIF_SRGBRead), fmtSrc);
|
||||
const astcenc_profile profile = GetAstcProfile(srcImage->HasImageFlags(EIF_SRGBRead), srcImage->HasImageFlags(EIF_HDR));
|
||||
|
||||
astcenc_config config;
|
||||
astcenc_error status;
|
||||
@@ -182,10 +180,12 @@ namespace ImageProcessingAtom
|
||||
// Create a context based on the configuration
|
||||
astcenc_context* context;
|
||||
AZ::u32 blockCount = ((srcImage->GetWidth(0)+ dstFormatInfo->blockWidth-1)/dstFormatInfo->blockWidth) * ((srcImage->GetHeight(0) + dstFormatInfo->blockHeight-1)/dstFormatInfo->blockHeight);
|
||||
AZ::u32 threadCount = AZStd::min(AZStd::thread::hardware_concurrency(), blockCount);
|
||||
AZ::u32 threadCount = AZStd::min(AZStd::thread::hardware_concurrency()/2, blockCount);
|
||||
status = astcenc_context_alloc(&config, threadCount, &context);
|
||||
AZ_Assert( status == ASTCENC_SUCCESS, "ERROR: Codec context alloc failed: %s\n", astcenc_get_error_string(status));
|
||||
|
||||
AZ::Job* currentJob = AZ::JobContext::GetGlobalContext()->GetJobManager().GetCurrentJob();
|
||||
|
||||
const astcenc_type dataType =GetAstcDataType(fmtSrc);
|
||||
|
||||
// Compress the image for each mips
|
||||
@@ -209,29 +209,65 @@ namespace ImageProcessingAtom
|
||||
dstImage->GetImagePointer(mip, dstMem, dstPitch);
|
||||
AZ::u32 dataSize = dstImage->GetMipBufSize(mip);
|
||||
|
||||
// Create jobs for each compression thread
|
||||
auto completionJob = aznew AZ::JobCompletion();
|
||||
for (AZ::u32 threadIdx = 0; threadIdx < threadCount; threadIdx++)
|
||||
if (threadCount == 1)
|
||||
{
|
||||
const auto jobLambda = [&status, context, &image, &swizzle, dstMem, dataSize, threadIdx]()
|
||||
astcenc_error error = astcenc_compress_image(context, &image, &swizzle, dstMem, dataSize, 0);
|
||||
if (error != ASTCENC_SUCCESS)
|
||||
{
|
||||
status = error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::JobCompletion* completionJob = nullptr;
|
||||
if (!currentJob)
|
||||
{
|
||||
completionJob = aznew AZ::JobCompletion();
|
||||
}
|
||||
// Create jobs for each compression thread
|
||||
for (AZ::u32 threadIdx = 0; threadIdx < threadCount; threadIdx++)
|
||||
{
|
||||
const auto jobLambda = [&status, context, &image, &swizzle, dstMem, dataSize, threadIdx]()
|
||||
{
|
||||
astcenc_error error = astcenc_compress_image(context, &image, &swizzle, dstMem, dataSize, threadIdx);
|
||||
if (error != ASTCENC_SUCCESS)
|
||||
{
|
||||
status = error;
|
||||
}
|
||||
};
|
||||
|
||||
AZ::Job* simulationJob = AZ::CreateJobFunction(AZStd::move(jobLambda), true, nullptr); //auto-deletes
|
||||
|
||||
// adds this job as child to current job if there is a current job
|
||||
// otherwise adds it as a dependent for the complete job
|
||||
if (currentJob)
|
||||
{
|
||||
currentJob->StartAsChild(simulationJob);
|
||||
}
|
||||
else
|
||||
{
|
||||
simulationJob->SetDependent(completionJob);
|
||||
simulationJob->Start();
|
||||
}
|
||||
|
||||
astcenc_error error = astcenc_compress_image(context, &image, &swizzle, dstMem, dataSize, threadIdx);
|
||||
if (error != ASTCENC_SUCCESS)
|
||||
{
|
||||
status = error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (currentJob)
|
||||
{
|
||||
currentJob->WaitForChildren();
|
||||
}
|
||||
|
||||
AZ::Job* simulationJob = AZ::CreateJobFunction(AZStd::move(jobLambda), true, nullptr); //auto-deletes
|
||||
simulationJob->SetDependent(completionJob);
|
||||
simulationJob->Start();
|
||||
}
|
||||
|
||||
if (completionJob)
|
||||
{
|
||||
completionJob->StartAndWaitForCompletion();
|
||||
delete completionJob;
|
||||
completionJob = nullptr;
|
||||
if (completionJob)
|
||||
{
|
||||
completionJob->StartAndWaitForCompletion();
|
||||
delete completionJob;
|
||||
completionJob = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (status != ASTCENC_SUCCESS)
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace ImageProcessingAtom
|
||||
builderDescriptor.m_busId = azrtti_typeid<ImageBuilderWorker>();
|
||||
builderDescriptor.m_createJobFunction = AZStd::bind(&ImageBuilderWorker::CreateJobs, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
builderDescriptor.m_processJobFunction = AZStd::bind(&ImageBuilderWorker::ProcessJob, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
|
||||
builderDescriptor.m_version = 26; // [ATOM-15086]
|
||||
builderDescriptor.m_version = 27; // [ATOM-16958]
|
||||
builderDescriptor.m_analysisFingerprint = ImageProcessingAtom::BuilderSettingManager::Instance()->GetAnalysisFingerprint();
|
||||
m_imageBuilder.BusConnect(builderDescriptor.m_busId);
|
||||
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor);
|
||||
@@ -221,18 +221,19 @@ namespace ImageProcessingAtom
|
||||
m_isShuttingDown = true;
|
||||
}
|
||||
|
||||
PresetName GetImagePreset(const AZStd::string& filepath)
|
||||
PresetName GetImagePreset(const AZStd::string& imageFileFullPath)
|
||||
{
|
||||
// first let preset from asset info
|
||||
TextureSettings textureSettings;
|
||||
StringOutcome output = TextureSettings::LoadTextureSetting(filepath, textureSettings);
|
||||
AZStd::string settingFilePath = imageFileFullPath + TextureSettings::ExtensionName;
|
||||
TextureSettings::LoadTextureSetting(settingFilePath, textureSettings);
|
||||
|
||||
if (!textureSettings.m_preset.IsEmpty())
|
||||
{
|
||||
return textureSettings.m_preset;
|
||||
}
|
||||
|
||||
return BuilderSettingManager::Instance()->GetSuggestedPreset(filepath);
|
||||
return BuilderSettingManager::Instance()->GetSuggestedPreset(imageFileFullPath);
|
||||
}
|
||||
|
||||
void HandlePresetDependency(PresetName presetName, AZStd::vector<AssetBuilderSDK::SourceFileDependency>& sourceDependencyList)
|
||||
@@ -283,6 +284,10 @@ namespace ImageProcessingAtom
|
||||
return;
|
||||
}
|
||||
|
||||
// Full path of the image file
|
||||
AZStd::string fullPath;
|
||||
AzFramework::StringFunc::Path::Join(request.m_watchFolder.data(), request.m_sourceFile.data(), fullPath, true, true);
|
||||
|
||||
// Get the extension of the file
|
||||
AZStd::string ext;
|
||||
AzFramework::StringFunc::Path::GetExtension(request.m_sourceFile.c_str(), ext, false);
|
||||
@@ -305,13 +310,12 @@ namespace ImageProcessingAtom
|
||||
// add source dependency for .assetinfo file
|
||||
AssetBuilderSDK::SourceFileDependency sourceFileDependency;
|
||||
sourceFileDependency.m_sourceDependencyType = AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Absolute;
|
||||
sourceFileDependency.m_sourceFileDependencyPath = request.m_sourceFile;
|
||||
AZ::StringFunc::Path::ReplaceExtension(sourceFileDependency.m_sourceFileDependencyPath, TextureSettings::ExtensionName);
|
||||
sourceFileDependency.m_sourceFileDependencyPath = fullPath + TextureSettings::ExtensionName;
|
||||
response.m_sourceFileDependencyList.push_back(sourceFileDependency);
|
||||
|
||||
// add source dependencies for .preset files
|
||||
// Get the preset for this file
|
||||
auto presetName = GetImagePreset(request.m_sourceFile);
|
||||
// Get the preset for this file
|
||||
auto presetName = GetImagePreset(fullPath.c_str());
|
||||
HandlePresetDependency(presetName, response.m_sourceFileDependencyList);
|
||||
|
||||
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <ImageLoader/ImageLoaders.h>
|
||||
#include <Processing/ImageFlags.h>
|
||||
#include <Atom/ImageProcessing/ImageObject.h>
|
||||
// warning C4251: class QT_Type needs to have dll-interface to be used by clients of class 'QT_Type'
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option")
|
||||
@@ -26,21 +27,31 @@ namespace ImageProcessingAtom
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IImageObject* loadedImage = nullptr;
|
||||
if (TIFFLoader::IsExtensionSupported(ext.toUtf8()))
|
||||
{
|
||||
return TIFFLoader::LoadImageFromTIFF(filename);
|
||||
loadedImage = TIFFLoader::LoadImageFromTIFF(filename);
|
||||
}
|
||||
else if (DdsLoader::IsExtensionSupported(ext.toUtf8()))
|
||||
{
|
||||
return DdsLoader::LoadImageFromFile(filename);
|
||||
loadedImage = DdsLoader::LoadImageFromFile(filename);
|
||||
}
|
||||
else if (QtImageLoader::IsExtensionSupported(ext.toUtf8()))
|
||||
{
|
||||
return QtImageLoader::LoadImageFromFile(filename);
|
||||
loadedImage = QtImageLoader::LoadImageFromFile(filename);
|
||||
}
|
||||
else if (ExrLoader::IsExtensionSupported(ext.toUtf8()))
|
||||
{
|
||||
return ExrLoader::LoadImageFromFile(filename);
|
||||
loadedImage = ExrLoader::LoadImageFromFile(filename);
|
||||
}
|
||||
|
||||
if (loadedImage)
|
||||
{
|
||||
if (IsHDRFormat(loadedImage->GetPixelFormat()))
|
||||
{
|
||||
loadedImage->AddImageFlags(EIF_HDR);
|
||||
}
|
||||
return loadedImage;
|
||||
}
|
||||
|
||||
AZ_Warning("ImageProcessing", false, "No proper image loader to load file: %s", filename.c_str());
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace ImageProcessingAtom
|
||||
}
|
||||
|
||||
m_image->Get()->Swizzle(swizzle.c_str());
|
||||
if (!m_input->m_presetSetting.m_discardAlpha)
|
||||
if (m_input->m_presetSetting.m_discardAlpha)
|
||||
{
|
||||
m_alphaContent = EAlphaContent::eAlphaContent_Absent;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ImageProcessingAtom
|
||||
const static AZ::u32 EIF_Decal = 0x4; // this is usually set through the preset
|
||||
const static AZ::u32 EIF_Greyscale = 0x8; // hint for the engine (e.g. greyscale light beams can be applied to shadow mask), can be for DXT1 because compression artfacts don't count as color
|
||||
const static AZ::u32 EIF_SupressEngineReduce = 0x10; // info for the engine: don't reduce texture resolution on this texture
|
||||
const static AZ::u32 EIF_UNUSED_BIT = 0x40; // Free to use
|
||||
const static AZ::u32 EIF_HDR = 0x40; // the image contains HDR data
|
||||
const static AZ::u32 EIF_AttachedAlpha = 0x400; // deprecated: info for the engine: it's a texture with attached alpha channel
|
||||
const static AZ::u32 EIF_SRGBRead = 0x800; // info for the engine: if gamma corrected rendering is on, this texture requires SRGBRead (it's not stored in linear)
|
||||
const static AZ::u32 EIF_DontResize = 0x8000; // info for the engine: for dds textures that shouldn't be resized
|
||||
|
||||
@@ -52,6 +52,24 @@ namespace ImageProcessingAtom
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsHDRFormat(EPixelFormat fmt)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case ePixelFormat_BC6UH:
|
||||
case ePixelFormat_R9G9B9E5:
|
||||
case ePixelFormat_R32G32B32A32F:
|
||||
case ePixelFormat_R32G32F:
|
||||
case ePixelFormat_R32F:
|
||||
case ePixelFormat_R16G16B16A16F:
|
||||
case ePixelFormat_R16G16F:
|
||||
case ePixelFormat_R16F:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PixelFormatInfo::PixelFormatInfo(
|
||||
uint32_t a_bitsPerPixel,
|
||||
uint32_t a_Channels,
|
||||
|
||||
@@ -25,7 +25,12 @@
|
||||
{
|
||||
"Name": "DepthStencilInput",
|
||||
"SlotType": "Input",
|
||||
"ScopeAttachmentUsage": "DepthStencil"
|
||||
"ScopeAttachmentUsage": "DepthStencil",
|
||||
"ImageViewDesc": {
|
||||
"AspectFlags": [
|
||||
"Depth"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "Output",
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
"PassData": {
|
||||
"$type": "RasterPassData",
|
||||
"DrawListTag": "2dpass",
|
||||
"PipelineViewTag": "MainCamera"
|
||||
"PipelineViewTag": "MainCamera",
|
||||
"DrawListSortType": "KeyThenReverseDepth"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+6
-7
@@ -150,18 +150,17 @@ namespace AZ
|
||||
}
|
||||
|
||||
// build newly added BLAS objects
|
||||
// [GFX TODO][ATOM-14159] Add changelist for meshes in the RayTracingFeatureProcessor
|
||||
RayTracingFeatureProcessor::MeshMap& rayTracingMeshes = rayTracingFeatureProcessor->GetMeshes();
|
||||
for (auto& rayTracingMesh : rayTracingMeshes)
|
||||
RayTracingFeatureProcessor::BlasInstanceMap& blasInstances = rayTracingFeatureProcessor->GetBlasInstances();
|
||||
for (auto& blasInstance : blasInstances)
|
||||
{
|
||||
if (rayTracingMesh.second.m_blasBuilt == false)
|
||||
if (blasInstance.second.m_blasBuilt == false)
|
||||
{
|
||||
for (auto& rayTracingSubMesh : rayTracingMesh.second.m_subMeshes)
|
||||
for (auto& blasInstanceSubMesh : blasInstance.second.m_subMeshes)
|
||||
{
|
||||
context.GetCommandList()->BuildBottomLevelAccelerationStructure(*rayTracingSubMesh.m_blas);
|
||||
context.GetCommandList()->BuildBottomLevelAccelerationStructure(*blasInstanceSubMesh.m_blas);
|
||||
}
|
||||
|
||||
rayTracingMesh.second.m_blasBuilt = true;
|
||||
blasInstance.second.m_blasBuilt = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,23 +149,18 @@ namespace AZ
|
||||
{
|
||||
AZ_Assert(blasInstanceFound == false, "Partial set of RayTracingBlas objects found for mesh");
|
||||
|
||||
// create the BLAS object
|
||||
subMesh.m_blas = AZ::RHI::RayTracingBlas::CreateRHIRayTracingBlas();
|
||||
// create the BLAS object and store it in the BLAS list
|
||||
RHI::Ptr<RHI::RayTracingBlas> rayTracingBlas = AZ::RHI::RayTracingBlas::CreateRHIRayTracingBlas();
|
||||
itMeshBlasInstance->second.m_subMeshes.push_back({ rayTracingBlas });
|
||||
|
||||
// create the buffers from the descriptor
|
||||
subMesh.m_blas->CreateBuffers(*device, &blasDescriptor, *m_bufferPools);
|
||||
// create the buffers from the BLAS descriptor
|
||||
rayTracingBlas->CreateBuffers(*device, &blasDescriptor, *m_bufferPools);
|
||||
|
||||
// store the BLAS in the side list
|
||||
itMeshBlasInstance->second.m_subMeshes.push_back({ subMesh.m_blas });
|
||||
// store the BLAS in the mesh
|
||||
subMesh.m_blas = rayTracingBlas;
|
||||
}
|
||||
}
|
||||
|
||||
if (blasInstanceFound)
|
||||
{
|
||||
// set the mesh BLAS flag so we don't try to rebuild it in the RayTracingAccelerationStructurePass
|
||||
mesh.m_blasBuilt = true;
|
||||
}
|
||||
|
||||
// set initial transform
|
||||
mesh.m_transform = m_transformServiceFeatureProcessor->GetTransformForId(objectId);
|
||||
mesh.m_nonUniformScale = m_transformServiceFeatureProcessor->GetNonUniformScaleForId(objectId);
|
||||
|
||||
@@ -127,9 +127,6 @@ namespace AZ
|
||||
|
||||
// mesh non-uniform scale
|
||||
AZ::Vector3 m_nonUniformScale = AZ::Vector3::CreateOne();
|
||||
|
||||
// flag indicating if the Blas objects in the sub-meshes are built
|
||||
bool m_blasBuilt = false;
|
||||
};
|
||||
|
||||
using MeshMap = AZStd::map<uint32_t, Mesh>;
|
||||
@@ -184,6 +181,23 @@ namespace AZ
|
||||
//! Updates the RayTracingSceneSrg and RayTracingMaterialSrg, called after the TLAS is allocated in the RayTracingAccelerationStructurePass
|
||||
void UpdateRayTracingSrgs();
|
||||
|
||||
struct SubMeshBlasInstance
|
||||
{
|
||||
RHI::Ptr<RHI::RayTracingBlas> m_blas;
|
||||
};
|
||||
|
||||
struct MeshBlasInstance
|
||||
{
|
||||
uint32_t m_count = 0;
|
||||
AZStd::vector<SubMeshBlasInstance> m_subMeshes;
|
||||
|
||||
// flag indicating if the Blas objects in the sub-mesh list are built
|
||||
bool m_blasBuilt = false;
|
||||
};
|
||||
|
||||
using BlasInstanceMap = AZStd::unordered_map<AZ::Data::AssetId, MeshBlasInstance>;
|
||||
BlasInstanceMap& GetBlasInstances() { return m_blasInstanceMap; }
|
||||
|
||||
private:
|
||||
|
||||
AZ_DISABLE_COPY_MOVE(RayTracingFeatureProcessor);
|
||||
@@ -266,18 +280,6 @@ namespace AZ
|
||||
bool m_materialInfoBufferNeedsUpdate = false;
|
||||
|
||||
// side list for looking up existing BLAS objects so they can be re-used when the same mesh is added multiple times
|
||||
struct SubMeshBlasInstance
|
||||
{
|
||||
RHI::Ptr<RHI::RayTracingBlas> m_blas;
|
||||
};
|
||||
|
||||
struct MeshBlasInstance
|
||||
{
|
||||
uint32_t m_count = 0;
|
||||
AZStd::vector<SubMeshBlasInstance> m_subMeshes;
|
||||
};
|
||||
|
||||
using BlasInstanceMap = AZStd::unordered_map<AZ::Data::AssetId, MeshBlasInstance>;
|
||||
BlasInstanceMap m_blasInstanceMap;
|
||||
|
||||
// Cache view pointers so we dont need to update them if none changed from frame to frame.
|
||||
|
||||
@@ -81,10 +81,10 @@ def start():
|
||||
try:
|
||||
_TAG_LY_BUILD_PATH = os.getenv('TAG_LY_BUILD_PATH', 'build')
|
||||
_DEFAULT_BIN_PATH = Path(str(_O3DE_DEV), _TAG_LY_BUILD_PATH, 'bin', 'profile')
|
||||
_O3DE_BIN_PATH = Path(os.getenv('O3DE_BIN_PATH', _DEFAULT_BIN_PATH))
|
||||
os.environ['O3DE_BIN_PATH'] = _O3DE_BIN_PATH.as_posix()
|
||||
_LOGGER.debug(f'O3DE_BIN_PATH is: {_O3DE_BIN_PATH}')
|
||||
site.addsitedir(_O3DE_BIN_PATH.resolve())
|
||||
_PATH_O3DE_BIN = Path(os.getenv('PATH_O3DE_BIN', _DEFAULT_BIN_PATH))
|
||||
os.environ['PATH_O3DE_BIN'] = _PATH_O3DE_BIN.as_posix()
|
||||
_LOGGER.debug(f'PATH_O3DE_BIN is: {_PATH_O3DE_BIN}')
|
||||
site.addsitedir(_PATH_O3DE_BIN.resolve())
|
||||
except EnvironmentError as e:
|
||||
_LOGGER.error('O3DE bin folder not set or found')
|
||||
raise e
|
||||
@@ -94,10 +94,10 @@ def start():
|
||||
os.environ['O3DE_DEV'] = _O3DE_DEV.as_posix()
|
||||
_LOGGER.debug(_O3DE_DEV)
|
||||
|
||||
_O3DE_BIN_PATH = Path(str(_O3DE_DEV),Path(azlmbr.paths.executableFolder))
|
||||
_PATH_O3DE_BIN = Path(str(_O3DE_DEV),Path(azlmbr.paths.executableFolder))
|
||||
|
||||
_O3DE_BIN = Path(os.getenv('O3DE_BIN', _O3DE_BIN_PATH.resolve()))
|
||||
os.environ['O3DE_BIN'] = _O3DE_BIN_PATH.as_posix()
|
||||
_O3DE_BIN = Path(os.getenv('O3DE_BIN', _PATH_O3DE_BIN.resolve()))
|
||||
os.environ['O3DE_BIN'] = _PATH_O3DE_BIN.as_posix()
|
||||
|
||||
_LOGGER.debug(_O3DE_BIN)
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ namespace AZ
|
||||
{
|
||||
return true;
|
||||
}
|
||||
AZ_PROFILE_FUNCTION(RHI);
|
||||
ValidateViewContext context;
|
||||
context.m_scopeName = m_scope->GetId().GetCStr();
|
||||
context.m_srgName = shaderResourceGroup.GetName().GetCStr();
|
||||
|
||||
@@ -248,8 +248,6 @@ namespace AZ
|
||||
|
||||
void ShaderResourceGroupPool::CompileGroupsForInterval(Interval interval)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(RHI, "CompileGroupsForInterval");
|
||||
|
||||
AZ_Assert(m_isCompiling, "You must call CompileGroupsBegin() first!");
|
||||
AZ_Assert(
|
||||
interval.m_max >= interval.m_min &&
|
||||
@@ -259,6 +257,8 @@ namespace AZ
|
||||
for (uint32_t i = interval.m_min; i < interval.m_max; ++i)
|
||||
{
|
||||
ShaderResourceGroup* group = m_groupsToCompile[i];
|
||||
AZ_PROFILE_SCOPE(RHI, "CompileGroupsForInterval %s", group->GetName().GetCStr());
|
||||
|
||||
CompileGroupInternal(*group, group->GetData());
|
||||
group->m_isQueuedForCompile = false;
|
||||
}
|
||||
|
||||
@@ -390,7 +390,6 @@ namespace AZ
|
||||
}
|
||||
|
||||
const PipelineLayout& pipelineLayout = pipelineState->GetPipelineLayout();
|
||||
const RHI::PipelineLayoutDescriptor& pipelineLayoutDescriptor = pipelineLayout.GetPipelineLayoutDescriptor();
|
||||
|
||||
// Pull from slot bindings dictated by the pipeline layout. Re-bind anything that has changed
|
||||
// at the flat index level.
|
||||
@@ -499,12 +498,15 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (AZ_RHI_ENABLE_VALIDATION)
|
||||
if (updatePipelineState || updateSRG)
|
||||
{
|
||||
const RHI::PipelineLayoutDescriptor& pipelineLayoutDescriptor = pipelineLayout.GetPipelineLayoutDescriptor();
|
||||
m_validator.ValidateShaderResourceGroup(
|
||||
*shaderResourceGroup,
|
||||
pipelineLayoutDescriptor.GetShaderResourceGroupBindingInfo(srgIndex));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -948,19 +948,17 @@ namespace AZ
|
||||
{
|
||||
AZStd::vector<uint16_t>& skinJointIndices = productMesh.m_skinJointIndices;
|
||||
AZStd::vector<float>& skinWeights = productMesh.m_skinWeights;
|
||||
const auto& sourceMeshData = sourceMesh.m_meshData;
|
||||
|
||||
size_t numInfluencesAdded = 0;
|
||||
for (const auto& skinData : sourceMesh.m_skinData)
|
||||
{
|
||||
const AZ::u32 controlPointIndex = sourceMeshData->GetControlPointIndex(static_cast<int>(vertexIndex));
|
||||
const size_t numSkinInfluences = skinData->GetLinkCount(controlPointIndex);
|
||||
const size_t numSkinInfluences = skinData->GetLinkCount(vertexIndex);
|
||||
|
||||
size_t numInfluencesExcess = 0;
|
||||
|
||||
for (size_t influenceIndex = 0; influenceIndex < numSkinInfluences; ++influenceIndex)
|
||||
{
|
||||
const AZ::SceneAPI::DataTypes::ISkinWeightData::Link& link = skinData->GetLink(controlPointIndex, influenceIndex);
|
||||
const AZ::SceneAPI::DataTypes::ISkinWeightData::Link& link = skinData->GetLink(vertexIndex, influenceIndex);
|
||||
|
||||
const float weight = link.weight;
|
||||
const AZStd::string& boneName = skinData->GetBoneName(link.boneId);
|
||||
|
||||
+3
-5
@@ -53,14 +53,12 @@ namespace AtomToolsFramework
|
||||
const AZ::RPI::MaterialTypeSourceData::PropertyDefinition& propertyDefinition,
|
||||
AZ::RPI::MaterialPropertyValue& propertyValue);
|
||||
|
||||
//! Generate a file path from the exported file to the external reference.
|
||||
//! This function returns a relative path from the export file to the reference file.
|
||||
//! If the relative path is too different or distant from the export path then we return the asset folder relative path.
|
||||
//! Generate a file path that is relative to either the source asset root or the export path
|
||||
//! @param exportPath absolute path of the file being saved
|
||||
//! @param referencePath absolute path of a file that will be treated as an external reference
|
||||
//! @param maxPathDepth the maximum relative depth or number of parent or child folders between the export path and the reference path
|
||||
//! @param relativeToExportPath specifies if the path is relative to the source asset root or the export path
|
||||
AZStd::string GetExteralReferencePath(
|
||||
const AZStd::string& exportPath, const AZStd::string& referencePath, const uint32_t maxPathDepth = 2);
|
||||
const AZStd::string& exportPath, const AZStd::string& referencePath, const bool relativeToExportPath = false);
|
||||
|
||||
//! Traverse up the instance data node hierarchy to find the containing dynamic property object
|
||||
const AtomToolsFramework::DynamicProperty* FindDynamicPropertyForInstanceDataNode(const AzToolsFramework::InstanceDataNode* pNode);
|
||||
|
||||
+14
-11
@@ -24,6 +24,7 @@ AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnin
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AtomToolsFramework
|
||||
@@ -121,7 +122,6 @@ namespace AtomToolsFramework
|
||||
|
||||
void AtomToolsDocumentSystemComponent::Deactivate()
|
||||
{
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
AtomToolsDocumentNotificationBus::Handler::BusDisconnect();
|
||||
AtomToolsDocumentSystemRequestBus::Handler::BusDisconnect();
|
||||
m_documentMap.clear();
|
||||
@@ -160,25 +160,30 @@ namespace AtomToolsFramework
|
||||
void AtomToolsDocumentSystemComponent::OnDocumentExternallyModified(const AZ::Uuid& documentId)
|
||||
{
|
||||
m_documentIdsWithExternalChanges.insert(documentId);
|
||||
if (!AZ::TickBus::Handler::BusIsConnected())
|
||||
{
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
}
|
||||
QueueReopenDocuments();
|
||||
}
|
||||
|
||||
void AtomToolsDocumentSystemComponent::OnDocumentDependencyModified(const AZ::Uuid& documentId)
|
||||
{
|
||||
m_documentIdsWithDependencyChanges.insert(documentId);
|
||||
if (!AZ::TickBus::Handler::BusIsConnected())
|
||||
QueueReopenDocuments();
|
||||
}
|
||||
|
||||
void AtomToolsDocumentSystemComponent::QueueReopenDocuments()
|
||||
{
|
||||
if (!m_queueReopenDocuments)
|
||||
{
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
m_queueReopenDocuments = true;
|
||||
QTimer::singleShot(0, [this] { ReopenDocuments(); });
|
||||
}
|
||||
}
|
||||
|
||||
void AtomToolsDocumentSystemComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
|
||||
void AtomToolsDocumentSystemComponent::ReopenDocuments()
|
||||
{
|
||||
for (const AZ::Uuid& documentId : m_documentIdsWithExternalChanges)
|
||||
{
|
||||
m_documentIdsWithDependencyChanges.erase(documentId);
|
||||
|
||||
AZStd::string documentPath;
|
||||
AtomToolsDocumentRequestBus::EventResult(documentPath, documentId, &AtomToolsDocumentRequestBus::Events::GetAbsolutePath);
|
||||
|
||||
@@ -191,8 +196,6 @@ namespace AtomToolsFramework
|
||||
continue;
|
||||
}
|
||||
|
||||
m_documentIdsWithDependencyChanges.erase(documentId);
|
||||
|
||||
AtomToolsFramework::TraceRecorder traceRecorder(m_maxMessageBoxLineCount);
|
||||
|
||||
bool openResult = false;
|
||||
@@ -235,7 +238,7 @@ namespace AtomToolsFramework
|
||||
|
||||
m_documentIdsWithDependencyChanges.clear();
|
||||
m_documentIdsWithExternalChanges.clear();
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
m_queueReopenDocuments = false;
|
||||
}
|
||||
|
||||
AZ::Uuid AtomToolsDocumentSystemComponent::OpenDocument(AZStd::string_view sourcePath)
|
||||
|
||||
+3
-6
@@ -9,7 +9,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
|
||||
@@ -28,7 +27,6 @@ namespace AtomToolsFramework
|
||||
//! AtomToolsDocumentSystemComponent is the central component of the Material Editor Core gem
|
||||
class AtomToolsDocumentSystemComponent
|
||||
: public AZ::Component
|
||||
, private AZ::TickBus::Handler
|
||||
, private AtomToolsDocumentNotificationBus::Handler
|
||||
, private AtomToolsDocumentSystemRequestBus::Handler
|
||||
{
|
||||
@@ -59,10 +57,8 @@ namespace AtomToolsFramework
|
||||
void OnDocumentExternallyModified(const AZ::Uuid& documentId) override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AZ::TickBus::Handler overrides...
|
||||
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
void QueueReopenDocuments();
|
||||
void ReopenDocuments();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AtomToolsDocumentSystemRequestBus::Handler overrides...
|
||||
@@ -87,6 +83,7 @@ namespace AtomToolsFramework
|
||||
AZStd::unordered_map<AZ::Uuid, AZStd::shared_ptr<AtomToolsDocument>> m_documentMap;
|
||||
AZStd::unordered_set<AZ::Uuid> m_documentIdsWithExternalChanges;
|
||||
AZStd::unordered_set<AZ::Uuid> m_documentIdsWithDependencyChanges;
|
||||
bool m_queueReopenDocuments = false;
|
||||
const size_t m_maxMessageBoxLineCount = 15;
|
||||
};
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
@@ -222,31 +222,15 @@ namespace AtomToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
AZStd::string GetExteralReferencePath(const AZStd::string& exportPath, const AZStd::string& referencePath, const uint32_t maxPathDepth)
|
||||
AZStd::string GetExteralReferencePath(
|
||||
const AZStd::string& exportPath, const AZStd::string& referencePath, const bool relativeToExportPath)
|
||||
{
|
||||
if (referencePath.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
AZ::IO::BasicPath<AZStd::string> exportFolder(exportPath);
|
||||
exportFolder.RemoveFilename();
|
||||
|
||||
const AZStd::string relativePath = AZ::IO::PathView(referencePath).LexicallyRelative(exportFolder).StringAsPosix();
|
||||
|
||||
// Count the difference in depth between the export file path and the referenced file path.
|
||||
uint32_t parentFolderCount = 0;
|
||||
AZStd::string::size_type pos = 0;
|
||||
const AZStd::string parentFolderToken = "..";
|
||||
while ((pos = relativePath.find(parentFolderToken, pos)) != AZStd::string::npos)
|
||||
{
|
||||
parentFolderCount++;
|
||||
pos += parentFolderToken.length();
|
||||
}
|
||||
|
||||
// If the difference in depth is too great then revert to using the asset folder relative path.
|
||||
// We could change this to only use relative paths for references in subfolders.
|
||||
if (parentFolderCount > maxPathDepth)
|
||||
if (!relativeToExportPath)
|
||||
{
|
||||
AZStd::string watchFolder;
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
@@ -260,7 +244,9 @@ namespace AtomToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
return relativePath;
|
||||
AZ::IO::BasicPath<AZStd::string> exportFolder(exportPath);
|
||||
exportFolder.RemoveFilename();
|
||||
return AZ::IO::PathView(referencePath).LexicallyRelative(exportFolder).StringAsPosix();
|
||||
}
|
||||
|
||||
const AtomToolsFramework::DynamicProperty* FindDynamicPropertyForInstanceDataNode(const AzToolsFramework::InstanceDataNode* pNode)
|
||||
|
||||
@@ -62,6 +62,8 @@ namespace AtomToolsFramework
|
||||
const QFileInfo initialFileInfo(initialPath);
|
||||
const QString initialExt(initialFileInfo.completeSuffix());
|
||||
|
||||
// Instead of just passing in the absolute file path, we pass in the absolute folder path and the base name to prevent the file
|
||||
// dialog from displaying multiple extensions when the extension contains a "."
|
||||
const QFileInfo selectedFileInfo(AzQtComponents::FileDialog::GetSaveFileName(
|
||||
QApplication::activeWindow(),
|
||||
"Save File",
|
||||
@@ -82,7 +84,9 @@ namespace AtomToolsFramework
|
||||
return QFileInfo();
|
||||
}
|
||||
|
||||
return selectedFileInfo;
|
||||
// Reconstructing the file info from the absolute path and expected extension to compensate for an issue with the save file
|
||||
// dialog adding the extension multiple times if it contains "." like *.lightingpreset.azasset
|
||||
return QFileInfo(selectedFileInfo.absolutePath() + AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING + selectedFileInfo.baseName() + "." + initialExt);
|
||||
}
|
||||
|
||||
QFileInfo GetOpenFileInfo(const AZStd::vector<AZ::Data::AssetType>& assetTypes)
|
||||
|
||||
@@ -66,15 +66,15 @@ namespace UnitTest
|
||||
|
||||
TEST_F(AtomToolsFrameworkTest, GetExteralReferencePath_Succeeds)
|
||||
{
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("", "", 2), "");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/materials/condor.material", "", 2), "");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/materials/talisman.material", "", 2), "");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/materials/talisman.material", "d:/project/assets/textures/gold.png", 2), "../textures/gold.png");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/materials/talisman.material", "d:/project/assets/textures/gold.png", 0), "textures/gold.png");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/objects/upgrades/materials/supercondor.material", "d:/project/assets/materials/condor.material", 3), "../../../materials/condor.material");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/objects/upgrades/materials/supercondor.material", "d:/project/assets/materials/condor.material", 2), "materials/condor.material");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/objects/upgrades/materials/supercondor.material", "d:/project/assets/materials/condor.material", 1), "materials/condor.material");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/objects/upgrades/materials/supercondor.material", "d:/project/assets/materials/condor.material", 0), "materials/condor.material");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("", "", true), "");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/materials/condor.material", "", true), "");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/materials/talisman.material", "", false), "");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/materials/talisman.material", "d:/project/assets/textures/gold.png", true), "../textures/gold.png");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/materials/talisman.material", "d:/project/assets/textures/gold.png", false), "textures/gold.png");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/objects/upgrades/materials/supercondor.material", "d:/project/assets/materials/condor.material", true), "../../../materials/condor.material");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/objects/upgrades/materials/supercondor.material", "d:/project/assets/materials/condor.material", false), "materials/condor.material");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/objects/upgrades/materials/supercondor.material", "d:/project/assets/materials/condor.material", false), "materials/condor.material");
|
||||
ASSERT_EQ(AtomToolsFramework::GetExteralReferencePath("d:/project/assets/objects/upgrades/materials/supercondor.material", "d:/project/assets/materials/condor.material", false), "materials/condor.material");
|
||||
}
|
||||
|
||||
AZ_UNIT_TEST_HOOK(new AtomToolsFrameworkTestEnvironment);
|
||||
|
||||
@@ -167,7 +167,8 @@ namespace UnitTest
|
||||
const auto ray = m_viewportInteractionImpl->ViewportScreenToWorldRay(ScreenPoint(832, 226));
|
||||
|
||||
float unused;
|
||||
auto intersection = AZ::Intersect::IntersectRaySphere(ray.origin, ray.direction, AZ::Vector3(-14.0f, 5.7f, 0.75f), 0.5f, unused);
|
||||
auto intersection =
|
||||
AZ::Intersect::IntersectRaySphere(ray.m_origin, ray.m_direction, AZ::Vector3(-14.0f, 5.7f, 0.75f), 0.5f, unused);
|
||||
|
||||
EXPECT_EQ(intersection, AZ::Intersect::SphereIsectTypes::ISECT_RAY_SPHERE_ISECT);
|
||||
}
|
||||
|
||||
@@ -555,7 +555,7 @@ namespace MaterialEditor
|
||||
|
||||
void MaterialDocument::SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid sourceUUID)
|
||||
{
|
||||
auto sourcePath = AZ::RPI::AssetUtils::ResolvePathReference(scanFolder, relativePath);
|
||||
const auto sourcePath = AZ::RPI::AssetUtils::ResolvePathReference(scanFolder, relativePath);
|
||||
|
||||
if (m_absolutePath == sourcePath)
|
||||
{
|
||||
|
||||
+8
-12
@@ -6,25 +6,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Window/CreateMaterialDialog/CreateMaterialDialog.h>
|
||||
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzQtComponents/Components/Widgets/FileDialog.h>
|
||||
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
|
||||
#include <Atom/Document/MaterialDocumentSettings.h>
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <Atom/RPI.Edit/Material/MaterialSourceData.h>
|
||||
#include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
|
||||
|
||||
#include <Atom/Document/MaterialDocumentSettings.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzQtComponents/Components/Widgets/FileDialog.h>
|
||||
#include <Window/CreateMaterialDialog/CreateMaterialDialog.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
CreateMaterialDialog::CreateMaterialDialog(QWidget* parent)
|
||||
: CreateMaterialDialog(QString(AZ::IO::FileIOBase::GetInstance()->GetAlias("@projectroot@")) + AZ_CORRECT_FILESYSTEM_SEPARATOR + "Materials", parent)
|
||||
: CreateMaterialDialog(QString(AZ::Utils::GetProjectPath().c_str()) + AZ_CORRECT_FILESYSTEM_SEPARATOR + "Assets", parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -12,6 +12,7 @@
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzCore/std/string/wildcard.h>
|
||||
#include <AzQtComponents/Utilities/DesktopUtilities.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
@@ -106,8 +107,8 @@ namespace MaterialEditor
|
||||
menu->addAction("Create Material...", [entry]()
|
||||
{
|
||||
const QString defaultPath = AtomToolsFramework::GetUniqueFileInfo(
|
||||
QString(AZ::IO::FileIOBase::GetInstance()->GetAlias("@projectroot@")) +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Materials" +
|
||||
QString(AZ::Utils::GetProjectPath().c_str()) +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Assets" +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "untitled." +
|
||||
AZ::RPI::MaterialSourceData::Extension).absoluteFilePath();
|
||||
|
||||
@@ -182,8 +183,8 @@ namespace MaterialEditor
|
||||
menu->addAction("Create Child Material...", [entry]()
|
||||
{
|
||||
const QString defaultPath = AtomToolsFramework::GetUniqueFileInfo(
|
||||
QString(AZ::IO::FileIOBase::GetInstance()->GetAlias("@projectroot@")) +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Materials" +
|
||||
QString(AZ::Utils::GetProjectPath().c_str()) +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Assets" +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "untitled." +
|
||||
AZ::RPI::MaterialSourceData::Extension).absoluteFilePath();
|
||||
|
||||
|
||||
+6
-8
@@ -6,10 +6,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Atom/Viewport/MaterialViewportRequestBus.h>
|
||||
#include <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h>
|
||||
#include <Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h>
|
||||
#include <Window/ViewportSettingsInspector/ViewportSettingsInspector.h>
|
||||
@@ -346,13 +347,10 @@ namespace MaterialEditor
|
||||
|
||||
AZStd::string ViewportSettingsInspector::GetDefaultUniqueSaveFilePath(const AZStd::string& baseName) const
|
||||
{
|
||||
AZStd::string savePath = AZ::IO::FileIOBase::GetInstance()->GetAlias("@projectroot@");
|
||||
savePath += AZ_CORRECT_FILESYSTEM_SEPARATOR;
|
||||
savePath += "Materials";
|
||||
savePath += AZ_CORRECT_FILESYSTEM_SEPARATOR;
|
||||
savePath += baseName;
|
||||
savePath = AtomToolsFramework::GetUniqueFileInfo(savePath.c_str()).absoluteFilePath().toUtf8().constData();
|
||||
return savePath;
|
||||
return AtomToolsFramework::GetUniqueFileInfo(
|
||||
QString(AZ::Utils::GetProjectPath().c_str()) +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + "Assets" +
|
||||
AZ_CORRECT_FILESYSTEM_SEPARATOR + baseName.c_str()).absoluteFilePath().toUtf8().constData();
|
||||
}
|
||||
|
||||
AZ::Crc32 ViewportSettingsInspector::GetGroupSaveStateKey(const AZStd::string& groupName) const
|
||||
|
||||
+23
-16
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "AtomViewportDisplayIconsSystemComponent.h"
|
||||
|
||||
#include <AzCore/Math/VectorConversions.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
@@ -117,8 +118,7 @@ namespace AZ::Render
|
||||
return;
|
||||
}
|
||||
|
||||
auto perViewportDynamicDrawInterface =
|
||||
AtomBridge::PerViewportDynamicDraw::Get();
|
||||
auto perViewportDynamicDrawInterface = AtomBridge::PerViewportDynamicDraw::Get();
|
||||
if (!perViewportDynamicDrawInterface)
|
||||
{
|
||||
return;
|
||||
@@ -131,7 +131,7 @@ namespace AZ::Render
|
||||
return;
|
||||
}
|
||||
|
||||
// Find our icon, falling back on a grey placeholder if its image is unavailable
|
||||
// Find our icon, falling back on a gray placeholder if its image is unavailable
|
||||
AZ::Data::Instance<AZ::RPI::Image> image = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::Grey);
|
||||
if (auto iconIt = m_iconData.find(drawParameters.m_icon); iconIt != m_iconData.end())
|
||||
{
|
||||
@@ -172,13 +172,16 @@ namespace AZ::Render
|
||||
}
|
||||
else if (drawParameters.m_positionSpace == CoordinateSpace::WorldSpace)
|
||||
{
|
||||
// Calculate the ndc point (0.0-1.0 range) including depth
|
||||
const AZ::Vector3 ndcPoint = AzFramework::WorldToScreenNdc(
|
||||
drawParameters.m_position, viewportContext->GetCameraViewMatrixAsMatrix3x4(),
|
||||
viewportContext->GetCameraProjectionMatrix());
|
||||
|
||||
// Calculate our screen space position using the viewport size
|
||||
// We want this instead of RenderViewportWidget::WorldToScreen which works in QWidget virtual coordinate space
|
||||
const AzFramework::ScreenPoint position = AzFramework::WorldToScreen(
|
||||
drawParameters.m_position, viewportContext->GetCameraViewMatrixAsMatrix3x4(),
|
||||
viewportContext->GetCameraProjectionMatrix(), viewportSize);
|
||||
screenPosition.SetX(aznumeric_cast<float>(position.m_x));
|
||||
screenPosition.SetY(aznumeric_cast<float>(position.m_y));
|
||||
const AzFramework::ScreenPoint screenPoint = AzFramework::ScreenPointFromNdc(AZ::Vector3ToVector2(ndcPoint), viewportSize);
|
||||
|
||||
screenPosition = AzFramework::Vector3FromScreenPoint(screenPoint, ndcPoint.GetZ());
|
||||
}
|
||||
|
||||
struct Vertex
|
||||
@@ -210,7 +213,12 @@ namespace AZ::Render
|
||||
createVertex(-0.5f, 0.5f, 0.f, 1.f)
|
||||
};
|
||||
AZStd::array<Indice, 6> indices = {0, 1, 2, 0, 2, 3};
|
||||
dynamicDraw->DrawIndexed(&vertices, static_cast<uint32_t>(vertices.size()), &indices, static_cast<uint32_t>(indices.size()), RHI::IndexFormat::Uint16, drawSrg);
|
||||
|
||||
dynamicDraw->SetSortKey(
|
||||
aznumeric_cast<int64_t>(screenPosition.GetZ() * aznumeric_cast<float>(AZStd::numeric_limits<int64_t>::max())));
|
||||
dynamicDraw->DrawIndexed(
|
||||
&vertices, static_cast<uint32_t>(vertices.size()), &indices, static_cast<uint32_t>(indices.size()), RHI::IndexFormat::Uint16,
|
||||
drawSrg);
|
||||
}
|
||||
|
||||
QString AtomViewportDisplayIconsSystemComponent::FindAssetPath(const QString& path) const
|
||||
@@ -354,7 +362,7 @@ namespace AZ::Render
|
||||
{
|
||||
// Once the shader is loaded, register it with the dynamic draw context
|
||||
Data::Asset<RPI::ShaderAsset> shaderAsset = asset;
|
||||
AtomBridge::PerViewportDynamicDraw::Get()->RegisterDynamicDrawContext(m_drawContextName, [shaderAsset](RPI::Ptr<RPI::DynamicDrawContext> drawContext)
|
||||
AtomBridge::PerViewportDynamicDraw::Get()->RegisterDynamicDrawContext(m_drawContextName, [shaderAsset](RPI::Ptr<RPI::DynamicDrawContext> dynamicDraw)
|
||||
{
|
||||
AZ_Assert(shaderAsset->IsReady(), "Attempting to register the AtomViewportDisplayIconsSystemComponent"
|
||||
" dynamic draw context before the shader asset is loaded. The shader should be loaded first"
|
||||
@@ -362,12 +370,11 @@ namespace AZ::Render
|
||||
" will be executed during scene processing and there may be multiple scenes executing in parallel.");
|
||||
|
||||
Data::Instance<RPI::Shader> shader = RPI::Shader::FindOrCreate(shaderAsset);
|
||||
drawContext->InitShader(shader);
|
||||
drawContext->InitVertexFormat(
|
||||
{ {"POSITION", RHI::Format::R32G32B32_FLOAT},
|
||||
{"COLOR", RHI::Format::R8G8B8A8_UNORM},
|
||||
{"TEXCOORD", RHI::Format::R32G32_FLOAT} });
|
||||
drawContext->EndInit();
|
||||
dynamicDraw->InitShader(shader);
|
||||
dynamicDraw->InitVertexFormat({ { "POSITION", RHI::Format::R32G32B32_FLOAT },
|
||||
{ "COLOR", RHI::Format::R8G8B8A8_UNORM },
|
||||
{ "TEXCOORD", RHI::Format::R32G32_FLOAT } });
|
||||
dynamicDraw->EndInit();
|
||||
});
|
||||
|
||||
m_drawContextRegistered = true;
|
||||
|
||||
@@ -326,6 +326,9 @@ namespace EMStudio
|
||||
Camera::Configuration cameraConfig;
|
||||
cameraConfig.m_fovRadians = AZ::DegToRad(m_renderOptions->GetFOV());
|
||||
cameraConfig.m_nearClipDistance = m_renderOptions->GetNearClipPlaneDistance();
|
||||
cameraConfig.m_farClipDistance = m_renderOptions->GetFarClipPlaneDistance();
|
||||
cameraConfig.m_frustumWidth = DefaultFrustumDimension;
|
||||
cameraConfig.m_frustumHeight = DefaultFrustumDimension;
|
||||
|
||||
preset->ApplyLightingPreset(
|
||||
iblFeatureProcessor, m_skyboxFeatureProcessor, exposureControlSettingInterface, m_directionalLightFeatureProcessor,
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace EMStudio
|
||||
AZStd::vector<AZ::Entity*> m_actorEntities;
|
||||
const RenderOptions* m_renderOptions;
|
||||
|
||||
const float DefaultFrustumDimension = 128.0f;
|
||||
AZStd::vector<AZ::Render::DirectionalLightFeatureProcessorInterface::LightHandle> m_lightHandles;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -162,6 +162,7 @@ namespace EMStudio
|
||||
|
||||
const bool isChecked = settings.value("CameraFollowUp", false).toBool();
|
||||
m_followCharacterAction->setChecked(isChecked);
|
||||
AnimViewportRequestBus::Broadcast(&AnimViewportRequestBus::Events::SetFollowCharacter, isChecked);
|
||||
}
|
||||
|
||||
void AnimViewportToolBar::SaveSettings()
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
export DYNACONF_COMPANY=Amazon
|
||||
# if a O3DE project isn't set use this gem
|
||||
export DYNACONF_O3DE_PROJECT=DccScriptingInterface
|
||||
export DYNACONF_O3DE_PROJECT_PATH=`pwd`
|
||||
export DYNACONF_O3DE_DEV=${O3DE_PROJECT_PATH}\..\..\..\..
|
||||
export DYNACONF_PATH_O3DE_PROJECT=`pwd`
|
||||
export DYNACONF_O3DE_DEV=${PATH_O3DE_PROJECT}\..\..\..\..
|
||||
|
||||
# LY build folder
|
||||
export DYNACONF_O3DE_BUILD_PATH=${O3DE_DEV}\build
|
||||
export DYNACONF_O3DE_BIN_PATH=${O3DE_BUILD_PATH}\bin\profile
|
||||
export DYNACONF_PATH_O3DE_BUILD=${O3DE_DEV}\build
|
||||
export DYNACONF_PATH_O3DE_BIN=${PATH_O3DE_BUILD}\bin\profile
|
||||
|
||||
# default IDE and debug settings
|
||||
#export DYNACONF_DCCSI_GDEBUG=false
|
||||
@@ -24,7 +24,7 @@ export DYNACONF_DCCSI_GDEBUGGER=WING
|
||||
export DYNACONF_DCCSI_LOGLEVEL=20
|
||||
|
||||
# defaults for DccScriptingInterface (DCCsi)
|
||||
export DYNACONF_DCCSIG_PATH=${O3DE_DEV}\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface
|
||||
export DYNACONF_PATH_DCCSIG=${O3DE_DEV}\Gems\AtomLyIntegration\TechnicalArt\DccScriptingInterface
|
||||
|
||||
# set up default python interpreter (O3DE)
|
||||
# we may want to entirely remove these and rely on config.py to dynamically set up
|
||||
@@ -33,20 +33,20 @@ export DYNACONF_DCCSI_PY_VERSION_MAJOR=3
|
||||
export DYNACONF_DCCSI_PY_VERSION_MINOR=7
|
||||
export DYNACONF_DCCSI_PY_VERSION_RELEASE=11
|
||||
# To Do: probably move the folder below into the /SDK folder?
|
||||
export DYNACONF_DCCSI_PYTHON_PATH=${DCCSIG_PATH}\3rdParty\Python
|
||||
export DYNACONF_PATH_DCCSI_PYTHON=${PATH_DCCSIG}\3rdParty\Python
|
||||
|
||||
# add access to a Lib location that matches the py version (3.7.x)
|
||||
# switch this for other python version like (2.7.x) for Maya
|
||||
export DYNACONF_DCCSI_PYTHON_LIB_PATH=${DCCSI_PYTHON_PATH}\Lib\${DCCSI_PY_VERSION_MAJOR}.x\${DCCSI_PY_VERSION_MAJOR}.${DCCSI_PY_VERSION_MINOR}.x\site-packages
|
||||
export DYNACONF_PATH_DCCSI_PYTHON_LIB=${PATH_DCCSI_PYTHON}\Lib\${DCCSI_PY_VERSION_MAJOR}.x\${DCCSI_PY_VERSION_MAJOR}.${DCCSI_PY_VERSION_MINOR}.x\site-packages
|
||||
|
||||
# TO DO: figure out how to best deal with OS folder (i.e. 'windows')
|
||||
export DYNACONF_O3DE_PYTHON_INSTALL=${O3DE_DEV}\python
|
||||
export DYNACONF_DCCSI_PY_BASE=${O3DE_PYTHON_INSTALL}\python.cmd
|
||||
export DYNACONF_PATH_O3DE_PYTHON_INSTALL=${O3DE_DEV}\python
|
||||
export DYNACONF_DCCSI_PY_BASE=${PATH_O3DE_PYTHON_INSTALL}\python.cmd
|
||||
|
||||
# set up Qt / PySide2
|
||||
# TO DO: These should NOT be set in the global env as they will cause conflicts
|
||||
# with other Qt apps (like DCC tools), only set in local.env, or modify config.py
|
||||
# for utils/tools/apps that need them ( see config.init_ly_pyside() )
|
||||
#export DYNACONF_QTFORPYTHON_PATH=${O3DE_DEV}\Gems\QtForPython\3rdParty\pyside2\windows\release
|
||||
#export DYNACONF_QT_PLUGIN_PATH=${O3DE_BUILD_PATH}\bin\profile\EditorPlugins
|
||||
#export DYNACONF_QT_QPA_PLATFORM_PLUGIN_PATH=${O3DE_BUILD_PATH}\bin\profile\EditorPlugins\platforms
|
||||
#export DYNACONF_QT_PLUGIN_PATH=${PATH_O3DE_BUILD}\bin\profile\EditorPlugins
|
||||
#export DYNACONF_QT_QPA_PLATFORM_PLUGIN_PATH=${PATH_O3DE_BUILD}\bin\profile\EditorPlugins\platforms
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user