Add ModelInstanceActor::GetMaterial to get actual material used to render certain entries

This commit is contained in:
Wojtek Figat
2023-07-14 11:58:51 +02:00
parent 7b88569e73
commit a6924d37c1
8 changed files with 63 additions and 4 deletions

View File

@@ -898,6 +898,23 @@ void AnimatedModel::Deserialize(DeserializeStream& stream, ISerializeModifier* m
DrawModes |= DrawPass::GlobalSurfaceAtlas;
}
MaterialBase* AnimatedModel::GetMaterial(int32 entryIndex)
{
if (SkinnedModel)
SkinnedModel->WaitForLoaded();
else
return nullptr;
CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
MaterialBase* material = Entries[entryIndex].Material.Get();
if (!material)
{
material = SkinnedModel->MaterialSlots[entryIndex].Material.Get();
if (!material)
material = GPUDevice::Instance->GetDefaultMaterial();
}
return material;
}
bool AnimatedModel::IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal)
{
auto model = SkinnedModel.Get();

View File

@@ -373,6 +373,7 @@ public:
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
MaterialBase* GetMaterial(int32 entryIndex) override;
bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) override;
bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override;
void OnDeleteObject() override;

View File

@@ -39,10 +39,9 @@ void ModelInstanceActor::SetMaterial(int32 entryIndex, MaterialBase* material)
MaterialInstance* ModelInstanceActor::CreateAndSetVirtualMaterialInstance(int32 entryIndex)
{
WaitForModelLoad();
CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
auto material = Entries[entryIndex].Material.Get();
MaterialBase* material = GetMaterial(entryIndex);
CHECK_RETURN(material && !material->WaitForLoaded(), nullptr);
const auto result = material->CreateVirtualInstance();
MaterialInstance* result = material->CreateVirtualInstance();
Entries[entryIndex].Material = result;
if (_sceneRenderingKey != -1)
GetSceneRendering()->UpdateActor(this, _sceneRenderingKey);

View File

@@ -35,6 +35,12 @@ public:
/// </summary>
API_PROPERTY() void SetEntries(const Array<ModelInstanceEntry>& value);
/// <summary>
/// Gets the material used to draw the meshes which are assigned to that slot (set in Entries or model's default).
/// </summary>
/// <param name="entryIndex">The material slot entry index.</param>
API_FUNCTION(Sealed) virtual MaterialBase* GetMaterial(int32 entryIndex) = 0;
/// <summary>
/// Sets the material to the entry slot. Can be used to override the material of the meshes using this slot.
/// </summary>

View File

@@ -341,6 +341,23 @@ void SplineModel::OnParentChanged()
OnSplineUpdated();
}
MaterialBase* SplineModel::GetMaterial(int32 entryIndex)
{
if (Model)
Model->WaitForLoaded();
else
return nullptr;
CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
MaterialBase* material = Entries[entryIndex].Material.Get();
if (!material)
{
material = Model->MaterialSlots[entryIndex].Material.Get();
if (!material)
material = GPUDevice::Instance->GetDefaultDeformableMaterial();
}
return material;
}
bool SplineModel::HasContentLoaded() const
{
return (Model == nullptr || Model->IsLoaded()) && Entries.HasContentLoaded();

View File

@@ -115,6 +115,7 @@ public:
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
void OnParentChanged() override;
MaterialBase* GetMaterial(int32 entryIndex) override;
protected:
// [ModelInstanceActor]

View File

@@ -535,6 +535,23 @@ void StaticModel::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
}
}
MaterialBase* StaticModel::GetMaterial(int32 entryIndex)
{
if (Model)
Model->WaitForLoaded();
else
return nullptr;
CHECK_RETURN(entryIndex >= 0 && entryIndex < Entries.Count(), nullptr);
MaterialBase* material = Entries[entryIndex].Material.Get();
if (!material)
{
material = Model->MaterialSlots[entryIndex].Material.Get();
if (!material)
material = GPUDevice::Instance->GetDefaultMaterial();
}
return material;
}
bool StaticModel::IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal)
{
auto model = Model.Get();

View File

@@ -121,7 +121,7 @@ public:
/// <param name="meshIndex">The zero-based mesh index.</param>
/// <param name="lodIndex">The LOD index.</param>
/// <returns>Material or null if not assigned.</returns>
API_FUNCTION() MaterialBase* GetMaterial(int32 meshIndex, int32 lodIndex = 0) const;
API_FUNCTION() MaterialBase* GetMaterial(int32 meshIndex, int32 lodIndex) const;
/// <summary>
/// Gets the color of the painter vertex (this model instance).
@@ -166,6 +166,7 @@ public:
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
MaterialBase* GetMaterial(int32 entryIndex) override;
bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) override;
bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override;