Tied up a few loose ends to support deeply nested property groups.

Simplified the call back for MaterialTypeSourceData::EnumeratePropertyGroups while also providing more data.
Made the Material Inspector join nested property group display names to be like "Layer 1 | Base Color", since the leaf property groups are shown as a flat list in the inspector.
Fixed CreateMaterialAssetFromSourceData to include the imported json files in the list of sourceDependencies. This triggers the Material Editor to hot-reload when one of these json files changes.
Updated a few places that were still assuming only one level of property group.
Updated EditorMaterialComponentInspector to apply the per-property-group material functors, before it was still only applying the top-level onces.
Moved some accessor function implementations to the cpp files, per feedback on another already-merged PR.

Testing:
Made changes to MinimalMultilayerPbr (in AtomSampleViewer) to use nested property groups, and saw the correct behavior in the Material Editor's property inspector.
Used MaterialComponent's property inspector to edit a StandardPbr material instance. Confrimed that functors were correctly controlling property visibility by enabling and disabling things like emissive and clear coat.
Used MaterialComponent's property inspector to edit a MinimalMultilayerPbr material instance. Saw all the expected groups and properties show up. Confirmed that per-group functors were correctly controlling property visibility.
Used MaterialComponent's property inspector to export a material instance and confirmed the .material file included the expected properties.

Signed-off-by: santorac <55155825+santorac@users.noreply.github.com>
This commit is contained in:
santorac
2022-02-09 13:13:40 -08:00
parent 2a3c5b38e5
commit 8fbd2aaaf5
9 changed files with 241 additions and 112 deletions
@@ -354,9 +354,7 @@ namespace MaterialEditor
return false;
}
// TODO: Support populating the Material Editor with nested property groups, not just the top level.
AZStd::string_view groupName = propertyId.GetStringView().substr(0, propertyId.GetStringView().size() - propertyDefinition->GetName().size() - 1);
sourceData.SetPropertyValue(AZ::RPI::MaterialPropertyId{groupName, propertyDefinition->GetName()}, propertyValue);
sourceData.SetPropertyValue(propertyId, propertyValue);
}
}
return true;
@@ -553,27 +551,38 @@ namespace MaterialEditor
// Assets must still be used for now because they contain the final accumulated value after all other materials
// in the hierarchy are applied
bool enumerateResult = m_materialTypeSourceData.EnumeratePropertyGroups(
[this, &parentPropertyValues](
const AZ::RPI::MaterialTypeSourceData::PropertyGroup* propertyGroup,
const AZ::RPI::MaterialNameContext& groupNameContext,
const AZ::RPI::MaterialNameContext& parentNameContext)
[this, &parentPropertyValues](const AZ::RPI::MaterialTypeSourceData::PropertyGroupStack& propertyGroupStack)
{
// Add any material functors that are located inside each property group.
using namespace AZ::RPI;
const MaterialTypeSourceData::PropertyGroup* propertyGroup = propertyGroupStack.back();
MaterialNameContext groupNameContext = MaterialTypeSourceData::MakeMaterialNameContext(propertyGroupStack);
if (!AddEditorMaterialFunctors(propertyGroup->GetFunctors(), groupNameContext))
{
return false;
}
AZStd::vector<AZStd::string> groupNameVector;
AZStd::vector<AZStd::string> groupDisplayNameVector;
for (auto& group : propertyGroupStack)
{
groupNameVector.push_back(group->GetName());
groupDisplayNameVector.push_back(group->GetDisplayName());
}
m_groups.emplace_back(aznew AtomToolsFramework::DynamicPropertyGroup);
m_groups.back()->m_name = propertyGroup->GetName();
parentNameContext.ContextualizeProperty(m_groups.back()->m_name);
m_groups.back()->m_displayName = propertyGroup->GetDisplayName();
m_groups.back()->m_description = propertyGroup->GetDescription();
AzFramework::StringFunc::Join(m_groups.back()->m_name, groupNameVector.begin(), groupNameVector.end(), ".");
AzFramework::StringFunc::Join(m_groups.back()->m_displayName, groupDisplayNameVector.begin(), groupDisplayNameVector.end(), " | ");
for (const auto& propertyDefinition : propertyGroup->GetProperties())
{
// Assign id before conversion so it can be used in dynamic description
AtomToolsFramework::DynamicPropertyConfig propertyConfig;
// Assign id before conversion so it can be used in dynamic description
propertyConfig.m_id = propertyDefinition->GetName();
groupNameContext.ContextualizeProperty(propertyConfig.m_id);
@@ -587,9 +596,8 @@ namespace MaterialEditor
if (propertyIndexInBounds)
{
AtomToolsFramework::ConvertToPropertyConfig(propertyConfig, *propertyDefinition);
// TODO: Support populating the Material Editor with nested property groups, not just the top level.
// (Does DynamicPropertyConfig really even need m_groupDisplayName?)
// (Does DynamicPropertyConfig really even need m_groupName? It doesn't seem to be used anywhere)
propertyConfig.m_groupName = m_groups.back()->m_name;
propertyConfig.m_groupDisplayName = m_groups.back()->m_displayName;
propertyConfig.m_showThumbnail = true;