From a71a5746ccd6734a68b8c592cab757879993301f Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Tue, 13 Apr 2021 17:15:10 +0100
Subject: [PATCH 001/209] [LY-113714] Jira: LY-113714
https://jira.agscollab.com/browse/LY-113714
---
.../Serialization/EditContextConstants.inl | 2 +
.../Components/img/UI20/line.svg | 7 ++++
.../AzQtComponents/Components/resources.qrc | 1 +
.../UI/PropertyEditor/PropertyRowWidget.cpp | 37 ++++++++++++++++++-
.../UI/PropertyEditor/PropertyRowWidget.hxx | 8 ++++
Code/Sandbox/Editor/Style/Editor.qss | 5 +++
Gems/Vegetation/Code/Source/Descriptor.cpp | 2 +
7 files changed, 61 insertions(+), 1 deletion(-)
create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
diff --git a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
index d4658d4e8c..de67013741 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
+++ b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
@@ -62,6 +62,8 @@ namespace AZ
const static AZ::Crc32 ButtonTooltip = AZ_CRC("ButtonTooltip", 0x1605a7d2);
const static AZ::Crc32 CheckboxTooltip = AZ_CRC("CheckboxTooltip", 0x1159eb78);
const static AZ::Crc32 CheckboxDefaultValue = AZ_CRC("CheckboxDefaultValue", 0x03f117e6);
+ //! Emboldens the text and adds a line above this item within the RPE.
+ const static AZ::Crc32 RPESectionSeparator = AZ_CRC("RPESectionSeparator", 0xc6249a95);
//! Affects the display order of a node relative to it's parent/children. Higher values display further down (after) lower values. Default is 0, negative values are allowed. Must be applied as an attribute to the EditorData element
const static AZ::Crc32 DisplayOrder = AZ_CRC("DisplayOrder", 0x23660ec2);
//! Specifies whether the UI should support multi-edit for aggregate instances of this property
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
new file mode 100644
index 0000000000..60f7c07c8d
--- /dev/null
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
index 77dead96a1..decc1bd72f 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
@@ -627,6 +627,7 @@
img/UI20/Settings.svg
img/UI20/Asset_Folder.svg
img/UI20/Asset_File.svg
+ img/UI20/line.svg
img/UI20/AssetEditor/default_document.svg
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
index 8c371baf8c..a16c1f7480 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
@@ -44,6 +44,24 @@ namespace AzToolsFramework
m_iconOpen = s_iconOpen;
m_iconClosed = s_iconClosed;
+ m_outerLayout = new QVBoxLayout(nullptr);
+ m_outerLayout->setSpacing(0);
+ m_outerLayout->setContentsMargins(0, 0, 0, 0);
+
+ // separatorLayout will contain a spacer and a separator line. The width of the spacer is adjusted later to ensure the line is the
+ // correct length.
+ QHBoxLayout* separatorLayout = new QHBoxLayout(nullptr);
+ m_outerLayout->addLayout(separatorLayout);
+
+ m_separatorIndent = new QSpacerItem(1, 1);
+ separatorLayout->addItem(m_separatorIndent);
+
+ m_separatorLine.load(QStringLiteral(":/Gallery/line.svg"));
+ m_separatorLine.setFixedHeight(3);
+
+ separatorLayout->addWidget(&m_separatorLine);
+ m_separatorLine.setVisible(false);
+
m_mainLayout = new QHBoxLayout();
m_mainLayout->setSpacing(0);
m_mainLayout->setContentsMargins(0, 1, 0, 1);
@@ -118,7 +136,8 @@ namespace AzToolsFramework
m_handler = nullptr;
m_containerSize = 0;
- setLayout(m_mainLayout);
+ m_outerLayout->addLayout(m_mainLayout);
+ setLayout(m_outerLayout);
}
bool PropertyRowWidget::HasChildWidgetAlready() const
@@ -301,6 +320,9 @@ namespace AzToolsFramework
}
}
+ m_isSectionSeparator = false;
+ m_separatorLine.setVisible(false);
+
RefreshAttributesFromNode(true);
// --------------------- HANDLER discovery:
@@ -946,6 +968,11 @@ namespace AzToolsFramework
{
HandleChangeNotifyAttribute(reader, m_sourceNode ? m_sourceNode->GetParent() : nullptr, m_editingCompleteNotifiers);
}
+ else if (attributeName == AZ::Edit::Attributes::RPESectionSeparator)
+ {
+ m_separatorLine.setVisible(true);
+ m_isSectionSeparator = true;
+ }
}
void PropertyRowWidget::SetReadOnlyQueryFunction(const ReadOnlyQueryFunction& readOnlyQueryFunction)
@@ -1070,6 +1097,7 @@ namespace AzToolsFramework
{
m_dropDownArrow->hide();
}
+ m_separatorIndent->changeSize((m_treeDepth * m_treeIndentation) + m_leafIndentation, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_indent->changeSize((m_treeDepth * m_treeIndentation) + m_leafIndentation, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_leftHandSideLayout->invalidate();
m_leftHandSideLayout->update();
@@ -1085,6 +1113,7 @@ namespace AzToolsFramework
connect(m_dropDownArrow, &QCheckBox::clicked, this, &PropertyRowWidget::OnClickedExpansionButton);
}
m_dropDownArrow->show();
+ m_separatorIndent->changeSize((m_treeDepth * m_treeIndentation), 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_indent->changeSize((m_treeDepth * m_treeIndentation), 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_leftHandSideLayout->invalidate();
m_leftHandSideLayout->update();
@@ -1095,6 +1124,7 @@ namespace AzToolsFramework
void PropertyRowWidget::SetIndentSize(int w)
{
+ m_separatorIndent->changeSize(w, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_indent->changeSize(w, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_leftHandSideLayout->invalidate();
m_leftHandSideLayout->update();
@@ -1318,6 +1348,11 @@ namespace AzToolsFramework
return canBeTopLevel(this);
}
+ bool PropertyRowWidget::IsSectionSeparator() const
+ {
+ return m_isSectionSeparator;
+ }
+
bool PropertyRowWidget::GetAppendDefaultLabelToName()
{
return false;
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
index e4b538ccdc..af1b68b66f 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
@@ -25,6 +25,7 @@ AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // class '...' needs t
#include
#include
#include
+#include
#include
AZ_POP_DISABLE_WARNING
@@ -44,6 +45,7 @@ namespace AzToolsFramework
Q_PROPERTY(bool hasChildRows READ HasChildRows);
Q_PROPERTY(bool isTopLevel READ IsTopLevel);
Q_PROPERTY(int getLevel READ GetLevel);
+ Q_PROPERTY(bool isSectionSeparator READ IsSectionSeparator);
Q_PROPERTY(bool appendDefaultLabelToName READ GetAppendDefaultLabelToName WRITE AppendDefaultLabelToName)
public:
AZ_CLASS_ALLOCATOR(PropertyRowWidget, AZ::SystemAllocator, 0)
@@ -82,6 +84,7 @@ namespace AzToolsFramework
PropertyRowWidget* GetParentRow() const { return m_parentRow; }
int GetLevel() const;
bool IsTopLevel() const;
+ bool IsSectionSeparator() const;
// Remove the default label and append the text to the name label.
bool GetAppendDefaultLabelToName();
@@ -161,6 +164,9 @@ namespace AzToolsFramework
QHBoxLayout* m_leftHandSideLayout;
QHBoxLayout* m_middleLayout;
QHBoxLayout* m_rightHandSideLayout;
+ QVBoxLayout* m_outerLayout;
+ QSvgWidget m_separatorLine;
+ QSpacerItem* m_separatorIndent;
QPointer m_dropDownArrow;
QPointer m_containerClearButton;
@@ -229,6 +235,8 @@ namespace AzToolsFramework
int m_treeIndentation = 14;
int m_leafIndentation = 16;
+ bool m_isSectionSeparator = false;
+
QIcon m_iconOpen;
QIcon m_iconClosed;
diff --git a/Code/Sandbox/Editor/Style/Editor.qss b/Code/Sandbox/Editor/Style/Editor.qss
index 0c3f64b85c..7887560105 100644
--- a/Code/Sandbox/Editor/Style/Editor.qss
+++ b/Code/Sandbox/Editor/Style/Editor.qss
@@ -38,6 +38,11 @@ AzToolsFramework--ComponentPaletteWidget > QTreeView
background-color: #222222;
}
+AzToolsFramework--PropertyRowWidget[isSectionSeparator="true"] QLabel#Name
+{
+ font-weight: bold;
+}
+
/* Style for visualizing property values overridden from their prefab values */
AzToolsFramework--PropertyRowWidget[IsOverridden=true] #Name QLabel,
AzToolsFramework--ComponentEditorHeader #Title[IsOverridden="true"]
diff --git a/Gems/Vegetation/Code/Source/Descriptor.cpp b/Gems/Vegetation/Code/Source/Descriptor.cpp
index 93a301f073..4fd1037f09 100644
--- a/Gems/Vegetation/Code/Source/Descriptor.cpp
+++ b/Gems/Vegetation/Code/Source/Descriptor.cpp
@@ -170,6 +170,8 @@ namespace Vegetation
{
edit->Class(
"Vegetation Descriptor", "Details used to create vegetation instances")
+ ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+ ->Attribute(AZ::Edit::Attributes::RPESectionSeparator, true)
// For this ComboBox to actually work, there is a PropertyHandler registration in EditorVegetationSystemComponent.cpp
->DataElement(AZ::Edit::UIHandlers::ComboBox, &Descriptor::m_spawnerType, "Instance Spawner", "The type of instances to spawn")
->Attribute(AZ::Edit::Attributes::GenericValueList, &Descriptor::GetSpawnerTypeList)
From a94700786133526d14971bddfdd87e5d989d8678 Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Wed, 14 Apr 2021 15:15:42 +0100
Subject: [PATCH 002/209] Darken line
---
.../AzQtComponents/AzQtComponents/Components/img/UI20/line.svg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
index 60f7c07c8d..fe01efddba 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
@@ -2,6 +2,6 @@
\ No newline at end of file
From 490b2afd319c595850df82f6038e13a4fa179102 Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Fri, 16 Apr 2021 10:59:27 +0100
Subject: [PATCH 003/209] [LY-105687] Jira: LY-105687
https://jira.agscollab.com/browse/LY-105687
---
.../Components/FancyDocking.cpp | 14 +++++++
.../AzQtComponents/Components/FancyDocking.h | 2 +
.../Components/Widgets/TabWidget.cpp | 24 ++++++++----
.../Components/Widgets/TabWidget.h | 3 ++
.../img/UI20/Cursors/Grab_release.svg | 37 +++++++++++++++++++
.../Components/img/UI20/Cursors/Grabbing.svg | 23 ++++++++++++
.../AzQtComponents/Components/resources.qrc | 2 +
7 files changed, 98 insertions(+), 7 deletions(-)
create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grabbing.svg
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
index 76df971108..bc8da127a6 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
@@ -159,6 +159,8 @@ namespace AzQtComponents
// Timer for updating our hovered drop zone opacity
QObject::connect(m_dropZoneHoverFadeInTimer, &QTimer::timeout, this, &FancyDocking::onDropZoneHoverFadeInUpdate);
m_dropZoneHoverFadeInTimer->setInterval(g_FancyDockingConstants.dropZoneHoverFadeUpdateIntervalMS);
+ QIcon dragIcon = QIcon(QStringLiteral(":/Cursors/Grabbing.svg"));
+ m_dragCursor = QCursor(dragIcon.pixmap(32), 10, 5);
}
FancyDocking::~FancyDocking()
@@ -1884,6 +1886,8 @@ namespace AzQtComponents
return;
}
+ QApplication::setOverrideCursor(m_dragCursor);
+
QPoint relativePressPos = pressPos;
// If we are dragging a floating window, we need to grab a reference to its
@@ -1999,6 +2003,11 @@ namespace AzQtComponents
clearDraggingState();
}
+ if (QApplication::overrideCursor())
+ {
+ QApplication::restoreOverrideCursor();
+ }
+
return true;
}
@@ -2376,6 +2385,11 @@ namespace AzQtComponents
*/
void FancyDocking::dropDockWidget(QDockWidget* dock, QWidget* onto, Qt::DockWidgetArea area)
{
+ if (QApplication::overrideCursor())
+ {
+ QApplication::restoreOverrideCursor();
+ }
+
// If the dock widget we are dropping is currently a tab, we need to retrieve it from
// the tab widget, and remove it as a tab. We also need to remove its item from our
// cache of widget <-> tab container since we are moving it somewhere else.
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.h
index a466ce7087..20b90ad25c 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.h
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.h
@@ -266,6 +266,8 @@ namespace AzQtComponents
QString m_floatingWindowIdentifierPrefix;
QString m_tabContainerIdentifierPrefix;
+
+ QCursor m_dragCursor;
};
} // namespace AzQtComponents
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
index 895785f47b..8f408b01ef 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
@@ -21,6 +21,7 @@
#include
#include
+#include
#include
#include
#include
@@ -419,6 +420,14 @@ namespace AzQtComponents
// a mouse move. The paint handler updates the close button's visibility
setAttribute(Qt::WA_Hover);
AzQtComponents::Style::addClass(this, g_emptyStyleClass);
+
+ QIcon icon = QIcon(QStringLiteral(":/Cursors/Grab release.svg"));
+ m_hoverCursor = QCursor(icon.pixmap(32), 10, 5);
+
+ icon = QIcon(QStringLiteral(":/Cursors/Grabbing.svg"));
+ m_dragCursor = QCursor(icon.pixmap(32), 10, 5);
+
+ this->setCursor(m_hoverCursor);
}
void TabBar::setHandleOverflow(bool handleOverflow)
@@ -479,6 +488,13 @@ namespace AzQtComponents
void TabBar::mouseReleaseEvent(QMouseEvent* mouseEvent)
{
+ // Ensure we don't reset the cursor in the case of a dummy event being sent from DockTabWidget to trigger the animation.
+ Qt::MouseButtons realButtons = QApplication::mouseButtons();
+ if (QApplication::overrideCursor() && !(realButtons & Qt::LeftButton))
+ {
+ QApplication::restoreOverrideCursor();
+ }
+
if (m_movingTab && !(mouseEvent->buttons() & Qt::LeftButton))
{
// When a moving tab is released, there is a short animation to put the moving tab
@@ -632,13 +648,7 @@ namespace AzQtComponents
{
QPoint p = tabRect(i).topLeft();
- int rightPadding = g_closeButtonPadding;
- if (m_overflowing == Overflowing)
- {
- rightPadding = 0;
- }
-
- p.setX(p.x() + tabRect(i).width() - rightPadding - g_closeButtonWidth);
+ p.setX(p.x() + tabRect(i).width() - g_closeButtonPadding - g_closeButtonWidth);
p.setY(p.y() + 1 + (tabRect(i).height() - g_closeButtonWidth) / 2);
tabBtn->move(p);
}
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.h
index 3f12f79907..e86deef7b4 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.h
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.h
@@ -203,6 +203,9 @@ namespace AzQtComponents
bool m_movingTab = false;
QPoint m_lastMousePress;
+ QCursor m_dragCursor;
+ QCursor m_hoverCursor;
+
void resetOverflow();
void overflowIfNeeded();
void showCloseButtonAt(int index);
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
new file mode 100644
index 0000000000..c0da9b802f
--- /dev/null
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
@@ -0,0 +1,37 @@
+
+
+
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grabbing.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grabbing.svg
new file mode 100644
index 0000000000..e70be77d51
--- /dev/null
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grabbing.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
index f9e601fb6d..048758c283 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
@@ -636,5 +636,7 @@
img/UI20/Cursors/Pointer.svg
+ img/UI20/Cursors/Grab_release.svg
+ img/UI20/Cursors/Grabbing.svg
From db4b080544d305052602e0ba7e8260ee90bf0a87 Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Fri, 16 Apr 2021 14:55:39 +0100
Subject: [PATCH 004/209] Renamed svg
---
.../AzQtComponents/Components/Widgets/TabWidget.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
index 8f408b01ef..121f35db61 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
@@ -421,7 +421,7 @@ namespace AzQtComponents
setAttribute(Qt::WA_Hover);
AzQtComponents::Style::addClass(this, g_emptyStyleClass);
- QIcon icon = QIcon(QStringLiteral(":/Cursors/Grab release.svg"));
+ QIcon icon = QIcon(QStringLiteral(":/Cursors/Grab_release.svg"));
m_hoverCursor = QCursor(icon.pixmap(32), 10, 5);
icon = QIcon(QStringLiteral(":/Cursors/Grabbing.svg"));
From 2a339edc4e9ddafedc6dac297abdd1d9c8faf3ca Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Fri, 16 Apr 2021 10:59:27 +0100
Subject: [PATCH 005/209] [LY-105687] Jira: LY-105687
https://jira.agscollab.com/browse/LY-105687
Renamed svg
---
.../Components/FancyDocking.cpp | 14 +++++++
.../AzQtComponents/Components/FancyDocking.h | 2 +
.../Components/Widgets/TabWidget.cpp | 24 ++++++++----
.../Components/Widgets/TabWidget.h | 3 ++
.../img/UI20/Cursors/Grab_release.svg | 37 +++++++++++++++++++
.../Components/img/UI20/Cursors/Grabbing.svg | 23 ++++++++++++
.../AzQtComponents/Components/resources.qrc | 2 +
7 files changed, 98 insertions(+), 7 deletions(-)
create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
create mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grabbing.svg
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
index 76df971108..bc8da127a6 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
@@ -159,6 +159,8 @@ namespace AzQtComponents
// Timer for updating our hovered drop zone opacity
QObject::connect(m_dropZoneHoverFadeInTimer, &QTimer::timeout, this, &FancyDocking::onDropZoneHoverFadeInUpdate);
m_dropZoneHoverFadeInTimer->setInterval(g_FancyDockingConstants.dropZoneHoverFadeUpdateIntervalMS);
+ QIcon dragIcon = QIcon(QStringLiteral(":/Cursors/Grabbing.svg"));
+ m_dragCursor = QCursor(dragIcon.pixmap(32), 10, 5);
}
FancyDocking::~FancyDocking()
@@ -1884,6 +1886,8 @@ namespace AzQtComponents
return;
}
+ QApplication::setOverrideCursor(m_dragCursor);
+
QPoint relativePressPos = pressPos;
// If we are dragging a floating window, we need to grab a reference to its
@@ -1999,6 +2003,11 @@ namespace AzQtComponents
clearDraggingState();
}
+ if (QApplication::overrideCursor())
+ {
+ QApplication::restoreOverrideCursor();
+ }
+
return true;
}
@@ -2376,6 +2385,11 @@ namespace AzQtComponents
*/
void FancyDocking::dropDockWidget(QDockWidget* dock, QWidget* onto, Qt::DockWidgetArea area)
{
+ if (QApplication::overrideCursor())
+ {
+ QApplication::restoreOverrideCursor();
+ }
+
// If the dock widget we are dropping is currently a tab, we need to retrieve it from
// the tab widget, and remove it as a tab. We also need to remove its item from our
// cache of widget <-> tab container since we are moving it somewhere else.
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.h
index a466ce7087..20b90ad25c 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.h
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.h
@@ -266,6 +266,8 @@ namespace AzQtComponents
QString m_floatingWindowIdentifierPrefix;
QString m_tabContainerIdentifierPrefix;
+
+ QCursor m_dragCursor;
};
} // namespace AzQtComponents
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
index 895785f47b..121f35db61 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
@@ -21,6 +21,7 @@
#include
#include
+#include
#include
#include
#include
@@ -419,6 +420,14 @@ namespace AzQtComponents
// a mouse move. The paint handler updates the close button's visibility
setAttribute(Qt::WA_Hover);
AzQtComponents::Style::addClass(this, g_emptyStyleClass);
+
+ QIcon icon = QIcon(QStringLiteral(":/Cursors/Grab_release.svg"));
+ m_hoverCursor = QCursor(icon.pixmap(32), 10, 5);
+
+ icon = QIcon(QStringLiteral(":/Cursors/Grabbing.svg"));
+ m_dragCursor = QCursor(icon.pixmap(32), 10, 5);
+
+ this->setCursor(m_hoverCursor);
}
void TabBar::setHandleOverflow(bool handleOverflow)
@@ -479,6 +488,13 @@ namespace AzQtComponents
void TabBar::mouseReleaseEvent(QMouseEvent* mouseEvent)
{
+ // Ensure we don't reset the cursor in the case of a dummy event being sent from DockTabWidget to trigger the animation.
+ Qt::MouseButtons realButtons = QApplication::mouseButtons();
+ if (QApplication::overrideCursor() && !(realButtons & Qt::LeftButton))
+ {
+ QApplication::restoreOverrideCursor();
+ }
+
if (m_movingTab && !(mouseEvent->buttons() & Qt::LeftButton))
{
// When a moving tab is released, there is a short animation to put the moving tab
@@ -632,13 +648,7 @@ namespace AzQtComponents
{
QPoint p = tabRect(i).topLeft();
- int rightPadding = g_closeButtonPadding;
- if (m_overflowing == Overflowing)
- {
- rightPadding = 0;
- }
-
- p.setX(p.x() + tabRect(i).width() - rightPadding - g_closeButtonWidth);
+ p.setX(p.x() + tabRect(i).width() - g_closeButtonPadding - g_closeButtonWidth);
p.setY(p.y() + 1 + (tabRect(i).height() - g_closeButtonWidth) / 2);
tabBtn->move(p);
}
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.h
index 3f12f79907..e86deef7b4 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.h
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.h
@@ -203,6 +203,9 @@ namespace AzQtComponents
bool m_movingTab = false;
QPoint m_lastMousePress;
+ QCursor m_dragCursor;
+ QCursor m_hoverCursor;
+
void resetOverflow();
void overflowIfNeeded();
void showCloseButtonAt(int index);
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
new file mode 100644
index 0000000000..c0da9b802f
--- /dev/null
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
@@ -0,0 +1,37 @@
+
+
+
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grabbing.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grabbing.svg
new file mode 100644
index 0000000000..e70be77d51
--- /dev/null
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grabbing.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
index f9e601fb6d..048758c283 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
@@ -636,5 +636,7 @@
img/UI20/Cursors/Pointer.svg
+ img/UI20/Cursors/Grab_release.svg
+ img/UI20/Cursors/Grabbing.svg
From 2dbd9e4a050e141a45c85a12b4d245f0695f581a Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Mon, 19 Apr 2021 15:54:41 +0100
Subject: [PATCH 006/209] Changed to use direct line drawing rather than adding
svg.
---
.../Components/img/UI20/line.svg | 7 ----
.../UI/PropertyEditor/PropertyRowWidget.cpp | 40 +++++++------------
.../UI/PropertyEditor/PropertyRowWidget.hxx | 4 +-
3 files changed, 16 insertions(+), 35 deletions(-)
delete mode 100644 Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
deleted file mode 100644
index fe01efddba..0000000000
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/line.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
index a16c1f7480..5b02e81e6d 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
@@ -27,6 +27,7 @@ AZ_PUSH_DISABLE_WARNING(4244 4251 4800, "-Wunknown-warning-option") // 4244: con
#include
#include
#include
+#include
AZ_POP_DISABLE_WARNING
static const int LabelColumnStretch = 2;
@@ -44,24 +45,6 @@ namespace AzToolsFramework
m_iconOpen = s_iconOpen;
m_iconClosed = s_iconClosed;
- m_outerLayout = new QVBoxLayout(nullptr);
- m_outerLayout->setSpacing(0);
- m_outerLayout->setContentsMargins(0, 0, 0, 0);
-
- // separatorLayout will contain a spacer and a separator line. The width of the spacer is adjusted later to ensure the line is the
- // correct length.
- QHBoxLayout* separatorLayout = new QHBoxLayout(nullptr);
- m_outerLayout->addLayout(separatorLayout);
-
- m_separatorIndent = new QSpacerItem(1, 1);
- separatorLayout->addItem(m_separatorIndent);
-
- m_separatorLine.load(QStringLiteral(":/Gallery/line.svg"));
- m_separatorLine.setFixedHeight(3);
-
- separatorLayout->addWidget(&m_separatorLine);
- m_separatorLine.setVisible(false);
-
m_mainLayout = new QHBoxLayout();
m_mainLayout->setSpacing(0);
m_mainLayout->setContentsMargins(0, 1, 0, 1);
@@ -136,8 +119,20 @@ namespace AzToolsFramework
m_handler = nullptr;
m_containerSize = 0;
- m_outerLayout->addLayout(m_mainLayout);
- setLayout(m_outerLayout);
+ setLayout(m_mainLayout);
+ }
+
+ void PropertyRowWidget::paintEvent(QPaintEvent* event)
+ {
+ QStylePainter p(this);
+
+ if (IsSectionSeparator())
+ {
+ const QPen linePen(QColor(0x3B3E3F));
+ p.setPen(linePen);
+ int indent = m_treeDepth * m_treeIndentation;
+ p.drawLine(event->rect().topLeft() + QPoint(indent, 0), event->rect().topRight());
+ }
}
bool PropertyRowWidget::HasChildWidgetAlready() const
@@ -321,7 +316,6 @@ namespace AzToolsFramework
}
m_isSectionSeparator = false;
- m_separatorLine.setVisible(false);
RefreshAttributesFromNode(true);
@@ -970,7 +964,6 @@ namespace AzToolsFramework
}
else if (attributeName == AZ::Edit::Attributes::RPESectionSeparator)
{
- m_separatorLine.setVisible(true);
m_isSectionSeparator = true;
}
}
@@ -1097,7 +1090,6 @@ namespace AzToolsFramework
{
m_dropDownArrow->hide();
}
- m_separatorIndent->changeSize((m_treeDepth * m_treeIndentation) + m_leafIndentation, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_indent->changeSize((m_treeDepth * m_treeIndentation) + m_leafIndentation, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_leftHandSideLayout->invalidate();
m_leftHandSideLayout->update();
@@ -1113,7 +1105,6 @@ namespace AzToolsFramework
connect(m_dropDownArrow, &QCheckBox::clicked, this, &PropertyRowWidget::OnClickedExpansionButton);
}
m_dropDownArrow->show();
- m_separatorIndent->changeSize((m_treeDepth * m_treeIndentation), 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_indent->changeSize((m_treeDepth * m_treeIndentation), 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_leftHandSideLayout->invalidate();
m_leftHandSideLayout->update();
@@ -1124,7 +1115,6 @@ namespace AzToolsFramework
void PropertyRowWidget::SetIndentSize(int w)
{
- m_separatorIndent->changeSize(w, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_indent->changeSize(w, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
m_leftHandSideLayout->invalidate();
m_leftHandSideLayout->update();
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
index af1b68b66f..d08779caa4 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
@@ -129,6 +129,7 @@ namespace AzToolsFramework
void SetSelectionEnabled(bool selectionEnabled);
void SetSelected(bool selected);
bool eventFilter(QObject *watched, QEvent *event) override;
+ void paintEvent(QPaintEvent*) override;
/// Apply tooltip to widget and some of its children.
void SetDescription(const QString& text);
@@ -164,9 +165,6 @@ namespace AzToolsFramework
QHBoxLayout* m_leftHandSideLayout;
QHBoxLayout* m_middleLayout;
QHBoxLayout* m_rightHandSideLayout;
- QVBoxLayout* m_outerLayout;
- QSvgWidget m_separatorLine;
- QSpacerItem* m_separatorIndent;
QPointer m_dropDownArrow;
QPointer m_containerClearButton;
From b1d8330870f31399d05aa0c1d1b28e5f55512580 Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Tue, 20 Apr 2021 17:20:19 +0100
Subject: [PATCH 007/209] Review fixes.
---
.../AzQtComponents/AzQtComponents/Components/resources.qrc | 1 -
.../AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx | 1 -
2 files changed, 2 deletions(-)
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
index e253c6492d..f9e601fb6d 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc
@@ -630,7 +630,6 @@
img/UI20/Settings.svg
img/UI20/Asset_Folder.svg
img/UI20/Asset_File.svg
- img/UI20/line.svg
img/UI20/AssetEditor/default_document.svg
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
index d08779caa4..2fb695fca5 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
@@ -25,7 +25,6 @@ AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // class '...' needs t
#include
#include
#include
-#include
#include
AZ_POP_DISABLE_WARNING
From bfa964a23edd6bce5f6ae0da11506aa0895f0961 Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Wed, 21 Apr 2021 10:19:12 +0100
Subject: [PATCH 008/209] Moved TabWidget grab animation to mouse press to
match fancy docking behavior, fixed missed mouse up cursor restore
---
.../AzQtComponents/Components/FancyDocking.cpp | 15 +++++----------
.../Components/Widgets/TabWidget.cpp | 6 ++++++
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
index bc8da127a6..2fb06a8367 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
@@ -2003,11 +2003,6 @@ namespace AzQtComponents
clearDraggingState();
}
- if (QApplication::overrideCursor())
- {
- QApplication::restoreOverrideCursor();
- }
-
return true;
}
@@ -2385,11 +2380,6 @@ namespace AzQtComponents
*/
void FancyDocking::dropDockWidget(QDockWidget* dock, QWidget* onto, Qt::DockWidgetArea area)
{
- if (QApplication::overrideCursor())
- {
- QApplication::restoreOverrideCursor();
- }
-
// If the dock widget we are dropping is currently a tab, we need to retrieve it from
// the tab widget, and remove it as a tab. We also need to remove its item from our
// cache of widget <-> tab container since we are moving it somewhere else.
@@ -3573,6 +3563,11 @@ namespace AzQtComponents
*/
void FancyDocking::clearDraggingState()
{
+ if (QApplication::overrideCursor())
+ {
+ QApplication::restoreOverrideCursor();
+ }
+
m_ghostWidget->hide();
// Release the mouse and keyboard from our main window since we grab them when we start dragging
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
index 121f35db61..a0006d7979 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
@@ -464,6 +464,11 @@ namespace AzQtComponents
{
if (mouseEvent->buttons() & Qt::LeftButton)
{
+ if (!QApplication::overrideCursor() || *QApplication::overrideCursor() != m_dragCursor)
+ {
+ QApplication::setOverrideCursor(m_dragCursor);
+ }
+
m_lastMousePress = mouseEvent->pos();
}
@@ -478,6 +483,7 @@ namespace AzQtComponents
// selected tab is moved around. The close button is not explicitly rendered for the
// moved tab during this operation. We need to make sure not to set it visible again
// while the tab is moving. This flag makes sure it happens.
+
m_movingTab = true;
}
From 2f4120cdfbbd736d18fdc5f3187a94f6640ed28b Mon Sep 17 00:00:00 2001
From: puvvadar
Date: Mon, 3 May 2021 13:07:11 -0700
Subject: [PATCH 009/209] Update Ctrl+G logic to account for prefab processing
status and timing
---
.../PrefabEditorEntityOwnershipInterface.h | 2 +
.../PrefabEditorEntityOwnershipService.cpp | 5 ++
.../PrefabEditorEntityOwnershipService.h | 2 +
Gems/Multiplayer/Code/CMakeLists.txt | 1 +
.../Code/Include/IMultiplayerTools.h | 39 ++++++++++++
.../MultiplayerEditorSystemComponent.cpp | 63 ++++++++++++-------
.../Editor/MultiplayerEditorSystemComponent.h | 12 +++-
.../Code/Source/MultiplayerToolsModule.cpp | 35 ++++-------
.../Code/Source/MultiplayerToolsModule.h | 27 ++++++++
.../Pipeline/NetworkPrefabProcessor.cpp | 3 +
.../Code/multiplayer_tools_files.cmake | 1 +
11 files changed, 142 insertions(+), 48 deletions(-)
create mode 100644 Gems/Multiplayer/Code/Include/IMultiplayerTools.h
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h
index 19c236f509..4476876b59 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h
@@ -46,6 +46,8 @@ namespace AzToolsFramework
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
+ virtual const AZStd::vector>& GetPlayInEditorAssetData() = 0;
+
virtual bool LoadFromStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
virtual bool SaveToStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
index 81233069a9..e81d6bf08e 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
@@ -321,6 +321,11 @@ namespace AzToolsFramework
return *m_rootInstance;
}
+ const AZStd::vector>& PrefabEditorEntityOwnershipService::GetPlayInEditorAssetData()
+ {
+ return m_playInEditorData.m_assets;
+ }
+
void PrefabEditorEntityOwnershipService::OnEntityRemoved(AZ::EntityId entityId)
{
AzFramework::SliceEntityRequestBus::MultiHandler::BusDisconnect(entityId);
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h
index 9c483e61c5..cf62220e67 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h
@@ -195,6 +195,8 @@ namespace AzToolsFramework
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override;
Prefab::InstanceOptionalReference GetRootPrefabInstance() override;
+
+ const AZStd::vector>& GetPlayInEditorAssetData() override;
//////////////////////////////////////////////////////////////////////////
void OnEntityRemoved(AZ::EntityId entityId);
diff --git a/Gems/Multiplayer/Code/CMakeLists.txt b/Gems/Multiplayer/Code/CMakeLists.txt
index 4eeee15c47..46f56ef315 100644
--- a/Gems/Multiplayer/Code/CMakeLists.txt
+++ b/Gems/Multiplayer/Code/CMakeLists.txt
@@ -119,6 +119,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
BUILD_DEPENDENCIES
PRIVATE
Gem::Multiplayer.Editor.Static
+ Gem::Multiplayer.Tools
)
endif()
diff --git a/Gems/Multiplayer/Code/Include/IMultiplayerTools.h b/Gems/Multiplayer/Code/Include/IMultiplayerTools.h
new file mode 100644
index 0000000000..c621808f7a
--- /dev/null
+++ b/Gems/Multiplayer/Code/Include/IMultiplayerTools.h
@@ -0,0 +1,39 @@
+/*
+* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+* its licensors.
+*
+* For complete copyright and license terms please see the LICENSE at the root of this
+* distribution (the "License"). All use of this software is governed by the License,
+* or, if provided, by the license below or the license accompanying this file. Do not
+* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*
+*/
+
+#pragma once
+
+#include
+
+namespace Multiplayer
+{
+ //! IMultiplayer provides insight into the Multiplayer session and its Agents
+ class IMultiplayerTools
+ {
+ public:
+ // NetworkPrefabProcessor is the only class that should be setting process network prefab status
+ friend class NetworkPrefabProcessor;
+
+ AZ_RTTI(IMultiplayerTools, "{E8A80EAB-29CB-4E3B-A0B2-FFCB37060FB0}");
+
+ virtual ~IMultiplayerTools() = default;
+
+ //! Returns if network prefab processing has created currently active or pending spawnables
+ //! @return If network prefab processing has created currently active or pending spawnables
+ virtual bool DidProcessNetworkPrefabs() = 0;
+
+ private:
+ //! Sets if network prefab processing has created currently active or pending spawnables
+ //! @param didProcessNetPrefabs if network prefab processing has created currently active or pending spawnables
+ virtual void SetDidProcessNetworkPrefabs(bool didProcessNetPrefabs) = 0;
+ };
+}
diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp
index aec3e7870f..0850b858a2 100644
--- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp
+++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp
@@ -10,12 +10,14 @@
*
*/
+#include
#include
#include
#include
#include
#include
#include
+#include
namespace Multiplayer
{
@@ -57,12 +59,14 @@ namespace Multiplayer
void MultiplayerEditorSystemComponent::Activate()
{
+ AzFramework::GameEntityContextEventBus::Handler::BusConnect();
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
}
void MultiplayerEditorSystemComponent::Deactivate()
{
AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect();
+ AzFramework::GameEntityContextEventBus::Handler::BusDisconnect();
}
void MultiplayerEditorSystemComponent::NotifyRegisterViews()
@@ -77,11 +81,42 @@ namespace Multiplayer
{
switch (event)
{
- case eNotify_OnBeginGameMode:
- {
+ case eNotify_OnQuit:
+ AZ_Warning("Multiplayer Editor", m_editor != nullptr, "Multiplayer Editor received On Quit without an Editor pointer.");
+ if (m_editor)
+ {
+ m_editor->UnregisterNotifyListener(this);
+ m_editor = nullptr;
+ }
+ [[fallthrough]];
+ case eNotify_OnEndGameMode:
+ AZ::TickBus::Handler::BusDisconnect();
+ // Kill the configured server if it's active
+ if (m_serverProcess)
+ {
+ m_serverProcess->TerminateProcess(0);
+ m_serverProcess = nullptr;
+ }
+ break;
+ }
+ }
+
+ void MultiplayerEditorSystemComponent::OnGameEntitiesStarted()
+ {
+ // BeginGameMode and Prefab Processing have completed at this point
+ IMultiplayerTools* mpTools = AZ::Interface::Get();
+ if (editorsv_enabled && mpTools != nullptr && mpTools->DidProcessNetworkPrefabs())
+ {
AZ::TickBus::Handler::BusConnect();
- if (editorsv_enabled)
+ auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get();
+ if (!prefabEditorEntityOwnershipInterface)
+ {
+ AZ_Error("MultiplayerEditor", prefabEditorEntityOwnershipInterface != nullptr, "PrefabEditorEntityOwnershipInterface unavailable");
+ }
+ const AZStd::vector>& assetData = prefabEditorEntityOwnershipInterface->GetPlayInEditorAssetData();
+
+ if (assetData.size() > 0)
{
// Assemble the server's path
AZ::CVarFixedString serverProcess = editorsv_process;
@@ -111,33 +146,13 @@ namespace Multiplayer
// Start the configured server if it's available
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
- processLaunchInfo.m_commandlineParameters =
- AZStd::string::format("\"%s\"", serverPath.c_str());
+ processLaunchInfo.m_commandlineParameters = AZStd::string::format("\"%s\"", serverPath.c_str());
processLaunchInfo.m_showWindow = true;
processLaunchInfo.m_processPriority = AzFramework::ProcessPriority::PROCESSPRIORITY_NORMAL;
m_serverProcess = AzFramework::ProcessWatcher::LaunchProcess(
processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE);
}
- break;
- }
- case eNotify_OnQuit:
- AZ_Warning("Multiplayer Editor", m_editor != nullptr, "Multiplayer Editor received On Quit without an Editor pointer.");
- if (m_editor)
- {
- m_editor->UnregisterNotifyListener(this);
- m_editor = nullptr;
- }
- [[fallthrough]];
- case eNotify_OnEndGameMode:
- AZ::TickBus::Handler::BusDisconnect();
- // Kill the configured server if it's active
- if (m_serverProcess)
- {
- m_serverProcess->TerminateProcess(0);
- m_serverProcess = nullptr;
- }
- break;
}
}
diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h
index 8c18a2e57a..31ecdf83a3 100644
--- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h
+++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h
@@ -19,6 +19,7 @@
#include
#include
+#include
#include
#include
@@ -34,6 +35,7 @@ namespace Multiplayer
class MultiplayerEditorSystemComponent final
: public AZ::Component
, private AZ::TickBus::Handler
+ , private AzFramework::GameEntityContextEventBus::Handler
, private AzToolsFramework::EditorEvents::Bus::Handler
, private IEditorNotifyListener
{
@@ -66,8 +68,16 @@ namespace Multiplayer
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
int GetTickOrder() override;
//! @}
- //!
+
+ //! EditorEvents::Handler overrides
+ //! @{
void OnEditorNotifyEvent(EEditorNotifyEvent event) override;
+ //! @}
+
+ //! GameEntityContextEventBus::Handler overrides
+ //! @{
+ void OnGameEntitiesStarted() override;
+ //! @}
IEditor* m_editor = nullptr;
AzFramework::ProcessWatcher* m_serverProcess = nullptr;
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.cpp b/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.cpp
index 5a223d6214..a5df3c1dc5 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.cpp
+++ b/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.cpp
@@ -18,32 +18,21 @@
namespace Multiplayer
{
- //! Multiplayer Tools system component provides serialize context reflection for tools-only systems.
- class MultiplayerToolsSystemComponent final
- : public AZ::Component
- {
- public:
- AZ_COMPONENT(MultiplayerToolsSystemComponent, "{65AF5342-0ECE-423B-B646-AF55A122F72B}");
-
- static void Reflect(AZ::ReflectContext* context)
- {
- NetworkPrefabProcessor::Reflect(context);
- }
-
- MultiplayerToolsSystemComponent() = default;
- ~MultiplayerToolsSystemComponent() override = default;
- /// AZ::Component overrides.
- void Activate() override
- {
-
- }
+ void MultiplayerToolsSystemComponent::Reflect(AZ::ReflectContext* context)
+ {
+ NetworkPrefabProcessor::Reflect(context);
+ }
- void Deactivate() override
- {
+ bool MultiplayerToolsSystemComponent::DidProcessNetworkPrefabs()
+ {
+ return m_didProcessNetPrefabs;
+ }
- }
- };
+ void MultiplayerToolsSystemComponent::SetDidProcessNetworkPrefabs(bool didProcessNetPrefabs)
+ {
+ m_didProcessNetPrefabs = didProcessNetPrefabs;
+ }
MultiplayerToolsModule::MultiplayerToolsModule()
: AZ::Module()
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.h b/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.h
index 823bd63a1d..82d0415c5a 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.h
+++ b/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.h
@@ -12,10 +12,37 @@
#pragma once
+#include
#include
+#include
namespace Multiplayer
{
+ class MultiplayerToolsSystemComponent final
+ : public AZ::Component
+ , public IMultiplayerTools
+ {
+ public:
+ AZ_COMPONENT(MultiplayerToolsSystemComponent, "{65AF5342-0ECE-423B-B646-AF55A122F72B}");
+
+ static void Reflect(AZ::ReflectContext* context);
+
+ MultiplayerToolsSystemComponent() = default;
+ ~MultiplayerToolsSystemComponent() override = default;
+
+ /// AZ::Component overrides.
+ void Activate() override {};
+
+ void Deactivate() override {};
+
+ bool DidProcessNetworkPrefabs() override;
+
+ private:
+ void SetDidProcessNetworkPrefabs(bool didProcessNetPrefabs) override;
+
+ bool m_didProcessNetPrefabs = false;
+ };
+
class MultiplayerToolsModule
: public AZ::Module
{
diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp
index 2006272135..8528b3d564 100644
--- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp
+++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -29,6 +30,8 @@ namespace Multiplayer
void NetworkPrefabProcessor::Process(PrefabProcessorContext& context)
{
+ IMultiplayerTools* mpTools = AZ::Interface::Get();
+ mpTools->SetDidProcessNetworkPrefabs(false);
context.ListPrefabs([&context](AZStd::string_view prefabName, PrefabDom& prefab) {
ProcessPrefab(context, prefabName, prefab);
});
diff --git a/Gems/Multiplayer/Code/multiplayer_tools_files.cmake b/Gems/Multiplayer/Code/multiplayer_tools_files.cmake
index 1be02fd999..12f12479ba 100644
--- a/Gems/Multiplayer/Code/multiplayer_tools_files.cmake
+++ b/Gems/Multiplayer/Code/multiplayer_tools_files.cmake
@@ -10,6 +10,7 @@
#
set(FILES
+ Include/IMultiplayerTools.h
Source/Multiplayer_precompiled.cpp
Source/Multiplayer_precompiled.h
Source/Pipeline/NetworkPrefabProcessor.cpp
From f5414050e36906541cad6fcf1377918f602ecae6 Mon Sep 17 00:00:00 2001
From: darapan
Date: Wed, 5 May 2021 00:37:53 -0700
Subject: [PATCH 010/209] smoke test cases migration
---
.../Gem/PythonTests/CMakeLists.txt | 15 ++
.../smoke/Editor_NewExistingLevels.py | 155 ++++++++++++++++++
.../Gem/PythonTests/smoke/ImportPathHelper.py | 16 ++
.../Gem/PythonTests/smoke/__init__.py | 10 ++
.../PythonTests/smoke/test_AssetBuilder.py | 44 +++++
.../smoke/test_AssetProcessorBatch.py | 43 +++++
.../PythonTests/smoke/test_AzTestRunner.py | 46 ++++++
.../smoke/test_Editor_NewExistingLevels.py | 34 ++++
.../smoke/test_PythonBindingsExample.py | 45 +++++
.../smoke/test_SerializeContextTools.py | 44 +++++
.../smoke/test_Statictool_Scripts.py | 48 ++++++
11 files changed, 500 insertions(+)
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/ImportPathHelper.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/__init__.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_AssetBuilder.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_AssetProcessorBatch.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_AzTestRunner.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_PythonBindingsExample.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_SerializeContextTools.py
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index 6d3727195e..26c425fd79 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -307,3 +307,18 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
#)
endif()
+## Smoke ##
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
+ ly_add_pytest(
+ NAME AutomatedTesting::SmokeTest_Periodic
+ TEST_SUITE periodic
+ TEST_SERIAL
+ PATH ${CMAKE_CURRENT_LIST_DIR}/smoke
+ TIMEOUT 3600
+ RUNTIME_DEPENDENCIES
+ AZ::AssetProcessor
+ AZ::PythonBindingsExample
+ Legacy::Editor
+ AutomatedTesting.GameLauncher
+ AutomatedTesting.Assets
+
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels.py b/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels.py
new file mode 100644
index 0000000000..4e4a037ec9
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels.py
@@ -0,0 +1,155 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+
+Test case ID: LY-123945
+Test Case Title: Create Test for UI apps- Editor
+URL of the test case: https://jira.agscollab.com/browse/LY-123945
+"""
+
+
+# fmt: off
+class Tests():
+ level_created = ("Level created", "Failed to create level")
+ entity_found = ("New Entity created in level", "Failed to create New Entity in level")
+ mesh_added = ("Mesh Component added", "Failed to add Mesh Component")
+ enter_game_mode = ("Game Mode successfully entered", "Failed to enter in Game Mode")
+ exit_game_mode = ("Game Mode successfully exited", "Failed to exit in Game Mode")
+ level_opened = ("Level opened successfully", "Failed to open level")
+ level_exported = ("Level exported successfully", "Failed to export level")
+ mesh_removed = ("Mesh Component removed", "Failed to remove Mesh Component")
+ entity_deleted = ("Entity deleted", "Failed to delete Entity")
+ level_edits_present = ("Level edits persist after saving", "Failed to save level edits after saving")
+# fmt: on
+
+
+def Editor_NewExistingLevels():
+ """
+ Summary: Perform the below operations on Editor
+
+ 1) Launch & Close editor
+ 2) Create new level
+ 3) Saving and loading levels
+ 4) Level edits persist after saving
+ 5) Export Level
+ 6) Can switch to play mode (ctrl+g) and exit that
+ 7) Run editor python bindings test
+ 8) Create an Entity
+ 9) Delete an Entity
+ 10) Add a component to an Entity
+
+ Expected Behavior:
+ All operations succeed and do not cause a crash
+
+ Test Steps:
+ 1) Launch editor and Create a new level
+ 2) Create a new entity
+ 3) Add Mesh component
+ 4) Verify enter/exit game mode
+ 5) Save, Load and Export level
+ 6) Remove Mesh component
+ 7) Delete entity
+ 8) Open an existing level
+ 9) Create a new entity in an existing level
+ 10) Save, Load and Export an existing level and close editor
+
+ Note:
+ - This test file must be called from the Lumberyard Editor command terminal
+ - Any passed and failed tests are written to the Editor.log file.
+ Parsing the file or running a log_monitor are required to observe the test results.
+
+ :return: None
+ """
+
+ import os
+ import hydra_editor_utils as hydra
+ from utils import TestHelper as helper
+ from utils import Report
+ import azlmbr.bus as bus
+ import azlmbr.editor as editor
+ import azlmbr.legacy.general as general
+ import azlmbr.math as math
+
+ # 1) Launch editor and Create a new level
+ helper.init_idle()
+ test_level_name = "temp_level"
+ general.create_level_no_prompt(test_level_name, 128, 1, 128, False)
+ general.idle_wait(2.0)
+ Report.result(Tests.level_created, general.get_current_level_name() == test_level_name)
+
+ # 2) Create a new entity
+ entity_position = math.Vector3(200.0, 200.0, 38.0)
+ new_entity = hydra.Entity("Entity1")
+ new_entity.create_entity(entity_position, [])
+ test_entity = hydra.find_entity_by_name("Entity1")
+ Report.result(Tests.entity_found, test_entity.IsValid())
+
+ # 3) Add Mesh component
+ new_entity.add_component("Mesh")
+ Report.result(Tests.mesh_added, hydra.has_components(new_entity.id, ["Mesh"]))
+
+ # 4) Verify enter/exit game mode
+ helper.enter_game_mode(Tests.enter_game_mode)
+ helper.exit_game_mode(Tests.exit_game_mode)
+
+ # 5) Save, Load and Export level
+ # Save Level
+ general.save_level()
+ # Open Level
+ general.open_level(test_level_name)
+ Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
+ # Export Level
+ general.idle_wait(1.0)
+ general.export_to_engine()
+ level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak")
+ Report.result(Tests.level_exported, os.path.exists(level_pak_file))
+
+ # 6) Remove Mesh component
+ new_entity.remove_component("Mesh")
+ Report.result(Tests.mesh_removed, not hydra.has_components(new_entity.id, ["Mesh"]))
+
+ # 7) Delete entity
+ editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", new_entity.id)
+ test_entity = hydra.find_entity_by_name("Entity1")
+ Report.result(Tests.entity_deleted, len(test_entity) == 0)
+
+ # 8) Open an existing level
+ general.open_level(test_level_name)
+ Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
+
+ # 9) Create a new entity in an existing level
+ entity_position = math.Vector3(200.0, 200.0, 38.0)
+ new_entity_2 = hydra.Entity("Entity2")
+ new_entity_2.create_entity(entity_position, [])
+ test_entity = hydra.find_entity_by_name("Entity2")
+ Report.result(Tests.entity_found, test_entity.IsValid())
+
+ # 10) Save, Load and Export an existing level
+ # Save Level
+ general.save_level()
+ # Open Level
+ general.open_level(test_level_name)
+ Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name)
+ entity_id = hydra.find_entity_by_name(new_entity_2.name)
+ Report.result(Tests.level_edits_present, entity_id == new_entity_2.id)
+ # Export Level
+ general.export_to_engine()
+ level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak")
+ Report.result(Tests.level_exported, os.path.exists(level_pak_file))
+
+
+if __name__ == "__main__":
+ import ImportPathHelper as imports
+
+ imports.init()
+
+ from utils import Report
+
+ Report.start_test(Editor_NewExistingLevels)
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/ImportPathHelper.py b/AutomatedTesting/Gem/PythonTests/smoke/ImportPathHelper.py
new file mode 100644
index 0000000000..70bed6e526
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/ImportPathHelper.py
@@ -0,0 +1,16 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+def init():
+ import os
+ import sys
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../EditorPythonTestTools/editor_python_test_tools')
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/__init__.py b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
new file mode 100644
index 0000000000..6ed3dc4bda
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
@@ -0,0 +1,10 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBuilder.py b/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBuilder.py
new file mode 100644
index 0000000000..da2abff50f
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBuilder.py
@@ -0,0 +1,44 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+LY-124059 : CLI tool - AssetBuilder
+Launch AssetBuilder and Verify the help message
+"""
+
+import os
+import pytest
+import subprocess
+import ly_test_tools.environment.process_utils as process_utils
+
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.usefixtures("automatic_process_killer")
+@pytest.mark.SUITE_smoke
+class TestAssetBuilder(object):
+ @pytest.fixture(autouse=True)
+ def setup_teardown(self, request):
+ def teardown():
+ process_utils.kill_processes_named("AssetBuilder", True)
+
+ request.addfinalizer(teardown)
+
+ @pytest.mark.test_case_id("LY-124059")
+ def test_AssetBuilder(self, request, editor, build_directory):
+ file_path = os.path.join(build_directory, "AssetBuilder")
+ help_message = "AssetBuilder is part of the Asset Processor"
+ # Launch AssetBuilder
+ output = subprocess.run([file_path, "-help"], capture_output=True)
+ assert (
+ len(output.stderr) == 0 and output.returncode == 0
+ ), f"Error occurred while launching {file_path}: {output.stderr}"
+ # Verify help message
+ assert help_message in str(output.stdout), f"Help Message: {help_message} is not present"
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetProcessorBatch.py b/AutomatedTesting/Gem/PythonTests/smoke/test_AssetProcessorBatch.py
new file mode 100644
index 0000000000..ab541b94c1
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_AssetProcessorBatch.py
@@ -0,0 +1,43 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+LY-124061 : CLI tool - AssetProcessorBatch
+Launch AssetProcessorBatch and Shutdown AssetProcessorBatch without any crash
+"""
+
+
+# Import builtin libraries
+import pytest
+import os
+import sys
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../assetpipeline/")
+
+# Import fixtures
+from ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
+
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.usefixtures("automatic_process_killer")
+@pytest.mark.usefixtures("asset_processor")
+@pytest.mark.SUITE_smoke
+class TestsAssetProcessorBatchs(object):
+ @pytest.mark.test_case_id("LY-124061")
+ def test_AssetProcessorBatch(self, asset_processor):
+ """
+ Test Launching AssetProcessorBatch and verifies that is shuts down without issue
+ """
+ # Create a sample asset root so we don't process every asset for every platform
+ asset_processor.create_temp_asset_root()
+ # Launch AssetProcessorBatch, assert batch processing success
+ result, _ = asset_processor.batch_process()
+ assert result, "AP Batch failed"
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_AzTestRunner.py b/AutomatedTesting/Gem/PythonTests/smoke/test_AzTestRunner.py
new file mode 100644
index 0000000000..d1bc44fe2f
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_AzTestRunner.py
@@ -0,0 +1,46 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+LY-124062 : CLI tool - AzTestRunner
+Launch AzTestRunner and Verify the help message
+"""
+
+import os
+import pytest
+import subprocess
+import ly_test_tools.environment.process_utils as process_utils
+
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.usefixtures("automatic_process_killer")
+@pytest.mark.SUITE_smoke
+class TestAzTestRunner(object):
+ @pytest.fixture(autouse=True)
+ def setup_teardown(self, request):
+ def teardown():
+ process_utils.kill_processes_named("AzTestRunner", True)
+
+ request.addfinalizer(teardown)
+
+ @pytest.mark.test_case_id("LY-124062")
+ def test_AzTestRunner(self, request, editor, build_directory):
+ file_path = os.path.join(build_directory, "AzTestRunner")
+ help_message = "OKAY Symbol found: AzRunUnitTests"
+ # Launch AzTestRunner
+ output = subprocess.run(
+ [file_path, "AzTestRunner.Tests", "AzRunUnitTests", "--gtest_list_tests"], capture_output=True
+ )
+ assert (
+ len(output.stderr) == 0 and output.returncode == 0
+ ), f"Error occurred while launching {file_path}: {output.stderr}"
+ # Verify help message
+ assert help_message in str(output.stdout), f"Help Message: {help_message} is not present"
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels.py
new file mode 100644
index 0000000000..85d53d098d
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels.py
@@ -0,0 +1,34 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+import pytest
+import os
+import sys
+
+sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../automatedtesting_shared")
+
+from automatedtesting_shared.base import TestAutomationBase
+import ly_test_tools.environment.file_system as file_system
+
+
+@pytest.mark.SUITE_smoke
+@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.parametrize("level", ["temp_level"])
+class TestAutomation(TestAutomationBase):
+ def test_Editor_NewExistingLevels(self, request, workspace, editor, level, project, launcher_platform):
+ def teardown():
+ file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+ request.addfinalizer(teardown)
+ file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
+ from . import Editor_NewExistingLevels as test_module
+ self._run_test(request, workspace, editor, test_module)
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_PythonBindingsExample.py b/AutomatedTesting/Gem/PythonTests/smoke/test_PythonBindingsExample.py
new file mode 100644
index 0000000000..140e76fc96
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_PythonBindingsExample.py
@@ -0,0 +1,45 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+LY-124064 : CLI tool - PythonBindingsExample
+Launch PythonBindingsExample and Verify the help message
+"""
+
+import os
+import pytest
+import subprocess
+import ly_test_tools.environment.process_utils as process_utils
+
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.usefixtures("automatic_process_killer")
+@pytest.mark.SUITE_smoke
+class TestPythonBindingsExample(object):
+ @pytest.fixture(autouse=True)
+ def setup_teardown(self, request):
+ def teardown():
+ process_utils.kill_processes_named("PythonBindingsExample", True)
+
+ request.addfinalizer(teardown)
+
+ @pytest.mark.test_case_id("LY-124064")
+ def test_PythonBindingsExample(self, request, editor, build_directory):
+ file_path = os.path.join(build_directory, "PythonBindingsExample")
+ help_message = "--help Prints the help text"
+ # Launch PythonBindingsExample
+ output = subprocess.run([file_path, "-help"], capture_output=True)
+ assert (
+ len(output.stderr) == 0 and output.returncode == 1
+ ), f"Error occurred while launching {file_path}: {output.stderr}"
+ # Verify help message
+ assert help_message in str(output.stdout), f"Help Message: {help_message} is not present"
+
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_SerializeContextTools.py b/AutomatedTesting/Gem/PythonTests/smoke/test_SerializeContextTools.py
new file mode 100644
index 0000000000..763d84625d
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_SerializeContextTools.py
@@ -0,0 +1,44 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+LY-124066 : CLI tool - SerializeContextTools
+Launch SerializeContextTools and Verify the help message
+"""
+
+import os
+import pytest
+import subprocess
+import ly_test_tools.environment.process_utils as process_utils
+
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.usefixtures("automatic_process_killer")
+@pytest.mark.SUITE_smoke
+class TestSerializeContextTools(object):
+ @pytest.fixture(autouse=True)
+ def setup_teardown(self, request):
+ def teardown():
+ process_utils.kill_processes_named("SerializeContextTools", True)
+
+ request.addfinalizer(teardown)
+
+ @pytest.mark.test_case_id("LY-124066")
+ def test_SerializeContextTools(self, request, editor, build_directory):
+ file_path = os.path.join(build_directory, "SerializeContextTools")
+ help_message = "Converts a file with an ObjectStream to the new JSON"
+ # Launch SerializeContextTools
+ output = subprocess.run([file_path, "-help"], capture_output=True)
+ assert (
+ len(output.stderr) == 0 and output.returncode == 0
+ ), f"Error occurred while launching {file_path}: {output.stderr}"
+ # Verify help message
+ assert help_message in str(output.stdout), f"Help Message: {help_message} is not present"
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
new file mode 100644
index 0000000000..d1ae1d4ee0
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
@@ -0,0 +1,48 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+LY-124058: Static tool scripts
+Launch Static tool and Verify the help message
+"""
+
+import os
+import pytest
+import subprocess
+import sys
+
+
+def verify_help_message(static_tool):
+ help_message = ["--help", "show this help message and exit"]
+ output = subprocess.run([sys.executable, static_tool, "-h"], capture_output=True)
+ assert (
+ len(output.stderr) == 0 and output.returncode == 0
+ ), f"Error occurred while launching {static_tool}: {output.stderr}"
+ # verify help message
+ for message in help_message:
+ assert message in str(output.stdout), f"Help Message: {message} is not present"
+
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.usefixtures("automatic_process_killer")
+@pytest.mark.SUITE_smoke
+class TestStatictoolScripts(object):
+ @pytest.mark.test_case_id("LY-124058")
+ def test_Statictool_Scripts(self, request, editor):
+ static_tools = [
+ os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "gen_shaders.py"),
+ os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "get_shader_list.py"),
+ os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "pak_shaders.py"),
+ ]
+
+ for tool in static_tools:
+ verify_help_message(tool)
+
\ No newline at end of file
From 4ce7e117a9347e5dc2fc8204bc8ffd6d44530920 Mon Sep 17 00:00:00 2001
From: darapan
Date: Wed, 5 May 2021 00:51:06 -0700
Subject: [PATCH 011/209] "Updating cmakelist.txt to remove extra intendation"
---
AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 4 ++--
.../Gem/PythonTests/smoke/test_Statictool_Scripts.py | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index 26c425fd79..e6fff224d3 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -316,9 +316,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
PATH ${CMAKE_CURRENT_LIST_DIR}/smoke
TIMEOUT 3600
RUNTIME_DEPENDENCIES
- AZ::AssetProcessor
+ AZ::AssetProcessor
AZ::PythonBindingsExample
Legacy::Editor
AutomatedTesting.GameLauncher
AutomatedTesting.Assets
-
+
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
index d1ae1d4ee0..86f5d67478 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
@@ -45,4 +45,4 @@ class TestStatictoolScripts(object):
for tool in static_tools:
verify_help_message(tool)
-
\ No newline at end of file
+
\ No newline at end of file
From 7eb6cc10b6559511927028d9f6c5514b973a99bb Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Wed, 5 May 2021 08:57:39 +0100
Subject: [PATCH 012/209] Made change affect all modifiable containers.
---
.../Serialization/EditContextConstants.inl | 2 --
.../UI/PropertyEditor/PropertyRowWidget.cpp | 22 +++++++++++++------
.../UI/PropertyEditor/PropertyRowWidget.hxx | 5 +++--
Gems/Vegetation/Code/Source/Descriptor.cpp | 2 --
4 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
index 481ae5a91c..90b9ba5afd 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
+++ b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl
@@ -62,8 +62,6 @@ namespace AZ
const static AZ::Crc32 ButtonTooltip = AZ_CRC("ButtonTooltip", 0x1605a7d2);
const static AZ::Crc32 CheckboxTooltip = AZ_CRC("CheckboxTooltip", 0x1159eb78);
const static AZ::Crc32 CheckboxDefaultValue = AZ_CRC("CheckboxDefaultValue", 0x03f117e6);
- //! Emboldens the text and adds a line above this item within the RPE.
- const static AZ::Crc32 RPESectionSeparator = AZ_CRC("RPESectionSeparator", 0xc6249a95);
//! Affects the display order of a node relative to it's parent/children. Higher values display further down (after) lower values. Default is 0, negative values are allowed. Must be applied as an attribute to the EditorData element
const static AZ::Crc32 DisplayOrder = AZ_CRC("DisplayOrder", 0x23660ec2);
//! Specifies whether the UI should support multi-edit for aggregate instances of this property
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
index 5b02e81e6d..faeae0a06d 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
@@ -315,8 +315,6 @@ namespace AzToolsFramework
}
}
- m_isSectionSeparator = false;
-
RefreshAttributesFromNode(true);
// --------------------- HANDLER discovery:
@@ -962,10 +960,6 @@ namespace AzToolsFramework
{
HandleChangeNotifyAttribute(reader, m_sourceNode ? m_sourceNode->GetParent() : nullptr, m_editingCompleteNotifiers);
}
- else if (attributeName == AZ::Edit::Attributes::RPESectionSeparator)
- {
- m_isSectionSeparator = true;
- }
}
void PropertyRowWidget::SetReadOnlyQueryFunction(const ReadOnlyQueryFunction& readOnlyQueryFunction)
@@ -1340,7 +1334,7 @@ namespace AzToolsFramework
bool PropertyRowWidget::IsSectionSeparator() const
{
- return m_isSectionSeparator;
+ return CanBeReordered();
}
bool PropertyRowWidget::GetAppendDefaultLabelToName()
@@ -1686,6 +1680,20 @@ namespace AzToolsFramework
m_nameLabel->setFilter(m_currentFilterString);
}
+ bool PropertyRowWidget::CanChildrenBeReordered() const
+ {
+ return m_containerEditable;
+ }
+
+ bool PropertyRowWidget::CanBeReordered() const
+ {
+ if (!m_parentRow)
+ {
+ return false;
+ }
+
+ return m_parentRow->CanChildrenBeReordered();
+ }
}
#include "UI/PropertyEditor/moc_PropertyRowWidget.cpp"
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
index 2fb695fca5..b6c94dc98b 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
@@ -149,6 +149,9 @@ namespace AzToolsFramework
QLabel* GetNameLabel() { return m_nameLabel; }
void SetIndentSize(int w);
void SetAsCustom(bool custom) { m_custom = custom; }
+
+ bool CanChildrenBeReordered() const;
+ bool CanBeReordered() const;
protected:
int CalculateLabelWidth() const;
@@ -232,8 +235,6 @@ namespace AzToolsFramework
int m_treeIndentation = 14;
int m_leafIndentation = 16;
- bool m_isSectionSeparator = false;
-
QIcon m_iconOpen;
QIcon m_iconClosed;
diff --git a/Gems/Vegetation/Code/Source/Descriptor.cpp b/Gems/Vegetation/Code/Source/Descriptor.cpp
index 45ec25038d..ecda8415e7 100644
--- a/Gems/Vegetation/Code/Source/Descriptor.cpp
+++ b/Gems/Vegetation/Code/Source/Descriptor.cpp
@@ -170,8 +170,6 @@ namespace Vegetation
{
edit->Class(
"Vegetation Descriptor", "Details used to create vegetation instances")
- ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
- ->Attribute(AZ::Edit::Attributes::RPESectionSeparator, true)
// For this ComboBox to actually work, there is a PropertyHandler registration in EditorVegetationSystemComponent.cpp
->DataElement(AZ::Edit::UIHandlers::ComboBox, &Descriptor::m_spawnerType, "Instance Spawner", "The type of instances to spawn")
->Attribute(AZ::Edit::Attributes::GenericValueList, &Descriptor::GetSpawnerTypeList)
From 0e666d046c37a305fa89bb335f7bc43bd4a89356 Mon Sep 17 00:00:00 2001
From: darapan
Date: Wed, 5 May 2021 00:57:51 -0700
Subject: [PATCH 013/209] "Adding new line"
---
AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 1 +
AutomatedTesting/Gem/PythonTests/smoke/__init__.py | 2 +-
.../Gem/PythonTests/smoke/test_Statictool_Scripts.py | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index e6fff224d3..8dfac40c43 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -321,4 +321,5 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
Legacy::Editor
AutomatedTesting.GameLauncher
AutomatedTesting.Assets
+
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/__init__.py b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
index 6ed3dc4bda..79f8fa4422 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
@@ -7,4 +7,4 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-"""
\ No newline at end of file
+"""
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
index 86f5d67478..92be4abeb9 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
@@ -45,4 +45,5 @@ class TestStatictoolScripts(object):
for tool in static_tools:
verify_help_message(tool)
+
\ No newline at end of file
From 2f153f994e2b5be015f661bf81d99e96c3947bab Mon Sep 17 00:00:00 2001
From: darapan
Date: Wed, 5 May 2021 01:12:38 -0700
Subject: [PATCH 014/209] "Adding new line"
---
AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 1 -
AutomatedTesting/Gem/PythonTests/smoke/__init__.py | 2 +-
.../Gem/PythonTests/smoke/test_Statictool_Scripts.py | 2 --
3 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index 8dfac40c43..e6fff224d3 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -321,5 +321,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
Legacy::Editor
AutomatedTesting.GameLauncher
AutomatedTesting.Assets
-
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/__init__.py b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
index 79f8fa4422..6ed3dc4bda 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
@@ -7,4 +7,4 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-"""
+"""
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
index 92be4abeb9..8eac2ff099 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
@@ -45,5 +45,3 @@ class TestStatictoolScripts(object):
for tool in static_tools:
verify_help_message(tool)
-
-
\ No newline at end of file
From 2f0ed6cfb21aac2b99b6b5f303286bccba3ea814 Mon Sep 17 00:00:00 2001
From: darapan
Date: Wed, 5 May 2021 01:17:20 -0700
Subject: [PATCH 015/209] ""
---
AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 1 -
AutomatedTesting/Gem/PythonTests/smoke/__init__.py | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index e6fff224d3..400dca33ce 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -321,4 +321,3 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
Legacy::Editor
AutomatedTesting.GameLauncher
AutomatedTesting.Assets
-
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/__init__.py b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
index 6ed3dc4bda..79f8fa4422 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py
@@ -7,4 +7,4 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-"""
\ No newline at end of file
+"""
From 682bdf684743ddc094cf32ab02a5246b63191eef Mon Sep 17 00:00:00 2001
From: darapan
Date: Wed, 5 May 2021 08:50:34 -0700
Subject: [PATCH 016/209] "Changing testsuite"
---
AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index 400dca33ce..92dcc7dc7f 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -310,8 +310,8 @@ endif()
## Smoke ##
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
- NAME AutomatedTesting::SmokeTest_Periodic
- TEST_SUITE periodic
+ NAME AutomatedTesting::SmokeTest
+ TEST_SUITE smoke
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/smoke
TIMEOUT 3600
From 2b511b68a2538326b199a088d7a4d4cfa94581c4 Mon Sep 17 00:00:00 2001
From: darapan
Date: Wed, 5 May 2021 10:26:11 -0700
Subject: [PATCH 017/209] "Adding AssetBundlerBatch test"
---
.../smoke/test_AssetBundlerBatch.py | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_AssetBundlerBatch.py
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBundlerBatch.py b/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBundlerBatch.py
new file mode 100644
index 0000000000..d361c62f5f
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBundlerBatch.py
@@ -0,0 +1,44 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+LY-124060 : CLI tool - AssetBundlerBatch
+Launch AssetBundlerBatch and Verify the help message
+"""
+
+import os
+import pytest
+import subprocess
+import ly_test_tools.environment.process_utils as process_utils
+
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.usefixtures("automatic_process_killer")
+@pytest.mark.SUITE_smoke
+class TestAssetBundlerBatch(object):
+ @pytest.fixture(autouse=True)
+ def setup_teardown(self, request):
+ def teardown():
+ process_utils.kill_processes_named("AssetBundlerBatch", True)
+
+ request.addfinalizer(teardown)
+
+ @pytest.mark.test_case_id("LY-124060")
+ def test_AssetBundlerBatch(self, request, editor, build_directory):
+ file_path = os.path.join(build_directory, "AssetBundlerBatch")
+ help_message = "Specifies the Seed List file to operate on by path"
+ # Launch AssetBundlerBatch
+ output = subprocess.run([file_path, "--help"], capture_output=True)
+ assert (
+ len(output.stderr) == 0 and output.returncode == 0
+ ), f"Error occurred while launching {file_path}: {output.stderr}"
+ # Verify help message
+ assert help_message in str(output.stdout), f"Help Message: {help_message} is not present"
From aa51233536a55816324da9d41fff6afe4e3970c9 Mon Sep 17 00:00:00 2001
From: puvvadar
Date: Thu, 6 May 2021 16:18:13 -0700
Subject: [PATCH 018/209] Add Asset serialization for Ctrl+G and related net
interfaces
---
.../AzNetworking/TcpTransport/TcpSocket.cpp | 4 +-
.../AutoGen/Multiplayer.AutoPackets.xml | 6 ++
.../MultiplayerEditorSystemComponent.cpp | 93 +++++++++++++++++--
.../Editor/MultiplayerEditorSystemComponent.h | 2 +
.../Source/MultiplayerSystemComponent.cpp | 21 +++++
.../Code/Source/MultiplayerSystemComponent.h | 4 +-
.../Code/Source/MultiplayerToolsModule.cpp | 10 ++
.../Code/Source/MultiplayerToolsModule.h | 5 +-
8 files changed, 132 insertions(+), 13 deletions(-)
diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocket.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocket.cpp
index 78020cb09d..e8c30d0816 100644
--- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocket.cpp
+++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocket.cpp
@@ -116,8 +116,8 @@ namespace AzNetworking
int32_t TcpSocket::Receive(uint8_t* outData, uint32_t size) const
{
- AZ_Assert(size > 0, "Invalid data size for send");
- AZ_Assert(outData != nullptr, "NULL data pointer passed to send");
+ AZ_Assert(size > 0, "Invalid data size for receive");
+ AZ_Assert(outData != nullptr, "NULL data pointer passed to receive");
if (!IsOpen())
{
return SocketOpResultErrorNotOpen;
diff --git a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml
index 5de466899c..21faefa880 100644
--- a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml
+++ b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml
@@ -57,4 +57,10 @@
+
+
+
+
+
+
diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp
index 0850b858a2..15f00bdf80 100644
--- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp
+++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.cpp
@@ -10,23 +10,32 @@
*
*/
+#include
#include
+#include
+#include
#include
#include
+#include
#include
#include
#include
#include
+#include
#include
namespace Multiplayer
{
+ static const AZStd::string_view s_networkInterfaceName("MultiplayerEditorServerInterface");
+
using namespace AzNetworking;
AZ_CVAR(bool, editorsv_enabled, false, nullptr, AZ::ConsoleFunctorFlags::DontReplicate,
"Whether Editor launching a local server to connect to is supported");
AZ_CVAR(AZ::CVarFixedString, editorsv_process, "", nullptr, AZ::ConsoleFunctorFlags::DontReplicate,
"The server executable that should be run. Empty to use the current project's ServerLauncher");
+ AZ_CVAR(AZ::CVarFixedString, sv_serveraddr, "127.0.0.1", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The address of the server to connect to");
+ AZ_CVAR(uint16_t, sv_port, 30091, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The port that the multiplayer editor gem will bind to for traffic");
void MultiplayerEditorSystemComponent::Reflect(AZ::ReflectContext* context)
{
@@ -61,6 +70,16 @@ namespace Multiplayer
{
AzFramework::GameEntityContextEventBus::Handler::BusConnect();
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
+
+ // Setup a network interface handled by MultiplayerSystemComponent
+ if (m_editorNetworkInterface == nullptr)
+ {
+ AZ::Entity* systemEntity = this->GetEntity();
+ MultiplayerSystemComponent* mpSysComponent = systemEntity->FindComponent();
+
+ m_editorNetworkInterface = AZ::Interface::Get()->CreateNetworkInterface(
+ AZ::Name(s_networkInterfaceName), ProtocolType::Tcp, TrustZone::ExternalClientToServer, *mpSysComponent);
+ }
}
void MultiplayerEditorSystemComponent::Deactivate()
@@ -97,25 +116,52 @@ namespace Multiplayer
m_serverProcess->TerminateProcess(0);
m_serverProcess = nullptr;
}
+ if (m_editorNetworkInterface)
+ {
+ // Disconnect the interface, connection management will clean it up
+ m_editorNetworkInterface->Disconnect(m_editorConnId, AzNetworking::DisconnectReason::TerminatedByUser);
+ m_editorConnId = AzNetworking::InvalidConnectionId;
+ }
break;
}
}
void MultiplayerEditorSystemComponent::OnGameEntitiesStarted()
{
+ auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get();
+ if (!prefabEditorEntityOwnershipInterface)
+ {
+ AZ_Error("MultiplayerEditor", prefabEditorEntityOwnershipInterface != nullptr, "PrefabEditorEntityOwnershipInterface unavailable");
+ }
+ const AZStd::vector>& assetData = prefabEditorEntityOwnershipInterface->GetPlayInEditorAssetData();
+
+ AZStd::vector buffer;
+ AZ::IO::ByteContainerStream byteStream(&buffer);
+
+ // Serialize Asset information and AssetData into a potentially large buffer
+ for (auto asset : assetData)
+ {
+ AZ::Data::AssetId assetId = asset.GetId();
+ AZ::Data::AssetType assetType = asset.GetType();
+ const AZStd::string& assetHint = asset.GetHint();
+ AZ::IO::SizeType assetHintSize = assetHint.size();
+ AZ::Data::AssetLoadBehavior assetLoadBehavior = asset.GetAutoLoadBehavior();
+
+ byteStream.Write(sizeof(AZ::Data::AssetId), reinterpret_cast(&assetId));
+ byteStream.Write(sizeof(AZ::Data::AssetType), reinterpret_cast(&assetType));
+ byteStream.Write(sizeof(assetHintSize), reinterpret_cast(&assetHintSize));
+ byteStream.Write(assetHint.size(), assetHint.c_str());
+ byteStream.Write(sizeof(AZ::Data::AssetLoadBehavior), reinterpret_cast(&assetLoadBehavior));
+
+ AZ::Utils::SaveObjectToStream(byteStream, AZ::DataStream::ST_BINARY, asset.GetData(), asset.GetData()->GetType());
+ }
+
// BeginGameMode and Prefab Processing have completed at this point
IMultiplayerTools* mpTools = AZ::Interface::Get();
if (editorsv_enabled && mpTools != nullptr && mpTools->DidProcessNetworkPrefabs())
{
AZ::TickBus::Handler::BusConnect();
- auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get();
- if (!prefabEditorEntityOwnershipInterface)
- {
- AZ_Error("MultiplayerEditor", prefabEditorEntityOwnershipInterface != nullptr, "PrefabEditorEntityOwnershipInterface unavailable");
- }
- const AZStd::vector>& assetData = prefabEditorEntityOwnershipInterface->GetPlayInEditorAssetData();
-
if (assetData.size() > 0)
{
// Assemble the server's path
@@ -154,6 +200,39 @@ namespace Multiplayer
processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE);
}
}
+
+ // Now that the server has launched, attempt to connect the NetworkInterface
+ const AZ::CVarFixedString remoteAddress = sv_serveraddr;
+ m_editorConnId = m_editorNetworkInterface->Connect(
+ AzNetworking::IpAddress(remoteAddress.c_str(), sv_port, AzNetworking::ProtocolType::Tcp));
+
+ // Read the buffer into EditorServerInit packets until we've flushed the whole thing
+ byteStream.Seek(0, AZ::IO::GenericStream::SeekMode::ST_SEEK_BEGIN);
+
+ while (byteStream.GetCurPos() < byteStream.GetLength())
+ {
+ MultiplayerPackets::EditorServerInit packet;
+ AzNetworking::TcpPacketEncodingBuffer& outBuffer = packet.ModifyAssetData();
+
+ // Size the packet's buffer appropriately
+ size_t readSize = TcpPacketEncodingBuffer::GetCapacity();
+ size_t byteStreamSize = byteStream.GetLength() - byteStream.GetCurPos();
+ if (byteStreamSize < readSize)
+ {
+ readSize = byteStreamSize;
+ }
+
+ outBuffer.Resize(readSize);
+ byteStream.Read(readSize, outBuffer.GetBuffer());
+
+ // If we've run out of buffer, mark that we're done
+ if (byteStream.GetCurPos() == byteStream.GetLength())
+ {
+ packet.SetLastUpdate(true);
+ }
+ m_editorNetworkInterface->SendReliablePacket(m_editorConnId, packet);
+ }
+
}
void MultiplayerEditorSystemComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h
index 31ecdf83a3..d43d8747b9 100644
--- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h
+++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorSystemComponent.h
@@ -81,5 +81,7 @@ namespace Multiplayer
IEditor* m_editor = nullptr;
AzFramework::ProcessWatcher* m_serverProcess = nullptr;
+ AzNetworking::ConnectionId m_editorConnId;
+ AzNetworking::INetworkInterface* m_editorNetworkInterface = nullptr;
};
}
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
index 03c661ab03..3c1e142d96 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
+++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
@@ -57,7 +57,9 @@ namespace Multiplayer
using namespace AzNetworking;
static const AZStd::string_view s_networkInterfaceName("MultiplayerNetworkInterface");
+ static const AZStd::string_view s_networkEditorInterfaceName("MultiplayerEditorNetworkInterface");
static constexpr uint16_t DefaultServerPort = 30090;
+ static constexpr uint16_t DefaultServerEditorPort = 30091;
AZ_CVAR(uint16_t, cl_clientport, 0, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The port to bind to for game traffic when connecting to a remote host, a value of 0 will select any available port");
AZ_CVAR(AZ::CVarFixedString, cl_serveraddr, "127.0.0.1", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The address of the remote server or host to connect to");
@@ -397,6 +399,19 @@ namespace Multiplayer
return false;
}
+ bool MultiplayerSystemComponent::HandleRequest
+ (
+ [[maybe_unused]] AzNetworking::IConnection* connection,
+ [[maybe_unused]] const IPacketHeader& packetHeader,
+ [[maybe_unused]] MultiplayerPackets::EditorServerInit& packet
+ )
+ {
+#if !defined(_RELEASE)
+ // Support Editor Server Init for all non-release targets
+#endif
+ return true;
+ }
+
ConnectResult MultiplayerSystemComponent::ValidateConnect
(
[[maybe_unused]] const IpAddress& remoteAddress,
@@ -492,6 +507,12 @@ namespace Multiplayer
{
if (multiplayerType == MultiplayerAgentType::ClientServer || multiplayerType == MultiplayerAgentType::DedicatedServer)
{
+#if !defined(_RELEASE)
+ m_networkEditorInterface = AZ::Interface::Get()->CreateNetworkInterface(
+ AZ::Name(s_networkEditorInterfaceName), ProtocolType::Tcp, TrustZone::ExternalClientToServer, *this);
+ m_networkEditorInterface->Listen(DefaultServerEditorPort);
+#endif
+
m_initEvent.Signal(m_networkInterface);
const AZ::Aabb worldBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-16384.0f), AZ::Vector3(16384.0f));
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h
index f25e530b61..e77fa129b0 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h
+++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h
@@ -72,7 +72,8 @@ namespace Multiplayer
bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::NotifyClientMigration& packet);
bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::EntityMigration& packet);
bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::ReadyForEntityUpdates& packet);
-
+ bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::EditorServerInit& packet);
+
//! IConnectionListener interface
//! @{
AzNetworking::ConnectResult ValidateConnect(const AzNetworking::IpAddress& remoteAddress, const AzNetworking::IPacketHeader& packetHeader, AzNetworking::ISerializer& serializer) override;
@@ -109,6 +110,7 @@ namespace Multiplayer
AZ_CONSOLEFUNC(MultiplayerSystemComponent, DumpStats, AZ::ConsoleFunctorFlags::Null, "Dumps stats for the current multiplayer session");
AzNetworking::INetworkInterface* m_networkInterface = nullptr;
+ AzNetworking::INetworkInterface* m_networkEditorInterface = nullptr;
AZ::ConsoleCommandInvokedEvent::Handler m_consoleCommandHandler;
AZ::ThreadSafeDeque m_cvarCommands;
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.cpp b/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.cpp
index a5df3c1dc5..ae91999a0c 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.cpp
+++ b/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.cpp
@@ -24,6 +24,16 @@ namespace Multiplayer
NetworkPrefabProcessor::Reflect(context);
}
+ void MultiplayerToolsSystemComponent::Activate()
+ {
+ AZ::Interface::Register(this);
+ }
+
+ void MultiplayerToolsSystemComponent::Deactivate()
+ {
+ AZ::Interface::Unregister(this);
+ }
+
bool MultiplayerToolsSystemComponent::DidProcessNetworkPrefabs()
{
return m_didProcessNetPrefabs;
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.h b/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.h
index 82d0415c5a..181a971150 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.h
+++ b/Gems/Multiplayer/Code/Source/MultiplayerToolsModule.h
@@ -31,9 +31,8 @@ namespace Multiplayer
~MultiplayerToolsSystemComponent() override = default;
/// AZ::Component overrides.
- void Activate() override {};
-
- void Deactivate() override {};
+ void Activate() override;
+ void Deactivate() override;
bool DidProcessNetworkPrefabs() override;
From 1f3d0beb387a68ac5ac87c63aafa5105d1f253b6 Mon Sep 17 00:00:00 2001
From: antonmic
Date: Fri, 7 May 2021 18:51:20 -0700
Subject: [PATCH 019/209] work in progress
---
.../Materials/Types/StandardPBR.materialtype | 15 +
.../Types/StandardPBR_ForwardPass.azsl | 15 +-
.../Types/StandardPBR_LowEndForward.azsl | 15 +
.../Types/StandardPBR_LowEndForward.shader | 53 +++
.../StandardPBR_LowEndForward_EDS.shader | 53 +++
.../Feature/Common/Assets/Passes/Forward.pass | 16 -
.../Assets/Passes/LightAdaptationParent.pass | 146 ++++++++
.../Common/Assets/Passes/LowEndForward.pass | 133 +++++++
.../Common/Assets/Passes/LowEndPipeline.pass | 344 ++++++++++++++++++
.../Common/Assets/Passes/OpaqueParent.pass | 11 +-
.../Assets/Passes/PassTemplates.azasset | 12 +
.../Assets/Passes/PostProcessParent.pass | 90 +----
.../Feature/Common/Assets/Passes/SkyBox.pass | 5 -
.../Atom/Features/PBR/ForwardPassOutput.azsli | 17 +
.../PBR/LowEndForwardPassOutput.azsli | 32 ++
.../Atom/Features/ShaderQualityOptions.azsli | 24 ++
.../Reflections/ReflectionComposite.azsl | 15 +-
.../Common/Assets/Shaders/SkyBox/SkyBox.azsl | 2 -
.../atom_feature_common_asset_files.cmake | 10 +
19 files changed, 887 insertions(+), 121 deletions(-)
create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl
create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.shader
create mode 100644 Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward_EDS.shader
create mode 100644 Gems/Atom/Feature/Common/Assets/Passes/LightAdaptationParent.pass
create mode 100644 Gems/Atom/Feature/Common/Assets/Passes/LowEndForward.pass
create mode 100644 Gems/Atom/Feature/Common/Assets/Passes/LowEndPipeline.pass
create mode 100644 Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli
create mode 100644 Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
index e071a793a5..fa5c94c606 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
@@ -77,6 +77,13 @@
],
"properties": {
"general": [
+ {
+ "id": "useLowEndShader",
+ "displayName": "Use Low End",
+ "description": "Whether to use the low end shader.",
+ "type": "Bool",
+ "defaultValue": false
+ },
{
"id": "applySpecularAA",
"displayName": "Apply Specular AA",
@@ -1175,6 +1182,14 @@
"file": "./StandardPBR_ForwardPass_EDS.shader",
"tag": "ForwardPass_EDS"
},
+ {
+ "file": "./StandardPBR_LowEndForward.shader",
+ "tag": "LowEndForward"
+ },
+ {
+ "file": "./StandardPBR_LowEndForward_EDS.shader",
+ "tag": "LowEndForward_EDS"
+ },
{
"file": "Shaders/Shadow/Shadowmap.shader",
"tag": "Shadowmap"
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl
index d3bc72d162..bb4e4cdaab 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl
@@ -10,6 +10,8 @@
*
*/
+#include "Atom/Features/ShaderQualityOptions.azsli"
+
#include "StandardPBR_Common.azsli"
// SRGs
@@ -306,13 +308,18 @@ ForwardPassOutputWithDepth StandardPbr_ForwardPassPS(VSOutput IN, bool isFrontFa
PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth);
+#ifdef UNIFIED_FORWARD_OUTPUT
+ OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb;
+ OUT.m_color.a = 1.0f;
+ OUT.m_depth = depth;
+#else
OUT.m_diffuseColor = lightingOutput.m_diffuseColor;
OUT.m_specularColor = lightingOutput.m_specularColor;
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
OUT.m_depth = depth;
-
+#endif
return OUT;
}
@@ -324,12 +331,16 @@ ForwardPassOutput StandardPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace :
PbrLightingOutput lightingOutput = ForwardPassPS_Common(IN, isFrontFace, depth);
+#ifdef UNIFIED_FORWARD_OUTPUT
+ OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb;
+ OUT.m_color.a = 1.0f;
+#else
OUT.m_diffuseColor = lightingOutput.m_diffuseColor;
OUT.m_specularColor = lightingOutput.m_specularColor;
OUT.m_specularF0 = lightingOutput.m_specularF0;
OUT.m_albedo = lightingOutput.m_albedo;
OUT.m_normal = lightingOutput.m_normal;
-
+#endif
return OUT;
}
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl
new file mode 100644
index 0000000000..a690cbf84a
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl
@@ -0,0 +1,15 @@
+/*
+* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+* its licensors.
+*
+* For complete copyright and license terms please see the LICENSE at the root of this
+* distribution (the "License"). All use of this software is governed by the License,
+* or, if provided, by the license below or the license accompanying this file. Do not
+* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*
+*/
+
+#define QUALITY_LOW_END 1
+
+#include "StandardPBR_ForwardPass.azsl"
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.shader b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.shader
new file mode 100644
index 0000000000..19538e5db3
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.shader
@@ -0,0 +1,53 @@
+{
+ "Source" : "./StandardPBR_LowEndForward.azsl",
+
+ "DepthStencilState" :
+ {
+ "Depth" :
+ {
+ "Enable" : true,
+ "CompareFunc" : "GreaterEqual"
+ },
+ "Stencil" :
+ {
+ "Enable" : true,
+ "ReadMask" : "0x00",
+ "WriteMask" : "0xFF",
+ "FrontFace" :
+ {
+ "Func" : "Always",
+ "DepthFailOp" : "Keep",
+ "FailOp" : "Keep",
+ "PassOp" : "Replace"
+ },
+ "BackFace" :
+ {
+ "Func" : "Always",
+ "DepthFailOp" : "Keep",
+ "FailOp" : "Keep",
+ "PassOp" : "Replace"
+ }
+ }
+ },
+
+ "CompilerHints" : {
+ "DisableOptimizations" : false
+ },
+
+ "ProgramSettings":
+ {
+ "EntryPoints":
+ [
+ {
+ "name": "StandardPbr_ForwardPassVS",
+ "type": "Vertex"
+ },
+ {
+ "name": "StandardPbr_ForwardPassPS",
+ "type": "Fragment"
+ }
+ ]
+ },
+
+ "DrawList" : "lowEndForward"
+}
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward_EDS.shader b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward_EDS.shader
new file mode 100644
index 0000000000..1b5f014d0e
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward_EDS.shader
@@ -0,0 +1,53 @@
+{
+ "Source" : "./StandardPBR_LowEndForward.azsl",
+
+ "DepthStencilState" :
+ {
+ "Depth" :
+ {
+ "Enable" : true,
+ "CompareFunc" : "GreaterEqual"
+ },
+ "Stencil" :
+ {
+ "Enable" : true,
+ "ReadMask" : "0x00",
+ "WriteMask" : "0xFF",
+ "FrontFace" :
+ {
+ "Func" : "Always",
+ "DepthFailOp" : "Keep",
+ "FailOp" : "Keep",
+ "PassOp" : "Replace"
+ },
+ "BackFace" :
+ {
+ "Func" : "Always",
+ "DepthFailOp" : "Keep",
+ "FailOp" : "Keep",
+ "PassOp" : "Replace"
+ }
+ }
+ },
+
+ "CompilerHints" : {
+ "DisableOptimizations" : false
+ },
+
+ "ProgramSettings":
+ {
+ "EntryPoints":
+ [
+ {
+ "name": "StandardPbr_ForwardPassVS",
+ "type": "Vertex"
+ },
+ {
+ "name": "StandardPbr_ForwardPassPS_EDS",
+ "type": "Fragment"
+ }
+ ]
+ },
+
+ "DrawList" : "lowEndForward"
+}
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/Forward.pass b/Gems/Atom/Feature/Common/Assets/Passes/Forward.pass
index 31a8ed1879..3dcc90ac5c 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/Forward.pass
+++ b/Gems/Atom/Feature/Common/Assets/Passes/Forward.pass
@@ -148,22 +148,6 @@
},
"LoadAction": "Clear"
}
- },
- {
- "Name": "ScatterDistanceOutput",
- "SlotType": "Output",
- "ScopeAttachmentUsage": "RenderTarget",
- "LoadStoreAction": {
- "ClearValue": {
- "Value": [
- 0.0,
- 0.0,
- 0.0,
- 0.0
- ]
- },
- "LoadAction": "Clear"
- }
}
],
"ImageAttachments": [
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/LightAdaptationParent.pass b/Gems/Atom/Feature/Common/Assets/Passes/LightAdaptationParent.pass
new file mode 100644
index 0000000000..3e804d23e2
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Passes/LightAdaptationParent.pass
@@ -0,0 +1,146 @@
+{
+ "Type": "JsonSerialization",
+ "Version": 1,
+ "ClassName": "PassAsset",
+ "ClassData": {
+ "PassTemplate": {
+ "Name": "LightAdaptationParentTemplate",
+ "PassClass": "ParentPass",
+ "Slots": [
+ // Inputs...
+ {
+ "Name": "LightingInput",
+ "SlotType": "Input"
+ },
+ // SwapChain here is only used to reference the frame height and format
+ {
+ "Name": "SwapChainOutput",
+ "SlotType": "InputOutput"
+ },
+ // Outputs...
+ {
+ "Name": "Output",
+ "SlotType": "Output"
+ },
+ // Debug Outputs...
+ {
+ "Name": "LuminanceMipChainOutput",
+ "SlotType": "Output"
+ }
+ ],
+ "Connections": [
+ {
+ "LocalSlot": "Output",
+ "AttachmentRef": {
+ "Pass": "DisplayMapperPass",
+ "Attachment": "Output"
+ }
+ },
+ {
+ "LocalSlot": "LuminanceMipChainOutput",
+ "AttachmentRef": {
+ "Pass": "DownsampleLuminanceMipChain",
+ "Attachment": "MipChainInputOutput"
+ }
+ }
+ ],
+ "PassRequests": [
+ {
+ "Name": "DownsampleLuminanceMinAvgMax",
+ "TemplateName": "DownsampleLuminanceMinAvgMaxCS",
+ "Connections": [
+ {
+ "LocalSlot": "Input",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "LightingInput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "DownsampleLuminanceMipChain",
+ "TemplateName": "DownsampleMipChainTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "MipChainInputOutput",
+ "AttachmentRef": {
+ "Pass": "DownsampleLuminanceMinAvgMax",
+ "Attachment": "Output"
+ }
+ }
+ ],
+ "PassData": {
+ "$type": "DownsampleMipChainPassData",
+ "ShaderAsset": {
+ "FilePath": "Shaders/PostProcessing/DownsampleMinAvgMaxCS.shader"
+ }
+ }
+ },
+ {
+ "Name": "EyeAdaptationPass",
+ "TemplateName": "EyeAdaptationTemplate",
+ "Enabled": false,
+ "Connections": [
+ {
+ "LocalSlot": "SceneLuminanceInput",
+ "AttachmentRef": {
+ "Pass": "DownsampleLuminanceMipChain",
+ "Attachment": "MipChainInputOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "LookModificationTransformPass",
+ "TemplateName": "LookModificationTransformTemplate",
+ "Enabled": true,
+ "Connections": [
+ {
+ "LocalSlot": "Input",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "LightingInput"
+ }
+ },
+ {
+ "LocalSlot": "EyeAdaptationDataInput",
+ "AttachmentRef": {
+ "Pass": "EyeAdaptationPass",
+ "Attachment": "EyeAdaptationDataInputOutput"
+ }
+ },
+ {
+ "LocalSlot": "SwapChainOutput",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "SwapChainOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "DisplayMapperPass",
+ "TemplateName": "DisplayMapperTemplate",
+ "Enabled": true,
+ "Connections": [
+ {
+ "LocalSlot": "Input",
+ "AttachmentRef": {
+ "Pass": "LookModificationTransformPass",
+ "Attachment": "Output"
+ }
+ },
+ {
+ "LocalSlot": "SwapChainOutput",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "SwapChainOutput"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/LowEndForward.pass b/Gems/Atom/Feature/Common/Assets/Passes/LowEndForward.pass
new file mode 100644
index 0000000000..4b865fcb6d
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Passes/LowEndForward.pass
@@ -0,0 +1,133 @@
+{
+ "Type": "JsonSerialization",
+ "Version": 1,
+ "ClassName": "PassAsset",
+ "ClassData": {
+ "PassTemplate": {
+ "Name": "LowEndForwardPassTemplate",
+ "PassClass": "RasterPass",
+ "Slots": [
+ // Inputs...
+ {
+ "Name": "BRDFTextureInput",
+ "ShaderInputName": "m_brdfMap",
+ "SlotType": "Input",
+ "ScopeAttachmentUsage": "Shader"
+ },
+ {
+ "Name": "DirectionalLightShadowmap",
+ "ShaderInputName": "m_directionalLightShadowmap",
+ "SlotType": "Input",
+ "ScopeAttachmentUsage": "Shader",
+ "ImageViewDesc": {
+ "IsArray": 1
+ }
+ },
+ {
+ "Name": "ExponentialShadowmapDirectional",
+ "ShaderInputName": "m_directionalLightExponentialShadowmap",
+ "SlotType": "Input",
+ "ScopeAttachmentUsage": "Shader",
+ "ImageViewDesc": {
+ "IsArray": 1
+ }
+ },
+ {
+ "Name": "ProjectedShadowmap",
+ "ShaderInputName": "m_projectedShadowmaps",
+ "SlotType": "Input",
+ "ScopeAttachmentUsage": "Shader",
+ "ImageViewDesc": {
+ "IsArray": 1
+ }
+ },
+ {
+ "Name": "ExponentialShadowmapProjected",
+ "ShaderInputName": "m_projectedExponentialShadowmap",
+ "SlotType": "Input",
+ "ScopeAttachmentUsage": "Shader",
+ "ImageViewDesc": {
+ "IsArray": 1
+ }
+ },
+ {
+ "Name": "TileLightData",
+ "SlotType": "Input",
+ "ShaderInputName": "m_tileLightData",
+ "ScopeAttachmentUsage": "Shader"
+ },
+ {
+ "Name": "LightListRemapped",
+ "SlotType": "Input",
+ "ShaderInputName": "m_lightListRemapped",
+ "ScopeAttachmentUsage": "Shader"
+ },
+ // Input/Outputs...
+ {
+ "Name": "DepthStencilInputOutput",
+ "SlotType": "InputOutput",
+ "ScopeAttachmentUsage": "DepthStencil"
+ },
+ // Outputs...
+ {
+ "Name": "LightingOutput",
+ "SlotType": "Output",
+ "ScopeAttachmentUsage": "RenderTarget",
+ "LoadStoreAction": {
+ "ClearValue": {
+ "Value": [
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "LoadAction": "Clear"
+ }
+ }
+ ],
+ "ImageAttachments": [
+ {
+ "Name": "LightingAttachment",
+ "SizeSource": {
+ "Source": {
+ "Pass": "Parent",
+ "Attachment": "SwapChainOutput"
+ }
+ },
+ "MultisampleSource": {
+ "Pass": "This",
+ "Attachment": "DepthStencilInputOutput"
+ },
+ "ImageDescriptor": {
+ "Format": "R16G16B16A16_FLOAT",
+ "SharedQueueMask": "Graphics"
+ }
+ },
+ {
+ "Name": "BRDFTexture",
+ "Lifetime": "Imported",
+ "AssetRef": {
+ "FilePath": "Textures/BRDFTexture.attimage"
+ }
+ }
+ ],
+ "Connections": [
+ {
+ "LocalSlot": "LightingOutput",
+ "AttachmentRef": {
+ "Pass": "This",
+ "Attachment": "LightingAttachment"
+ }
+ },
+ {
+ "LocalSlot": "BRDFTextureInput",
+ "AttachmentRef": {
+ "Pass": "This",
+ "Attachment": "BRDFTexture"
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/LowEndPipeline.pass b/Gems/Atom/Feature/Common/Assets/Passes/LowEndPipeline.pass
new file mode 100644
index 0000000000..b19569fb9d
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Passes/LowEndPipeline.pass
@@ -0,0 +1,344 @@
+{
+ "Type": "JsonSerialization",
+ "Version": 1,
+ "ClassName": "PassAsset",
+ "ClassData": {
+ "PassTemplate": {
+ "Name": "LowEndPipelineTemplate",
+ "PassClass": "ParentPass",
+ "Slots": [
+ {
+ "Name": "SwapChainOutput",
+ "SlotType": "InputOutput",
+ "ScopeAttachmentUsage": "RenderTarget"
+ }
+ ],
+ "PassRequests": [
+ {
+ "Name": "MorphTargetPass",
+ "TemplateName": "MorphTargetPassTemplate"
+ },
+ {
+ "Name": "SkinningPass",
+ "TemplateName": "SkinningPassTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "SkinnedMeshOutputStream",
+ "AttachmentRef": {
+ "Pass": "MorphTargetPass",
+ "Attachment": "MorphTargetDeltaOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "DepthPrePass",
+ "TemplateName": "DepthMSAAParentTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "SkinnedMeshes",
+ "AttachmentRef": {
+ "Pass": "SkinningPass",
+ "Attachment": "SkinnedMeshOutputStream"
+ }
+ },
+ {
+ "LocalSlot": "SwapChainOutput",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "SwapChainOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "LightCullingPass",
+ "TemplateName": "LightCullingParentTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "SkinnedMeshes",
+ "AttachmentRef": {
+ "Pass": "SkinningPass",
+ "Attachment": "SkinnedMeshOutputStream"
+ }
+ },
+ {
+ "LocalSlot": "DepthMSAA",
+ "AttachmentRef": {
+ "Pass": "DepthPrePass",
+ "Attachment": "DepthMSAA"
+ }
+ },
+ {
+ "LocalSlot": "SwapChainOutput",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "SwapChainOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "ShadowPass",
+ "TemplateName": "ShadowParentTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "SkinnedMeshes",
+ "AttachmentRef": {
+ "Pass": "SkinningPass",
+ "Attachment": "SkinnedMeshOutputStream"
+ }
+ },
+ {
+ "LocalSlot": "SwapChainOutput",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "SwapChainOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "ForwardPass",
+ "TemplateName": "LowEndForwardPassTemplate",
+ "Connections": [
+ // Inputs...
+ {
+ "LocalSlot": "DirectionalLightShadowmap",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "DirectionalShadowmap"
+ }
+ },
+ {
+ "LocalSlot": "ExponentialShadowmapDirectional",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "DirectionalESM"
+ }
+ },
+ {
+ "LocalSlot": "ProjectedShadowmap",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "ProjectedShadowmap"
+ }
+ },
+ {
+ "LocalSlot": "ExponentialShadowmapProjected",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "ProjectedESM"
+ }
+ },
+ {
+ "LocalSlot": "TileLightData",
+ "AttachmentRef": {
+ "Pass": "LightCullingPass",
+ "Attachment": "TileLightData"
+ }
+ },
+ {
+ "LocalSlot": "LightListRemapped",
+ "AttachmentRef": {
+ "Pass": "LightCullingPass",
+ "Attachment": "LightListRemapped"
+ }
+ },
+ // Input/Outputs...
+ {
+ "LocalSlot": "DepthStencilInputOutput",
+ "AttachmentRef": {
+ "Pass": "DepthPrePass",
+ "Attachment": "DepthMSAA"
+ }
+ }
+ ],
+ "PassData": {
+ "$type": "RasterPassData",
+ "DrawListTag": "lowEndForward",
+ "PipelineViewTag": "MainCamera",
+ "PassSrgAsset": {
+ "FilePath": "shaderlib/atom/features/pbr/forwardpasssrg.azsli:PassSrg"
+ }
+ }
+ },
+ {
+ "Name": "SkyBoxPass",
+ "TemplateName": "SkyBoxTemplate",
+ "Enabled": true,
+ "Connections": [
+ {
+ "LocalSlot": "SpecularInputOutput",
+ "AttachmentRef": {
+ "Pass": "ForwardPass",
+ "Attachment": "LightingOutput"
+ }
+ },
+ {
+ "LocalSlot": "SkyBoxDepth",
+ "AttachmentRef": {
+ "Pass": "ForwardPass",
+ "Attachment": "DepthStencilInputOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "MSAAResolvePass",
+ "TemplateName": "MSAAResolveColorTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "Input",
+ "AttachmentRef": {
+ "Pass": "SkyBoxPass",
+ "Attachment": "SpecularInputOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "TransparentPass",
+ "TemplateName": "TransparentParentTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "DirectionalShadowmap",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "DirectionalShadowmap"
+ }
+ },
+ {
+ "LocalSlot": "DirectionalESM",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "DirectionalESM"
+ }
+ },
+ {
+ "LocalSlot": "ProjectedShadowmap",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "ProjectedShadowmap"
+ }
+ },
+ {
+ "LocalSlot": "ProjectedESM",
+ "AttachmentRef": {
+ "Pass": "ShadowPass",
+ "Attachment": "ProjectedESM"
+ }
+ },
+ {
+ "LocalSlot": "TileLightData",
+ "AttachmentRef": {
+ "Pass": "LightCullingPass",
+ "Attachment": "TileLightData"
+ }
+ },
+ {
+ "LocalSlot": "LightListRemapped",
+ "AttachmentRef": {
+ "Pass": "LightCullingPass",
+ "Attachment": "LightListRemapped"
+ }
+ },
+ {
+ "LocalSlot": "DepthStencil",
+ "AttachmentRef": {
+ "Pass": "DepthPrePass",
+ "Attachment": "Depth"
+ }
+ },
+ {
+ "LocalSlot": "InputOutput",
+ "AttachmentRef": {
+ "Pass": "MSAAResolvePass",
+ "Attachment": "Output"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "LightAdaptation",
+ "TemplateName": "LightAdaptationParentTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "LightingInput",
+ "AttachmentRef": {
+ "Pass": "TransparentPass",
+ "Attachment": "InputOutput"
+ }
+ },
+ {
+ "LocalSlot": "SwapChainOutput",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "SwapChainOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "AuxGeomPass",
+ "TemplateName": "AuxGeomPassTemplate",
+ "Enabled": true,
+ "Connections": [
+ {
+ "LocalSlot": "ColorInputOutput",
+ "AttachmentRef": {
+ "Pass": "LightAdaptation",
+ "Attachment": "Output"
+ }
+ },
+ {
+ "LocalSlot": "DepthInputOutput",
+ "AttachmentRef": {
+ "Pass": "DepthPrePass",
+ "Attachment": "Depth"
+ }
+ }
+ ],
+ "PassData": {
+ "$type": "RasterPassData",
+ "DrawListTag": "auxgeom",
+ "PipelineViewTag": "MainCamera"
+ }
+ },
+ {
+ "Name": "UIPass",
+ "TemplateName": "UIParentTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "InputOutput",
+ "AttachmentRef": {
+ "Pass": "AuxGeomPass",
+ "Attachment": "ColorInputOutput"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "CopyToSwapChain",
+ "TemplateName": "FullscreenCopyTemplate",
+ "Connections": [
+ {
+ "LocalSlot": "Input",
+ "AttachmentRef": {
+ "Pass": "UIPass",
+ "Attachment": "InputOutput"
+ }
+ },
+ {
+ "LocalSlot": "Output",
+ "AttachmentRef": {
+ "Pass": "Parent",
+ "Attachment": "SwapChainOutput"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/OpaqueParent.pass b/Gems/Atom/Feature/Common/Assets/Passes/OpaqueParent.pass
index dda120e164..40d6a51e77 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/OpaqueParent.pass
+++ b/Gems/Atom/Feature/Common/Assets/Passes/OpaqueParent.pass
@@ -315,13 +315,6 @@
"Attachment": "SpecularInputOutput"
}
},
- {
- "LocalSlot": "ReflectionInputOutput",
- "AttachmentRef": {
- "Pass": "ReflectionsPass",
- "Attachment": "ReflectionOutput"
- }
- },
{
"LocalSlot": "SkyBoxDepth",
"AttachmentRef": {
@@ -338,8 +331,8 @@
{
"LocalSlot": "ReflectionInput",
"AttachmentRef": {
- "Pass": "SkyBoxPass",
- "Attachment": "ReflectionInputOutput"
+ "Pass": "ReflectionsPass",
+ "Attachment": "ReflectionOutput"
}
},
{
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset b/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset
index b83ab65ff2..2421d7fbe7 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset
+++ b/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset
@@ -483,6 +483,18 @@
{
"Name": "UIParentTemplate",
"Path": "Passes/UIParent.pass"
+ },
+ {
+ "Name": "LightAdaptationParentTemplate",
+ "Path": "Passes/LightAdaptationParent.pass"
+ },
+ {
+ "Name": "LowEndForwardPassTemplate",
+ "Path": "Passes/LowEndForward.pass"
+ },
+ {
+ "Name": "LowEndPipelineTemplate",
+ "Path": "Passes/LowEndPipeline.pass"
}
]
}
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass b/Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass
index 37b1ee5c5a..36f7f1e985 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass
+++ b/Gems/Atom/Feature/Common/Assets/Passes/PostProcessParent.pass
@@ -40,7 +40,7 @@
{
"LocalSlot": "Output",
"AttachmentRef": {
- "Pass": "DisplayMapperPass",
+ "Pass": "LightAdaptation",
"Attachment": "Output"
}
},
@@ -54,8 +54,8 @@
{
"LocalSlot": "LuminanceMipChainOutput",
"AttachmentRef": {
- "Pass": "DownsampleLuminanceMipChain",
- "Attachment": "MipChainInputOutput"
+ "Pass": "LightAdaptation",
+ "Attachment": "LuminanceMipChainOutput"
}
}
],
@@ -115,94 +115,16 @@
}
]
},
- // Everything before this point deals in raw lighting values
- // ---------------------------------------------------------
- // Everything after starts to map to values we see on screen
{
- "Name": "DownsampleLuminanceMinAvgMax",
- "TemplateName": "DownsampleLuminanceMinAvgMaxCS",
+ "Name": "LightAdaptation",
+ "TemplateName": "LightAdaptationParentTemplate",
"Connections": [
{
- "LocalSlot": "Input",
+ "LocalSlot": "LightingInput",
"AttachmentRef": {
"Pass": "BloomPass",
"Attachment": "InputOutput"
}
- }
- ]
- },
- {
- "Name": "DownsampleLuminanceMipChain",
- "TemplateName": "DownsampleMipChainTemplate",
- "Connections": [
- {
- "LocalSlot": "MipChainInputOutput",
- "AttachmentRef": {
- "Pass": "DownsampleLuminanceMinAvgMax",
- "Attachment": "Output"
- }
- }
- ],
- "PassData": {
- "$type": "DownsampleMipChainPassData",
- "ShaderAsset": {
- "FilePath": "Shaders/PostProcessing/DownsampleMinAvgMaxCS.shader"
- }
- }
- },
- {
- "Name": "EyeAdaptationPass",
- "TemplateName": "EyeAdaptationTemplate",
- "Enabled": false,
- "Connections": [
- {
- "LocalSlot": "SceneLuminanceInput",
- "AttachmentRef": {
- "Pass": "DownsampleLuminanceMipChain",
- "Attachment": "MipChainInputOutput"
- }
- }
- ]
- },
- {
- "Name": "LookModificationTransformPass",
- "TemplateName": "LookModificationTransformTemplate",
- "Enabled": true,
- "Connections": [
- {
- "LocalSlot": "Input",
- "AttachmentRef": {
- "Pass": "BloomPass",
- "Attachment": "InputOutput"
- }
- },
- {
- "LocalSlot": "EyeAdaptationDataInput",
- "AttachmentRef": {
- "Pass": "EyeAdaptationPass",
- "Attachment": "EyeAdaptationDataInputOutput"
- }
- },
- {
- "LocalSlot": "SwapChainOutput",
- "AttachmentRef": {
- "Pass": "Parent",
- "Attachment": "SwapChainOutput"
- }
- }
- ]
- },
- {
- "Name": "DisplayMapperPass",
- "TemplateName": "DisplayMapperTemplate",
- "Enabled": true,
- "Connections": [
- {
- "LocalSlot": "Input",
- "AttachmentRef": {
- "Pass": "LookModificationTransformPass",
- "Attachment": "Output"
- }
},
{
"LocalSlot": "SwapChainOutput",
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass b/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
index 57f442e5de..fb16271ba7 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
+++ b/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
@@ -12,11 +12,6 @@
"SlotType": "InputOutput",
"ScopeAttachmentUsage": "RenderTarget"
},
- {
- "Name": "ReflectionInputOutput",
- "SlotType": "InputOutput",
- "ScopeAttachmentUsage": "RenderTarget"
- },
{
"Name": "SkyBoxDepth",
"SlotType": "InputOutput",
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/ForwardPassOutput.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/ForwardPassOutput.azsli
index acc215f1c9..5821deb3b1 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/ForwardPassOutput.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/ForwardPassOutput.azsli
@@ -10,6 +10,21 @@
*
*/
+#ifdef UNIFIED_FORWARD_OUTPUT
+
+struct ForwardPassOutput
+{
+ float4 m_color : SV_Target0;
+};
+
+struct ForwardPassOutputWithDepth
+{
+ float4 m_color : SV_Target0;
+ float m_depth : SV_Depth;
+};
+
+#else
+
struct ForwardPassOutput
{
float4 m_diffuseColor : SV_Target0; //!< RGB = Diffuse Lighting, A = Blend Alpha (for blended surfaces) OR A = special encoding of surfaceScatteringFactor, m_subsurfaceScatteringQuality, o_enableSubsurfaceScattering
@@ -30,3 +45,5 @@ struct ForwardPassOutputWithDepth
float4 m_normal : SV_Target4;
float m_depth : SV_Depth;
};
+
+#endif
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli
new file mode 100644
index 0000000000..acc215f1c9
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli
@@ -0,0 +1,32 @@
+/*
+* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+* its licensors.
+*
+* For complete copyright and license terms please see the LICENSE at the root of this
+* distribution (the "License"). All use of this software is governed by the License,
+* or, if provided, by the license below or the license accompanying this file. Do not
+* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*
+*/
+
+struct ForwardPassOutput
+{
+ float4 m_diffuseColor : SV_Target0; //!< RGB = Diffuse Lighting, A = Blend Alpha (for blended surfaces) OR A = special encoding of surfaceScatteringFactor, m_subsurfaceScatteringQuality, o_enableSubsurfaceScattering
+ float4 m_specularColor : SV_Target1; //!< RGB = Specular Lighting, A = Unused
+ float4 m_albedo : SV_Target2; //!< RGB = Surface albedo pre-multiplied by other factors that will be multiplied later by diffuse GI, A = specularOcclusion
+ float4 m_specularF0 : SV_Target3; //!< RGB = Specular F0, A = roughness
+ float4 m_normal : SV_Target4; //!< RGB10 = EncodeNormalSignedOctahedron(worldNormal), A2 = multiScatterCompensationEnabled
+};
+
+struct ForwardPassOutputWithDepth
+{
+ // See above for descriptions of special encodings
+
+ float4 m_diffuseColor : SV_Target0;
+ float4 m_specularColor : SV_Target1;
+ float4 m_albedo : SV_Target2;
+ float4 m_specularF0 : SV_Target3;
+ float4 m_normal : SV_Target4;
+ float m_depth : SV_Depth;
+};
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
new file mode 100644
index 0000000000..907e67ada5
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
@@ -0,0 +1,24 @@
+/*
+* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+* its licensors.
+*
+* For complete copyright and license terms please see the LICENSE at the root of this
+* distribution (the "License"). All use of this software is governed by the License,
+* or, if provided, by the license below or the license accompanying this file. Do not
+* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*
+*/
+
+#pragma once
+
+// These are a list of quality options to specify as macros (either in azsl or in shader files)
+//
+// QUALITY_LOW_END
+
+#ifdef QUALITY_LOW_END
+
+#define UNIFIED_FORWARD_OUTPUT 1
+
+#endif
+
diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionComposite.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionComposite.azsl
index 92f8c3f638..865d657d85 100644
--- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionComposite.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionComposite.azsl
@@ -53,13 +53,22 @@ PSOutput MainPS(VSOutput IN)
uint width, height, samples;
PassSrg::m_reflection.GetDimensions(width, height, samples);
+ float nonZeroSamples = 0.0f;
for (uint sampleIndex = 0; sampleIndex < samples; ++sampleIndex)
{
- reflection += PassSrg::m_reflection.Load(IN.m_position.xy, sampleIndex).rgb;
+ float3 reflectionSample = PassSrg::m_reflection.Load(IN.m_position.xy, sampleIndex).rgb;
+ if(any(reflectionSample))
+ {
+ reflection += reflectionSample;
+ nonZeroSamples += 1.0f;
+ }
+ }
+
+ if(nonZeroSamples != 0.0f)
+ {
+ reflection /= nonZeroSamples;
}
- reflection /= samples;
-
PSOutput OUT;
OUT.m_color = float4(reflection, 1.0f);
return OUT;
diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
index 1ee30a4f98..a7de426374 100644
--- a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
@@ -102,7 +102,6 @@ float3 GetCubemapCoords(float3 original)
struct PSOutput
{
float4 m_specular : SV_Target0;
- float4 m_reflection : SV_Target1;
};
PSOutput MainPS(VSOutput input)
@@ -163,6 +162,5 @@ PSOutput MainPS(VSOutput input)
PSOutput OUT;
OUT.m_specular = float4(color, 1.0);
- OUT.m_reflection = float4(color, 1.0);
return OUT;
}
diff --git a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake
index f14fb4f4a0..6902d456ff 100644
--- a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake
+++ b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake
@@ -52,6 +52,8 @@ set(FILES
Materials/Types/StandardPBR_ForwardPass_EDS.shader
Materials/Types/StandardPBR_HandleOpacityDoubleSided.lua
Materials/Types/StandardPBR_HandleOpacityMode.lua
+ Materials/Types/StandardPBR_LowEndForward.azsl
+ Materials/Types/StandardPBR_LowEndForward.shader
Materials/Types/StandardPBR_ParallaxState.lua
Materials/Types/StandardPBR_Roughness.lua
Materials/Types/StandardPBR_ShaderEnable.lua
@@ -116,6 +118,7 @@ set(FILES
Passes/DiffuseProbeGridBlendDistance.pass
Passes/DiffuseProbeGridBlendIrradiance.pass
Passes/DiffuseProbeGridBorderUpdate.pass
+ Passes/DiffuseProbeGridClassification.pass
Passes/DiffuseProbeGridDownsample.pass
Passes/DiffuseProbeGridRayTracing.pass
Passes/DiffuseProbeGridRelocation.pass
@@ -144,6 +147,7 @@ set(FILES
Passes/FullscreenCopy.pass
Passes/FullscreenOutputOnly.pass
Passes/ImGui.pass
+ Passes/LightAdaptationParent.pass
Passes/LightCulling.pass
Passes/LightCullingHeatmap.pass
Passes/LightCullingParent.pass
@@ -152,6 +156,8 @@ set(FILES
Passes/LightCullingTilePrepareMSAA.pass
Passes/LookModificationComposite.pass
Passes/LookModificationTransform.pass
+ Passes/LowEndForward.pass
+ Passes/LowEndPipeline.pass
Passes/LuminanceHeatmap.pass
Passes/LuminanceHistogramGenerator.pass
Passes/MainPipeline.pass
@@ -179,8 +185,10 @@ set(FILES
Passes/ReflectionScreenSpace.pass
Passes/ReflectionScreenSpaceBlur.pass
Passes/ReflectionScreenSpaceBlurHorizontal.pass
+ Passes/ReflectionScreenSpaceBlurMobile.pass
Passes/ReflectionScreenSpaceBlurVertical.pass
Passes/ReflectionScreenSpaceComposite.pass
+ Passes/ReflectionScreenSpaceMobile.pass
Passes/ReflectionScreenSpaceTrace.pass
Passes/Reflections_nomsaa.pass
Passes/ShadowParent.pass
@@ -205,6 +213,7 @@ set(FILES
ShaderLib/Atom/Features/IndirectRendering.azsli
ShaderLib/Atom/Features/MatrixUtility.azsli
ShaderLib/Atom/Features/ParallaxMapping.azsli
+ ShaderLib/Atom/Features/ShaderQualityOptions.azsli
ShaderLib/Atom/Features/SphericalHarmonicsUtility.azsli
ShaderLib/Atom/Features/SrgSemantics.azsli
ShaderLib/Atom/Features/ColorManagement/TransformColor.azsli
@@ -234,6 +243,7 @@ set(FILES
ShaderLib/Atom/Features/PBR/Hammersley.azsli
ShaderLib/Atom/Features/PBR/LightingOptions.azsli
ShaderLib/Atom/Features/PBR/LightingUtils.azsli
+ ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli
ShaderLib/Atom/Features/PBR/TransparentPassSrg.azsli
ShaderLib/Atom/Features/PBR/Lighting/DualSpecularLighting.azsli
ShaderLib/Atom/Features/PBR/Lighting/EnhancedLighting.azsli
From 24aa0f852179f94bce8ae354b66c6804628bd1b7 Mon Sep 17 00:00:00 2001
From: antonmic
Date: Fri, 7 May 2021 20:56:40 -0700
Subject: [PATCH 020/209] skybox pass separation for single vs double output
---
.../Common/Assets/Passes/OpaqueParent.pass | 13 ++++--
.../Assets/Passes/PassTemplates.azasset | 4 ++
.../Feature/Common/Assets/Passes/SkyBox.pass | 5 +++
.../Assets/Passes/SkyBox_TwoOutputs.pass | 43 +++++++++++++++++++
.../Reflections/ReflectionComposite.azsl | 15 ++-----
.../Common/Assets/Shaders/SkyBox/SkyBox.azsl | 11 +++++
.../Shaders/SkyBox/SkyBox_TwoOutputs.azsl | 15 +++++++
.../Shaders/SkyBox/SkyBox_TwoOutputs.shader | 22 ++++++++++
8 files changed, 113 insertions(+), 15 deletions(-)
create mode 100644 Gems/Atom/Feature/Common/Assets/Passes/SkyBox_TwoOutputs.pass
create mode 100644 Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.azsl
create mode 100644 Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.shader
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/OpaqueParent.pass b/Gems/Atom/Feature/Common/Assets/Passes/OpaqueParent.pass
index 40d6a51e77..a691fe2534 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/OpaqueParent.pass
+++ b/Gems/Atom/Feature/Common/Assets/Passes/OpaqueParent.pass
@@ -305,7 +305,7 @@
},
{
"Name": "SkyBoxPass",
- "TemplateName": "SkyBoxTemplate",
+ "TemplateName": "SkyBoxTwoOutputsTemplate",
"Enabled": true,
"Connections": [
{
@@ -315,6 +315,13 @@
"Attachment": "SpecularInputOutput"
}
},
+ {
+ "LocalSlot": "ReflectionInputOutput",
+ "AttachmentRef": {
+ "Pass": "ReflectionsPass",
+ "Attachment": "ReflectionOutput"
+ }
+ },
{
"LocalSlot": "SkyBoxDepth",
"AttachmentRef": {
@@ -331,8 +338,8 @@
{
"LocalSlot": "ReflectionInput",
"AttachmentRef": {
- "Pass": "ReflectionsPass",
- "Attachment": "ReflectionOutput"
+ "Pass": "SkyBoxPass",
+ "Attachment": "ReflectionInputOutput"
}
},
{
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset b/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset
index 2421d7fbe7..c56e8932b1 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset
+++ b/Gems/Atom/Feature/Common/Assets/Passes/PassTemplates.azasset
@@ -92,6 +92,10 @@
"Name": "SkyBoxTemplate",
"Path": "Passes/SkyBox.pass"
},
+ {
+ "Name": "SkyBoxTwoOutputsTemplate",
+ "Path": "Passes/SkyBox_TwoOutputs.pass"
+ },
{
"Name": "UIPassTemplate",
"Path": "Passes/UI.pass"
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass b/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
index fb16271ba7..57f442e5de 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
+++ b/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
@@ -12,6 +12,11 @@
"SlotType": "InputOutput",
"ScopeAttachmentUsage": "RenderTarget"
},
+ {
+ "Name": "ReflectionInputOutput",
+ "SlotType": "InputOutput",
+ "ScopeAttachmentUsage": "RenderTarget"
+ },
{
"Name": "SkyBoxDepth",
"SlotType": "InputOutput",
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/SkyBox_TwoOutputs.pass b/Gems/Atom/Feature/Common/Assets/Passes/SkyBox_TwoOutputs.pass
new file mode 100644
index 0000000000..0ed7b39288
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Passes/SkyBox_TwoOutputs.pass
@@ -0,0 +1,43 @@
+{
+ "Type": "JsonSerialization",
+ "Version": 1,
+ "ClassName": "PassAsset",
+ "ClassData": {
+ "PassTemplate": {
+ "Name": "SkyBoxTwoOutputsTemplate",
+ "PassClass": "FullScreenTriangle",
+ "Slots": [
+ {
+ "Name": "SpecularInputOutput",
+ "SlotType": "InputOutput",
+ "ScopeAttachmentUsage": "RenderTarget"
+ },
+ {
+ "Name": "ReflectionInputOutput",
+ "SlotType": "InputOutput",
+ "ScopeAttachmentUsage": "RenderTarget"
+ },
+ {
+ "Name": "SkyBoxDepth",
+ "SlotType": "InputOutput",
+ "ScopeAttachmentUsage": "DepthStencil"
+ }
+ ],
+ "PassData": {
+ "$type": "FullscreenTrianglePassData",
+ "ShaderAsset": {
+ "FilePath": "shaders/skybox/skybox_twooutputs.shader"
+ },
+ "PipelineViewTag": "MainCamera",
+ "ShaderDataMappings": {
+ "FloatMappings": [
+ {
+ "Name": "m_sunIntensityMultiplier",
+ "Value": 1.0
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionComposite.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionComposite.azsl
index 865d657d85..92f8c3f638 100644
--- a/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionComposite.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Shaders/Reflections/ReflectionComposite.azsl
@@ -53,22 +53,13 @@ PSOutput MainPS(VSOutput IN)
uint width, height, samples;
PassSrg::m_reflection.GetDimensions(width, height, samples);
- float nonZeroSamples = 0.0f;
for (uint sampleIndex = 0; sampleIndex < samples; ++sampleIndex)
{
- float3 reflectionSample = PassSrg::m_reflection.Load(IN.m_position.xy, sampleIndex).rgb;
- if(any(reflectionSample))
- {
- reflection += reflectionSample;
- nonZeroSamples += 1.0f;
- }
- }
-
- if(nonZeroSamples != 0.0f)
- {
- reflection /= nonZeroSamples;
+ reflection += PassSrg::m_reflection.Load(IN.m_position.xy, sampleIndex).rgb;
}
+ reflection /= samples;
+
PSOutput OUT;
OUT.m_color = float4(reflection, 1.0f);
return OUT;
diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
index a7de426374..4b3e9536b7 100644
--- a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
@@ -10,6 +10,11 @@
*
*/
+// Static Options:
+//
+// SKYBOX_TWO_OUTPUTS - Allows the skybox to render to two rendertargets instead of one
+
+
#include
#include
#include
@@ -102,6 +107,9 @@ float3 GetCubemapCoords(float3 original)
struct PSOutput
{
float4 m_specular : SV_Target0;
+#ifdef SKYBOX_TWO_OUTPUTS
+ float4 m_reflection : SV_Target1;
+#endif
};
PSOutput MainPS(VSOutput input)
@@ -162,5 +170,8 @@ PSOutput MainPS(VSOutput input)
PSOutput OUT;
OUT.m_specular = float4(color, 1.0);
+#ifdef SKYBOX_TWO_OUTPUTS
+ OUT.m_reflection = float4(color, 1.0);
+#endif
return OUT;
}
diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.azsl
new file mode 100644
index 0000000000..99d7b45e4c
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.azsl
@@ -0,0 +1,15 @@
+/*
+* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+* its licensors.
+*
+* For complete copyright and license terms please see the LICENSE at the root of this
+* distribution (the "License"). All use of this software is governed by the License,
+* or, if provided, by the license below or the license accompanying this file. Do not
+* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*
+*/
+
+#define SKYBOX_TWO_OUTPUTS
+
+#include "SkyBox.azsl"
diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.shader b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.shader
new file mode 100644
index 0000000000..ec80d4a20e
--- /dev/null
+++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.shader
@@ -0,0 +1,22 @@
+{
+ "Source" : "SkyBox_TwoOutputs",
+
+ "DepthStencilState" : {
+ "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" }
+ },
+
+ "ProgramSettings":
+ {
+ "EntryPoints":
+ [
+ {
+ "name": "MainVS",
+ "type": "Vertex"
+ },
+ {
+ "name": "MainPS",
+ "type": "Fragment"
+ }
+ ]
+ }
+}
From cb245730a1f214c4891817b11bb617166f73c7b7 Mon Sep 17 00:00:00 2001
From: antonmic
Date: Sun, 9 May 2021 23:01:24 -0700
Subject: [PATCH 021/209] work in progress
---
.../Types/StandardPBR_LowEndForward.azsl | 2 ++
.../Feature/Common/Assets/Passes/Forward.pass | 20 -------------------
.../Feature/Common/Assets/Passes/SkyBox.pass | 5 -----
.../Shaders/SkyBox/SkyBox_TwoOutputs.azsl | 2 ++
.../atom_feature_common_asset_files.cmake | 4 ++++
5 files changed, 8 insertions(+), 25 deletions(-)
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl
index a690cbf84a..c87faffcbe 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_LowEndForward.azsl
@@ -10,6 +10,8 @@
*
*/
+// NOTE: This file is a temporary workaround until .shader files can #define macros for their .azsl files
+
#define QUALITY_LOW_END 1
#include "StandardPBR_ForwardPass.azsl"
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/Forward.pass b/Gems/Atom/Feature/Common/Assets/Passes/Forward.pass
index 3dcc90ac5c..b66e3bb4e1 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/Forward.pass
+++ b/Gems/Atom/Feature/Common/Assets/Passes/Forward.pass
@@ -222,19 +222,6 @@
"AssetRef": {
"FilePath": "Textures/BRDFTexture.attimage"
}
- },
- {
- "Name": "ScatterDistanceImage",
- "SizeSource": {
- "Source": {
- "Pass": "Parent",
- "Attachment": "SwapChainOutput"
- }
- },
- "ImageDescriptor": {
- "Format": "R11G11B10_FLOAT",
- "SharedQueueMask": "Graphics"
- }
}
],
"Connections": [
@@ -279,13 +266,6 @@
"Pass": "This",
"Attachment": "BRDFTexture"
}
- },
- {
- "LocalSlot": "ScatterDistanceOutput",
- "AttachmentRef": {
- "Pass": "This",
- "Attachment": "ScatterDistanceImage"
- }
}
]
}
diff --git a/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass b/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
index 57f442e5de..fb16271ba7 100644
--- a/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
+++ b/Gems/Atom/Feature/Common/Assets/Passes/SkyBox.pass
@@ -12,11 +12,6 @@
"SlotType": "InputOutput",
"ScopeAttachmentUsage": "RenderTarget"
},
- {
- "Name": "ReflectionInputOutput",
- "SlotType": "InputOutput",
- "ScopeAttachmentUsage": "RenderTarget"
- },
{
"Name": "SkyBoxDepth",
"SlotType": "InputOutput",
diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.azsl
index 99d7b45e4c..feacd2f44f 100644
--- a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox_TwoOutputs.azsl
@@ -10,6 +10,8 @@
*
*/
+// NOTE: This file is a temporary workaround until .shader files can #define macros for their .azsl files
+
#define SKYBOX_TWO_OUTPUTS
#include "SkyBox.azsl"
diff --git a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake
index 6902d456ff..7419c1e669 100644
--- a/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake
+++ b/Gems/Atom/Feature/Common/Assets/atom_feature_common_asset_files.cmake
@@ -54,6 +54,7 @@ set(FILES
Materials/Types/StandardPBR_HandleOpacityMode.lua
Materials/Types/StandardPBR_LowEndForward.azsl
Materials/Types/StandardPBR_LowEndForward.shader
+ Materials/Types/StandardPBR_LowEndForward_EDS.shader
Materials/Types/StandardPBR_ParallaxState.lua
Materials/Types/StandardPBR_Roughness.lua
Materials/Types/StandardPBR_ShaderEnable.lua
@@ -194,6 +195,7 @@ set(FILES
Passes/ShadowParent.pass
Passes/Skinning.pass
Passes/SkyBox.pass
+ Passes/SkyBox_TwoOutputs.pass
Passes/SMAA1xApplyLinearHDRColor.pass
Passes/SMAA1xApplyPerceptualColor.pass
Passes/SMAABlendingWeightCalculation.pass
@@ -483,4 +485,6 @@ set(FILES
Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli
Shaders/SkyBox/SkyBox.azsl
Shaders/SkyBox/SkyBox.shader
+ Shaders/SkyBox/SkyBox_TwoOutputs.azsl
+ Shaders/SkyBox/SkyBox_TwoOutputs.shader
)
From 521a486ee45f373a4cf7d0f9fece8ac54086e02f Mon Sep 17 00:00:00 2001
From: moudgils
Date: Mon, 10 May 2021 09:13:15 -0700
Subject: [PATCH 022/209] Fixes to ios build
---
.../Code/Source/ImageBuilderComponent.cpp | 2 +-
.../Source/Processing/ImageAssetProducer.cpp | 12 ++++--------
.../Atom/RHI.Reflect/ImageSubresource.h | 11 ++++++++++-
.../Source/RHI.Reflect/ImageSubresource.cpp | 12 ++++++++++--
.../Code/Source/RHI/AsyncUploadQueue.cpp | 14 +++++++++++---
.../Shader/ShaderVariantTreeAsset.cpp | 19 ++++++++-----------
6 files changed, 44 insertions(+), 26 deletions(-)
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
index ccba00f15f..59c799a601 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
@@ -79,7 +79,7 @@ namespace ImageProcessingAtom
builderDescriptor.m_busId = azrtti_typeid();
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 = 22; // [ATOM-14765]
+ builderDescriptor.m_version = 23; // [ATOM-14022]
builderDescriptor.m_analysisFingerprint = ImageProcessingAtom::BuilderSettingManager::Instance()->GetAnalysisFingerprint();
m_imageBuilder.BusConnect(builderDescriptor.m_busId);
AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor);
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp
index 9c02894b7c..2448f501af 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageAssetProducer.cpp
@@ -19,6 +19,7 @@
#include
#include
+#include
#include
#include
@@ -238,14 +239,9 @@ namespace ImageProcessingAtom
uint8_t* mipBuffer;
uint32_t pitch;
m_imageObject->GetImagePointer(mip, mipBuffer, pitch);
- uint32_t mipBufferSize = m_imageObject->GetMipBufSize(mip);
-
- RHI::ImageSubresourceLayout layout;
- layout.m_bytesPerImage = mipBufferSize / arraySize;
- layout.m_rowCount = layout.m_bytesPerImage / pitch;
- layout.m_size = RHI::Size(m_imageObject->GetWidth(mip), m_imageObject->GetHeight(mip) / arraySize, 1);
- layout.m_bytesPerRow = pitch;
-
+ RHI::Format format = Utils::PixelFormatToRHIFormat(m_imageObject->GetPixelFormat(), m_imageObject->HasImageFlags(EIF_SRGBRead));
+
+ RHI::ImageSubresourceLayout layout = RHI::GetImageSubresourceLayout(RHI::Size(m_imageObject->GetWidth(mip), m_imageObject->GetHeight(mip) / arraySize, 1), format);
builder.BeginMip(layout);
for (uint32_t arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex)
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h
index b536ed5524..d81ffc006c 100644
--- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageSubresource.h
@@ -100,7 +100,9 @@ namespace AZ
Size size,
uint32_t rowCount,
uint32_t bytesPerRow,
- uint32_t bytesPerImage);
+ uint32_t bytesPerImage,
+ uint32_t numBlocksWidth,
+ uint32_t numBlocksHeight);
/// The size of the image subresource in pixels. Certain formats have alignment requirements.
/// Block compressed formats are 4 pixel aligned. Other non-standard formats may be 2 pixel aligned.
@@ -114,6 +116,13 @@ namespace AZ
/// The number of bytes in a single image slice. 3D textures are comprised of m_size.m_depth image slices.
uint32_t m_bytesPerImage = 0;
+
+ /// The number of blocks in width based on the texture fomat
+ uint32_t m_numBlocksWidth = 1;
+
+ /// The number of blocks in height based on the texture fomat
+ uint32_t m_numBlocksHeight = 1;
+
};
struct ImageSubresourceLayoutPlaced : ImageSubresourceLayout
diff --git a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp
index 4e34fe2b32..a956a13d1b 100644
--- a/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp
+++ b/Gems/Atom/RHI/Code/Source/RHI.Reflect/ImageSubresource.cpp
@@ -102,11 +102,13 @@ namespace AZ
if (auto* serializeContext = azrtti_cast(context))
{
serializeContext->Class()
- ->Version(0)
+ ->Version(1)
->Field("m_size", &ImageSubresourceLayout::m_size)
->Field("m_rowCount", &ImageSubresourceLayout::m_rowCount)
->Field("m_bytesPerRow", &ImageSubresourceLayout::m_bytesPerRow)
->Field("m_bytesPerImage", &ImageSubresourceLayout::m_bytesPerImage)
+ ->Field("m_numBlocksWidth", &ImageSubresourceLayout::m_numBlocksWidth)
+ ->Field("m_numBlocksHeight", &ImageSubresourceLayout::m_numBlocksHeight)
;
}
}
@@ -115,11 +117,15 @@ namespace AZ
Size size,
uint32_t rowCount,
uint32_t bytesPerRow,
- uint32_t bytesPerImage)
+ uint32_t bytesPerImage,
+ uint32_t numBlocksWidth,
+ uint32_t numBlocksHeight)
: m_size{size}
, m_rowCount{rowCount}
, m_bytesPerRow{bytesPerRow}
, m_bytesPerImage{bytesPerImage}
+ , m_numBlocksWidth{numBlocksWidth}
+ , m_numBlocksHeight{numBlocksHeight}
{}
ImageSubresourceLayoutPlaced::ImageSubresourceLayoutPlaced(const ImageSubresourceLayout& subresourceLayout, size_t offset)
@@ -316,6 +322,8 @@ namespace AZ
subresourceLayout.m_rowCount = numBlocksHigh;
subresourceLayout.m_size.m_width = imageSize.m_width;
subresourceLayout.m_size.m_height = imageSize.m_height;
+ subresourceLayout.m_numBlocksWidth = numBlocks;
+ subresourceLayout.m_numBlocksHeight = numBlocks;
}
else if (isPacked)
{
diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp
index 891f9ea2f3..d9a8f8aa3b 100644
--- a/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp
+++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/AsyncUploadQueue.cpp
@@ -190,8 +190,8 @@ namespace AZ
const uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, bufferOffsetAlign);
const uint32_t stagingSlicePitch = RHI::AlignUp(subresourceLayout.m_rowCount * stagingRowPitch, bufferOffsetAlign);
const uint32_t rowsPerSplit = static_cast(m_descriptor.m_stagingSizeInBytes) / stagingRowPitch;
- const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount;
-
+ const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_numBlocksHeight;
+
// ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression.
// Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images.
if (subresourceLayout.m_size.m_height < subresourceLayout.m_rowCount)
@@ -281,7 +281,7 @@ namespace AZ
const uint32_t endRow = AZStd::min(startRow + rowsPerSplit, subresourceLayout.m_rowCount);
// Calculate the blocksize for BC formatted images; the copy command works in texels.
- const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight;
+ uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight;
// Copy subresource data to staging memory.
uint8_t* stagingDataStart = framePacket->m_stagingResourceData + framePacket->m_dataOffset;
@@ -293,6 +293,14 @@ namespace AZ
const uint32_t bytesCopied = (endRow - startRow) * stagingRowPitch;
Platform::SynchronizeBufferOnCPU(framePacket->m_stagingResource, framePacket->m_dataOffset, bytesCopied);
+ //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over
+ //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight
+ if(destHeight+heightToCopy > subresourceLayout.m_size.m_height)
+ {
+ uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height;
+ heightToCopy -= HeightDiff;
+ }
+
const RHI::Size sourceSize = RHI::Size(subresourceLayout.m_size.m_width, heightToCopy, 1);
const RHI::Origin sourceOrigin = RHI::Origin(0, destHeight, depth);
CopyBufferToImage(framePacket, image, stagingRowPitch, bytesCopied,
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp
index 25ba5aa837..f550a6f2ca 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Shader/ShaderVariantTreeAsset.cpp
@@ -12,6 +12,7 @@
#include
#include
+#include
#include
#include
@@ -40,15 +41,12 @@ namespace AZ
Data::AssetId ShaderVariantTreeAsset::GetShaderVariantTreeAssetIdFromShaderAssetId(const Data::AssetId& shaderAssetId)
{
//From the shaderAssetId We can deduce the path of the shader asset, and from the path of the shader asset we can deduce the path of the ShaderVariantTreeAsset.
- AZStd::string shaderAssetPath;
- AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderAssetPath
- , &AZ::Data::AssetCatalogRequests::GetAssetPathById
- , shaderAssetId);
-
- AZStd::string shaderAssetPathRoot;
- AZStd::string shaderAssetPathName;
- AzFramework::StringFunc::Path::Split(shaderAssetPath.c_str(), nullptr /*drive*/, &shaderAssetPathRoot, &shaderAssetPathName, nullptr /*extension*/);
-
+ AZ::IO::FixedMaxPath shaderAssetPath;
+ AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderAssetPath.Native(), &AZ::Data::AssetCatalogRequests::GetAssetPathById
+ , shaderAssetId);
+ AZ::IO::FixedMaxPath shaderAssetPathRoot = shaderAssetPath.ParentPath();
+ AZ::IO::FixedMaxPath shaderAssetPathName = shaderAssetPath.Stem();
+
AZStd::string shaderVariantTreeAssetDir;
AzFramework::StringFunc::Path::Join(ShaderVariantTreeAsset::CommonSubFolderLowerCase, shaderAssetPathRoot.c_str(), shaderVariantTreeAssetDir);
AZStd::string shaderVariantTreeAssetFilename = AZStd::string::format("%s.%s", shaderAssetPathName.c_str(), ShaderVariantTreeAsset::Extension);
@@ -63,8 +61,7 @@ namespace AZ
{
// If the game project did not customize the shadervariantlist, let's see if the original author of the .shader file
// provided a shadervariantlist.
- shaderVariantTreeAssetDir = shaderAssetPathRoot;
- AzFramework::StringFunc::Path::Join(shaderVariantTreeAssetDir.c_str(), shaderVariantTreeAssetFilename.c_str(), shaderVariantTreeAssetPath);
+ AzFramework::StringFunc::Path::Join(shaderAssetPathRoot.c_str(), shaderVariantTreeAssetFilename.c_str(), shaderVariantTreeAssetPath);
AZ::Data::AssetCatalogRequestBus::BroadcastResult(shaderVariantTreeAssetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath
, shaderVariantTreeAssetPath.c_str(), AZ::Data::s_invalidAssetType, false);
}
From d1eae23347c095333ed5c83a934a407de192d9c2 Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Mon, 10 May 2021 17:26:46 +0100
Subject: [PATCH 023/209] reduced cursor size.
---
.../Components/FancyDocking.cpp | 2 +-
.../Components/Widgets/TabWidget.cpp | 4 +-
.../img/UI20/Cursors/Grab_release.svg | 40 +++++++++----------
.../Components/img/UI20/Cursors/Grabbing.svg | 40 +++++++++++--------
4 files changed, 47 insertions(+), 39 deletions(-)
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
index b89a220b1a..1a7512a4fc 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/FancyDocking.cpp
@@ -160,7 +160,7 @@ namespace AzQtComponents
QObject::connect(m_dropZoneHoverFadeInTimer, &QTimer::timeout, this, &FancyDocking::onDropZoneHoverFadeInUpdate);
m_dropZoneHoverFadeInTimer->setInterval(g_FancyDockingConstants.dropZoneHoverFadeUpdateIntervalMS);
QIcon dragIcon = QIcon(QStringLiteral(":/Cursors/Grabbing.svg"));
- m_dragCursor = QCursor(dragIcon.pixmap(32), 10, 5);
+ m_dragCursor = QCursor(dragIcon.pixmap(16), 5, 2);
}
FancyDocking::~FancyDocking()
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
index a0006d7979..48fb47d7e6 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TabWidget.cpp
@@ -422,10 +422,10 @@ namespace AzQtComponents
AzQtComponents::Style::addClass(this, g_emptyStyleClass);
QIcon icon = QIcon(QStringLiteral(":/Cursors/Grab_release.svg"));
- m_hoverCursor = QCursor(icon.pixmap(32), 10, 5);
+ m_hoverCursor = QCursor(icon.pixmap(16), 5, 2);
icon = QIcon(QStringLiteral(":/Cursors/Grabbing.svg"));
- m_dragCursor = QCursor(icon.pixmap(32), 10, 5);
+ m_dragCursor = QCursor(icon.pixmap(16), 5, 2);
this->setCursor(m_hoverCursor);
}
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
index c0da9b802f..ad89e7d1b1 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/Cursors/Grab_release.svg
@@ -1,5 +1,5 @@
-
+
From 92ef82f9331dee683f3d4df7869c27d913321420 Mon Sep 17 00:00:00 2001
From: pereslav
Date: Mon, 10 May 2021 19:52:23 +0100
Subject: [PATCH 024/209] Added handling parented net entities
---
.../EntityReplicationManager.cpp | 6 ++---
.../NetworkEntity/NetworkEntityManager.cpp | 26 ++++++++++++++++++-
.../Pipeline/NetworkPrefabProcessor.cpp | 4 +++
3 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp
index 74bdcd5cf0..64eb3fcc6a 100644
--- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp
+++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp
@@ -550,10 +550,10 @@ namespace Multiplayer
{
replicatorEntity = entityList[0];
}
-
- AZ_Assert(replicatorEntity != nullptr, "Failed to create entity from prefab %s", prefabEntityId.m_prefabName.GetCStr());
- if (replicatorEntity == nullptr)
+ else
{
+ AZ_Assert(false, "There should be exactly one created entity out of prefab %s, index %d. Got: %d",
+ prefabEntityId.m_prefabName.GetCStr(), prefabEntityId.m_entityOffset, entityList.size());
return false;
}
}
diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp
index ce55f66caa..3bcd613d8b 100644
--- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp
+++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp
@@ -334,15 +334,39 @@ namespace Multiplayer
const AzFramework::Spawnable::EntityList& entities = spawnable.GetEntities();
size_t entitiesSize = entities.size();
+ using EntityIdMap = AZStd::unordered_map;
+ EntityIdMap originalToCloneIdMap;
+
for (size_t i = 0; i < entitiesSize; ++i)
{
- AZ::Entity* clone = serializeContext->CloneObject(entities[i].get());
+ AZ::Entity* originalEntity = entities[i].get();
+ AZ::Entity* clone = serializeContext->CloneObject(originalEntity);
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
+
clone->SetId(AZ::Entity::MakeId());
+ originalToCloneIdMap[originalEntity->GetId()] = clone->GetId();
+
NetBindComponent* netBindComponent = clone->FindComponent();
if (netBindComponent != nullptr)
{
+ // Update TransformComponent parent Id. It is guaranteed for the entities array to be sorted from parent->child here.
+ auto* transformComponent = clone->FindComponent();
+ AZ::EntityId parentId = transformComponent->GetParentId();
+ if (parentId.IsValid())
+ {
+ auto it = originalToCloneIdMap.find(parentId);
+ if (it != originalToCloneIdMap.end())
+ {
+ transformComponent->SetParentRelative(it->second);
+ }
+ else
+ {
+ AZ_Warning("NetworkEntityManager", false, "Entity %s doesn't have the parent entity %s present in network.spawnable",
+ clone->GetName().c_str(), parentId.ToString().data());
+ }
+ }
+
PrefabEntityId prefabEntityId;
prefabEntityId.m_prefabName = m_networkPrefabLibrary.GetPrefabNameFromAssetId(spawnable.GetId());
prefabEntityId.m_entityOffset = aznumeric_cast(i);
diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp
index 4962d16fb4..56201bd5fd 100644
--- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp
+++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp
@@ -59,6 +59,7 @@ namespace Multiplayer
return result;
}
+
void NetworkPrefabProcessor::ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab)
{
using namespace AzToolsFramework::Prefab;
@@ -175,6 +176,9 @@ namespace Multiplayer
(*it)->InvalidateDependencies();
(*it)->EvaluateDependencies();
}
+
+ SpawnableUtils::SortEntitiesByTransformHierarchy(*networkSpawnable);
+
context.GetProcessedObjects().push_back(AZStd::move(object));
}
else
From f856bd26b08cb63bf67e14800ff42d2a25f5f6cb Mon Sep 17 00:00:00 2001
From: moudgils
Date: Mon, 10 May 2021 13:58:43 -0700
Subject: [PATCH 025/209] Propogated fixes to other RHI backends
---
.../RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp | 12 ++++++++++--
.../RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp | 10 +++++++++-
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp
index f816a7ae04..ec18b985ff 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/RHI/AsyncUploadQueue.cpp
@@ -267,7 +267,7 @@ namespace AZ
// Staging sizes
uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, DX12_TEXTURE_DATA_PITCH_ALIGNMENT);
uint32_t stagingSlicePitch = RHI::AlignUp(subresourceLayout.m_rowCount*stagingRowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
- const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount;
+ const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_numBlocksHeight;
// ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression.
// Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images.
@@ -382,7 +382,7 @@ namespace AZ
const uint32_t numRowsToCopy = endRow - startRow;
// Calculate the blocksize for BC formatted images; the copy command works in texels.
- const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight;
+ uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight;
// Copy subresource data to staging memory
{
@@ -398,6 +398,14 @@ namespace AZ
}
}
+ //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over
+ //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight
+ if(destHeight+heightToCopy > subresourceLayout.m_size.m_height)
+ {
+ uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height;
+ heightToCopy -= HeightDiff;
+ }
+
// Add copy command to copy image subresource from staging memory to image gpu resource
// Source location
diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp
index a6e7ff082f..08d8fca9b3 100644
--- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp
+++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp
@@ -214,7 +214,7 @@ namespace AZ
const uint32_t stagingRowPitch = RHI::AlignUp(subresourceLayout.m_bytesPerRow, bufferOffsetAlign);
const uint32_t stagingSlicePitch = subresourceLayout.m_rowCount * stagingRowPitch;
const uint32_t rowsPerSplit = static_cast(m_descriptor.m_stagingSizeInBytes) / stagingRowPitch;
- const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_size.m_height / subresourceLayout.m_rowCount;
+ const uint32_t compressedTexelBlockSizeHeight = subresourceLayout.m_numBlocksHeight;
// ImageHeight must be bigger than or equal to the Image's row count. Images with a RowCount that is less than the ImageHeight indicates a block compression.
// Images with a RowCount which is higher than the ImageHeight indicates a planar image, which is not supported for streaming images.
@@ -348,6 +348,14 @@ namespace AZ
framePacket->m_stagingBuffer->GetBufferMemoryView()->Unmap(RHI::HostMemoryAccess::Write);
}
+ //Clamp heightToCopy to match subresourceLayout.m_size.m_height as it is possible to go over
+ //if subresourceLayout.m_size.m_height is not perfectly divisible by compressedTexelBlockSizeHeight
+ if(destHeight+heightToCopy > subresourceLayout.m_size.m_height)
+ {
+ uint32_t HeightDiff = (destHeight + heightToCopy) - subresourceLayout.m_size.m_height;
+ heightToCopy -= HeightDiff;
+ }
+
// Add copy command to copy image subresource from staging memory to image GPU resource.
copyDescriptor.m_destinationOrigin.m_top = destHeight;
copyDescriptor.m_sourceSize.m_height = heightToCopy;
From 3c315df36f5bc086806efda05b8cdec0131ecbd6 Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Wed, 5 May 2021 16:47:44 -0700
Subject: [PATCH 026/209] Fix Camera transform property notifications.
Moves transform notification logic from CComponentEntityObject::InvalidateTM (which will eventually go away) to AzToolsFramework::TransformComponent::OnTransformChanged.
We also specifically make sure PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged fires, which is used by Track View to detect camera position changes.
---
.../ToolsComponents/TransformComponent.cpp | 19 ++++++++++++++++++-
.../Objects/ComponentEntityObject.cpp | 8 --------
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp
index f8d02b6581..6ce797c3ee 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp
@@ -253,7 +253,7 @@ namespace AzToolsFramework
m_localTransformDirty = true;
m_worldTransformDirty = true;
- if (GetEntity())
+ if (const AZ::Entity* entity = GetEntity())
{
SetDirty();
@@ -265,6 +265,23 @@ namespace AzToolsFramework
AZ::TransformNotificationBus::Event(
GetEntityId(), &TransformNotification::OnTransformChanged, localTM, worldTM);
+
+ // Fire a property changed notification for this component
+ if (const AZ::Component* component = entity->FindComponent())
+ {
+ PropertyEditorEntityChangeNotificationBus::Event(
+ GetEntityId(), &PropertyEditorEntityChangeNotifications::OnEntityComponentPropertyChanged, component->GetId());
+ }
+
+ // Refresh the property editor if we're selected
+ bool selected = false;
+ ToolsApplicationRequestBus::BroadcastResult(
+ selected, &AzToolsFramework::ToolsApplicationRequests::IsSelected, GetEntityId());
+ if (selected)
+ {
+ ToolsApplicationEvents::Bus::Broadcast(
+ &ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values);
+ }
}
}
diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp
index c85ed1248f..20ae0a74cd 100644
--- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp
+++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp
@@ -609,14 +609,6 @@ void CComponentEntityObject::InvalidateTM(int nWhyFlags)
{
Matrix34 worldTransform = GetWorldTM();
EBUS_EVENT_ID(m_entityId, AZ::TransformBus, SetWorldTM, LYTransformToAZTransform(worldTransform));
-
- // When transformed via the editor, make sure the entity is marked dirty for undo capture.
- EBUS_EVENT(AzToolsFramework::ToolsApplicationRequests::Bus, AddDirtyEntity, m_entityId);
-
- if (CheckFlags(OBJFLAG_SELECTED))
- {
- EBUS_EVENT(AzToolsFramework::ToolsApplicationEvents::Bus, InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values);
- }
}
}
}
From dca2294b362538a03f4566dd9e4d76634d16c9b1 Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Wed, 5 May 2021 16:51:49 -0700
Subject: [PATCH 027/209] Move GetCameraTransform into RPI::View.
---
Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h | 2 ++
Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp | 9 +++++++++
Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp | 7 +------
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h
index d6146d3760..aad099dc23 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h
@@ -91,6 +91,8 @@ namespace AZ
const AZ::Matrix4x4& GetViewToWorldMatrix() const;
const AZ::Matrix4x4& GetViewToClipMatrix() const;
const AZ::Matrix4x4& GetWorldToClipMatrix() const;
+ //! Get the camera's world transform, converted from the viewToWorld matrix's native y-up to z-up
+ AZ::Transform GetCameraTransform() const;
//! Finalize draw lists in this view. This function should only be called when all
//! draw packets for current frame are added.
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp
index e3f41cbda9..85216707a8 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp
@@ -110,6 +110,15 @@ namespace AZ
InvalidateSrg();
}
+ AZ::Transform View::GetCameraTransform() const
+ {
+ const Quaternion zUpToYUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi);
+ return AZ::Transform::CreateFromQuaternionAndTranslation(
+ Quaternion::CreateFromMatrix4x4(m_worldToViewMatrix) * zUpToYUp,
+ m_worldToViewMatrix.GetTranslation()
+ ).GetOrthogonalized();
+ }
+
void View::SetCameraTransform(const AZ::Matrix3x4& cameraTransform)
{
m_position = cameraTransform.GetTranslation();
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp
index b5d3f815fe..b2f9acb855 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/ViewportContext.cpp
@@ -192,12 +192,7 @@ namespace AZ
AZ::Transform ViewportContext::GetCameraTransform() const
{
- const Matrix4x4& worldToViewMatrix = GetDefaultView()->GetViewToWorldMatrix();
- const Quaternion zUpToYUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi);
- return AZ::Transform::CreateFromQuaternionAndTranslation(
- Quaternion::CreateFromMatrix4x4(worldToViewMatrix) * zUpToYUp,
- worldToViewMatrix.GetTranslation()
- ).GetOrthogonalized();
+ return GetDefaultView()->GetCameraTransform();
}
void ViewportContext::SetCameraTransform(const AZ::Transform& transform)
From 5d9c99436a81cabeff5758a22f86522acfc63265 Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Wed, 5 May 2021 16:54:31 -0700
Subject: [PATCH 028/209] Ensure CameraComponentController entities get synced
with Atom camera changes.
This ensures the camera entity's transform gets correctly set if the RPI::View (or ViewportContext) is directly used instead of adjusting the entity transform, for e.g. camera controllers.
---
.../Code/Source/CameraComponentController.cpp | 18 ++++++++++++++++++
.../Code/Source/CameraComponentController.h | 3 +++
2 files changed, 21 insertions(+)
diff --git a/Gems/Camera/Code/Source/CameraComponentController.cpp b/Gems/Camera/Code/Source/CameraComponentController.cpp
index 2799d897d6..3dcee68169 100644
--- a/Gems/Camera/Code/Source/CameraComponentController.cpp
+++ b/Gems/Camera/Code/Source/CameraComponentController.cpp
@@ -160,6 +160,17 @@ namespace Camera
incompatible.push_back(AZ_CRC("CameraService", 0x1dd1caa4));
}
+ void CameraComponentController::Init()
+ {
+ m_onViewMatrixChanged = AZ::Event::Handler([this](const AZ::Matrix4x4&)
+ {
+ if (!m_updatingTransformFromEntity)
+ {
+ AZ::TransformBus::Event(m_entityId, &AZ::TransformInterface::SetWorldTM, m_atomCamera->GetCameraTransform());
+ }
+ });
+ }
+
void CameraComponentController::Activate(AZ::EntityId entityId)
{
m_entityId = entityId;
@@ -218,6 +229,8 @@ namespace Camera
}
}
AZ::RPI::ViewProviderBus::Handler::BusConnect(m_entityId);
+
+ m_atomCamera->ConnectWorldToViewMatrixChangedHandler(m_onViewMatrixChanged);
}
UpdateCamera();
@@ -258,6 +271,7 @@ namespace Camera
if (atomViewportRequests)
{
AZ::RPI::ViewProviderBus::Handler::BusDisconnect(m_entityId);
+ m_onViewMatrixChanged.Disconnect();
}
DeactivateAtomView();
@@ -376,7 +390,9 @@ namespace Camera
if (m_atomCamera)
{
+ m_updatingTransformFromEntity = true;
m_atomCamera->SetCameraTransform(AZ::Matrix3x4::CreateFromTransform(world.GetOrthogonalized()));
+ m_updatingTransformFromEntity = false;
}
}
@@ -425,7 +441,9 @@ namespace Camera
m_config.m_nearClipDistance,
m_config.m_farClipDistance,
true);
+ m_updatingTransformFromEntity = true;
m_atomCamera->SetViewToClipMatrix(viewToClipMatrix);
+ m_updatingTransformFromEntity = false;
}
}
diff --git a/Gems/Camera/Code/Source/CameraComponentController.h b/Gems/Camera/Code/Source/CameraComponentController.h
index 92e1354f17..cae6ad4663 100644
--- a/Gems/Camera/Code/Source/CameraComponentController.h
+++ b/Gems/Camera/Code/Source/CameraComponentController.h
@@ -77,6 +77,7 @@ namespace Camera
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+ void Init();
void Activate(AZ::EntityId entityId);
void Deactivate();
void SetConfiguration(const CameraComponentConfig& config);
@@ -121,6 +122,8 @@ namespace Camera
// Atom integration
AZ::RPI::ViewPtr m_atomCamera;
AZ::RPI::AuxGeomDrawPtr m_atomAuxGeom;
+ AZ::Event::Handler m_onViewMatrixChanged;
+ bool m_updatingTransformFromEntity = false;
// Cry view integration
IView* m_view = nullptr;
From ccfb232e93bf0c9298a8d2852496862aff794efd Mon Sep 17 00:00:00 2001
From: moudgils
Date: Mon, 10 May 2021 15:19:37 -0700
Subject: [PATCH 029/209] Missed a change
---
Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp
index 08d8fca9b3..6b16110c12 100644
--- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp
+++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/AsyncUploadQueue.cpp
@@ -333,7 +333,7 @@ namespace AZ
const uint32_t endRow = AZStd::min(startRow + rowsPerSplit, subresourceLayout.m_rowCount);
// Calculate the blocksize for BC formatted images; the copy command works in texels.
- const uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight;
+ uint32_t heightToCopy = (endRow - startRow) * compressedTexelBlockSizeHeight;
// Copy subresource data to staging memory.
{
From 64d53d1fabc4aa9d2fcad9c7506ce9dc78b26ec8 Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Mon, 10 May 2021 15:53:11 -0700
Subject: [PATCH 030/209] Fix View::GetCameraTransform
---
Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp
index 85216707a8..21a46693d5 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp
@@ -112,10 +112,10 @@ namespace AZ
AZ::Transform View::GetCameraTransform() const
{
- const Quaternion zUpToYUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi);
+ static const Quaternion yUpToZUp = Quaternion::CreateRotationX(-AZ::Constants::HalfPi);
return AZ::Transform::CreateFromQuaternionAndTranslation(
- Quaternion::CreateFromMatrix4x4(m_worldToViewMatrix) * zUpToYUp,
- m_worldToViewMatrix.GetTranslation()
+ Quaternion::CreateFromMatrix4x4(m_viewToWorldMatrix) * yUpToZUp,
+ m_viewToWorldMatrix.GetTranslation()
).GetOrthogonalized();
}
@@ -127,7 +127,7 @@ namespace AZ
// is in a Z-up world and an identity matrix means that it faces along the positive-Y axis and Z is up.
// An identity view matrix on the other hand looks along the negative Z-axis.
// So we adjust for this by rotating the camera world matrix by 90 degrees around the X axis.
- AZ::Matrix3x4 zUpToYUp = AZ::Matrix3x4::CreateRotationX(AZ::Constants::HalfPi);
+ static AZ::Matrix3x4 zUpToYUp = AZ::Matrix3x4::CreateRotationX(AZ::Constants::HalfPi);
AZ::Matrix3x4 yUpWorld = cameraTransform * zUpToYUp;
float viewToWorldMatrixRaw[16] = {
From 7276253c4225dd09dc0208693815abffe7ac672c Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Tue, 11 May 2021 08:20:44 +0100
Subject: [PATCH 031/209] renamed function
---
.../AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp | 4 ++--
.../AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
index faeae0a06d..85784d61e0 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
@@ -126,7 +126,7 @@ namespace AzToolsFramework
{
QStylePainter p(this);
- if (IsSectionSeparator())
+ if (IsReorderableRow())
{
const QPen linePen(QColor(0x3B3E3F));
p.setPen(linePen);
@@ -1332,7 +1332,7 @@ namespace AzToolsFramework
return canBeTopLevel(this);
}
- bool PropertyRowWidget::IsSectionSeparator() const
+ bool PropertyRowWidget::IsReorderableRow() const
{
return CanBeReordered();
}
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
index b6c94dc98b..58bf3bb9f0 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
@@ -83,7 +83,7 @@ namespace AzToolsFramework
PropertyRowWidget* GetParentRow() const { return m_parentRow; }
int GetLevel() const;
bool IsTopLevel() const;
- bool IsSectionSeparator() const;
+ bool IsReorderableRow() const;
// Remove the default label and append the text to the name label.
bool GetAppendDefaultLabelToName();
From 8e4d0d73dcea7f50d05a9318011de9a07e0d88e6 Mon Sep 17 00:00:00 2001
From: antonmic
Date: Tue, 11 May 2021 01:29:53 -0700
Subject: [PATCH 032/209] Good working state, but material always emmits low
end draw item
---
.../Materials/Types/StandardPBR.materialtype | 24 ++--
.../Atom/Features/PBR/Lights/Ibl.azsli | 108 ++++++------------
.../Atom/Features/ShaderQualityOptions.azsli | 3 +-
.../Code/Include/Atom/RPI.Public/Pass/Pass.h | 1 +
.../RPI/Code/Source/RPI.Public/Pass/Pass.cpp | 4 +-
5 files changed, 59 insertions(+), 81 deletions(-)
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
index 1612bf43b0..47d8a9d9d5 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
@@ -1304,9 +1304,11 @@
"textureProperty": "baseColor.textureMap",
"useTextureProperty": "baseColor.useTexture",
"dependentProperties": ["baseColor.textureMapUv", "baseColor.textureBlendMode"],
- "shaderTags": [
+ "shaderTags": [
"ForwardPass",
- "ForwardPass_EDS"
+ "ForwardPass_EDS",
+ "LowEndForward",
+ "LowEndForward_EDS"
],
"shaderOption": "o_baseColor_useTexture"
}
@@ -1317,9 +1319,11 @@
"textureProperty": "metallic.textureMap",
"useTextureProperty": "metallic.useTexture",
"dependentProperties": ["metallic.textureMapUv"],
- "shaderTags": [
+ "shaderTags": [
"ForwardPass",
- "ForwardPass_EDS"
+ "ForwardPass_EDS",
+ "LowEndForward",
+ "LowEndForward_EDS"
],
"shaderOption": "o_metallic_useTexture"
}
@@ -1330,9 +1334,11 @@
"textureProperty": "specularF0.textureMap",
"useTextureProperty": "specularF0.useTexture",
"dependentProperties": ["specularF0.textureMapUv"],
- "shaderTags": [
+ "shaderTags": [
"ForwardPass",
- "ForwardPass_EDS"
+ "ForwardPass_EDS",
+ "LowEndForward",
+ "LowEndForward_EDS"
],
"shaderOption": "o_specularF0_useTexture"
}
@@ -1343,9 +1349,11 @@
"textureProperty": "normal.textureMap",
"useTextureProperty": "normal.useTexture",
"dependentProperties": ["normal.textureMapUv", "normal.factor", "normal.flipX", "normal.flipY"],
- "shaderTags": [
+ "shaderTags": [
"ForwardPass",
- "ForwardPass_EDS"
+ "ForwardPass_EDS",
+ "LowEndForward",
+ "LowEndForward_EDS"
],
"shaderOption": "o_normal_useTexture"
}
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli
index 7400005508..721c48835d 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli
@@ -18,32 +18,30 @@
#include
#include
-void ApplyIblDiffuse(
+float3 GetIblDiffuse(
float3 normal,
float3 albedo,
- float3 diffuseResponse,
- out float3 outDiffuse)
+ float3 diffuseResponse)
{
float3 irradianceDir = MultiplyVectorQuaternion(normal, SceneSrg::m_iblOrientation);
float3 diffuseSample = SceneSrg::m_diffuseEnvMap.Sample(SceneSrg::m_samplerEnv, GetCubemapCoords(irradianceDir)).rgb;
- outDiffuse = diffuseResponse * albedo * diffuseSample;
+ return diffuseResponse * albedo * diffuseSample;
}
-void ApplyIblSpecular(
+float3 GetIblSpecular(
float3 position,
float3 normal,
float3 specularF0,
float roughnessLinear,
float3 dirToCamera,
- float2 brdf,
- out float3 outSpecular)
+ float2 brdf)
{
float3 reflectDir = reflect(-dirToCamera, normal);
reflectDir = MultiplyVectorQuaternion(reflectDir, SceneSrg::m_iblOrientation);
// global
- outSpecular = SceneSrg::m_specularEnvMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(roughnessLinear)).rgb;
+ float3 outSpecular = SceneSrg::m_specularEnvMap.SampleLevel(SceneSrg::m_samplerEnv, GetCubemapCoords(reflectDir), GetRoughnessMip(roughnessLinear)).rgb;
outSpecular *= (specularF0 * brdf.x + brdf.y);
// reflection probe
@@ -72,86 +70,54 @@ void ApplyIblSpecular(
outSpecular = lerp(outSpecular, probeSpecular, blendAmount);
}
+ return outSpecular;
}
void ApplyIBL(Surface surface, inout LightingData lightingData)
{
- if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent)
+#ifdef FORCE_IBL_IN_FORWARD_PASS
+ bool useDiffuseIbl = true;
+ bool useSpecularIbl = true;
+ bool useIbl = true;
+#else
+ bool useDiffuseIbl = (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent);
+ bool useSpecularIbl = (useDiffuseIbl || o_meshUseForwardPassIBLSpecular || o_materialUseForwardPassIBLSpecular);
+ bool useIbl = o_enableIBL && (useDiffuseIbl || useSpecularIbl);
+#endif
+
+ if(useIbl)
{
- // transparencies currently require IBL in the forward pass
- if (o_enableIBL)
+ float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
+
+ if(useDiffuseIbl)
{
- float3 iblDiffuse = 0.0f;
- ApplyIblDiffuse(
- surface.normal,
- surface.albedo,
- lightingData.diffuseResponse,
- iblDiffuse);
-
- float3 iblSpecular = 0.0f;
- ApplyIblSpecular(
- surface.position,
- surface.normal,
- surface.specularF0,
- surface.roughnessLinear,
- lightingData.dirToCamera,
- lightingData.brdf,
- iblSpecular);
-
- // Adjust IBL lighting by exposure.
- float iblExposureFactor = pow(2.0, SceneSrg::m_iblExposure);
+ float3 iblDiffuse = GetIblDiffuse(surface.normal, surface.albedo, lightingData.diffuseResponse);
lightingData.diffuseLighting += (iblDiffuse * iblExposureFactor * lightingData.diffuseAmbientOcclusion);
- lightingData.specularLighting += (iblSpecular * iblExposureFactor);
}
- }
- else if (o_meshUseForwardPassIBLSpecular || o_materialUseForwardPassIBLSpecular)
- {
- if (o_enableIBL)
- {
- float3 iblSpecular = 0.0f;
- ApplyIblSpecular(
- surface.position,
- surface.normal,
- surface.specularF0,
- surface.roughnessLinear,
- lightingData.dirToCamera,
- lightingData.brdf,
- iblSpecular);
+ if(useSpecularIbl)
+ {
+ float3 iblSpecular = GetIblSpecular(surface.position, surface.normal, surface.specularF0, surface.roughnessLinear, lightingData.dirToCamera, lightingData.brdf);
iblSpecular *= lightingData.multiScatterCompensation;
- if (o_clearCoat_feature_enabled)
+ if (o_clearCoat_feature_enabled && surface.clearCoat.factor > 0.0f)
{
- if (surface.clearCoat.factor > 0.0f)
- {
- float clearCoatNdotV = saturate(dot(surface.clearCoat.normal, lightingData.dirToCamera));
- clearCoatNdotV = max(clearCoatNdotV, 0.01f); // [GFX TODO][ATOM-4466] This is a current band-aid for specular noise at grazing angles.
- float2 clearCoatBrdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, GetBRDFTexCoords(surface.clearCoat.roughness, clearCoatNdotV)).rg;
-
- // clear coat uses fixed IOR = 1.5 represents polyurethane which is the most common material for gloss clear coat
- // coat layer assumed to be dielectric thus don't need multiple scattering compensation
- float3 clearCoatSpecularF0 = float3(0.04f, 0.04f, 0.04f);
- float3 clearCoatIblSpecular = 0.0f;
+ float clearCoatNdotV = saturate(dot(surface.clearCoat.normal, lightingData.dirToCamera));
+ clearCoatNdotV = max(clearCoatNdotV, 0.01f); // [GFX TODO][ATOM-4466] This is a current band-aid for specular noise at grazing angles.
+ float2 clearCoatBrdf = PassSrg::m_brdfMap.Sample(PassSrg::LinearSampler, GetBRDFTexCoords(surface.clearCoat.roughness, clearCoatNdotV)).rg;
- ApplyIblSpecular(
- surface.position,
- surface.clearCoat.normal,
- clearCoatSpecularF0,
- surface.clearCoat.roughness,
- lightingData.dirToCamera,
- clearCoatBrdf,
- clearCoatIblSpecular);
+ // clear coat uses fixed IOR = 1.5 represents polyurethane which is the most common material for gloss clear coat
+ // coat layer assumed to be dielectric thus don't need multiple scattering compensation
+ float3 clearCoatSpecularF0 = float3(0.04f, 0.04f, 0.04f);
+ float3 clearCoatIblSpecular = GetIblSpecular(surface.position, surface.clearCoat.normal, clearCoatSpecularF0, surface.clearCoat.roughness, lightingData.dirToCamera, clearCoatBrdf);
- clearCoatIblSpecular *= surface.clearCoat.factor;
+ clearCoatIblSpecular *= surface.clearCoat.factor;
- // attenuate base layer energy
- float3 clearCoatResponse = FresnelSchlickWithRoughness(clearCoatNdotV, clearCoatSpecularF0, surface.clearCoat.roughness) * surface.clearCoat.factor;
- iblSpecular = iblSpecular * (1.0 - clearCoatResponse) * (1.0 - clearCoatResponse) + clearCoatIblSpecular;
- }
+ // attenuate base layer energy
+ float3 clearCoatResponse = FresnelSchlickWithRoughness(clearCoatNdotV, clearCoatSpecularF0, surface.clearCoat.roughness) * surface.clearCoat.factor;
+ iblSpecular = iblSpecular * (1.0 - clearCoatResponse) * (1.0 - clearCoatResponse) + clearCoatIblSpecular;
}
-
- float iblExposureFactor = pow(2.0f, SceneSrg::m_iblExposure);
lightingData.specularLighting += (iblSpecular * iblExposureFactor);
}
}
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
index 907e67ada5..d6fb259548 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
@@ -18,7 +18,8 @@
#ifdef QUALITY_LOW_END
-#define UNIFIED_FORWARD_OUTPUT 1
+#define UNIFIED_FORWARD_OUTPUT 1
+#define FORCE_IBL_IN_FORWARD_PASS 1
#endif
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h
index b0d6bd4117..1cba71ae7e 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Pass/Pass.h
@@ -381,6 +381,7 @@ namespace AZ
uint64_t m_createdByPassRequest : 1;
uint64_t m_initialized : 1;
uint64_t m_enabled : 1;
+ uint64_t m_parentEnabled : 1;
uint64_t m_alreadyCreated : 1;
uint64_t m_alreadyReset : 1;
uint64_t m_alreadyPrepared : 1;
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp
index 9401d1a9e0..f93d661b0f 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/Pass.cpp
@@ -93,11 +93,12 @@ namespace AZ
void Pass::SetEnabled(bool enabled)
{
m_flags.m_enabled = enabled;
+ OnHierarchyChange();
}
bool Pass::IsEnabled() const
{
- return m_flags.m_enabled;
+ return m_flags.m_enabled && (m_flags.m_parentEnabled || m_parent == nullptr);
}
// --- Error Logging ---
@@ -140,6 +141,7 @@ namespace AZ
}
// Set new tree depth and path
+ m_flags.m_parentEnabled = m_parent->IsEnabled();
m_treeDepth = m_parent->m_treeDepth + 1;
m_path = ConcatPassName(m_parent->m_path, m_name);
m_flags.m_partOfHierarchy = m_parent->m_flags.m_partOfHierarchy;
From b08643d9da90d0215ed5b22efcc3716fdaa90622 Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Tue, 11 May 2021 11:24:51 +0100
Subject: [PATCH 033/209] Use renamed functions in stylesheet.
---
.../AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx | 2 +-
Code/Sandbox/Editor/Style/Editor.qss | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
index 58bf3bb9f0..1c17cab69f 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
@@ -44,7 +44,7 @@ namespace AzToolsFramework
Q_PROPERTY(bool hasChildRows READ HasChildRows);
Q_PROPERTY(bool isTopLevel READ IsTopLevel);
Q_PROPERTY(int getLevel READ GetLevel);
- Q_PROPERTY(bool isSectionSeparator READ IsSectionSeparator);
+ Q_PROPERTY(bool canBeReordered READ CanBeReordered);
Q_PROPERTY(bool appendDefaultLabelToName READ GetAppendDefaultLabelToName WRITE AppendDefaultLabelToName)
public:
AZ_CLASS_ALLOCATOR(PropertyRowWidget, AZ::SystemAllocator, 0)
diff --git a/Code/Sandbox/Editor/Style/Editor.qss b/Code/Sandbox/Editor/Style/Editor.qss
index 7887560105..fa7d67dd43 100644
--- a/Code/Sandbox/Editor/Style/Editor.qss
+++ b/Code/Sandbox/Editor/Style/Editor.qss
@@ -38,7 +38,7 @@ AzToolsFramework--ComponentPaletteWidget > QTreeView
background-color: #222222;
}
-AzToolsFramework--PropertyRowWidget[isSectionSeparator="true"] QLabel#Name
+AzToolsFramework--PropertyRowWidget[canBeReordered="true"] QLabel#Name
{
font-weight: bold;
}
From dbe16c6a164cf89342749efbbd2d0785d473a37a Mon Sep 17 00:00:00 2001
From: darapan
Date: Tue, 11 May 2021 05:07:16 -0700
Subject: [PATCH 034/209] "fixing review comments"
---
...s.py => Editor_NewExistingLevels_Works.py} | 17 +++++---------
.../Gem/PythonTests/smoke/ImportPathHelper.py | 16 -------------
....py => test_CLITool_AssetBuilder_Works.py} | 7 +++---
...> test_CLITool_AssetBundlerBatch_Works.py} | 7 +++---
...test_CLITool_AssetProcessorBatch_Works.py} | 23 +++++--------------
....py => test_CLITool_AzTestRunner_Works.py} | 7 +++---
...st_CLITool_PythonBindingsExample_Works.py} | 8 +++----
...st_CLITool_SerializeContextTools_Works.py} | 7 +++---
...=> test_Editor_NewExistingLevels_Works.py} | 6 +++--
...> test_StaticTools_GenPakShaders_Works.py} | 7 +++---
10 files changed, 34 insertions(+), 71 deletions(-)
rename AutomatedTesting/Gem/PythonTests/smoke/{Editor_NewExistingLevels.py => Editor_NewExistingLevels_Works.py} (93%)
delete mode 100644 AutomatedTesting/Gem/PythonTests/smoke/ImportPathHelper.py
rename AutomatedTesting/Gem/PythonTests/smoke/{test_AssetBuilder.py => test_CLITool_AssetBuilder_Works.py} (89%)
rename AutomatedTesting/Gem/PythonTests/smoke/{test_AssetBundlerBatch.py => test_CLITool_AssetBundlerBatch_Works.py} (89%)
rename AutomatedTesting/Gem/PythonTests/smoke/{test_AssetProcessorBatch.py => test_CLITool_AssetProcessorBatch_Works.py} (54%)
rename AutomatedTesting/Gem/PythonTests/smoke/{test_AzTestRunner.py => test_CLITool_AzTestRunner_Works.py} (90%)
rename AutomatedTesting/Gem/PythonTests/smoke/{test_PythonBindingsExample.py => test_CLITool_PythonBindingsExample_Works.py} (87%)
rename AutomatedTesting/Gem/PythonTests/smoke/{test_SerializeContextTools.py => test_CLITool_SerializeContextTools_Works.py} (88%)
rename AutomatedTesting/Gem/PythonTests/smoke/{test_Editor_NewExistingLevels.py => test_Editor_NewExistingLevels_Works.py} (88%)
rename AutomatedTesting/Gem/PythonTests/smoke/{test_Statictool_Scripts.py => test_StaticTools_GenPakShaders_Works.py} (90%)
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels.py b/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py
similarity index 93%
rename from AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels.py
rename to AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py
index 4e4a037ec9..ce46da494c 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py
@@ -9,9 +9,7 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-Test case ID: LY-123945
Test Case Title: Create Test for UI apps- Editor
-URL of the test case: https://jira.agscollab.com/browse/LY-123945
"""
@@ -30,7 +28,7 @@ class Tests():
# fmt: on
-def Editor_NewExistingLevels():
+def Editor_NewExistingLevels_Works():
"""
Summary: Perform the below operations on Editor
@@ -69,9 +67,9 @@ def Editor_NewExistingLevels():
"""
import os
- import hydra_editor_utils as hydra
- from utils import TestHelper as helper
- from utils import Report
+ import editor_python_test_tools.hydra_editor_utils as hydra
+ from editor_python_test_tools.utils import TestHelper as helper
+ from editor_python_test_tools.utils import Report
import azlmbr.bus as bus
import azlmbr.editor as editor
import azlmbr.legacy.general as general
@@ -146,10 +144,7 @@ def Editor_NewExistingLevels():
if __name__ == "__main__":
- import ImportPathHelper as imports
- imports.init()
+ from editor_python_test_tools.utils import Report
- from utils import Report
-
- Report.start_test(Editor_NewExistingLevels)
+ Report.start_test(Editor_NewExistingLevels_Works)
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/ImportPathHelper.py b/AutomatedTesting/Gem/PythonTests/smoke/ImportPathHelper.py
deleted file mode 100644
index 70bed6e526..0000000000
--- a/AutomatedTesting/Gem/PythonTests/smoke/ImportPathHelper.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-its licensors.
-
-For complete copyright and license terms please see the LICENSE at the root of this
-distribution (the "License"). All use of this software is governed by the License,
-or, if provided, by the license below or the license accompanying this file. Do not
-remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-"""
-
-def init():
- import os
- import sys
- sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
- sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../EditorPythonTestTools/editor_python_test_tools')
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBuilder.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBuilder_Works.py
similarity index 89%
rename from AutomatedTesting/Gem/PythonTests/smoke/test_AssetBuilder.py
rename to AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBuilder_Works.py
index da2abff50f..e20809b1b8 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBuilder.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBuilder_Works.py
@@ -10,7 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
-LY-124059 : CLI tool - AssetBuilder
+CLI tool - AssetBuilder
Launch AssetBuilder and Verify the help message
"""
@@ -23,7 +23,7 @@ import ly_test_tools.environment.process_utils as process_utils
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.usefixtures("automatic_process_killer")
@pytest.mark.SUITE_smoke
-class TestAssetBuilder(object):
+class TestCLIToolAssetBuilderWorks(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request):
def teardown():
@@ -31,8 +31,7 @@ class TestAssetBuilder(object):
request.addfinalizer(teardown)
- @pytest.mark.test_case_id("LY-124059")
- def test_AssetBuilder(self, request, editor, build_directory):
+ def test_CLITool_AssetBuilder_Works(self, request, editor, build_directory):
file_path = os.path.join(build_directory, "AssetBuilder")
help_message = "AssetBuilder is part of the Asset Processor"
# Launch AssetBuilder
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBundlerBatch.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBundlerBatch_Works.py
similarity index 89%
rename from AutomatedTesting/Gem/PythonTests/smoke/test_AssetBundlerBatch.py
rename to AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBundlerBatch_Works.py
index d361c62f5f..8a20715b3f 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetBundlerBatch.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBundlerBatch_Works.py
@@ -10,7 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
-LY-124060 : CLI tool - AssetBundlerBatch
+CLI tool - AssetBundlerBatch
Launch AssetBundlerBatch and Verify the help message
"""
@@ -23,7 +23,7 @@ import ly_test_tools.environment.process_utils as process_utils
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.usefixtures("automatic_process_killer")
@pytest.mark.SUITE_smoke
-class TestAssetBundlerBatch(object):
+class TestCLIToolAssetBundlerBatchWorks(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request):
def teardown():
@@ -31,8 +31,7 @@ class TestAssetBundlerBatch(object):
request.addfinalizer(teardown)
- @pytest.mark.test_case_id("LY-124060")
- def test_AssetBundlerBatch(self, request, editor, build_directory):
+ def test_CLITool_AssetBundlerBatch_Works(self, request, editor, build_directory):
file_path = os.path.join(build_directory, "AssetBundlerBatch")
help_message = "Specifies the Seed List file to operate on by path"
# Launch AssetBundlerBatch
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetProcessorBatch.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetProcessorBatch_Works.py
similarity index 54%
rename from AutomatedTesting/Gem/PythonTests/smoke/test_AssetProcessorBatch.py
rename to AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetProcessorBatch_Works.py
index ab541b94c1..30e681050c 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_AssetProcessorBatch.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetProcessorBatch_Works.py
@@ -10,34 +10,23 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
-LY-124061 : CLI tool - AssetProcessorBatch
+CLI tool - AssetProcessorBatch
Launch AssetProcessorBatch and Shutdown AssetProcessorBatch without any crash
"""
# Import builtin libraries
import pytest
-import os
-import sys
-
-sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../assetpipeline/")
-
-# Import fixtures
-from ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
+from ly_test_tools.o3de.asset_processor import AssetProcessor
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.usefixtures("automatic_process_killer")
-@pytest.mark.usefixtures("asset_processor")
@pytest.mark.SUITE_smoke
-class TestsAssetProcessorBatchs(object):
- @pytest.mark.test_case_id("LY-124061")
- def test_AssetProcessorBatch(self, asset_processor):
+class TestsCLIToolAssetProcessorBatchWorks(object):
+ def test_CLITool_AssetProcessorBatch_Works(self, workspace):
"""
Test Launching AssetProcessorBatch and verifies that is shuts down without issue
"""
- # Create a sample asset root so we don't process every asset for every platform
- asset_processor.create_temp_asset_root()
- # Launch AssetProcessorBatch, assert batch processing success
- result, _ = asset_processor.batch_process()
- assert result, "AP Batch failed"
+ asset_processor = AssetProcessor(workspace)
+ asset_processor.batch_process()
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_AzTestRunner.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py
similarity index 90%
rename from AutomatedTesting/Gem/PythonTests/smoke/test_AzTestRunner.py
rename to AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py
index d1bc44fe2f..5983cd7496 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_AzTestRunner.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py
@@ -10,7 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
-LY-124062 : CLI tool - AzTestRunner
+CLI tool - AzTestRunner
Launch AzTestRunner and Verify the help message
"""
@@ -23,7 +23,7 @@ import ly_test_tools.environment.process_utils as process_utils
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.usefixtures("automatic_process_killer")
@pytest.mark.SUITE_smoke
-class TestAzTestRunner(object):
+class TestCLIToolAzTestRunnerWorks(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request):
def teardown():
@@ -31,8 +31,7 @@ class TestAzTestRunner(object):
request.addfinalizer(teardown)
- @pytest.mark.test_case_id("LY-124062")
- def test_AzTestRunner(self, request, editor, build_directory):
+ def test_CLITool_AzTestRunner_Works(self, request, editor, build_directory):
file_path = os.path.join(build_directory, "AzTestRunner")
help_message = "OKAY Symbol found: AzRunUnitTests"
# Launch AzTestRunner
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_PythonBindingsExample.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_PythonBindingsExample_Works.py
similarity index 87%
rename from AutomatedTesting/Gem/PythonTests/smoke/test_PythonBindingsExample.py
rename to AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_PythonBindingsExample_Works.py
index 140e76fc96..68d12d0e70 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_PythonBindingsExample.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_PythonBindingsExample_Works.py
@@ -10,7 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
-LY-124064 : CLI tool - PythonBindingsExample
+CLI tool - PythonBindingsExample
Launch PythonBindingsExample and Verify the help message
"""
@@ -23,7 +23,7 @@ import ly_test_tools.environment.process_utils as process_utils
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.usefixtures("automatic_process_killer")
@pytest.mark.SUITE_smoke
-class TestPythonBindingsExample(object):
+class TestCLIToolPythonBindingsExampleWorks(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request):
def teardown():
@@ -31,8 +31,7 @@ class TestPythonBindingsExample(object):
request.addfinalizer(teardown)
- @pytest.mark.test_case_id("LY-124064")
- def test_PythonBindingsExample(self, request, editor, build_directory):
+ def test_CLITool_PythonBindingsExample_Works(self, request, editor, build_directory):
file_path = os.path.join(build_directory, "PythonBindingsExample")
help_message = "--help Prints the help text"
# Launch PythonBindingsExample
@@ -42,4 +41,3 @@ class TestPythonBindingsExample(object):
), f"Error occurred while launching {file_path}: {output.stderr}"
# Verify help message
assert help_message in str(output.stdout), f"Help Message: {help_message} is not present"
-
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_SerializeContextTools.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py
similarity index 88%
rename from AutomatedTesting/Gem/PythonTests/smoke/test_SerializeContextTools.py
rename to AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py
index 763d84625d..94178ca9d6 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_SerializeContextTools.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py
@@ -10,7 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
-LY-124066 : CLI tool - SerializeContextTools
+CLI tool - SerializeContextTools
Launch SerializeContextTools and Verify the help message
"""
@@ -23,7 +23,7 @@ import ly_test_tools.environment.process_utils as process_utils
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.usefixtures("automatic_process_killer")
@pytest.mark.SUITE_smoke
-class TestSerializeContextTools(object):
+class TestCLIToolSerializeContextToolsWorks(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request):
def teardown():
@@ -31,8 +31,7 @@ class TestSerializeContextTools(object):
request.addfinalizer(teardown)
- @pytest.mark.test_case_id("LY-124066")
- def test_SerializeContextTools(self, request, editor, build_directory):
+ def test_CLITool_SerializeContextTools_Works(self, request, editor, build_directory):
file_path = os.path.join(build_directory, "SerializeContextTools")
help_message = "Converts a file with an ObjectStream to the new JSON"
# Launch SerializeContextTools
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py
similarity index 88%
rename from AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels.py
rename to AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py
index 85d53d098d..510734a4a2 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py
@@ -24,11 +24,13 @@ import ly_test_tools.environment.file_system as file_system
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("level", ["temp_level"])
class TestAutomation(TestAutomationBase):
- def test_Editor_NewExistingLevels(self, request, workspace, editor, level, project, launcher_platform):
+ def test_Editor_NewExistingLevels_Works(self, request, workspace, editor, level, project, launcher_platform):
def teardown():
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
+
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
- from . import Editor_NewExistingLevels as test_module
+ from . import Editor_NewExistingLevels_Works as test_module
+
self._run_test(request, workspace, editor, test_module)
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py b/AutomatedTesting/Gem/PythonTests/smoke/test_StaticTools_GenPakShaders_Works.py
similarity index 90%
rename from AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
rename to AutomatedTesting/Gem/PythonTests/smoke/test_StaticTools_GenPakShaders_Works.py
index 8eac2ff099..05b91a602d 100644
--- a/AutomatedTesting/Gem/PythonTests/smoke/test_Statictool_Scripts.py
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_StaticTools_GenPakShaders_Works.py
@@ -10,7 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
"""
-LY-124058: Static tool scripts
+Static tool scripts
Launch Static tool and Verify the help message
"""
@@ -34,9 +34,8 @@ def verify_help_message(static_tool):
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.usefixtures("automatic_process_killer")
@pytest.mark.SUITE_smoke
-class TestStatictoolScripts(object):
- @pytest.mark.test_case_id("LY-124058")
- def test_Statictool_Scripts(self, request, editor):
+class TestStaticToolsGenPakShadersWorks(object):
+ def test_StaticTools_GenPakShaders_Works(self, request, editor):
static_tools = [
os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "gen_shaders.py"),
os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "get_shader_list.py"),
From d48df87bda8d653025e4a9c6fc8f45e873cbf443 Mon Sep 17 00:00:00 2001
From: darapan
Date: Tue, 11 May 2021 05:20:06 -0700
Subject: [PATCH 035/209] "Updating Cmake"
---
AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index 127db8e7e6..2a0a7f8008 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -399,3 +399,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
Legacy::Editor
AutomatedTesting.GameLauncher
AutomatedTesting.Assets
+ COMPONENT
+ Smoke
+ )
+endif()
\ No newline at end of file
From 006f4d2e8294da878161ce9db571e55b84fe2dc9 Mon Sep 17 00:00:00 2001
From: darapan
Date: Tue, 11 May 2021 05:34:38 -0700
Subject: [PATCH 036/209] "Adding Ap Test"
---
.../Gem/PythonTests/CMakeLists.txt | 2 +-
.../test_UIApps_AssetProcessor_CheckIdle.py | 41 +++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 AutomatedTesting/Gem/PythonTests/smoke/test_UIApps_AssetProcessor_CheckIdle.py
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index 2a0a7f8008..e91190f8e7 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -402,4 +402,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
COMPONENT
Smoke
)
-endif()
\ No newline at end of file
+endif()
diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_UIApps_AssetProcessor_CheckIdle.py b/AutomatedTesting/Gem/PythonTests/smoke/test_UIApps_AssetProcessor_CheckIdle.py
new file mode 100644
index 0000000000..0f5f870461
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/smoke/test_UIApps_AssetProcessor_CheckIdle.py
@@ -0,0 +1,41 @@
+"""
+All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+its licensors.
+
+For complete copyright and license terms please see the LICENSE at the root of this
+distribution (the "License"). All use of this software is governed by the License,
+or, if provided, by the license below or the license accompanying this file. Do not
+remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+"""
+
+"""
+UI Apps: AssetProcessor
+Open AssetProcessor, Wait until AssetProcessor is Idle
+Close AssetProcessor.
+"""
+
+
+import pytest
+from ly_test_tools.o3de.asset_processor import AssetProcessor
+
+
+@pytest.mark.parametrize("project", ["AutomatedTesting"])
+@pytest.mark.usefixtures("automatic_process_killer")
+@pytest.mark.SUITE_smoke
+class TestsUIAppsAssetProcessorCheckIdle(object):
+ @pytest.fixture(autouse=True)
+ def setup_teardown(self, request):
+ self.asset_processor = None
+
+ def teardown():
+ self.asset_processor.stop()
+
+ request.addfinalizer(teardown)
+
+ def test_UIApps_AssetProcessor_CheckIdle(self, workspace):
+ """
+ Test Launching AssetProcessorBatch and verifies that is shuts down without issue
+ """
+ self.asset_processor = AssetProcessor(workspace)
+ self.asset_processor.gui_process()
From 3ebf23211f8631c27ebe388830d471651f65ca66 Mon Sep 17 00:00:00 2001
From: Gene Walters
Date: Tue, 11 May 2021 09:37:34 -0700
Subject: [PATCH 037/209] Update Mutliplayer Autocomponent to add Get/Set
behavior context methods for any Network Properties with
GenerateEventBindings=true. Known issues: not tested with container types,
some jinja whitespace
---
.../Source/AutoGen/AutoComponent_Header.jinja | 1 +
.../Source/AutoGen/AutoComponent_Source.jinja | 62 +++++++++++++++----
2 files changed, 52 insertions(+), 11 deletions(-)
diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja
index 14a68cddf1..137a544a34 100644
--- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja
+++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja
@@ -410,6 +410,7 @@ namespace {{ Component.attrib['Namespace'] }}
static void Reflect(AZ::ReflectContext* context);
static void ReflectToEditContext(AZ::ReflectContext* context);
+ static void ReflectToBehaviorContext(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
index fb802541ce..6467119b89 100644
--- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
+++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
@@ -661,18 +661,42 @@ enum class NetworkProperties
{#
#}
-{% macro DefineNetworkPropertyBehaviorReflection(Component, ReplicateFrom, ReplicateTo, ClassType) %}
+{% macro DefineNetworkPropertyBehaviorReflection(Component, ReplicateFrom, ReplicateTo, ClassName) %}
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
-{% if (Property.attrib['IsPublic'] | booleanTrue == true) %}
-{% if Property.attrib['Container'] == 'Array' %}
-->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }})
-{% elif Property.attrib['Container'] == 'Vector' %}
-->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }})
-->Event("{{ Property.attrib['Name'] }}GetBack", &{{ ClassType }}Bus::Events::{{ Property.attrib['Name'] }}GetBack)
-->Event("{{ Property.attrib['Name'] }}GetSize", &{{ ClassType }}Bus::Events::{{ Property.attrib['Name'] }}GetSize)
-{% else %}
-->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }})
-{% endif %}
+{% if (Property.attrib['IsPublic'] | booleanTrue == true) and (Property.attrib['GenerateEventBindings'] | booleanTrue == true) %}
+ ->Method("Get{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id) -> {{ Property.attrib['Type'] }}
+ {
+ AZ::Entity* entity;
+ AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id);
+
+ if (entity)
+ {
+ if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>())
+ {
+ return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}();
+ }
+ }
+
+ return {{ Property.attrib['Type'] }}();
+ })
+ ->Method("Set{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id, const {{ Property.attrib['Type'] }}& {{ LowerFirst(Property.attrib['Name']) }}) -> void
+ {
+ AZ::Entity* entity;
+ AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id);
+
+ if (entity)
+ {
+ return;
+ }
+
+ if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>())
+ {
+ if (auto* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController()))
+ {
+ controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }});
+ }
+ }
+ })
{% endif %}
{% endcall -%}
{% endmacro %}
@@ -805,6 +829,7 @@ m_{{ LowerFirst(Service.attrib['Name']) }} = FindComponent<{{ UpperFirst(Service
{% endmacro %}
{#
+
#}
{% macro DefineNetworkPropertyEditConstruction(Component, ReplicateFrom, ReplicateTo, ClassName) %}
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
@@ -1131,6 +1156,7 @@ namespace {{ Component.attrib['Namespace'] }}
{{ DefineArchetypePropertyReflection(Component, ComponentBaseName)|indent(16) }};
}
ReflectToEditContext(context);
+ ReflectToBehaviorContext(context);
}
void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToEditContext(AZ::ReflectContext* context)
@@ -1155,6 +1181,20 @@ namespace {{ Component.attrib['Namespace'] }}
}
}
+ void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToBehaviorContext(AZ::ReflectContext* context)
+ {
+ if (auto* behaviorContext = azrtti_cast(context))
+ {
+ behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}")
+ {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}}
+{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Server', ComponentName)|indent(16) -}}
+{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Client', ComponentName)|indent(16) -}}
+{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Autonomous', ComponentName)|indent(16) -}}
+{{ DefineNetworkPropertyBehaviorReflection(Component, 'Autonomous', 'Authority', ComponentName)|indent(16) }}
+ {{ DefineArchetypePropertyBehaviorReflection(Component, ComponentName)|indent(16) }};
+ }
+ }
+
void {{ ComponentBaseName }}::{{ ComponentBaseName }}::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC_CE("{{ ComponentName }}Service"));
From f7641f3d3845dad3acb219b727521a4ab26fc8a1 Mon Sep 17 00:00:00 2001
From: darapan
Date: Tue, 11 May 2021 10:56:42 -0700
Subject: [PATCH 038/209] "Changing TIMEOUT in cmakelist.txt"
---
AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index e91190f8e7..a81630b880 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -392,7 +392,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
TEST_SUITE smoke
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/smoke
- TIMEOUT 3600
+ TIMEOUT 1500
RUNTIME_DEPENDENCIES
AZ::AssetProcessor
AZ::PythonBindingsExample
From 7ff5c0e10526a1297e5248f8819c8e5f61604c9d Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Tue, 11 May 2021 12:18:04 -0700
Subject: [PATCH 039/209] Add multiline spacing and GetTextSize to Atom Font
---
Code/CryEngine/CryCommon/IFont.h | 4 +
.../AzFramework/Font/FontInterface.h | 4 +
.../AtomLyIntegration/AtomFont/FFont.h | 14 +++
.../AtomFont/Code/Source/FFont.cpp | 93 ++++++++++++-------
4 files changed, 83 insertions(+), 32 deletions(-)
diff --git a/Code/CryEngine/CryCommon/IFont.h b/Code/CryEngine/CryCommon/IFont.h
index c8634fa854..7d573308aa 100644
--- a/Code/CryEngine/CryCommon/IFont.h
+++ b/Code/CryEngine/CryCommon/IFont.h
@@ -150,6 +150,7 @@ struct STextDrawContext
Vec2 m_size;
Vec2i m_requestSize;
float m_widthScale;
+ float m_lineSpacing;
float m_clipX;
float m_clipY;
@@ -180,6 +181,7 @@ struct STextDrawContext
, m_size(16.0f, 16.0f)
, m_requestSize(static_cast(m_size.x), static_cast(m_size.y))
, m_widthScale(1.0f)
+ , m_lineSpacing(0.f)
, m_clipX(0)
, m_clipY(0)
, m_clipWidth(0)
@@ -214,11 +216,13 @@ struct STextDrawContext
void SetTransform(const Matrix34& transform) { m_transform = transform; }
void SetBaseState(int baseState) { m_baseState = baseState; }
void SetOverrideViewProjMatrices(bool overrideViewProjMatrices) { m_overrideViewProjMatrices = overrideViewProjMatrices; }
+ void SetLineSpacing(float lineSpacing) { m_lineSpacing = lineSpacing; }
float GetCharWidth() const { return m_size.x; }
float GetCharHeight() const { return m_size.y; }
float GetCharWidthScale() const { return m_widthScale; }
int GetFlags() const { return m_drawTextFlags; }
+ float GetLineSpacing() const { return m_lineSpacing; }
bool IsColorOverridden() const { return m_colorOverride.a != 0; }
};
diff --git a/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h b/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h
index 7c5bcce6d6..48fa5bc2d2 100644
--- a/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h
+++ b/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h
@@ -44,6 +44,7 @@ namespace AzFramework
AZ::Vector3 m_position; //! world space position for 3d draws, screen space x,y,depth for 2d.
AZ::Color m_color = AZ::Colors::White; //! Color to draw the text
AZ::Vector2 m_scale = AZ::Vector2(1.0f); //! font scale
+ float m_lineSpacing; //! Spacing between new lines, as a percentage of m_scale.
TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //! Horizontal text alignment
TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //! Vertical text alignment
bool m_monospace = false; //! disable character proportional spacing
@@ -67,6 +68,9 @@ namespace AzFramework
virtual void DrawScreenAlignedText3d(
const TextDrawParameters& params,
const AZStd::string_view& string) = 0;
+ virtual AZ::Vector2 GetTextSize(
+ const TextDrawParameters& params,
+ const AZStd::string_view& string) = 0;
};
class FontQueryInterface
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
index fd66534197..83273633be 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
@@ -213,6 +213,10 @@ namespace AZ
const AzFramework::TextDrawParameters& params,
const AZStd::string_view& string) override;
+ AZ::Vector2 GetTextSize(
+ const AzFramework::TextDrawParameters& params,
+ const AZStd::string_view& string) override;
+
public:
FFont(AtomFont* atomFont, const char* fontName);
@@ -282,6 +286,16 @@ namespace AZ
RPI::WindowContextSharedPtr GetDefaultWindowContext() const;
RPI::ViewportContextPtr GetDefaultViewportContext() const;
+ struct DrawParameters
+ {
+ TextDrawContext m_ctx;
+ AZ::Vector2 m_position;
+ AZ::Vector2 m_size;
+ AZ::RPI::ViewportContext* m_viewportContext;
+ const AZ::RHI::Viewport* m_viewport;
+ };
+ DrawParameters ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize);
+
private:
static constexpr uint32_t NumBuffers = 2;
static constexpr float WindowScaleWidth = 800.0f;
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
index 40684640d6..48d24f0473 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
@@ -505,7 +505,7 @@ Vec2 AZ::FFont::GetTextSizeUInternal(
}
charX = offset.x;
- charY += size.y;
+ charY += size.y * (1.f + ctx.GetLineSpacing());
if (charY > maxH)
{
@@ -944,7 +944,7 @@ int AZ::FFont::CreateQuadsForText(const RHI::Viewport& viewport, float x, float
case '\n':
{
charX = baseXY.x + offset.x;
- charY += size.y;
+ charY += size.y * (1.f + ctx.GetLineSpacing());
continue;
}
break;
@@ -1674,47 +1674,47 @@ static void SetCommonContextFlags(AZ::TextDrawContext& ctx, const AzFramework::T
}
}
-void AZ::FFont::DrawScreenAlignedText2d(
- const AzFramework::TextDrawParameters& params,
- const AZStd::string_view& string)
+AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize)
{
+ DrawParameters internalParams;
if (params.m_drawViewportId == AzFramework::InvalidViewportId ||
string.empty())
{
- return;
+ return internalParams;
}
//Code mostly duplicated from CRenderer::Draw2dTextWithDepth
float posX = params.m_position.GetX();
float posY = params.m_position.GetY();
- AZ::RPI::ViewportContext* viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId).get();
- const AZ::RHI::Viewport& viewport = viewportContext->GetWindowContext()->GetViewport();
+ internalParams.m_viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId).get();
+ const AZ::RHI::Viewport& viewport = internalParams.m_viewportContext->GetWindowContext()->GetViewport();
+ internalParams.m_viewport = &viewport;
if (params.m_virtual800x600ScreenSize)
{
posX *= WindowScaleWidth / (viewport.m_maxX - viewport.m_minX);
posY *= WindowScaleHeight / (viewport.m_maxY - viewport.m_minY);
}
- TextDrawContext ctx;
- ctx.SetBaseState(GS_NODEPTHTEST);
- ctx.SetColor(AZColorToLYColorF(params.m_color));
- ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f);
- ctx.EnableFrame(false);
- ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow);
- ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize);
- ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale));
+ internalParams.m_ctx.SetBaseState(GS_NODEPTHTEST);
+ internalParams.m_ctx.SetColor(AZColorToLYColorF(params.m_color));
+ internalParams.m_ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f);
+ internalParams.m_ctx.EnableFrame(false);
+ internalParams.m_ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow);
+ internalParams.m_ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize);
+ internalParams.m_ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale));
+ internalParams.m_ctx.SetLineSpacing(params.m_lineSpacing);
if (params.m_monospace || !params.m_scaleWithWindow)
{
ScaleCoord(viewport, posX, posY);
}
if (params.m_hAlign != AzFramework::TextHorizontalAlignment::Left ||
- params.m_vAlign != AzFramework::TextVerticalAlignment::Top)
+ params.m_vAlign != AzFramework::TextVerticalAlignment::Top ||
+ forceCalculateSize)
{
- Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, ctx);
-
+ Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, internalParams.m_ctx);
// If we're using virtual 800x600 coordinates, convert the text size from
// pixels to that before using it as an offset.
- if (ctx.m_sizeIn800x600)
+ if (internalParams.m_ctx.m_sizeIn800x600)
{
float width = 1.0f;
float height = 1.0f;
@@ -1740,19 +1740,33 @@ void AZ::FFont::DrawScreenAlignedText2d(
{
posY -= textSize.y;
}
+ internalParams.m_size = AZ::Vector2{textSize.x, textSize.y};
+ }
+ SetCommonContextFlags(internalParams.m_ctx, params);
+ internalParams.m_ctx.m_drawTextFlags |= eDrawText_2D;
+ internalParams.m_position = AZ::Vector2{posX, posY};
+ return internalParams;
+}
+
+void AZ::FFont::DrawScreenAlignedText2d(
+ const AzFramework::TextDrawParameters& params,
+ const AZStd::string_view& string)
+{
+ DrawParameters internalParams = ExtractDrawParameters(params, string, false);
+ if (!internalParams.m_viewportContext)
+ {
+ return;
}
- SetCommonContextFlags(ctx, params);
- ctx.m_drawTextFlags |= eDrawText_2D;
DrawStringUInternal(
- viewport,
- viewportContext,
- posX,
- posY,
+ *internalParams.m_viewport,
+ internalParams.m_viewportContext,
+ internalParams.m_position.GetX(),
+ internalParams.m_position.GetY(),
params.m_position.GetZ(), // Z
string.data(),
params.m_multiline,
- ctx
+ internalParams.m_ctx
);
}
@@ -1760,13 +1774,12 @@ void AZ::FFont::DrawScreenAlignedText3d(
const AzFramework::TextDrawParameters& params,
const AZStd::string_view& string)
{
- if (params.m_drawViewportId == AzFramework::InvalidViewportId ||
- string.empty())
+ DrawParameters internalParams = ExtractDrawParameters(params, string, false);
+ if (!internalParams.m_viewportContext)
{
return;
}
- AZ::RPI::ViewportContext* viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId).get();
- AZ::RPI::ViewPtr currentView = viewportContext->GetDefaultView();
+ AZ::RPI::ViewPtr currentView = internalParams.m_viewportContext->GetDefaultView();
if (!currentView)
{
return;
@@ -1778,7 +1791,23 @@ void AZ::FFont::DrawScreenAlignedText3d(
);
AzFramework::TextDrawParameters param2d = params;
param2d.m_position = positionNDC;
- DrawScreenAlignedText2d(param2d, string);
+
+ DrawStringUInternal(
+ *internalParams.m_viewport,
+ internalParams.m_viewportContext,
+ internalParams.m_position.GetX(),
+ internalParams.m_position.GetY(),
+ params.m_position.GetZ(), // Z
+ string.data(),
+ params.m_multiline,
+ internalParams.m_ctx
+ );
+}
+
+AZ::Vector2 AZ::FFont::GetTextSize(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string)
+{
+ DrawParameters sizeParams = ExtractDrawParameters(params, string, true);
+ return sizeParams.m_size;
}
#endif //USE_NULLFONT_ALWAYS
From fe2931829338c9e6805050533056417a2f2d2686 Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Tue, 11 May 2021 12:18:49 -0700
Subject: [PATCH 040/209] Make ScriptTimePoint::Get const correct
---
Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h b/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h
index 7cb81829ef..08c997de2d 100644
--- a/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h
+++ b/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h
@@ -43,7 +43,7 @@ namespace AZ
return AZStd::string::format("Time %llu", m_timePoint.time_since_epoch().count());
}
- const AZStd::chrono::system_clock::time_point& Get() { return m_timePoint; }
+ const AZStd::chrono::system_clock::time_point& Get() const { return m_timePoint; }
// Returns the time point in seconds
double GetSeconds() const
From 3c5659668a0cd4343b7b7f86f56a3092328a4714 Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Tue, 11 May 2021 12:19:56 -0700
Subject: [PATCH 041/209] Add AZ::RPI::ViewportContextRequests alias for the
full interface
---
Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h
index bc7e5a4b1d..377c1d5c4e 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/ViewportContextBus.h
@@ -92,6 +92,8 @@ namespace AZ
virtual ViewPtr GetCurrentView(const Name& contextName) const = 0;
};
+ using ViewportContextRequests = AZ::Interface;
+
class ViewportContextManagerNotifications
: public AZ::EBusTraits
{
From 85e4f0d65ff5d5b7b6e1ba9759cace1907f60634 Mon Sep 17 00:00:00 2001
From: rgba16f <82187279+rgba16f@users.noreply.github.com>
Date: Tue, 11 May 2021 16:24:28 -0500
Subject: [PATCH 042/209] Fix AzFramework::g_defaultSceneEntityDebugDisplayId
not working for the AtomDebugDisplayViewportInstance
---
Code/Sandbox/Editor/EditorViewportWidget.cpp | 9 +++++
.../Code/Source/AtomBridgeSystemComponent.cpp | 38 +++++++------------
2 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp
index 3803867870..631a93af92 100644
--- a/Code/Sandbox/Editor/EditorViewportWidget.cpp
+++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp
@@ -452,6 +452,15 @@ void EditorViewportWidget::Update()
return;
}
+ static bool sentOnWindowCreated = false;
+ if (!sentOnWindowCreated && windowHandle()->isActive())
+ {
+ sentOnWindowCreated = true;
+ AzFramework::WindowSystemNotificationBus::Broadcast(
+ &AzFramework::WindowSystemNotificationBus::Handler::OnWindowCreated,
+ reinterpret_cast(winId()));
+ }
+
m_updatingCameraPosition = true;
auto transform = LYTransformToAZTransform(m_Camera.GetMatrix());
m_renderViewport->GetViewportContext()->SetCameraTransform(transform);
diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp
index 90731488f4..9148cdba6f 100644
--- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp
+++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/AtomBridgeSystemComponent.cpp
@@ -91,13 +91,9 @@ namespace AZ
AZ_UNUSED(dependent);
}
- static const AZ::Crc32 mainViewportEntityDebugDisplayId = AZ_CRC_CE("MainViewportEntityDebugDisplayId");
-
void AtomBridgeSystemComponent::Init()
{
-#if defined(ENABLE_ATOM_DEBUG_DISPLAY) && ENABLE_ATOM_DEBUG_DISPLAY
AZ::RPI::ViewportContextManagerNotificationsBus::Handler::BusConnect();
-#endif
}
void AtomBridgeSystemComponent::Activate()
@@ -112,9 +108,7 @@ namespace AZ
void AtomBridgeSystemComponent::Deactivate()
{
-#if defined(ENABLE_ATOM_DEBUG_DISPLAY) && ENABLE_ATOM_DEBUG_DISPLAY
AZ::RPI::ViewportContextManagerNotificationsBus::Handler::BusDisconnect();
-#endif
RPI::Scene* scene = RPI::RPISystemInterface::Get()->GetDefaultScene().get();
// Check if scene is emptry since scene might be released already when running AtomSampleViewer
if (scene)
@@ -193,36 +187,32 @@ namespace AZ
renderPipeline = bootstrapScene->GetDefaultRenderPipeline();
renderPipeline->SetDefaultView(m_view);
-
- auto auxGeomFP = bootstrapScene->GetFeatureProcessor();
- if (auxGeomFP)
- {
- auxGeomFP->GetOrCreateDrawQueueForView(m_view.get());
- }
-
-#if defined(ENABLE_ATOM_DEBUG_DISPLAY) && ENABLE_ATOM_DEBUG_DISPLAY
- // Make default AtomDebugDisplayViewportInterface for the scene
- AZStd::shared_ptr mainEntityDebugDisplay = AZStd::make_shared(mainViewportEntityDebugDisplayId);
- m_activeViewportsList[mainViewportEntityDebugDisplayId] = mainEntityDebugDisplay;
-#endif
}
+ else
+ {
+ m_view = renderPipeline->GetDefaultView();
+ }
+ auto auxGeomFP = bootstrapScene->GetFeatureProcessor();
+ if (auxGeomFP)
+ {
+ auxGeomFP->GetOrCreateDrawQueueForView(m_view.get());
+ }
+
+ // Make default AtomDebugDisplayViewportInterface for the scene
+ AZStd::shared_ptr mainEntityDebugDisplay = AZStd::make_shared(AzFramework::g_defaultSceneEntityDebugDisplayId);
+ m_activeViewportsList[AzFramework::g_defaultSceneEntityDebugDisplayId] = mainEntityDebugDisplay;
}
void AtomBridgeSystemComponent::OnViewportContextAdded(AZ::RPI::ViewportContextPtr viewportContext)
{
-#if defined(ENABLE_ATOM_DEBUG_DISPLAY) && ENABLE_ATOM_DEBUG_DISPLAY
AZStd::shared_ptr viewportDebugDisplay = AZStd::make_shared(viewportContext);
m_activeViewportsList[viewportContext->GetId()] = viewportDebugDisplay;
-#endif
}
void AtomBridgeSystemComponent::OnViewportContextRemoved(AzFramework::ViewportId viewportId)
{
-#if defined(ENABLE_ATOM_DEBUG_DISPLAY) && ENABLE_ATOM_DEBUG_DISPLAY
+ AZ_Assert(viewportId != AzFramework::g_defaultSceneEntityDebugDisplayId, "Error trying to remove the default scene draw instance");
m_activeViewportsList.erase(viewportId);
-#else
- AZ_UNUSED(viewportId);
-#endif
}
From 9775822778ec2cf8003ea86f455906f75bce1c14 Mon Sep 17 00:00:00 2001
From: scottr
Date: Tue, 11 May 2021 16:09:16 -0700
Subject: [PATCH 043/209] [cpack_installer] remove wxs file ext from lfs filter
---
.gitattributes | 1 -
1 file changed, 1 deletion(-)
diff --git a/.gitattributes b/.gitattributes
index 1755def66a..55b43e4ba7 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -115,5 +115,4 @@
*.wav filter=lfs diff=lfs merge=lfs -text
*.webm filter=lfs diff=lfs merge=lfs -text
*.wem filter=lfs diff=lfs merge=lfs -text
-*.wxs filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
From c777e2e35301cd0054fe39e8fdccb5e632d48a21 Mon Sep 17 00:00:00 2001
From: scottr
Date: Tue, 11 May 2021 18:07:19 -0700
Subject: [PATCH 044/209] [cpack_installer] some cpack cleanup and prep for
online installer support (pre/post build steps)
---
cmake/Packaging.cmake | 28 +++++++++++++------
.../Platform/Windows/PackagingPostBuild.cmake | 12 ++++++++
.../Platform/Windows/Packaging_windows.cmake | 8 ++++--
.../Windows/platform_windows_files.cmake | 1 +
4 files changed, 38 insertions(+), 11 deletions(-)
create mode 100644 cmake/Platform/Windows/PackagingPostBuild.cmake
diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake
index 4f6565edc7..e398ea7509 100644
--- a/cmake/Packaging.cmake
+++ b/cmake/Packaging.cmake
@@ -13,28 +13,38 @@ if(NOT PAL_TRAIT_BUILD_CPACK_SUPPORTED)
return()
endif()
-ly_get_absolute_pal_filename(pal_dir ${CMAKE_SOURCE_DIR}/cmake/Platform/${PAL_HOST_PLATFORM_NAME})
-include(${pal_dir}/Packaging_${PAL_HOST_PLATFORM_NAME_LOWERCASE}.cmake)
-
-# if we get here and the generator hasn't been set, then a non fatal error occurred disabling packaging support
-if(NOT CPACK_GENERATOR)
- return()
-endif()
+# set the common cpack variables first so they are accessible via configure_file
+# when the platforms specific properties are applied below
+set(LY_INSTALLER_DOWNLOAD_URL "" CACHE PATH "URL embded into the installer to download additional artifacts")
set(CPACK_PACKAGE_VENDOR "${PROJECT_NAME}")
set(CPACK_PACKAGE_VERSION "${LY_VERSION_STRING}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Installation Tool")
string(TOLOWER ${PROJECT_NAME} _project_name_lower)
-set(CPACK_PACKAGE_FILE_NAME "${_project_name_lower}_installer")
+set(CPACK_PACKAGE_FILE_NAME "${_project_name_lower}_${LY_VERSION_STRING}_installer")
set(DEFAULT_LICENSE_NAME "Apache-2.0")
-set(DEFAULT_LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
+set(DEFAULT_LICENSE_FILE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
set(CPACK_RESOURCE_FILE_LICENSE ${DEFAULT_LICENSE_FILE})
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_VENDOR}/${CPACK_PACKAGE_VERSION}")
+# custom cpack cache variables for use in pre/post build scripts
+set(CPACK_SOURCE_DIR ${CMAKE_SOURCE_DIR}/cmake)
+set(CPACK_BINARY_DIR ${CMAKE_BINARY_DIR}/installer)
+set(CPACK_DOWNLOAD_URL ${LY_INSTALLER_DOWNLOAD_URL})
+
+# attempt to apply platform specific settings
+ly_get_absolute_pal_filename(pal_dir ${CMAKE_SOURCE_DIR}/cmake/Platform/${PAL_HOST_PLATFORM_NAME})
+include(${pal_dir}/Packaging_${PAL_HOST_PLATFORM_NAME_LOWERCASE}.cmake)
+
+# if we get here and the generator hasn't been set, then a non fatal error occurred disabling packaging support
+if(NOT CPACK_GENERATOR)
+ return()
+endif()
+
# IMPORTANT: required to be included AFTER setting all property overrides
include(CPack REQUIRED)
diff --git a/cmake/Platform/Windows/PackagingPostBuild.cmake b/cmake/Platform/Windows/PackagingPostBuild.cmake
new file mode 100644
index 0000000000..fe57904003
--- /dev/null
+++ b/cmake/Platform/Windows/PackagingPostBuild.cmake
@@ -0,0 +1,12 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+
+message(STATUS "Hello from CPack post build!")
diff --git a/cmake/Platform/Windows/Packaging_windows.cmake b/cmake/Platform/Windows/Packaging_windows.cmake
index 8aa6f2386d..ba3ce011a4 100644
--- a/cmake/Platform/Windows/Packaging_windows.cmake
+++ b/cmake/Platform/Windows/Packaging_windows.cmake
@@ -32,7 +32,7 @@ set(CPACK_GENERATOR "WIX")
# however, they are unique for each run. instead, let's do the auto generation here and add it to
# the cache for run persistence. an additional cache file will be used to store the information on
# the original generation so we still have the ability to detect if they are still being used.
-set(_guid_cache_file "${CMAKE_BINARY_DIR}/installer/wix_guid_cache.cmake")
+set(_guid_cache_file "${CPACK_BINARY_DIR}/wix_guid_cache.cmake")
if(NOT EXISTS ${_guid_cache_file})
set(_wix_guid_namespace "6D43F57A-2917-4AD9-B758-1F13CDB08593")
@@ -89,4 +89,8 @@ endif()
set(CPACK_WIX_PRODUCT_GUID ${LY_WIX_PRODUCT_GUID})
set(CPACK_WIX_UPGRADE_GUID ${LY_WIX_UPGRADE_GUID})
-set(CPACK_WIX_TEMPLATE "${CMAKE_SOURCE_DIR}/cmake/Platform/Windows/PackagingTemplate.wxs.in")
+set(CPACK_WIX_TEMPLATE "${CPACK_SOURCE_DIR}/Platform/Windows/PackagingTemplate.wxs.in")
+
+set(CPACK_POST_BUILD_SCRIPTS
+ ${CPACK_SOURCE_DIR}/Platform/Windows/PackagingPostBuild.cmake
+)
diff --git a/cmake/Platform/Windows/platform_windows_files.cmake b/cmake/Platform/Windows/platform_windows_files.cmake
index 2fc869b43e..579621d5ea 100644
--- a/cmake/Platform/Windows/platform_windows_files.cmake
+++ b/cmake/Platform/Windows/platform_windows_files.cmake
@@ -24,5 +24,6 @@ set(FILES
PALDetection_windows.cmake
Install_windows.cmake
Packaging_windows.cmake
+ PackagingPostBuild.cmake
PackagingTemplate.wxs.in
)
From cdca18ca2590ddd46217398a3d63c5a5ffac7328 Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Tue, 11 May 2021 18:26:05 -0700
Subject: [PATCH 045/209] Use a smart viewport context pointer in AtomFont to
avoid a crash
---
.../Code/Include/AtomLyIntegration/AtomFont/FFont.h | 4 ++--
Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
index 83273633be..84d53a5446 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/FFont.h
@@ -237,7 +237,7 @@ namespace AZ
void Prepare(const char* str, bool updateTexture, const AtomFont::GlyphSize& glyphSize = AtomFont::defaultGlyphSize);
void DrawStringUInternal(
const RHI::Viewport& viewport,
- RPI::ViewportContext* viewportContext,
+ RPI::ViewportContextPtr viewportContext,
float x,
float y,
float z,
@@ -291,7 +291,7 @@ namespace AZ
TextDrawContext m_ctx;
AZ::Vector2 m_position;
AZ::Vector2 m_size;
- AZ::RPI::ViewportContext* m_viewportContext;
+ AZ::RPI::ViewportContextPtr m_viewportContext;
const AZ::RHI::Viewport* m_viewport;
};
DrawParameters ExtractDrawParameters(const AzFramework::TextDrawParameters& params, const AZStd::string_view& string, bool forceCalculateSize);
diff --git a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
index 48d24f0473..faeed52fb0 100644
--- a/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
+++ b/Gems/AtomLyIntegration/AtomFont/Code/Source/FFont.cpp
@@ -280,7 +280,7 @@ void AZ::FFont::DrawString(float x, float y, const char* str, const bool asciiMu
return;
}
- DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext().get(), x, y, 1.0f, str, asciiMultiLine, ctx);
+ DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext(), x, y, 1.0f, str, asciiMultiLine, ctx);
}
void AZ::FFont::DrawString(float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx)
@@ -290,12 +290,12 @@ void AZ::FFont::DrawString(float x, float y, float z, const char* str, const boo
return;
}
- DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext().get(), x, y, z, str, asciiMultiLine, ctx);
+ DrawStringUInternal(GetDefaultWindowContext()->GetViewport(), GetDefaultViewportContext(), x, y, z, str, asciiMultiLine, ctx);
}
void AZ::FFont::DrawStringUInternal(
const RHI::Viewport& viewport,
- RPI::ViewportContext* viewportContext,
+ RPI::ViewportContextPtr viewportContext,
float x,
float y,
float z,
@@ -1686,7 +1686,7 @@ AZ::FFont::DrawParameters AZ::FFont::ExtractDrawParameters(const AzFramework::Te
//Code mostly duplicated from CRenderer::Draw2dTextWithDepth
float posX = params.m_position.GetX();
float posY = params.m_position.GetY();
- internalParams.m_viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId).get();
+ internalParams.m_viewportContext = AZ::Interface::Get()->GetViewportContextById(params.m_drawViewportId);
const AZ::RHI::Viewport& viewport = internalParams.m_viewportContext->GetWindowContext()->GetViewport();
internalParams.m_viewport = &viewport;
if (params.m_virtual800x600ScreenSize)
From 6fcd5c7817a3a78172c8f98058056be710a52eb6 Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Tue, 11 May 2021 18:27:47 -0700
Subject: [PATCH 046/209] Restore Viewport debug text
Adds the AtomViewportDisplayInfo Gem which renders debug text to the default viewport context depending on the value of r_DisplayInfo.
The gem is flagged as a dependency of AtomBridge, so all Atom projects will consume it by default.
---
.../AtomBridge/Code/CMakeLists.txt | 4 +
.../AtomViewportDisplayInfo/CMakeLists.txt | 12 +
.../Code/CMakeLists.txt | 50 +++
...AtomViewportDisplayInfoSystemComponent.cpp | 289 ++++++++++++++++++
.../AtomViewportDisplayInfoSystemComponent.h | 79 +++++
.../Code/Source/Module.cpp | 51 ++++
.../Code/Source/Tests/test_Main.cpp | 20 ++
.../Code/atomviewportdisplayinfo_files.cmake | 16 +
.../atomviewportdisplayinfo_test_files.cmake | 14 +
.../AtomViewportDisplayInfo/gem.json | 32 ++
Gems/AtomLyIntegration/CMakeLists.txt | 1 +
11 files changed, 568 insertions(+)
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/CMakeLists.txt
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Module.cpp
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Tests/test_Main.cpp
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_files.cmake
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_test_files.cmake
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json
diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt
index b684e445b3..885f0d1a25 100644
--- a/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt
+++ b/Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt
@@ -29,6 +29,8 @@ ly_add_target(
Gem::Atom_RPI.Public
Gem::Atom_Bootstrap.Headers
Legacy::CryCommon
+ RUNTIME_DEPENDENCIES
+ Gem::AtomViewportDisplayInfo
)
ly_add_target(
@@ -68,5 +70,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
AZ::AssetBuilderSDK
Gem::Atom_Utils.Static
Gem::Atom_AtomBridge.Static
+ RUNTIME_DEPENDENCIES
+ Gem::AtomViewportDisplayInfo
)
endif()
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/CMakeLists.txt b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/CMakeLists.txt
new file mode 100644
index 0000000000..20a680bce9
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/CMakeLists.txt
@@ -0,0 +1,12 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+
+add_subdirectory(Code)
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt
new file mode 100644
index 0000000000..395cc22d47
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt
@@ -0,0 +1,50 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+
+ly_add_target(
+ NAME AtomViewportDisplayInfo GEM_MODULE
+ NAMESPACE Gem
+ FILES_CMAKE
+ atomviewportdisplayinfo_files.cmake
+ INCLUDE_DIRECTORIES
+ PRIVATE
+ Source
+ BUILD_DEPENDENCIES
+ PRIVATE
+ AZ::AzCore
+ AZ::AtomCore
+ Legacy::CryCommon
+ Gem::Atom_RHI.Reflect
+ Gem::Atom_RPI.Public
+)
+
+################################################################################
+# Tests
+################################################################################
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
+ ly_add_target(
+ NAME AtomViewportDisplayInfo.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
+ NAMESPACE Gem
+ FILES_CMAKE
+ atomviewportdisplayinfo_test_files.cmake
+ INCLUDE_DIRECTORIES
+ PRIVATE
+ Include
+ Tests
+ BUILD_DEPENDENCIES
+ PRIVATE
+ AZ::AzTest
+ )
+ ly_add_googletest(
+ NAME Gem::AtomViewportDisplayInfo.Tests
+ )
+endif()
+
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
new file mode 100644
index 0000000000..394923071e
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
@@ -0,0 +1,289 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+
+#include "AtomViewportDisplayInfoSystemComponent.h"
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+AZ_CVAR(float, r_fpsInterval, 1.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate,
+ "The time period over which to calculate the framerate for r_displayInfo");
+
+namespace AZ::Render
+{
+ static constexpr int DisplayInfoLevelNone = 0;
+ static constexpr int DisplayInfoLevelNormal = 1;
+ static constexpr int DisplayInfoLevelFull = 2;
+ static constexpr int DisplayInfoLevelCompact = 3;
+
+ void AtomViewportDisplayInfoSystemComponent::Reflect(AZ::ReflectContext* context)
+ {
+ if (AZ::SerializeContext* serialize = azrtti_cast(context))
+ {
+ serialize->Class()
+ ->Version(0)
+ ;
+
+ if (AZ::EditContext* ec = serialize->GetEditContext())
+ {
+ ec->Class("Viewport Display Info", "Manages debug viewport information through r_DisplayInfo")
+ ->ClassElement(Edit::ClassElements::EditorData, "")
+ ->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
+ ->Attribute(Edit::Attributes::AutoExpand, true)
+ ;
+ }
+ }
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+ {
+ provided.push_back(AZ_CRC("ViewportDisplayInfoService"));
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+ {
+ incompatible.push_back(AZ_CRC("ViewportDisplayInfoService"));
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
+ {
+ required.push_back(AZ_CRC("RPISystem", 0xf2add773));
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+ {
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::Activate()
+ {
+ AZ::Name apiName = AZ::RHI::Factory::Get().GetName();
+ if (!apiName.IsEmpty())
+ {
+ m_rendererDescription = AZStd::string::format("Atom using %s RHI", apiName.GetCStr());
+ }
+
+ CrySystemEventBus::Handler::BusConnect();
+ AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect(
+ AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContextName());
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::Deactivate()
+ {
+ AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect();
+ CrySystemEventBus::Handler::BusDisconnect();
+ }
+
+ AZ::RPI::ViewportContextPtr AtomViewportDisplayInfoSystemComponent::GetViewportContext() const
+ {
+ return AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContext();
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::DrawLine(AZStd::string_view line, AZ::Color color)
+ {
+ m_drawParams.m_color = color;
+ AzFramework::FontDrawInterface* fontDrawInterface =
+ AZ::Interface::Get()->GetDefaultFontDrawInterface();
+ AZ::Vector2 textSize = fontDrawInterface->GetTextSize(m_drawParams, line);
+ fontDrawInterface->DrawScreenAlignedText2d(m_drawParams, line);
+ m_drawParams.m_position.SetY(m_drawParams.m_position.GetY() + textSize.GetY() + m_lineSpacing);
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::OnRenderTick()
+ {
+ AzFramework::FontDrawInterface* fontDrawInterface =
+ AZ::Interface::Get()->GetDefaultFontDrawInterface();
+ AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
+
+ if (!fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene())
+ {
+ return;
+ }
+
+ m_fpsInterval = AZStd::chrono::seconds(r_fpsInterval);
+
+ UpdateFramerate();
+
+ if (!m_displayInfoCVar)
+ {
+ return;
+ }
+ int displayLevel = m_displayInfoCVar->GetIVal();
+ if (displayLevel == DisplayInfoLevelNone)
+ {
+ return;
+ }
+
+ m_drawParams.m_drawViewportId = viewportContext->GetId();
+ auto viewportSize = viewportContext->GetViewportSize();
+ m_drawParams.m_position = AZ::Vector3(viewportSize.m_width, 0.f, 1.f);
+ m_drawParams.m_color = AZ::Colors::White;
+ m_drawParams.m_scale = AZ::Vector2(0.7f);
+ m_drawParams.m_hAlign = AzFramework::TextHorizontalAlignment::Right;
+ m_drawParams.m_monospace = false;
+ m_drawParams.m_depthTest = false;
+ m_drawParams.m_virtual800x600ScreenSize = true;
+ m_drawParams.m_scaleWithWindow = false;
+ m_drawParams.m_multiline = true;
+ m_drawParams.m_lineSpacing = 0.5f;
+
+ // Calculate line spacing based on the font's actual line height
+ const float lineHeight = fontDrawInterface->GetTextSize(m_drawParams, " ").GetY();
+ m_lineSpacing = lineHeight * m_drawParams.m_lineSpacing;
+
+ DrawRendererInfo();
+ if (displayLevel != DisplayInfoLevelCompact)
+ {
+ DrawCameraInfo();
+ DrawMemoryInfo();
+ }
+ DrawFramerate();
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::OnCrySystemInitialized(ISystem& system, [[maybe_unused]]const SSystemInitParams& initParams)
+ {
+ m_displayInfoCVar = system.GetGlobalEnvironment()->pConsole->GetCVar("r_DisplayInfo");
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::OnCrySystemShutdown([[maybe_unused]]ISystem& system)
+ {
+ m_displayInfoCVar = nullptr;
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::DrawRendererInfo()
+ {
+ DrawLine(m_rendererDescription, AZ::Colors::Yellow);
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::DrawCameraInfo()
+ {
+ AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
+ AZ::RPI::ViewPtr currentView = viewportContext->GetDefaultView();
+ if (currentView == nullptr)
+ {
+ return;
+ }
+
+ auto viewportSize = viewportContext->GetViewportSize();
+ AzFramework::CameraState cameraState;
+ AzFramework::SetCameraClippingVolumeFromPerspectiveFovMatrixRH(cameraState, currentView->GetViewToClipMatrix());
+ const AZ::Transform transform = currentView->GetCameraTransform();
+ const AZ::Vector3 translation = transform.GetTranslation();
+ const AZ::Vector3 rotation = transform.GetEulerDegrees();
+ DrawLine(AZStd::string::format(
+ "CamPos=%.2f %.2f %.2f Angl=%3.0f %3.0f %4.0f ZN=%.2f ZF=%.0f",
+ translation.GetX(), translation.GetY(), translation.GetZ(),
+ rotation.GetX(), rotation.GetY(), rotation.GetZ(),
+ cameraState.m_nearClip, cameraState.m_farClip
+ ));
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::DrawMemoryInfo()
+ {
+ static IMemoryManager::SProcessMemInfo processMemInfo;
+
+ // Throttle memory usage updates to avoid potentially expensive memory usage API calls every tick.
+ constexpr AZStd::chrono::duration memoryUpdateInterval = AZStd::chrono::seconds(0.5);
+ AZStd::chrono::time_point currentTime = m_fpsHistory.back().Get();
+ if (m_lastMemoryUpdate.has_value())
+ {
+ if (currentTime - m_lastMemoryUpdate.value() > memoryUpdateInterval)
+ {
+ if (auto memoryManager = GetISystem()->GetIMemoryManager())
+ {
+ memoryManager->GetProcessMemInfo(processMemInfo);
+ }
+ }
+ }
+ m_lastMemoryUpdate = currentTime;
+
+
+ int peakUsageMB = aznumeric_cast(processMemInfo.PeakPagefileUsage >> 20);
+ int currentUsageMB = aznumeric_cast(processMemInfo.PagefileUsage >> 20);
+ DrawLine(AZStd::string::format("Mem=%d Peak=%d", currentUsageMB, peakUsageMB));
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::UpdateFramerate()
+ {
+ if (!m_tickRequests)
+ {
+ m_tickRequests = AZ::TickRequestBus::FindFirstHandler();
+ }
+ if (!m_tickRequests)
+ {
+ return;
+ }
+
+ AZ::ScriptTimePoint currentTime = m_tickRequests->GetTimeAtCurrentTick();
+ // Only keep as much sampling data is is required by our FPS history.
+ while (!m_fpsHistory.empty() && (currentTime.Get() - m_fpsHistory.front().Get() > m_fpsInterval))
+ {
+ m_fpsHistory.pop_front();
+ }
+ m_fpsHistory.push_back(currentTime);
+ }
+
+ void AtomViewportDisplayInfoSystemComponent::DrawFramerate()
+ {
+ AZStd::chrono::duration actualInterval = AZStd::chrono::seconds(0);
+ AZStd::optional lastTime;
+ AZStd::optional minFPS;
+ AZStd::optional maxFPS;
+ for (const AZ::ScriptTimePoint& time : m_fpsHistory)
+ {
+ if (lastTime.has_value())
+ {
+ AZStd::chrono::duration deltaTime = time.Get() - lastTime.value().Get();
+ if (deltaTime.count() == 0.0)
+ {
+ continue;
+ }
+ double fps = AZStd::chrono::seconds(1) / deltaTime;
+ if (!minFPS.has_value())
+ {
+ minFPS = fps;
+ maxFPS = fps;
+ }
+ else
+ {
+ minFPS = AZStd::min(minFPS.value(), fps);
+ maxFPS = AZStd::max(maxFPS.value(), fps);
+ }
+ actualInterval += deltaTime;
+ }
+ lastTime = time;
+ }
+
+ const double averageFPS = aznumeric_cast(m_fpsHistory.size()) / actualInterval.count();
+ const double frameIntervalSeconds = m_fpsInterval.count();
+
+ DrawLine(
+ AZStd::string::format(
+ "FPS %.1f [%.0f..%.0f], frame avg over %.1fs",
+ averageFPS,
+ minFPS.value_or(0.0),
+ maxFPS.value_or(0.0),
+ frameIntervalSeconds),
+ AZ::Colors::Yellow);
+ }
+} // namespace AZ::Render
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h
new file mode 100644
index 0000000000..5cb6ed3308
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.h
@@ -0,0 +1,79 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+#pragma once
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct ICVar;
+
+namespace AZ
+{
+ class TickRequests;
+
+ namespace Render
+ {
+ class AtomViewportDisplayInfoSystemComponent
+ : public AZ::Component
+ , public AZ::RPI::ViewportContextNotificationBus::Handler
+ , public CrySystemEventBus::Handler
+ {
+ public:
+ AZ_COMPONENT(AtomViewportDisplayInfoSystemComponent, "{AC32F173-E7E2-4943-8E6C-7C3091978221}");
+
+ static void Reflect(AZ::ReflectContext* context);
+
+ static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+ static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+ static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+ static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+ protected:
+ // AZ::Component overrides...
+ void Activate() override;
+ void Deactivate() override;
+
+ // AZ::RPI::ViewportContextNotificationBus::Handler overrides...
+ void OnRenderTick() override;
+
+ // CrySystemEventBus::Handler overrides...
+ void OnCrySystemInitialized(ISystem& system, const SSystemInitParams& initParams) override;
+ void OnCrySystemShutdown(ISystem& system) override;
+
+ private:
+ AZ::RPI::ViewportContextPtr GetViewportContext() const;
+ void DrawLine(AZStd::string_view line, AZ::Color color = AZ::Colors::White);
+
+ void UpdateFramerate();
+
+ void DrawRendererInfo();
+ void DrawCameraInfo();
+ void DrawMemoryInfo();
+ void DrawFramerate();
+
+ AZStd::string m_rendererDescription;
+ AzFramework::TextDrawParameters m_drawParams;
+ float m_lineSpacing;
+ AZStd::chrono::duration m_fpsInterval = AZStd::chrono::seconds(1);
+ AZStd::deque m_fpsHistory;
+ AZStd::optional m_lastMemoryUpdate;
+ AZ::TickRequests* m_tickRequests = nullptr;
+ ICVar* m_displayInfoCVar = nullptr;
+ };
+ } // namespace Render
+} // namespace AZ
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Module.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Module.cpp
new file mode 100644
index 0000000000..f67e1bd1f5
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Module.cpp
@@ -0,0 +1,51 @@
+/*
+ * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+ * its licensors.
+ *
+ * For complete copyright and license terms please see the LICENSE at the root of this
+ * distribution (the "License"). All use of this software is governed by the License,
+ * or, if provided, by the license below or the license accompanying this file. Do not
+ * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ */
+
+#include
+#include
+#include
+
+#include "AtomViewportDisplayInfoSystemComponent.h"
+
+namespace AZ
+{
+ namespace Render
+ {
+ class AtomViewportDisplayInfoModule
+ : public AZ::Module
+ {
+ public:
+ AZ_RTTI(AtomViewportDisplayInfoModule, "{B10C0E55-03A1-4A46-AE3E-D3615AEAA659}", AZ::Module);
+ AZ_CLASS_ALLOCATOR(AtomViewportDisplayInfoModule, AZ::SystemAllocator, 0);
+
+ AtomViewportDisplayInfoModule()
+ : AZ::Module()
+ {
+ m_descriptors.insert(m_descriptors.end(), {
+ AtomViewportDisplayInfoSystemComponent::CreateDescriptor(),
+ });
+ }
+
+ AZ::ComponentTypeList GetRequiredSystemComponents() const override
+ {
+ return AZ::ComponentTypeList{
+ azrtti_typeid(),
+ };
+ }
+ };
+ } // namespace Render
+} // namespace AZ
+
+// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
+// The first parameter should be GemName_GemIdLower
+// The second should be the fully qualified name of the class above
+AZ_DECLARE_MODULE_CLASS(Gem_AtomViewportDisplayInfo, AZ::Render::AtomViewportDisplayInfoModule)
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Tests/test_Main.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Tests/test_Main.cpp
new file mode 100644
index 0000000000..b533221bbe
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/Tests/test_Main.cpp
@@ -0,0 +1,20 @@
+/*
+* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+* its licensors.
+*
+* For complete copyright and license terms please see the LICENSE at the root of this
+* distribution (the "License"). All use of this software is governed by the License,
+* or, if provided, by the license below or the license accompanying this file. Do not
+* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*
+*/
+
+#include
+
+AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
+
+TEST(AtomViewportDisplayInfoSanityTest, Sanity)
+{
+ EXPECT_EQ(1, 1);
+}
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_files.cmake b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_files.cmake
new file mode 100644
index 0000000000..561971453b
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_files.cmake
@@ -0,0 +1,16 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+
+set(FILES
+ Source/AtomViewportDisplayInfoSystemComponent.cpp
+ Source/AtomViewportDisplayInfoSystemComponent.h
+ Source/Module.cpp
+)
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_test_files.cmake b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_test_files.cmake
new file mode 100644
index 0000000000..0bc1ee3a50
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/atomviewportdisplayinfo_test_files.cmake
@@ -0,0 +1,14 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+
+set(FILES
+ Source/Tests/test_Main.cpp
+)
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json
new file mode 100644
index 0000000000..a54dc188a7
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json
@@ -0,0 +1,32 @@
+{
+ "gem_name": "AtomLyIntegration_AtomViewportDisplayInfo",
+ "Dependencies": [
+ {
+ "Uuid": "a218db9eb2114477b46600fea4441a6c",
+ "VersionConstraints": [
+ "~>0.1.0"
+ ],
+ "_comment": "Atom RPI"
+ },
+ {
+ "Uuid": "c7ff89ad6e8b4b45b2fadef2bcf12d6e",
+ "VersionConstraints": [
+ "~>0.1.0"
+ ],
+ "_comment": "Atom_Bootstrap"
+ }
+ ],
+ "GemFormatVersion": 4,
+ "Uuid": "7c255c884bae4046b0640abe3c88cc4c",
+ "Name": "AtomLyIntegration_AtomViewportDisplayInfo",
+ "DisplayName": "Atom.AtomViewportDisplayInfo",
+ "Version": "0.1.0",
+ "Summary": "Provides a diagnostic viewport overlay for the default O3DE Atom viewport.",
+ "Tags": ["Atom"],
+ "IconPath": "preview.png",
+ "Modules": [
+ {
+ "Type": "GameModule"
+ }
+ ]
+}
diff --git a/Gems/AtomLyIntegration/CMakeLists.txt b/Gems/AtomLyIntegration/CMakeLists.txt
index 57bb860a9e..35022e643b 100644
--- a/Gems/AtomLyIntegration/CMakeLists.txt
+++ b/Gems/AtomLyIntegration/CMakeLists.txt
@@ -16,3 +16,4 @@ add_subdirectory(EMotionFXAtom)
add_subdirectory(AtomFont)
add_subdirectory(TechnicalArt)
add_subdirectory(AtomBridge)
+add_subdirectory(AtomViewportDisplayInfo)
From 7342e62680a8a651df4bd935f9c44ddb11239e8d Mon Sep 17 00:00:00 2001
From: mnaumov
Date: Tue, 11 May 2021 19:33:46 -0700
Subject: [PATCH 047/209] Hiding "Open Material" when material asset is
assigned
---
.../Code/Source/Material/EditorMaterialComponentSlot.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp
index 9d63f4a4a9..7ebf25454d 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp
@@ -269,7 +269,8 @@ namespace AZ
QAction* action = nullptr;
- menu.addAction("Open Material Editor", [this]() { EditorMaterialSystemComponentRequestBus::Broadcast(&EditorMaterialSystemComponentRequestBus::Events::OpenInMaterialEditor, ""); });
+ action = menu.addAction("Open Material Editor...", [this]() { EditorMaterialSystemComponentRequestBus::Broadcast(&EditorMaterialSystemComponentRequestBus::Events::OpenInMaterialEditor, ""); });
+ action->setVisible(!m_materialAsset.GetId().IsValid());
action = menu.addAction("Clear", [this]() { Clear(); });
action->setEnabled(m_materialAsset.GetId().IsValid() || !m_propertyOverrides.empty() || !m_matModUvOverrides.empty());
From 0867764e5b732074a67985c4d758fab1a53910db Mon Sep 17 00:00:00 2001
From: Gene Walters
Date: Tue, 11 May 2021 22:46:21 -0700
Subject: [PATCH 048/209] Updating Autocomponent behavior context property
methods to give warnings if a Get/Set fails and how users might go about
fixing the issue
---
.../Source/AutoGen/AutoComponent_Source.jinja | 47 ++++++++++++-------
1 file changed, 29 insertions(+), 18 deletions(-)
diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
index 423aa57706..576978f75c 100644
--- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
+++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
@@ -666,36 +666,46 @@ enum class NetworkProperties
{% if (Property.attrib['IsPublic'] | booleanTrue == true) and (Property.attrib['GenerateEventBindings'] | booleanTrue == true) %}
->Method("Get{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id) -> {{ Property.attrib['Type'] }}
{
- AZ::Entity* entity;
- AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id);
+ AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id);
+ if (!entity)
+ {
+ AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
+ return {{ Property.attrib['Type'] }}();
+ }
- if (entity)
+ {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>();
+ if (!networkComponent)
{
- if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>())
- {
- return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}();
- }
+ AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str())
+ return {{ Property.attrib['Type'] }}();
}
- return {{ Property.attrib['Type'] }}();
+ return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}();
})
->Method("Set{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id, const {{ Property.attrib['Type'] }}& {{ LowerFirst(Property.attrib['Name']) }}) -> void
{
- AZ::Entity* entity;
- AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id);
-
- if (entity)
+ AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id);
+ if (!entity)
+ {
+ AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
+ return;
+ }
+
+ {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>();
+ if (!networkComponent)
{
+ AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} method failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str())
return;
}
- if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>())
+ {{ ClassName }}Controller* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController());
+ if (!controller)
{
- if (auto* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController()))
- {
- controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }});
- }
+ AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} method failed. Entity '%s' (id: %s) {{ ClassName }} is missing the network controller. Network controllers only spawn when some form of write access is available; for example, when you're server authoritatively controlling this entity, or you're a client predictively writing to your player entity. Please check your network context before attempting to set {{ UpperFirst(Property.attrib['Name']) }}.", entity->GetName().c_str(), id.ToString().c_str())
+ return;
}
+
+ controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }});
})
{% endif %}
{% endcall -%}
@@ -1183,7 +1193,8 @@ namespace {{ Component.attrib['Namespace'] }}
void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToBehaviorContext(AZ::ReflectContext* context)
{
- if (auto* behaviorContext = azrtti_cast(context))
+ AZ::BehaviorContext* behaviorContext = azrtti_cast(context);
+ if (behaviorContext)
{
behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}")
{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}}
From f5e91c6e4284f00e64db5cc4ba4e0678be111b1c Mon Sep 17 00:00:00 2001
From: antonmic
Date: Wed, 12 May 2021 10:39:18 -0700
Subject: [PATCH 049/209] Added low end shaders in StandardPBR_ShaderEnable.lua
---
.../Assets/Materials/Types/StandardPBR_ShaderEnable.lua | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ShaderEnable.lua b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ShaderEnable.lua
index 7c3d989c35..2733713122 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ShaderEnable.lua
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ShaderEnable.lua
@@ -29,26 +29,33 @@ function Process(context)
local depthPass = context:GetShaderByTag("DepthPass")
local shadowMap = context:GetShaderByTag("Shadowmap")
local forwardPassEDS = context:GetShaderByTag("ForwardPass_EDS")
+ local lowEndForwardEDS = context:GetShaderByTag("LowEndForward_EDS")
+
local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS")
local shadowMapWitPS = context:GetShaderByTag("Shadowmap_WithPS")
local forwardPass = context:GetShaderByTag("ForwardPass")
+ local lowEndForward = context:GetShaderByTag("LowEndForward")
if parallaxEnabled and parallaxPdoEnabled then
depthPass:SetEnabled(false)
shadowMap:SetEnabled(false)
forwardPassEDS:SetEnabled(false)
+ lowEndForwardEDS:SetEnabled(false)
depthPassWithPS:SetEnabled(true)
shadowMapWitPS:SetEnabled(true)
forwardPass:SetEnabled(true)
+ lowEndForward:SetEnabled(true)
else
depthPass:SetEnabled(opacityMode == OpacityMode_Opaque)
shadowMap:SetEnabled(opacityMode == OpacityMode_Opaque)
forwardPassEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
+ lowEndForwardEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
depthPassWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
shadowMapWitPS:SetEnabled(opacityMode == OpacityMode_Cutout)
forwardPass:SetEnabled(opacityMode == OpacityMode_Cutout)
+ lowEndForward:SetEnabled(opacityMode == OpacityMode_Cutout)
end
context:GetShaderByTag("DepthPassTransparentMin"):SetEnabled((opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
From 92b7099d78953eef8552633201b98d8f07597529 Mon Sep 17 00:00:00 2001
From: antonmic
Date: Wed, 12 May 2021 11:10:13 -0700
Subject: [PATCH 050/209] Some clean up
---
.../Common/Assets/Materials/Types/StandardPBR.materialtype | 7 -------
.../Assets/Materials/Types/StandardPBR_ForwardPass.azsl | 4 ++--
.../Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli | 3 +++
.../ShaderLib/Atom/Features/ShaderQualityOptions.azsli | 4 +---
Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl | 6 ++----
5 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
index 47d8a9d9d5..a9a3e9e09b 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype
@@ -77,13 +77,6 @@
],
"properties": {
"general": [
- {
- "id": "useLowEndShader",
- "displayName": "Use Low End",
- "description": "Whether to use the low end shader.",
- "type": "Bool",
- "defaultValue": false
- },
{
"id": "applySpecularAA",
"displayName": "Apply Specular AA",
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl
index 1e6fafda9b..7ae5934d4f 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl
@@ -321,7 +321,7 @@ ForwardPassOutputWithDepth StandardPbr_ForwardPassPS(VSOutput IN, bool isFrontFa
#ifdef UNIFIED_FORWARD_OUTPUT
OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb;
- OUT.m_color.a = 1.0f;
+ OUT.m_color.a = lightingOutput.m_diffuseColor.a;
OUT.m_depth = depth;
#else
OUT.m_diffuseColor = lightingOutput.m_diffuseColor;
@@ -344,7 +344,7 @@ ForwardPassOutput StandardPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace :
#ifdef UNIFIED_FORWARD_OUTPUT
OUT.m_color.rgb = lightingOutput.m_diffuseColor.rgb + lightingOutput.m_specularColor.rgb;
- OUT.m_color.a = 1.0f;
+ OUT.m_color.a = lightingOutput.m_diffuseColor.a;
#else
OUT.m_diffuseColor = lightingOutput.m_diffuseColor;
OUT.m_specularColor = lightingOutput.m_specularColor;
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli
index 721c48835d..3e3544fe9e 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Lights/Ibl.azsli
@@ -12,6 +12,9 @@
#pragma once
+// --- Static Options Available ---
+// FORCE_IBL_IN_FORWARD_PASS - forces IBL lighting to be run in the forward pass, used in pipelines that don't have a reflection pass
+
#include
#include
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
index d6fb259548..6e89269f8d 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/ShaderQualityOptions.azsli
@@ -12,9 +12,7 @@
#pragma once
-// These are a list of quality options to specify as macros (either in azsl or in shader files)
-//
-// QUALITY_LOW_END
+// This file translates quality option macros like QUALITY_LOW_END to their relevant settings
#ifdef QUALITY_LOW_END
diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
index 4b3e9536b7..1bebb2ec47 100644
--- a/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Shaders/SkyBox/SkyBox.azsl
@@ -10,10 +10,8 @@
*
*/
-// Static Options:
-//
-// SKYBOX_TWO_OUTPUTS - Allows the skybox to render to two rendertargets instead of one
-
+// --- Static Options Available ---
+// SKYBOX_TWO_OUTPUTS - Skybox renders to two rendertargets instead of one (SkyBox_TwoOutputs.pass writes to specular and reflection targets)
#include
#include
From b52388f5ebfb5af09505a99fe1e416ae12907dd0 Mon Sep 17 00:00:00 2001
From: antonmic
Date: Wed, 12 May 2021 11:11:45 -0700
Subject: [PATCH 051/209] Remove unused file
---
.../PBR/LowEndForwardPassOutput.azsli | 32 -------------------
1 file changed, 32 deletions(-)
delete mode 100644 Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli
deleted file mode 100644
index acc215f1c9..0000000000
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/LowEndForwardPassOutput.azsli
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
-* its licensors.
-*
-* For complete copyright and license terms please see the LICENSE at the root of this
-* distribution (the "License"). All use of this software is governed by the License,
-* or, if provided, by the license below or the license accompanying this file. Do not
-* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-*
-*/
-
-struct ForwardPassOutput
-{
- float4 m_diffuseColor : SV_Target0; //!< RGB = Diffuse Lighting, A = Blend Alpha (for blended surfaces) OR A = special encoding of surfaceScatteringFactor, m_subsurfaceScatteringQuality, o_enableSubsurfaceScattering
- float4 m_specularColor : SV_Target1; //!< RGB = Specular Lighting, A = Unused
- float4 m_albedo : SV_Target2; //!< RGB = Surface albedo pre-multiplied by other factors that will be multiplied later by diffuse GI, A = specularOcclusion
- float4 m_specularF0 : SV_Target3; //!< RGB = Specular F0, A = roughness
- float4 m_normal : SV_Target4; //!< RGB10 = EncodeNormalSignedOctahedron(worldNormal), A2 = multiScatterCompensationEnabled
-};
-
-struct ForwardPassOutputWithDepth
-{
- // See above for descriptions of special encodings
-
- float4 m_diffuseColor : SV_Target0;
- float4 m_specularColor : SV_Target1;
- float4 m_albedo : SV_Target2;
- float4 m_specularF0 : SV_Target3;
- float4 m_normal : SV_Target4;
- float m_depth : SV_Depth;
-};
From 7bdf44a0996b93bea061c5146e5627e7abbb8b21 Mon Sep 17 00:00:00 2001
From: srikappa
Date: Wed, 12 May 2021 13:38:44 -0700
Subject: [PATCH 052/209] Detect cyclical dependencies in the nested prefabs of
the prefab being instantiated
---
.../Prefab/PrefabDomUtils.cpp | 37 ++++++++++++++++
.../AzToolsFramework/Prefab/PrefabDomUtils.h | 14 +++++++
.../Prefab/PrefabPublicHandler.cpp | 42 ++++++++++---------
.../Prefab/PrefabPublicHandler.h | 18 ++++----
4 files changed, 84 insertions(+), 27 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
index 0bffd26be0..145a293ab8 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
@@ -199,6 +199,43 @@ namespace AzToolsFramework
return true;
}
+ void GetTemplateSourcePaths(const PrefabDomValue& prefabDom, AZStd::unordered_set& templateSourcePaths)
+ {
+ PrefabDomValueConstReference findSourceResult = PrefabDomUtils::FindPrefabDomValue(prefabDom, PrefabDomUtils::SourceName);
+ if (!findSourceResult.has_value() || !(findSourceResult->get().IsString()) ||
+ findSourceResult->get().GetStringLength() == 0)
+ {
+ AZ_Assert(
+ false,
+ "PrefabDomUtils::GetDependentTemplatePath - Source value of prefab in the provided DOM is not a valid string.");
+ return;
+ }
+
+ templateSourcePaths.emplace(findSourceResult->get().GetString());
+ PrefabDomValueConstReference instancesReference = GetInstancesValue(prefabDom);
+ if (instancesReference.has_value())
+ {
+ const PrefabDomValue& instances = instancesReference->get();
+
+ for (PrefabDomValue::ConstMemberIterator instanceIterator = instances.MemberBegin();
+ instanceIterator != instances.MemberEnd(); ++instanceIterator)
+ {
+ GetTemplateSourcePaths(instanceIterator->value, templateSourcePaths);
+ }
+ }
+ }
+
+ PrefabDomValueConstReference GetInstancesValue(const PrefabDomValue& prefabDom)
+ {
+ PrefabDomValueConstReference findInstancesResult = FindPrefabDomValue(prefabDom, PrefabDomUtils::InstancesName);
+ if (!findInstancesResult.has_value() || !(findInstancesResult->get().IsObject()))
+ {
+ return AZStd::nullopt;
+ }
+
+ return findInstancesResult->get();
+ }
+
void PrintPrefabDomValue(
[[maybe_unused]] const AZStd::string_view printMessage,
[[maybe_unused]] const PrefabDomValue& prefabDomValue)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h
index c7c2827770..6f7d2fe9b1 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h
@@ -100,6 +100,20 @@ namespace AzToolsFramework
.Append(instanceName);
};
+ /**
+ * Gets a set of all the template source paths in the given dom.
+ * @param prefabDom The DOM to get the template source paths from.
+ * @param templateSourcePaths The set of template source paths to populate.
+ */
+ void GetTemplateSourcePaths(const PrefabDomValue& prefabDom, AZStd::unordered_set& templateSourcePaths);
+
+ /**
+ * Gets the instances DOM value from the given prefab DOM.
+ *
+ * @return the instances DOM value or AZStd::nullopt if it instances can't be found.
+ */
+ PrefabDomValueConstReference GetInstancesValue(const PrefabDomValue& prefabDom);
+
/**
* Prints the contents of the given prefab DOM value to the debug output console in a readable format.
* @param printMessage The message that will be printed before printing the PrefabDomValue
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
index 14537683ef..e2c616d5d8 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
@@ -191,25 +191,30 @@ namespace AzToolsFramework
auto relativePath = m_prefabLoaderInterface->GetRelativePathToProject(filePath);
Prefab::TemplateId templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(relativePath);
- // If the template isn't currently loaded, there's no way for it to be in the hierarchy so we just skip the check.
- if (templateId != Prefab::InvalidTemplateId && IsPrefabInInstanceAncestorHierarchy(templateId, instanceToParentUnder->get()))
+ if (templateId == InvalidTemplateId)
{
- return AZ::Failure(
- AZStd::string::format(
- "Instantiate Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).",
- relativePath.Native().c_str(),
- instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str()
- )
- );
+ // Load the template from the file
+ templateId = m_prefabLoaderInterface->LoadTemplateFromFile(filePath);
+ AZ_Assert(templateId != InvalidTemplateId, "Template with source path %s couldn't be loaded correctly.", filePath);
}
-
+
+ const PrefabDom& templateDom = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
+ AZStd::unordered_set templatePaths;
+ PrefabDomUtils::GetTemplateSourcePaths(templateDom, templatePaths);
+
+ if (IsCyclicalDependencyFound(instanceToParentUnder->get(), templatePaths))
+ {
+ return AZ::Failure(AZStd::string::format(
+ "Instantiate Prefab operation aborted - Cyclical dependency detected\n(%s depends on %s).",
+ relativePath.Native().c_str(), instanceToParentUnder->get().GetTemplateSourcePath().Native().c_str()));
+ }
+
{
// Initialize Undo Batch object
ScopedUndoBatch undoBatch("Instantiate Prefab");
PrefabDom instanceToParentUnderDomBeforeCreate;
- m_instanceToTemplateInterface->GenerateDomForInstance(
- instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get());
+ m_instanceToTemplateInterface->GenerateDomForInstance(instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get());
// Instantiate the Prefab
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(relativePath, instanceToParentUnder);
@@ -223,8 +228,7 @@ namespace AzToolsFramework
PrefabUndoHelpers::UpdatePrefabInstance(
instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch());
- CreateLink({}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(),
- undoBatch.GetUndoBatch(), parent);
+ CreateLink({}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), undoBatch.GetUndoBatch(), parent);
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
// Apply position
@@ -277,17 +281,17 @@ namespace AzToolsFramework
return AZ::Success();
}
- bool PrefabPublicHandler::IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance)
+ bool PrefabPublicHandler::IsCyclicalDependencyFound(
+ InstanceOptionalConstReference instance, AZStd::unordered_set& templateSourcePaths)
{
InstanceOptionalConstReference currentInstance = instance;
while (currentInstance.has_value())
{
- if (currentInstance->get().GetTemplateId() == prefabTemplateId)
+ if (templateSourcePaths.contains(currentInstance->get().GetTemplateSourcePath()))
{
return true;
}
-
currentInstance = currentInstance->get().GetParentInstance();
}
@@ -966,5 +970,5 @@ namespace AzToolsFramework
return true;
}
- }
-}
+ } // namespace Prefab
+} // namespace AzToolsFramework
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
index 03b3827328..519c7ca53f 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
@@ -12,8 +12,8 @@
#pragma once
-#include
#include
+#include
#include
#include
@@ -106,13 +106,15 @@ namespace AzToolsFramework
const AZStd::vector& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance);
- /* Detects whether an instance of prefabTemplateId is present in the hierarchy of ancestors of instance.
+ /* Checks whether the template source path of any of the ancestors in the instance hierarchy matches with one of the
+ * paths provided in a set.
*
- * \param prefabTemplateId The template id to test for
- * \param instance The instance whose ancestor hierarchy prefabTemplateId will be tested against.
- * \return true if an instance of the template of id prefabTemplateId could be found in the ancestor hierarchy of instance, false otherwise.
+ * \param instance The instance whose ancestor hierarchy the provided set of template source paths will be tested against.
+ * \param templateSourcePaths The template source paths provided to be checked against the instance ancestor hierarchy.
+ * \return true if any of the template source paths could be found in the ancestor hierarchy of instance, false otherwise.
*/
- bool IsPrefabInInstanceAncestorHierarchy(TemplateId prefabTemplateId, InstanceOptionalConstReference instance);
+ bool IsCyclicalDependencyFound(
+ InstanceOptionalConstReference instance, AZStd::unordered_set& templateSourcePaths);
static Instance* GetParentInstance(Instance* instance);
static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant);
@@ -128,5 +130,5 @@ namespace AzToolsFramework
uint64_t m_newEntityCounter = 1;
};
- }
-}
+ } // namespace Prefab
+} // namespace AzToolsFramework
From 9a4884ff0bc1577a4947d3c835ec144e195d5a53 Mon Sep 17 00:00:00 2001
From: Gene Walters
Date: Wed, 12 May 2021 14:19:18 -0700
Subject: [PATCH 053/209] Exposing Multiplayer integral types (just wrapped
ints) to bevahior context so that Network Properties using these type can be
Get/Set from Script Canvas
---
.../Code/Include/MultiplayerTypes.h | 11 ++++++++++
.../Source/AutoGen/AutoComponent_Source.jinja | 20 +++++++++++++++++++
.../Source/MultiplayerSystemComponent.cpp | 11 ++++++++++
3 files changed, 42 insertions(+)
diff --git a/Gems/Multiplayer/Code/Include/MultiplayerTypes.h b/Gems/Multiplayer/Code/Include/MultiplayerTypes.h
index 1bee9867e3..e9f3865563 100644
--- a/Gems/Multiplayer/Code/Include/MultiplayerTypes.h
+++ b/Gems/Multiplayer/Code/Include/MultiplayerTypes.h
@@ -130,3 +130,14 @@ AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::PropertyIndex);
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::RpcIndex);
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::ClientInputId);
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::HostFrameId);
+
+namespace AZ
+{
+ AZ_TYPE_INFO_SPECIALIZE(Multiplayer::HostId, "{D04B3363-8E1B-4193-8B2B-D2140389C9D5}");
+ AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetEntityId, "{05E4C08B-3A1B-4390-8144-3767D8E56A81}");
+ AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetComponentId, "{8AF3B382-F187-4323-9014-B380638767E3}");
+ AZ_TYPE_INFO_SPECIALIZE(Multiplayer::PropertyIndex, "{F4460210-024D-4B3B-A10A-04B669C34230}");
+ AZ_TYPE_INFO_SPECIALIZE(Multiplayer::RpcIndex, "{EBB1C475-FA03-4111-8C84-985377434B9B}");
+ AZ_TYPE_INFO_SPECIALIZE(Multiplayer::ClientInputId, "{35BF3504-CEC9-4406-A275-C633A17FBEFB}");
+ AZ_TYPE_INFO_SPECIALIZE(Multiplayer::HostFrameId, "{DF17F6F3-48C6-4B4A-BBD9-37DA03162864}");
+} // namespace AZ
diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
index 576978f75c..a3eef99b20 100644
--- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
+++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja
@@ -707,6 +707,26 @@ enum class NetworkProperties
controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }});
})
+ ->Method("GetOn{{ UpperFirst(Property.attrib['Name']) }}ChangedEvent", [](AZ::EntityId id) -> AZ::Event<{{ Property.attrib['Type'] }}>*
+ {
+ AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id);
+ if (!entity)
+ {
+ AZ_Warning("Network Property", false, "{{ ClassName }} GetOn{{ UpperFirst(Property.attrib['Name']) }}ChangedEvent failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
+ return nullptr;
+ }
+
+ {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>();
+ if (!networkComponent)
+ {
+ AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str())
+ return nullptr;
+ }
+
+ return &networkComponent->m_{{ LowerFirst(Property.attrib['Name']) }}Event;
+ })
+ ->Attribute(AZ::Script::Attributes::AzEventDescription, AZ::BehaviorAzEventDescription{ "On {{ UpperFirst(Property.attrib['Name']) }} Changed Event", {"New {{ UpperFirst(Property.attrib['Name']) }}"} })
+
{% endif %}
{% endcall -%}
{% endmacro %}
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
index e6fb77eca7..9f45122c1d 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
+++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
@@ -78,6 +78,17 @@ namespace Multiplayer
->Version(1);
}
+ if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context))
+ {
+ behaviorContext->Class("HostId");
+ behaviorContext->Class("NetEntityId");
+ behaviorContext->Class("NetComponentId");
+ behaviorContext->Class("PropertyIndex");
+ behaviorContext->Class ("RpcIndex");
+ behaviorContext->Class ("ClientInputId");
+ behaviorContext->Class ("HostFrameId");
+ }
+
MultiplayerComponent::Reflect(context);
}
From 84216f04793e17c923b744e2531c3e7d0feca27d Mon Sep 17 00:00:00 2001
From: nvsickle
Date: Wed, 12 May 2021 15:58:28 -0700
Subject: [PATCH 054/209] Add API for ViewportInfoDisplayState, add some minor
RHI integration
---
.../Code/CMakeLists.txt | 2 +
.../AtomViewportInfoDisplayBus.h | 61 ++++++++++
...AtomViewportDisplayInfoSystemComponent.cpp | 107 +++++++++++++-----
.../AtomViewportDisplayInfoSystemComponent.h | 14 +--
4 files changed, 150 insertions(+), 34 deletions(-)
create mode 100644 Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Include/AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt
index 395cc22d47..de4ee9b4b5 100644
--- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt
@@ -17,6 +17,8 @@ ly_add_target(
INCLUDE_DIRECTORIES
PRIVATE
Source
+ PUBLIC
+ Include
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Include/AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Include/AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h
new file mode 100644
index 0000000000..ae9359d9d3
--- /dev/null
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Include/AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h
@@ -0,0 +1,61 @@
+/*
+* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+* its licensors.
+*
+* For complete copyright and license terms please see the LICENSE at the root of this
+* distribution (the "License"). All use of this software is governed by the License,
+* or, if provided, by the license below or the license accompanying this file. Do not
+* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*
+*/
+#pragma once
+#include
+#include
+
+namespace AZ
+{
+ namespace AtomBridge
+ {
+ //! The level of information to display in the viewport info display overlay.
+ enum class ViewportInfoDisplayState : int
+ {
+ NoInfo = 0,
+ NormalInfo = 1,
+ FullInfo = 2,
+ CompactInfo = 3,
+ Invalid
+ };
+
+ //! This bus is used to request changes to the viewport info display overlay.
+ class AtomViewportInfoDisplayRequests
+ : public AZ::EBusTraits
+ {
+ public:
+ static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single;
+ static const AZ::EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single;
+
+ //! Gets the current viewport info overlay state.
+ virtual ViewportInfoDisplayState GetDisplayState() const = 0;
+ //! Sets the current viewport info overlay state.
+ //! The overlay will be drawn to the default viewport context every frame, if enabled.
+ virtual void SetDisplayState(ViewportInfoDisplayState state) = 0;
+ };
+
+ using AtomViewportInfoDisplayRequestBus = AZ::EBus;
+
+ //! This bus is used to listen for state changes in the viewport info display overlay.
+ class AtomViewportInfoDisplayNotifications
+ : public AZ::EBusTraits
+ {
+ public:
+ static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Multiple;
+ static const AZ::EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single;
+
+ //! Called when the ViewportInfoDisplayState (via the r_displayInfo CVar) has changed.
+ virtual void OnViewportInfoDisplayStateChanged([[maybe_unused]]ViewportInfoDisplayState state){}
+ };
+
+ using AtomViewportInfoDisplayNotificationBus = AZ::EBus;
+ }
+}
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
index 394923071e..c9128c001f 100644
--- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/Source/AtomViewportDisplayInfoSystemComponent.cpp
@@ -21,21 +21,30 @@
#include
#include
#include
+#include
#include
#include
#include
#include
-AZ_CVAR(float, r_fpsInterval, 1.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate,
- "The time period over which to calculate the framerate for r_displayInfo");
-
namespace AZ::Render
{
- static constexpr int DisplayInfoLevelNone = 0;
- static constexpr int DisplayInfoLevelNormal = 1;
- static constexpr int DisplayInfoLevelFull = 2;
- static constexpr int DisplayInfoLevelCompact = 3;
+ AZ_CVAR(int, r_displayInfo, 1, [](const int& newDisplayInfoVal)->void
+ {
+ // Forward this event to the system component so it can update accordingly.
+ // This callback only gets triggered by console commands, so this will not recurse.
+ AtomBridge::AtomViewportInfoDisplayRequestBus::Broadcast(
+ &AtomBridge::AtomViewportInfoDisplayRequestBus::Events::SetDisplayState,
+ static_cast(newDisplayInfoVal)
+ );
+ }, AZ::ConsoleFunctorFlags::DontReplicate,
+ "Toggles debugging information display.\n"
+ "Usage: r_displayInfo [0=off/1=show/2=enhanced/3=compact]"
+ );
+ AZ_CVAR(float, r_fpsCalcInterval, 1.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate,
+ "The time period over which to calculate the framerate for r_displayInfo."
+ );
void AtomViewportDisplayInfoSystemComponent::Reflect(AZ::ReflectContext* context)
{
@@ -47,7 +56,7 @@ namespace AZ::Render
if (AZ::EditContext* ec = serialize->GetEditContext())
{
- ec->Class("Viewport Display Info", "Manages debug viewport information through r_DisplayInfo")
+ ec->Class("Viewport Display Info", "Manages debug viewport information through r_displayInfo")
->ClassElement(Edit::ClassElements::EditorData, "")
->Attribute(Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
->Attribute(Edit::Attributes::AutoExpand, true)
@@ -83,15 +92,15 @@ namespace AZ::Render
m_rendererDescription = AZStd::string::format("Atom using %s RHI", apiName.GetCStr());
}
- CrySystemEventBus::Handler::BusConnect();
AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect(
AZ::RPI::ViewportContextRequests::Get()->GetDefaultViewportContextName());
+ AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler::BusConnect();
}
void AtomViewportDisplayInfoSystemComponent::Deactivate()
{
+ AZ::AtomBridge::AtomViewportInfoDisplayRequestBus::Handler::BusDisconnect();
AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect();
- CrySystemEventBus::Handler::BusDisconnect();
}
AZ::RPI::ViewportContextPtr AtomViewportDisplayInfoSystemComponent::GetViewportContext() const
@@ -111,8 +120,13 @@ namespace AZ::Render
void AtomViewportDisplayInfoSystemComponent::OnRenderTick()
{
+ auto fontQueryInterface = AZ::Interface::Get();
+ if (!fontQueryInterface)
+ {
+ return;
+ }
AzFramework::FontDrawInterface* fontDrawInterface =
- AZ::Interface::Get()->GetDefaultFontDrawInterface();
+ fontQueryInterface->GetDefaultFontDrawInterface();
AZ::RPI::ViewportContextPtr viewportContext = GetViewportContext();
if (!fontDrawInterface || !viewportContext || !viewportContext->GetRenderScene())
@@ -120,18 +134,23 @@ namespace AZ::Render
return;
}
- m_fpsInterval = AZStd::chrono::seconds(r_fpsInterval);
+ m_fpsInterval = AZStd::chrono::seconds(r_fpsCalcInterval);
UpdateFramerate();
- if (!m_displayInfoCVar)
+ const AtomBridge::ViewportInfoDisplayState displayLevel = GetDisplayState();
+ if (displayLevel == AtomBridge::ViewportInfoDisplayState::NoInfo)
{
return;
}
- int displayLevel = m_displayInfoCVar->GetIVal();
- if (displayLevel == DisplayInfoLevelNone)
+
+ if (m_updateRootPassQuery)
{
- return;
+ if (auto rootPass = AZ::RPI::PassSystemInterface::Get()->GetRootPass())
+ {
+ rootPass->SetPipelineStatisticsQueryEnabled(displayLevel == AtomBridge::ViewportInfoDisplayState::FullInfo);
+ m_updateRootPassQuery = false;
+ }
}
m_drawParams.m_drawViewportId = viewportContext->GetId();
@@ -152,22 +171,30 @@ namespace AZ::Render
m_lineSpacing = lineHeight * m_drawParams.m_lineSpacing;
DrawRendererInfo();
- if (displayLevel != DisplayInfoLevelCompact)
+ if (displayLevel == AtomBridge::ViewportInfoDisplayState::FullInfo)
{
DrawCameraInfo();
+ DrawPassInfo();
+ }
+ if (displayLevel != AtomBridge::ViewportInfoDisplayState::CompactInfo)
+ {
DrawMemoryInfo();
}
DrawFramerate();
}
- void AtomViewportDisplayInfoSystemComponent::OnCrySystemInitialized(ISystem& system, [[maybe_unused]]const SSystemInitParams& initParams)
+ AtomBridge::ViewportInfoDisplayState AtomViewportDisplayInfoSystemComponent::GetDisplayState() const
{
- m_displayInfoCVar = system.GetGlobalEnvironment()->pConsole->GetCVar("r_DisplayInfo");
+ return static_cast(r_displayInfo.operator int());
}
- void AtomViewportDisplayInfoSystemComponent::OnCrySystemShutdown([[maybe_unused]]ISystem& system)
+ void AtomViewportDisplayInfoSystemComponent::SetDisplayState(AtomBridge::ViewportInfoDisplayState state)
{
- m_displayInfoCVar = nullptr;
+ r_displayInfo = static_cast(state);
+ AtomBridge::AtomViewportInfoDisplayNotificationBus::Broadcast(
+ &AtomBridge::AtomViewportInfoDisplayNotificationBus::Events::OnViewportInfoDisplayStateChanged,
+ state);
+ m_updateRootPassQuery = true;
}
void AtomViewportDisplayInfoSystemComponent::DrawRendererInfo()
@@ -198,6 +225,31 @@ namespace AZ::Render
));
}
+ void AtomViewportDisplayInfoSystemComponent::DrawPassInfo()
+ {
+ auto rootPass = AZ::RPI::PassSystemInterface::Get()->GetRootPass();
+ const RPI::PipelineStatisticsResult stats = rootPass->GetLatestPipelineStatisticsResult();
+ AZStd::function)> containingPassCount = [&containingPassCount](const AZ::RPI::Ptr