Merge pull request #5052 from aws-lumberyard-dev/daimini/gitflow_211027_o3de

GitFlow 10/27/21 (stabilization2110 to development) - O3DE
This commit is contained in:
Danilo Aimini
2021-10-27 17:45:45 -07:00
committed by GitHub
69 changed files with 699 additions and 386 deletions
@@ -9,7 +9,7 @@
#import <AppKit/NSEvent.h>
#include "EditorDefs.h"
#include "QtEditorApplication.h"
#include "QtEditorApplication_mac.h"
// AzFramework
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Platform.h>
@@ -1788,6 +1788,11 @@ AZStd::string SandboxIntegrationManager::GetComponentEditorIcon(const AZ::Uuid&
return iconPath;
}
AZStd::string SandboxIntegrationManager::GetComponentTypeEditorIcon(const AZ::Uuid& componentType)
{
return GetComponentEditorIcon(componentType, nullptr);
}
AZStd::string SandboxIntegrationManager::GetComponentIconPath(const AZ::Uuid& componentType,
AZ::Crc32 componentIconAttrib, AZ::Component* component)
{
@@ -233,6 +233,7 @@ private:
}
AZStd::string GetComponentEditorIcon(const AZ::Uuid& componentType, AZ::Component* component) override;
AZStd::string GetComponentTypeEditorIcon(const AZ::Uuid& componentType) override;
AZStd::string GetComponentIconPath(const AZ::Uuid& componentType, AZ::Crc32 componentIconAttrib, AZ::Component* component) override;
//////////////////////////////////////////////////////////////////////////
@@ -139,7 +139,7 @@ ComponentDataModel::ComponentDataModel(QObject* parent)
if (element.m_elementId == AZ::Edit::ClassElements::EditorData)
{
AZStd::string iconPath;
EBUS_EVENT_RESULT(iconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, classData->m_typeId, nullptr);
AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, classData->m_typeId);
if (!iconPath.empty())
{
m_componentIcons[classData->m_typeId] = QIcon(iconPath.c_str());
+1 -1
View File
@@ -408,7 +408,7 @@ CTrackViewNodesCtrl::CTrackViewNodesCtrl(QWidget* hParentWnd, CTrackViewDialog*
serializeContext->EnumerateDerived<AZ::Component>([this](const AZ::SerializeContext::ClassData* classData, const AZ::Uuid&) -> bool
{
AZStd::string iconPath;
EBUS_EVENT_RESULT(iconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, classData->m_typeId, nullptr);
AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, classData->m_typeId);
if (!iconPath.empty())
{
m_componentTypeToIconMap[classData->m_typeId] = QIcon(iconPath.c_str());
@@ -258,10 +258,17 @@ namespace AzFramework
////////////////////////////////////////////////////////////////////////////////////////////////
void XcbNativeWindow::SetWindowTitle(const AZStd::string& title)
{
// Set the title of both the window and the task bar by using
// a buffer to hold the title twice, separated by a null-terminator
auto doubleTitleSize = (title.size() + 1) * 2;
AZStd::string doubleTitle(doubleTitleSize, '\0');
azstrncpy(doubleTitle.data(), doubleTitleSize, title.c_str(), title.size());
azstrncpy(&doubleTitle.data()[title.size() + 1], title.size(), title.c_str(), title.size());
xcb_void_cookie_t xcbCheckResult;
xcbCheckResult = xcb_change_property(
m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, static_cast<uint32_t>(title.size()),
title.c_str());
m_xcbConnection, XCB_PROP_MODE_REPLACE, m_xcbWindow, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, static_cast<uint32_t>(doubleTitle.size()),
doubleTitle.c_str());
AZ_Assert(ValidateXcbResult(xcbCheckResult), "Failed to set window title.");
}
@@ -826,6 +826,10 @@ namespace AzToolsFramework
/// Path will be empty if component should have no icon.
virtual AZStd::string GetComponentEditorIcon(const AZ::Uuid& /*componentType*/, AZ::Component* /*component*/) { return AZStd::string(); }
//! Return path to icon for component type.
//! Path will be empty if component type should have no icon.
virtual AZStd::string GetComponentTypeEditorIcon(const AZ::Uuid& /*componentType*/) { return AZStd::string(); }
/**
* Return the icon image path based on the component type and where it is used.
* \param componentType component type
@@ -43,6 +43,8 @@ namespace AzToolsFramework
};
//! Provides a bus to notify when the different editor modes are entered/exit.
//! @note The editor modes are not discrete states but rather each progression of mode retain the active the parent
//! mode that the new mode progressed from.
class ViewportEditorModeNotifications : public AZ::EBusTraits
{
public:
@@ -176,7 +176,7 @@ namespace AzToolsFramework
, public AZ::BehaviorEBusHandler
{
AZ_EBUS_BEHAVIOR_BINDER(ToolsApplicationNotificationBusHandler, "{7EB67956-FF86-461A-91E2-7B08279CFACF}", AZ::SystemAllocator,
EntityRegistered, EntityDeregistered);
EntityRegistered, EntityDeregistered, AfterEntitySelectionChanged);
void EntityRegistered(AZ::EntityId entityId) override
{
@@ -187,6 +187,11 @@ namespace AzToolsFramework
{
Call(FN_EntityDeregistered, entityId);
}
void AfterEntitySelectionChanged(const EntityIdList& newlySelectedEntities, const EntityIdList& newlyDeselectedEntities) override
{
Call(FN_AfterEntitySelectionChanged, newlySelectedEntities, newlyDeselectedEntities);
}
};
struct ViewPaneCallbackBusHandler final
@@ -410,6 +415,7 @@ namespace AzToolsFramework
->Handler<Internal::ToolsApplicationNotificationBusHandler>()
->Event("EntityRegistered", &ToolsApplicationEvents::EntityRegistered)
->Event("EntityDeregistered", &ToolsApplicationEvents::EntityDeregistered)
->Event("AfterEntitySelectionChanged", &ToolsApplicationEvents::AfterEntitySelectionChanged)
;
behaviorContext->Class<ViewPaneOptions>()
@@ -428,6 +434,7 @@ namespace AzToolsFramework
->Attribute(AZ::Script::Attributes::Module, "editor")
->Event("RegisterCustomViewPane", &EditorRequests::RegisterCustomViewPane)
->Event("UnregisterViewPane", &EditorRequests::UnregisterViewPane)
->Event("GetComponentTypeEditorIcon", &EditorRequests::GetComponentTypeEditorIcon)
;
behaviorContext->EBus<EditorEventsBus>("EditorEventBus")
@@ -90,7 +90,7 @@ namespace AzToolsFramework
}
AZStd::string componentIconPath;
EBUS_EVENT_RESULT(componentIconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, componentClass->m_typeId, nullptr);
AzToolsFramework::EditorRequestBus::BroadcastResult(componentIconPath, &AzToolsFramework::EditorRequests::GetComponentTypeEditorIcon, componentClass->m_typeId);
componentIconTable[componentClass] = QString::fromUtf8(componentIconPath.c_str());
}
@@ -72,7 +72,7 @@ namespace AzToolsFramework
void EntityOutlinerTreeView::leaveEvent([[maybe_unused]] QEvent* event)
{
m_mousePosition = QPoint();
m_mousePosition = QPoint(-1, -1);
m_currentHoveredIndex = QModelIndex();
update();
}
@@ -200,7 +200,7 @@ namespace AzToolsFramework
const bool isEnabled = (this->model()->flags(index) & Qt::ItemIsEnabled);
const bool isSelected = selectionModel()->isSelected(index);
const bool isHovered = (index == indexAt(m_mousePosition)) && isEnabled;
const bool isHovered = (index == indexAt(m_mousePosition).siblingAtColumn(0)) && isEnabled;
// Paint the branch Selection/Hover Rect
PaintBranchSelectionHoverRect(painter, rect, isSelected, isHovered);
@@ -153,6 +153,9 @@ namespace AzToolsFramework
{
initEntityOutlinerWidgetResources();
m_editorEntityUiInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
AZ_Assert(m_editorEntityUiInterface != nullptr, "EntityOutlinerWidget requires a EditorEntityUiInterface instance on Initialize.");
m_gui = new Ui::EntityOutlinerWidgetUI();
m_gui->setupUi(this);
@@ -282,12 +285,6 @@ namespace AzToolsFramework
m_listModel->Initialize();
m_editorEntityUiInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
AZ_Assert(
m_editorEntityUiInterface != nullptr,
"EntityOutlinerWidget requires a EditorEntityUiInterface instance on Initialize.");
EditorPickModeNotificationBus::Handler::BusConnect(GetEntityContextId());
EntityHighlightMessages::Bus::Handler::BusConnect();
EntityOutlinerModelNotificationBus::Handler::BusConnect();
@@ -583,7 +583,7 @@ namespace AzToolsFramework
}
AZStd::string iconPath;
EBUS_EVENT_RESULT(iconPath, AzToolsFramework::EditorRequests::Bus, GetComponentEditorIcon, componentType, const_cast<AZ::Component*>(&componentInstance));
AzToolsFramework::EditorRequestBus::BroadcastResult(iconPath, &AzToolsFramework::EditorRequests::GetComponentEditorIcon, componentType, const_cast<AZ::Component*>(&componentInstance));
GetHeader()->SetIcon(QIcon(iconPath.c_str()));
bool isExpanded = true;
@@ -8,6 +8,7 @@
#include <AzTest/AzTest.h>
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <AzToolsFramework/ViewportSelection/EditorPickEntitySelection.h>
@@ -187,10 +188,13 @@ namespace UnitTest
ASSERT_NE(m_viewportEditorModeTracker, nullptr);
m_viewportEditorModes = m_viewportEditorModeTracker->GetViewportEditorModes({AzToolsFramework::GetEntityContextId()});
ASSERT_NE(m_viewportEditorModes, nullptr);
m_focusModeInterface = AZ::Interface<AzToolsFramework::FocusModeInterface>::Get();
ASSERT_NE(m_focusModeInterface, nullptr);
}
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr;
const ViewportEditorModesInterface* m_viewportEditorModes = nullptr;
AzToolsFramework::FocusModeInterface* m_focusModeInterface = nullptr;
};
TEST_F(ViewportEditorModesTestsFixture, NumberOfEditorModesIsEqualTo4)
@@ -522,32 +526,48 @@ namespace UnitTest
}
TEST_F(
ViewportEditorModeTrackerIntegrationTestFixture, EnteringComponentModeAfterInitialStateHasViewportEditorModesDefaultAndComponentModeActive)
ViewportEditorModeTrackerIntegrationTestFixture,
EnteringComponentModeAfterInitialStateHasViewportEditorModesDefaultAndComponentModeActive)
{
// When component mode is entered
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::BeginComponentMode,
AZStd::vector<AzToolsFramework::ComponentModeFramework::EntityAndComponentModeBuilders>{});
bool inComponentMode = false;
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::BroadcastResult(
inComponentMode, &AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::InComponentMode);
// Expect to be in component mode
EXPECT_TRUE(inComponentMode);
EXPECT_TRUE(AzToolsFramework::ComponentModeFramework::InComponentMode());
// Expect the default and component viewport editor modes to be active
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Default));
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Component));
// Do not expect the pick and focus viewport editor modes to be active
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Pick));
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Focus));
}
TEST_F(
ViewportEditorModeTrackerIntegrationTestFixture,
EnteringEditorPickEntitySelectionAfterInitialStateHasOnlyViewportEditorModePickModeActive)
ExitingComponentModeAfterEnteringFrominitialStateHasViewportEditorModesDefaultActive)
{
// When component mode is entered and exited
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::BeginComponentMode,
AZStd::vector<AzToolsFramework::ComponentModeFramework::EntityAndComponentModeBuilders>{});
EXPECT_TRUE(AzToolsFramework::ComponentModeFramework::InComponentMode());
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::EndComponentMode);
// Expect to not be in component mode
EXPECT_FALSE(AzToolsFramework::ComponentModeFramework::InComponentMode());
// Expect only the default viewport editor mode to be active
ExpectOnlyModeActive(*m_viewportEditorModes, ViewportEditorMode::Default);
}
TEST_F(
ViewportEditorModeTrackerIntegrationTestFixture,
EnteringEditorPickEntitySelectionAfterInitialStateHasOnlyViewportEditorModePickActive)
{
// When entering pick mode
using AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus;
@@ -563,6 +583,96 @@ namespace UnitTest
ExpectOnlyModeActive(*m_viewportEditorModes, ViewportEditorMode::Pick);
}
// FocusMode integration tests will follow (LYN-6995)
TEST_F(
ViewportEditorModeTrackerIntegrationTestFixture,
EnteringEditorDefaultEntitySelectionFromEditorPickEntitySelectionHasOnlyViewportEditorModeDefaultActive)
{
// When pick mode is entered and exited
using AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus;
EditorInteractionSystemViewportSelectionRequestBus::Event(
AzToolsFramework::GetEntityContextId(), &EditorInteractionSystemViewportSelectionRequestBus::Events::SetHandler,
[](const AzToolsFramework::EditorVisibleEntityDataCache* entityDataCache,
[[maybe_unused]] AzToolsFramework::ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
{
return AZStd::make_unique<AzToolsFramework::EditorPickEntitySelection>(entityDataCache, viewportEditorModeTracker);
});
EditorInteractionSystemViewportSelectionRequestBus::Event(
AzToolsFramework::GetEntityContextId(), &EditorInteractionSystemViewportSelectionRequestBus::Events::SetHandler,
[](const AzToolsFramework::EditorVisibleEntityDataCache* entityDataCache,
[[maybe_unused]] AzToolsFramework::ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
{
return AZStd::make_unique<AzToolsFramework::EditorDefaultSelection>(entityDataCache, viewportEditorModeTracker);
});
// Expect only the default viewport editor mode to be active
ExpectOnlyModeActive(*m_viewportEditorModes, ViewportEditorMode::Default);
}
TEST_F(ViewportEditorModeTrackerIntegrationTestFixture, EnteringFocusModeAfterInitialStateHasViewportEditorModeDefaultAndPickActive)
{
// When entering focus mode
m_focusModeInterface->SetFocusRoot(AZ::EntityId{ 1 });
// Expect the default and focus viewport editor modes to be active
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Default));
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Focus));
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Pick));
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Component));
}
TEST_F(
ViewportEditorModeTrackerIntegrationTestFixture,
ExitingFocusModeAfterEnteringFromInitialStateHasOnlyViewportEditorModeDefaultActive)
{
// When entering and leaving focus mode
m_focusModeInterface->SetFocusRoot(AZ::EntityId{ 1 });
m_focusModeInterface->SetFocusRoot(AZ::EntityId());
// Expect only the default mode to be active
ExpectOnlyModeActive(*m_viewportEditorModes, ViewportEditorMode::Default);
}
TEST_F(ViewportEditorModeTrackerIntegrationTestFixture, EnteringComponentModeFromFocusModeStateHasViewportEditorModeDefaultAndFocusAndComponentActive)
{
// When entering component mode from focus mode
m_focusModeInterface->SetFocusRoot(AZ::EntityId{ 1 });
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::BeginComponentMode,
AZStd::vector<AzToolsFramework::ComponentModeFramework::EntityAndComponentModeBuilders>{});
// Expect to be in component mode
EXPECT_TRUE(AzToolsFramework::ComponentModeFramework::InComponentMode());
// Expect the default, focus and component viewport editor modes to be active
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Default));
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Focus));
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Component));
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Pick));
}
TEST_F(
ViewportEditorModeTrackerIntegrationTestFixture,
ExitingComponentModeAfterEnteringFromFocusModeHasViewportEditorModeDefaultAndFocusActive)
{
// When entering and leaving component mode from focus mode
m_focusModeInterface->SetFocusRoot(AZ::EntityId{ 1 });
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::BeginComponentMode,
AZStd::vector<AzToolsFramework::ComponentModeFramework::EntityAndComponentModeBuilders>{});
EXPECT_TRUE(AzToolsFramework::ComponentModeFramework::InComponentMode());
AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequestBus::Broadcast(
&AzToolsFramework::ComponentModeFramework::ComponentModeSystemRequests::EndComponentMode);
// Expect to not be in component mode
EXPECT_FALSE(AzToolsFramework::ComponentModeFramework::InComponentMode());
// Expect the default and focus viewport editor modes to be active
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Default));
EXPECT_TRUE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Focus));
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Component));
EXPECT_FALSE(m_viewportEditorModes->IsModeActive(ViewportEditorMode::Pick));
}
} // namespace UnitTest
@@ -691,6 +691,12 @@ QProgressBar::chunk {
#gemRepoAddDialogInstructionTitleLabel {
font-size:14px;
font-weight:bold;
}
#gemRepoAddDialogWarningLabel {
font-size:12px;
font-style:italic;
}
#addGemRepoDialog #formFrame {
@@ -167,6 +167,10 @@ namespace O3DE::ProjectManager
{
notification += " " + tr("and") + " ";
}
if (added && GemModel::GetDownloadStatus(modelIndex) == GemInfo::DownloadStatus::NotDownloaded)
{
m_downloadController->AddGemDownload(GemModel::GetName(modelIndex));
}
}
if (numChangedDependencies == 1 )
@@ -225,21 +225,22 @@ namespace O3DE::ProjectManager
QVector<QString> elementNames;
QVector<int> elementCounts;
const int totalGems = m_gemModel->rowCount();
const int selectedGemTotal = m_gemModel->TotalAddedGems();
const int selectedGemTotal = m_gemModel->GatherGemsToBeAdded(/*includeDependencies=*/true).size();
const int unselectedGemTotal = m_gemModel->GatherGemsToBeRemoved(/*includeDependencies=*/true).size();
const int enabledGemTotal = m_gemModel->TotalAddedGems(/*includeDependencies=*/true);
elementNames.push_back(GemSortFilterProxyModel::GetGemSelectedString(GemSortFilterProxyModel::GemSelected::Unselected));
elementCounts.push_back(totalGems - selectedGemTotal);
elementNames.push_back(GemSortFilterProxyModel::GetGemSelectedString(GemSortFilterProxyModel::GemSelected::Selected));
elementCounts.push_back(selectedGemTotal);
elementNames.push_back(GemSortFilterProxyModel::GetGemActiveString(GemSortFilterProxyModel::GemActive::Inactive));
elementCounts.push_back(totalGems - enabledGemTotal);
elementNames.push_back(GemSortFilterProxyModel::GetGemSelectedString(GemSortFilterProxyModel::GemSelected::Unselected));
elementCounts.push_back(unselectedGemTotal);
elementNames.push_back(GemSortFilterProxyModel::GetGemActiveString(GemSortFilterProxyModel::GemActive::Active));
elementCounts.push_back(enabledGemTotal);
elementNames.push_back(GemSortFilterProxyModel::GetGemActiveString(GemSortFilterProxyModel::GemActive::Inactive));
elementCounts.push_back(totalGems - enabledGemTotal);
bool wasCollapsed = false;
if (m_statusFilter)
{
@@ -262,44 +263,51 @@ namespace O3DE::ProjectManager
const QList<QAbstractButton*> buttons = m_statusFilter->GetButtonGroup()->buttons();
QAbstractButton* unselectedButton = buttons[0];
QAbstractButton* selectedButton = buttons[1];
unselectedButton->setChecked(m_filterProxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Unselected);
selectedButton->setChecked(m_filterProxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Selected);
QAbstractButton* selectedButton = buttons[0];
QAbstractButton* unselectedButton = buttons[1];
selectedButton->setChecked(m_filterProxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Selected);
unselectedButton->setChecked(m_filterProxyModel->GetGemSelected() == GemSortFilterProxyModel::GemSelected::Unselected);
auto updateGemSelection = [=]([[maybe_unused]] bool checked)
{
if (unselectedButton->isChecked() && !selectedButton->isChecked())
{
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Unselected);
}
else if (!unselectedButton->isChecked() && selectedButton->isChecked())
if (!unselectedButton->isChecked() && selectedButton->isChecked())
{
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Selected);
}
else if (unselectedButton->isChecked() && !selectedButton->isChecked())
{
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Unselected);
}
else
{
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::NoFilter);
if (unselectedButton->isChecked() && selectedButton->isChecked())
{
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::Both);
}
else
{
m_filterProxyModel->SetGemSelected(GemSortFilterProxyModel::GemSelected::NoFilter);
}
}
};
connect(unselectedButton, &QAbstractButton::toggled, this, updateGemSelection);
connect(selectedButton, &QAbstractButton::toggled, this, updateGemSelection);
QAbstractButton* inactiveButton = buttons[2];
QAbstractButton* activeButton = buttons[3];
inactiveButton->setChecked(m_filterProxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Inactive);
activeButton->setChecked(m_filterProxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Active);
QAbstractButton* activeButton = buttons[2];
QAbstractButton* inactiveButton = buttons[3];
activeButton->setChecked(m_filterProxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Active);
inactiveButton->setChecked(m_filterProxyModel->GetGemActive() == GemSortFilterProxyModel::GemActive::Inactive);
auto updateGemActive = [=]([[maybe_unused]] bool checked)
{
if (inactiveButton->isChecked() && !activeButton->isChecked())
{
m_filterProxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Inactive);
}
else if (!inactiveButton->isChecked() && activeButton->isChecked())
if (!inactiveButton->isChecked() && activeButton->isChecked())
{
m_filterProxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Active);
}
else if (inactiveButton->isChecked() && !activeButton->isChecked())
{
m_filterProxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::Inactive);
}
else
{
m_filterProxyModel->SetGemActive(GemSortFilterProxyModel::GemActive::NoFilter);
@@ -50,11 +50,26 @@ namespace O3DE::ProjectManager
}
}
// Gem selected
if (m_gemSelectedFilter != GemSelected::NoFilter)
// Gem selected
if (m_gemSelectedFilter == GemSelected::Selected)
{
const GemSelected sourceGemStatus = static_cast<GemSelected>(GemModel::IsAdded(sourceIndex));
if (m_gemSelectedFilter != sourceGemStatus)
if (!GemModel::NeedsToBeAdded(sourceIndex, true))
{
return false;
}
}
// Gem unselected
else if (m_gemSelectedFilter == GemSelected::Unselected)
{
if (!GemModel::NeedsToBeRemoved(sourceIndex, true))
{
return false;
}
}
// Gem selected or unselected
else if (m_gemSelectedFilter == GemSelected::Both)
{
if (!GemModel::NeedsToBeAdded(sourceIndex, true) && !GemModel::NeedsToBeRemoved(sourceIndex, true))
{
return false;
}
@@ -29,7 +29,8 @@ namespace O3DE::ProjectManager
{
NoFilter = -1,
Unselected,
Selected
Selected,
Both
};
enum class GemActive
{
@@ -27,6 +27,7 @@ namespace O3DE::ProjectManager
QVBoxLayout* vLayout = new QVBoxLayout();
vLayout->setContentsMargins(30, 30, 25, 10);
vLayout->setSpacing(0);
vLayout->setAlignment(Qt::AlignTop);
setLayout(vLayout);
QLabel* instructionTitleLabel = new QLabel(tr("Enter a valid path to add a new user repository"));
@@ -41,9 +42,18 @@ namespace O3DE::ProjectManager
vLayout->addWidget(instructionContextLabel);
m_repoPath = new FormFolderBrowseEditWidget(tr("Repository Path"), "", this);
m_repoPath->setFixedWidth(600);
m_repoPath->setFixedSize(QSize(600, 100));
vLayout->addWidget(m_repoPath);
vLayout->addSpacing(10);
QLabel* warningLabel = new QLabel(tr("Online repositories may contain files that could potentially harm your computer,"
" please ensure you understand the risks before downloading Gems from third-party sources."));
warningLabel->setObjectName("gemRepoAddDialogWarningLabel");
warningLabel->setWordWrap(true);
warningLabel->setAlignment(Qt::AlignLeft);
vLayout->addWidget(warningLabel);
vLayout->addSpacing(40);
QDialogButtonBox* dialogButtons = new QDialogButtonBox();
@@ -133,6 +133,11 @@ namespace O3DE::ProjectManager
return true;
}
else
{
// If we are already on this screen still notify we are on this screen to refresh it
newScreen->NotifyCurrentScreen();
}
}
return false;
@@ -108,7 +108,7 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallWithoutClientSe
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
WaitForProcessFinish([&](){ return matchmakingHandlerMock.m_numMatchError == 1; });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
@@ -122,7 +122,7 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_MultipleCallsWithou
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
WaitForProcessFinish([&](){ return matchmakingHandlerMock.m_numMatchError == 1; });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
@@ -140,7 +140,7 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallButWithFailedOu
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
WaitForProcessFinish([&](){ return matchmakingHandlerMock.m_numMatchError == 1; });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
@@ -160,7 +160,7 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallWithMoreThanOne
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
WaitForProcessFinish([&](){ return matchmakingHandlerMock.m_numMatchError == 1; });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
@@ -23,6 +23,7 @@
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <CommonFiles/Preprocessor.h>
#include <CommonFiles/GlobalBuildOptions.h>
@@ -91,19 +92,31 @@ namespace AZ
m_shaderAssetBuilder.BusConnect(shaderAssetBuilderDescriptor.m_busId);
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderAssetBuilderDescriptor);
// Register Shader Variant Asset Builder
AssetBuilderSDK::AssetBuilderDesc shaderVariantAssetBuilderDescriptor;
shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
// Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
// ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
shaderVariantAssetBuilderDescriptor.m_version = 26; // [AZSL] Changing inlineConstant to rootConstant keyword work.
shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
shaderVariantAssetBuilderDescriptor.m_processJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::ProcessJob, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
// If, either the SettingsRegistry doesn't exist, or the property @EnableShaderVariantAssetBuilderRegistryKey is not found,
// the default is to enable the ShaderVariantAssetBuilder.
m_enableShaderVariantAssetBuilder = true;
auto settingsRegistry = AZ::SettingsRegistry::Get();
if (settingsRegistry)
{
settingsRegistry->Get(m_enableShaderVariantAssetBuilder, EnableShaderVariantAssetBuilderRegistryKey);
}
m_shaderVariantAssetBuilder.BusConnect(shaderVariantAssetBuilderDescriptor.m_busId);
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderVariantAssetBuilderDescriptor);
if (m_enableShaderVariantAssetBuilder)
{
// Register Shader Variant Asset Builder
AssetBuilderSDK::AssetBuilderDesc shaderVariantAssetBuilderDescriptor;
shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder";
// Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update
// ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder".
shaderVariantAssetBuilderDescriptor.m_version = 26; // [AZSL] Changing inlineConstant to rootConstant keyword work.
shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid<ShaderVariantAssetBuilder>();
shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
shaderVariantAssetBuilderDescriptor.m_processJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::ProcessJob, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2);
m_shaderVariantAssetBuilder.BusConnect(shaderVariantAssetBuilderDescriptor.m_busId);
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBus::Handler::RegisterBuilderInformation, shaderVariantAssetBuilderDescriptor);
}
// Register Precompiled Shader Builder
AssetBuilderSDK::AssetBuilderDesc precompiledShaderBuilderDescriptor;
@@ -121,7 +134,10 @@ namespace AZ
void AzslShaderBuilderSystemComponent::Deactivate()
{
m_shaderAssetBuilder.BusDisconnect();
m_shaderVariantAssetBuilder.BusDisconnect();
if (m_enableShaderVariantAssetBuilder)
{
m_shaderVariantAssetBuilder.BusDisconnect();
}
m_precompiledShaderBuilder.BusDisconnect();
RHI::ShaderPlatformInterfaceRegisterBus::Handler::BusDisconnect();
@@ -61,7 +61,17 @@ namespace AZ
private:
ShaderAssetBuilder m_shaderAssetBuilder;
// The ShaderVariantAssetBuilder can be disabled with this registry key.
// By default it is enabled. A user might want to disable it when doing look development
// work with shaders or doing lots of iterative changes to shaders. In these cases
// GPU performance doesn't matter at all so it is important to not waste time
// building ShaderVariantAssets (Other than the Root ShaderVariantAsset, of course.).
static constexpr char EnableShaderVariantAssetBuilderRegistryKey[] = "/O3DE/Atom/Shaders/BuildVariants";
bool m_enableShaderVariantAssetBuilder = true;
ShaderVariantAssetBuilder m_shaderVariantAssetBuilder;
PrecompiledShaderBuilder m_precompiledShaderBuilder;
/// Contains the ShaderPlatformInterface for all registered RHIs
@@ -477,8 +477,8 @@ namespace AZ
preprocessorOptions.m_predefinedMacros.end(), macroDefinitionsToAdd.begin(), macroDefinitionsToAdd.end());
// Run the preprocessor.
PreprocessorData output;
PreprocessFile(prependedAzslFilePath, output, preprocessorOptions, true, true);
RHI::ReportErrorMessages(ShaderAssetBuilderName, output.diagnostics);
const bool preprocessorSuccess = PreprocessFile(prependedAzslFilePath, output, preprocessorOptions, true, true);
RHI::ReportMessages(ShaderAssetBuilderName, output.diagnostics, !preprocessorSuccess);
// Dump the preprocessed string as a flat AZSL file with extension .azslin, which will be given to AZSLc to generate the HLSL file.
AZStd::string superVariantAzslinStemName = shaderFileName;
if (!supervariantInfo.m_name.IsEmpty())
@@ -0,0 +1,10 @@
{
"O3DE": {
"Atom": {
"Shaders": {
"BuildVariants": true
}
}
}
}
}
@@ -14,6 +14,7 @@
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Components/TransformComponent.h>
@@ -115,7 +116,9 @@ namespace AZ
{
// GFX TODO - investigate window creation being part of the GameApplication.
m_nativeWindow = AZStd::make_unique<AzFramework::NativeWindow>("O3DELauncher", AzFramework::WindowGeometry(0, 0, 1920, 1080));
auto projectTitle = AZ::Utils::GetProjectName();
m_nativeWindow = AZStd::make_unique<AzFramework::NativeWindow>(projectTitle.c_str(), AzFramework::WindowGeometry(0, 0, 1920, 1080));
AZ_Assert(m_nativeWindow, "Failed to create the game window\n");
m_nativeWindow->Activate();
@@ -1,6 +1,14 @@
{
"description": "Material Type with properties used to define Enhanced PBR, a metallic-roughness Physically-Based Rendering (PBR) material shading model, with advanced features like subsurface scattering, transmission, and anisotropy.",
"version": 3,
"version": 4,
"versionUpdates": [
{
"toVersion": 4,
"actions": [
{"op": "rename", "from": "opacity.doubleSided", "to": "general.doubleSided"}
]
}
],
"propertyLayout": {
"groups": [
{
@@ -92,6 +100,12 @@
],
"properties": {
"general": [
{
"name": "doubleSided",
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"name": "applySpecularAA",
"displayName": "Apply Specular AA",
@@ -709,12 +723,6 @@
"name": "m_opacityFactor"
}
},
{
"name": "doubleSided",
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"name": "alphaAffectsSpecular",
"displayName": "Alpha affects specular",
@@ -1,6 +1,14 @@
{
"description": "Material Type with properties used to define Standard PBR, a metallic-roughness Physically-Based Rendering (PBR) material shading model.",
"version": 3,
"version": 4,
"versionUpdates": [
{
"toVersion": 4,
"actions": [
{"op": "rename", "from": "opacity.doubleSided", "to": "general.doubleSided"}
]
}
],
"propertyLayout": {
"groups": [
{
@@ -72,6 +80,12 @@
],
"properties": {
"general": [
{
"name": "doubleSided",
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"name": "applySpecularAA",
"displayName": "Apply Specular AA",
@@ -650,12 +664,6 @@
"name": "m_opacityFactor"
}
},
{
"name": "doubleSided",
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"name": "alphaAffectsSpecular",
"displayName": "Alpha affects specular",
@@ -10,14 +10,14 @@
----------------------------------------------------------------------------------------------------
function GetMaterialPropertyDependencies()
return {"opacity.doubleSided"}
return {"general.doubleSided"}
end
ForwardPassIndex = 0
ForwardPassEdsIndex = 1
function Process(context)
local doubleSided = context:GetMaterialPropertyValue_bool("opacity.doubleSided")
local doubleSided = context:GetMaterialPropertyValue_bool("general.doubleSided")
local lastShader = context:GetShaderCount() - 1;
if(doubleSided) then
@@ -81,7 +81,6 @@ function ProcessEditor(context)
context:SetMaterialPropertyVisibility("opacity.textureMap", mainVisibility)
context:SetMaterialPropertyVisibility("opacity.textureMapUv", mainVisibility)
context:SetMaterialPropertyVisibility("opacity.factor", mainVisibility)
context:SetMaterialPropertyVisibility("opacity.doubleSided", mainVisibility)
if(opacityMode == OpacityMode_Blended or opacityMode == OpacityMode_TintedTransparent) then
context:SetMaterialPropertyVisibility("opacity.alphaAffectsSpecular", MaterialPropertyVisibility_Enabled)
@@ -23,8 +23,8 @@
"DrawList" : "forward",
"CompilerHints" : {
"DxcDisableOptimizations" : false,
"DxcGenerateDebugInfo" : false
"DisableOptimizations" : false,
"GenerateDebugInfo" : false
},
"ProgramSettings":
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:57d6744696768f9fb8a5fe5fee9aa36fee1eb87a9dbc1e60d4a35ed3c39d68e6
size 810620
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:513f47f6fea5105f603170a8881b7e3b1cd2c4258636d64a6399c725032b500d
size 38689
@@ -5,12 +5,3 @@
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
if(LY_MONOLITHIC_GAME) # Do not use OpenImageIO in monolithic game
return()
endif()
set(LY_BUILD_DEPENDENCIES
PRIVATE
3rdParty::ilmbase
)
@@ -57,12 +57,19 @@ namespace AZ
AZStd::string m_azslcAdditionalFreeArguments;
// note: if you add new sort of arguments here, don't forget to update HasDifferentAzslcArguments()
//! DXC
bool m_dxcDisableWarnings = false;
bool m_dxcWarningAsError = false;
bool m_dxcDisableOptimizations = false;
bool m_dxcGenerateDebugInfo = false;
uint8_t m_dxcOptimizationLevel = LevelUnset;
//! Remark: To the user, the following parameters are exposed without the
//! "Dxc" prefix because these are common options for the "main" compiler
//! for the given RHI. At the moment the only "main" compiler is Dxc, but in
//! the future AZSLc may transpile from AZSL to some other proprietary language
//! and in that case the "main" compiler won't be DXC
bool m_disableWarnings = false;
bool m_warningAsError = false;
bool m_disableOptimizations = false;
bool m_generateDebugInfo = false;
uint8_t m_optimizationLevel = LevelUnset;
//! "DxcAdditionalFreeArguments" keeps the "Dxc" prefix because these arguments
//! are specific to DXC, and it will be relevant only if DXC is the "main" compiler
//! for a given RHI, otherwise this parameter won't matter.
AZStd::string m_dxcAdditionalFreeArguments;
//! both
@@ -83,11 +83,12 @@ namespace AZ
const AZStd::string& shaderSourcePathForDebug,
const char* toolNameForLog);
//! Reports error messages to AZ_Error and/or AZ_Warning, given a text blob that potentially contains many lines of errors and warnings.
//! @param window Debug window name used for AZ Trace functions
//! @param errorMessages String that may contain many lines of errors and warnings
//! @param return true if Errors were detected and reported (Warnings don't count)
bool ReportErrorMessages(AZStd::string_view window, AZStd::string_view errorMessages);
//! Reports messages with AZ_Error or AZ_Warning (See @reportAsErrors).
//! @param window Debug window name used for AZ Trace functions.
//! @param errorMessages Message string.
//! @param reportAsErrors If true, messages are traced with AZ_Error, otherwise AZ_Warning is used.
//! @returns true If the input text blob contains at least one line with the "error" string.
bool ReportMessages(AZStd::string_view window, AZStd::string_view errorMessages, bool reportAsErrors);
//! Converts from a RHI::ShaderHardwareStage to an RHI::ShaderStage
ShaderStage ToRHIShaderStage(ShaderHardwareStage stageType);
@@ -33,17 +33,17 @@ namespace AZ
RegisterEnumerators<MatrixOrder>(serializeContext);
serializeContext->Class<ShaderCompilerArguments>()
->Version(2)
->Version(3)
->Field("AzslcWarningLevel", &ShaderCompilerArguments::m_azslcWarningLevel)
->Field("AzslcWarningAsError", &ShaderCompilerArguments::m_azslcWarningAsError)
->Field("AzslcAdditionalFreeArguments", &ShaderCompilerArguments::m_azslcAdditionalFreeArguments)
->Field("DxcDisableWarnings", &ShaderCompilerArguments::m_dxcDisableWarnings)
->Field("DxcWarningAsError", &ShaderCompilerArguments::m_dxcWarningAsError)
->Field("DxcDisableOptimizations", &ShaderCompilerArguments::m_dxcDisableOptimizations)
->Field("DxcGenerateDebugInfo", &ShaderCompilerArguments::m_dxcGenerateDebugInfo)
->Field("DxcOptimizationLevel", &ShaderCompilerArguments::m_dxcOptimizationLevel)
->Field("DxcAdditionalFreeArguments", &ShaderCompilerArguments::m_dxcAdditionalFreeArguments)
->Field("DisableWarnings", &ShaderCompilerArguments::m_disableWarnings)
->Field("WarningAsError", &ShaderCompilerArguments::m_warningAsError)
->Field("DisableOptimizations", &ShaderCompilerArguments::m_disableOptimizations)
->Field("GenerateDebugInfo", &ShaderCompilerArguments::m_generateDebugInfo)
->Field("OptimizationLevel", &ShaderCompilerArguments::m_optimizationLevel)
->Field("DefaultMatrixOrder", &ShaderCompilerArguments::m_defaultMatrixOrder)
->Field("DxcAdditionalFreeArguments", &ShaderCompilerArguments::m_dxcAdditionalFreeArguments)
;
}
}
@@ -62,13 +62,13 @@ namespace AZ
}
m_azslcWarningAsError = m_azslcWarningAsError || right.m_azslcWarningAsError;
m_azslcAdditionalFreeArguments = CommandLineArgumentUtils::MergeCommandLineArguments(m_azslcAdditionalFreeArguments, right.m_azslcAdditionalFreeArguments);
m_dxcDisableWarnings = m_dxcDisableWarnings || right.m_dxcDisableWarnings;
m_dxcWarningAsError = m_dxcWarningAsError || right.m_dxcWarningAsError;
m_dxcDisableOptimizations = m_dxcDisableOptimizations || right.m_dxcDisableOptimizations;
m_dxcGenerateDebugInfo = m_dxcGenerateDebugInfo || right.m_dxcGenerateDebugInfo;
if (right.m_dxcOptimizationLevel != LevelUnset)
m_disableWarnings = m_disableWarnings || right.m_disableWarnings;
m_warningAsError = m_warningAsError || right.m_warningAsError;
m_disableOptimizations = m_disableOptimizations || right.m_disableOptimizations;
m_generateDebugInfo = m_generateDebugInfo || right.m_generateDebugInfo;
if (right.m_optimizationLevel != LevelUnset)
{
m_dxcOptimizationLevel = right.m_dxcOptimizationLevel;
m_optimizationLevel = right.m_optimizationLevel;
}
m_dxcAdditionalFreeArguments = CommandLineArgumentUtils::MergeCommandLineArguments(m_dxcAdditionalFreeArguments, right.m_dxcAdditionalFreeArguments);
if (right.m_defaultMatrixOrder != MatrixOrder::Default)
@@ -131,21 +131,21 @@ namespace AZ
AZStd::string ShaderCompilerArguments::MakeAdditionalDxcCommandLineString() const
{
AZStd::string arguments;
if (m_dxcDisableWarnings)
if (m_disableWarnings)
{
arguments += " -no-warnings";
}
else if (m_dxcWarningAsError)
else if (m_warningAsError)
{
arguments += " -WX";
}
if (m_dxcDisableOptimizations)
if (m_disableOptimizations)
{
arguments += " -Od";
}
else if (m_dxcOptimizationLevel <= 3)
else if (m_optimizationLevel <= 3)
{
arguments = " -O" + AZStd::to_string(m_dxcOptimizationLevel);
arguments = " -O" + AZStd::to_string(m_optimizationLevel);
}
if (m_defaultMatrixOrder == MatrixOrder::Column)
{
+12 -24
View File
@@ -330,7 +330,7 @@ namespace AZ
// Pump one last time to make sure the streams have been flushed
pumpOuputStreams();
const bool reportedErrors = ReportErrorMessages(toolNameForLog, errorMessages);
const bool reportedErrors = ReportMessages(toolNameForLog, errorMessages, exitCode != 0);
if (timedOut)
{
@@ -367,32 +367,20 @@ namespace AZ
return true;
}
bool ReportErrorMessages([[maybe_unused]] AZStd::string_view window, AZStd::string_view errorMessages)
bool ReportMessages([[maybe_unused]] AZStd::string_view window, AZStd::string_view errorMessages, bool reportAsErrors)
{
// There are more efficient ways to do this, but this approach is simple and gets us moving for now.
AZStd::vector<AZStd::string> lines;
AzFramework::StringFunc::Tokenize(errorMessages.data(), lines, "\n\r");
bool foundErrors = false;
for (auto& line : lines)
if (reportAsErrors)
{
if (AZStd::string::npos != AzFramework::StringFunc::Find(line, "error"))
{
AZ_Error(window.data(), false, "%s", line.data());
foundErrors = true;
}
else if (AZStd::string::npos != AzFramework::StringFunc::Find(line, "warning"))
{
AZ_Warning(window.data(), false, "%s", line.data());
}
else
{
AZ_TracePrintf(window.data(), "%s", line.data());
}
AZ_Error(window.data(), false, "%.*s", aznumeric_cast<int>(errorMessages.size()), errorMessages.data());
}
return foundErrors;
else
{
// Using AZ_Warning instead of AZ_TracePrintf because this function is commonly
// used to report messages from stderr when executing applications. Applications
// when ran successfully, only output to stderr for errors or warnings.
AZ_Warning(window.data(), false, "%.*s", aznumeric_cast<int>(errorMessages.size()), errorMessages.data());
}
return AZStd::string::npos != AzFramework::StringFunc::Find(errorMessages, "error");
}
ShaderStage ToRHIShaderStage(ShaderHardwareStage stageType)
@@ -114,7 +114,7 @@ namespace AZ
}
}
if (shaderCompilerArguments.m_dxcDisableOptimizations)
if (shaderCompilerArguments.m_disableOptimizations)
{
// When optimizations are disabled (-Od), all resources declared in the source file are available to all stages
// (when enabled only the resources which are referenced in a stage are bound to the stage)
@@ -195,7 +195,7 @@ namespace AZ
bool ShaderPlatformInterface::BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return shaderCompilerArguments.m_dxcGenerateDebugInfo;
return shaderCompilerArguments.m_generateDebugInfo;
}
const char* ShaderPlatformInterface::GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const
@@ -167,7 +167,7 @@ namespace AZ
bool ShaderPlatformInterface::BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return shaderCompilerArguments.m_dxcGenerateDebugInfo;
return shaderCompilerArguments.m_generateDebugInfo;
}
const char* ShaderPlatformInterface::GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const
@@ -109,7 +109,7 @@ namespace AZ
bool ShaderPlatformInterface::BuildHasDebugInfo(const RHI::ShaderCompilerArguments& shaderCompilerArguments) const
{
return shaderCompilerArguments.m_dxcGenerateDebugInfo;
return shaderCompilerArguments.m_generateDebugInfo;
}
const char* ShaderPlatformInterface::GetAzslHeader(const AssetBuilderSDK::PlatformInfo& platform) const
@@ -93,31 +93,28 @@ namespace AZ
// Note that the only kind of property update currently supported is rename...
PropertyGroupMap newPropertyGroups;
for (auto& groupPair : m_properties)
{
PropertyMap& propertyMap = groupPair.second;
PropertyMap newPropertyMap;
for (auto& propertyPair : propertyMap)
{
MaterialPropertyId propertyId{groupPair.first, propertyPair.first};
if (materialTypeSourceData.ApplyPropertyRenames(propertyId, m_materialTypeVersion))
{
newPropertyMap[propertyId.GetPropertyName().GetStringView()] = propertyPair.second;
changesWereApplied = true;
}
else
{
newPropertyMap[propertyPair.first] = propertyPair.second;
}
newPropertyGroups[propertyId.GetGroupName().GetStringView()][propertyId.GetPropertyName().GetStringView()] = propertyPair.second;
}
propertyMap = newPropertyMap;
}
if (changesWereApplied)
{
m_properties = AZStd::move(newPropertyGroups);
AZ_Warning("MaterialSourceData", false,
"This material is based on version '%u' of '%s', but the material type is now at version '%u'. "
"Automatic updates are available. Consider updating the .material source file.",
@@ -164,16 +164,14 @@ namespace AZ
const MaterialTypeSourceData::PropertyDefinition* MaterialTypeSourceData::FindProperty(AZStd::string_view groupName, AZStd::string_view propertyName, uint32_t materialTypeVersion) const
{
auto groupIter = m_propertyLayout.m_properties.find(groupName);
if (groupIter == m_propertyLayout.m_properties.end())
if (groupIter != m_propertyLayout.m_properties.end())
{
return nullptr;
}
for (const PropertyDefinition& property : groupIter->second)
{
if (property.m_name == propertyName)
for (const PropertyDefinition& property : groupIter->second)
{
return &property;
if (property.m_name == propertyName)
{
return &property;
}
}
}
@@ -185,16 +183,14 @@ namespace AZ
// Do the search again with the new names
groupIter = m_propertyLayout.m_properties.find(propertyId.GetGroupName().GetStringView());
if (groupIter == m_propertyLayout.m_properties.end())
if (groupIter != m_propertyLayout.m_properties.end())
{
return nullptr;
}
for (const PropertyDefinition& property : groupIter->second)
{
if (property.m_name == propertyId.GetPropertyName().GetStringView())
for (const PropertyDefinition& property : groupIter->second)
{
return &property;
if (property.m_name == propertyId.GetPropertyName().GetStringView())
{
return &property;
}
}
}
@@ -264,7 +264,6 @@ namespace AZ
{
// When rebuilding shaders we may be in a state where the ShaderAsset and root ShaderVariantAsset have been rebuilt and reloaded, but some (or all)
// shader variants haven't been built yet. Since we want to use the latest version of the shader code, ignore the old variants and fall back to the newer root variant instead.
AZ_Warning("ShaderAsset", false, "ShaderAsset and ShaderVariantAsset are out of sync; defaulting to root shader variant. (This is common while reloading shaders).");
return GetRootVariant(supervariantIndex);
}
}
@@ -105,6 +105,13 @@ namespace UnitTest
{"op": "rename", "from": "general.testColorNameB", "to": "general.testColorNameC"}
]
},
{
"toVersion": 6,
"actions": [
{"op": "rename", "from": "oldGroup.MyFloat", "to": "general.MyFloat"},
{"op": "rename", "from": "oldGroup.MyIntOldName", "to": "general.MyInt"}
]
},
{
"toVersion": 10,
"actions": [
@@ -751,6 +758,72 @@ namespace UnitTest
material.ApplyVersionUpdates();
}
TEST_F(MaterialSourceDataTests, Load_MaterialTypeVersionUpdate_MovePropertiesToAnotherGroup)
{
const AZStd::string inputJson = R"(
{
"materialType": "@exefolder@/Temp/test.materialtype",
"materialTypeVersion": 3,
"properties": {
"oldGroup": {
"MyFloat": 1.2,
"MyIntOldName": 5
}
}
}
)";
MaterialSourceData material;
JsonTestResult loadResult = LoadTestDataFromJson(material, inputJson);
EXPECT_EQ(AZ::JsonSerializationResult::Tasks::ReadField, loadResult.m_jsonResultCode.GetTask());
EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, loadResult.m_jsonResultCode.GetProcessing());
// Initially, the loaded material data will match the .material file exactly. This gives us the accurate representation of
// what's actually saved on disk.
EXPECT_NE(material.m_properties["oldGroup"].find("MyFloat"), material.m_properties["oldGroup"].end());
EXPECT_NE(material.m_properties["oldGroup"].find("MyIntOldName"), material.m_properties["oldGroup"].end());
EXPECT_EQ(material.m_properties["general"].find("MyFloat"), material.m_properties["general"].end());
EXPECT_EQ(material.m_properties["general"].find("MyInt"), material.m_properties["general"].end());
float myFloat = material.m_properties["oldGroup"]["MyFloat"].m_value.GetValue<float>();
EXPECT_EQ(myFloat, 1.2f);
int32_t myInt = material.m_properties["oldGroup"]["MyIntOldName"].m_value.GetValue<int32_t>();
EXPECT_EQ(myInt, 5);
EXPECT_EQ(3, material.m_materialTypeVersion);
// Then we force the material data to update to the latest material type version specification
ErrorMessageFinder warningFinder; // Note this finds errors and warnings, and we're looking for a warning.
warningFinder.AddExpectedErrorMessage("Automatic updates are available. Consider updating the .material source file");
warningFinder.AddExpectedErrorMessage("This material is based on version '3'");
warningFinder.AddExpectedErrorMessage("material type is now at version '10'");
material.ApplyVersionUpdates();
warningFinder.CheckExpectedErrorsFound();
// Now the material data should match the latest material type.
// Look for the property under the latest name in the material type, not the name used in the .material file.
EXPECT_EQ(material.m_properties["oldGroup"].find("MyFloat"), material.m_properties["oldGroup"].end());
EXPECT_EQ(material.m_properties["oldGroup"].find("MyIntOldName"), material.m_properties["oldGroup"].end());
EXPECT_NE(material.m_properties["general"].find("MyFloat"), material.m_properties["general"].end());
EXPECT_NE(material.m_properties["general"].find("MyInt"), material.m_properties["general"].end());
myFloat = material.m_properties["general"]["MyFloat"].m_value.GetValue<float>();
EXPECT_EQ(myFloat, 1.2f);
myInt = material.m_properties["general"]["MyInt"].m_value.GetValue<int32_t>();
EXPECT_EQ(myInt, 5);
EXPECT_EQ(10, material.m_materialTypeVersion);
// Calling ApplyVersionUpdates() again should not report the warning again, since the material has already been updated.
warningFinder.Reset();
material.ApplyVersionUpdates();
}
TEST_F(MaterialSourceDataTests, Load_MaterialTypeVersionPartialUpdate)
{
// This case is similar to Load_MaterialTypeVersionUpdate but we start at a later
@@ -1346,7 +1346,8 @@ namespace UnitTest
{
"toVersion": 7,
"actions": [
{ "op": "rename", "from": "general.bazA", "to": "otherGroup.bazB" }
{ "op": "rename", "from": "general.bazA", "to": "otherGroup.bazB" },
{ "op": "rename", "from": "onlyOneProperty.bopA", "to": "otherGroup.bopB" } // This tests a group 'onlyOneProperty' that no longer exists in the material type
]
}
],
@@ -1370,6 +1371,10 @@ namespace UnitTest
{
"name": "bazB",
"type": "Float"
},
{
"name": "bopB",
"type": "Float"
}
]
}
@@ -1386,13 +1391,16 @@ namespace UnitTest
const MaterialTypeSourceData::PropertyDefinition* foo = materialType.FindProperty("general", "fooC");
const MaterialTypeSourceData::PropertyDefinition* bar = materialType.FindProperty("general", "barC");
const MaterialTypeSourceData::PropertyDefinition* baz = materialType.FindProperty("otherGroup", "bazB");
const MaterialTypeSourceData::PropertyDefinition* bop = materialType.FindProperty("otherGroup", "bopB");
EXPECT_TRUE(foo);
EXPECT_TRUE(bar);
EXPECT_TRUE(baz);
EXPECT_TRUE(bop);
EXPECT_EQ(foo->m_name, "fooC");
EXPECT_EQ(bar->m_name, "barC");
EXPECT_EQ(baz->m_name, "bazB");
EXPECT_EQ(bop->m_name, "bopB");
// Now try doing the property lookup using old versions of the name and make sure the same property can be found
@@ -1401,12 +1409,15 @@ namespace UnitTest
EXPECT_EQ(bar, materialType.FindProperty("general", "barA"));
EXPECT_EQ(bar, materialType.FindProperty("general", "barB"));
EXPECT_EQ(baz, materialType.FindProperty("general", "bazA"));
EXPECT_EQ(bop, materialType.FindProperty("onlyOneProperty", "bopA"));
EXPECT_EQ(nullptr, materialType.FindProperty("general", "fooX"));
EXPECT_EQ(nullptr, materialType.FindProperty("general", "barX"));
EXPECT_EQ(nullptr, materialType.FindProperty("general", "bazX"));
EXPECT_EQ(nullptr, materialType.FindProperty("general", "bazB"));
EXPECT_EQ(nullptr, materialType.FindProperty("otherGroup", "bazA"));
EXPECT_EQ(nullptr, materialType.FindProperty("onlyOneProperty", "bopB"));
EXPECT_EQ(nullptr, materialType.FindProperty("otherGroup", "bopA"));
}
TEST_F(MaterialTypeSourceDataTests, FindPropertyUsingOldName_Error_UnsupportedVersionUpdate)
@@ -0,0 +1,14 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"textureMap": "Textures/Default/checker_uv_basecolor.png"
},
"general": {
"doubleSided": true
}
}
}
@@ -24,7 +24,7 @@
},
"CompilerHints" : {
"DxcDisableOptimizations" : false
"DisableOptimizations" : false
},
"ProgramSettings":
@@ -24,7 +24,7 @@
},
"CompilerHints" : {
"DxcDisableOptimizations" : false
"DisableOptimizations" : false
},
"ProgramSettings":
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b2ecc32cd3052f3cb5836c8be7bf5cba54d98f46e6a0eeac95aaef00a123411a
size 27340
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:93a7e033d9fb0fcac221647322bde03716643d789390f79078c4fcc37ecfd005
size 68327
oid sha256:513f47f6fea5105f603170a8881b7e3b1cd2c4258636d64a6399c725032b500d
size 38689
@@ -86,6 +86,8 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
FILES_CMAKE
atomlyintegration_commonfeatures_editor_files.cmake
${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
PLATFORM_INCLUDE_FILES
${pal_source_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
@@ -0,0 +1,7 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
@@ -0,0 +1,8 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
@@ -0,0 +1,7 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
@@ -0,0 +1,7 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
@@ -0,0 +1,13 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
if(NOT LY_MONOLITHIC_GAME) # Do not use OpenImageIO in monolithic game
set(LY_RUNTIME_DEPENDENCIES
3rdParty::OpenImageIO
)
endif()
@@ -0,0 +1,7 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
@@ -739,14 +739,32 @@ void ViewportInteraction::MouseWheelEvent(QWheelEvent* ev)
bool ViewportInteraction::KeyPressEvent(QKeyEvent* ev)
{
if (ev->key() == Qt::Key_Space)
switch (ev->key())
{
case Qt::Key_Space:
if (!ev->isAutoRepeat())
{
ActivateSpaceBar();
}
return true;
case Qt::Key_Up:
Nudge(ViewportInteraction::NudgeDirection::Up,
(ev->modifiers() & Qt::ShiftModifier) ? ViewportInteraction::NudgeSpeed::Fast : ViewportInteraction::NudgeSpeed::Slow);
return true;
case Qt::Key_Down:
Nudge(ViewportInteraction::NudgeDirection::Down,
(ev->modifiers() & Qt::ShiftModifier) ? ViewportInteraction::NudgeSpeed::Fast : ViewportInteraction::NudgeSpeed::Slow);
return true;
case Qt::Key_Left:
Nudge(ViewportInteraction::NudgeDirection::Left,
(ev->modifiers() & Qt::ShiftModifier) ? ViewportInteraction::NudgeSpeed::Fast : ViewportInteraction::NudgeSpeed::Slow);
return true;
case Qt::Key_Right:
Nudge(ViewportInteraction::NudgeDirection::Right,
(ev->modifiers() & Qt::ShiftModifier) ? ViewportInteraction::NudgeSpeed::Fast : ViewportInteraction::NudgeSpeed::Slow);
return true;
default:
break;
}
return false;
+30 -129
View File
@@ -220,6 +220,7 @@ ViewportWidget::ViewportWidget(EditorWindow* parent)
InitUiRenderer();
SetupShortcuts();
installEventFilter(m_editorWindow);
// Setup a timer for the maximum refresh rate we want.
// Refresh is actually triggered by interaction events and by the IdleUpdate. This avoids the UI
@@ -258,6 +259,8 @@ ViewportWidget::~ViewportWidget()
LyShinePassDataRequestBus::Handler::BusDisconnect();
AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect();
removeEventFilter(m_editorWindow);
m_uiRenderer.reset();
// Notify LyShine that this is no longer a valid UiRenderer.
@@ -688,9 +691,9 @@ void ViewportWidget::wheelEvent(QWheelEvent* ev)
Refresh();
}
bool ViewportWidget::event(QEvent* ev)
bool ViewportWidget::eventFilter([[maybe_unused]] QObject* watched, QEvent* event)
{
if (ev->type() == QEvent::ShortcutOverride)
if (event->type() == QEvent::ShortcutOverride)
{
// When a shortcut is matched, Qt's event processing sends out a shortcut override event
// to allow other systems to override it. If it's not overridden, then the key events
@@ -698,40 +701,48 @@ bool ViewportWidget::event(QEvent* ev)
// handler. In our case this causes a problem in preview mode for the Key_Delete event.
// So, if we are preview mode avoid treating Key_Delete as a shortcut.
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(ev);
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
int key = keyEvent->key();
// Override the space bar shortcut so that the key gets handled by the viewport's KeyPress/KeyRelease
// events when the viewport has the focus. The space bar is set up as a shortcut in order to give the
// viewport the focus and activate the space bar when another widget has the focus. Once the shortcut
// is pressed and focus is given to the viewport, the viewport takes over handling the space bar via
// the KeyPress/KeyRelease events
if (key == Qt::Key_Space)
// the KeyPress/KeyRelease events.
// Also ignore nudge shortcuts in edit/preview mode so that the KeyPressEvent will be sent.
switch (key)
{
ev->accept();
case Qt::Key_Space:
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Left:
case Qt::Key_Right:
{
event->accept();
return true;
}
default:
{
break;
}
}
UiEditorMode editorMode = m_editorWindow->GetEditorMode();
if (editorMode == UiEditorMode::Preview)
{
switch (key)
if (key == Qt::Key_Delete)
{
case Qt::Key_Delete:
// Ignore nudge shortcuts in preview mode so that the KeyPressEvent will be sent
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Left:
case Qt::Key_Right:
{
ev->accept();
event->accept();
return true;
}
break;
};
}
}
return false;
}
bool ViewportWidget::event(QEvent* ev)
{
bool result = RenderViewportWidget::event(ev);
return result;
}
@@ -742,8 +753,7 @@ void ViewportWidget::keyPressEvent(QKeyEvent* event)
if (editorMode == UiEditorMode::Edit)
{
// in Edit mode just send input to ViewportInteraction
bool handled = m_viewportInteraction->KeyPressEvent(event);
if (!handled)
if (!m_viewportInteraction->KeyPressEvent(event))
{
RenderViewportWidget::keyPressEvent(event);
}
@@ -1246,115 +1256,6 @@ void ViewportWidget::SetupShortcuts()
{
// Actions with shortcuts are created instead of direct shortcuts because the shortcut dispatcher only looks for matching actions
// Create nudge shortcuts that are active across the entire UI Editor window. Any widgets (such as the spin box widget) that
// handle the same keys and want the shortcut to be ignored need to handle that with a shortcut override event.
// In preview mode, the nudge shortcuts are ignored via the shortcut override event. KeyPressEvents are sent instead,
// and passed along to the canvas
// Nudge up
{
QAction* action = new QAction("Up", this);
action->setShortcut(QKeySequence(Qt::Key_Up));
QObject::connect(action,
&QAction::triggered,
[this]()
{
m_viewportInteraction->Nudge(ViewportInteraction::NudgeDirection::Up, ViewportInteraction::NudgeSpeed::Slow);
});
addAction(action);
}
// Nudge up fast
{
QAction* action = new QAction("Up Fast", this);
action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Up));
QObject::connect(action,
&QAction::triggered,
[this]()
{
m_viewportInteraction->Nudge(ViewportInteraction::NudgeDirection::Up, ViewportInteraction::NudgeSpeed::Fast);
});
addAction(action);
}
// Nudge down
{
QAction* action = new QAction("Down", this);
action->setShortcut(QKeySequence(Qt::Key_Down));
QObject::connect(action,
&QAction::triggered,
[this]()
{
m_viewportInteraction->Nudge(ViewportInteraction::NudgeDirection::Down, ViewportInteraction::NudgeSpeed::Slow);
});
addAction(action);
}
// Nudge down fast
{
QAction* action = new QAction("Down Fast", this);
action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Down));
QObject::connect(action,
&QAction::triggered,
[this]()
{
m_viewportInteraction->Nudge(ViewportInteraction::NudgeDirection::Down, ViewportInteraction::NudgeSpeed::Fast);
});
addAction(action);
}
// Nudge left
{
QAction* action = new QAction("Left", this);
action->setShortcut(QKeySequence(Qt::Key_Left));
QObject::connect(action,
&QAction::triggered,
[this]()
{
m_viewportInteraction->Nudge(ViewportInteraction::NudgeDirection::Left, ViewportInteraction::NudgeSpeed::Slow);
});
addAction(action);
}
// Nudge left fast
{
QAction* action = new QAction("Left Fast", this);
action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Left));
QObject::connect(action,
&QAction::triggered,
[this]()
{
m_viewportInteraction->Nudge(ViewportInteraction::NudgeDirection::Left, ViewportInteraction::NudgeSpeed::Fast);
});
addAction(action);
}
// Nudge right
{
QAction* action = new QAction("Right", this);
action->setShortcut(QKeySequence(Qt::Key_Right));
QObject::connect(action,
&QAction::triggered,
[this]()
{
m_viewportInteraction->Nudge(ViewportInteraction::NudgeDirection::Right, ViewportInteraction::NudgeSpeed::Slow);
});
addAction(action);
}
// Nudge right fast
{
QAction* action = new QAction("Right Fast", this);
action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Right));
QObject::connect(action,
&QAction::triggered,
[this]()
{
m_viewportInteraction->Nudge(ViewportInteraction::NudgeDirection::Right, ViewportInteraction::NudgeSpeed::Fast);
});
addAction(action);
}
// Give the viewport focus and activate the space bar
{
QAction* action = new QAction("Viewport Focus", this);
+5 -2
View File
@@ -122,12 +122,15 @@ protected:
void wheelEvent(QWheelEvent* ev) override;
//! Prevents shortcuts from interfering with preview mode.
bool eventFilter(QObject* watched, QEvent* event) override;
//! Handle events from Qt.
bool event(QEvent* ev) override;
//! Key press event from Qt
//! Key press event from Qt.
void keyPressEvent(QKeyEvent* event) override;
//! Key release event from Qt
//! Key release event from Qt.
void keyReleaseEvent(QKeyEvent* event) override;
void focusOutEvent(QFocusEvent* ev) override;
@@ -348,19 +348,7 @@ namespace PhysX
LmbrCentral::BoxShapeComponentRequestsBus::EventResult(boxDimensions, GetEntityId(),
&LmbrCentral::BoxShapeComponentRequests::GetBoxDimensions);
if (m_shapeType != ShapeType::Box)
{
m_shapeConfigs.clear();
m_shapeConfigs.emplace_back(AZStd::make_shared<Physics::BoxShapeConfiguration>(boxDimensions));
m_shapeType = ShapeType::Box;
}
else
{
Physics::BoxShapeConfiguration& configuration =
static_cast<Physics::BoxShapeConfiguration&>(*m_shapeConfigs.back());
configuration = Physics::BoxShapeConfiguration(boxDimensions);
}
SetShapeConfig(ShapeType::Box, Physics::BoxShapeConfiguration(boxDimensions));
m_shapeConfigs.back()->m_scale = scale;
m_geometryCache.m_boxDimensions = scale * boxDimensions;
@@ -374,19 +362,7 @@ namespace PhysX
const Physics::CapsuleShapeConfiguration& capsuleShapeConfig =
Utils::ConvertFromLmbrCentralCapsuleConfig(lmbrCentralCapsuleShapeConfig);
if (m_shapeType != ShapeType::Capsule)
{
m_shapeConfigs.clear();
m_shapeConfigs.emplace_back(AZStd::make_shared<Physics::CapsuleShapeConfiguration>(capsuleShapeConfig));
m_shapeType = ShapeType::Capsule;
}
else
{
Physics::CapsuleShapeConfiguration& configuration =
static_cast<Physics::CapsuleShapeConfiguration&>(*m_shapeConfigs.back());
configuration = capsuleShapeConfig;
}
SetShapeConfig(ShapeType::Capsule, capsuleShapeConfig);
m_shapeConfigs.back()->m_scale = scale;
const float scalarScale = scale.GetMaxElement();
@@ -400,19 +376,7 @@ namespace PhysX
LmbrCentral::SphereShapeComponentRequestsBus::EventResult(radius, GetEntityId(),
&LmbrCentral::SphereShapeComponentRequests::GetRadius);
if (m_shapeType != ShapeType::Sphere)
{
m_shapeConfigs.clear();
m_shapeConfigs.emplace_back(AZStd::make_shared<Physics::SphereShapeConfiguration>(radius));
m_shapeType = ShapeType::Sphere;
}
else
{
Physics::SphereShapeConfiguration& configuration =
static_cast<Physics::SphereShapeConfiguration&>(*m_shapeConfigs.back());
configuration = Physics::SphereShapeConfiguration(radius);
}
SetShapeConfig(ShapeType::Sphere, Physics::SphereShapeConfiguration(radius));
m_shapeConfigs.back()->m_scale = scale;
m_geometryCache.m_radius = scale.GetMaxElement() * radius;
@@ -455,19 +419,7 @@ namespace PhysX
if (shapeConfig.has_value())
{
if (m_shapeType != ShapeType::Cylinder)
{
m_shapeConfigs.clear();
m_shapeConfigs.push_back(AZStd::make_shared<Physics::CookedMeshShapeConfiguration>(shapeConfig.value()));
m_shapeType = ShapeType::Cylinder;
}
else
{
Physics::CookedMeshShapeConfiguration& configuration =
static_cast<Physics::CookedMeshShapeConfiguration&>(*m_shapeConfigs.back());
configuration = Physics::CookedMeshShapeConfiguration(shapeConfig.value());
}
SetShapeConfig(ShapeType::Cylinder, shapeConfig.value());
CreateStaticEditorCollider();
}
@@ -8,6 +8,7 @@
#pragma once
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Component/NonUniformScaleBus.h>
#include <AzFramework/Physics/Shape.h>
@@ -90,12 +91,15 @@ namespace PhysX
void UpdateBoxConfig(const AZ::Vector3& scale);
void UpdateCapsuleConfig(const AZ::Vector3& scale);
void UpdateSphereConfig(const AZ::Vector3& scale);
void UpdateCylinderConfig(const AZ::Vector3& scale);
void UpdatePolygonPrismDecomposition();
void UpdatePolygonPrismDecomposition(const AZ::PolygonPrismPtr polygonPrismPtr);
void RefreshUiProperties();
// Helper function to set a specific shape configuration
template<typename ConfigType>
void SetShapeConfig(ShapeType shapeType, const ConfigType& shapeConfig);
void UpdateCylinderConfig(const AZ::Vector3& scale);
void RefreshUiProperties();
AZ::u32 OnSubdivisionCountChange();
AZ::Crc32 SubdivisionCountVisibility();
@@ -154,4 +158,28 @@ namespace PhysX
AZ::NonUniformScaleChangedEvent::Handler m_nonUniformScaleChangedHandler; //!< Responds to changes in non-uniform scale.
AZ::Vector3 m_currentNonUniformScale = AZ::Vector3::CreateOne(); //!< Caches the current non-uniform scale.
};
template<typename ConfigType>
void EditorShapeColliderComponent::SetShapeConfig(ShapeType shapeType, const ConfigType& shapeConfig)
{
if (m_shapeType != shapeType)
{
m_shapeConfigs.clear();
m_shapeType = shapeType;
}
if (m_shapeConfigs.empty())
{
m_shapeConfigs.emplace_back(AZStd::make_shared<ConfigType>(shapeConfig));
}
else
{
AZ_Assert(m_shapeConfigs.back()->GetShapeType() == shapeConfig.GetShapeType(),
"Expected Physics shape configuration with shape type %d but found one with shape type %d.",
static_cast<int>(shapeConfig.GetShapeType()), static_cast<int>(m_shapeConfigs.back()->GetShapeType()));
ConfigType& configuration =
static_cast<ConfigType&>(*m_shapeConfigs.back());
configuration = shapeConfig;
}
}
} // namespace PhysX
+1 -1
View File
@@ -102,7 +102,7 @@ namespace PhysX
const float scaleFactor = (maxHeightBounds <= minHeightBounds) ? 1.0f : AZStd::numeric_limits<int16_t>::max() / halfBounds;
const float heightScale{ 1.0f / scaleFactor };
const uint8_t physxMaximumMaterialIndex = 0x7f;
[[maybe_unused]] const uint8_t physxMaximumMaterialIndex = 0x7f;
// Delete the cached heightfield object if it is there, and create a new one and save in the shape configuration
heightfieldConfig.SetCachedNativeHeightfield(nullptr);
@@ -320,7 +320,7 @@ namespace PhysXEditorTests
TEST_F(PhysXEditorFixture, EditorShapeColliderComponent_ShapeColliderWithCylinderWithNullHeight_HandledGracefully)
{
ValidateInvalidEditorShapeColliderComponentParams(0.f, 1.f);
ValidateInvalidEditorShapeColliderComponentParams(1.f, 0.f);
}
TEST_F(PhysXEditorFixture, EditorShapeColliderComponent_ShapeColliderWithCylinderWithNullRadiusAndNullHeight_HandledGracefully)
@@ -338,6 +338,44 @@ namespace PhysXEditorTests
ValidateInvalidEditorShapeColliderComponentParams(0.f, -1.f);
}
TEST_F(PhysXEditorFixture, EditorShapeColliderComponent_ShapeColliderWithCylinderSwitchingFromNullHeightToValidHeight_HandledGracefully)
{
// create an editor entity with a shape collider component and a cylinder shape component
EntityPtr editorEntity = CreateInactiveEditorEntity("ShapeColliderComponentEditorEntity");
editorEntity->CreateComponent<PhysX::EditorShapeColliderComponent>();
editorEntity->CreateComponent(LmbrCentral::EditorCylinderShapeComponentTypeId);
editorEntity->Activate();
const float validRadius = 1.0f;
const float nullHeight = 0.0f;
const float validHeight = 1.0f;
LmbrCentral::CylinderShapeComponentRequestsBus::Event(editorEntity->GetId(),
&LmbrCentral::CylinderShapeComponentRequests::SetRadius, validRadius);
{
UnitTest::ErrorHandler dimensionWarningHandler("Negative or zero cylinder dimensions are invalid");
UnitTest::ErrorHandler colliderWarningHandler("No Collider or Shape information found when creating Rigid body");
LmbrCentral::CylinderShapeComponentRequestsBus::Event(editorEntity->GetId(),
&LmbrCentral::CylinderShapeComponentRequests::SetHeight, nullHeight);
EXPECT_EQ(dimensionWarningHandler.GetExpectedWarningCount(), 1);
EXPECT_EQ(colliderWarningHandler.GetExpectedWarningCount(), 1);
}
{
UnitTest::ErrorHandler dimensionWarningHandler("Negative or zero cylinder dimensions are invalid");
UnitTest::ErrorHandler colliderWarningHandler("No Collider or Shape information found when creating Rigid body");
LmbrCentral::CylinderShapeComponentRequestsBus::Event(editorEntity->GetId(),
&LmbrCentral::CylinderShapeComponentRequests::SetHeight, validHeight);
EXPECT_EQ(dimensionWarningHandler.GetExpectedWarningCount(), 0);
EXPECT_EQ(colliderWarningHandler.GetExpectedWarningCount(), 0);
}
}
TEST_F(PhysXEditorFixture, EditorShapeColliderComponent_ShapeColliderWithBoxAndRigidBody_CorrectRuntimeComponents)
{
// create an editor entity with a shape collider component and a box shape component
@@ -46,7 +46,7 @@ namespace Terrain
WorldSizeCount,
};
WorldSize m_worldSize;
WorldSize m_worldSize = WorldSize::_1024Meters;
};
+1 -1
View File
@@ -33,7 +33,7 @@ ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-linux
ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-linux TARGETS googletest PACKAGE_HASH 7b7ad330f369450c316a4c4592d17fbb4c14c731c95bd8f37757203e8c2bbc1b)
ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-linux TARGETS GoogleBenchmark PACKAGE_HASH 4038878f337fc7e0274f0230f71851b385b2e0327c495fc3dd3d1c18a807928d)
ly_associate_package(PACKAGE_NAME unwind-1.2.1-linux TARGETS unwind PACKAGE_HASH 3453265fb056e25432f611a61546a25f60388e315515ad39007b5925dd054a77)
ly_associate_package(PACKAGE_NAME qt-5.15.2-rev5-linux TARGETS Qt PACKAGE_HASH 76b395897b941a173002845c7219a5f8a799e44b269ffefe8091acc048130f28)
ly_associate_package(PACKAGE_NAME qt-5.15.2-rev6-linux TARGETS Qt PACKAGE_HASH a37bd9989f1e8fe57d94b98cbf9bd5c3caaea740e2f314e5162fa77300551531)
ly_associate_package(PACKAGE_NAME libpng-1.6.37-rev1-linux TARGETS libpng PACKAGE_HASH 896451999f1de76375599aec4b34ae0573d8d34620d9ab29cc30b8739c265ba6)
ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-linux TARGETS libsamplerate PACKAGE_HASH 41643c31bc6b7d037f895f89d8d8d6369e906b92eff42b0fe05ee6a100f06261)
ly_associate_package(PACKAGE_NAME OpenSSL-1.1.1b-rev2-linux TARGETS OpenSSL PACKAGE_HASH b779426d1e9c5ddf71160d5ae2e639c3b956e0fb5e9fcaf9ce97c4526024e3bc)
+2 -2
View File
@@ -115,14 +115,14 @@ def get_gem_json_paths_from_cached_repo(repo_uri: str) -> set:
file_name = pathlib.Path(cache_filename).resolve()
if not file_name.is_file():
logger.error(f'Could not find cached repo json file for {repo_uri}')
return gem_list
return gem_set
with file_name.open('r') as f:
try:
repo_data = json.load(f)
except json.JSONDecodeError as e:
logger.error(f'{file_name} failed to load: {str(e)}')
return gem_list
return gem_set
# Get list of gems, then add all json paths to the list if they exist in the cache
repo_gems = []