Moved the material slot list from ModelLodAsset to ModelAsset, so all the slots live in one main list. This removes data duplication between LODs and cleans up the code a bit.

I had to update the ModelLod class to take in both the ModelLodAsset and ModelAsset for initialization so it can fetch the slots for each mesh.

Signed-off-by: santorac <55155825+santorac@users.noreply.github.com>
monroegm-disable-blank-issue-2
Chris Santora 4 years ago committed by santorac
parent a71ee7eb3a
commit fec79a7d53

@ -640,7 +640,8 @@ namespace AZ
Aabb localAabb = lod.m_subMeshProperties[i].m_aabb;
modelLodCreator.SetMeshAabb(AZStd::move(localAabb));
modelLodCreator.SetMeshMaterialSlot(lod.m_subMeshProperties[i].m_materialSlot);
modelCreator.AddMaterialSlot(lod.m_subMeshProperties[i].m_materialSlot);
modelLodCreator.SetMeshMaterialSlot(lod.m_subMeshProperties[i].m_materialSlot.m_stableId);
modelLodCreator.EndMesh();
}

@ -90,8 +90,8 @@ namespace AZ
private:
Model() = default;
static Data::Instance<Model> CreateInternal(ModelAsset& modelAsset);
RHI::ResultCode Init(ModelAsset& modelAsset);
static Data::Instance<Model> CreateInternal(const Data::Asset<ModelAsset>& modelAsset);
RHI::ResultCode Init(const Data::Asset<ModelAsset>& modelAsset);
AZStd::fixed_vector<Data::Instance<ModelLod>, ModelLodAsset::LodCountMax> m_lods;
Data::Asset<ModelAsset> m_modelAsset;

@ -18,6 +18,7 @@
#include <Atom/RHI.Reflect/Limits.h>
#include <Atom/RPI.Reflect/Model/ModelLodAsset.h>
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
#include <AtomCore/std/containers/array_view.h>
#include <AtomCore/std/containers/vector_set.h>
@ -84,7 +85,7 @@ namespace AZ
AZ_INSTANCE_DATA(ModelLod, "{3C796FC9-2067-4E0F-A660-269F8254D1D5}");
AZ_CLASS_ALLOCATOR(ModelLod, AZ::SystemAllocator, 0);
static Data::Instance<ModelLod> FindOrCreate(const Data::Asset<ModelLodAsset>& lodAsset);
static Data::Instance<ModelLod> FindOrCreate(const Data::Asset<ModelLodAsset>& lodAsset, const Data::Asset<ModelAsset>& modelAsset);
~ModelLod() = default;
@ -124,8 +125,8 @@ namespace AZ
private:
ModelLod() = default;
static Data::Instance<ModelLod> CreateInternal(ModelLodAsset& lodAsset);
RHI::ResultCode Init(ModelLodAsset& lodAsset);
static Data::Instance<ModelLod> CreateInternal(const Data::Asset<ModelLodAsset>& lodAsset, const AZStd::any* modelAssetAny);
RHI::ResultCode Init(const Data::Asset<ModelLodAsset>& lodAsset, const Data::Asset<ModelAsset>& modelAsset);
bool SetMeshInstanceData(
const ModelLodAsset::Mesh::StreamBufferInfo& streamBufferInfo,

@ -51,7 +51,10 @@ namespace AZ
const AZ::Aabb& GetAabb() const;
//! Returns the list of all ModelMaterialSlot's for the model, across all LODs.
RPI::ModelMaterialSlotMap GetModelMaterialSlots() const;
const ModelMaterialSlotMap& GetMaterialSlots() const;
//! Find a material slot with the given stableId, or returns an invalid slot if it isn't found.
const ModelMaterialSlot& FindMaterialSlot(uint32_t stableId) const;
//! Returns the number of Lods in the model
size_t GetLodCount() const;
@ -101,6 +104,13 @@ namespace AZ
mutable AZStd::mutex m_kdTreeLock;
mutable AZStd::optional<AZStd::size_t> m_modelTriangleCount;
// Lists all of the material slots that are used by this LOD.
// Note the same slot can appear in multiple LODs in the model, so that LODs don't have to refer back to the model asset.
ModelMaterialSlotMap m_materialSlots;
// A default ModelMaterialSlot to be returned upon error conditions.
ModelMaterialSlot m_fallbackSlot;
AZStd::size_t CalculateTriangleCount() const;
};

@ -30,6 +30,10 @@ namespace AZ
//! Assigns a name to the model
void SetName(AZStd::string_view name);
//! Adds a new material slot to the asset.
//! If a slot with the same stable ID already exists, it will be replaced.
void AddMaterialSlot(const ModelMaterialSlot& materialSlot);
//! Adds a Lod to the model.
void AddLodAsset(Data::Asset<ModelLodAsset>&& lodAsset);

@ -85,9 +85,9 @@ namespace AZ
//! Returns the number of indices in this mesh
uint32_t GetIndexCount() const;
//! Returns the index of the material slot used by this mesh.
//! This indexes into the ModelLodAsset's material slot list.
size_t GetMaterialSlotIndex() const;
//! Returns the ID of the material slot used by this mesh.
//! This maps into the ModelAsset's material slot list.
ModelMaterialSlot::StableId GetMaterialSlotId() const;
//! Returns the name of this mesh
const AZ::Name& GetName() const;
@ -126,9 +126,9 @@ namespace AZ
AZ::Name m_name;
AZ::Aabb m_aabb = AZ::Aabb::CreateNull();
// Identifies the material that is used by this mesh.
// References material slot in the ModelLodAsset that owns this mesh; see ModelLodAsset::GetMaterialSlot().
size_t m_materialSlotIndex = 0;
// Identifies the material slot that is used by this mesh.
// References material slot in the ModelAsset that owns this mesh; see ModelAsset::FindMaterialSlot().
ModelMaterialSlot::StableId m_materialSlotId = ModelMaterialSlot::InvalidStableId;
// Both the buffer in m_indexBufferAssetView and the buffers in m_streamBufferInfo
// may point to either unique buffers for the mesh or to consolidated
@ -148,16 +148,6 @@ namespace AZ
//! Returns the model-space axis-aligned bounding box of all meshes in the lod
const AZ::Aabb& GetAabb() const;
//! Returns an array view into the collection of material slots available to this lod
AZStd::array_view<ModelMaterialSlot> GetMaterialSlots() const;
//! Returns a specific material slot by index, with error checking.
//! The index can be retrieved from Mesh::GetMaterialSlotIndex().
const ModelMaterialSlot& GetMaterialSlot(size_t slotIndex) const;
//! Find a material slot with the given stableId, or returns null if it isn't found.
const ModelMaterialSlot* FindMaterialSlot(uint32_t stableId) const;
private:
AZStd::vector<Mesh> m_meshes;
AZ::Aabb m_aabb = AZ::Aabb::CreateNull();
@ -169,13 +159,6 @@ namespace AZ
Data::Asset<BufferAsset> m_indexBuffer;
AZStd::vector<Data::Asset<BufferAsset>> m_streamBuffers;
// Lists all of the material slots that are used by this LOD.
// Note the same slot can appear in multiple LODs in the model, so that LODs don't have to refer back to the model asset.
AZStd::vector<ModelMaterialSlot> m_materialSlots;
// A default ModelMaterialSlot to be returned upon error conditions.
ModelMaterialSlot m_fallbackSlot;
void AddMesh(const Mesh& mesh);
void SetReady();

@ -46,10 +46,9 @@ namespace AZ
//! Begin and BeginMesh must be called first.
void SetMeshAabb(AZ::Aabb&& aabb);
//! Sets the material slot data for the current SubMesh.
//! Adds a new material slot to the ModelLodAsset if it doesn't already exist.
//! Sets the ID of the model's material slot that this mesh uses.
//! Begin and BeginMesh must be called first
void SetMeshMaterialSlot(const ModelMaterialSlot& materialSlot);
void SetMeshMaterialSlot(ModelMaterialSlot::StableId id);
//! Sets the given BufferAssetView to the current SubMesh as the index buffer.
//! Begin and BeginMesh must be called first

@ -91,7 +91,7 @@ namespace AZ
if (auto* serialize = azrtti_cast<SerializeContext*>(context))
{
serialize->Class<MaterialAssetBuilderComponent, SceneAPI::SceneCore::ExportingComponent>()
->Version(14); // [ATOM-13410]
->Version(16); // Optional material conversion
}
}

@ -368,6 +368,9 @@ namespace AZ
MorphTargetMetaAssetCreator morphTargetMetaCreator;
morphTargetMetaCreator.Begin(MorphTargetMetaAsset::ConstructAssetId(modelAssetId, modelAssetName));
ModelAssetCreator modelAssetCreator;
modelAssetCreator.Begin(modelAssetId);
uint32_t lodIndex = 0;
for (const SourceMeshContentList& sourceMeshContentList : sourceMeshContentListsByLod)
{
@ -429,7 +432,7 @@ namespace AZ
for (const ProductMeshView& meshView : lodMeshViews)
{
if (!CreateMesh(meshView, indexBuffer, streamBuffers, lodAssetCreator, context.m_materialsByUid))
if (!CreateMesh(meshView, indexBuffer, streamBuffers, modelAssetCreator, lodAssetCreator, context.m_materialsByUid))
{
return AZ::SceneAPI::Events::ProcessingResult::Failure;
}
@ -469,10 +472,6 @@ namespace AZ
}
sourceMeshContentListsByLod.clear();
// Build the final asset structure
ModelAssetCreator modelAssetCreator;
modelAssetCreator.Begin(modelAssetId);
// Finalize all LOD assets
for (auto& lodAsset : lodAssets)
{
@ -1796,6 +1795,7 @@ namespace AZ
const ProductMeshView& meshView,
const BufferAssetView& lodIndexBuffer,
const AZStd::vector<ModelLodAsset::Mesh::StreamBufferInfo>& lodStreamBuffers,
ModelAssetCreator& modelAssetCreator,
ModelLodAssetCreator& lodAssetCreator,
const MaterialAssetsByUid& materialAssetsByUid)
{
@ -1811,7 +1811,8 @@ namespace AZ
materialSlot.m_displayName = iter->second.m_name;
materialSlot.m_defaultMaterialAsset = iter->second.m_asset;
lodAssetCreator.SetMeshMaterialSlot(materialSlot);
modelAssetCreator.AddMaterialSlot(materialSlot);
lodAssetCreator.SetMeshMaterialSlot(materialSlot.m_stableId);
}
}

@ -294,6 +294,7 @@ namespace AZ
const ProductMeshView& meshView,
const BufferAssetView& lodIndexBuffer,
const AZStd::vector<ModelLodAsset::Mesh::StreamBufferInfo>& lodStreamBuffers,
ModelAssetCreator& modelAssetCreator,
ModelLodAssetCreator& lodAssetCreator,
const MaterialAssetsByUid& materialAssetsByUid);

@ -40,7 +40,7 @@ namespace AZ
return m_lods;
}
Data::Instance<Model> Model::CreateInternal(ModelAsset& modelAsset)
Data::Instance<Model> Model::CreateInternal(const Data::Asset<ModelAsset>& modelAsset)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
Data::Instance<Model> model = aznew Model();
@ -54,15 +54,15 @@ namespace AZ
return nullptr;
}
RHI::ResultCode Model::Init(ModelAsset& modelAsset)
RHI::ResultCode Model::Init(const Data::Asset<ModelAsset>& modelAsset)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
m_lods.resize(modelAsset.GetLodAssets().size());
m_lods.resize(modelAsset->GetLodAssets().size());
for (size_t lodIndex = 0; lodIndex < m_lods.size(); ++lodIndex)
{
const Data::Asset<ModelLodAsset>& lodAsset = modelAsset.GetLodAssets()[lodIndex];
const Data::Asset<ModelLodAsset>& lodAsset = modelAsset->GetLodAssets()[lodIndex];
if (!lodAsset)
{
@ -70,7 +70,7 @@ namespace AZ
return RHI::ResultCode::Fail;
}
Data::Instance<ModelLod> lodInstance = ModelLod::FindOrCreate(lodAsset);
Data::Instance<ModelLod> lodInstance = ModelLod::FindOrCreate(lodAsset, modelAsset);
if (lodInstance == nullptr)
{
return RHI::ResultCode::Fail;
@ -98,7 +98,7 @@ namespace AZ
m_lods[lodIndex] = AZStd::move(lodInstance);
}
m_modelAsset = { &modelAsset, AZ::Data::AssetLoadBehavior::PreLoad };
m_modelAsset = modelAsset;
m_isUploadPending = true;
return RHI::ResultCode::Success;
}

@ -19,11 +19,14 @@ namespace AZ
{
namespace RPI
{
Data::Instance<ModelLod> ModelLod::FindOrCreate(const Data::Asset<ModelLodAsset>& lodAsset)
Data::Instance<ModelLod> ModelLod::FindOrCreate(const Data::Asset<ModelLodAsset>& lodAsset, const Data::Asset<ModelAsset>& modelAsset)
{
AZStd::any modelAssetAny{&modelAsset};
return Data::InstanceDatabase<ModelLod>::Instance().FindOrCreate(
Data::InstanceId::CreateFromAssetId(lodAsset.GetId()),
lodAsset);
lodAsset,
&modelAssetAny);
}
AZStd::array_view<ModelLod::Mesh> ModelLod::GetMeshes() const
@ -31,10 +34,13 @@ namespace AZ
return m_meshes;
}
Data::Instance<ModelLod> ModelLod::CreateInternal(ModelLodAsset& lodAsset)
Data::Instance<ModelLod> ModelLod::CreateInternal(const Data::Asset<ModelLodAsset>& lodAsset, const AZStd::any* modelAssetAny)
{
AZ_Assert(modelAssetAny != nullptr, "Invalid model asset param");
auto modelAsset = AZStd::any_cast<Data::Asset<ModelAsset>*>(*modelAssetAny);
Data::Instance<ModelLod> lod = aznew ModelLod();
const RHI::ResultCode resultCode = lod->Init(lodAsset);
const RHI::ResultCode resultCode = lod->Init(lodAsset, *modelAsset);
if (resultCode == RHI::ResultCode::Success)
{
@ -44,11 +50,11 @@ namespace AZ
return nullptr;
}
RHI::ResultCode ModelLod::Init(ModelLodAsset& lodAsset)
RHI::ResultCode ModelLod::Init(const Data::Asset<ModelLodAsset>& lodAsset, const Data::Asset<ModelAsset>& modelAsset)
{
AZ_TRACE_METHOD();
for (const ModelLodAsset::Mesh& mesh : lodAsset.GetMeshes())
for (const ModelLodAsset::Mesh& mesh : lodAsset->GetMeshes())
{
Mesh meshInstance;
@ -100,7 +106,7 @@ namespace AZ
}
}
const ModelMaterialSlot& materialSlot = lodAsset.GetMaterialSlot(mesh.GetMaterialSlotIndex());
const ModelMaterialSlot& materialSlot = modelAsset->FindMaterialSlot(mesh.GetMaterialSlotId());
meshInstance.m_materialSlotStableId = materialSlot.m_stableId;

@ -41,9 +41,9 @@ namespace AZ
{
//Create Lod Database
AZ::Data::InstanceHandler<ModelLod> lodInstanceHandler;
lodInstanceHandler.m_createFunction = [](Data::AssetData* modelLodAsset)
lodInstanceHandler.m_createFunctionWithParam = [](Data::AssetData* modelLodAsset, const AZStd::any* modelAsset)
{
return ModelLod::CreateInternal(*(azrtti_cast<ModelLodAsset*>(modelLodAsset)));
return ModelLod::CreateInternal(Data::Asset<ModelLodAsset>{modelLodAsset, AZ::Data::AssetLoadBehavior::PreLoad}, modelAsset);
};
Data::InstanceDatabase<ModelLod>::Create(azrtti_typeid<ModelLodAsset>(), lodInstanceHandler);
@ -51,7 +51,7 @@ namespace AZ
AZ::Data::InstanceHandler<Model> modelInstanceHandler;
modelInstanceHandler.m_createFunction = [](Data::AssetData* modelAsset)
{
return Model::CreateInternal(*(azrtti_cast<ModelAsset*>(modelAsset)));
return Model::CreateInternal(Data::Asset<ModelAsset>{modelAsset, AZ::Data::AssetLoadBehavior::PreLoad});
};
Data::InstanceDatabase<Model>::Create(azrtti_typeid<ModelAsset>(), modelInstanceHandler);
}

@ -29,9 +29,10 @@ namespace AZ
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
{
serializeContext->Class<ModelAsset, Data::AssetData>()
->Version(0)
->Version(1)
->Field("Name", &ModelAsset::m_name)
->Field("Aabb", &ModelAsset::m_aabb)
->Field("MaterialSlots", &ModelAsset::m_materialSlots)
->Field("LodAssets", &ModelAsset::m_lodAssets)
;
}
@ -57,29 +58,24 @@ namespace AZ
return m_aabb;
}
RPI::ModelMaterialSlotMap ModelAsset::GetModelMaterialSlots() const
const ModelMaterialSlotMap& ModelAsset::GetMaterialSlots() const
{
RPI::ModelMaterialSlotMap slotMap;
return m_materialSlots;
}
for (const Data::Asset<AZ::RPI::ModelLodAsset>& lod : GetLodAssets())
{
for (const AZ::RPI::ModelMaterialSlot& materialSlot : lod->GetMaterialSlots())
const ModelMaterialSlot& ModelAsset::FindMaterialSlot(uint32_t stableId) const
{
auto iter = slotMap.find(materialSlot.m_stableId);
if (iter == slotMap.end())
auto iter = m_materialSlots.find(stableId);
if (iter == m_materialSlots.end())
{
slotMap.emplace(materialSlot.m_stableId, materialSlot);
return m_fallbackSlot;
}
else
{
AZ_Assert(materialSlot.m_displayName == iter->second.m_displayName && materialSlot.m_defaultMaterialAsset.GetId() == iter->second.m_defaultMaterialAsset.GetId(),
"Multiple LODs have mismatched data for the same material slot.");
return iter->second;
}
}
}
return slotMap;
}
size_t ModelAsset::GetLodCount() const
{

@ -30,6 +30,33 @@ namespace AZ
}
}
void ModelAssetCreator::AddMaterialSlot(const ModelMaterialSlot& materialSlot)
{
if (ValidateIsReady())
{
auto iter = m_asset->m_materialSlots.find(materialSlot.m_stableId);
if (iter == m_asset->m_materialSlots.end())
{
m_asset->m_materialSlots[materialSlot.m_stableId] = materialSlot;
}
else
{
if (materialSlot.m_displayName != iter->second.m_displayName)
{
ReportWarning("Material slot %u was already added with a different name.", materialSlot.m_stableId);
}
if (materialSlot.m_defaultMaterialAsset != iter->second.m_defaultMaterialAsset)
{
ReportWarning("Material slot %u was already added with a different default MaterialAsset.", materialSlot.m_stableId);
}
iter->second = materialSlot;
}
}
}
void ModelAssetCreator::AddLodAsset(Data::Asset<ModelLodAsset>&& lodAsset)
{
if (ValidateIsReady())

@ -23,10 +23,9 @@ namespace AZ
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<ModelLodAsset>()
->Version(1)
->Version(0)
->Field("Meshes", &ModelLodAsset::m_meshes)
->Field("Aabb", &ModelLodAsset::m_aabb)
->Field("MaterialSlots", &ModelLodAsset::m_materialSlots)
;
}
@ -41,7 +40,7 @@ namespace AZ
->Version(1)
->Field("Name", &ModelLodAsset::Mesh::m_name)
->Field("AABB", &ModelLodAsset::Mesh::m_aabb)
->Field("MaterialSlotIndex", &ModelLodAsset::Mesh::m_materialSlotIndex)
->Field("MaterialSlotId", &ModelLodAsset::Mesh::m_materialSlotId)
->Field("IndexBufferAssetView", &ModelLodAsset::Mesh::m_indexBufferAssetView)
->Field("StreamBufferInfo", &ModelLodAsset::Mesh::m_streamBufferInfo)
;
@ -76,9 +75,9 @@ namespace AZ
return m_indexBufferAssetView.GetBufferViewDescriptor().m_elementCount;
}
size_t ModelLodAsset::Mesh::GetMaterialSlotIndex() const
ModelMaterialSlot::StableId ModelLodAsset::Mesh::GetMaterialSlotId() const
{
return m_materialSlotIndex;
return m_materialSlotId;
}
const AZ::Name& ModelLodAsset::Mesh::GetName() const
@ -120,41 +119,6 @@ namespace AZ
return m_aabb;
}
AZStd::array_view<ModelMaterialSlot> ModelLodAsset::GetMaterialSlots() const
{
return m_materialSlots;
}
const ModelMaterialSlot& ModelLodAsset::GetMaterialSlot(size_t slotIndex) const
{
if (slotIndex < m_materialSlots.size())
{
return m_materialSlots[slotIndex];
}
else
{
AZ_Error("ModelAsset", false, "Material slot index %zu out of range. ModelAsset has %zu slots.", slotIndex, m_materialSlots.size());
return m_fallbackSlot;
}
}
const ModelMaterialSlot* ModelLodAsset::FindMaterialSlot(uint32_t stableId) const
{
auto iter = AZStd::find_if(m_materialSlots.begin(), m_materialSlots.end(), [&stableId](const ModelMaterialSlot& existingMaterialSlot)
{
return existingMaterialSlot.m_stableId == stableId;
});
if (iter == m_materialSlots.end())
{
return nullptr;
}
else
{
return iter;
}
}
const BufferAssetView* ModelLodAsset::Mesh::GetSemanticBufferAssetView(const AZ::Name& semantic) const
{
const AZStd::array_view<ModelLodAsset::Mesh::StreamBufferInfo>& streamBufferList = GetStreamBufferInfoList();

@ -61,32 +61,14 @@ namespace AZ
}
}
void ModelLodAssetCreator::SetMeshMaterialSlot(const ModelMaterialSlot& materialSlot)
void ModelLodAssetCreator::SetMeshMaterialSlot(ModelMaterialSlot::StableId id)
{
auto iter = AZStd::find_if(m_asset->m_materialSlots.begin(), m_asset->m_materialSlots.end(), [&materialSlot](const ModelMaterialSlot& existingMaterialSlot)
{
return existingMaterialSlot.m_stableId == materialSlot.m_stableId;
});
if (iter == m_asset->m_materialSlots.end())
{
m_currentMesh.m_materialSlotIndex = m_asset->m_materialSlots.size();
m_asset->m_materialSlots.push_back(materialSlot);
}
else
{
if (materialSlot.m_displayName != iter->m_displayName)
{
ReportWarning("Material slot %u was already added with a different name.", materialSlot.m_stableId);
}
if (materialSlot.m_defaultMaterialAsset != iter->m_defaultMaterialAsset)
if (!ValidateIsMeshReady())
{
ReportWarning("Material slot %u was already added with a different MaterialAsset.", materialSlot.m_stableId);
return;
}
*iter = materialSlot;
}
m_currentMesh.m_materialSlotId = id;
}
void ModelLodAssetCreator::SetMeshIndexBuffer(const BufferAssetView& bufferAssetView)
@ -309,8 +291,7 @@ namespace AZ
AZ::Aabb aabb = sourceMesh.GetAabb();
creator.SetMeshAabb(AZStd::move(aabb));
const ModelMaterialSlot& materialSlot = sourceAsset->GetMaterialSlot(sourceMesh.GetMaterialSlotIndex());
creator.SetMeshMaterialSlot(materialSlot);
creator.SetMeshMaterialSlot(sourceMesh.GetMaterialSlotId());
// Mesh index buffer view
const BufferAssetView& sourceIndexBufferView = sourceMesh.GetIndexBufferAssetView();

@ -257,7 +257,7 @@ namespace AZ
Data::Asset<const RPI::ModelAsset> modelAsset = GetModelAsset();
if (modelAsset.IsReady())
{
return modelAsset->GetModelMaterialSlots();
return modelAsset->GetMaterialSlots();
}
else
{

@ -96,7 +96,7 @@ namespace AZ
skinnedSubMesh.m_vertexCount = aznumeric_cast<uint32_t>(subMeshVertexCount);
lodVertexCount += aznumeric_cast<uint32_t>(subMeshVertexCount);
skinnedSubMesh.m_materialSlot = lodAsset->GetMaterialSlot(modelMesh.GetMaterialSlotIndex());
skinnedSubMesh.m_materialSlot = actor->GetMeshAsset()->FindMaterialSlot(modelMesh.GetMaterialSlotId());
// Queue the material asset - the ModelLod seems to handle delayed material loads
skinnedSubMesh.m_materialSlot.m_defaultMaterialAsset.QueueLoad();

@ -313,7 +313,7 @@ namespace AZ
Data::Asset<const RPI::ModelAsset> modelAsset = GetModelAsset();
if (modelAsset.IsReady())
{
return modelAsset->GetModelMaterialSlots();
return modelAsset->GetMaterialSlots();
}
else
{

@ -113,19 +113,7 @@ namespace WhiteBox
modelLodCreator.BeginMesh();
modelLodCreator.SetMeshAabb(meshData.GetAabb());
// set the default material
if (auto materialAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath<AZ::RPI::MaterialAsset>(TexturedMaterialPath.data()))
{
AZ::RPI::ModelMaterialSlot materialSlot;
materialSlot.m_stableId = 0;
materialSlot.m_defaultMaterialAsset = materialAsset;
modelLodCreator.SetMeshMaterialSlot(materialSlot);
}
else
{
AZ_Error("CreateLodAsset", false, "Could not load material.");
return false;
}
modelLodCreator.SetMeshMaterialSlot(OneMaterialSlotId);
AddMeshBuffers(modelLodCreator);
modelLodCreator.EndMesh();
@ -157,6 +145,20 @@ namespace WhiteBox
modelCreator.Begin(AZ::Data::AssetId(AZ::Uuid::CreateRandom()));
modelCreator.SetName(ModelName);
modelCreator.AddLodAsset(AZStd::move(m_lodAsset));
if (auto materialAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath<AZ::RPI::MaterialAsset>(TexturedMaterialPath.data()))
{
AZ::RPI::ModelMaterialSlot materialSlot;
materialSlot.m_stableId = OneMaterialSlotId;
materialSlot.m_defaultMaterialAsset = materialAsset;
modelCreator.AddMaterialSlot(materialSlot);
}
else
{
AZ_Error("CreateLodAsset", false, "Could not load material.");
return;
}
modelCreator.End(m_modelAsset);
}

@ -91,6 +91,7 @@ namespace WhiteBox
// TODO: LYN-784
static constexpr AZStd::string_view TexturedMaterialPath = "materials/defaultpbr.azmaterial";
static constexpr AZStd::string_view SolidMaterialPath = "materials/defaultpbr.azmaterial";
static constexpr AZ::RPI::ModelMaterialSlot::StableId OneMaterialSlotId = 0;
//! White box model name.
static constexpr AZStd::string_view ModelName = "WhiteBoxMesh";

Loading…
Cancel
Save