// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "../BinaryAsset.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Graphics/Models/MaterialSlot.h"
#include "Engine/Streaming/StreamableResource.h"
///
/// Base class for asset types that can contain a model resource.
///
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API ModelBase : public BinaryAsset, public StreamableResource
{
DECLARE_ASSET_HEADER(ModelBase);
protected:
explicit ModelBase(const SpawnParams& params, const AssetInfo* info, StreamingGroup* group)
: BinaryAsset(params, info)
, StreamableResource(group)
{
}
public:
///
/// The minimum screen size to draw this model (the bottom limit). Used to cull small models. Set to 0 to disable this feature.
///
API_FIELD() float MinScreenSize = 0.0f;
///
/// The list of material slots.
///
API_FIELD(ReadOnly) Array MaterialSlots;
///
/// Gets the amount of the material slots used by this model asset.
///
API_PROPERTY() int32 GetMaterialSlotsCount() const
{
return MaterialSlots.Count();
}
///
/// Resizes the material slots collection. Updates meshes that were using removed slots.
///
API_FUNCTION() virtual void SetupMaterialSlots(int32 slotsCount)
{
CHECK(slotsCount >= 0 && slotsCount < 4096);
if (!IsVirtual() && WaitForLoaded())
return;
ScopeLock lock(Locker);
const int32 prevCount = MaterialSlots.Count();
MaterialSlots.Resize(slotsCount);
// Initialize slot names
for (int32 i = prevCount; i < slotsCount; i++)
MaterialSlots[i].Name = String::Format(TEXT("Material {0}"), i + 1);
}
///
/// Gets the material slot by the name.
///
/// The slot name.
/// The material slot with the given name or null if cannot find it (asset may be not loaded yet).
API_FUNCTION() MaterialSlot* GetSlot(const StringView& name)
{
MaterialSlot* result = nullptr;
for (auto& slot : MaterialSlots)
{
if (slot.Name == name)
{
result = &slot;
break;
}
}
return result;
}
};