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 01/66] [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 02/66] 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 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 03/66] 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 04/66] 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 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 05/66] 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 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 06/66] 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 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 07/66] 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 36a79aca8a353316f560f3079ff2b66cb5120996 Mon Sep 17 00:00:00 2001
From: sphrose <82213493+sphrose@users.noreply.github.com>
Date: Thu, 13 May 2021 10:56:39 +0100
Subject: [PATCH 08/66] Remove redundant function.
---
.../UI/PropertyEditor/PropertyRowWidget.cpp | 7 +------
.../UI/PropertyEditor/PropertyRowWidget.hxx | 1 -
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.cpp
index 85784d61e0..890253b528 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 (IsReorderableRow())
+ if (CanBeReordered())
{
const QPen linePen(QColor(0x3B3E3F));
p.setPen(linePen);
@@ -1332,11 +1332,6 @@ namespace AzToolsFramework
return canBeTopLevel(this);
}
- bool PropertyRowWidget::IsReorderableRow() const
- {
- return CanBeReordered();
- }
-
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 1c17cab69f..79121403c9 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyRowWidget.hxx
@@ -83,7 +83,6 @@ namespace AzToolsFramework
PropertyRowWidget* GetParentRow() const { return m_parentRow; }
int GetLevel() const;
bool IsTopLevel() const;
- bool IsReorderableRow() const;
// Remove the default label and append the text to the name label.
bool GetAppendDefaultLabelToName();
From f478340376267f1623f7138fe2b06024d050687c Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Wed, 12 May 2021 16:04:25 -0500
Subject: [PATCH 09/66] Data driven asset importer. Need to fix reflection
---
AssetImporterSettings.json | 7 +++
.../FbxImportRequestHandler.cpp | 60 +++++++++++++++++--
.../FbxSceneBuilder/FbxImportRequestHandler.h | 16 ++++-
3 files changed, 78 insertions(+), 5 deletions(-)
create mode 100644 AssetImporterSettings.json
diff --git a/AssetImporterSettings.json b/AssetImporterSettings.json
new file mode 100644
index 0000000000..134484cf8d
--- /dev/null
+++ b/AssetImporterSettings.json
@@ -0,0 +1,7 @@
+{
+ "SupportedFileTypeExtensions" : [
+ ".fbx",
+ ".stl",
+ ".stp"
+ ]
+}
\ No newline at end of file
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
index 155209f1b5..2210abfaf7 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
@@ -10,7 +10,14 @@
*
*/
+#include
+#include
+#include
+#include
#include
+#include
+#include
+#include
#include
#include
#include
@@ -23,10 +30,47 @@ namespace AZ
{
namespace FbxSceneImporter
{
- const char* FbxImportRequestHandler::s_extension = ".fbx";
+ AssetImporterSettings::AssetImporterSettings()
+ {
+ // Default supported extension in case the settings file isn't found
+ m_supportedFileTypeExtensions.emplace(".fbx");
+ }
+
+ void AssetImporterSettings::Reflect(AZ::ReflectContext* context)
+ {
+ if (auto serializeContext = azrtti_cast(context); serializeContext)
+ {
+ serializeContext->Class()
+ ->Version(1)
+ ->Field("SupportedFileTypeExtensions", &AssetImporterSettings::m_supportedFileTypeExtensions);
+ }
+ }
void FbxImportRequestHandler::Activate()
{
+ // Attempt to load the Slice Builder Settings file
+ AZ::IO::LocalFileIO localFileIO;
+
+ // This will point to @assets@/SettingsFilename, which loads from the cache
+ // We don't really want this but it works for now
+ // Trying to use AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath at this point
+ // would fail because components seem to activate before the AP has populated its file list
+ AZ::IO::Path sliceBuilderSettingsIoPath(SettingsFilename);
+ auto result = AzFramework::FileFunc::ReadJsonFile(sliceBuilderSettingsIoPath, &localFileIO);
+ if (result.IsSuccess())
+ {
+ AZ::JsonSerializationResult::ResultCode serializationResult =
+ AZ::JsonSerialization::Load(m_settings, result.GetValue());
+ if (serializationResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
+ {
+ AZ_Warning("", false, "Error in Asset Importer Settings file.\nUsing default settings.");
+ }
+ }
+ else
+ {
+ AZ_Warning("", false, "Failed to load Asset Importer Settings file.\nUsing default settings.");
+ }
+
BusConnect();
}
@@ -37,21 +81,29 @@ namespace AZ
void FbxImportRequestHandler::Reflect(ReflectContext* context)
{
+ AssetImporterSettings::Reflect(context);
+
SerializeContext* serializeContext = azrtti_cast(context);
if (serializeContext)
{
- serializeContext->Class()->Version(1);
+ serializeContext->Class()->Version(1)->Attribute(
+ AZ::Edit::Attributes::SystemComponentTags,
+ AZStd::vector({AssetBuilderSDK::ComponentTags::AssetBuilder}));
+
}
}
void FbxImportRequestHandler::GetSupportedFileExtensions(AZStd::unordered_set& extensions)
{
- extensions.insert(s_extension);
+ extensions.insert(m_settings.m_supportedFileTypeExtensions.begin(), m_settings.m_supportedFileTypeExtensions.end());
}
Events::LoadingResult FbxImportRequestHandler::LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, [[maybe_unused]] RequestingApplication requester)
{
- if (!AzFramework::StringFunc::Path::IsExtension(path.c_str(), s_extension))
+ AZStd::string extension;
+ AzFramework::StringFunc::Path::GetExtension(path.c_str(), extension);
+
+ if (!m_settings.m_supportedFileTypeExtensions.contains(extension))
{
return Events::LoadingResult::Ignored;
}
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
index 8b33051f1e..3ef2823e24 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
@@ -21,6 +21,17 @@ namespace AZ
{
namespace FbxSceneImporter
{
+ struct AssetImporterSettings
+ {
+ AZ_TYPE_INFO(AssetImporterSettings, "{8BB6C7AD-BF99-44DC-9DA1-E7AD3F03DC10}");
+
+ AssetImporterSettings();
+
+ static void Reflect(AZ::ReflectContext* context);
+
+ AZStd::unordered_set m_supportedFileTypeExtensions;
+ };
+
class FbxImportRequestHandler
: public SceneCore::BehaviorComponent
, public Events::AssetImportRequestBus::Handler
@@ -39,7 +50,10 @@ namespace AZ
RequestingApplication requester) override;
private:
- static const char* s_extension;
+
+ AssetImporterSettings m_settings;
+
+ static constexpr const char* SettingsFilename = "AssetImporterSettings.json";
};
} // namespace FbxSceneImporter
} // namespace SceneAPI
From 2b538c9921ce2be2ee4fc9c9877c1dd0272c8f58 Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Thu, 13 May 2021 09:47:21 -0500
Subject: [PATCH 10/66] Switch to using settings registry
# Conflicts:
# Assets/Engine/Registry/assetimporter.setreg
---
AssetImporterSettings.json | 7 ----
.../SceneAPI/FbxSceneBuilder/DllMain.cpp | 6 +---
.../FbxImportRequestHandler.cpp | 35 +++++--------------
.../FbxSceneBuilder/FbxImportRequestHandler.h | 6 ++--
.../SceneBuilder/SceneBuilderComponent.cpp | 6 +++-
.../SceneBuilder/SceneBuilderComponent.h | 2 ++
Registry/assetimporter.setreg | 17 +++++++++
7 files changed, 37 insertions(+), 42 deletions(-)
delete mode 100644 AssetImporterSettings.json
create mode 100644 Registry/assetimporter.setreg
diff --git a/AssetImporterSettings.json b/AssetImporterSettings.json
deleted file mode 100644
index 134484cf8d..0000000000
--- a/AssetImporterSettings.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "SupportedFileTypeExtensions" : [
- ".fbx",
- ".stl",
- ".stp"
- ]
-}
\ No newline at end of file
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
index 3dc14814de..d3d7b38663 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
@@ -46,11 +46,6 @@ namespace AZ
// Currently it's still needed to explicitly create an instance of this instead of letting
// it be a normal component. This is because ResourceCompilerScene needs to return
// the list of available extensions before it can start the application.
- if (!g_fbxImporter)
- {
- g_fbxImporter = aznew AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler();
- g_fbxImporter->Activate();
- }
}
void Reflect(AZ::SerializeContext* /*context*/)
@@ -64,6 +59,7 @@ namespace AZ
{
// Global importer and behavior
g_componentDescriptors.push_back(FbxSceneBuilder::FbxImporter::CreateDescriptor());
+ g_componentDescriptors.push_back(FbxSceneImporter::FbxImportRequestHandler::CreateDescriptor());
// Node and attribute importers
g_componentDescriptors.push_back(AssImpBitangentStreamImporter::CreateDescriptor());
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
index 2210abfaf7..d3962cce60 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
@@ -30,12 +30,6 @@ namespace AZ
{
namespace FbxSceneImporter
{
- AssetImporterSettings::AssetImporterSettings()
- {
- // Default supported extension in case the settings file isn't found
- m_supportedFileTypeExtensions.emplace(".fbx");
- }
-
void AssetImporterSettings::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast(context); serializeContext)
@@ -48,27 +42,11 @@ namespace AZ
void FbxImportRequestHandler::Activate()
{
- // Attempt to load the Slice Builder Settings file
- AZ::IO::LocalFileIO localFileIO;
-
- // This will point to @assets@/SettingsFilename, which loads from the cache
- // We don't really want this but it works for now
- // Trying to use AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath at this point
- // would fail because components seem to activate before the AP has populated its file list
- AZ::IO::Path sliceBuilderSettingsIoPath(SettingsFilename);
- auto result = AzFramework::FileFunc::ReadJsonFile(sliceBuilderSettingsIoPath, &localFileIO);
- if (result.IsSuccess())
+ auto settingsRegistry = AZ::SettingsRegistry::Get();
+
+ if (settingsRegistry)
{
- AZ::JsonSerializationResult::ResultCode serializationResult =
- AZ::JsonSerialization::Load(m_settings, result.GetValue());
- if (serializationResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
- {
- AZ_Warning("", false, "Error in Asset Importer Settings file.\nUsing default settings.");
- }
- }
- else
- {
- AZ_Warning("", false, "Failed to load Asset Importer Settings file.\nUsing default settings.");
+ settingsRegistry->GetObject(m_settings, "/O3DE/SceneAPI/AssetImporter");
}
BusConnect();
@@ -125,6 +103,11 @@ namespace AZ
return Events::LoadingResult::AssetFailure;
}
}
+
+ void FbxImportRequestHandler::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided)
+ {
+ provided.emplace_back(AZ_CRC_CE("AssetImportRequestHandler"));
+ }
} // namespace Import
} // namespace SceneAPI
} // namespace AZ
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
index 3ef2823e24..99d2061229 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
@@ -24,9 +24,7 @@ namespace AZ
struct AssetImporterSettings
{
AZ_TYPE_INFO(AssetImporterSettings, "{8BB6C7AD-BF99-44DC-9DA1-E7AD3F03DC10}");
-
- AssetImporterSettings();
-
+
static void Reflect(AZ::ReflectContext* context);
AZStd::unordered_set m_supportedFileTypeExtensions;
@@ -49,6 +47,8 @@ namespace AZ
Events::LoadingResult LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid,
RequestingApplication requester) override;
+ static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided);
+
private:
AssetImporterSettings m_settings;
diff --git a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp
index e71a5207d0..25faca3667 100644
--- a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp
+++ b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.cpp
@@ -72,6 +72,11 @@ namespace SceneBuilder
m_sceneBuilder.BusDisconnect();
}
+ void BuilderPluginComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
+ {
+ required.emplace_back(AZ_CRC_CE("AssetImportRequestHandler"));
+ }
+
void BuilderPluginComponent::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast(context);
@@ -81,5 +86,4 @@ namespace SceneBuilder
->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder }));
}
}
-
} // namespace SceneBuilder
diff --git a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h
index c1fc6ebb36..aed5e1b026 100644
--- a/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h
+++ b/Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderComponent.h
@@ -32,6 +32,8 @@ namespace SceneBuilder
void Activate() override;
void Deactivate() override;
+ static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+
private:
SceneBuilderWorker m_sceneBuilder;
};
diff --git a/Registry/assetimporter.setreg b/Registry/assetimporter.setreg
new file mode 100644
index 0000000000..e0b0f00f6c
--- /dev/null
+++ b/Registry/assetimporter.setreg
@@ -0,0 +1,17 @@
+{
+ "O3DE":
+ {
+ "SceneAPI":
+ {
+ "AssetImporter":
+ {
+ "SupportedFileTypeExtensions":
+ [
+ ".fbx",
+ ".stl",
+ ".stp"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
From 81067e38c9e6b6f489457baa0b5108f02ae7b397 Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Thu, 13 May 2021 17:39:27 -0500
Subject: [PATCH 11/66] Remove stp
---
Registry/assetimporter.setreg | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Registry/assetimporter.setreg b/Registry/assetimporter.setreg
index e0b0f00f6c..bd7c4d0705 100644
--- a/Registry/assetimporter.setreg
+++ b/Registry/assetimporter.setreg
@@ -8,8 +8,7 @@
"SupportedFileTypeExtensions":
[
".fbx",
- ".stl",
- ".stp"
+ ".stl"
]
}
}
From b7891f4fb6e3fa5a596d5acd436fc9de12446588 Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Thu, 13 May 2021 18:43:51 -0500
Subject: [PATCH 12/66] Code cleanup
---
Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp | 7 -------
.../FbxSceneBuilder/FbxImportRequestHandler.cpp | 11 ++++-------
2 files changed, 4 insertions(+), 14 deletions(-)
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
index d3d7b38663..5ffe916d23 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
@@ -41,13 +41,6 @@ namespace AZ
static AZ::SceneAPI::FbxSceneImporter::FbxImportRequestHandler* g_fbxImporter = nullptr;
static AZStd::vector g_componentDescriptors;
- void Initialize()
- {
- // Currently it's still needed to explicitly create an instance of this instead of letting
- // it be a normal component. This is because ResourceCompilerScene needs to return
- // the list of available extensions before it can start the application.
- }
-
void Reflect(AZ::SerializeContext* /*context*/)
{
// Descriptor registration is done in Reflect instead of Initialize because the ResourceCompilerScene initializes the libraries before
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
index d3962cce60..65bb8de4c7 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
@@ -10,19 +10,16 @@
*
*/
-#include
#include
-#include
#include
#include
#include
-#include
-#include
-#include
+#include
+#include
+#include
#include
#include
#include
-#include
namespace AZ
{
@@ -79,7 +76,7 @@ namespace AZ
Events::LoadingResult FbxImportRequestHandler::LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, [[maybe_unused]] RequestingApplication requester)
{
AZStd::string extension;
- AzFramework::StringFunc::Path::GetExtension(path.c_str(), extension);
+ StringFunc::Path::GetExtension(path.c_str(), extension);
if (!m_settings.m_supportedFileTypeExtensions.contains(extension))
{
From ba4439c397ef8b2b3203b482f5a0fd56ebf88713 Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Thu, 13 May 2021 19:52:00 -0500
Subject: [PATCH 13/66] Remove call to deleted init function
---
Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
index 5ffe916d23..d2818f3653 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/DllMain.cpp
@@ -114,7 +114,6 @@ namespace AZ
extern "C" AZ_DLL_EXPORT void InitializeDynamicModule(void* env)
{
AZ::Environment::Attach(static_cast(env));
- AZ::SceneAPI::FbxSceneBuilder::Initialize();
}
extern "C" AZ_DLL_EXPORT void Reflect(AZ::SerializeContext* context)
{
From 70c968f82917b83528deed7cec2b316be2e5fc03 Mon Sep 17 00:00:00 2001
From: daimini
Date: Fri, 14 May 2021 15:02:39 -0700
Subject: [PATCH 14/66] Fixes issue with relative positioning of children on
Prefab creation. Makes CreateLink more generic to facilitate reuse.
---
.../Prefab/PrefabPublicHandler.cpp | 83 ++++++++++---------
.../Prefab/PrefabPublicHandler.h | 7 +-
2 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
index 5ecff637a1..4eb6580158 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
@@ -121,6 +121,41 @@ namespace AzToolsFramework
}
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
+ AZ::Entity* containerEntity = GetEntityById(containerEntityId);
+
+ {
+ // Generate the transform for the container entity out of the top level entities, and set it
+ // This step needs to be done before anything is parented to the container, else children position will be wrong
+ Prefab::PrefabDom containerEntityDomBefore;
+ m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *containerEntity);
+
+ AZ::Vector3 containerEntityTranslation(AZ::Vector3::CreateZero());
+ AZ::Quaternion containerEntityRotation(AZ::Quaternion::CreateZero());
+
+ // Set container entity to be child of common root
+ AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
+
+ // Set the transform (translation, rotation) of the container entity
+ GenerateContainerEntityTransform(topLevelEntities, containerEntityTranslation, containerEntityRotation);
+ AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalTranslation, containerEntityTranslation);
+ AZ::TransformBus::Event(
+ containerEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, containerEntityRotation);
+
+ PrefabDom containerEntityDomAfter;
+ m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *containerEntity);
+
+ PrefabDom patch;
+ m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
+ m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
+
+ // Update the cache - this prevents these changes from being stored in the regular undo/redo nodes
+ m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
+
+ // Create a link between the templates of the newly created instance and the instance it's being parented under.
+ CreateLink(
+ instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(),
+ undoBatch.GetUndoBatch(), patch);
+ }
// Parent the entities to the container entity. Parenting the container entities of the instances passed to createPrefab
// will be done during the creation of links below.
@@ -144,16 +179,10 @@ namespace AzToolsFramework
// These link creations shouldn't be undone because that would put the template in a non-usable state if a user
// chooses to instantiate the template after undoing the creation.
- CreateLink(
- {&nestedInstanceContainerEntity->get()}, *nestedInstance, instanceToCreate->get().GetTemplateId(),
- undoBatch.GetUndoBatch(), containerEntityId, false);
+ PrefabDom emptyPatch;
+ CreateLink(*nestedInstance, instanceToCreate->get().GetTemplateId(), undoBatch.GetUndoBatch(), emptyPatch, false);
});
- // Create a link between the templates of the newly created instance and the instance it's being parented under.
- CreateLink(
- topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(),
- undoBatch.GetUndoBatch(), commonRootEntityId);
-
for (AZ::Entity* topLevelEntity : topLevelEntities)
{
AZ::EntityId topLevelEntityId = topLevelEntity->GetId();
@@ -227,8 +256,7 @@ namespace AzToolsFramework
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);
@@ -242,8 +270,8 @@ namespace AzToolsFramework
PrefabUndoHelpers::UpdatePrefabInstance(
instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch());
- CreateLink({}, instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(),
- undoBatch.GetUndoBatch(), parent);
+ PrefabDom emptyPatch;
+ CreateLink(instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), undoBatch.GetUndoBatch(), emptyPatch);
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
// Apply position
@@ -314,33 +342,9 @@ namespace AzToolsFramework
}
void PrefabPublicHandler::CreateLink(
- const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
- UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool isUndoRedoSupportNeeded)
+ Instance& sourceInstance, TemplateId targetTemplateId,
+ UndoSystem::URSequencePoint* undoBatch, PrefabDom& patch, const bool isUndoRedoSupportNeeded)
{
- AZ::EntityId containerEntityId = sourceInstance.GetContainerEntityId();
- AZ::Entity* containerEntity = GetEntityById(containerEntityId);
- Prefab::PrefabDom containerEntityDomBefore;
- m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *containerEntity);
-
- AZ::Vector3 containerEntityTranslation(AZ::Vector3::CreateZero());
- AZ::Quaternion containerEntityRotation(AZ::Quaternion::CreateZero());
-
- // Set the transform (translation, rotation) of the container entity
- GenerateContainerEntityTransform(topLevelEntities, containerEntityTranslation, containerEntityRotation);
-
- // Set container entity to be child of common root
- AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
-
- AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalTranslation, containerEntityTranslation);
- AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, containerEntityRotation);
-
- PrefabDom containerEntityDomAfter;
- m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *containerEntity);
-
- PrefabDom patch;
- m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
- m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
-
LinkId linkId;
if (isUndoRedoSupportNeeded)
{
@@ -356,9 +360,6 @@ namespace AzToolsFramework
}
sourceInstance.SetLinkId(linkId);
-
- // Update the cache - this prevents these changes from being stored in the regular undo/redo nodes
- m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
}
void PrefabPublicHandler::RemoveLink(
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
index 138bc84aa0..95f9cb8174 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
@@ -72,16 +72,15 @@ namespace AzToolsFramework
/**
* Creates a link between the templates of an instance and its parent.
*
- * \param topLevelEntities The list of entities that are immediate children to the container entity of the instance.
* \param sourceInstance The instance that corresponds to the source template of the link.
* \param targetInstance The id of the target template.
* \param undoBatch The undo batch to set as parent for this create link action.
- * \param commonRootEntityId The id of the entity that the source instance should be parented under.
+ * \param patch The patch to store in the newly created link dom.
* \param isUndoRedoSupportNeeded The flag indicating whether the link should be created with undo/redo support or not.
*/
void CreateLink(
- const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
- UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool isUndoRedoSupportNeeded = true);
+ Instance& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch,
+ PrefabDom& patch, const bool isUndoRedoSupportNeeded = true);
/**
* Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId.
From 12760ef6a302309ce8e658e724bb51a697f0a041 Mon Sep 17 00:00:00 2001
From: daimini
Date: Fri, 14 May 2021 16:37:47 -0700
Subject: [PATCH 15/66] Remove unused container entity retrieval
---
.../AzToolsFramework/Prefab/PrefabPublicHandler.cpp | 5 -----
1 file changed, 5 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
index 4eb6580158..5323fd3d7f 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
@@ -172,11 +172,6 @@ namespace AzToolsFramework
}
instanceToCreate->get().GetNestedInstances([&](AZStd::unique_ptr& nestedInstance) {
- AZ_Assert(nestedInstance, "Invalid nested instance found in the new prefab created.");
- EntityOptionalReference nestedInstanceContainerEntity = nestedInstance->GetContainerEntity();
- AZ_Assert(
- nestedInstanceContainerEntity, "Invalid container entity found for the nested instance used in prefab creation.");
-
// These link creations shouldn't be undone because that would put the template in a non-usable state if a user
// chooses to instantiate the template after undoing the creation.
PrefabDom emptyPatch;
From d12cf2b6e136ce7f21801df3f4165477a393fa2d Mon Sep 17 00:00:00 2001
From: balibhan
Date: Mon, 17 May 2021 10:21:56 +0530
Subject: [PATCH 16/66] Pane properties test script
---
...Pane_PropertiesChanged_RetainsOnRestart.py | 161 ++++++++++++++++++
.../PythonTests/scripting/TestSuite_Active.py | 41 ++++-
2 files changed, 195 insertions(+), 7 deletions(-)
create mode 100644 AutomatedTesting/Gem/PythonTests/scripting/Pane_PropertiesChanged_RetainsOnRestart.py
diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_PropertiesChanged_RetainsOnRestart.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_PropertiesChanged_RetainsOnRestart.py
new file mode 100644
index 0000000000..3750fd290b
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_PropertiesChanged_RetainsOnRestart.py
@@ -0,0 +1,161 @@
+"""
+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.
+"""
+
+
+class Tests:
+ test_panes_visible = "All the test panes are opened"
+ close_pane_1 = "Test pane 1 is closed"
+ resize_pane_3 = "Test pane 3 resized successfully"
+ location_changed = "Location of test pane 2 changed successfully"
+ visiblity_retained = "Test pane retained its visiblity on Editor restart"
+ location_retained = "Test pane retained its location on Editor restart"
+ size_retained = "Test pane retained its size on Editor restart"
+
+
+def Pane_PropertiesChanged_RetainsOnRestart():
+ """
+ Summary:
+ The Script Canvas window is opened to verify if Script canvas panes can retain its visibility, size and location
+ upon Editor restart.
+
+ Expected Behavior:
+ The ScriptCanvas pane retain it's visiblity, size and location upon Editor restart.
+
+ Test Steps:
+ 1) Open Script Canvas window (Tools > Script Canvas)
+ 2) Make sure test panes are open and visible
+ 3) Close test pane 1
+ 4) Change dock location of test pane 2
+ 5) Resize test pane 3
+ 6) Restart Editor
+ 7) Verify if test pane 1 retain its visiblity
+ 8) Verify if location of test pane 2 is retained
+ 9) Verify if size of test pane 3 is retained
+ 10) Restore default layout and close SC window
+
+ Note:
+ - This test file must be called from the Open 3D Engine 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 sys
+
+ # Helper imports
+ from utils import Report
+ from utils import TestHelper as helper
+ import pyside_utils
+
+ # Lumberyard Imports
+ import azlmbr.legacy.general as general
+
+ # Pyside imports
+ from PySide2 import QtCore, QtWidgets
+ from PySide2.QtCore import Qt
+
+ # Constants
+ TEST_CONDITION = sys.argv[1]
+ TEST_PANE_1 = "NodePalette" # pane used to test visibility
+ TEST_PANE_2 = "VariableManager" # pane used to test location
+ TEST_PANE_3 = "NodeInspector" # pane used to test size
+ SCALE_INT = 10 # Random resize scale integer
+ DOCKAREA = Qt.TopDockWidgetArea # Preferred top area since no widget is docked on top
+
+ def click_menu_option(window, option_text):
+ action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction})
+ action.trigger()
+
+ def find_pane(window, pane_name):
+ return window.findChild(QtWidgets.QDockWidget, pane_name)
+
+ # Test starts here
+ general.idle_enable(True)
+
+ # 1) Open Script Canvas window (Tools > Script Canvas)
+ general.open_pane("Script Canvas")
+ helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0)
+
+ if TEST_CONDITION == "before_restart":
+ # 2) Make sure test panes are open and visible
+ editor_window = pyside_utils.get_editor_main_window()
+ sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
+ click_menu_option(sc, "Restore Default Layout")
+ test_pane_1 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_1)
+ test_pane_2 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_2)
+ test_pane_3 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_3)
+
+ result = test_pane_1.isVisible() and test_pane_2.isVisible() and test_pane_3.isVisible()
+ Report.info(f"{Tests.test_panes_visible}: {result}")
+
+ # 3) Close test pane
+ test_pane_1.close()
+ Report.info(f"{Tests.close_pane_1}: {not test_pane_1.isVisible()}")
+
+ # 4) Change dock location of test pane 2
+ sc_main = sc.findChild(QtWidgets.QMainWindow)
+ sc_main.addDockWidget(DOCKAREA, find_pane(sc_main, TEST_PANE_2), QtCore.Qt.Vertical)
+ Report.info(f"{Tests.location_changed}: {sc_main.dockWidgetArea(find_pane(sc_main, TEST_PANE_2)) == DOCKAREA}")
+
+ # 5) Resize test pane 3
+ initial_size = test_pane_3.frameSize()
+ test_pane_3.resize(initial_size.width() + SCALE_INT, initial_size.height() + SCALE_INT)
+ new_size = test_pane_3.frameSize()
+ resize_success = (
+ abs(initial_size.width() - new_size.width()) == abs(initial_size.height() - new_size.height()) == SCALE_INT
+ )
+ Report.info(f"{Tests.resize_pane_3}: {resize_success}")
+
+ if TEST_CONDITION == "after_restart":
+ try:
+ # 6) Restart Editor
+ # Restart is not possible through script and hence it is done by running the same file as 2 tests with a
+ # condition as before_test and after_test
+
+ # 7) Verify if test pane 1 retain its visiblity
+ # This pane closed before restart and expected that pane should not be visible.
+ editor_window = pyside_utils.get_editor_main_window()
+ sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
+ Report.info(f"{Tests.visiblity_retained}: {not find_pane(sc, TEST_PANE_1).isVisible()}")
+
+ # 8) Verify if location of test pane 2 is retained
+ # This pane was set at DOCKAREA lcoation before restart
+ sc_main = sc.findChild(QtWidgets.QMainWindow)
+ Report.info(
+ f"{Tests.location_retained}: {sc_main.dockWidgetArea(find_pane(sc_main, TEST_PANE_2)) == DOCKAREA}"
+ )
+
+ # 9) Verify if size of test pane 3 is retained
+ # Verifying if size retained by checking current size not matching with default size
+ test_pane_3 = find_pane(sc, TEST_PANE_3)
+ retained_size = test_pane_3.frameSize()
+ click_menu_option(sc, "Restore Default Layout")
+ actual_size = test_pane_3.frameSize()
+ Report.info(f"{Tests.size_retained}: {retained_size != actual_size}")
+
+ finally:
+ # 10) Restore default layout and close SC window
+ general.open_pane("Script Canvas")
+ helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0)
+ sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
+ click_menu_option(sc, "Restore Default Layout")
+ sc.close()
+
+
+if __name__ == "__main__":
+ import ImportPathHelper as imports
+
+ imports.init()
+
+ from utils import Report
+
+ Report.start_test(Pane_PropertiesChanged_RetainsOnRestart)
diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py
index c42c9f1a03..9180c1b44c 100755
--- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py
+++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py
@@ -76,14 +76,8 @@ class TestAutomation(TestAutomationBase):
from . import ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage as test_module
self._run_test(request, workspace, editor, test_module)
-<<<<<<< HEAD
def test_NodePalette_HappyPath_ClearSelection(self, request, workspace, editor, launcher_platform, project):
from . import NodePalette_HappyPath_ClearSelection as test_module
-=======
- @pytest.mark.test_case_id("T92562993")
- def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project):
- from . import NodePalette_ClearSelection as test_module
->>>>>>> main
self._run_test(request, workspace, editor, test_module)
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -119,7 +113,6 @@ class TestAutomation(TestAutomationBase):
from . import Debugger_HappyPath_TargetMultipleGraphs as test_module
self._run_test(request, workspace, editor, test_module)
- @pytest.mark.test_case_id("T92569137")
def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project):
from . import Debugging_TargetMultipleGraphs as test_module
self._run_test(request, workspace, editor, test_module)
@@ -262,3 +255,37 @@ class TestScriptCanvasTests(object):
auto_test_mode=False,
timeout=60,
)
+
+ @pytest.mark.parametrize(
+ "config",
+ [
+ {
+ "cfg_args": "before_restart",
+ "expected_lines": [
+ "All the test panes are opened: True",
+ "Test pane 1 is closed: True",
+ "Location of test pane 2 changed successfully: True",
+ "Test pane 3 resized successfully: True",
+ ],
+ },
+ {
+ "cfg_args": "after_restart",
+ "expected_lines": [
+ "Test pane retained its visiblity on Editor restart: True",
+ "Test pane retained its location on Editor restart: True",
+ "Test pane retained its size on Editor restart: True",
+ ],
+ },
+ ],
+ )
+ def test_Pane_PropertiesChanged_RetainsOnRestart(self, request, editor, config, project, launcher_platform):
+ hydra.launch_and_validate_results(
+ request,
+ TEST_DIRECTORY,
+ editor,
+ "Pane_PropertiesChanged_RetainsOnRestart.py",
+ config.get('expected_lines'),
+ cfg_args=[config.get('cfg_args')],
+ auto_test_mode=False,
+ timeout=60,
+ )
From 3e0ce61d0003a9ad618607364d6403be80afb507 Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Mon, 17 May 2021 08:24:02 -0500
Subject: [PATCH 17/66] Rename setreg file to sceneassetimporter
---
Registry/{assetimporter.setreg => sceneassetimporter.setreg} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename Registry/{assetimporter.setreg => sceneassetimporter.setreg} (100%)
diff --git a/Registry/assetimporter.setreg b/Registry/sceneassetimporter.setreg
similarity index 100%
rename from Registry/assetimporter.setreg
rename to Registry/sceneassetimporter.setreg
From ee4e9af46521fe06a08f910b0086790042fff8af Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Mon, 17 May 2021 08:27:04 -0500
Subject: [PATCH 18/66] Rename AssetImporterSettings to SceneImporterSettings
---
.../SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp | 8 ++++----
.../SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h | 6 +++---
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
index 65bb8de4c7..52ab184f66 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.cpp
@@ -27,13 +27,13 @@ namespace AZ
{
namespace FbxSceneImporter
{
- void AssetImporterSettings::Reflect(AZ::ReflectContext* context)
+ void SceneImporterSettings::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast(context); serializeContext)
{
- serializeContext->Class()
+ serializeContext->Class()
->Version(1)
- ->Field("SupportedFileTypeExtensions", &AssetImporterSettings::m_supportedFileTypeExtensions);
+ ->Field("SupportedFileTypeExtensions", &SceneImporterSettings::m_supportedFileTypeExtensions);
}
}
@@ -56,7 +56,7 @@ namespace AZ
void FbxImportRequestHandler::Reflect(ReflectContext* context)
{
- AssetImporterSettings::Reflect(context);
+ SceneImporterSettings::Reflect(context);
SerializeContext* serializeContext = azrtti_cast(context);
if (serializeContext)
diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
index 99d2061229..f68b56314b 100644
--- a/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
+++ b/Code/Tools/SceneAPI/FbxSceneBuilder/FbxImportRequestHandler.h
@@ -21,9 +21,9 @@ namespace AZ
{
namespace FbxSceneImporter
{
- struct AssetImporterSettings
+ struct SceneImporterSettings
{
- AZ_TYPE_INFO(AssetImporterSettings, "{8BB6C7AD-BF99-44DC-9DA1-E7AD3F03DC10}");
+ AZ_TYPE_INFO(SceneImporterSettings, "{8BB6C7AD-BF99-44DC-9DA1-E7AD3F03DC10}");
static void Reflect(AZ::ReflectContext* context);
@@ -51,7 +51,7 @@ namespace AZ
private:
- AssetImporterSettings m_settings;
+ SceneImporterSettings m_settings;
static constexpr const char* SettingsFilename = "AssetImporterSettings.json";
};
From bcaf4209d59a5aa054c0fb2d5030b09d57655ee9 Mon Sep 17 00:00:00 2001
From: daimini
Date: Mon, 17 May 2021 15:39:25 -0700
Subject: [PATCH 19/66] Move some logic to a helper function. Revert order of
link creation operations as they are not necessary to fix the bug, so it is
preferred to leave them untouched.
---
.../Prefab/PrefabPublicHandler.cpp | 84 ++++++++++---------
.../Prefab/PrefabPublicHandler.h | 5 +-
2 files changed, 49 insertions(+), 40 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
index 47642e90f3..53bf515860 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
@@ -121,41 +121,9 @@ namespace AzToolsFramework
}
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
- AZ::Entity* containerEntity = GetEntityById(containerEntityId);
- {
- // Generate the transform for the container entity out of the top level entities, and set it
- // This step needs to be done before anything is parented to the container, else children position will be wrong
- Prefab::PrefabDom containerEntityDomBefore;
- m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *containerEntity);
-
- AZ::Vector3 containerEntityTranslation(AZ::Vector3::CreateZero());
- AZ::Quaternion containerEntityRotation(AZ::Quaternion::CreateZero());
-
- // Set container entity to be child of common root
- AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
-
- // Set the transform (translation, rotation) of the container entity
- GenerateContainerEntityTransform(topLevelEntities, containerEntityTranslation, containerEntityRotation);
- AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalTranslation, containerEntityTranslation);
- AZ::TransformBus::Event(
- containerEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, containerEntityRotation);
-
- PrefabDom containerEntityDomAfter;
- m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *containerEntity);
-
- PrefabDom patch;
- m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
- m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
-
- // Update the cache - this prevents these changes from being stored in the regular undo/redo nodes
- m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
-
- // Create a link between the templates of the newly created instance and the instance it's being parented under.
- CreateLink(
- instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(),
- undoBatch.GetUndoBatch(), patch);
- }
+ // Apply the correct transform to the container for the new instance, and store the patch for use when creating the link.
+ PrefabDom patch = ApplyContainerTransformAndGeneratePatch(containerEntityId, commonRootEntityId, topLevelEntities);
// Parent the entities to the container entity. Parenting the container entities of the instances passed to createPrefab
// will be done during the creation of links below.
@@ -172,12 +140,18 @@ namespace AzToolsFramework
}
instanceToCreate->get().GetNestedInstances([&](AZStd::unique_ptr& nestedInstance) {
+ AZ_Assert(nestedInstance, "Invalid nested instance found in the new prefab created.");
+
// These link creations shouldn't be undone because that would put the template in a non-usable state if a user
// chooses to instantiate the template after undoing the creation.
- PrefabDom emptyPatch;
- CreateLink(*nestedInstance, instanceToCreate->get().GetTemplateId(), undoBatch.GetUndoBatch(), emptyPatch, false);
+ CreateLink(*nestedInstance, instanceToCreate->get().GetTemplateId(), undoBatch.GetUndoBatch(), {}, false);
});
+ // Create a link between the templates of the newly created instance and the instance it's being parented under.
+ CreateLink(
+ instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(),
+ AZStd::move(patch));
+
for (AZ::Entity* topLevelEntity : topLevelEntities)
{
AZ::EntityId topLevelEntityId = topLevelEntity->GetId();
@@ -206,6 +180,39 @@ namespace AzToolsFramework
return AZ::Success();
}
+ PrefabDom PrefabPublicHandler::ApplyContainerTransformAndGeneratePatch(AZ::EntityId containerEntityId, AZ::EntityId commonRootEntityId, const EntityList& topLevelEntities)
+ {
+ AZ::Entity* containerEntity = GetEntityById(containerEntityId);
+
+ // Generate the transform for the container entity out of the top level entities, and set it
+ // This step needs to be done before anything is parented to the container, else children position will be wrong
+ Prefab::PrefabDom containerEntityDomBefore;
+ m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *containerEntity);
+
+ AZ::Vector3 containerEntityTranslation(AZ::Vector3::CreateZero());
+ AZ::Quaternion containerEntityRotation(AZ::Quaternion::CreateZero());
+
+ // Set container entity to be child of common root
+ AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
+
+ // Set the transform (translation, rotation) of the container entity
+ GenerateContainerEntityTransform(topLevelEntities, containerEntityTranslation, containerEntityRotation);
+ AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalTranslation, containerEntityTranslation);
+ AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, containerEntityRotation);
+
+ PrefabDom containerEntityDomAfter;
+ m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *containerEntity);
+
+ PrefabDom patch;
+ m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
+ m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
+
+ // Update the cache - this prevents these changes from being stored in the regular undo/redo nodes
+ m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
+
+ return AZStd::move(patch);
+ }
+
PrefabOperationResult PrefabPublicHandler::InstantiatePrefab(
AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position)
{
@@ -271,8 +278,7 @@ namespace AzToolsFramework
PrefabUndoHelpers::UpdatePrefabInstance(
instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch());
- PrefabDom emptyPatch;
- CreateLink(instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), undoBatch.GetUndoBatch(), emptyPatch);
+ CreateLink(instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), undoBatch.GetUndoBatch(), {});
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
// Apply position
@@ -344,7 +350,7 @@ namespace AzToolsFramework
void PrefabPublicHandler::CreateLink(
Instance& sourceInstance, TemplateId targetTemplateId,
- UndoSystem::URSequencePoint* undoBatch, PrefabDom& patch, const bool isUndoRedoSupportNeeded)
+ UndoSystem::URSequencePoint* undoBatch, PrefabDom patch, const bool isUndoRedoSupportNeeded)
{
LinkId linkId;
if (isUndoRedoSupportNeeded)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
index 583def2219..d6763cab40 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
@@ -69,6 +69,9 @@ namespace AzToolsFramework
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
bool EntitiesBelongToSameInstance(const EntityIdList& entityIds) const;
+ PrefabDom ApplyContainerTransformAndGeneratePatch(
+ AZ::EntityId containerEntityId, AZ::EntityId commonRootEntityId, const EntityList& topLevelEntities);
+
/**
* Creates a link between the templates of an instance and its parent.
*
@@ -80,7 +83,7 @@ namespace AzToolsFramework
*/
void CreateLink(
Instance& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch,
- PrefabDom& patch, const bool isUndoRedoSupportNeeded = true);
+ PrefabDom patch, const bool isUndoRedoSupportNeeded = true);
/**
* Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId.
From 8792cac88a863d9b1daacf6d6964c5d58af80062 Mon Sep 17 00:00:00 2001
From: sconel
Date: Mon, 17 May 2021 18:50:21 -0700
Subject: [PATCH 20/66] Updating SpawnableEntitiesManager to handle entity
references during spawn
---
.../Spawnable/SpawnableEntitiesManager.cpp | 28 ++++++++++++++-----
.../Spawnable/SpawnableEntitiesManager.h | 7 ++++-
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
index 3ab004b516..ac71b9fed8 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
@@ -11,6 +11,7 @@
*/
#include
+#include
#include
#include
#include
@@ -200,11 +201,13 @@ namespace AzFramework
}
}
- AZ::Entity* SpawnableEntitiesManager::SpawnSingleEntity(const AZ::Entity& entityTemplate, AZ::SerializeContext& serializeContext)
+ AZ::Entity* SpawnableEntitiesManager::SpawnSingleEntity(const AZ::Entity& entityTemplate, EntityIdMap& spawnableToInstanceEntityIdMap,
+ AZ::SerializeContext& serializeContext)
{
- AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate);
+ AZ::Entity* clone = AZ::IdUtils::Remapper::CloneObjectAndGenerateNewIdsAndFixRefs(
+ &entityTemplate, spawnableToInstanceEntityIdMap, &serializeContext);
+
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
- clone->SetId(AZ::Entity::MakeId());
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, clone);
return clone;
}
@@ -217,13 +220,16 @@ namespace AzFramework
size_t spawnedEntitiesCount = ticket.m_spawnedEntities.size();
const Spawnable::EntityList& entities = ticket.m_spawnable->GetEntities();
+ EntityIdMap& spawnableToInstanceEntityIdMap = ticket.m_spawnableToInstanceEntityIdMap;
+
size_t entitiesSize = entities.size();
ticket.m_spawnedEntities.reserve(ticket.m_spawnedEntities.size() + entitiesSize);
ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesSize);
+ spawnableToInstanceEntityIdMap.reserve(entitiesSize);
for(size_t i=0; iGetEntities();
+ EntityIdMap& spawnableToInstanceEntityIdMap = ticket.m_spawnableToInstanceEntityIdMap;
+
size_t entitiesSize = entities.size();
ticket.m_spawnedEntities.reserve(ticket.m_spawnedEntities.size() + entitiesSize);
ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesSize);
+ spawnableToInstanceEntityIdMap.reserve(entitiesSize);
for (size_t index : request.m_entityIndices)
{
- ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[index], serializeContext));
+ ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[index], spawnableToInstanceEntityIdMap, serializeContext));
ticket.m_spawnedEntityIndices.push_back(index);
}
ticket.m_loadAll = false;
@@ -337,6 +346,8 @@ namespace AzFramework
// Rebuild the list of entities.
ticket.m_spawnedEntities.clear();
const Spawnable::EntityList& entities = request.m_spawnable->GetEntities();
+ EntityIdMap& spawnableToInstanceEntityIdMap = ticket.m_spawnableToInstanceEntityIdMap;
+
if (ticket.m_loadAll)
{
// The new spawnable may have a different number of entities and since the intent of the user was
@@ -346,7 +357,9 @@ namespace AzFramework
size_t entitiesSize = entities.size();
for (size_t i = 0; i < entitiesSize; ++i)
{
- ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[i], serializeContext));
+ ticket.m_spawnedEntities.push_back(
+ SpawnSingleEntity(*entities[i], spawnableToInstanceEntityIdMap, serializeContext));
+
ticket.m_spawnedEntityIndices.push_back(i);
}
}
@@ -356,7 +369,8 @@ namespace AzFramework
for (size_t index : ticket.m_spawnedEntityIndices)
{
ticket.m_spawnedEntities.push_back(
- index < entitiesSize ? SpawnSingleEntity(*entities[index], serializeContext) : nullptr);
+ index < entitiesSize ?
+ SpawnSingleEntity(*entities[index], spawnableToInstanceEntityIdMap, serializeContext) : nullptr);
}
}
ticket.m_spawnable = AZStd::move(request.m_spawnable);
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
index c70b9ccaa6..b101268c5f 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
@@ -29,6 +29,8 @@ namespace AZ
namespace AzFramework
{
+ using EntityIdMap = AZStd::unordered_map;
+
class SpawnableEntitiesManager
: public SpawnableEntitiesInterface::Registrar
{
@@ -81,6 +83,8 @@ namespace AzFramework
AZStd::vector m_spawnedEntities;
AZStd::vector m_spawnedEntityIndices;
+ EntityIdMap m_spawnableToInstanceEntityIdMap;
+
AZ::Data::Asset m_spawnable;
uint32_t m_nextTicketId{ 0 }; //!< Next id for this ticket.
uint32_t m_currentTicketId{ 0 }; //!< The id for the command that should be executed.
@@ -140,7 +144,8 @@ namespace AzFramework
using Requests = AZStd::variant;
- AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate, AZ::SerializeContext& serializeContext);
+ AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate, EntityIdMap& spawnableToInstanceEntityIdMap,
+ AZ::SerializeContext& serializeContext);
bool ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext);
bool ProcessRequest(SpawnEntitiesCommand& request, AZ::SerializeContext& serializeContext);
From 6dd1985e2d301f618ec7a9a9e5520b734c482b7c Mon Sep 17 00:00:00 2001
From: balibhan
Date: Tue, 18 May 2021 15:06:26 +0530
Subject: [PATCH 21/66] removed unused import
---
.../editor_python_test_tools/pyside_utils.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/pyside_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/pyside_utils.py
index 10f060bba6..eed6a18614 100644
--- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/pyside_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/pyside_utils.py
@@ -18,7 +18,6 @@ from PySide2 import QtCore, QtWidgets, QtGui, QtTest
from PySide2.QtWidgets import QAction, QWidget
from PySide2.QtCore import Qt
from PySide2.QtTest import QTest
-import azlmbr.legacy.general as general
import traceback
import threading
import types
From dff3efbfcad6e8777a335de73085fb3b3a638b37 Mon Sep 17 00:00:00 2001
From: pruiksma
Date: Tue, 18 May 2021 14:01:18 -0500
Subject: [PATCH 22/66] [ATOM-15561] Adding AZ_Error for unhandled pass binding
failure case.
---
Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
index 1fad385fa6..3f5c16678c 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp
@@ -163,6 +163,11 @@ namespace AZ
binding.m_shaderInputIndex = idx.IsValid() ? static_cast(idx.GetIndex()) : PassAttachmentBinding::ShaderInputNoBind;
}
}
+ else
+ {
+ AZ_Error("Pass System", false, "[Pass %s] Could not bind shader buffer index '%s' because it has no attachment.", GetName().GetCStr(), shaderName.GetCStr());
+ binding.m_shaderInputIndex = PassAttachmentBinding::ShaderInputNoBind;
+ }
}
}
From bb458254a2645ca75b4b1be216d82bc54c889fe6 Mon Sep 17 00:00:00 2001
From: daimini
Date: Tue, 18 May 2021 14:52:30 -0700
Subject: [PATCH 23/66] Polish pass - rename arguments to be more generic, add
comments, restore patches to links during instantiation that were mistakenly
removed in previous changes.
---
.../Prefab/PrefabPublicHandler.cpp | 34 +++++++++++++++----
.../Prefab/PrefabPublicHandler.h | 14 ++++++--
2 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
index 53bf515860..7ddd9f16e1 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
@@ -180,9 +180,10 @@ namespace AzToolsFramework
return AZ::Success();
}
- PrefabDom PrefabPublicHandler::ApplyContainerTransformAndGeneratePatch(AZ::EntityId containerEntityId, AZ::EntityId commonRootEntityId, const EntityList& topLevelEntities)
+ PrefabDom PrefabPublicHandler::ApplyContainerTransformAndGeneratePatch(AZ::EntityId containerEntityId, AZ::EntityId parentEntityId, const EntityList& childEntities)
{
AZ::Entity* containerEntity = GetEntityById(containerEntityId);
+ AZ_Assert(containerEntity, "Invalid container entity passed to ApplyContainerTransformAndGeneratePatch.");
// Generate the transform for the container entity out of the top level entities, and set it
// This step needs to be done before anything is parented to the container, else children position will be wrong
@@ -193,10 +194,10 @@ namespace AzToolsFramework
AZ::Quaternion containerEntityRotation(AZ::Quaternion::CreateZero());
// Set container entity to be child of common root
- AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
+ AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, parentEntityId);
// Set the transform (translation, rotation) of the container entity
- GenerateContainerEntityTransform(topLevelEntities, containerEntityTranslation, containerEntityRotation);
+ GenerateContainerEntityTransform(childEntities, containerEntityTranslation, containerEntityRotation);
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalTranslation, containerEntityTranslation);
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, containerEntityRotation);
@@ -263,10 +264,10 @@ namespace AzToolsFramework
// Initialize Undo Batch object
ScopedUndoBatch undoBatch("Instantiate Prefab");
+ // Instantiate the Prefab
PrefabDom instanceToParentUnderDomBeforeCreate;
m_instanceToTemplateInterface->GenerateDomForInstance(instanceToParentUnderDomBeforeCreate, instanceToParentUnder->get());
- // Instantiate the Prefab
auto instanceToCreate = prefabEditorEntityOwnershipInterface->InstantiatePrefab(relativePath, instanceToParentUnder);
if (!instanceToCreate)
@@ -278,11 +279,32 @@ namespace AzToolsFramework
PrefabUndoHelpers::UpdatePrefabInstance(
instanceToParentUnder->get(), "Update prefab instance", instanceToParentUnderDomBeforeCreate, undoBatch.GetUndoBatch());
- CreateLink(instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), undoBatch.GetUndoBatch(), {});
+ // Create Link with correct container patches
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
+ AZ::Entity* containerEntity = GetEntityById(containerEntityId);
+ AZ_Assert(containerEntity, "Invalid container entity detected in InstantiatePrefab.");
- // Apply position
+ Prefab::PrefabDom containerEntityDomBefore;
+ m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *containerEntity);
+
+ // Set container entity's parent
+ AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, parent);
+
+ // Set the position of the container entity
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetWorldTranslation, position);
+
+ PrefabDom containerEntityDomAfter;
+ m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *containerEntity);
+
+ // Generate patch to be stored in the link
+ PrefabDom patch;
+ m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
+ m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
+
+ CreateLink(instanceToCreate->get(), instanceToParentUnder->get().GetTemplateId(), undoBatch.GetUndoBatch(), AZStd::move(patch));
+
+ // Update the cache - this prevents these changes from being stored in the regular undo/redo nodes
+ m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
}
return AZ::Success();
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
index d6763cab40..5ad5b4a9cf 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h
@@ -68,9 +68,19 @@ namespace AzToolsFramework
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
bool EntitiesBelongToSameInstance(const EntityIdList& entityIds) const;
-
+
+ /**
+ * Applies the correct transform changes to the container entity based on the parent and child entities provided, and returns an appropriate patch.
+ * The container will be parented to parentId, moved to the average transform of the future direct children and its cache will be updated.
+ * This helper function won't support undo/redo, update the templates or create any links. All that needs to be done by the caller.
+ *
+ * \param containerEntityId The container to apply the changes to.
+ * \param parentEntityId The id of the entity the container should be parented to.
+ * \param childEntities A list of entities that will subsequently be parented to this container.
+ * \return The PrefabDom containing the patches that should be stored in the parent link.
+ */
PrefabDom ApplyContainerTransformAndGeneratePatch(
- AZ::EntityId containerEntityId, AZ::EntityId commonRootEntityId, const EntityList& topLevelEntities);
+ AZ::EntityId containerEntityId, AZ::EntityId parentEntityId, const EntityList& childEntities);
/**
* Creates a link between the templates of an instance and its parent.
From b006eb57fe939fcf9277291a3094c607d0cdca22 Mon Sep 17 00:00:00 2001
From: gallowj
Date: Mon, 3 May 2021 19:21:17 -0500
Subject: [PATCH 24/66] Updating a bunch of materials in TestData to correct
changes to referenced texture paths
---
.../SkinTestCases/001_lucy_regression_test.material | 4 ++--
.../SkinTestCases/002_wrinkle_regression_test.material | 2 +-
.../101_DetailMaps_LucyBaseNoDetailMaps.material | 8 ++++----
.../StandardPbrTestCases/102_DetailMaps_All.material | 8 ++++----
.../105_DetailMaps_BlendMaskUsingDetailUVs.material | 8 ++++----
5 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material
index f43f6d0808..c359fea3b5 100644
--- a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material
+++ b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/001_lucy_regression_test.material
@@ -11,7 +11,7 @@
0.29372090101242068,
1.0
],
- "textureMap": "Objects/Lucy/Lucy_brass_baseColor.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"useTexture": false
},
"detailLayerGroup": {
@@ -30,7 +30,7 @@
},
"normal": {
"flipY": true,
- "textureMap": "Objects/Lucy/Lucy_normal.tif"
+ "textureMap": "Objects/Lucy/Lucy_normal.png"
},
"subsurfaceScattering": {
"enableSubsurfaceScattering": true,
diff --git a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material
index c611b992b6..ce42f32b67 100644
--- a/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material
+++ b/Gems/Atom/TestData/TestData/Materials/SkinTestCases/002_wrinkle_regression_test.material
@@ -29,7 +29,7 @@
},
"normal": {
"flipY": true,
- "textureMap": "Objects/Lucy/Lucy_normal.tif"
+ "textureMap": "Objects/Lucy/Lucy_normal.png"
},
"subsurfaceScattering": {
"enableSubsurfaceScattering": true,
diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material
index 2c711a3bf3..7b1f0ba6a9 100644
--- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material
+++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/101_DetailMaps_LucyBaseNoDetailMaps.material
@@ -5,20 +5,20 @@
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
- "textureMap": "Objects/Lucy/Lucy_brass_baseColor.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_BaseColor.png",
"textureMapUv": "Unwrapped"
},
"metallic": {
- "textureMap": "Objects/Lucy/Lucy_brass_metalness.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
- "textureMap": "Objects/Lucy/Lucy_normal.tif",
+ "textureMap": "Objects/Lucy/Lucy_normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
- "textureMap": "Objects/Lucy/Lucy_brass_roughness.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_roughness.png",
"textureMapUv": "Unwrapped"
}
}
diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material
index 7a94386a18..55a01866b5 100644
--- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material
+++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/102_DetailMaps_All.material
@@ -5,7 +5,7 @@
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
- "textureMap": "Objects/Lucy/Lucy_brass_baseColor.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_baseColor.png",
"textureMapUv": "Unwrapped"
},
"detailLayerGroup": {
@@ -22,16 +22,16 @@
"scale": 10.0
},
"metallic": {
- "textureMap": "Objects/Lucy/Lucy_brass_metalness.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
- "textureMap": "Objects/Lucy/Lucy_normal.tif",
+ "textureMap": "Objects/Lucy/Lucy_normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
- "textureMap": "Objects/Lucy/Lucy_brass_roughness.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_roughness.png",
"textureMapUv": "Unwrapped"
}
}
diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material
index ddeace43da..6193cf4eed 100644
--- a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material
+++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/105_DetailMaps_BlendMaskUsingDetailUVs.material
@@ -5,7 +5,7 @@
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
- "textureMap": "Objects/Lucy/Lucy_brass_baseColor.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_baseColor.png",
"textureMapUv": "Unwrapped"
},
"detailLayerGroup": {
@@ -21,16 +21,16 @@
"scale": 10.0
},
"metallic": {
- "textureMap": "Objects/Lucy/Lucy_brass_metalness.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_metallic.png",
"textureMapUv": "Unwrapped"
},
"normal": {
"flipY": true,
- "textureMap": "Objects/Lucy/Lucy_normal.tif",
+ "textureMap": "Objects/Lucy/Lucy_normal.png",
"textureMapUv": "Unwrapped"
},
"roughness": {
- "textureMap": "Objects/Lucy/Lucy_brass_roughness.tif",
+ "textureMap": "Objects/Lucy/Lucy_bronze_roughness.png",
"textureMapUv": "Unwrapped"
}
}
From 66a7db44f7521bdabee11aeb69a6fa3cab620b78 Mon Sep 17 00:00:00 2001
From: sconel
Date: Tue, 18 May 2021 17:13:24 -0700
Subject: [PATCH 25/66] Reduced scope of change to focus on SpawnAllEntities
---
.../Spawnable/SpawnableEntitiesManager.cpp | 60 ++++++++-----------
.../Spawnable/SpawnableEntitiesManager.h | 6 +-
2 files changed, 29 insertions(+), 37 deletions(-)
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
index ad2e1551d5..39501ba0cd 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
@@ -216,6 +216,18 @@ namespace AzFramework
return clone;
}
+ Spawnable::EntityList* SpawnableEntitiesManager::CloneAllEntities(const Spawnable::EntityList& entitiesTemplate,
+ AZ::SerializeContext& serializeContext)
+ {
+ // Map keeps track of ids from template (spawnable) to clone (instance)
+ // Allowing patch ups of fields referring to entityIds outside of a given entity
+ EntityIdMap templateToCloneIdMap;
+ templateToCloneIdMap.reserve(entitiesTemplate.size());
+
+ return AZ::IdUtils::Remapper::CloneObjectAndGenerateNewIdsAndFixRefs(
+ &entitiesTemplate, templateToCloneIdMap, &serializeContext);
+ }
+
bool SpawnableEntitiesManager::ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext)
{
Ticket& ticket = GetTicketPayload(*request.m_ticket);
@@ -235,44 +247,16 @@ namespace AzFramework
spawnedEntities.reserve(spawnedEntities.size() + entitiesToSpawnSize);
ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesToSpawnSize);
- // TEMP: To be replaced by IdUtils::Remapper
- using EntityIdMap = AZStd::unordered_map;
- EntityIdMap templateToCloneIdMap;
- // \TEMP
-
// Clone the entities from Spawnable
+ Spawnable::EntityList* clonedEntities = CloneAllEntities(entitiesToSpawn, serializeContext);
+ AZ_Assert(clonedEntities != nullptr, "Failed to clone entities while processing a SpawnAllEntitiesCommand");
+
+ spawnedEntities.insert(spawnedEntities.end(), clonedEntities->begin(), clonedEntities->end());
+
+ // Mark all indices as spawned
for (size_t i = 0; i < entitiesToSpawnSize; ++i)
{
- const AZ::Entity& entityTemplate = *entitiesToSpawn[i];
-
- AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate);
- AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
- clone->SetId(AZ::Entity::MakeId());
-
- spawnedEntities.push_back(clone);
spawnedEntityIndices.push_back(i);
-
- // TEMP: To be replaced by IdUtils::Remapper
- templateToCloneIdMap[entityTemplate.GetId()] = clone->GetId();
-
- // 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 = templateToCloneIdMap.find(parentId);
- if (it != templateToCloneIdMap.end())
- {
- transformComponent->SetParentRelative(it->second);
- }
- else
- {
- AZ_Warning(
- "SpawnableEntitiesManager", false, "Entity %s doesn't have the parent entity %s present in the spawnable",
- clone->GetName().c_str(), parentId.ToString().data());
- }
- }
- // \TEMP
}
// Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context.
@@ -438,10 +422,16 @@ namespace AzFramework
// to load every, simply start over.
ticket.m_spawnedEntityIndices.clear();
+ // Clone the entities from Spawnable
+ Spawnable::EntityList* clonedEntities = CloneAllEntities(entities, serializeContext);
+ AZ_Assert(clonedEntities != nullptr, "Failed to clone entities while processing a SpawnAllEntitiesCommand");
+
+ ticket.m_spawnedEntities.insert(ticket.m_spawnedEntities.end(), clonedEntities->begin(), clonedEntities->end());
+
+ // Mark all indices as spawned
size_t entitiesSize = entities.size();
for (size_t i = 0; i < entitiesSize; ++i)
{
- ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[i], serializeContext));
ticket.m_spawnedEntityIndices.push_back(i);
}
}
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
index bcd6a7b6ea..c9e1fbd715 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
@@ -83,7 +83,6 @@ namespace AzFramework
AZStd::vector m_spawnedEntities;
AZStd::vector m_spawnedEntityIndices;
- EntityIdMap m_spawnableToInstanceEntityIdMap;
AZ::Data::Asset m_spawnable;
uint32_t m_nextTicketId{ 0 }; //!< Next id for this ticket.
@@ -146,7 +145,10 @@ namespace AzFramework
using Requests = AZStd::variant;
- AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate, EntityIdMap& spawnableToInstanceEntityIdMap,
+ AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate,
+ AZ::SerializeContext& serializeContext);
+
+ Spawnable::EntityList* CloneAllEntities(const Spawnable::EntityList& entitiesTemplate,
AZ::SerializeContext& serializeContext);
bool ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext);
From 8733f0e4928eb8481dfcf153cc12ada493daad3a Mon Sep 17 00:00:00 2001
From: sconel
Date: Tue, 18 May 2021 17:16:44 -0700
Subject: [PATCH 26/66] Remove extra newline
---
.../AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
index c9e1fbd715..3def85170f 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
@@ -83,7 +83,6 @@ namespace AzFramework
AZStd::vector m_spawnedEntities;
AZStd::vector m_spawnedEntityIndices;
-
AZ::Data::Asset m_spawnable;
uint32_t m_nextTicketId{ 0 }; //!< Next id for this ticket.
uint32_t m_currentTicketId{ 0 }; //!< The id for the command that should be executed.
From c3fe375e8ff13c024faae837a0037f4117cba6ff Mon Sep 17 00:00:00 2001
From: jromnoa
Date: Tue, 18 May 2021 17:19:40 -0700
Subject: [PATCH 27/66] add some extra general.idle_wait() and
general.idle_wait_frames() calls to increase test stability to stop race
condition / intermittent failure in test
---
...ydra_AtomEditorComponents_AddedToEntity.py | 23 ++++++++++++-------
.../atom_renderer/test_Atom_MainSuite.py | 2 +-
2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
index e701ff8d16..f09da298f8 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
@@ -63,13 +63,13 @@ def run():
# undo component addition
general.undo()
- TestHelper.wait_for_condition(lambda: not hydra.has_components(new_entity.id, [component_name]), 2.0)
+ TestHelper.wait_for_condition(lambda: not hydra.has_components(new_entity.id, [component_name]), 1.5)
general.log(f"{component_name}_test: Component removed after UNDO: "
f"{not hydra.has_components(new_entity.id, [component_name])}")
# redo component addition
general.redo()
- TestHelper.wait_for_condition(lambda: hydra.has_components(new_entity.id, [component_name]), 2.0)
+ TestHelper.wait_for_condition(lambda: hydra.has_components(new_entity.id, [component_name]), 1.5)
general.log(f"{component_name}_test: Component added after REDO: "
f"{hydra.has_components(new_entity.id, [component_name])}")
@@ -77,10 +77,10 @@ def run():
def verify_enter_exit_game_mode(component_name):
general.enter_game_mode()
- TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 1.0)
+ TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 1.5)
general.log(f"{component_name}_test: Entered game mode: {general.is_in_game_mode()}")
general.exit_game_mode()
- TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 1.0)
+ TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 1.5)
general.log(f"{component_name}_test: Exit game mode: {not general.is_in_game_mode()}")
def verify_hide_unhide_entity(component_name, entity_obj):
@@ -97,16 +97,16 @@ def run():
def verify_deletion_undo_redo(component_name, entity_obj):
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", entity_obj.id)
- TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.0)
+ TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.5)
general.log(f"{component_name}_test: Entity deleted: {not hydra.find_entity_by_name(entity_obj.name)}")
general.undo()
- TestHelper.wait_for_condition(lambda: hydra.find_entity_by_name(entity_obj.name) is not None, 1.0)
+ TestHelper.wait_for_condition(lambda: hydra.find_entity_by_name(entity_obj.name) is not None, 1.5)
general.log(f"{component_name}_test: UNDO entity deletion works: "
f"{hydra.find_entity_by_name(entity_obj.name) is not None}")
general.redo()
- TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.0)
+ TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.5)
general.log(f"{component_name}_test: REDO entity deletion works: "
f"{not hydra.find_entity_by_name(entity_obj.name)}")
@@ -120,7 +120,7 @@ def run():
f"{not is_component_enabled(entity_obj.components[0])}")
for component in components_to_add:
entity_obj.add_component(component)
- TestHelper.wait_for_condition(lambda: is_component_enabled(entity_obj.components[0]), 1.0)
+ TestHelper.wait_for_condition(lambda: is_component_enabled(entity_obj.components[0]), 1.5)
general.log(
f"{component_name}_test: Entity enabled after adding "
f"required components: {is_component_enabled(entity_obj.components[0])}"
@@ -135,7 +135,9 @@ def run():
# Delete all existing entities initially
search_filter = azlmbr.entity.SearchFilter()
all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
+ general.idle_wait_frames(1)
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
+ general.idle_wait_frames(1)
class ComponentTests:
"""Test launcher for each component."""
@@ -147,9 +149,11 @@ def run():
def run_component_tests(self):
# Run common and additional tests
entity_obj = create_entity_undo_redo_component_addition(self.component_name)
+ general.idle_wait(0.5)
# Enter/Exit game mode test
verify_enter_exit_game_mode(self.component_name)
+ general.idle_wait(0.5)
# Any additional tests are executed here
for test in self.additional_tests:
@@ -157,13 +161,16 @@ def run():
# Hide/Unhide entity test
verify_hide_unhide_entity(self.component_name, entity_obj)
+ general.idle_wait(0.5)
# Deletion/Undo/Redo test
verify_deletion_undo_redo(self.component_name, entity_obj)
+ general.idle_wait(0.5)
# DepthOfField Component
camera_entity = hydra.Entity("camera_entity")
camera_entity.create_entity(math.Vector3(512.0, 512.0, 34.0), ["Camera"])
+ general.idle_wait(0.5)
depth_of_field = "DepthOfField"
ComponentTests(
depth_of_field,
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
index 0b75760e05..7589375ee9 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
@@ -163,7 +163,7 @@ class TestAtomEditorComponentsMain(object):
]
unexpected_lines = [
- "failed to open",
+ "Trace::Error",
"Traceback (most recent call last):",
]
From 6f22cfd20b7dba80a5b6ee19da951673d78391fe Mon Sep 17 00:00:00 2001
From: jromnoa
Date: Tue, 18 May 2021 17:27:42 -0700
Subject: [PATCH 28/66] fix timeout values for general.idle_wait() and add
Trace::Assert check with Trace::Error check, remove the 'failed to open'
check (not needed)
---
.../hydra_AtomEditorComponents_AddedToEntity.py | 16 ++++++++--------
.../atom_renderer/test_Atom_MainSuite.py | 1 +
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
index f09da298f8..39586b9dc2 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
@@ -63,13 +63,13 @@ def run():
# undo component addition
general.undo()
- TestHelper.wait_for_condition(lambda: not hydra.has_components(new_entity.id, [component_name]), 1.5)
+ TestHelper.wait_for_condition(lambda: not hydra.has_components(new_entity.id, [component_name]), 2.0)
general.log(f"{component_name}_test: Component removed after UNDO: "
f"{not hydra.has_components(new_entity.id, [component_name])}")
# redo component addition
general.redo()
- TestHelper.wait_for_condition(lambda: hydra.has_components(new_entity.id, [component_name]), 1.5)
+ TestHelper.wait_for_condition(lambda: hydra.has_components(new_entity.id, [component_name]), 2.0)
general.log(f"{component_name}_test: Component added after REDO: "
f"{hydra.has_components(new_entity.id, [component_name])}")
@@ -77,10 +77,10 @@ def run():
def verify_enter_exit_game_mode(component_name):
general.enter_game_mode()
- TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 1.5)
+ TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 2.0)
general.log(f"{component_name}_test: Entered game mode: {general.is_in_game_mode()}")
general.exit_game_mode()
- TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 1.5)
+ TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 2/-)
general.log(f"{component_name}_test: Exit game mode: {not general.is_in_game_mode()}")
def verify_hide_unhide_entity(component_name, entity_obj):
@@ -97,16 +97,16 @@ def run():
def verify_deletion_undo_redo(component_name, entity_obj):
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", entity_obj.id)
- TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.5)
+ TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 2.0)
general.log(f"{component_name}_test: Entity deleted: {not hydra.find_entity_by_name(entity_obj.name)}")
general.undo()
- TestHelper.wait_for_condition(lambda: hydra.find_entity_by_name(entity_obj.name) is not None, 1.5)
+ TestHelper.wait_for_condition(lambda: hydra.find_entity_by_name(entity_obj.name) is not None, 2.0)
general.log(f"{component_name}_test: UNDO entity deletion works: "
f"{hydra.find_entity_by_name(entity_obj.name) is not None}")
general.redo()
- TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.5)
+ TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 2.0)
general.log(f"{component_name}_test: REDO entity deletion works: "
f"{not hydra.find_entity_by_name(entity_obj.name)}")
@@ -120,7 +120,7 @@ def run():
f"{not is_component_enabled(entity_obj.components[0])}")
for component in components_to_add:
entity_obj.add_component(component)
- TestHelper.wait_for_condition(lambda: is_component_enabled(entity_obj.components[0]), 1.5)
+ TestHelper.wait_for_condition(lambda: is_component_enabled(entity_obj.components[0]), 2.0)
general.log(
f"{component_name}_test: Entity enabled after adding "
f"required components: {is_component_enabled(entity_obj.components[0])}"
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
index 7589375ee9..b64a592c1d 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py
@@ -163,6 +163,7 @@ class TestAtomEditorComponentsMain(object):
]
unexpected_lines = [
+ "Trace::Assert",
"Trace::Error",
"Traceback (most recent call last):",
]
From 0dd6d819850accdf7bd9617fba9ccfc21414d106 Mon Sep 17 00:00:00 2001
From: jromnoa
Date: Tue, 18 May 2021 17:29:24 -0700
Subject: [PATCH 29/66] small accidental typo fix
---
.../hydra_AtomEditorComponents_AddedToEntity.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
index 39586b9dc2..904075c747 100644
--- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
+++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py
@@ -80,7 +80,7 @@ def run():
TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 2.0)
general.log(f"{component_name}_test: Entered game mode: {general.is_in_game_mode()}")
general.exit_game_mode()
- TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 2/-)
+ TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 2.0)
general.log(f"{component_name}_test: Exit game mode: {not general.is_in_game_mode()}")
def verify_hide_unhide_entity(component_name, entity_obj):
From 977030a27ab1fe1a0367c238e30045f3129aecbf Mon Sep 17 00:00:00 2001
From: daimini
Date: Tue, 18 May 2021 17:53:27 -0700
Subject: [PATCH 30/66] On prefab creation, inherit the patches when moving the
nested prefab instances and then update the link with the new parent if
necessary.
---
.../Prefab/PrefabPublicHandler.cpp | 56 +++++++++++++++----
1 file changed, 46 insertions(+), 10 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
index 394349c378..dc9f34b0cb 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp
@@ -84,6 +84,7 @@ namespace AzToolsFramework
AZStd::vector entities;
AZStd::vector> instances;
+ AZStd::unordered_map nestedInstanceLinkPatches;
// Retrieve all entities affected and identify Instances
if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances))
@@ -96,6 +97,16 @@ namespace AzToolsFramework
// target templates of the other instances.
for (auto& nestedInstance : instances)
{
+ auto linkRef = m_prefabSystemComponentInterface->FindLink(nestedInstance->GetLinkId());
+
+ if (linkRef.has_value())
+ {
+ PrefabDom oldLinkPatches;
+ oldLinkPatches.CopyFrom(linkRef->get().GetLinkDom(), oldLinkPatches.GetAllocator());
+
+ nestedInstanceLinkPatches.emplace(nestedInstance.get(), AZStd::move(oldLinkPatches));
+ }
+
RemoveLink(nestedInstance, commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch());
}
@@ -145,23 +156,48 @@ namespace AzToolsFramework
instanceToCreate->get().GetNestedInstances([&](AZStd::unique_ptr& nestedInstance) {
AZ_Assert(nestedInstance, "Invalid nested instance found in the new prefab created.");
- AZ::EntityId parentId;
- AZ::TransformBus::EventResult(
- parentId, nestedInstanceContainerEntity->get().GetId(), &AZ::TransformBus::Events::GetParentId);
+ EntityOptionalReference nestedInstanceContainerEntity = nestedInstance->GetContainerEntity();
+ AZ_Assert(
+ nestedInstanceContainerEntity, "Invalid container entity found for the nested instance used in prefab creation.");
- auto entityIterator = AZStd::find_if(
- entities.begin(), entities.end(), [parentId](AZ::Entity* entity) { return entity->GetId() == parentId; });
+ AZ::EntityId nestedInstanceContainerEntityId = nestedInstanceContainerEntity->get().GetId();
+ PrefabDom previousPatch;
- // If the previous parent entity of the nested instance is not part of the entities of the newly created prefab,
- // then set the parent of the nested prefab as the container entity of the newly created prefab.
- if (entityIterator == entities.end())
+ // Retrieve the previous patch if it exists
+ if (nestedInstanceLinkPatches.contains(nestedInstance.get()))
{
- parentId = containerEntityId;
+ previousPatch = AZStd::move(nestedInstanceLinkPatches[nestedInstance.get()]);
}
// These link creations shouldn't be undone because that would put the template in a non-usable state if a user
// chooses to instantiate the template after undoing the creation.
- CreateLink(*nestedInstance, instanceToCreate->get().GetTemplateId(), undoBatch.GetUndoBatch(), {}, false);
+ CreateLink(*nestedInstance, instanceToCreate->get().GetTemplateId(), undoBatch.GetUndoBatch(), AZStd::move(previousPatch), false);
+
+ // If this nested instance's container is a top level entity in the new prefab, re-parent it and apply the change.
+ if (AZStd::find(topLevelEntities.begin(), topLevelEntities.end(), &nestedInstanceContainerEntity->get()) != topLevelEntities.end())
+ {
+ Prefab::PrefabDom containerEntityDomBefore;
+ m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *nestedInstanceContainerEntity);
+
+ AZ::TransformBus::Event(nestedInstanceContainerEntityId, &AZ::TransformBus::Events::SetParent, containerEntityId);
+
+ PrefabDom containerEntityDomAfter;
+ m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *nestedInstanceContainerEntity);
+
+ PrefabDom reparentPatch;
+ m_instanceToTemplateInterface->GeneratePatch(reparentPatch, containerEntityDomBefore, containerEntityDomAfter);
+ m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(reparentPatch, nestedInstanceContainerEntityId);
+
+ // Update the cache - this prevents these changes from being stored in the regular undo/redo nodes as a separate step
+ m_prefabUndoCache.Store(nestedInstanceContainerEntityId, AZStd::move(containerEntityDomAfter));
+
+ // Save these changes as patches to the link
+ PrefabUndoLinkUpdate* linkUpdate = aznew PrefabUndoLinkUpdate(AZStd::to_string(static_cast(nestedInstanceContainerEntityId)));
+ linkUpdate->SetParent(undoBatch.GetUndoBatch());
+ linkUpdate->Capture(reparentPatch, nestedInstance->GetLinkId());
+
+ linkUpdate->Redo();
+ }
});
// Create a link between the templates of the newly created instance and the instance it's being parented under.
From 85feef74dc990eb1feae981db2cd6c3be8e2b6c8 Mon Sep 17 00:00:00 2001
From: Mike Chang <62353586+amzn-changml@users.noreply.github.com>
Date: Tue, 18 May 2021 22:24:14 -0700
Subject: [PATCH 31/66] Update Windows 2019 AMI v3 Label
* Added new Windows v3 build label
* New v3 AMI
---
scripts/build/Platform/Windows/pipeline.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/build/Platform/Windows/pipeline.json b/scripts/build/Platform/Windows/pipeline.json
index 5f10ccc7ae..622fa9d5ae 100644
--- a/scripts/build/Platform/Windows/pipeline.json
+++ b/scripts/build/Platform/Windows/pipeline.json
@@ -1,6 +1,6 @@
{
"ENV": {
- "NODE_LABEL": "windows-047e5cdf",
+ "NODE_LABEL": "windows-b3c8994f1",
"LY_3RDPARTY_PATH": "C:/ly/3rdParty",
"TIMEOUT": 30,
"WORKSPACE": "D:/workspace",
From db7afee38320f7c739c6b71f199644b075d99e4d Mon Sep 17 00:00:00 2001
From: mnaumov
Date: Tue, 18 May 2021 22:38:27 -0700
Subject: [PATCH 32/66] Adding parameters to ACES tone mapping
---
.../DisplayMapper/AcesOutputTransformPass.h | 3 +
.../DisplayMapperConfigurationDescriptor.h | 46 +++++++++++
.../DisplayMapper/AcesOutputTransformPass.cpp | 30 ++++++++
.../DisplayMapperConfigurationDescriptor.cpp | 42 ++++++++++
.../DisplayMapper/DisplayMapperPass.cpp | 4 +-
.../DisplayMapperComponentConfig.h | 2 +-
.../DisplayMapperComponentConfig.cpp | 4 +-
.../DisplayMapperComponentController.cpp | 1 +
.../EditorDisplayMapperComponent.cpp | 77 ++++++++++++++++++-
.../EditorDisplayMapperComponent.h | 1 +
10 files changed, 205 insertions(+), 5 deletions(-)
diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h
index 5fce71fc07..e891344bdd 100644
--- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h
+++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h
@@ -46,6 +46,7 @@ namespace AZ
static RPI::Ptr Create(const RPI::PassDescriptor& descriptor);
void SetDisplayBufferFormat(RHI::Format format);
+ void SetAcesParameterOverrides(const DisplayMapperAcesParameters& acesParameterOverrides);
private:
explicit AcesOutputTransformPass(const RPI::PassDescriptor& descriptor);
@@ -65,6 +66,8 @@ namespace AZ
AZ::Render::DisplayMapperParameters m_displayMapperParameters = {};
RHI::Format m_displayBufferFormat = RHI::Format::Unknown;
+
+ DisplayMapperAcesParameters m_acesParameterOverrides;
};
} // namespace Render
} // namespace AZ
diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
index b645df4f6f..ca63fc054a 100644
--- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
+++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
@@ -24,6 +24,50 @@ namespace AZ
namespace Render
{
+ /**
+ * The ACES display mapper parameters.
+ * These parameters are input to the display mapper shader on the DisplayMapperPass.
+ */
+ struct DisplayMapperAcesParameters
+ {
+ AZ_RTTI(DisplayMapperAcesParameters, "{3EE8C0D4-3792-46C0-B91C-B89A81C36B91}");
+ AZ_CLASS_ALLOCATOR(DisplayMapperAcesParameters, SystemAllocator, 0);
+
+ static void Reflect(ReflectContext* context);
+
+ // When enabled allows parameter overrides for ACES configuration
+ bool m_overrideDefaults = false;
+
+ // Apply gamma adjustment to compensate for dim surround
+ bool m_alterSurround;
+ // Apply desaturation to compensate for luminance difference
+ bool m_applyDesaturation;
+ // Apply Color appearance transform (CAT) from ACES white point to assumed observer adapted white point
+ bool m_applyCATD60toD65;
+
+ // Reference white and black luminance values
+ float m_cinemaLimitsBlack = 0.02f;
+ float m_cinemaLimitsWhite = 48.0f;
+
+ // luminance linear extension below this
+ float m_minPoint = 0.0028798957f;
+ // luminance mid grey
+ float m_midPoint = 4.8f;
+ // luminance linear extension above this
+ float m_maxPoint = 1005.71912f;
+
+ // Gamma adjustment to be applied to compensate for the condition of the viewing environment.
+ // Note that ACES uses a value of 0.9811 for adjusting from dark to dim surrounding.
+ float m_surroundGamma = 0.9811f;
+ // Optional gamma value that is applied as basic gamma curve OETF
+ float m_gamma = 2.2f;
+
+ // Allows specifying default preset for different ODT modes
+ OutputDeviceTransformType m_preset = OutputDeviceTransformType_48Nits;
+
+ void LoadPreset();
+ };
+
//! A descriptor used to configure the DisplayMapper
struct DisplayMapperConfigurationDescriptor final
{
@@ -37,6 +81,8 @@ namespace AZ
bool m_ldrGradingLutEnabled = false;
Data::Asset m_ldrColorGradingLut;
+
+ DisplayMapperAcesParameters m_acesParameterOverrides;
};
//! Custom pass data for DisplayMapperPass.
diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp
index b2103739ba..1defb572aa 100644
--- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp
@@ -102,6 +102,36 @@ namespace AZ
AcesDisplayMapperFeatureProcessor::GetAcesDisplayMapperParameters(&m_displayMapperParameters, OutputDeviceTransformType_48Nits);
}
}
+
+ if (m_acesParameterOverrides.m_overrideDefaults)
+ {
+ m_displayMapperParameters.m_OutputDisplayTransformFlags = 0;
+ if (m_acesParameterOverrides.m_alterSurround)
+ {
+ m_displayMapperParameters.m_OutputDisplayTransformFlags |= 0x1;
+ }
+ if (m_acesParameterOverrides.m_applyDesaturation)
+ {
+ m_displayMapperParameters.m_OutputDisplayTransformFlags |= 0x2;
+ }
+ if (m_acesParameterOverrides.m_applyCATD60toD65)
+ {
+ m_displayMapperParameters.m_OutputDisplayTransformFlags |= 0x4;
+ }
+
+ m_displayMapperParameters.m_cinemaLimits[0] = m_acesParameterOverrides.m_cinemaLimitsBlack;
+ m_displayMapperParameters.m_cinemaLimits[1] = m_acesParameterOverrides.m_cinemaLimitsWhite;
+ m_displayMapperParameters.m_acesSplineParams.minPoint[0] = m_acesParameterOverrides.m_minPoint;
+ m_displayMapperParameters.m_acesSplineParams.midPoint[0] = m_acesParameterOverrides.m_midPoint;
+ m_displayMapperParameters.m_acesSplineParams.maxPoint[0] = m_acesParameterOverrides.m_maxPoint;
+ m_displayMapperParameters.m_surroundGamma = m_acesParameterOverrides.m_surroundGamma;
+ m_displayMapperParameters.m_gamma = m_acesParameterOverrides.m_gamma;
+ }
+ }
+
+ void AcesOutputTransformPass::SetAcesParameterOverrides(const DisplayMapperAcesParameters& acesParameterOverrides)
+ {
+ m_acesParameterOverrides = acesParameterOverrides;
}
} // namespace Render
} // namespace AZ
diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp
index d80a02d083..eb73f310c0 100644
--- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp
@@ -9,16 +9,58 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
+
#include
#include
+#include
namespace AZ
{
namespace Render
{
+ void DisplayMapperAcesParameters::Reflect(ReflectContext* context)
+ {
+ if (auto serializeContext = azrtti_cast(context))
+ {
+ serializeContext->Class()
+ ->Version(0)
+ ->Field("OverrideDefaults", &DisplayMapperAcesParameters::m_overrideDefaults)
+ ->Field("AlterSurround", &DisplayMapperAcesParameters::m_alterSurround)
+ ->Field("ApplyDesaturation", &DisplayMapperAcesParameters::m_applyDesaturation)
+ ->Field("ApplyCATD60toD65", &DisplayMapperAcesParameters::m_applyCATD60toD65)
+ ->Field("PresetODT", &DisplayMapperAcesParameters::m_preset)
+ ->Field("CinemaLimitsBlack", &DisplayMapperAcesParameters::m_cinemaLimitsBlack)
+ ->Field("CinemaLimitsWhite", &DisplayMapperAcesParameters::m_cinemaLimitsWhite)
+ ->Field("MinPoint", &DisplayMapperAcesParameters::m_minPoint)
+ ->Field("MidPoint", &DisplayMapperAcesParameters::m_midPoint)
+ ->Field("MaxPoint", &DisplayMapperAcesParameters::m_maxPoint)
+ ->Field("SurroundGamma", &DisplayMapperAcesParameters::m_surroundGamma)
+ ->Field("Gamma", &DisplayMapperAcesParameters::m_gamma);
+ }
+ }
+
+ void DisplayMapperAcesParameters::LoadPreset()
+ {
+ DisplayMapperParameters displayMapperParameters;
+ AcesDisplayMapperFeatureProcessor::GetAcesDisplayMapperParameters(&displayMapperParameters, m_preset);
+
+ m_alterSurround = (displayMapperParameters.m_OutputDisplayTransformFlags & 0x1) != 0;
+ m_applyDesaturation = (displayMapperParameters.m_OutputDisplayTransformFlags & 0x2) != 0;
+ m_applyCATD60toD65 = (displayMapperParameters.m_OutputDisplayTransformFlags & 0x4) != 0;
+ m_cinemaLimitsBlack = displayMapperParameters.m_cinemaLimits[0];
+ m_cinemaLimitsWhite = displayMapperParameters.m_cinemaLimits[1];
+ m_minPoint = displayMapperParameters.m_acesSplineParams.minPoint[0];
+ m_midPoint = displayMapperParameters.m_acesSplineParams.midPoint[0];
+ m_maxPoint = displayMapperParameters.m_acesSplineParams.maxPoint[0];
+ m_surroundGamma = displayMapperParameters.m_surroundGamma;
+ m_gamma = displayMapperParameters.m_gamma;
+ }
+
void DisplayMapperConfigurationDescriptor::Reflect(AZ::ReflectContext* context)
{
+ DisplayMapperAcesParameters::Reflect(context);
+
if (auto* serializeContext = azrtti_cast(context))
{
serializeContext->Enum()
diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp
index 1de92c42f6..8ae790e12c 100644
--- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperPass.cpp
@@ -106,6 +106,7 @@ namespace AZ
{
if (m_acesOutputTransformPass)
{
+ m_acesOutputTransformPass->SetAcesParameterOverrides(m_displayMapperConfigurationDescriptor.m_acesParameterOverrides);
m_acesOutputTransformPass->SetDisplayBufferFormat(m_displayBufferFormat);
}
if (m_bakeAcesOutputTransformLutPass)
@@ -509,7 +510,8 @@ namespace AZ
if (desc.m_operationType != m_displayMapperConfigurationDescriptor.m_operationType ||
desc.m_ldrGradingLutEnabled != m_displayMapperConfigurationDescriptor.m_ldrGradingLutEnabled ||
- desc.m_ldrColorGradingLut != m_displayMapperConfigurationDescriptor.m_ldrColorGradingLut)
+ desc.m_ldrColorGradingLut != m_displayMapperConfigurationDescriptor.m_ldrColorGradingLut ||
+ desc.m_acesParameterOverrides.m_overrideDefaults != m_displayMapperConfigurationDescriptor.m_acesParameterOverrides.m_overrideDefaults)
{
m_needToRebuildChildren = true;
}
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/DisplayMapper/DisplayMapperComponentConfig.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/DisplayMapper/DisplayMapperComponentConfig.h
index 81645b25a9..f3e3c63f5a 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/DisplayMapper/DisplayMapperComponentConfig.h
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/DisplayMapper/DisplayMapperComponentConfig.h
@@ -20,7 +20,6 @@ namespace AZ
{
namespace Render
{
-
class DisplayMapperComponentConfig final
: public ComponentConfig
{
@@ -33,6 +32,7 @@ namespace AZ
DisplayMapperOperationType m_displayMapperOperation = DisplayMapperOperationType::Aces;
bool m_ldrColorGradingLutEnabled = false;
Data::Asset m_ldrColorGradingLut = {};
+ DisplayMapperAcesParameters m_acesParameterOverrides;
};
}
}
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentConfig.cpp
index e6afd4f21f..94b7dd6fb0 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentConfig.cpp
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentConfig.cpp
@@ -23,13 +23,13 @@ namespace AZ
if (auto serializeContext = azrtti_cast(context))
{
serializeContext->Class()
- ->Version(0)
+ ->Version(1)
->Field("DisplayMapperOperationType", &DisplayMapperComponentConfig::m_displayMapperOperation)
->Field("LdrColorGradingLutEnabled", &DisplayMapperComponentConfig::m_ldrColorGradingLutEnabled)
->Field("LdrColorGradingLut", &DisplayMapperComponentConfig::m_ldrColorGradingLut)
+ ->Field("AcesParameters", &DisplayMapperComponentConfig::m_acesParameterOverrides)
;
}
}
-
} // namespace Render
} // namespace AZ
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentController.cpp
index d90e170322..0e283199e7 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentController.cpp
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentController.cpp
@@ -85,6 +85,7 @@ namespace AZ
desc.m_operationType = m_configuration.m_displayMapperOperation;
desc.m_ldrGradingLutEnabled = m_configuration.m_ldrColorGradingLutEnabled;
desc.m_ldrColorGradingLut = m_configuration.m_ldrColorGradingLut;
+ desc.m_acesParameterOverrides = m_configuration.m_acesParameterOverrides;
fp->RegisterDisplayMapperConfiguration(desc);
}
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp
index 80aad79218..9b0e5a9553 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp
@@ -10,6 +10,8 @@
*
*/
+#include "Atom/Feature/ACES/AcesDisplayMapperFeatureProcessor.h"
+
#include
#include
@@ -47,6 +49,76 @@ namespace AZ
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
;
+ editContext->Class(
+ "DisplayMapperAcesParameters", "")
+ ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+ ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
+
+ ->DataElement(
+ AZ::Edit::UIHandlers::CheckBox, &DisplayMapperAcesParameters::m_overrideDefaults, "Override Defaults",
+ "When enabled allows parameter overrides for ACES configuration")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+
+ ->DataElement(
+ AZ::Edit::UIHandlers::CheckBox, &DisplayMapperAcesParameters::m_alterSurround, "Alter Surround",
+ "Apply gamma adjustment to compensate for dim surround")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+ ->DataElement(
+ AZ::Edit::UIHandlers::CheckBox, &DisplayMapperAcesParameters::m_applyDesaturation, "Alter Desaturation",
+ "Apply desaturation to compensate for luminance difference")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+ ->DataElement(
+ AZ::Edit::UIHandlers::CheckBox, &DisplayMapperAcesParameters::m_applyCATD60toD65, "Alter CAT D60 to D65",
+ "Apply Color appearance transform (CAT) from ACES white point to assumed observer adapted white point")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+
+ ->DataElement(
+ Edit::UIHandlers::Default, &DisplayMapperAcesParameters::m_cinemaLimitsBlack,
+ "Cinema Limit (black)",
+ "Reference black luminance value")
+ ->DataElement(
+ Edit::UIHandlers::Default, &DisplayMapperAcesParameters::m_cinemaLimitsWhite,
+ "Cinema Limit (white)",
+ "Reference white luminance value")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+
+ ->DataElement(
+ Edit::UIHandlers::Vector2, &DisplayMapperAcesParameters::m_minPoint, "Min Point (luminance)",
+ "Linear extension below this")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+ ->DataElement(
+ Edit::UIHandlers::Vector2, &DisplayMapperAcesParameters::m_midPoint, "Mid Point (luminance)",
+ "Middle gray")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+ ->DataElement(
+ Edit::UIHandlers::Vector2, &DisplayMapperAcesParameters::m_maxPoint, "Max Point (luminance)",
+ "Linear extension above this")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+
+ ->DataElement(
+ AZ::Edit::UIHandlers::Default, &DisplayMapperAcesParameters::m_surroundGamma, "Surround Gamma",
+ "Gamma adjustment to be applied to compensate for the condition of the viewing environment")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+ ->DataElement(
+ AZ::Edit::UIHandlers::Default, &DisplayMapperAcesParameters::m_gamma, "Gamma",
+ "Optional gamma value that is applied as basic gamma curve OETF")
+ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
+
+ // Load preset group
+ ->ClassElement(AZ::Edit::ClassElements::Group, "Load Preset")
+ ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
+ ->DataElement(
+ Edit::UIHandlers::ComboBox, &DisplayMapperAcesParameters::m_preset, "Preset Selection",
+ "Allows specifying default preset for different ODT modes")
+ ->EnumAttribute(OutputDeviceTransformType::OutputDeviceTransformType_48Nits, "48 Nits")
+ ->EnumAttribute(OutputDeviceTransformType::OutputDeviceTransformType_1000Nits, "1000 Nits")
+ ->EnumAttribute(OutputDeviceTransformType::OutputDeviceTransformType_2000Nits, "2000 Nits")
+ ->EnumAttribute(OutputDeviceTransformType::OutputDeviceTransformType_4000Nits, "4000 Nits")
+ ->UIElement(AZ::Edit::UIHandlers::Button, "Load", "Load default preset")
+ ->Attribute(AZ::Edit::Attributes::ChangeNotify, &DisplayMapperAcesParameters::LoadPreset)
+ ->Attribute(AZ::Edit::Attributes::ButtonText, "Load")
+ ;
+
editContext->Class("ToneMapperComponentConfig", "")
->ClassElement(Edit::ClassElements::EditorData, "")
->DataElement(Edit::UIHandlers::ComboBox,
@@ -64,7 +136,10 @@ namespace AZ
&DisplayMapperComponentConfig::m_ldrColorGradingLutEnabled,
"Enable LDR color grading LUT",
"Enable LDR color grading LUT.")
- ->DataElement(AZ::Edit::UIHandlers::Default, &DisplayMapperComponentConfig::m_ldrColorGradingLut, "LDR color Grading LUT", "LDR color grading LUT");
+ ->DataElement(AZ::Edit::UIHandlers::Default, &DisplayMapperComponentConfig::m_ldrColorGradingLut, "LDR color Grading LUT", "LDR color grading LUT")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &DisplayMapperComponentConfig::m_acesParameterOverrides, "ACES Parameters", "Parameter overrides for ACES.")
+ ;
+
}
}
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.h
index 12c3f5292c..ed69509bac 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.h
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.h
@@ -34,6 +34,7 @@ namespace AZ
//! EditorRenderComponentAdapter overrides...
AZ::u32 OnConfigurationChanged() override;
+
};
} // namespace Render
From 44601b7a38ef5e00a7cbc58d054e6da7001d8fe8 Mon Sep 17 00:00:00 2001
From: mnaumov
Date: Tue, 18 May 2021 22:45:43 -0700
Subject: [PATCH 33/66] Some refactoring
---
.../DisplayMapper/AcesOutputTransformPass.h | 4 +--
.../DisplayMapperConfigurationDescriptor.h | 18 +++++------
.../DisplayMapper/AcesOutputTransformPass.cpp | 2 +-
.../DisplayMapperConfigurationDescriptor.cpp | 32 +++++++++----------
.../DisplayMapperComponentConfig.h | 2 +-
.../DisplayMapperComponentConfig.cpp | 2 +-
.../EditorDisplayMapperComponent.cpp | 30 ++++++++---------
7 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h
index e891344bdd..5a0ccdb32a 100644
--- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h
+++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/AcesOutputTransformPass.h
@@ -46,7 +46,7 @@ namespace AZ
static RPI::Ptr Create(const RPI::PassDescriptor& descriptor);
void SetDisplayBufferFormat(RHI::Format format);
- void SetAcesParameterOverrides(const DisplayMapperAcesParameters& acesParameterOverrides);
+ void SetAcesParameterOverrides(const AcesParameterOverrides& acesParameterOverrides);
private:
explicit AcesOutputTransformPass(const RPI::PassDescriptor& descriptor);
@@ -67,7 +67,7 @@ namespace AZ
RHI::Format m_displayBufferFormat = RHI::Format::Unknown;
- DisplayMapperAcesParameters m_acesParameterOverrides;
+ AcesParameterOverrides m_acesParameterOverrides;
};
} // namespace Render
} // namespace AZ
diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
index ca63fc054a..e7042589ba 100644
--- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
+++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
@@ -25,13 +25,13 @@ namespace AZ
namespace Render
{
/**
- * The ACES display mapper parameters.
- * These parameters are input to the display mapper shader on the DisplayMapperPass.
+ * The ACES display mapper parameter overrides.
+ * These parameters override default ACES parameters when m_overrideDefaults is true.
*/
- struct DisplayMapperAcesParameters
+ struct AcesParameterOverrides
{
- AZ_RTTI(DisplayMapperAcesParameters, "{3EE8C0D4-3792-46C0-B91C-B89A81C36B91}");
- AZ_CLASS_ALLOCATOR(DisplayMapperAcesParameters, SystemAllocator, 0);
+ AZ_RTTI(AcesParameterOverrides, "{3EE8C0D4-3792-46C0-B91C-B89A81C36B91}");
+ AZ_CLASS_ALLOCATOR(AcesParameterOverrides, SystemAllocator, 0);
static void Reflect(ReflectContext* context);
@@ -39,11 +39,11 @@ namespace AZ
bool m_overrideDefaults = false;
// Apply gamma adjustment to compensate for dim surround
- bool m_alterSurround;
+ bool m_alterSurround = true;
// Apply desaturation to compensate for luminance difference
- bool m_applyDesaturation;
+ bool m_applyDesaturation = true;
// Apply Color appearance transform (CAT) from ACES white point to assumed observer adapted white point
- bool m_applyCATD60toD65;
+ bool m_applyCATD60toD65 = true;
// Reference white and black luminance values
float m_cinemaLimitsBlack = 0.02f;
@@ -82,7 +82,7 @@ namespace AZ
bool m_ldrGradingLutEnabled = false;
Data::Asset m_ldrColorGradingLut;
- DisplayMapperAcesParameters m_acesParameterOverrides;
+ AcesParameterOverrides m_acesParameterOverrides;
};
//! Custom pass data for DisplayMapperPass.
diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp
index 1defb572aa..b7042b83fc 100644
--- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/AcesOutputTransformPass.cpp
@@ -129,7 +129,7 @@ namespace AZ
}
}
- void AcesOutputTransformPass::SetAcesParameterOverrides(const DisplayMapperAcesParameters& acesParameterOverrides)
+ void AcesOutputTransformPass::SetAcesParameterOverrides(const AcesParameterOverrides& acesParameterOverrides)
{
m_acesParameterOverrides = acesParameterOverrides;
}
diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp
index eb73f310c0..ddd440aa88 100644
--- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp
@@ -19,28 +19,28 @@ namespace AZ
{
namespace Render
{
- void DisplayMapperAcesParameters::Reflect(ReflectContext* context)
+ void AcesParameterOverrides::Reflect(ReflectContext* context)
{
if (auto serializeContext = azrtti_cast(context))
{
- serializeContext->Class()
+ serializeContext->Class()
->Version(0)
- ->Field("OverrideDefaults", &DisplayMapperAcesParameters::m_overrideDefaults)
- ->Field("AlterSurround", &DisplayMapperAcesParameters::m_alterSurround)
- ->Field("ApplyDesaturation", &DisplayMapperAcesParameters::m_applyDesaturation)
- ->Field("ApplyCATD60toD65", &DisplayMapperAcesParameters::m_applyCATD60toD65)
- ->Field("PresetODT", &DisplayMapperAcesParameters::m_preset)
- ->Field("CinemaLimitsBlack", &DisplayMapperAcesParameters::m_cinemaLimitsBlack)
- ->Field("CinemaLimitsWhite", &DisplayMapperAcesParameters::m_cinemaLimitsWhite)
- ->Field("MinPoint", &DisplayMapperAcesParameters::m_minPoint)
- ->Field("MidPoint", &DisplayMapperAcesParameters::m_midPoint)
- ->Field("MaxPoint", &DisplayMapperAcesParameters::m_maxPoint)
- ->Field("SurroundGamma", &DisplayMapperAcesParameters::m_surroundGamma)
- ->Field("Gamma", &DisplayMapperAcesParameters::m_gamma);
+ ->Field("OverrideDefaults", &AcesParameterOverrides::m_overrideDefaults)
+ ->Field("AlterSurround", &AcesParameterOverrides::m_alterSurround)
+ ->Field("ApplyDesaturation", &AcesParameterOverrides::m_applyDesaturation)
+ ->Field("ApplyCATD60toD65", &AcesParameterOverrides::m_applyCATD60toD65)
+ ->Field("PresetODT", &AcesParameterOverrides::m_preset)
+ ->Field("CinemaLimitsBlack", &AcesParameterOverrides::m_cinemaLimitsBlack)
+ ->Field("CinemaLimitsWhite", &AcesParameterOverrides::m_cinemaLimitsWhite)
+ ->Field("MinPoint", &AcesParameterOverrides::m_minPoint)
+ ->Field("MidPoint", &AcesParameterOverrides::m_midPoint)
+ ->Field("MaxPoint", &AcesParameterOverrides::m_maxPoint)
+ ->Field("SurroundGamma", &AcesParameterOverrides::m_surroundGamma)
+ ->Field("Gamma", &AcesParameterOverrides::m_gamma);
}
}
- void DisplayMapperAcesParameters::LoadPreset()
+ void AcesParameterOverrides::LoadPreset()
{
DisplayMapperParameters displayMapperParameters;
AcesDisplayMapperFeatureProcessor::GetAcesDisplayMapperParameters(&displayMapperParameters, m_preset);
@@ -59,7 +59,7 @@ namespace AZ
void DisplayMapperConfigurationDescriptor::Reflect(AZ::ReflectContext* context)
{
- DisplayMapperAcesParameters::Reflect(context);
+ AcesParameterOverrides::Reflect(context);
if (auto* serializeContext = azrtti_cast(context))
{
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/DisplayMapper/DisplayMapperComponentConfig.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/DisplayMapper/DisplayMapperComponentConfig.h
index f3e3c63f5a..3c5bcbea00 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/DisplayMapper/DisplayMapperComponentConfig.h
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/PostProcess/DisplayMapper/DisplayMapperComponentConfig.h
@@ -32,7 +32,7 @@ namespace AZ
DisplayMapperOperationType m_displayMapperOperation = DisplayMapperOperationType::Aces;
bool m_ldrColorGradingLutEnabled = false;
Data::Asset m_ldrColorGradingLut = {};
- DisplayMapperAcesParameters m_acesParameterOverrides;
+ AcesParameterOverrides m_acesParameterOverrides;
};
}
}
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentConfig.cpp
index 94b7dd6fb0..9829cc2516 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentConfig.cpp
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/DisplayMapperComponentConfig.cpp
@@ -27,7 +27,7 @@ namespace AZ
->Field("DisplayMapperOperationType", &DisplayMapperComponentConfig::m_displayMapperOperation)
->Field("LdrColorGradingLutEnabled", &DisplayMapperComponentConfig::m_ldrColorGradingLutEnabled)
->Field("LdrColorGradingLut", &DisplayMapperComponentConfig::m_ldrColorGradingLut)
- ->Field("AcesParameters", &DisplayMapperComponentConfig::m_acesParameterOverrides)
+ ->Field("AcesParameterOverrides", &DisplayMapperComponentConfig::m_acesParameterOverrides)
;
}
}
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp
index 9b0e5a9553..64cd450940 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.cpp
@@ -49,58 +49,58 @@ namespace AZ
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
;
- editContext->Class(
- "DisplayMapperAcesParameters", "")
+ editContext->Class(
+ "AcesParameterOverrides", "")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(
- AZ::Edit::UIHandlers::CheckBox, &DisplayMapperAcesParameters::m_overrideDefaults, "Override Defaults",
+ AZ::Edit::UIHandlers::CheckBox, &AcesParameterOverrides::m_overrideDefaults, "Override Defaults",
"When enabled allows parameter overrides for ACES configuration")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- AZ::Edit::UIHandlers::CheckBox, &DisplayMapperAcesParameters::m_alterSurround, "Alter Surround",
+ AZ::Edit::UIHandlers::CheckBox, &AcesParameterOverrides::m_alterSurround, "Alter Surround",
"Apply gamma adjustment to compensate for dim surround")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- AZ::Edit::UIHandlers::CheckBox, &DisplayMapperAcesParameters::m_applyDesaturation, "Alter Desaturation",
+ AZ::Edit::UIHandlers::CheckBox, &AcesParameterOverrides::m_applyDesaturation, "Alter Desaturation",
"Apply desaturation to compensate for luminance difference")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- AZ::Edit::UIHandlers::CheckBox, &DisplayMapperAcesParameters::m_applyCATD60toD65, "Alter CAT D60 to D65",
+ AZ::Edit::UIHandlers::CheckBox, &AcesParameterOverrides::m_applyCATD60toD65, "Alter CAT D60 to D65",
"Apply Color appearance transform (CAT) from ACES white point to assumed observer adapted white point")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- Edit::UIHandlers::Default, &DisplayMapperAcesParameters::m_cinemaLimitsBlack,
+ Edit::UIHandlers::Default, &AcesParameterOverrides::m_cinemaLimitsBlack,
"Cinema Limit (black)",
"Reference black luminance value")
->DataElement(
- Edit::UIHandlers::Default, &DisplayMapperAcesParameters::m_cinemaLimitsWhite,
+ Edit::UIHandlers::Default, &AcesParameterOverrides::m_cinemaLimitsWhite,
"Cinema Limit (white)",
"Reference white luminance value")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- Edit::UIHandlers::Vector2, &DisplayMapperAcesParameters::m_minPoint, "Min Point (luminance)",
+ Edit::UIHandlers::Vector2, &AcesParameterOverrides::m_minPoint, "Min Point (luminance)",
"Linear extension below this")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- Edit::UIHandlers::Vector2, &DisplayMapperAcesParameters::m_midPoint, "Mid Point (luminance)",
+ Edit::UIHandlers::Vector2, &AcesParameterOverrides::m_midPoint, "Mid Point (luminance)",
"Middle gray")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- Edit::UIHandlers::Vector2, &DisplayMapperAcesParameters::m_maxPoint, "Max Point (luminance)",
+ Edit::UIHandlers::Vector2, &AcesParameterOverrides::m_maxPoint, "Max Point (luminance)",
"Linear extension above this")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- AZ::Edit::UIHandlers::Default, &DisplayMapperAcesParameters::m_surroundGamma, "Surround Gamma",
+ AZ::Edit::UIHandlers::Default, &AcesParameterOverrides::m_surroundGamma, "Surround Gamma",
"Gamma adjustment to be applied to compensate for the condition of the viewing environment")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
->DataElement(
- AZ::Edit::UIHandlers::Default, &DisplayMapperAcesParameters::m_gamma, "Gamma",
+ AZ::Edit::UIHandlers::Default, &AcesParameterOverrides::m_gamma, "Gamma",
"Optional gamma value that is applied as basic gamma curve OETF")
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
@@ -108,14 +108,14 @@ namespace AZ
->ClassElement(AZ::Edit::ClassElements::Group, "Load Preset")
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(
- Edit::UIHandlers::ComboBox, &DisplayMapperAcesParameters::m_preset, "Preset Selection",
+ Edit::UIHandlers::ComboBox, &AcesParameterOverrides::m_preset, "Preset Selection",
"Allows specifying default preset for different ODT modes")
->EnumAttribute(OutputDeviceTransformType::OutputDeviceTransformType_48Nits, "48 Nits")
->EnumAttribute(OutputDeviceTransformType::OutputDeviceTransformType_1000Nits, "1000 Nits")
->EnumAttribute(OutputDeviceTransformType::OutputDeviceTransformType_2000Nits, "2000 Nits")
->EnumAttribute(OutputDeviceTransformType::OutputDeviceTransformType_4000Nits, "4000 Nits")
->UIElement(AZ::Edit::UIHandlers::Button, "Load", "Load default preset")
- ->Attribute(AZ::Edit::Attributes::ChangeNotify, &DisplayMapperAcesParameters::LoadPreset)
+ ->Attribute(AZ::Edit::Attributes::ChangeNotify, &AcesParameterOverrides::LoadPreset)
->Attribute(AZ::Edit::Attributes::ButtonText, "Load")
;
From 06784a8026c07b2d3fdb78b48fa07fdb9e8601aa Mon Sep 17 00:00:00 2001
From: mnaumov
Date: Tue, 18 May 2021 22:50:13 -0700
Subject: [PATCH 34/66] cleanup
---
.../DisplayMapper/DisplayMapperConfigurationDescriptor.h | 4 ++--
.../PostProcess/DisplayMapper/EditorDisplayMapperComponent.h | 1 -
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
index e7042589ba..79d004bbea 100644
--- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
+++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/DisplayMapper/DisplayMapperConfigurationDescriptor.h
@@ -35,6 +35,8 @@ namespace AZ
static void Reflect(ReflectContext* context);
+ void LoadPreset();
+
// When enabled allows parameter overrides for ACES configuration
bool m_overrideDefaults = false;
@@ -64,8 +66,6 @@ namespace AZ
// Allows specifying default preset for different ODT modes
OutputDeviceTransformType m_preset = OutputDeviceTransformType_48Nits;
-
- void LoadPreset();
};
//! A descriptor used to configure the DisplayMapper
diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.h
index ed69509bac..12c3f5292c 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.h
+++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/PostProcess/DisplayMapper/EditorDisplayMapperComponent.h
@@ -34,7 +34,6 @@ namespace AZ
//! EditorRenderComponentAdapter overrides...
AZ::u32 OnConfigurationChanged() override;
-
};
} // namespace Render
From bf4b65afdeec8f5fa1f72639193f23e90e65f5b9 Mon Sep 17 00:00:00 2001
From: amzn-sean <75276488+amzn-sean@users.noreply.github.com>
Date: Wed, 19 May 2021 14:18:54 +0100
Subject: [PATCH 35/66] Fix crash in character component when using prefabs
(#798)
---
.../CharacterControllerComponent.cpp | 43 ++++++++++++++-----
.../Components/CharacterControllerComponent.h | 7 +++
Gems/PhysX/Code/Source/Scene/PhysXScene.cpp | 1 +
3 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.cpp
index 473e9534cb..6fa69c7a24 100644
--- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.cpp
+++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.cpp
@@ -73,7 +73,10 @@ namespace PhysX
{
}
- CharacterControllerComponent::~CharacterControllerComponent() = default;
+ CharacterControllerComponent::~CharacterControllerComponent()
+ {
+ DisableController();
+ }
// AZ::Component
void CharacterControllerComponent::Init()
@@ -92,7 +95,7 @@ namespace PhysX
void CharacterControllerComponent::Deactivate()
{
- DestroyController();
+ DisableController();
Physics::CollisionFilteringRequestBus::Handler::BusDisconnect();
AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect();
@@ -198,7 +201,7 @@ namespace PhysX
void CharacterControllerComponent::DisablePhysics()
{
- DestroyController();
+ DisableController();
}
bool CharacterControllerComponent::IsPhysicsEnabled() const
@@ -421,17 +424,32 @@ namespace PhysX
AZ::TransformBus::EventResult(entityTranslation, GetEntityId(), &AZ::TransformBus::Events::GetWorldTranslation);
m_characterConfig->m_position = entityTranslation;
- if (auto* sceneInterface = AZ::Interface::Get())
+ auto* sceneInterface = AZ::Interface::Get();
+ if (sceneInterface != nullptr)
{
- AzPhysics::SimulatedBodyHandle bodyHandle = sceneInterface->AddSimulatedBody(defaultSceneHandle, m_characterConfig.get());
- m_controller = azdynamic_cast(sceneInterface->GetSimulatedBodyFromHandle(defaultSceneHandle, bodyHandle));
+ m_controllerBodyHandle = sceneInterface->AddSimulatedBody(defaultSceneHandle, m_characterConfig.get());
+ m_controller = azdynamic_cast(
+ sceneInterface->GetSimulatedBodyFromHandle(defaultSceneHandle, m_controllerBodyHandle));
}
if (m_controller == nullptr)
{
AZ_Error("PhysX Character Controller Component", false, "Failed to create character controller.");
return;
}
-
+
+ if (sceneInterface != nullptr)
+ {
+ // if the scene removes this controller body, we should also clean up our resources.
+ m_onSimulatedBodyRemovedHandler = AzPhysics::SceneEvents::OnSimulationBodyRemoved::Handler(
+ [this]([[maybe_unused]] AzPhysics::SceneHandle sceneHandle, AzPhysics::SimulatedBodyHandle bodyHandle) {
+ if (bodyHandle == m_controllerBodyHandle)
+ {
+ DestroyController();
+ }
+ });
+ sceneInterface->RegisterSimulationBodyRemovedHandler(defaultSceneHandle, m_onSimulatedBodyRemovedHandler);
+ }
+
CharacterControllerRequestBus::Handler::BusConnect(GetEntityId());
m_preSimulateHandler = AzPhysics::SystemEvents::OnPresimulateEvent::Handler(
@@ -447,7 +465,7 @@ namespace PhysX
}
}
- void CharacterControllerComponent::DestroyController()
+ void CharacterControllerComponent::DisableController()
{
if (!IsPhysicsEnabled())
{
@@ -460,10 +478,15 @@ namespace PhysX
{
sceneInterface->RemoveSimulatedBody(m_controller->m_sceneOwner, m_controller->m_bodyHandle);
}
+
+ DestroyController();
+ }
+
+ void CharacterControllerComponent::DestroyController()
+ {
m_controller = nullptr;
-
m_preSimulateHandler.Disconnect();
-
+ m_onSimulatedBodyRemovedHandler.Disconnect();
CharacterControllerRequestBus::Handler::BusDisconnect();
}
} // namespace PhysX
diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h
index a7a1a92ad2..7c25312b72 100644
--- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h
+++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h
@@ -131,7 +131,12 @@ namespace PhysX
void ToggleCollisionLayer(const AZStd::string& layerName, AZ::Crc32 colliderTag, bool enabled) override;
private:
+ // Creates the physics character controller in the current default physics scene.
+ // This will do nothing if the controller is already created.
void CreateController();
+ // Removes the physics character controller from the scene and will call DestroyController for clean up.
+ void DisableController();
+ // Cleans up all references and events used with the physics character controller.
void DestroyController();
void OnPreSimulate(float deltaTime);
@@ -139,6 +144,8 @@ namespace PhysX
AZStd::unique_ptr m_characterConfig;
AZStd::shared_ptr m_shapeConfig;
PhysX::CharacterController* m_controller = nullptr;
+ AzPhysics::SimulatedBodyHandle m_controllerBodyHandle = AzPhysics::InvalidSimulatedBodyHandle;
AzPhysics::SystemEvents::OnPresimulateEvent::Handler m_preSimulateHandler;
+ AzPhysics::SceneEvents::OnSimulationBodyRemoved::Handler m_onSimulatedBodyRemovedHandler;
};
} // namespace PhysX
diff --git a/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp b/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp
index 79aa767959..689ea47be7 100644
--- a/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp
+++ b/Gems/PhysX/Code/Source/Scene/PhysXScene.cpp
@@ -489,6 +489,7 @@ namespace PhysX
// Disable simulation on body (not signaling OnSimulationBodySimulationDisabled event)
DisableSimulationOfBodyInternal(*simulatedBody.second);
}
+ m_simulatedBodyRemovedEvent.Signal(m_sceneHandle, simulatedBody.second->m_bodyHandle);
delete simulatedBody.second;
}
}
From c49875fc37568a9cb6c7af52e1deb7b5fbcccc7f Mon Sep 17 00:00:00 2001
From: ibtehajn <81370835+ibtehajn@users.noreply.github.com>
Date: Wed, 12 May 2021 11:08:23 +0100
Subject: [PATCH 36/66] Use author instead of committer in changelog
computations
Any commits created through the GitHub UI (e.g. commits created by
merging PRs) usually assign GitHub itself as the ccommitter. This is
expected behaviour, as the commit is applied by GitHub itself. However,
for the purposes of changelog creation, showing the author (e.g. the
person who clicked the merge button on the PR) is more useful.
---
scripts/build/Jenkins/Jenkinsfile | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile
index ae2779eba8..ad01d6ed05 100644
--- a/scripts/build/Jenkins/Jenkinsfile
+++ b/scripts/build/Jenkins/Jenkinsfile
@@ -190,6 +190,7 @@ def CheckoutBootstrapScripts(String branchName) {
doGenerateSubmoduleConfigurations: false,
extensions: [
[$class: 'PruneStaleBranch'],
+ [$class: 'AuthorInChangelog'],
[$class: 'SparseCheckoutPaths', sparseCheckoutPaths: [
[ $class: 'SparseCheckoutPath', path: 'scripts/build/Jenkins/' ],
[ $class: 'SparseCheckoutPath', path: 'scripts/build/bootstrap/' ],
@@ -234,6 +235,7 @@ def CheckoutRepo(boolean disableSubmodules = false) {
branches: scm.branches,
extensions: [
[$class: 'PruneStaleBranch'],
+ [$class: 'AuthorInChangelog'],
[$class: 'SubmoduleOption', disableSubmodules: disableSubmodules, recursiveSubmodules: true],
[$class: 'CheckoutOption', timeout: 60]
],
@@ -339,7 +341,10 @@ def TestMetrics(Map pipelineConfig, String workspace, String branchName, String
checkout scm: [
$class: 'GitSCM',
branches: [[name: '*/main']],
- extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'mars']],
+ extensions: [
+ [$class: 'AuthorInChangelog'],
+ [$class: 'RelativeTargetDirectory', relativeTargetDir: 'mars']
+ ],
userRemoteConfigs: [[url: "${env.MARS_REPO}", name: 'mars', credentialsId: "${env.GITHUB_USER}"]]
]
withCredentials([usernamePassword(credentialsId: "${env.SERVICE_USER}", passwordVariable: 'apitoken', usernameVariable: 'username')]) {
From d8126d59c7082bceff7b31622e504fb3cc1e10c0 Mon Sep 17 00:00:00 2001
From: sconel
Date: Wed, 19 May 2021 08:39:00 -0700
Subject: [PATCH 37/66] Moved to iterative clone instead of bulk, addressed PR
feedback
---
.../Spawnable/SpawnableEntitiesManager.cpp | 50 +++++++++++--------
.../Spawnable/SpawnableEntitiesManager.h | 4 +-
2 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
index 39501ba0cd..fd838d5cb5 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
@@ -216,16 +216,11 @@ namespace AzFramework
return clone;
}
- Spawnable::EntityList* SpawnableEntitiesManager::CloneAllEntities(const Spawnable::EntityList& entitiesTemplate,
- AZ::SerializeContext& serializeContext)
+ AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityTemplate,
+ EntityIdMap& templateToCloneEntityIdMap, AZ::SerializeContext& serializeContext)
{
- // Map keeps track of ids from template (spawnable) to clone (instance)
- // Allowing patch ups of fields referring to entityIds outside of a given entity
- EntityIdMap templateToCloneIdMap;
- templateToCloneIdMap.reserve(entitiesTemplate.size());
-
return AZ::IdUtils::Remapper::CloneObjectAndGenerateNewIdsAndFixRefs(
- &entitiesTemplate, templateToCloneIdMap, &serializeContext);
+ &entityTemplate, templateToCloneEntityIdMap, &serializeContext);
}
bool SpawnableEntitiesManager::ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext)
@@ -243,19 +238,25 @@ namespace AzFramework
const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities();
size_t entitiesToSpawnSize = entitiesToSpawn.size();
+ // Map keeps track of ids from template (spawnable) to clone (instance)
+ // Allowing patch ups of fields referring to entityIds outside of a given entity
+ EntityIdMap templateToCloneEntityIdMap;
+
// Reserve buffers
spawnedEntities.reserve(spawnedEntities.size() + entitiesToSpawnSize);
- ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesToSpawnSize);
-
- // Clone the entities from Spawnable
- Spawnable::EntityList* clonedEntities = CloneAllEntities(entitiesToSpawn, serializeContext);
- AZ_Assert(clonedEntities != nullptr, "Failed to clone entities while processing a SpawnAllEntitiesCommand");
-
- spawnedEntities.insert(spawnedEntities.end(), clonedEntities->begin(), clonedEntities->end());
+ spawnedEntityIndices.reserve(spawnedEntityIndices.size() + entitiesToSpawnSize);
+ templateToCloneEntityIdMap.reserve(entitiesToSpawnSize);
// Mark all indices as spawned
for (size_t i = 0; i < entitiesToSpawnSize; ++i)
{
+ const AZ::Entity& entityTemplate = *entitiesToSpawn[i];
+
+ AZ::Entity* clone = CloneSingleEntity(entityTemplate, templateToCloneEntityIdMap, serializeContext);
+
+ AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
+
+ spawnedEntities.emplace_back(clone);
spawnedEntityIndices.push_back(i);
}
@@ -422,16 +423,23 @@ namespace AzFramework
// to load every, simply start over.
ticket.m_spawnedEntityIndices.clear();
- // Clone the entities from Spawnable
- Spawnable::EntityList* clonedEntities = CloneAllEntities(entities, serializeContext);
- AZ_Assert(clonedEntities != nullptr, "Failed to clone entities while processing a SpawnAllEntitiesCommand");
+ size_t entitiesToSpawnSize = entities.size();
- ticket.m_spawnedEntities.insert(ticket.m_spawnedEntities.end(), clonedEntities->begin(), clonedEntities->end());
+ // Map keeps track of ids from template (spawnable) to clone (instance)
+ // Allowing patch ups of fields referring to entityIds outside of a given entity
+ EntityIdMap templateToCloneEntityIdMap;
+ templateToCloneEntityIdMap.reserve(entitiesToSpawnSize);
// Mark all indices as spawned
- size_t entitiesSize = entities.size();
- for (size_t i = 0; i < entitiesSize; ++i)
+ for (size_t i = 0; i < entitiesToSpawnSize; ++i)
{
+ const AZ::Entity& entityTemplate = *entities[i];
+
+ AZ::Entity* clone = CloneSingleEntity(entityTemplate, templateToCloneEntityIdMap, serializeContext);
+
+ AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
+
+ ticket.m_spawnedEntities.emplace_back(clone);
ticket.m_spawnedEntityIndices.push_back(i);
}
}
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
index 3def85170f..e20f58ac76 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h
@@ -147,8 +147,8 @@ namespace AzFramework
AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate,
AZ::SerializeContext& serializeContext);
- Spawnable::EntityList* CloneAllEntities(const Spawnable::EntityList& entitiesTemplate,
- AZ::SerializeContext& serializeContext);
+ AZ::Entity* CloneSingleEntity(const AZ::Entity& entityTemplate,
+ EntityIdMap& templateToCloneEntityIdMap, AZ::SerializeContext& serializeContext);
bool ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext);
bool ProcessRequest(SpawnEntitiesCommand& request, AZ::SerializeContext& serializeContext);
From 8dbcd9f199825e857e32dcb2dbcee5fa3422b113 Mon Sep 17 00:00:00 2001
From: amzn-sean <75276488+amzn-sean@users.noreply.github.com>
Date: Wed, 19 May 2021 16:44:53 +0100
Subject: [PATCH 38/66] increase physics max frame time to 0.1 seconds (10fps)
(#824)
---
.../AzFramework/Physics/Configuration/SystemConfiguration.cpp | 2 +-
.../AzFramework/Physics/Configuration/SystemConfiguration.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.cpp
index 497d67bef1..cd250b71a9 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.cpp
@@ -21,7 +21,7 @@ namespace AzPhysics
namespace
{
const float TimestepMin = 0.001f; //1000fps
- const float TimestepMax = 0.05f; //20fps
+ const float TimestepMax = 0.1f; //10fps
}
AZ_CLASS_ALLOCATOR_IMPL(SystemConfiguration, AZ::SystemAllocator, 0);
diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.h
index 3de4dafd8c..0a00d627a7 100644
--- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.h
+++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.h
@@ -34,7 +34,7 @@ namespace AzPhysics
static constexpr float DefaultFixedTimestep = 0.0166667f; //! Value represents 1/60th or 60 FPS.
- float m_maxTimestep = 1.f / 20.f; //!< Maximum fixed timestep in seconds to run the physics update.
+ float m_maxTimestep = 0.1f; //!< Maximum fixed timestep in seconds to run the physics update (10FPS).
float m_fixedTimestep = DefaultFixedTimestep; //!< Timestep in seconds to run the physics update. See DefaultFixedTimestep.
AZ::u64 m_raycastBufferSize = 32; //!< Maximum number of hits that will be returned from a raycast.
From 4769664e9e660b40696168cedb65645b0ea12f20 Mon Sep 17 00:00:00 2001
From: sconel
Date: Wed, 19 May 2021 08:50:14 -0700
Subject: [PATCH 39/66] Updating the loadAll flag after a SpawnAllCommand
---
.../AzFramework/Spawnable/SpawnableEntitiesManager.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
index fd838d5cb5..0418bce3a2 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
@@ -260,6 +260,8 @@ namespace AzFramework
spawnedEntityIndices.push_back(i);
}
+ ticket.m_loadAll = true;
+
// Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context.
if (request.m_preInsertionCallback)
{
From 31e5a312b4b6499d4047ba941ebfff9a4a146a22 Mon Sep 17 00:00:00 2001
From: sconel
Date: Wed, 19 May 2021 08:58:12 -0700
Subject: [PATCH 40/66] Updated loadAll check to set to false if previous
entities already spawned on ticket
---
.../Spawnable/SpawnableEntitiesManager.cpp | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
index 0418bce3a2..8045766686 100644
--- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp
@@ -260,7 +260,16 @@ namespace AzFramework
spawnedEntityIndices.push_back(i);
}
- ticket.m_loadAll = true;
+ // loadAll is true if every entity has been spawned only once
+ if (spawnedEntities.size() == entitiesToSpawnSize)
+ {
+ ticket.m_loadAll = true;
+ }
+ else
+ {
+ // Case where there were already spawns from a previous request
+ ticket.m_loadAll = false;
+ }
// Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context.
if (request.m_preInsertionCallback)
From 3c3f3fa91e7723b64818e02281790b1d8933ff15 Mon Sep 17 00:00:00 2001
From: ibtehajn <81370835+ibtehajn@users.noreply.github.com>
Date: Wed, 12 May 2021 11:04:54 +0100
Subject: [PATCH 41/66] Disable shallow checkout in initial setup step
Performing a shallow checkout breaks changelog computation, which is
required for accurate build failure notifications.
---
scripts/build/Jenkins/Jenkinsfile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile
index ad01d6ed05..eb0778791d 100644
--- a/scripts/build/Jenkins/Jenkinsfile
+++ b/scripts/build/Jenkins/Jenkinsfile
@@ -196,7 +196,8 @@ def CheckoutBootstrapScripts(String branchName) {
[ $class: 'SparseCheckoutPath', path: 'scripts/build/bootstrap/' ],
[ $class: 'SparseCheckoutPath', path: 'scripts/build/Platform' ]
]],
- [$class: 'CloneOption', depth: 1, noTags: false, reference: '', shallow: true]
+ // Shallow checkouts break changelog computation. Do not enable.
+ [$class: 'CloneOption', noTags: false, reference: '', shallow: false]
],
submoduleCfg: [],
userRemoteConfigs: scm.userRemoteConfigs
From ad2d2381a4a350804b653e63fc2a069f86390562 Mon Sep 17 00:00:00 2001
From: Vincent Liu <5900509+onecent1101@users.noreply.github.com>
Date: Wed, 19 May 2021 10:33:48 -0700
Subject: [PATCH 42/66] [SPEC-6713] Add common session interfaces and
notifications (#773)
---
.../Session/ISessionHandlingRequests.h | 78 +++++++
.../AzFramework/Session/ISessionRequests.cpp | 130 ++++++++++++
.../AzFramework/Session/ISessionRequests.h | 192 ++++++++++++++++++
.../AzFramework/Session/SessionConfig.cpp | 74 +++++++
.../AzFramework/Session/SessionConfig.h | 70 +++++++
.../Session/SessionNotifications.h | 47 +++++
.../AzFramework/azframework_files.cmake | 6 +
7 files changed, 597 insertions(+)
create mode 100644 Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h
create mode 100644 Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.cpp
create mode 100644 Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h
create mode 100644 Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp
create mode 100644 Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
create mode 100644 Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h
diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h b/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h
new file mode 100644
index 0000000000..47388c56c3
--- /dev/null
+++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h
@@ -0,0 +1,78 @@
+/*
+ * 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 AzFramework
+{
+ //! SessionConnectionConfig
+ //! The properties for handling join session request.
+ struct SessionConnectionConfig
+ {
+ // A unique identifier for registered player in session.
+ AZStd::string m_playerSessionId;
+
+ // The DNS identifier assigned to the instance that is running the session.
+ AZStd::string m_dnsName;
+
+ // The IP address of the session.
+ AZStd::string m_ipAddress;
+
+ // The port number for the session.
+ uint16_t m_port;
+ };
+
+ //! SessionConnectionConfig
+ //! The properties for handling player connect/disconnect
+ struct PlayerConnectionConfig
+ {
+ // A unique identifier for player connection.
+ uint32_t m_playerConnectionId;
+
+ // A unique identifier for registered player in session.
+ AZStd::string m_playerSessionId;
+ };
+
+ //! ISessionHandlingClientRequests
+ //! The session handling events to invoke multiplayer component handle the work on client side
+ class ISessionHandlingClientRequests
+ {
+ public:
+ // Handle the player join session process
+ // @param sessionConnectionConfig The required properties to handle the player join session process
+ // @return The result of player join session process
+ virtual bool HandlePlayerJoinSession(const SessionConnectionConfig& sessionConnectionConfig) = 0;
+
+ // Handle the player leave session process
+ virtual void HandlePlayerLeaveSession() = 0;
+ };
+
+ //! ISessionHandlingServerRequests
+ //! The session handling events to invoke server provider handle the work on server side
+ class ISessionHandlingServerRequests
+ {
+ public:
+ // Handle the destroy session process
+ virtual void HandleDestroySession() = 0;
+
+ // Validate the player join session process
+ // @param playerConnectionConfig The required properties to validate the player join session process
+ // @return The result of player join session validation
+ virtual bool ValidatePlayerJoinSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
+
+ // Handle the player leave session process
+ // @param playerConnectionConfig The required properties to handle the player leave session process
+ virtual void HandlePlayerLeaveSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
+ };
+} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.cpp b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.cpp
new file mode 100644
index 0000000000..4eb42ab815
--- /dev/null
+++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.cpp
@@ -0,0 +1,130 @@
+/*
+ * 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
+
+namespace AzFramework
+{
+ void CreateSessionRequest::Reflect(AZ::ReflectContext* context)
+ {
+ if (auto serializeContext = azrtti_cast(context))
+ {
+ serializeContext->Class()
+ ->Version(0)
+ ->Field("creatorId", &CreateSessionRequest::m_creatorId)
+ ->Field("sessionProperties", &CreateSessionRequest::m_sessionProperties)
+ ->Field("sessionName", &CreateSessionRequest::m_sessionName)
+ ->Field("maxPlayer", &CreateSessionRequest::m_maxPlayer)
+ ;
+
+ if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+ {
+ editContext->Class("CreateSessionRequest", "The container for CreateSession request parameters")
+ ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+ ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
+ ->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_creatorId,
+ "CreatorId", "A unique identifier for a player or entity creating the session")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_sessionProperties,
+ "SessionProperties", "A collection of custom properties for a session")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_sessionName,
+ "SessionName", "A descriptive label that is associated with a session")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_maxPlayer,
+ "MaxPlayer", "The maximum number of players that can be connected simultaneously to the session")
+ ;
+ }
+ }
+ }
+
+ void SearchSessionsRequest::Reflect(AZ::ReflectContext* context)
+ {
+ if (auto serializeContext = azrtti_cast(context))
+ {
+ serializeContext->Class()
+ ->Version(0)
+ ->Field("filterExpression", &SearchSessionsRequest::m_filterExpression)
+ ->Field("sortExpression", &SearchSessionsRequest::m_sortExpression)
+ ->Field("maxResult", &SearchSessionsRequest::m_maxResult)
+ ->Field("nextToken", &SearchSessionsRequest::m_nextToken)
+ ;
+
+ if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+ {
+ editContext->Class("SearchSessionsRequest", "The container for SearchSessions request parameters")
+ ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+ ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
+ ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_filterExpression,
+ "FilterExpression", "String containing the search criteria for the session search")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_sortExpression,
+ "SortExpression", "Instructions on how to sort the search results")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_maxResult,
+ "MaxResult", "The maximum number of results to return")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_nextToken,
+ "NextToken", "A token that indicates the start of the next sequential page of results")
+ ;
+ }
+ }
+ }
+
+ void SearchSessionsResponse::Reflect(AZ::ReflectContext* context)
+ {
+ if (auto serializeContext = azrtti_cast(context))
+ {
+ serializeContext->Class()
+ ->Version(0)
+ ->Field("sessionConfigs", &SearchSessionsResponse::m_sessionConfigs)
+ ->Field("nextToken", &SearchSessionsResponse::m_nextToken)
+ ;
+
+ if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+ {
+ editContext->Class("SearchSessionsResponse", "The container for SearchSession request results")
+ ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+ ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
+ ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsResponse::m_sessionConfigs,
+ "SessionConfigs", "A collection of sessions that match the search criteria and sorted in specific order")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsResponse::m_nextToken,
+ "NextToken", "A token that indicates the start of the next sequential page of results")
+ ;
+ }
+ }
+ }
+
+ void JoinSessionRequest::Reflect(AZ::ReflectContext* context)
+ {
+ if (auto serializeContext = azrtti_cast(context))
+ {
+ serializeContext->Class()
+ ->Version(0)
+ ->Field("sessionId", &JoinSessionRequest::m_sessionId)
+ ->Field("playerId", &JoinSessionRequest::m_playerId)
+ ->Field("playerData", &JoinSessionRequest::m_playerData)
+ ;
+
+ if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+ {
+ editContext->Class("JoinSessionRequest", "The container for JoinSession request parameters")
+ ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+ ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
+ ->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_sessionId,
+ "SessionId", "A unique identifier for the session")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_playerId,
+ "PlayerId", "A unique identifier for a player. Player IDs are developer-defined")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_playerData,
+ "PlayerData", "Developer-defined information related to a player")
+ ;
+ }
+ }
+ }
+} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h
new file mode 100644
index 0000000000..9d21a7f282
--- /dev/null
+++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h
@@ -0,0 +1,192 @@
+/*
+ * 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
+
+namespace AzFramework
+{
+ struct SessionConfig;
+
+ //! CreateSessionRequest
+ //! The container for CreateSession request parameters.
+ struct CreateSessionRequest
+ {
+ AZ_RTTI(CreateSessionRequest, "{E39C2A45-89C9-4CFB-B337-9734DC798930}");
+ static void Reflect(AZ::ReflectContext* context);
+
+ CreateSessionRequest() = default;
+ virtual ~CreateSessionRequest() = default;
+
+ // A unique identifier for a player or entity creating the session.
+ AZStd::string m_creatorId;
+
+ // A collection of custom properties for a session.
+ AZStd::unordered_map m_sessionProperties;
+
+ // A descriptive label that is associated with a session.
+ AZStd::string m_sessionName;
+
+ // The maximum number of players that can be connected simultaneously to the session.
+ uint64_t m_maxPlayer;
+ };
+
+ //! SearchSessionsRequest
+ //! The container for SearchSessions request parameters.
+ struct SearchSessionsRequest
+ {
+ AZ_RTTI(SearchSessionsRequest, "{B49207A8-8549-4ADB-B7D9-D7A4932F9B4B}");
+ static void Reflect(AZ::ReflectContext* context);
+
+ SearchSessionsRequest() = default;
+ virtual ~SearchSessionsRequest() = default;
+
+ // String containing the search criteria for the session search. If no filter expression is included, the request returns results
+ // for all active sessions.
+ AZStd::string m_filterExpression;
+
+ // Instructions on how to sort the search results. If no sort expression is included, the request returns results in random order.
+ AZStd::string m_sortExpression;
+
+ // The maximum number of results to return.
+ uint8_t m_maxResult;
+
+ // A token that indicates the start of the next sequential page of results.
+ AZStd::string m_nextToken;
+ };
+
+ //! SearchSessionsResponse
+ //! The container for SearchSession request results.
+ struct SearchSessionsResponse
+ {
+ AZ_RTTI(SearchSessionsResponse, "{F93DE7DC-D381-4E08-8A3B-0B08F7C38714}");
+ static void Reflect(AZ::ReflectContext* context);
+
+ SearchSessionsResponse() = default;
+ virtual ~SearchSessionsResponse() = default;
+
+ // A collection of sessions that match the search criteria and sorted in specific order.
+ AZStd::vector m_sessionConfigs;
+
+ // A token that indicates the start of the next sequential page of results.
+ AZStd::string m_nextToken;
+ };
+
+ //! JoinSessionRequest
+ //! The container for JoinSession request parameters.
+ struct JoinSessionRequest
+ {
+ AZ_RTTI(JoinSessionRequest, "{519769E8-3CDE-4385-A0D7-24DBB3685657}");
+ static void Reflect(AZ::ReflectContext* context);
+
+ JoinSessionRequest() = default;
+ virtual ~JoinSessionRequest() = default;
+
+ // A unique identifier for the session.
+ AZStd::string m_sessionId;
+
+ // A unique identifier for a player. Player IDs are developer-defined.
+ AZStd::string m_playerId;
+
+ // Developer-defined information related to a player.
+ AZStd::string m_playerData;
+ };
+
+ //! ISessionRequests
+ //! Pure virtual session interface class to abstract the details of session handling from application code.
+ class ISessionRequests
+ {
+ public:
+ AZ_RTTI(ISessionRequests, "{D6C41A71-DD8D-47FE-8515-FAF90670AE2F}");
+
+ ISessionRequests() = default;
+ virtual ~ISessionRequests() = default;
+
+ // Create a session for players to find and join.
+ // @param createSessionRequest The request of CreateSession operation
+ // @return The request id if session creation request succeeds; empty if it fails
+ virtual AZStd::string CreateSession(const CreateSessionRequest& createSessionRequest) = 0;
+
+ // Retrieve all active sessions that match the given search criteria and sorted in specific order.
+ // @param searchSessionsRequest The request of SearchSessions operation
+ // @return The response of SearchSessions operation
+ virtual SearchSessionsResponse SearchSessions(const SearchSessionsRequest& searchSessionsRequest) const = 0;
+
+ // Reserve an open player slot in a session, and perform connection from client to server.
+ // @param joinSessionRequest The request of JoinSession operation
+ // @return True if joining session succeeds; False otherwise
+ virtual bool JoinSession(const JoinSessionRequest& joinSessionRequest) = 0;
+
+ // Disconnect player from session.
+ virtual void LeaveSession() = 0;
+ };
+
+ //! ISessionAsyncRequests
+ //! Async version of ISessionRequests
+ class ISessionAsyncRequests
+ {
+ public:
+ AZ_RTTI(ISessionAsyncRequests, "{471542AF-96B9-4930-82FE-242A4E68432D}");
+
+ ISessionAsyncRequests() = default;
+ virtual ~ISessionAsyncRequests() = default;
+
+ // CreateSession Async
+ // @param createSessionRequest The request of CreateSession operation
+ virtual void CreateSessionAsync(const CreateSessionRequest& createSessionRequest) = 0;
+
+ // SearchSessions Async
+ // @param searchSessionsRequest The request of SearchSessions operation
+ virtual void SearchSessionsAsync(const SearchSessionsRequest& searchSessionsRequest) const = 0;
+
+ // JoinSession Async
+ // @param joinSessionRequest The request of JoinSession operation
+ virtual void JoinSessionAsync(const JoinSessionRequest& joinSessionRequest) = 0;
+
+ // LeaveSession Async
+ virtual void LeaveSessionAsync() = 0;
+ };
+
+ //! SessionAsyncRequestNotifications
+ //! The notifications correspond to session async requests
+ class SessionAsyncRequestNotifications
+ : public AZ::EBusTraits
+ {
+ public:
+ //////////////////////////////////////////////////////////////////////////
+ // EBusTraits overrides
+ static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
+ static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
+ //////////////////////////////////////////////////////////////////////////
+
+ // OnCreateSessionAsyncComplete is fired once CreateSessionAsync completes
+ // @param createSessionResponse The request id if session creation request succeeds; empty if it fails
+ virtual void OnCreateSessionAsyncComplete(const AZStd::string& createSessionReponse) = 0;
+
+ // OnSearchSessionsAsyncComplete is fired once SearchSessionsAsync completes
+ // @param searchSessionsResponse The response of SearchSessions call
+ virtual void OnSearchSessionsAsyncComplete(const SearchSessionsResponse& searchSessionsResponse) = 0;
+
+ // OnJoinSessionAsyncComplete is fired once JoinSessionAsync completes
+ // @param joinSessionsResponse True if joining session succeeds; False otherwise
+ virtual void OnJoinSessionAsyncComplete(bool joinSessionsResponse) = 0;
+
+ // OnLeaveSessionAsyncComplete is fired once LeaveSessionAsync completes
+ virtual void OnLeaveSessionAsyncComplete() = 0;
+ };
+ using SessionAsyncRequestNotificationBus = AZ::EBus;
+} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp
new file mode 100644
index 0000000000..12c5163031
--- /dev/null
+++ b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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
+
+namespace AzFramework
+{
+ void SessionConfig::Reflect(AZ::ReflectContext* context)
+ {
+ if (auto serializeContext = azrtti_cast(context))
+ {
+ serializeContext->Class()
+ ->Version(0)
+ ->Field("creationTime", &SessionConfig::m_creationTime)
+ ->Field("terminationTime", &SessionConfig::m_terminationTime)
+ ->Field("creatorId", &SessionConfig::m_creatorId)
+ ->Field("sessionProperties", &SessionConfig::m_sessionProperties)
+ ->Field("sessionId", &SessionConfig::m_sessionId)
+ ->Field("sessionName", &SessionConfig::m_sessionName)
+ ->Field("dnsName", &SessionConfig::m_dnsName)
+ ->Field("ipAddress", &SessionConfig::m_ipAddress)
+ ->Field("port", &SessionConfig::m_port)
+ ->Field("maxPlayer", &SessionConfig::m_maxPlayer)
+ ->Field("currentPlayer", &SessionConfig::m_currentPlayer)
+ ->Field("status", &SessionConfig::m_status)
+ ->Field("statusReason", &SessionConfig::m_statusReason)
+ ;
+
+ if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+ {
+ editContext->Class("SessionConfig", "Properties describing a session")
+ ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+ ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_creationTime,
+ "CreationTime", "A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_terminationTime,
+ "TerminationTime", "A time stamp indicating when this data object was terminated. Same format as creation time.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_creatorId,
+ "CreatorId", "A unique identifier for a player or entity creating the session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionProperties,
+ "SessionProperties", "A collection of custom properties for a session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionId,
+ "SessionId", "A unique identifier for the session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionName,
+ "SessionName", "A descriptive label that is associated with a session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_dnsName,
+ "DnsName", "The DNS identifier assigned to the instance that is running the session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_ipAddress,
+ "IpAddress", "The IP address of the session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_port,
+ "Port", "The port number for the session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_maxPlayer,
+ "MaxPlayer", "The maximum number of players that can be connected simultaneously to the session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_currentPlayer,
+ "CurrentPlayer", "Number of players currently in the session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_status,
+ "Status", "Current status of the session.")
+ ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_statusReason,
+ "StatusReason", "Provides additional information about session status.");
+ }
+ }
+ }
+} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
new file mode 100644
index 0000000000..22d1c9e875
--- /dev/null
+++ b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h
@@ -0,0 +1,70 @@
+/*
+* 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
+
+namespace AzFramework
+{
+ //! SessionConfig
+ //! Properties describing a session.
+ struct SessionConfig
+ {
+ AZ_RTTI(SessionConfig, "{992DD4BE-8BA5-4071-8818-B99FD2952086}");
+ static void Reflect(AZ::ReflectContext* context);
+
+ SessionConfig() = default;
+ virtual ~SessionConfig() = default;
+
+ // A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.
+ uint64_t m_creationTime;
+
+ // A time stamp indicating when this data object was terminated. Same format as creation time.
+ uint64_t m_terminationTime;
+
+ // A unique identifier for a player or entity creating the session.
+ AZStd::string m_creatorId;
+
+ // A collection of custom properties for a session.
+ AZStd::unordered_map m_sessionProperties;
+
+ // A unique identifier for the session.
+ AZStd::string m_sessionId;
+
+ // A descriptive label that is associated with a session.
+ AZStd::string m_sessionName;
+
+ // The DNS identifier assigned to the instance that is running the session.
+ AZStd::string m_dnsName;
+
+ // The IP address of the session.
+ AZStd::string m_ipAddress;
+
+ // The port number for the session.
+ uint16_t m_port;
+
+ // The maximum number of players that can be connected simultaneously to the session.
+ uint64_t m_maxPlayer;
+
+ // Number of players currently in the session.
+ uint64_t m_currentPlayer;
+
+ // Current status of the session.
+ AZStd::string m_status;
+
+ // Provides additional information about session status.
+ AZStd::string m_statusReason;
+ };
+} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h b/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h
new file mode 100644
index 0000000000..a61c995db7
--- /dev/null
+++ b/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h
@@ -0,0 +1,47 @@
+/*
+ * 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 AzFramework
+{
+ struct SessionConfig;
+
+ //! SessionNotifications
+ //! The session notifications to listen for performing required operations
+ class SessionNotifications
+ : public AZ::EBusTraits
+ {
+ public:
+ //////////////////////////////////////////////////////////////////////////
+ // EBusTraits overrides
+ static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
+ static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
+ //////////////////////////////////////////////////////////////////////////
+
+ // OnSessionHealthCheck is fired in health check process
+ // @return The result of all OnSessionHealthCheck
+ virtual bool OnSessionHealthCheck() = 0;
+
+ // OnCreateSessionBegin is fired at the beginning of session creation
+ // @param sessionConfig The properties to describe a session
+ // @return The result of all OnCreateSessionBegin notifications
+ virtual bool OnCreateSessionBegin(const SessionConfig& sessionConfig) = 0;
+
+ // OnDestroySessionBegin is fired at the beginning of session termination
+ // @return The result of all OnDestroySessionBegin notifications
+ virtual bool OnDestroySessionBegin() = 0;
+ };
+ using SessionNotificationBus = AZ::EBus;
+} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake
index 8cff479ec8..13dff43f68 100644
--- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake
+++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake
@@ -188,6 +188,12 @@ set(FILES
Script/ScriptDebugMsgReflection.h
Script/ScriptRemoteDebugging.cpp
Script/ScriptRemoteDebugging.h
+ Session/ISessionHandlingRequests.h
+ Session/ISessionRequests.cpp
+ Session/ISessionRequests.h
+ Session/SessionConfig.cpp
+ Session/SessionConfig.h
+ Session/SessionNotifications.h
StreamingInstall/StreamingInstall.h
StreamingInstall/StreamingInstall.cpp
StreamingInstall/StreamingInstallRequests.h
From 659998cd26bb501eb94ea28df9e515fead1ef9fa Mon Sep 17 00:00:00 2001
From: amzn-hdoke <61443753+hdoke@users.noreply.github.com>
Date: Wed, 19 May 2021 11:07:53 -0700
Subject: [PATCH 43/66] AWSI Gems CDK Automation fixtures (#707)
* Adding AWS automation tests cdk and resource mapping fixtures
* Add aws_utils fixture
* Update assume role arn
* Get region and account id from aws_utils fixture
* Adding NodeJS and AWS CDK as install dependencies
* Fixing missing copyright headers
* Add missing copyright header
* Remove cdk and node install from build folder
* Remove unused script canvas file
* Uncomment code, remove unused script canvas
* Add region to aws_utils fixture
* Adding AWS gems to automated testing for all platforms
* Re-exporting ClientAuth level
* Add PythonTests/AWS CMakeLists.txt
---
.../Config/aws_resource_mappings.json | 6 +
.../Gem/Code/runtime_dependencies.cmake | 3 +
.../Gem/Code/tool_dependencies.cmake | 3 +
.../Gem/PythonTests/AWS/CMakeLists.txt | 31 +
.../Gem/PythonTests/AWS/Windows/cdk/cdk.py | 155 ++
.../client_auth/test_anonymous_credentials.py | 78 +
.../AWS/Windows/resource_mappings/__init__.py | 10 +
.../resource_mappings/resource_mappings.py | 137 +
.../Gem/PythonTests/AWS/__init__.py | 11 +
.../Gem/PythonTests/AWS/common/aws_utils.py | 82 +
.../Gem/PythonTests/CMakeLists.txt | 5 +-
.../Levels/AWS/ClientAuth/ClientAuth.ly | 3 +
.../ConitoAnonymousAuthorization.scriptcanvas | 2313 +++++++++++++++++
.../AWS/ClientAuth/LevelData/Environment.xml | 1 +
.../AWS/ClientAuth/LevelData/TimeOfDay.xml | 1 +
.../Levels/AWS/ClientAuth/filelist.xml | 6 +
.../Levels/AWS/ClientAuth/level.pak | 3 +
.../Levels/AWS/ClientAuth/tags.txt | 12 +
.../Registry/awscoreconfiguration.setreg | 10 +
19 files changed, 2869 insertions(+), 1 deletion(-)
create mode 100644 AutomatedTesting/Config/aws_resource_mappings.json
create mode 100644 AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt
create mode 100644 AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py
create mode 100644 AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py
create mode 100644 AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__init__.py
create mode 100644 AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py
create mode 100644 AutomatedTesting/Gem/PythonTests/AWS/__init__.py
create mode 100644 AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py
create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly
create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas
create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml
create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml
create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml
create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/level.pak
create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/tags.txt
create mode 100644 AutomatedTesting/Registry/awscoreconfiguration.setreg
diff --git a/AutomatedTesting/Config/aws_resource_mappings.json b/AutomatedTesting/Config/aws_resource_mappings.json
new file mode 100644
index 0000000000..03a611b749
--- /dev/null
+++ b/AutomatedTesting/Config/aws_resource_mappings.json
@@ -0,0 +1,6 @@
+{
+ "AWSResourceMappings": {},
+ "AccountId": "",
+ "Region": "us-west-2",
+ "Version": "1.0.0"
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake
index 280c25bcf7..33c2bf8d5f 100644
--- a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake
+++ b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake
@@ -45,4 +45,7 @@ set(GEM_DEPENDENCIES
Gem::Atom_AtomBridge
Gem::NvCloth
Gem::Blast
+ Gem::AWSCore
+ Gem::AWSClientAuth
+ Gem::AWSMetrics
)
diff --git a/AutomatedTesting/Gem/Code/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/tool_dependencies.cmake
index fc50707c12..d4a49bfad5 100644
--- a/AutomatedTesting/Gem/Code/tool_dependencies.cmake
+++ b/AutomatedTesting/Gem/Code/tool_dependencies.cmake
@@ -55,4 +55,7 @@ set(GEM_DEPENDENCIES
Gem::Atom_AtomBridge.Editor
Gem::NvCloth.Editor
Gem::Blast.Editor
+ Gem::AWSCore.Editor
+ Gem::AWSClientAuth
+ Gem::AWSMetrics
)
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt
new file mode 100644
index 0000000000..b406ea77de
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+################################################################################
+# AWS Automated Tests
+# Runs AWS Gems automation tests.
+################################################################################
+
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
+ # Enable after installing NodeJS and CDK on jenkins Windows AMI.
+ #ly_add_pytest(
+ # NAME AutomatedTesting::AWSTests
+ # TEST_SUITE periodic
+ # TEST_SERIAL
+ # PATH ${CMAKE_CURRENT_LIST_DIR}/AWS/${PAL_PLATFORM_NAME}/
+ # RUNTIME_DEPENDENCIES
+ # Legacy::Editor
+ # AZ::AssetProcessor
+ # AutomatedTesting.Assets
+ # COMPONENT
+ # AWS
+ #)
+endif()
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py
new file mode 100644
index 0000000000..455b3f94cb
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.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.
+"""
+
+import os
+import pytest
+import boto3
+
+import ly_test_tools.environment.process_utils as process_utils
+from typing import List
+
+
+class Cdk:
+ """
+ Cdk class that provides methods to run cdk application commands.
+ Expects system to have NodeJS, AWS CLI and CDK installed globally and have their paths setup as env variables.
+ """
+ def __init__(self, cdk_path: str, project: str, account_id: str,
+ workspace: pytest.fixture, session: boto3.session.Session):
+ """
+ :param cdk_path: Path where cdk app.py is stored.
+ :param project: Project name used for cdk project name env variable.
+ :param account_id: AWS account id to use with cdk application.
+ :param workspace: ly_test_tools workspace fixture.
+ """
+ self._cdk_env = os.environ.copy()
+ self._cdk_env['O3DE_AWS_PROJECT_NAME'] = project
+ self._cdk_env['O3DE_AWS_DEPLOY_REGION'] = session.region_name
+ self._cdk_env['O3DE_AWS_DEPLOY_ACCOUNT'] = account_id
+ self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH']
+
+ credentials = session.get_credentials().get_frozen_credentials()
+ self._cdk_env['AWS_ACCESS_KEY_ID'] = credentials.access_key
+ self._cdk_env['AWS_SECRET_ACCESS_KEY'] = credentials.secret_key
+ self._cdk_env['AWS_SESSION_TOKEN'] = credentials.token
+ self._stacks = []
+ self._cdk_path = cdk_path
+
+ output = process_utils.check_output(
+ 'python -m pip install -r requirements.txt',
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ def list(self) -> List[str]:
+ """
+ lists cdk stack names
+ :return List of cdk stack names
+ """
+
+ if not self._cdk_path:
+ return []
+
+ list_cdk_application_cmd = ['cdk', 'list']
+ output = process_utils.check_output(
+ list_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ return output.splitlines()
+
+ def synthesize(self) -> None:
+ """
+ Synthesizes all cdk stacks
+ """
+ if not self._cdk_path:
+ return
+
+ list_cdk_application_cmd = ['cdk', 'synth']
+
+ process_utils.check_output(
+ list_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ def deploy(self, context_variable: str = '') -> List[str]:
+ """
+ Deploys all the CDK stacks.
+ :param context_variable: Context variable for enabling optional features.
+ :return List of deployed stack arns.
+ """
+ if not self._cdk_path:
+ return []
+
+ deploy_cdk_application_cmd = ['cdk', 'deploy', '--require-approval', 'never']
+ if context_variable:
+ deploy_cdk_application_cmd.extend(['-c', f'{context_variable}'])
+
+ output = process_utils.check_output(
+ deploy_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ stacks = []
+ for line in output.splitlines():
+ line_sections = line.split('/')
+ assert len(line_sections), 3
+ stacks.append(line.split('/')[-2])
+
+ return stacks
+
+ def destroy(self) -> None:
+ """
+ Destroys the cdk application.
+ """
+ destroy_cdk_application_cmd = ['cdk', 'destroy', '-f']
+ process_utils.check_output(
+ destroy_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ self._stacks = []
+ self._cdk_path = ''
+
+
+@pytest.fixture(scope='function')
+def cdk(
+ request: pytest.fixture,
+ project: str,
+ feature_name: str,
+ workspace: pytest.fixture,
+ aws_utils: pytest.fixture,
+ destroy_stacks_on_teardown: bool = True) -> Cdk:
+ """
+ Fixture for setting up a Cdk
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param project: Project name used for cdk project name env variable.
+ :param feature_name: Feature gem name to expect cdk folder in.
+ :param workspace: ly_test_tools workspace fixture.
+ :param aws_utils: aws_utils fixture.
+ :param destroy_stacks_on_teardown: option to control calling destroy ot the end of test.
+ :return Cdk class object.
+ """
+
+ cdk_path = f'{workspace.paths.engine_root()}/Gems/{feature_name}/cdk'
+ cdk_obj = Cdk(cdk_path, project, aws_utils.assume_account_id(), workspace, aws_utils.assume_session())
+
+ def teardown():
+ if destroy_stacks_on_teardown:
+ cdk_obj.destroy()
+ request.addfinalizer(teardown)
+
+ return cdk_obj
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py
new file mode 100644
index 0000000000..5997701870
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py
@@ -0,0 +1,78 @@
+"""
+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 logging
+import ly_test_tools.log.log_monitor
+
+from AWS.Windows.resource_mappings.resource_mappings import resource_mappings
+from AWS.Windows.cdk.cdk import cdk
+from AWS.common.aws_utils import aws_utils
+from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
+
+AWS_PROJECT_NAME = 'AWS-AutomationTest'
+AWS_CLIENT_AUTH_FEATURE_NAME = 'AWSClientAuth'
+AWS_CLIENT_AUTH_DEFAULT_PROFILE_NAME = 'default'
+
+GAME_LOG_NAME = 'Game.log'
+
+logger = logging.getLogger(__name__)
+
+
+@pytest.mark.SUITE_periodic
+@pytest.mark.usefixtures('automatic_process_killer')
+@pytest.mark.usefixtures('asset_processor')
+@pytest.mark.usefixtures('workspace')
+@pytest.mark.parametrize('project', ['AutomatedTesting'])
+@pytest.mark.parametrize('level', ['AWS/ClientAuth'])
+@pytest.mark.usefixtures('cdk')
+@pytest.mark.parametrize('feature_name', [AWS_CLIENT_AUTH_FEATURE_NAME])
+@pytest.mark.usefixtures('resource_mappings')
+@pytest.mark.parametrize('resource_mappings_filename', ['aws_resource_mappings.json'])
+@pytest.mark.usefixtures('aws_utils')
+@pytest.mark.parametrize('region_name', ['us-west-2'])
+@pytest.mark.parametrize('assume_role_arn', ['arn:aws:iam::645075835648:role/o3de-automation-tests'])
+@pytest.mark.parametrize('session_name', ['o3de-Automation-session'])
+class TestAWSClientAuthAnonymousCredentials(object):
+ """
+ Test class to verify AWS Cognito Identity pool anonymous authorization.
+ """
+
+ def test_anonymous_credentials(self,
+ level: str,
+ launcher: pytest.fixture,
+ cdk: pytest.fixture,
+ resource_mappings: pytest.fixture,
+ workspace: pytest.fixture,
+ asset_processor: pytest.fixture
+ ):
+ """
+ Setup: Deploys cdk and updates resource mapping file.
+ Tests: Getting AWS credentials for no signed in user.
+ Verification: Log monitor looks for success credentials log.
+ """
+ logger.info(f'Cdk stack names:\n{cdk.list()}')
+ stacks = cdk.deploy()
+ resource_mappings.populate_output_keys(stacks)
+ asset_processor.start()
+ asset_processor.wait_for_idle()
+
+ file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME)
+ log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor)
+
+ launcher.args = ['+LoadLevel', level]
+
+ with launcher.start(launch_ap=False):
+ result = log_monitor.monitor_log_for_lines(
+ expected_lines=['(Script) - Success anonymous credentials'],
+ unexpected_lines=['(Script) - Fail anonymous credentials'],
+ halt_on_unexpected=True,
+ )
+ assert result, 'Anonymous credentials fetched successfully.'
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__init__.py
new file mode 100644
index 0000000000..6ed3dc4bda
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__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/AWS/Windows/resource_mappings/resource_mappings.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py
new file mode 100644
index 0000000000..c8d8cff828
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py
@@ -0,0 +1,137 @@
+"""
+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 os
+import pytest
+import json
+
+AWS_RESOURCE_MAPPINGS_KEY = 'AWSResourceMappings'
+AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY = 'AccountId'
+AWS_RESOURCE_MAPPINGS_REGION_KEY = 'Region'
+
+
+class ResourceMappings:
+ """
+ ResourceMappings class that handles writing Cloud formation outputs to resource mappings json file in a project.
+ """
+
+ def __init__(self, file_path: str, region: str, feature_name: str, account_id: str, workspace: pytest.fixture,
+ cloud_formation_client):
+ """
+ :param file_path: Path for the resource mapping file.
+ :param region: Region value for the resource mapping file.
+ :param feature_name: Feature gem name to use to append name to mappings key.
+ :param account_id: AWS account id value for the resource mapping file.
+ :param workspace: ly_test_tools workspace fixture.
+ :param cloud_formation_client: AWS cloud formation client.
+ """
+ self._cdk_env = os.environ.copy()
+ self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH']
+ self._resource_mapping_file_path = file_path
+ self._region = region
+ self._feature_name = feature_name
+ self._account_id = account_id
+
+ assert os.path.exists(self._resource_mapping_file_path), \
+ f'Invalid resource mapping file path {self._resource_mapping_file_path}'
+ self._client = cloud_formation_client
+
+ def populate_output_keys(self, stacks=[]) -> None:
+ """
+ Calls describe stacks on cloud formation service and persists outputs to resource mappings file.
+ :param stacks List of stack arns to describe and populate resource mappings with.
+ """
+ for stack_name in stacks:
+ response = self._client.describe_stacks(
+ StackName=stack_name
+ )
+ stacks = response.get('Stacks', [])
+ assert len(stacks) == 1, f'{stack_name} is invalid.'
+
+ self.__write_resource_mappings(stacks[0].get('Outputs', []))
+
+ def __write_resource_mappings(self, outputs, append_feature_name = True) -> None:
+ with open(self._resource_mapping_file_path) as file_content:
+ resource_mappings = json.load(file_content)
+
+ resource_mappings[AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY] = self._account_id
+ resource_mappings[AWS_RESOURCE_MAPPINGS_REGION_KEY] = self._region
+
+ # Append new mappings.
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = resource_mappings.get(AWS_RESOURCE_MAPPINGS_KEY, {})
+
+ for output in outputs:
+ if append_feature_name:
+ resource_key = f'{self._feature_name}.{output.get("OutputKey", "InvalidKey")}'
+ else:
+ resource_key = output.get("OutputKey", "InvalidKey")
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key] = resource_mappings[
+ AWS_RESOURCE_MAPPINGS_KEY].get(resource_key, {})
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key]['Type'] = 'AutomationTestType'
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key]['Name/ID'] = output.get('OutputValue',
+ 'InvalidId')
+
+ with open(self._resource_mapping_file_path, 'w') as file_content:
+ json.dump(resource_mappings, file_content, indent=4)
+
+ def clear_output_keys(self) -> None:
+ """
+ Clears values of all resource mapping keys. Sets region to default to us-west-2
+ """
+ with open(self._resource_mapping_file_path) as file_content:
+ resource_mappings = json.load(file_content)
+
+ resource_mappings[AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY] = ''
+ resource_mappings[AWS_RESOURCE_MAPPINGS_REGION_KEY] = 'us-west-2'
+
+ # Append new mappings.
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = resource_mappings.get(AWS_RESOURCE_MAPPINGS_KEY, {})
+ resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = {}
+
+ with open(self._resource_mapping_file_path, 'w') as file_content:
+ json.dump(resource_mappings, file_content, indent=4)
+
+ self._resource_mapping_file_path = ''
+ self._region = ''
+ self._client = None
+
+
+@pytest.fixture(scope='function')
+def resource_mappings(
+ request: pytest.fixture,
+ project: str,
+ feature_name: str,
+ resource_mappings_filename: str,
+ workspace: pytest.fixture,
+ aws_utils: pytest.fixture) -> ResourceMappings:
+ """
+ Fixture for setting up resource mappings file.
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param project: Project to find resource mapping file.
+ :param feature_name: AWS Gem name that is prepended to resource mapping keys.
+ :param resource_mappings_filename: Name of resource mapping file.
+ :param workspace: ly_test_tools workspace fixture.
+ :param aws_utils: AWS utils fixture.
+ :return: ResourceMappings class object.
+ """
+
+ path = f'{workspace.paths.engine_root()}\\{project}\\Config\\{resource_mappings_filename}'
+ resource_mappings_obj = ResourceMappings(path, aws_utils.assume_session().region_name, feature_name,
+ aws_utils.assume_account_id(), workspace,
+ aws_utils.client('cloudformation'))
+
+ def teardown():
+ resource_mappings_obj.clear_output_keys()
+
+ request.addfinalizer(teardown)
+
+ return resource_mappings_obj
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/__init__.py
new file mode 100644
index 0000000000..8caef52682
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/__init__.py
@@ -0,0 +1,11 @@
+"""
+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.
+"""
+
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py
new file mode 100644
index 0000000000..7a15ba0abe
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py
@@ -0,0 +1,82 @@
+"""
+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 boto3
+import pytest
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+class AwsUtils:
+
+ def __init__(self, arn: str, session_name: str, region_name: str):
+ local_session = boto3.Session(profile_name='default')
+ local_sts_client = local_session.client('sts')
+ self._local_account_id = local_sts_client.get_caller_identity()["Account"]
+ logger.info(f'Local Account Id: {self._local_account_id}')
+
+ response = local_sts_client.assume_role(RoleArn=arn, RoleSessionName=session_name)
+
+ self._assume_session = boto3.Session(aws_access_key_id=response['Credentials']['AccessKeyId'],
+ aws_secret_access_key=response['Credentials']['SecretAccessKey'],
+ aws_session_token=response['Credentials']['SessionToken'],
+ region_name=region_name)
+
+ assume_sts_client = self._assume_session.client('sts')
+ assume_account_id = assume_sts_client.get_caller_identity()["Account"]
+ logger.info(f'Assume Account Id: {assume_account_id}')
+ self._assume_account_id = assume_account_id
+
+ def client(self, service: str):
+ """
+ Get the client for a specific AWS service from configured session
+ :return: Client for the AWS service.
+ """
+ return self._assume_session.client(service)
+
+ def assume_session(self):
+ return self._assume_session
+
+ def local_account_id(self):
+ return self._local_account_id
+
+ def assume_account_id(self):
+ return self._assume_account_id
+
+ def destroy(self) -> None:
+ """
+ clears stored session
+ """
+ self._assume_session = None
+
+
+@pytest.fixture(scope='function')
+def aws_utils(
+ request: pytest.fixture,
+ assume_role_arn: str,
+ session_name: str,
+ region_name: str):
+ """
+ Fixture for setting up a Cdk
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param assume_role_arn: Role used to fetch temporary aws credentials, configure service clients with obtained credentials.
+ :param session_name: Session name to set.
+ :param region_name: AWS account region to set for session.
+ :return AWSUtils class object.
+ """
+ aws_utils_obj = AwsUtils(assume_role_arn, session_name, region_name)
+
+ def teardown():
+ aws_utils_obj.destroy()
+
+ request.addfinalizer(teardown)
+
+ return aws_utils_obj
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index d6f9ecff4b..c6ed6c7538 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -56,5 +56,8 @@ add_subdirectory(editor)
## Streaming ##
add_subdirectory(streaming)
-## Streaming ##
+## Smoke ##
add_subdirectory(smoke)
+
+## AWS ##
+add_subdirectory(AWS)
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly b/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly
new file mode 100644
index 0000000000..af8a7f5c8e
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f0f4d4e0155feaa76c80a14128000a0fd9570ab76e79f4847eaef9006324a4d2
+size 9084
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas b/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas
new file mode 100644
index 0000000000..ef03c66b16
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas
@@ -0,0 +1,2313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml
new file mode 100644
index 0000000000..d4e3d33551
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml
@@ -0,0 +1 @@
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml
new file mode 100644
index 0000000000..d827d4da29
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml
@@ -0,0 +1 @@
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml b/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml
new file mode 100644
index 0000000000..f69a99fe37
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/level.pak b/AutomatedTesting/Levels/AWS/ClientAuth/level.pak
new file mode 100644
index 0000000000..1ae0bb1f7a
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/level.pak
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4900bdf28654e21032e69957f2762fa0a3b93a4b82163267a1f10f19f6d78692
+size 3795
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt b/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt
@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
diff --git a/AutomatedTesting/Registry/awscoreconfiguration.setreg b/AutomatedTesting/Registry/awscoreconfiguration.setreg
new file mode 100644
index 0000000000..ca110eb103
--- /dev/null
+++ b/AutomatedTesting/Registry/awscoreconfiguration.setreg
@@ -0,0 +1,10 @@
+{
+ "Amazon":
+ {
+ "AWSCore":
+ {
+ "ProfileName": "default",
+ "ResourceMappingConfigFileName": "aws_resource_mappings.json"
+ }
+ }
+}
\ No newline at end of file
From d5122b2829235a03c2d64b753a3b08cc089c1984 Mon Sep 17 00:00:00 2001
From: abrmich
Date: Fri, 14 May 2021 12:53:03 -0700
Subject: [PATCH 44/66] Add image builder processing bus
---
.../Atom/ImageProcessing/ImageProcessingBus.h | 41 ++++++++++
.../ImageProcessingEditorBus.h | 7 +-
.../Code/Source/ImageBuilderComponent.cpp | 78 +++++++++++++++++++
.../Code/Source/ImageBuilderComponent.h | 20 +++++
4 files changed, 145 insertions(+), 1 deletion(-)
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingBus.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingBus.h
index b8deb50cc5..9f6b6e629f 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingBus.h
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingBus.h
@@ -13,8 +13,14 @@
#pragma once
#include
+#include
#include
+namespace AssetBuilderSDK
+{
+ struct JobProduct;
+}
+
namespace ImageProcessingAtom
{
class ImageProcessingRequests
@@ -35,4 +41,39 @@ namespace ImageProcessingAtom
virtual IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) = 0;
};
using ImageProcessingRequestBus = AZ::EBus;
+
+ class ImageBuilderRequests
+ : public AZ::EBusTraits
+ {
+ public:
+ //////////////////////////////////////////////////////////////////////////
+ // EBusTraits overrides
+ static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
+ static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
+ /////////////////////////////////////////////////////////////////////////
+
+ //! Create an image object
+ virtual IImageObjectPtr CreateImage(
+ AZ::u32 width,
+ AZ::u32 height,
+ AZ::u32 maxMipCount,
+ EPixelFormat pixelFormat) = 0;
+
+ //! Convert an image and save its products to the specified folder
+ virtual AZStd::vector ConvertImageObject(
+ IImageObjectPtr imageObject,
+ const AZStd::string& presetName,
+ const AZStd::string& platformName,
+ const AZStd::string& outputDir,
+ const AZ::Data::AssetId& sourceAssetId,
+ const AZStd::string& sourceAssetName) = 0;
+
+ //! Return whether the specified platform is supported by the image builder
+ virtual bool DoesSupportPlatform(const AZStd::string& platformId) = 0;
+
+ //! Return whether the specified preset requires an image to be square and a power of 2
+ virtual bool IsPresetFormatSquarePow2(const AZStd::string& presetName, const AZStd::string& platformName) = 0;
+ };
+
+ using ImageBuilderRequestBus = AZ::EBus;
} // namespace ImageProcessingAtom
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h
index acd1d7a2da..5340b0d380 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h
@@ -13,10 +13,15 @@
#include
-class QString;
+namespace ImageProcessingAtom
+{
+ class IImageObject;
+}
namespace ImageProcessingAtomEditor
{
+ typedef AZStd::shared_ptr IImageObjectPtr;
+
class ImageProcessingEditorRequests
: public AZ::EBusTraits
{
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
index 59c799a601..a17c094fc7 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
@@ -88,11 +88,13 @@ namespace ImageProcessingAtom
m_assetHandlers.emplace_back(AZ::RPI::MakeAssetHandler());
ImageProcessingRequestBus::Handler::BusConnect();
+ ImageBuilderRequestBus::Handler::BusConnect();
}
void BuilderPluginComponent::Deactivate()
{
ImageProcessingRequestBus::Handler::BusDisconnect();
+ ImageBuilderRequestBus::Handler::BusDisconnect();
m_imageBuilder.BusDisconnect();
BuilderSettingManager::DestroyInstance();
CPixelFormats::DestroyInstance();
@@ -146,6 +148,82 @@ namespace ImageProcessingAtom
return image;
}
+ IImageObjectPtr BuilderPluginComponent::CreateImage(
+ AZ::u32 width,
+ AZ::u32 height,
+ AZ::u32 maxMipCount,
+ EPixelFormat pixelFormat)
+ {
+ IImageObjectPtr image(IImageObject::CreateImage(width, height, maxMipCount, pixelFormat));
+ return image;
+ }
+
+ AZStd::vector BuilderPluginComponent::ConvertImageObject(
+ IImageObjectPtr imageObject,
+ const AZStd::string& presetName,
+ const AZStd::string& platformName,
+ const AZStd::string& outputDir,
+ const AZ::Data::AssetId& sourceAssetId,
+ const AZStd::string& sourceAssetName)
+ {
+ AZStd::vector outProducts;
+
+ AZStd::string_view presetFilePath;
+ const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(presetName, platformName, &presetFilePath);
+ if (preset == nullptr)
+ {
+ AZ_Assert(false, "Cannot find preset with name %s.", presetName.c_str());
+ return outProducts;
+ }
+
+ AZStd::unique_ptr desc = AZStd::make_unique();
+ TextureSettings& textureSettings = desc->m_textureSetting;
+ textureSettings.m_preset = preset->m_uuid;
+ desc->m_inputImage = imageObject;
+ desc->m_presetSetting = *preset;
+ desc->m_isPreview = false;
+ desc->m_platform = platformName;
+ desc->m_filePath = presetFilePath;
+ desc->m_isStreaming = BuilderSettingManager::Instance()->GetBuilderSetting(platformName)->m_enableStreaming;
+ desc->m_imageName = sourceAssetName;
+ desc->m_outputFolder = outputDir;
+ desc->m_sourceAssetId = sourceAssetId;
+
+ // Create an image convert process
+ ImageConvertProcess* process = new ImageConvertProcess(AZStd::move(desc));
+ if (process)
+ {
+ process->ProcessAll();
+ bool result = process->IsSucceed();
+ if (result)
+ {
+ process->GetAppendOutputProducts(outProducts);
+ }
+ delete process;
+ }
+
+ return outProducts;
+ }
+
+ bool BuilderPluginComponent::DoesSupportPlatform(const AZStd::string& platformId)
+ {
+ return ImageProcessingAtom::BuilderSettingManager::Instance()->DoesSupportPlatform(platformId);
+ }
+
+ bool BuilderPluginComponent::IsPresetFormatSquarePow2(const AZStd::string& presetName, const AZStd::string& platformName)
+ {
+ AZStd::string_view filePath;
+ const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(presetName, platformName, &filePath);
+ if (preset == nullptr)
+ {
+ AZ_Assert(false, "Cannot find preset with name %s.", presetName.c_str());
+ return false;
+ }
+
+ const PixelFormatInfo* info = CPixelFormats::GetInstance().GetPixelFormatInfo(preset->m_pixelFormat);
+ return info->bSquarePow2;
+ }
+
void ImageBuilderWorker::ShutDown()
{
// it is important to note that this will be called on a different thread than your process job thread
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.h
index fd099eb08a..9723278380 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.h
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.h
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
namespace ImageProcessingAtom
{
@@ -47,6 +48,7 @@ namespace ImageProcessingAtom
class BuilderPluginComponent
: public AZ::Component
, protected ImageProcessingRequestBus::Handler
+ , protected ImageBuilderRequestBus::Handler
{
public:
AZ_COMPONENT(BuilderPluginComponent, "{A227F803-D2E4-406E-93EC-121EF45A64A1}")
@@ -71,6 +73,24 @@ namespace ImageProcessingAtom
IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) override;
////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////
+ // ImageBuilderRequestBus interface implementation
+ IImageObjectPtr CreateImage(
+ AZ::u32 width,
+ AZ::u32 height,
+ AZ::u32 maxMipCount,
+ EPixelFormat pixelFormat) override;
+ AZStd::vector ConvertImageObject(
+ IImageObjectPtr imageObject,
+ const AZStd::string& presetName,
+ const AZStd::string& platformName,
+ const AZStd::string& outputDir,
+ const AZ::Data::AssetId& sourceAssetId,
+ const AZStd::string& sourceAssetName) override;
+ bool DoesSupportPlatform(const AZStd::string& platformId) override;
+ bool IsPresetFormatSquarePow2(const AZStd::string& presetName, const AZStd::string& platformName) override;
+ ////////////////////////////////////////////////////////////////////////
+
private:
BuilderPluginComponent(const BuilderPluginComponent&) = delete;
From ded39be57ee8410bdc4a48b5e81065bd8e909133 Mon Sep 17 00:00:00 2001
From: Tommy Walton <82672795+amzn-tommy@users.noreply.github.com>
Date: Wed, 19 May 2021 11:21:44 -0700
Subject: [PATCH 45/66] Merging WrinkleMask support from 1.0 to main (#680)
Added a loop to the skin shader that will sample from wrinkle masks, multiply them by a weight, combine them, and use them instead of vertex colors for wrinkle map blending
Added an array of masks, an array of weights, and a wrinkle mask count to the DefaultObjectSrg. -Will create a follow up task to handle this a better way.
Removed motion vector (for now) from skin.materialtype since we're not using them, and removed depthtransparent since skin doesn't support transparency
Added an interface to the MeshFeatureProcessor to get the object srg
Wrapped srg->Compile in if(srg->IsQueuedForCompile()) to prevent compiling twice --This doesn't stop a race condition if both happen at the same time, but that is at least far less likely. It will need a better solution later.
Added a function to the MorphTargetExporter that will check to see if a texture that matches the blend shape name exists in a particular folder, and adds a reference to that image to the MorphTargetMetaAsset --Only supports .tif, and doesn't automatically re-process the .fbx if the folder is updated. These can be improved in later iterations
Added a null check in MaterialTypeSourceData.cpp to fix a crash I ran into
Added a for loop in two places to look for the first submesh that has a morph target, instead of just using the first to check if a lod has morph targets or not. --I have a better fix for this, but it involves more areas of the code, so I'm saving that for another change.
Modified AtomActorInstance to look for any morph targets that have a wrinkle mask reference
Then each frame, for any morph targets with non-zero weights that also have wrinkle masks, it updates the mask array, weights, and count on the object srg.
---
.../Common/Assets/Materials/Types/Skin.azsl | 53 ++++++----
.../Assets/Materials/Types/Skin.materialtype | 9 --
.../Atom/Features/PBR/DefaultObjectSrg.azsli | 10 ++
.../Atom/Feature/Mesh/MeshFeatureProcessor.h | 2 +
.../Mesh/MeshFeatureProcessorInterface.h | 8 ++
.../Code/Mocks/MockMeshFeatureProcessor.h | 2 +
.../Code/Source/Mesh/MeshFeatureProcessor.cpp | 13 +++
.../SkinnedMeshFeatureProcessor.cpp | 12 +--
.../SkinnedMesh/SkinnedMeshFeatureProcessor.h | 1 -
.../RPI.Reflect/Model/MorphTargetMetaAsset.h | 4 +
.../Model/MorphTargetExporter.cpp | 53 +++++++++-
.../RPI.Builders/Model/MorphTargetExporter.h | 6 +-
.../Material/MaterialTypeSourceData.cpp | 2 +-
.../Model/MorphTargetMetaAsset.cpp | 1 +
.../Code/Source/AtomActorInstance.cpp | 100 +++++++++++++++++-
.../Code/Source/AtomActorInstance.h | 15 +++
16 files changed, 247 insertions(+), 44 deletions(-)
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl
index 84095ac163..456d7cbabe 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.azsl
@@ -101,7 +101,7 @@ struct VSOutput
float2 m_uv[UvSetCount] : UV1;
float2 m_detailUv : UV3;
- float4 m_blendMask : UV8;
+ float4 m_wrinkleBlendFactors : UV8;
};
#include
@@ -132,11 +132,11 @@ VSOutput SkinVS(VSInput IN)
if(o_blendMask_isBound)
{
- OUT.m_blendMask = IN.m_optional_blendMask;
+ OUT.m_wrinkleBlendFactors = IN.m_optional_blendMask;
}
else
{
- OUT.m_blendMask = float4(0,1,0,0);
+ OUT.m_wrinkleBlendFactors = float4(0,0,0,0);
}
VertexHelper(IN, OUT, worldPosition, false);
@@ -214,7 +214,22 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
float2 normalUv = IN.m_uv[MaterialSrg::m_normalMapUvIndex];
float detailLayerNormalFactor = MaterialSrg::m_detail_normal_factor * detailLayerBlendFactor;
-
+
+ // ------- Wrinkle Map Setup -------
+
+ // Combine the optional per-morph target wrinkle masks
+ float4 wrinkleBlendFactors = float4(0.0, 0.0, 0.0, 0.0);
+ for(uint wrinkleMaskIndex = 0; wrinkleMaskIndex < ObjectSrg::m_wrinkle_mask_count; ++wrinkleMaskIndex)
+ {
+ wrinkleBlendFactors += ObjectSrg::m_wrinkle_masks[wrinkleMaskIndex].Sample(MaterialSrg::m_sampler, normalUv) * ObjectSrg::GetWrinkleMaskWeight(wrinkleMaskIndex);
+ }
+
+ // If texture based morph target driven masks are being used, use those values instead of the per-vertex colors
+ if(ObjectSrg::m_wrinkle_mask_count)
+ {
+ IN.m_wrinkleBlendFactors = saturate(wrinkleBlendFactors);
+ }
+
// Since the wrinkle normal maps should all be in the same tangent space as the main normal map, we should be able to blend the raw normal map
// texture values before doing all the tangent space transforms, so we only have to do the transforms once, for better performance.
@@ -223,12 +238,12 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
{
normalMapSample = SampleNormalXY(MaterialSrg::m_normalMap, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY);
}
- if(o_wrinkleLayers_enabled && o_blendMask_isBound && o_wrinkleLayers_normal_enabled)
+ if(o_wrinkleLayers_enabled && o_wrinkleLayers_normal_enabled)
{
- normalMapSample = ApplyNormalWrinkleMap(o_wrinkleLayers_normal_useTexture1, normalMapSample, MaterialSrg::m_wrinkle_normal_texture1, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, IN.m_blendMask.r);
- normalMapSample = ApplyNormalWrinkleMap(o_wrinkleLayers_normal_useTexture2, normalMapSample, MaterialSrg::m_wrinkle_normal_texture2, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, IN.m_blendMask.g);
- normalMapSample = ApplyNormalWrinkleMap(o_wrinkleLayers_normal_useTexture3, normalMapSample, MaterialSrg::m_wrinkle_normal_texture3, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, IN.m_blendMask.b);
- normalMapSample = ApplyNormalWrinkleMap(o_wrinkleLayers_normal_useTexture4, normalMapSample, MaterialSrg::m_wrinkle_normal_texture4, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, IN.m_blendMask.a);
+ normalMapSample = ApplyNormalWrinkleMap(o_wrinkleLayers_normal_useTexture1, normalMapSample, MaterialSrg::m_wrinkle_normal_texture1, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, IN.m_wrinkleBlendFactors.r);
+ normalMapSample = ApplyNormalWrinkleMap(o_wrinkleLayers_normal_useTexture2, normalMapSample, MaterialSrg::m_wrinkle_normal_texture2, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, IN.m_wrinkleBlendFactors.g);
+ normalMapSample = ApplyNormalWrinkleMap(o_wrinkleLayers_normal_useTexture3, normalMapSample, MaterialSrg::m_wrinkle_normal_texture3, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, IN.m_wrinkleBlendFactors.b);
+ normalMapSample = ApplyNormalWrinkleMap(o_wrinkleLayers_normal_useTexture4, normalMapSample, MaterialSrg::m_wrinkle_normal_texture4, MaterialSrg::m_sampler, normalUv, MaterialSrg::m_flipNormalX, MaterialSrg::m_flipNormalY, IN.m_wrinkleBlendFactors.a);
}
if(o_detail_normal_useTexture)
@@ -255,7 +270,7 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
float3 baseColor = GetBaseColorInput(MaterialSrg::m_baseColorMap, MaterialSrg::m_sampler, baseColorUv, MaterialSrg::m_baseColor, o_baseColor_useTexture);
bool useSampledBaseColor = o_baseColor_useTexture;
- if(o_wrinkleLayers_enabled && o_blendMask_isBound && o_wrinkleLayers_baseColor_enabled)
+ if(o_wrinkleLayers_enabled && o_wrinkleLayers_baseColor_enabled)
{
// If any of the wrinkle maps are applied, we will use the Base Color blend settings to apply the MaterialSrg::m_baseColor tint to the wrinkle maps,
// even if the main base color map is not used.
@@ -272,10 +287,10 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
baseColor = float3(1,1,1);
}
- baseColor = ApplyBaseColorWrinkleMap(o_wrinkleLayers_baseColor_useTexture1, baseColor, MaterialSrg::m_wrinkle_baseColor_texture1, MaterialSrg::m_sampler, baseColorUv, IN.m_blendMask.r);
- baseColor = ApplyBaseColorWrinkleMap(o_wrinkleLayers_baseColor_useTexture2, baseColor, MaterialSrg::m_wrinkle_baseColor_texture2, MaterialSrg::m_sampler, baseColorUv, IN.m_blendMask.g);
- baseColor = ApplyBaseColorWrinkleMap(o_wrinkleLayers_baseColor_useTexture3, baseColor, MaterialSrg::m_wrinkle_baseColor_texture3, MaterialSrg::m_sampler, baseColorUv, IN.m_blendMask.b);
- baseColor = ApplyBaseColorWrinkleMap(o_wrinkleLayers_baseColor_useTexture4, baseColor, MaterialSrg::m_wrinkle_baseColor_texture4, MaterialSrg::m_sampler, baseColorUv, IN.m_blendMask.a);
+ baseColor = ApplyBaseColorWrinkleMap(o_wrinkleLayers_baseColor_useTexture1, baseColor, MaterialSrg::m_wrinkle_baseColor_texture1, MaterialSrg::m_sampler, baseColorUv, IN.m_wrinkleBlendFactors.r);
+ baseColor = ApplyBaseColorWrinkleMap(o_wrinkleLayers_baseColor_useTexture2, baseColor, MaterialSrg::m_wrinkle_baseColor_texture2, MaterialSrg::m_sampler, baseColorUv, IN.m_wrinkleBlendFactors.g);
+ baseColor = ApplyBaseColorWrinkleMap(o_wrinkleLayers_baseColor_useTexture3, baseColor, MaterialSrg::m_wrinkle_baseColor_texture3, MaterialSrg::m_sampler, baseColorUv, IN.m_wrinkleBlendFactors.b);
+ baseColor = ApplyBaseColorWrinkleMap(o_wrinkleLayers_baseColor_useTexture4, baseColor, MaterialSrg::m_wrinkle_baseColor_texture4, MaterialSrg::m_sampler, baseColorUv, IN.m_wrinkleBlendFactors.a);
}
@@ -283,13 +298,13 @@ PbrLightingOutput SkinPS_Common(VSOutput IN)
baseColor = ApplyTextureOverlay(o_detail_baseColor_useTexture, baseColor, MaterialSrg::m_detail_baseColor_texture, MaterialSrg::m_sampler, IN.m_detailUv, detailLayerBaseColorFactor);
- if(o_wrinkleLayers_enabled && o_wrinkleLayers_showBlendMaskValues && o_blendMask_isBound)
+ if(o_wrinkleLayers_enabled && o_wrinkleLayers_showBlendMaskValues)
{
// Overlay debug colors to highlight the different blend weights coming from the vertex color stream.
- if(o_wrinkleLayers_count > 0) { baseColor = lerp(baseColor, float3(1,0,0), IN.m_blendMask.r); }
- if(o_wrinkleLayers_count > 1) { baseColor = lerp(baseColor, float3(0,1,0), IN.m_blendMask.g); }
- if(o_wrinkleLayers_count > 2) { baseColor = lerp(baseColor, float3(0,0,1), IN.m_blendMask.b); }
- if(o_wrinkleLayers_count > 3) { baseColor = lerp(baseColor, float3(1,1,1), IN.m_blendMask.a); }
+ if(o_wrinkleLayers_count > 0) { baseColor = lerp(baseColor, float3(1,0,0), IN.m_wrinkleBlendFactors.r); }
+ if(o_wrinkleLayers_count > 1) { baseColor = lerp(baseColor, float3(0,1,0), IN.m_wrinkleBlendFactors.g); }
+ if(o_wrinkleLayers_count > 2) { baseColor = lerp(baseColor, float3(0,0,1), IN.m_wrinkleBlendFactors.b); }
+ if(o_wrinkleLayers_count > 3) { baseColor = lerp(baseColor, float3(1,1,1), IN.m_wrinkleBlendFactors.a); }
}
// ------- Specular -------
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.materialtype
index b8951d69c7..101a03b907 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.materialtype
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/Skin.materialtype
@@ -987,15 +987,6 @@
{
"file": "Shaders/MotionVector/SkinnedMeshMotionVector.shader",
"tag": "SkinnedMeshMotionVector"
- },
- // Used by the light culling system to produce accurate depth bounds for this object when it uses blended transparency
- {
- "file": "Shaders/Depth/DepthPassTransparentMin.shader",
- "tag": "DepthPassTransparentMin"
- },
- {
- "file": "Shaders/Depth/DepthPassTransparentMax.shader",
- "tag": "DepthPassTransparentMax"
}
],
"functors": [
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli
index 50896cdf25..abc4ec7fc4 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/DefaultObjectSrg.azsli
@@ -31,6 +31,16 @@ ShaderResourceGroup ObjectSrg : SRG_PerObject
return SceneSrg::GetObjectToWorldInverseTransposeMatrix(m_objectId);
}
+ //[GFX TODO][ATOM-15280] Move wrinkle mask data from the default object srg into something specific to the Skin shader
+ uint m_wrinkle_mask_count;
+ float4 m_wrinkle_mask_weights[4];
+ Texture2D m_wrinkle_masks[16];
+
+ float GetWrinkleMaskWeight(uint index)
+ {
+ return m_wrinkle_mask_weights[index / 4][index % 4];
+ }
+
//! Reflection Probe (smallest probe volume that overlaps the object position)
struct ReflectionProbeData
{
diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h
index 7875e38fc0..0d61ef82d1 100644
--- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h
+++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessor.h
@@ -148,6 +148,8 @@ namespace AZ
Data::Instance GetModel(const MeshHandle& meshHandle) const override;
Data::Asset GetModelAsset(const MeshHandle& meshHandle) const override;
+ Data::Instance GetObjectSrg(const MeshHandle& meshHandle) const override;
+ void QueueObjectSrgForCompile(const MeshHandle& meshHandle) const override;
void SetMaterialAssignmentMap(const MeshHandle& meshHandle, const Data::Instance& material) override;
void SetMaterialAssignmentMap(const MeshHandle& meshHandle, const MaterialAssignmentMap& materials) override;
const MaterialAssignmentMap& GetMaterialAssignmentMap(const MeshHandle& meshHandle) const override;
diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h
index c2360068de..fb5bff5584 100644
--- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h
+++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Mesh/MeshFeatureProcessorInterface.h
@@ -61,6 +61,14 @@ namespace AZ
virtual Data::Instance GetModel(const MeshHandle& meshHandle) const = 0;
//! Gets the underlying RPI::ModelAsset for a meshHandle.
virtual Data::Asset GetModelAsset(const MeshHandle& meshHandle) const = 0;
+ //! Gets the ObjectSrg for a meshHandle.
+ //! Updating the ObjectSrg should be followed by a call to QueueObjectSrgForCompile,
+ //! instead of compiling the srg directly. This way, if the srg has already been queued for compile,
+ //! it will not be queued twice in the same frame. The ObjectSrg should not be updated during
+ //! Simulate, or it will create a race between updating the data and the call to Compile
+ virtual Data::Instance GetObjectSrg(const MeshHandle& meshHandle) const = 0;
+ //! Queues the object srg for compile.
+ virtual void QueueObjectSrgForCompile(const MeshHandle& meshHandle) const = 0;
//! Sets the MaterialAssignmentMap for a meshHandle, using just a single material for the DefaultMaterialAssignmentId.
//! Note if there is already a material assignment map, this will replace the entire map with just a single material.
virtual void SetMaterialAssignmentMap(const MeshHandle& meshHandle, const Data::Instance& material) = 0;
diff --git a/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h
index 39fd7b4380..418ee0cfb8 100644
--- a/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h
+++ b/Gems/Atom/Feature/Common/Code/Mocks/MockMeshFeatureProcessor.h
@@ -23,6 +23,8 @@ namespace UnitTest
MOCK_METHOD1(CloneMesh, MeshHandle(const MeshHandle&));
MOCK_CONST_METHOD1(GetModel, AZStd::intrusive_ptr(const MeshHandle&));
MOCK_CONST_METHOD1(GetModelAsset, AZ::Data::Asset(const MeshHandle&));
+ MOCK_CONST_METHOD1(GetObjectSrg, AZStd::intrusive_ptr(const MeshHandle&));
+ MOCK_CONST_METHOD1(QueueObjectSrgForCompile, void(const MeshHandle&));
MOCK_CONST_METHOD1(GetMaterialAssignmentMap, const AZ::Render::MaterialAssignmentMap&(const MeshHandle&));
MOCK_METHOD2(ConnectModelChangeEventHandler, void(const MeshHandle&, ModelChangedEvent::Handler&));
MOCK_METHOD3(SetTransform, void(const MeshHandle&, const AZ::Transform&, const AZ::Vector3&));
diff --git a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp
index 29f0636e9e..4059d65cbb 100644
--- a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp
@@ -231,6 +231,19 @@ namespace AZ
return {};
}
+ Data::Instance MeshFeatureProcessor::GetObjectSrg(const MeshHandle& meshHandle) const
+ {
+ return meshHandle.IsValid() ? meshHandle->m_shaderResourceGroup : nullptr;
+ }
+
+ void MeshFeatureProcessor::QueueObjectSrgForCompile(const MeshHandle& meshHandle) const
+ {
+ if (meshHandle.IsValid())
+ {
+ meshHandle->m_objectSrgNeedsUpdate = true;
+ }
+ }
+
void MeshFeatureProcessor::SetMaterialAssignmentMap(const MeshHandle& meshHandle, const Data::Instance& material)
{
Render::MaterialAssignmentMap materials;
diff --git a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshFeatureProcessor.cpp
index 388f4112a0..cb2d6a69ef 100644
--- a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshFeatureProcessor.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshFeatureProcessor.cpp
@@ -71,16 +71,6 @@ namespace AZ
}
- void SkinnedMeshFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
- {
- AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
- AZ_ATOM_PROFILE_FUNCTION("SkinnedMesh", "SkinnedMeshFeatureProcessor: Simulate");
- AZ_UNUSED(packet);
-
- SkinnedMeshFeatureProcessorNotificationBus::Broadcast(&SkinnedMeshFeatureProcessorNotificationBus::Events::OnUpdateSkinningMatrices);
-
- }
-
void SkinnedMeshFeatureProcessor::Render(const FeatureProcessor::RenderPacket& packet)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
@@ -268,6 +258,8 @@ namespace AZ
void SkinnedMeshFeatureProcessor::OnBeginPrepareRender()
{
m_renderProxiesChecker.soft_lock();
+
+ SkinnedMeshFeatureProcessorNotificationBus::Broadcast(&SkinnedMeshFeatureProcessorNotificationBus::Events::OnUpdateSkinningMatrices);
}
void SkinnedMeshFeatureProcessor::OnRenderEnd()
diff --git a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshFeatureProcessor.h
index bb3dd242a1..75d41742b2 100644
--- a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshFeatureProcessor.h
+++ b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshFeatureProcessor.h
@@ -49,7 +49,6 @@ namespace AZ
// FeatureProcessor overrides ...
void Activate() override;
void Deactivate() override;
- void Simulate(const FeatureProcessor::SimulatePacket& packet) override;
void Render(const FeatureProcessor::RenderPacket& packet) override;
void OnRenderEnd() override;
diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/MorphTargetMetaAsset.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/MorphTargetMetaAsset.h
index 5b92047226..4aa3faa6c9 100644
--- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/MorphTargetMetaAsset.h
+++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Model/MorphTargetMetaAsset.h
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
namespace AZ::RPI
{
@@ -56,6 +57,9 @@ namespace AZ::RPI
float m_minPositionDelta;
float m_maxPositionDelta;
+ //! Reference to the wrinkle mask, if it exists
+ AZ::Data::Asset m_wrinkleMask;
+
//! Boolean to indicate the presence or absence of color deltas
bool m_hasColorDeltas = false;
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp
index 7aace50760..3d0cbca8e6 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.cpp
@@ -18,6 +18,9 @@
#include
#include
+#include
+#include
+
namespace AZ::RPI
{
using namespace AZ::SceneAPI;
@@ -114,7 +117,7 @@ namespace AZ::RPI
meshNodeName, sourceMesh.m_name.GetCStr());
const DataTypes::MatrixType globalTransform = Utilities::BuildWorldTransform(sceneGraph, sceneNodeIndex);
- BuildMorphTargetMesh(vertexOffset, sourceMesh, productMesh, metaAssetCreator, blendShapeName, blendShapeData, globalTransform, coordSysConverter);
+ BuildMorphTargetMesh(vertexOffset, sourceMesh, productMesh, metaAssetCreator, blendShapeName, blendShapeData, globalTransform, coordSysConverter, scene.GetSourceFilename());
}
}
}
@@ -157,7 +160,8 @@ namespace AZ::RPI
const AZStd::string& blendShapeName,
const AZStd::shared_ptr& blendShapeData,
const DataTypes::MatrixType& globalTransform,
- const AZ::SceneAPI::CoordinateSystemConverter& coordSysConverter)
+ const AZ::SceneAPI::CoordinateSystemConverter& coordSysConverter,
+ const AZStd::string& sourceSceneFilename)
{
const float tolerance = CalcPositionDeltaTolerance(sourceMesh);
AZ::Aabb deltaPositionAabb = AZ::Aabb::CreateNull();
@@ -288,6 +292,8 @@ namespace AZ::RPI
metaData.m_maxPositionDelta = maxValue;
}
+ metaData.m_wrinkleMask = GetWrinkleMask(sourceSceneFilename, blendShapeName);
+
metaAssetCreator.AddMorphTarget(metaData);
AZ_Assert(uncompressedPositionDeltas.size() == compressedDeltas.size(), "Number of uncompressed (%d) and compressed position delta components (%d) do not match.",
@@ -312,4 +318,47 @@ namespace AZ::RPI
AZ_Assert((packedCompressedMorphTargetVertexData.size() - metaData.m_startIndex) == numMorphedVertices, "Vertex index range (%d) in morph target meta data does not match number of morphed vertices (%d).",
packedCompressedMorphTargetVertexData.size() - metaData.m_startIndex, numMorphedVertices);
}
+
+ Data::Asset MorphTargetExporter::GetWrinkleMask(const AZStd::string& sourceSceneFullFilePath, const AZStd::string& blendShapeName) const
+ {
+ AZ::Data::Asset imageAsset;
+
+ // See if there is a wrinkle map mask for this mesh
+ AZStd::string sceneRelativeFilePath;
+ bool relativePathFound = true;
+ AzToolsFramework::AssetSystemRequestBus::BroadcastResult(relativePathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetRelativeProductPathFromFullSourceOrProductPath, sourceSceneFullFilePath, sceneRelativeFilePath);
+
+ if (relativePathFound)
+ {
+ AZ::StringFunc::Path::StripFullName(sceneRelativeFilePath);
+
+ // Get the folder the masks are supposed to be in
+ AZStd::string folderName;
+ AZ::StringFunc::Path::GetFileName(sourceSceneFullFilePath.c_str(), folderName);
+ folderName += "_wrinklemasks";
+
+ // Note: for now, we're assuming the mask is always authored as a .tif
+ AZStd::string blendMaskFileName = blendShapeName + "_wrinklemask.tif.streamingimage";
+
+ AZStd::string maskFolderAndFile;
+ AZ::StringFunc::Path::Join(folderName.c_str(), blendMaskFileName.c_str(), maskFolderAndFile);
+
+ AZStd::string maskRelativePath;
+ AZ::StringFunc::Path::Join(sceneRelativeFilePath.c_str(), maskFolderAndFile.c_str(), maskRelativePath);
+ AZ::StringFunc::Path::Normalize(maskRelativePath);
+
+ // Now see if the file exists
+ AZ::Data::AssetId maskAssetId;
+ Data::AssetCatalogRequestBus::BroadcastResult(maskAssetId, &Data::AssetCatalogRequests::GetAssetIdByPath, maskRelativePath.c_str(), AZ::Data::s_invalidAssetType, false);
+
+ if (maskAssetId.IsValid())
+ {
+ // Flush asset manager events to ensure no asset references are held by closures queued on Ebuses.
+ AZ::Data::AssetManager::Instance().DispatchEvents();
+
+ imageAsset.Create(maskAssetId, AZ::Data::AssetLoadBehavior::PreLoad, false);
+ }
+ }
+ return imageAsset;
+ }
} // namespace AZ::RPI
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.h b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.h
index d968a803d6..4845d7d1da 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.h
+++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Model/MorphTargetExporter.h
@@ -64,7 +64,11 @@ namespace AZ
const AZStd::string& blendShapeName,
const AZStd::shared_ptr& blendShapeData,
const AZ::SceneAPI::DataTypes::MatrixType& globalTransform,
- const AZ::SceneAPI::CoordinateSystemConverter& coordSysConverter);
+ const AZ::SceneAPI::CoordinateSystemConverter& coordSysConverter,
+ const AZStd::string& sourceSceneFilename);
+
+ // Find a wrinkle mask for this morph target, if it exists
+ Data::Asset GetWrinkleMask(const AZStd::string& sourceSceneFullFilePath, const AZStd::string& blendShapeName) const;
};
} // namespace RPI
} // namespace AZ
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp
index 2ab6ee92e9..109af70166 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialTypeSourceData.cpp
@@ -422,7 +422,7 @@ namespace AZ
const MaterialPropertyDescriptor* propertyDescriptor = materialTypeAssetCreator.GetMaterialPropertiesLayout()->GetPropertyDescriptor(propertyIndex);
AZ::Name enumName = AZ::Name(property.m_value.GetValue());
- uint32_t enumValue = propertyDescriptor->GetEnumValue(enumName);
+ uint32_t enumValue = propertyDescriptor ? propertyDescriptor->GetEnumValue(enumName) : MaterialPropertyDescriptor::InvalidEnumValue;
if (enumValue == MaterialPropertyDescriptor::InvalidEnumValue)
{
materialTypeAssetCreator.ReportError("Enum value '%s' couldn't be found in the 'enumValues' list", enumName.GetCStr());
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/MorphTargetMetaAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/MorphTargetMetaAsset.cpp
index 313e0bea31..3c0f832807 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/MorphTargetMetaAsset.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Model/MorphTargetMetaAsset.cpp
@@ -28,6 +28,7 @@ namespace AZ::RPI
->Field("numVertices", &MorphTargetMetaAsset::MorphTarget::m_numVertices)
->Field("minPositionDelta", &MorphTargetMetaAsset::MorphTarget::m_minPositionDelta)
->Field("maxPositionDelta", &MorphTargetMetaAsset::MorphTarget::m_maxPositionDelta)
+ ->Field("wrinkleMask", &MorphTargetMetaAsset::MorphTarget::m_wrinkleMask)
->Field("hasColorDeltas", &MorphTargetMetaAsset::MorphTarget::m_hasColorDeltas)
;
}
diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp
index d0116452b7..9079f639ba 100644
--- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp
+++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp
@@ -28,6 +28,7 @@
#include
#include
+#include
#include
#include
@@ -39,6 +40,8 @@ namespace AZ
{
namespace Render
{
+ static constexpr uint32_t s_maxActiveWrinkleMasks = 16;
+
AZ_CLASS_ALLOCATOR_IMPL(AtomActorInstance, EMotionFX::Integration::EMotionFXAllocator, 0)
AtomActorInstance::AtomActorInstance(AZ::EntityId entityId,
@@ -413,6 +416,10 @@ namespace AZ
EMotionFX::MorphSetup* morphSetup = m_actorInstance->GetActor()->GetMorphSetup(lodIndex);
if (morphSetup)
{
+ // Track all the masks/weights that are currently active
+ m_wrinkleMasks.clear();
+ m_wrinkleMaskWeights.clear();
+
uint32_t morphTargetCount = morphSetup->GetNumMorphTargets();
m_morphTargetWeights.clear();
for (uint32_t morphTargetIndex = 0; morphTargetIndex < morphTargetCount; ++morphTargetIndex)
@@ -437,11 +444,28 @@ namespace AZ
const EMotionFX::MorphTargetStandard::DeformData* deformData = morphTargetStandard->GetDeformData(deformDataIndex);
if (deformData->mNumVerts > 0)
{
- m_morphTargetWeights.push_back(morphTargetSetupInstance->GetWeight());
+ float weight = morphTargetSetupInstance->GetWeight();
+ m_morphTargetWeights.push_back(weight);
+
+ // If the morph target is active and it has a wrinkle mask
+ auto wrinkleMaskIter = m_morphTargetWrinkleMaskMapsByLod[lodIndex].find(morphTargetStandard);
+ if (weight > 0 && wrinkleMaskIter != m_morphTargetWrinkleMaskMapsByLod[lodIndex].end())
+ {
+ // Add the wrinkle mask and weight, to be set on the material
+ m_wrinkleMasks.push_back(wrinkleMaskIter->second);
+ m_wrinkleMaskWeights.push_back(weight);
+ }
}
}
}
m_skinnedMeshRenderProxy->SetMorphTargetWeights(lodIndex, m_morphTargetWeights);
+
+ // Until EMotionFX and Atom lods are synchronized [ATOM-13564] we don't know which EMotionFX lod to pull the weights from
+ // Until that is fixed, just use lod 0 [ATOM-15251]
+ if (lodIndex == 0)
+ {
+ UpdateWrinkleMasks();
+ }
}
}
}
@@ -453,6 +477,8 @@ namespace AZ
MaterialComponentRequestBus::EventResult(materials, m_entityId, &MaterialComponentRequests::GetMaterialOverrides);
CreateRenderProxy(materials);
+ InitWrinkleMasks();
+
TransformNotificationBus::Handler::BusConnect(m_entityId);
MaterialComponentNotificationBus::Handler::BusConnect(m_entityId);
MeshComponentRequestBus::Handler::BusConnect(m_entityId);
@@ -573,5 +599,77 @@ namespace AZ
{
CreateSkinnedMeshInstance();
}
+
+ void AtomActorInstance::InitWrinkleMasks()
+ {
+ EMotionFX::Actor* actor = m_actorAsset->GetActor();
+ m_morphTargetWrinkleMaskMapsByLod.resize(m_skinnedMeshInputBuffers->GetLodCount());
+ m_wrinkleMasks.reserve(s_maxActiveWrinkleMasks);
+ m_wrinkleMaskWeights.reserve(s_maxActiveWrinkleMasks);
+
+ for (size_t lodIndex = 0; lodIndex < m_skinnedMeshInputBuffers->GetLodCount(); ++lodIndex)
+ {
+ EMotionFX::MorphSetup* morphSetup = actor->GetMorphSetup(lodIndex);
+ if (morphSetup)
+ {
+ const AZStd::vector& metaDatas = actor->GetMorphTargetMetaAsset()->GetMorphTargets();
+ // Loop over all the EMotionFX morph targets
+ uint32_t numMorphTargets = morphSetup->GetNumMorphTargets();
+ for (uint32_t morphTargetIndex = 0; morphTargetIndex < numMorphTargets; ++morphTargetIndex)
+ {
+ EMotionFX::MorphTargetStandard* morphTarget = static_cast(morphSetup->GetMorphTarget(morphTargetIndex));
+ for (const RPI::MorphTargetMetaAsset::MorphTarget& metaData : metaDatas)
+ {
+ // Find the metaData associated with this morph target
+ if (metaData.m_morphTargetName == morphTarget->GetNameString() && metaData.m_wrinkleMask && metaData.m_numVertices > 0)
+ {
+ // If the metaData has a wrinkle mask, add it to the map
+ Data::Instance streamingImage = RPI::StreamingImage::FindOrCreate(metaData.m_wrinkleMask);
+ if (streamingImage)
+ {
+ m_morphTargetWrinkleMaskMapsByLod[lodIndex][morphTarget] = streamingImage;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void AtomActorInstance::UpdateWrinkleMasks()
+ {
+ if (m_meshHandle)
+ {
+ Data::Instance wrinkleMaskObjectSrg = m_meshFeatureProcessor->GetObjectSrg(*m_meshHandle);
+ if (wrinkleMaskObjectSrg)
+ {
+ RHI::ShaderInputImageIndex wrinkleMasksIndex = wrinkleMaskObjectSrg->FindShaderInputImageIndex(Name{ "m_wrinkle_masks" });
+ RHI::ShaderInputConstantIndex wrinkleMaskWeightsIndex = wrinkleMaskObjectSrg->FindShaderInputConstantIndex(Name{ "m_wrinkle_mask_weights" });
+ RHI::ShaderInputConstantIndex wrinkleMaskCountIndex = wrinkleMaskObjectSrg->FindShaderInputConstantIndex(Name{ "m_wrinkle_mask_count" });
+ if (wrinkleMasksIndex.IsValid() || wrinkleMaskWeightsIndex.IsValid() || wrinkleMaskCountIndex.IsValid())
+ {
+ AZ_Error("AtomActorInstance", wrinkleMasksIndex.IsValid(), "m_wrinkle_masks not found on the ObjectSrg, but m_wrinkle_mask_weights and/or m_wrinkle_mask_count are being used.");
+ AZ_Error("AtomActorInstance", wrinkleMaskWeightsIndex.IsValid(), "m_wrinkle_mask_weights not found on the ObjectSrg, but m_wrinkle_masks and/or m_wrinkle_mask_count are being used.");
+ AZ_Error("AtomActorInstance", wrinkleMaskCountIndex.IsValid(), "m_wrinkle_mask_count not found on the ObjectSrg, but m_wrinkle_mask_weights and/or m_wrinkle_masks are being used.");
+
+ if (m_wrinkleMasks.size())
+ {
+ wrinkleMaskObjectSrg->SetImageArray(wrinkleMasksIndex, AZStd::array_view>(m_wrinkleMasks.data(), m_wrinkleMasks.size()));
+
+ // Set the weights for any active masks
+ for (size_t i = 0; i < m_wrinkleMaskWeights.size(); ++i)
+ {
+ wrinkleMaskObjectSrg->SetConstant(wrinkleMaskWeightsIndex, m_wrinkleMaskWeights[i], i);
+ }
+ AZ_Error("AtomActorInstance", m_wrinkleMaskWeights.size() <= s_maxActiveWrinkleMasks, "The skinning shader supports no more than %d active morph targets with wrinkle masks.", s_maxActiveWrinkleMasks);
+ }
+
+ wrinkleMaskObjectSrg->SetConstant(wrinkleMaskCountIndex, aznumeric_cast(m_wrinkleMasks.size()));
+ m_meshFeatureProcessor->QueueObjectSrgForCompile(*m_meshHandle);
+ }
+ }
+ }
+ }
+
} //namespace Render
} // namespace AZ
diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h
index 1002fcbde1..e05280e896 100644
--- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h
+++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h
@@ -17,6 +17,7 @@
#include
#include
+#include
#include
@@ -29,6 +30,8 @@
#include
#include
#include
+#include
+
#include
#include
@@ -41,6 +44,7 @@ namespace AZ::RPI
{
class Model;
class Buffer;
+ class StreamingImage;
}
namespace AZ
@@ -168,6 +172,11 @@ namespace AZ
// SkinnedMeshOutputStreamNotificationBus
void OnSkinnedMeshOutputStreamMemoryAvailable() override;
+ // Check to see if the skin material is being used,
+ // and if there are blend shapes with wrinkle masks that should be applied to it
+ void InitWrinkleMasks();
+ void UpdateWrinkleMasks();
+
AZStd::intrusive_ptr m_skinnedMeshInputBuffers = nullptr;
AZStd::intrusive_ptr m_skinnedMeshInstance;
AZ::Data::Instance m_boneTransforms = nullptr;
@@ -179,6 +188,12 @@ namespace AZ
AZ::TransformInterface* m_transformInterface = nullptr;
AZStd::set m_waitForMaterialLoadIds;
AZStd::vector m_morphTargetWeights;
+
+ typedef AZStd::unordered_map> MorphTargetWrinkleMaskMap;
+ AZStd::vector m_morphTargetWrinkleMaskMapsByLod;
+
+ AZStd::vector> m_wrinkleMasks;
+ AZStd::vector m_wrinkleMaskWeights;
};
} // namespace Render
From 1127235715f15ec981c22cb6d3a3ee1d6813c726 Mon Sep 17 00:00:00 2001
From: abrmich
Date: Wed, 19 May 2021 11:36:44 -0700
Subject: [PATCH 46/66] Remove unnecessary heap allocation
---
.../Code/Source/ImageBuilderComponent.cpp | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
index a17c094fc7..34d18a26eb 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp
@@ -190,16 +190,12 @@ namespace ImageProcessingAtom
desc->m_sourceAssetId = sourceAssetId;
// Create an image convert process
- ImageConvertProcess* process = new ImageConvertProcess(AZStd::move(desc));
- if (process)
+ ImageConvertProcess process(AZStd::move(desc));
+ process.ProcessAll();
+ bool result = process.IsSucceed();
+ if (result)
{
- process->ProcessAll();
- bool result = process->IsSucceed();
- if (result)
- {
- process->GetAppendOutputProducts(outProducts);
- }
- delete process;
+ process.GetAppendOutputProducts(outProducts);
}
return outProducts;
From bd74835f30eff9c705152f3f9f31ea7b346135d9 Mon Sep 17 00:00:00 2001
From: abrmich
Date: Wed, 19 May 2021 11:46:02 -0700
Subject: [PATCH 47/66] Remove leftover code that's no longer needed
---
.../Atom/ImageProcessing/ImageProcessingEditorBus.h | 7 -------
.../Code/Source/ImageBuilderComponent.h | 1 -
2 files changed, 8 deletions(-)
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h
index 5340b0d380..bf5289bc45 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h
+++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h
@@ -13,15 +13,8 @@
#include
-namespace ImageProcessingAtom
-{
- class IImageObject;
-}
-
namespace ImageProcessingAtomEditor
{
- typedef AZStd::shared_ptr