diff --git a/Source/Editor/Content/Proxy/CubeTextureProxy.cs b/Source/Editor/Content/Proxy/CubeTextureProxy.cs
index 691e4ac53..0477ad18e 100644
--- a/Source/Editor/Content/Proxy/CubeTextureProxy.cs
+++ b/Source/Editor/Content/Proxy/CubeTextureProxy.cs
@@ -54,12 +54,7 @@ namespace FlaxEditor.Content
///
public override bool CanDrawThumbnail(ThumbnailRequest request)
{
- if (!_preview.HasLoadedAssets)
- return false;
-
- // Check if all mip maps are streamed
- var asset = (CubeTexture)request.Asset;
- return asset.ResidentMipLevels >= Mathf.Max(1, (int)(asset.MipLevels * ThumbnailsModule.MinimumRequiredResourcesQuality));
+ return _preview.HasLoadedAssets && ThumbnailsModule.HasMinimumQuality((Texture)request.Asset);
}
///
diff --git a/Source/Editor/Content/Proxy/MaterialInstanceProxy.cs b/Source/Editor/Content/Proxy/MaterialInstanceProxy.cs
index dcc3e3ec4..331ff81c3 100644
--- a/Source/Editor/Content/Proxy/MaterialInstanceProxy.cs
+++ b/Source/Editor/Content/Proxy/MaterialInstanceProxy.cs
@@ -62,7 +62,7 @@ namespace FlaxEditor.Content
///
public override bool CanDrawThumbnail(ThumbnailRequest request)
{
- return _preview.HasLoadedAssets;
+ return _preview.HasLoadedAssets && ThumbnailsModule.HasMinimumQuality((MaterialInstance)request.Asset);
}
///
diff --git a/Source/Editor/Content/Proxy/MaterialProxy.cs b/Source/Editor/Content/Proxy/MaterialProxy.cs
index cf7c8b77e..a7fcfecc8 100644
--- a/Source/Editor/Content/Proxy/MaterialProxy.cs
+++ b/Source/Editor/Content/Proxy/MaterialProxy.cs
@@ -106,7 +106,7 @@ namespace FlaxEditor.Content
///
public override bool CanDrawThumbnail(ThumbnailRequest request)
{
- return _preview.HasLoadedAssets;
+ return _preview.HasLoadedAssets && ThumbnailsModule.HasMinimumQuality((Material)request.Asset);
}
///
diff --git a/Source/Editor/Content/Proxy/ModelProxy.cs b/Source/Editor/Content/Proxy/ModelProxy.cs
index c78863e5e..0cf16850d 100644
--- a/Source/Editor/Content/Proxy/ModelProxy.cs
+++ b/Source/Editor/Content/Proxy/ModelProxy.cs
@@ -82,18 +82,7 @@ namespace FlaxEditor.Content
///
public override bool CanDrawThumbnail(ThumbnailRequest request)
{
- if (!_preview.HasLoadedAssets)
- return false;
-
- // Check if asset is streamed enough
- var asset = (Model)request.Asset;
- var slots = asset.MaterialSlots;
- foreach (var slot in slots)
- {
- if (slot.Material && !slot.Material.IsLoaded)
- return false;
- }
- return asset.LoadedLODs >= Mathf.Max(1, (int)(asset.LODs.Length * ThumbnailsModule.MinimumRequiredResourcesQuality));
+ return _preview.HasLoadedAssets && ThumbnailsModule.HasMinimumQuality((Model)request.Asset);
}
///
diff --git a/Source/Editor/Content/Proxy/SkinnedModelProxy.cs b/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
index 4fd71e933..6e228aa86 100644
--- a/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
+++ b/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
@@ -54,21 +54,7 @@ namespace FlaxEditor.Content
///
public override bool CanDrawThumbnail(ThumbnailRequest request)
{
- if (!_preview.HasLoadedAssets)
- return false;
-
- // Check if asset is streamed enough
- var asset = (SkinnedModel)request.Asset;
- var lods = asset.LODs.Length;
- if (asset.IsLoaded && lods == 0)
- return true; // Skeleton-only model
- var slots = asset.MaterialSlots;
- foreach (var slot in slots)
- {
- if (slot.Material && !slot.Material.IsLoaded)
- return false;
- }
- return asset.LoadedLODs >= Mathf.Max(1, (int)(lods * ThumbnailsModule.MinimumRequiredResourcesQuality));
+ return _preview.HasLoadedAssets && ThumbnailsModule.HasMinimumQuality((SkinnedModel)request.Asset);
}
///
diff --git a/Source/Editor/Content/Proxy/TextureProxy.cs b/Source/Editor/Content/Proxy/TextureProxy.cs
index 48bfcc9e9..709ca4dbf 100644
--- a/Source/Editor/Content/Proxy/TextureProxy.cs
+++ b/Source/Editor/Content/Proxy/TextureProxy.cs
@@ -57,11 +57,7 @@ namespace FlaxEditor.Content
///
public override bool CanDrawThumbnail(ThumbnailRequest request)
{
- // Check if asset is streamed enough
- var asset = (Texture)request.Asset;
- var mipLevels = asset.MipLevels;
- var minMipLevels = Mathf.Min(mipLevels, 7);
- return asset.ResidentMipLevels >= Mathf.Max(minMipLevels, (int)(mipLevels * ThumbnailsModule.MinimumRequiredResourcesQuality));
+ return ThumbnailsModule.HasMinimumQuality((Texture)request.Asset);
}
///
diff --git a/Source/Editor/Content/Thumbnails/ThumbnailsModule.cs b/Source/Editor/Content/Thumbnails/ThumbnailsModule.cs
index a6996310e..f1889d9ed 100644
--- a/Source/Editor/Content/Thumbnails/ThumbnailsModule.cs
+++ b/Source/Editor/Content/Thumbnails/ThumbnailsModule.cs
@@ -125,6 +125,74 @@ namespace FlaxEditor.Content.Thumbnails
}
}
+ internal static bool HasMinimumQuality(TextureBase asset)
+ {
+ var mipLevels = asset.MipLevels;
+ var minMipLevels = Mathf.Min(mipLevels, 7);
+ return asset.IsLoaded && asset.ResidentMipLevels >= Mathf.Max(minMipLevels, (int)(mipLevels * MinimumRequiredResourcesQuality));
+ }
+
+ internal static bool HasMinimumQuality(Model asset)
+ {
+ if (!asset.IsLoaded)
+ return false;
+ var lods = asset.LODs.Length;
+ var slots = asset.MaterialSlots;
+ foreach (var slot in slots)
+ {
+ if (slot.Material && !HasMinimumQuality(slot.Material))
+ return false;
+ }
+ return asset.LoadedLODs >= Mathf.Max(1, (int)(lods * MinimumRequiredResourcesQuality));
+ }
+
+ internal static bool HasMinimumQuality(SkinnedModel asset)
+ {
+ var lods = asset.LODs.Length;
+ if (asset.IsLoaded && lods == 0)
+ return true; // Skeleton-only model
+ var slots = asset.MaterialSlots;
+ foreach (var slot in slots)
+ {
+ if (slot.Material && !HasMinimumQuality(slot.Material))
+ return false;
+ }
+ return asset.LoadedLODs >= Mathf.Max(1, (int)(lods * MinimumRequiredResourcesQuality));
+ }
+
+ internal static bool HasMinimumQuality(MaterialBase asset)
+ {
+ if (asset is MaterialInstance asInstance)
+ return HasMinimumQuality(asInstance);
+ return HasMinimumQualityInternal(asset);
+ }
+
+ internal static bool HasMinimumQuality(Material asset)
+ {
+ return HasMinimumQualityInternal(asset);
+ }
+
+ internal static bool HasMinimumQuality(MaterialInstance asset)
+ {
+ if (!HasMinimumQualityInternal(asset))
+ return false;
+ var baseMaterial = asset.BaseMaterial;
+ return baseMaterial == null || HasMinimumQualityInternal(baseMaterial);
+ }
+
+ private static bool HasMinimumQualityInternal(MaterialBase asset)
+ {
+ if (!asset.IsLoaded)
+ return false;
+ var parameters = asset.Parameters;
+ foreach (var parameter in parameters)
+ {
+ if (parameter.Value is TextureBase asTexture && !HasMinimumQuality(asTexture))
+ return false;
+ }
+ return true;
+ }
+
#region IContentItemOwner
///