using System; using UnityEngine.Perception.Randomization.Samplers; namespace UnityEngine.Perception.Randomization { /// /// AssetSources are used to load assets from a generically within a /// /// The type of asset to load [Serializable] public sealed class AssetSource where T : Object { [SerializeReference] IAssetRoleBase m_AssetRoleBase; /// /// The location to load assets from /// [SerializeReference] public AssetSourceLocation assetSourceLocation = new LocalAssetSourceLocation(); bool m_Initialized; UniformSampler m_Sampler = new UniformSampler(); /// /// The asset role used to preprocess assets from this source /// public AssetRole assetRole { get => (AssetRole)m_AssetRoleBase; set => m_AssetRoleBase = value; } /// /// The number of assets available within this asset source /// public int count { get { CheckIfInitialized(); return assetSourceLocation.count; } } /// /// Execute setup steps for this AssetSource. It is often unnecessary to call this API directly since all other /// relevant APIs in this class will Initialize() this AssetSource if it hasn't been already. /// public void Initialize() { if (!m_Initialized) { assetSourceLocation.Initialize(assetRole); m_Initialized = true; } } /// /// Returns the unprocessed asset loaded from the provided index /// /// The index of the asset to load /// The asset loaded at the provided index public T LoadRawAsset(int index) { CheckIfInitialized(); return assetSourceLocation.LoadAsset(index); } /// /// Returns all unprocessed assets that can be loaded from this AssetSource /// /// All assets that can be loaded from this AssetSource public T[] LoadAllRawAssets() { CheckIfInitialized(); var array = new T[count]; for (var i = 0; i < count; i++) array[i] = LoadRawAsset(i); return array; } /// /// Creates an instance of the asset loaded from the provided index and preprocesses it using the asset role /// assigned to this asset source /// /// The index of the asset to load /// The instantiated instance public T CreateProcessedInstance(int index) { CheckIfInitialized(); return CreateProcessedInstance(LoadRawAsset(index)); } /// /// Instantiates, preprocesses, and returns all assets that can be loaded from this asset source /// /// Instantiated instances from every loadable asset public T[] CreateProcessedInstances() { CheckIfInitialized(); var array = new T[count]; for (var i = 0; i < count; i++) array[i] = CreateProcessedInstance(i); return array; } /// /// Returns a uniformly random sampled asset from this AssetSource /// /// The randomly sampled asset public T SampleAsset() { CheckIfInitialized(); return count == 0 ? null : assetSourceLocation.LoadAsset((int)(m_Sampler.Sample() * count)); } /// /// Instantiates and preprocesses a uniformly random sampled asset from this AssetSource /// /// The generated random instance public T SampleInstance() { CheckIfInitialized(); return CreateProcessedInstance(SampleAsset()); } /// /// Unloads all assets that have been loaded from this AssetSource /// public void ReleaseAssets() { CheckIfInitialized(); assetSourceLocation.ReleaseAssets(); } void CheckIfInitialized() { if (!m_Initialized) Initialize(); } T CreateProcessedInstance(T asset) { if (asset == null) return null; var instance = Object.Instantiate(asset); if (assetRole != null) assetRole.Preprocess(instance); return instance; } } }