Enable material version updates.

Signed-off-by: Robin <rbarrand@amazon.com>
This commit is contained in:
rbarrand
2021-09-21 15:35:59 -07:00
committed by Robin
parent 2c19abf7ee
commit 59031d2f17
12 changed files with 316 additions and 6 deletions
@@ -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>
@@ -31,8 +32,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)
;
@@ -102,9 +104,19 @@ namespace AZ
AZStd::array_view<MaterialPropertyValue> MaterialAsset::GetPropertyValues() const
{
if (!m_propertyNames.empty() && m_isDirty)
if (!m_propertyNames.empty())
{
const_cast<MaterialAsset*>(this)->RealignPropertyValuesAndNames();
const uint32_t materialTypeVersion = m_materialTypeAsset->GetVersion();
if (m_materialTypeVersion != materialTypeVersion)
{
const_cast<MaterialAsset*>(this)->RenamePropertyNames();
const_cast<uint32_t&>(m_materialTypeVersion) = materialTypeVersion;
}
if (m_isDirty)
{
const_cast<MaterialAsset*>(this)->RealignPropertyValuesAndNames();
}
}
return m_propertyValues;
@@ -182,6 +194,52 @@ namespace AZ
m_isDirty = false;
}
template <typename iteratorType>
void MaterialAsset::RenamePropertyNames(iteratorType start, iteratorType end)
{
for (iteratorType it = start; it != end; ++it)
{
for (auto& propertyName : m_propertyNames)
{
const auto toFromIterator = it->find(propertyName.GetCStr());
if (toFromIterator != it->end())
{
propertyName = AZ::Name{ toFromIterator->second };
}
}
}
}
void MaterialAsset::RenamePropertyNames()
{
// construct toFrom map in ascending order of version.
AZStd::vector<AZStd::map<AZStd::string, AZStd::string>> versionToFrom;
const bool ascending = m_materialTypeVersion < m_materialTypeAsset->GetVersion();
for (int i = 0; i < AZStd::abs(static_cast<int>(m_materialTypeVersion - m_materialTypeAsset->GetVersion())); ++i)
{
const auto& versionUpdate = m_materialTypeAsset->GetMaterialVersionUpdate((m_materialTypeVersion < m_materialTypeAsset->GetVersion() ? m_materialTypeVersion : m_materialTypeAsset->GetVersion()) + i + 1);
versionToFrom.push_back();
for (const auto& action : versionUpdate.m_actions)
{
const AZStd::string from = ascending ? action.m_argsMap.find("from")->second : action.m_argsMap.find("to")->second;
const AZStd::string to = ascending ? action.m_argsMap.find("to")->second : action.m_argsMap.find("from")->second;
versionToFrom[i][from] = to;
}
}
if (ascending)
{
RenamePropertyNames(versionToFrom.cbegin(), versionToFrom.cend());
}
else
{
RenamePropertyNames(versionToFrom.crbegin(), versionToFrom.crend());
}
}
void MaterialAsset::ReinitializeMaterialTypeAsset(Data::Asset<Data::AssetData> asset)
{
Data::Asset<MaterialTypeAsset> newMaterialTypeAsset = { asset.GetAs<MaterialTypeAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };