merging dev
Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com>
This commit is contained in:
@@ -47,7 +47,7 @@ namespace AZ
|
||||
{
|
||||
AssetBuilderSDK::AssetBuilderDesc materialBuilderDescriptor;
|
||||
materialBuilderDescriptor.m_name = JobKey;
|
||||
materialBuilderDescriptor.m_version = 109; // Changed "id" to "name" in serialization
|
||||
materialBuilderDescriptor.m_version = 110; // Material version auto update feature
|
||||
materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.material", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
|
||||
materialBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.materialtype", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
|
||||
materialBuilderDescriptor.m_busId = azrtti_typeid<MaterialBuilder>();
|
||||
@@ -287,6 +287,11 @@ namespace AZ
|
||||
return {};
|
||||
}
|
||||
|
||||
if (MaterialSourceData::ApplyVersionUpdatesResult::Failed == material.GetValue().ApplyVersionUpdates(materialSourceFilePath))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto materialAssetOutcome = material.GetValue().CreateMaterialAsset(Uuid::CreateRandom(), materialSourceFilePath, true);
|
||||
if (!materialAssetOutcome.IsSuccess())
|
||||
{
|
||||
|
||||
@@ -62,6 +62,8 @@ namespace AZ
|
||||
return context.Report(JsonSerializationResult::Tasks::ReadField, JsonSerializationResult::Outcomes::Catastrophic, "Material type reference not found.");
|
||||
}
|
||||
|
||||
const JsonMaterialPropertyValueSerializer::LoadContext* loadContext = context.GetMetadata().Find<JsonMaterialPropertyValueSerializer::LoadContext>();
|
||||
|
||||
// Construct the full property name (groupName.propertyName) by parsing it from the JSON path string.
|
||||
size_t startPropertyName = context.GetPath().Get().rfind('/');
|
||||
size_t startGroupName = context.GetPath().Get().rfind('/', startPropertyName-1);
|
||||
@@ -70,7 +72,7 @@ namespace AZ
|
||||
|
||||
JSR::ResultCode result(JSR::Tasks::ReadField);
|
||||
|
||||
auto propertyDefinition = materialType->FindProperty(groupName, propertyName);
|
||||
auto propertyDefinition = materialType->FindProperty(groupName, propertyName, loadContext->m_materialTypeVersion);
|
||||
if (!propertyDefinition)
|
||||
{
|
||||
AZStd::string message = AZStd::string::format("Property '%.*s.%.*s' not found in material type.", AZ_STRING_ARG(groupName), AZ_STRING_ARG(propertyName));
|
||||
|
||||
@@ -72,6 +72,62 @@ namespace AZ
|
||||
materialAssetCreator.SetPropertyValue(propertyId, entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
MaterialSourceData::ApplyVersionUpdatesResult MaterialSourceData::ApplyVersionUpdates(AZStd::string_view materialSourceFilePath)
|
||||
{
|
||||
AZStd::string materialTypeFullPath = AssetUtils::ResolvePathReference(materialSourceFilePath, m_materialType);
|
||||
auto materialTypeSourceDataOutcome = MaterialUtils::LoadMaterialTypeSourceData(materialTypeFullPath);
|
||||
if (!materialTypeSourceDataOutcome.IsSuccess())
|
||||
{
|
||||
return ApplyVersionUpdatesResult::Failed;
|
||||
}
|
||||
|
||||
MaterialTypeSourceData materialTypeSourceData = materialTypeSourceDataOutcome.TakeValue();
|
||||
|
||||
if (m_materialTypeVersion == materialTypeSourceData.m_version)
|
||||
{
|
||||
return ApplyVersionUpdatesResult::NoUpdates;
|
||||
}
|
||||
|
||||
bool changesWereApplied = false;
|
||||
|
||||
// Note that the only kind of property update currently supported is rename...
|
||||
|
||||
for (auto& groupPair : m_properties)
|
||||
{
|
||||
PropertyMap& propertyMap = groupPair.second;
|
||||
|
||||
PropertyMap newPropertyMap;
|
||||
|
||||
for (auto& propertyPair : propertyMap)
|
||||
{
|
||||
MaterialPropertyId propertyId{groupPair.first, propertyPair.first};
|
||||
if (materialTypeSourceData.ApplyPropertyRenames(propertyId, m_materialTypeVersion))
|
||||
{
|
||||
newPropertyMap[propertyId.GetPropertyName().GetStringView()] = propertyPair.second;
|
||||
changesWereApplied = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
newPropertyMap[propertyPair.first] = propertyPair.second;
|
||||
}
|
||||
}
|
||||
|
||||
propertyMap = newPropertyMap;
|
||||
}
|
||||
|
||||
if (changesWereApplied)
|
||||
{
|
||||
AZ_Warning("MaterialSourceData", false,
|
||||
"This material is based on version '%u' of '%s', but the material type is now at version '%u'. "
|
||||
"Automatic updates are available. Consider updating the .material source file.",
|
||||
m_materialTypeVersion, m_materialType.c_str(), materialTypeSourceData.m_version);
|
||||
}
|
||||
|
||||
m_materialTypeVersion = materialTypeSourceData.m_version;
|
||||
|
||||
return changesWereApplied ? ApplyVersionUpdatesResult::UpdatesApplied : ApplyVersionUpdatesResult::NoUpdates;
|
||||
}
|
||||
|
||||
Outcome<Data::Asset<MaterialAsset> > MaterialSourceData::CreateMaterialAsset(Data::AssetId assetId, AZStd::string_view materialSourceFilePath, bool elevateWarnings, bool includeMaterialPropertyNames) const
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <Atom/RPI.Edit/Material/MaterialSourceDataSerializer.h>
|
||||
#include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
|
||||
#include <Atom/RPI.Edit/Material/MaterialPropertyValueSerializer.h>
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <Atom/RPI.Edit/Common/JsonFileLoadContext.h>
|
||||
#include <Atom/RPI.Edit/Common/JsonUtils.h>
|
||||
@@ -45,9 +46,9 @@ namespace AZ
|
||||
}
|
||||
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_description, azrtti_typeid<AZStd::string>(), inputValue, "description", context));
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_materialType, azrtti_typeid<AZStd::string>(), inputValue, "materialType", context));
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_parentMaterial, azrtti_typeid<AZStd::string>(), inputValue, "parentMaterial", context));
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_propertyLayoutVersion, azrtti_typeid<uint32_t>(), inputValue, "propertyLayoutVersion", context));
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_materialType, azrtti_typeid<AZStd::string>(), inputValue, "materialType", context));
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_materialTypeVersion, azrtti_typeid<uint32_t>(), inputValue, "materialTypeVersion", context));
|
||||
|
||||
if (materialSourceData->m_materialType.empty())
|
||||
{
|
||||
@@ -118,6 +119,10 @@ namespace AZ
|
||||
|
||||
context.GetMetadata().Add(AZStd::move(materialTypeData));
|
||||
|
||||
JsonMaterialPropertyValueSerializer::LoadContext materialPropertyValueLoadContext;
|
||||
materialPropertyValueLoadContext.m_materialTypeVersion = materialSourceData->m_materialTypeVersion;
|
||||
context.GetMetadata().Add(materialPropertyValueLoadContext);
|
||||
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(&materialSourceData->m_properties, azrtti_typeid<MaterialSourceData::PropertyGroupMap>(), inputValue, "properties", context));
|
||||
|
||||
if (result.GetProcessing() == JsonSerializationResult::Processing::Completed)
|
||||
@@ -146,9 +151,9 @@ namespace AZ
|
||||
|
||||
JSR::ResultCode resultCode(JSR::Tasks::ReadField);
|
||||
resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "description", &materialSourceData->m_description, nullptr, azrtti_typeid<AZStd::string>(), context));
|
||||
resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "materialType", &materialSourceData->m_materialType, nullptr, azrtti_typeid<AZStd::string>(), context));
|
||||
resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "parentMaterial", &materialSourceData->m_parentMaterial, nullptr, azrtti_typeid<AZStd::string>(), context));
|
||||
resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "propertyLayoutVersion", &materialSourceData->m_propertyLayoutVersion, nullptr, azrtti_typeid<uint32_t>(), context));
|
||||
resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "materialType", &materialSourceData->m_materialType, nullptr, azrtti_typeid<AZStd::string>(), context));
|
||||
resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "materialTypeVersion", &materialSourceData->m_materialTypeVersion, nullptr, azrtti_typeid<uint32_t>(), context));
|
||||
resultCode.Combine(ContinueStoringToJsonObjectField(outputValue, "properties", &materialSourceData->m_properties, nullptr, azrtti_typeid<MaterialSourceData::PropertyGroupMap>(), context));
|
||||
|
||||
return context.Report(resultCode, "Processed material.");
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialTypeAssetCreator.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialFunctor.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialVersionUpdate.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderOptionGroup.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
@@ -59,6 +60,23 @@ namespace AZ
|
||||
|
||||
serializeContext->RegisterGenericType<PropertyConnectionList>();
|
||||
|
||||
serializeContext->Class<VersionUpdatesRenameOperationDefinition>()
|
||||
->Version(1)
|
||||
->Field("op", &VersionUpdatesRenameOperationDefinition::m_operation)
|
||||
->Field("from", &VersionUpdatesRenameOperationDefinition::m_renameFrom)
|
||||
->Field("to", &VersionUpdatesRenameOperationDefinition::m_renameTo)
|
||||
;
|
||||
|
||||
serializeContext->RegisterGenericType<VersionUpdateActions>();
|
||||
|
||||
serializeContext->Class<VersionUpdateDefinition>()
|
||||
->Version(1)
|
||||
->Field("toVersion", &VersionUpdateDefinition::m_toVersion)
|
||||
->Field("actions", &VersionUpdateDefinition::m_actions)
|
||||
;
|
||||
|
||||
serializeContext->RegisterGenericType<VersionUpdates>();
|
||||
|
||||
serializeContext->Class<ShaderVariantReferenceData>()
|
||||
->Version(2)
|
||||
->Field("file", &ShaderVariantReferenceData::m_shaderFilePath)
|
||||
@@ -67,8 +85,8 @@ namespace AZ
|
||||
;
|
||||
|
||||
serializeContext->Class<PropertyLayout>()
|
||||
->Version(1)
|
||||
->Field("version", &PropertyLayout::m_version)
|
||||
->Version(2) // Material Version Update
|
||||
->Field("version", &PropertyLayout::m_versionOld)
|
||||
->Field("groups", &PropertyLayout::m_groups)
|
||||
->Field("properties", &PropertyLayout::m_properties)
|
||||
;
|
||||
@@ -76,8 +94,10 @@ namespace AZ
|
||||
serializeContext->RegisterGenericType<UvNameMap>();
|
||||
|
||||
serializeContext->Class<MaterialTypeSourceData>()
|
||||
->Version(3)
|
||||
->Version(4) // Material Version Update
|
||||
->Field("description", &MaterialTypeSourceData::m_description)
|
||||
->Field("version", &MaterialTypeSourceData::m_version)
|
||||
->Field("versionUpdates", &MaterialTypeSourceData::m_versionUpdates)
|
||||
->Field("propertyLayout", &MaterialTypeSourceData::m_propertyLayout)
|
||||
->Field("shaders", &MaterialTypeSourceData::m_shaderCollection)
|
||||
->Field("functors", &MaterialTypeSourceData::m_materialFunctorSourceData)
|
||||
@@ -110,7 +130,38 @@ namespace AZ
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MaterialTypeSourceData::PropertyDefinition* MaterialTypeSourceData::FindProperty(AZStd::string_view groupName, AZStd::string_view propertyName) const
|
||||
bool MaterialTypeSourceData::ApplyPropertyRenames(MaterialPropertyId& propertyId, uint32_t materialTypeVersion) const
|
||||
{
|
||||
bool renamed = false;
|
||||
|
||||
for (const VersionUpdateDefinition& versionUpdate : m_versionUpdates)
|
||||
{
|
||||
if (materialTypeVersion >= versionUpdate.m_toVersion)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const VersionUpdatesRenameOperationDefinition& action : versionUpdate.m_actions)
|
||||
{
|
||||
if (action.m_operation == "rename")
|
||||
{
|
||||
if (action.m_renameFrom == propertyId.GetFullName().GetStringView())
|
||||
{
|
||||
propertyId = MaterialPropertyId::Parse(action.m_renameTo);
|
||||
renamed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("Material source data", false, "Unsupported material version update operation '%s'", action.m_operation.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return renamed;
|
||||
}
|
||||
|
||||
const MaterialTypeSourceData::PropertyDefinition* MaterialTypeSourceData::FindProperty(AZStd::string_view groupName, AZStd::string_view propertyName, uint32_t materialTypeVersion) const
|
||||
{
|
||||
auto groupIter = m_propertyLayout.m_properties.find(groupName);
|
||||
if (groupIter == m_propertyLayout.m_properties.end())
|
||||
@@ -126,6 +177,27 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
// Property has not been found, try looking for renames in the version history
|
||||
|
||||
MaterialPropertyId propertyId = MaterialPropertyId{groupName, propertyName};
|
||||
ApplyPropertyRenames(propertyId, materialTypeVersion);
|
||||
|
||||
// Do the search again with the new names
|
||||
|
||||
groupIter = m_propertyLayout.m_properties.find(propertyId.GetGroupName().GetStringView());
|
||||
if (groupIter == m_propertyLayout.m_properties.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (const PropertyDefinition& property : groupIter->second)
|
||||
{
|
||||
if (property.m_name == propertyId.GetPropertyName().GetStringView())
|
||||
{
|
||||
return &property;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -280,6 +352,41 @@ namespace AZ
|
||||
materialTypeAssetCreator.SetElevateWarnings(elevateWarnings);
|
||||
materialTypeAssetCreator.Begin(assetId);
|
||||
|
||||
if (m_propertyLayout.m_versionOld != 0)
|
||||
{
|
||||
materialTypeAssetCreator.ReportError(
|
||||
"The field '/propertyLayout/version' is deprecated and moved to '/version'. "
|
||||
"Please edit this material type source file and move the '\"version\": %u' setting up one level.",
|
||||
m_propertyLayout.m_versionOld);
|
||||
return Failure();
|
||||
}
|
||||
|
||||
// Set materialtype version and add each version update object into MaterialTypeAsset.
|
||||
materialTypeAssetCreator.SetVersion(m_version);
|
||||
{
|
||||
const AZ::Name rename = AZ::Name{ "rename" };
|
||||
|
||||
for (const auto& versionUpdate : m_versionUpdates)
|
||||
{
|
||||
MaterialVersionUpdate materialVersionUpdate{versionUpdate.m_toVersion};
|
||||
for (const auto& action : versionUpdate.m_actions)
|
||||
{
|
||||
if (action.m_operation == rename.GetStringView())
|
||||
{
|
||||
materialVersionUpdate.AddAction(MaterialVersionUpdate::RenamePropertyAction{
|
||||
AZ::Name{ action.m_renameFrom },
|
||||
AZ::Name{ action.m_renameTo }
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
materialTypeAssetCreator.ReportWarning("Unsupported material version update operation '%s'", action.m_operation.c_str());
|
||||
}
|
||||
}
|
||||
materialTypeAssetCreator.AddVersionUpdate(materialVersionUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
// Used to gather all the UV streams used in this material type from its shaders in alphabetical order.
|
||||
auto semanticComp = [](const RHI::ShaderSemantic& lhs, const RHI::ShaderSemantic& rhs) -> bool
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialPropertiesLayout.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialFunctor.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialVersionUpdate.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetHandler.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderReloadDebugTracker.h>
|
||||
|
||||
@@ -32,8 +33,9 @@ namespace AZ
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<MaterialAsset, AZ::Data::AssetData>()
|
||||
->Version(10)
|
||||
->Version(11) // Material version update
|
||||
->Field("materialTypeAsset", &MaterialAsset::m_materialTypeAsset)
|
||||
->Field("materialTypeVersion", &MaterialAsset::m_materialTypeVersion)
|
||||
->Field("propertyValues", &MaterialAsset::m_propertyValues)
|
||||
->Field("propertyNames", &MaterialAsset::m_propertyNames)
|
||||
;
|
||||
@@ -103,9 +105,25 @@ namespace AZ
|
||||
|
||||
AZStd::array_view<MaterialPropertyValue> MaterialAsset::GetPropertyValues() const
|
||||
{
|
||||
if (!m_propertyNames.empty() && m_isDirty)
|
||||
// If property names are included, they are used to re-arrange the property value list to align with the
|
||||
// MaterialPropertiesLayout. This realignment would be necessary if the material type is updated with
|
||||
// a new property layout, and a corresponding material is not reprocessed by the AP and continues using the
|
||||
// old property layout.
|
||||
if (!m_propertyNames.empty())
|
||||
{
|
||||
const_cast<MaterialAsset*>(this)->RealignPropertyValuesAndNames();
|
||||
const uint32_t materialTypeVersion = m_materialTypeAsset->GetVersion();
|
||||
if (m_materialTypeVersion < materialTypeVersion)
|
||||
{
|
||||
// It is possible that the material type has had some properties renamed. If that's the case, and this material
|
||||
// is still referencing the old property layout, we need to apply any auto updates to rename those properties
|
||||
// before using them to realign the property values.
|
||||
const_cast<MaterialAsset*>(this)->ApplyVersionUpdates();
|
||||
}
|
||||
|
||||
if (m_isDirty)
|
||||
{
|
||||
const_cast<MaterialAsset*>(this)->RealignPropertyValuesAndNames();
|
||||
}
|
||||
}
|
||||
|
||||
return m_propertyValues;
|
||||
@@ -183,6 +201,40 @@ namespace AZ
|
||||
m_isDirty = false;
|
||||
}
|
||||
|
||||
void MaterialAsset::ApplyVersionUpdates()
|
||||
{
|
||||
if (m_materialTypeVersion == m_materialTypeAsset->GetVersion())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t originalVersion = m_materialTypeVersion;
|
||||
|
||||
bool changesWereApplied = false;
|
||||
|
||||
for (const MaterialVersionUpdate& versionUpdate : m_materialTypeAsset->GetMaterialVersionUpdateList())
|
||||
{
|
||||
if (m_materialTypeVersion < versionUpdate.GetVersion())
|
||||
{
|
||||
if (versionUpdate.ApplyVersionUpdates(*this))
|
||||
{
|
||||
changesWereApplied = true;
|
||||
m_materialTypeVersion = versionUpdate.GetVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changesWereApplied)
|
||||
{
|
||||
AZ_Warning("MaterialAsset", false,
|
||||
"This material is based on version '%u' of %s, but the material type is now at version '%u'. "
|
||||
"Automatic updates are available. Consider updating the .material source file.",
|
||||
originalVersion, m_materialTypeAsset.ToString<AZStd::string>().c_str(), m_materialTypeAsset->GetVersion());
|
||||
}
|
||||
|
||||
m_materialTypeVersion = m_materialTypeAsset->GetVersion();
|
||||
}
|
||||
|
||||
void MaterialAsset::ReinitializeMaterialTypeAsset(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
Data::Asset<MaterialTypeAsset> newMaterialTypeAsset = { asset.GetAs<MaterialTypeAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace AZ
|
||||
if (ValidateIsReady())
|
||||
{
|
||||
m_asset->m_materialTypeAsset = parentMaterial.m_materialTypeAsset;
|
||||
m_asset->m_materialTypeVersion = m_asset->m_materialTypeAsset->GetVersion();
|
||||
|
||||
if (!m_asset->m_materialTypeAsset)
|
||||
{
|
||||
@@ -69,6 +70,7 @@ namespace AZ
|
||||
ReportError("MaterialTypeAsset is null");
|
||||
return;
|
||||
}
|
||||
m_asset->m_materialTypeVersion = m_asset->m_materialTypeAsset->GetVersion();
|
||||
|
||||
m_materialPropertiesLayout = m_asset->GetMaterialPropertiesLayout();
|
||||
if (includeMaterialPropertyNames)
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace AZ
|
||||
|
||||
void MaterialTypeAsset::Reflect(ReflectContext* context)
|
||||
{
|
||||
MaterialVersionUpdate::Reflect(context);
|
||||
UvNamePair::Reflect(context);
|
||||
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
@@ -44,7 +45,9 @@ namespace AZ
|
||||
serializeContext->RegisterGenericType<MaterialUvNameMap>();
|
||||
|
||||
serializeContext->Class<MaterialTypeAsset, AZ::Data::AssetData>()
|
||||
->Version(4) // ATOM-15472
|
||||
->Version(5) // Material version update
|
||||
->Field("Version", &MaterialTypeAsset::m_version)
|
||||
->Field("VersionUpdates", &MaterialTypeAsset::m_materialVersionUpdates)
|
||||
->Field("ShaderCollection", &MaterialTypeAsset::m_shaderCollection)
|
||||
->Field("MaterialFunctors", &MaterialTypeAsset::m_materialFunctors)
|
||||
->Field("MaterialSrgShaderIndex", &MaterialTypeAsset::m_materialSrgShaderIndex)
|
||||
@@ -161,6 +164,11 @@ namespace AZ
|
||||
return m_uvNameMap;
|
||||
}
|
||||
|
||||
uint32_t MaterialTypeAsset::GetVersion() const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
|
||||
void MaterialTypeAsset::SetReady()
|
||||
{
|
||||
m_status = AssetStatus::Ready;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace AZ
|
||||
|
||||
bool MaterialTypeAssetCreator::End(Data::Asset<MaterialTypeAsset>& result)
|
||||
{
|
||||
if (!ValidateIsReady() || !ValidateEndMaterialProperty())
|
||||
if (!ValidateIsReady() || !ValidateEndMaterialProperty() || !ValidateMaterialVersion())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -100,6 +100,48 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
bool MaterialTypeAssetCreator::ValidateMaterialVersion()
|
||||
{
|
||||
if (m_asset->m_materialVersionUpdates.empty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t prevVersion = 0;
|
||||
for(const MaterialVersionUpdate& versionUpdate : m_asset->m_materialVersionUpdates)
|
||||
{
|
||||
if (versionUpdate.GetVersion() <= prevVersion)
|
||||
{
|
||||
ReportError("Version updates are not sequential. See version update '%u'.", versionUpdate.GetVersion());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (versionUpdate.GetVersion() > m_asset->m_version)
|
||||
{
|
||||
ReportError("Version updates go beyond the current material type version. See version update '%u'.", versionUpdate.GetVersion());
|
||||
return false;
|
||||
}
|
||||
|
||||
prevVersion = versionUpdate.GetVersion();
|
||||
}
|
||||
|
||||
const auto& lastMaterialVersionUpdate = m_asset->m_materialVersionUpdates.back();
|
||||
for (const auto& action : lastMaterialVersionUpdate.GetActions())
|
||||
{
|
||||
const auto propertyIndex = m_asset->m_materialPropertiesLayout->FindPropertyIndex(AZ::Name{ action.m_toPropertyId });
|
||||
if (!propertyIndex.IsValid())
|
||||
{
|
||||
ReportError("Renamed property '%s' not found in material property layout. Check that the property name has been "
|
||||
"upgraded to the correct version",
|
||||
action.m_toPropertyId.GetCStr());
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MaterialTypeAssetCreator::AddShader(const AZ::Data::Asset<ShaderAsset>& shaderAsset, const ShaderVariantId& shaderVaraintId, const AZ::Name& shaderTag)
|
||||
{
|
||||
if (ValidateIsReady() && ValidateNotNull(shaderAsset, "ShaderAsset"))
|
||||
@@ -123,6 +165,16 @@ namespace AZ
|
||||
AddShader(shaderAsset, ShaderVariantId{}, shaderTag);
|
||||
}
|
||||
|
||||
void MaterialTypeAssetCreator::SetVersion(uint32_t version)
|
||||
{
|
||||
m_asset->m_version = version;
|
||||
}
|
||||
|
||||
void MaterialTypeAssetCreator::AddVersionUpdate(const MaterialVersionUpdate& materialVersionUpdate)
|
||||
{
|
||||
m_asset->m_materialVersionUpdates.push_back(materialVersionUpdate);
|
||||
}
|
||||
|
||||
void MaterialTypeAssetCreator::ClaimShaderOptionOwnership(const Name& shaderOptionName)
|
||||
{
|
||||
bool optionFound = false;
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RPI.Reflect/Material/MaterialVersionUpdate.h>
|
||||
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace RPI
|
||||
{
|
||||
void MaterialVersionUpdate::RenamePropertyAction::Reflect(ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<RenamePropertyAction>()
|
||||
->Version(1)
|
||||
->Field("From", &RenamePropertyAction::m_fromPropertyId)
|
||||
->Field("To", &RenamePropertyAction::m_toPropertyId)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialVersionUpdate::Reflect(ReflectContext* context)
|
||||
{
|
||||
MaterialVersionUpdate::RenamePropertyAction::Reflect(context);
|
||||
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->RegisterGenericType<MaterialVersionUpdate::Actions>();
|
||||
|
||||
serializeContext->Class<MaterialVersionUpdate>()
|
||||
->Version(1)
|
||||
->Field("ToVersion", &MaterialVersionUpdate::m_toVersion)
|
||||
->Field("Actions", &MaterialVersionUpdate::m_actions)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
MaterialVersionUpdate::MaterialVersionUpdate(uint32_t toVersion)
|
||||
: m_toVersion(toVersion)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t MaterialVersionUpdate::GetVersion() const
|
||||
{
|
||||
return m_toVersion;
|
||||
}
|
||||
|
||||
void MaterialVersionUpdate::SetVersion(uint32_t toVersion)
|
||||
{
|
||||
m_toVersion = toVersion;
|
||||
}
|
||||
|
||||
bool MaterialVersionUpdate::ApplyVersionUpdates(MaterialAsset& materialAsset) const
|
||||
{
|
||||
bool changesWereApplied = false;
|
||||
|
||||
for (auto& propertyName : materialAsset.m_propertyNames)
|
||||
{
|
||||
for (const auto& action : m_actions)
|
||||
{
|
||||
if (propertyName == action.m_fromPropertyId)
|
||||
{
|
||||
propertyName = action.m_toPropertyId;
|
||||
changesWereApplied = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changesWereApplied;
|
||||
}
|
||||
|
||||
const AZ::RPI::MaterialVersionUpdate::Actions& MaterialVersionUpdate::GetActions() const
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
void MaterialVersionUpdate::AddAction(const RenamePropertyAction& action)
|
||||
{
|
||||
m_actions.push_back(action);
|
||||
}
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
Reference in New Issue
Block a user