Material Component: Can set material property overrides on default materials

No longer need to assign material overrides to set/edit properties in UI or script
Material component will load and use the default material for a slot if no override is assigned

Signed-off-by: Guthrie Adams <guthadam@amazon.com>
This commit is contained in:
Guthrie Adams
2021-09-23 22:58:39 -05:00
parent 1050f95601
commit ebcf3723f9
9 changed files with 162 additions and 46 deletions
@@ -110,12 +110,14 @@ namespace AZ
m_queuedMaterialUpdateNotification = false;
MaterialComponentRequestBus::Handler::BusConnect(m_entityId);
MaterialReceiverNotificationBus::Handler::BusConnect(m_entityId);
LoadMaterials();
}
void MaterialComponentController::Deactivate()
{
MaterialComponentRequestBus::Handler::BusDisconnect();
MaterialReceiverNotificationBus::Handler::BusDisconnect();
TickBus::Handler::BusDisconnect();
ReleaseMaterials();
@@ -214,13 +216,29 @@ namespace AZ
bool anyQueued = false;
for (auto& materialPair : m_configuration.m_materials)
{
auto& materialAsset = materialPair.second.m_materialAsset;
if (materialPair.second.m_materialInstancePreCreated)
{
continue;
}
if (materialAsset.GetId().IsValid() && !Data::AssetBus::MultiHandler::BusIsConnectedId(materialAsset.GetId()))
if (materialPair.second.m_materialAsset.GetId().IsValid() &&
!Data::AssetBus::MultiHandler::BusIsConnectedId(materialPair.second.m_materialAsset.GetId()))
{
anyQueued = true;
materialAsset.QueueLoad();
Data::AssetBus::MultiHandler::BusConnect(materialAsset.GetId());
materialPair.second.m_materialAsset.QueueLoad();
Data::AssetBus::MultiHandler::BusConnect(materialPair.second.m_materialAsset.GetId());
continue;
}
materialPair.second.m_defaultMaterialAsset = AZ::Data::Asset<AZ::RPI::MaterialAsset>(
GetDefaultMaterialAssetId(materialPair.first), AZ::AzTypeInfo<AZ::RPI::MaterialAsset>::Uuid());
if (materialPair.second.m_defaultMaterialAsset.GetId().IsValid() &&
!Data::AssetBus::MultiHandler::BusIsConnectedId(materialPair.second.m_defaultMaterialAsset.GetId()))
{
anyQueued = true;
materialPair.second.m_defaultMaterialAsset.QueueLoad();
Data::AssetBus::MultiHandler::BusConnect(materialPair.second.m_defaultMaterialAsset.GetId());
}
}
@@ -236,13 +254,22 @@ namespace AZ
for (auto& materialPair : m_configuration.m_materials)
{
auto& materialAsset = materialPair.second.m_materialAsset;
if (materialAsset.GetId() == asset.GetId())
if (materialPair.second.m_materialAsset.GetId() == asset.GetId())
{
materialAsset = asset;
materialPair.second.m_materialAsset = asset;
}
if (materialAsset.GetId().IsValid() && !materialAsset.IsReady())
if (materialPair.second.m_materialAsset.GetId().IsValid() && !materialPair.second.m_materialAsset.IsReady())
{
allReady = false;
}
if (materialPair.second.m_defaultMaterialAsset.GetId() == asset.GetId())
{
materialPair.second.m_defaultMaterialAsset = asset;
}
if (materialPair.second.m_defaultMaterialAsset.GetId().IsValid() && !materialPair.second.m_defaultMaterialAsset.IsReady())
{
allReady = false;
}
@@ -268,11 +295,7 @@ namespace AZ
for (auto& materialPair : m_configuration.m_materials)
{
if (materialPair.second.m_materialAsset.GetId().IsValid())
{
materialPair.second.m_materialAsset.Release();
materialPair.second.m_materialInstance = nullptr;
}
materialPair.second.Release();
}
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialsUpdated, m_configuration.m_materials);
@@ -459,18 +482,21 @@ namespace AZ
void MaterialComponentController::SetPropertyOverride(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZStd::any& value)
{
auto& materialAssignment = m_configuration.m_materials[materialAssignmentId];
const bool wasEmpty = materialAssignment.m_propertyOverrides.empty();
materialAssignment.m_propertyOverrides[AZ::Name(propertyName)] = value;
// When applying property overrides for the first time, new instance needs to be created in case the current instance is already used somewhere else to keep overrides local
if (materialAssignment.m_propertyOverrides.empty())
if (materialAssignment.RequiresLoading())
{
materialAssignment.m_propertyOverrides[AZ::Name(propertyName)] = value;
materialAssignment.RebuildInstance();
MaterialComponentNotificationBus::Event(m_entityId, &MaterialComponentNotifications::OnMaterialInstanceCreated, materialAssignment);
QueueMaterialUpdateNotification();
LoadMaterials();
return;
}
else
if (wasEmpty != materialAssignment.m_propertyOverrides.empty())
{
materialAssignment.m_propertyOverrides[AZ::Name(propertyName)] = value;
materialAssignment.RebuildInstance();
MaterialComponentNotificationBus::Event(
m_entityId, &MaterialComponentNotifications::OnMaterialInstanceCreated, materialAssignment);
QueueMaterialUpdateNotification();
}
QueuePropertyChanges(materialAssignmentId);
@@ -703,6 +729,12 @@ namespace AZ
const bool wasEmpty = materialAssignment.m_propertyOverrides.empty();
materialAssignment.m_propertyOverrides = propertyOverrides;
if (materialAssignment.RequiresLoading())
{
LoadMaterials();
return;
}
if (wasEmpty != materialAssignment.m_propertyOverrides.empty())
{
materialAssignment.RebuildInstance();
@@ -712,14 +744,11 @@ namespace AZ
QueuePropertyChanges(materialAssignmentId);
}
MaterialPropertyOverrideMap MaterialComponentController::GetPropertyOverrides(const MaterialAssignmentId& materialAssignmentId) const
MaterialPropertyOverrideMap MaterialComponentController::GetPropertyOverrides(
const MaterialAssignmentId& materialAssignmentId) const
{
const auto materialIt = m_configuration.m_materials.find(materialAssignmentId);
if (materialIt == m_configuration.m_materials.end())
{
return {};
}
return materialIt->second.m_propertyOverrides;
return materialIt != m_configuration.m_materials.end() ? materialIt->second.m_propertyOverrides : MaterialPropertyOverrideMap();
}
void MaterialComponentController::SetModelUvOverrides(
@@ -729,6 +758,12 @@ namespace AZ
const bool wasEmpty = materialAssignment.m_matModUvOverrides.empty();
materialAssignment.m_matModUvOverrides = modelUvOverrides;
if (materialAssignment.RequiresLoading())
{
LoadMaterials();
return;
}
if (wasEmpty != materialAssignment.m_matModUvOverrides.empty())
{
materialAssignment.RebuildInstance();
@@ -742,11 +777,19 @@ namespace AZ
const MaterialAssignmentId& materialAssignmentId) const
{
const auto materialIt = m_configuration.m_materials.find(materialAssignmentId);
if (materialIt == m_configuration.m_materials.end())
return materialIt != m_configuration.m_materials.end() ? materialIt->second.m_matModUvOverrides : AZ::RPI::MaterialModelUvOverrideMap();
}
void MaterialComponentController::OnMaterialAssignmentsChanged()
{
for (const auto& materialPair : m_configuration.m_materials)
{
return {};
if (materialPair.second.RequiresLoading())
{
LoadMaterials();
return;
}
}
return materialIt->second.m_matModUvOverrides;
}
void MaterialComponentController::QueuePropertyChanges(const MaterialAssignmentId& materialAssignmentId)