Refactored how model material slots work in preparation to support more flexible material conversion options for the scene asset pipeline. The material slot IDs are based on the MaterialUid that come from SceneAPI. Since these IDs are also used as the AssetId sub-ID for the converted material assets, the system was just checking the material asset sub-ID to determine the material slot ID. But in order to support certain FBX material conversion options, we needed to break this tie, so the slot ID is separate from the AssetId of the material in that slot. This will allow some other material to be used in the slot, instead of being forced to use one that was generated from the FBX.

Here we inttroduce a new struct ModelMaterialSlot which formalizes the concept of material slot, with an ID, display name, and default material assignment. The ID still comes from the MaterialUid like before. The display name is built-in, rather than being parsed out from the asset file name. And the default material assignment can be any material asset, it doesn't have to come from the FBX (or other scene file).

This commit is just the preliminary set of changes. Cursory testing shows that it works pretty well but more testing is needed (and likely some fixes) before merging.

Here is what's left to do...
Add serialization version converters to preserve prior prefab data.
See if we can get rid of GetLabelByAssetId function only rely on the display name inside ModelMaterialSlot.
I'm not sure if the condition for enabling the "Edit Material Instance..." context menu item is correct.
Test actors
Lots more testing in general

Signed-off-by: santorac <55155825+santorac@users.noreply.github.com>
This commit is contained in:
Chris Santora
2021-07-17 00:07:23 -07:00
committed by santorac
parent 0cf6ecf3f7
commit 14d2e38b90
31 changed files with 399 additions and 195 deletions
@@ -20,7 +20,7 @@
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QMenu>
#include <QAction>
#include <QAction>
#include <QCursor>
AZ_POP_DISABLE_WARNING
@@ -48,7 +48,7 @@ namespace AZ
return false;
}
const MaterialAssignmentId newId(oldId.first, oldId.second);
const MaterialAssignmentId newId(oldId.first, oldId.second.m_subId);
classElement.AddElementWithData(context, "id", newId);
}
@@ -83,6 +83,7 @@ namespace AZ
->Version(5, &EditorMaterialComponentSlot::ConvertVersion)
->Field("id", &EditorMaterialComponentSlot::m_id)
->Field("materialAsset", &EditorMaterialComponentSlot::m_materialAsset)
->Field("defaultMaterialAsset", &EditorMaterialComponentSlot::m_defaultMaterialAsset)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
@@ -121,21 +122,12 @@ namespace AZ
AZ::Data::AssetId EditorMaterialComponentSlot::GetDefaultAssetId() const
{
return m_id.m_materialAssetId;
return m_defaultMaterialAsset.GetId();
}
AZStd::string EditorMaterialComponentSlot::GetLabel() const
{
// Generate the label for the material slot based on the assignment ID
// If this is the default material assignment ID then it represents the default slot which is not contained in any other group
if (m_id == DefaultMaterialAssignmentId)
{
return "Default Material";
}
// Otherwise the label can be generated by parsing the source file name associated with the asset ID
const AZStd::string& label = EditorMaterialComponentExporter::GetLabelByAssetId(m_id.m_materialAssetId);
return !label.empty() ? label : "<unknown>";
return m_label;
}
bool EditorMaterialComponentSlot::HasSourceData() const
@@ -183,27 +175,22 @@ namespace AZ
OnMaterialChanged();
}
void EditorMaterialComponentSlot::SetDefaultAsset()
void EditorMaterialComponentSlot::ResetToDefaultAsset()
{
m_materialAsset = {};
m_materialAsset = m_defaultMaterialAsset;
m_propertyOverrides = {};
m_matModUvOverrides = {};
if (m_id.m_materialAssetId.IsValid())
{
// If no material is assigned to this slot, assign the default material from the slot id to edit its properties
m_materialAsset.Create(m_id.m_materialAssetId);
}
OnMaterialChanged();
}
void EditorMaterialComponentSlot::OpenMaterialExporter()
{
// Because we are generating a source material from this specific slot there is only one entry
// But we still need to allow the user to reconfigure it using the dialogue
// But we still need to allow the user to reconfigure it using the dialog
EditorMaterialComponentExporter::ExportItemsContainer exportItems;
{
EditorMaterialComponentExporter::ExportItem exportItem;
exportItem.m_assetId = m_id.m_materialAssetId;
exportItem.m_originalAssetId = m_defaultMaterialAsset.GetId();
exportItems.push_back(exportItem);
}
@@ -275,7 +262,7 @@ namespace AZ
QAction* action = nullptr;
action = menu.addAction("Generate/Manage Source Material...", [this]() { OpenMaterialExporter(); });
action->setEnabled(m_id.m_materialAssetId.IsValid());
action->setEnabled(m_defaultMaterialAsset.GetId().IsValid());
menu.addSeparator();