Separate TextureFactory from MaterialFactory

This commit is contained in:
ousttrue
2021-02-15 13:44:30 +09:00
parent 48f51d33a7
commit 693cc665c2
9 changed files with 195 additions and 136 deletions

View File

@@ -108,6 +108,9 @@ namespace UniGLTF
MaterialFactory m_materialFactory;
public MaterialFactory MaterialFactory => m_materialFactory;
TextureFactory m_textureFactory;
public TextureFactory TextureFactory => m_textureFactory;
public ImporterContext()
{
}
@@ -499,7 +502,13 @@ namespace UniGLTF
{
// root task. do nothing
})
.ContinueWithCoroutine(Scheduler.MainThread, m_materialFactory.LoadMaterials)
.ContinueWithCoroutine(Scheduler.MainThread, () =>
{
using (MeasureTime("LoadMaterials"))
{
return m_materialFactory.LoadMaterials(m_textureFactory.GetTextureAsync);
}
})
.OnExecute(Scheduler.ThreadPool, parent =>
{
// UniGLTF does not support draco
@@ -690,6 +699,10 @@ namespace UniGLTF
protected virtual IEnumerable<UnityEngine.Object> ObjectsForSubAsset()
{
foreach (var x in TextureFactory.ObjectsForSubAsset())
{
yield return x;
}
foreach (var x in MaterialFactory.ObjectsForSubAsset())
{
yield return x;
@@ -885,7 +898,7 @@ namespace UniGLTF
}
// texture will load from assets
m_materialFactory.ImageBaseDir = prefabParentDir;
m_textureFactory.ImageBaseDir = prefabParentDir;
}
#endregion
#endif

View File

@@ -4,9 +4,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniGLTF
{
@@ -20,8 +17,6 @@ namespace UniGLTF
m_storage = storage;
}
public UnityPath ImageBaseDir { get; set; }
public delegate Task<Material> CreateMaterialAsyncFunc(glTF glTF, int i, GetTextureAsyncFunc getTexture);
CreateMaterialAsyncFunc m_createMaterialAsync;
public CreateMaterialAsyncFunc CreateMaterialAsync
@@ -40,85 +35,24 @@ namespace UniGLTF
}
}
List<Texture2D> m_textuers = new List<Texture2D>();
Dictionary<GetTextureParam, Texture2D> m_textureCache = new Dictionary<GetTextureParam, Texture2D>();
/// <summary>
/// テクスチャーをロード、必要であれば変換して返す。
/// 同じものはキャッシュを返す
/// </summary>
/// <param name="texture_type">変換の有無を判断する: METALLIC_GLOSS_PROP</param>
/// <param name="roughnessFactor">METALLIC_GLOSS_PROPの追加パラメーター</param>
/// <param name="indices">gltf の texture index</param>
/// <returns></returns>
public async Task<Texture2D> GetTextureAsync(GetTextureParam param)
{
if (m_textureCache.TryGetValue(param, out Texture2D texture))
{
return texture;
}
{
var defaultParam = GetTextureParam.Create(param.Index0.Value);
if (!m_textureCache.TryGetValue(defaultParam, out texture))
{
texture = await LoadTextureAsync(param.Index0.Value);
m_textureCache.Add(defaultParam, texture);
}
}
switch (param.TextureType)
{
case GetTextureParam.NORMAL_PROP:
{
if (Application.isPlaying)
{
var converted = new NormalConverter().GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
else
{
#if UNITY_EDITOR
var textureAssetPath = AssetDatabase.GetAssetPath(texture);
if (!string.IsNullOrEmpty(textureAssetPath))
{
TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath);
}
else
{
Debug.LogWarningFormat("no asset for {0}", texture);
}
#endif
m_textureCache.Add(param, texture);
return texture;
}
}
case GetTextureParam.METALLIC_GLOSS_PROP:
{
// Bake roughnessFactor values into a texture.
var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
case GetTextureParam.OCCLUSION_PROP:
{
var converted = new OcclusionConverter().GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
default:
return texture;
}
throw new NotImplementedException();
}
List<Material> m_materials = new List<Material>();
public IReadOnlyList<Material> Materials => m_materials;
public void Dispose()
{
foreach (var x in ObjectsForSubAsset())
{
UnityEngine.Object.DestroyImmediate(x, true);
}
}
public IEnumerable<UnityEngine.Object> ObjectsForSubAsset()
{
foreach (var x in m_materials)
{
yield return x;
}
}
public void AddMaterial(Material material)
{
var originalName = material.name;
@@ -136,65 +70,33 @@ namespace UniGLTF
return m_materials[index];
}
public virtual Task<Texture2D> LoadTextureAsync(int index)
public IEnumerator LoadMaterials(GetTextureAsyncFunc getTexture)
{
#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER
return UnityWebRequestTextureLoader.LoadTextureAsync(index);
#else
return GltfTextureLoader.LoadTextureAsync(m_gltf, m_storage, index);
#endif
}
public IEnumerator LoadMaterials()
{
// using (MeasureTime("LoadMaterials"))
if (m_gltf.materials == null || m_gltf.materials.Count == 0)
{
if (m_gltf.materials == null || m_gltf.materials.Count == 0)
{
var task = CreateMaterialAsync(m_gltf, 0, GetTextureAsync);
var task = CreateMaterialAsync(m_gltf, 0, getTexture);
foreach (var x in task.AsIEnumerator())
{
yield return x;
}
AddMaterial(task.Result);
}
else
{
for (int i = 0; i < m_gltf.materials.Count; ++i)
{
var task = CreateMaterialAsync(m_gltf, i, getTexture);
foreach (var x in task.AsIEnumerator())
{
yield return x;
yield return null;
}
AddMaterial(task.Result);
}
else
{
for (int i = 0; i < m_gltf.materials.Count; ++i)
{
var task = CreateMaterialAsync(m_gltf, i, GetTextureAsync);
foreach (var x in task.AsIEnumerator())
{
yield return null;
}
AddMaterial(task.Result);
}
}
}
yield return null;
}
public void Dispose()
{
foreach (var x in ObjectsForSubAsset())
{
UnityEngine.Object.DestroyImmediate(x, true);
}
}
public IEnumerable<UnityEngine.Object> ObjectsForSubAsset()
{
foreach (var kv in m_textureCache)
{
yield return kv.Value;
}
foreach (var x in m_materials)
{
yield return x;
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 54a405d31cce94643be8f76f805da8c8
guid: a4bd2e8f388fb204186d743f337ddb83
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -51,5 +51,4 @@ namespace UniGLTF
}
}
public delegate Task<Texture2D> GetTextureAsyncFunc(GetTextureParam param);
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8f1dc05e4970e724e9f50c0a5a67a25e
guid: 405597f56d6540347bbecb1203aba033
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
namespace UniGLTF
{
public delegate Task<Texture2D> GetTextureAsyncFunc(GetTextureParam param);
public class TextureFactory : IDisposable
{
glTF m_gltf;
IStorage m_storage;
public UnityPath ImageBaseDir { get; set; }
public TextureFactory(glTF gltf, IStorage storage)
{
m_gltf = gltf;
m_storage = storage;
}
List<Texture2D> m_textuers = new List<Texture2D>();
public void Dispose()
{
foreach (var x in ObjectsForSubAsset())
{
UnityEngine.Object.DestroyImmediate(x, true);
}
}
public IEnumerable<UnityEngine.Object> ObjectsForSubAsset()
{
foreach (var kv in m_textureCache)
{
yield return kv.Value;
}
}
Dictionary<GetTextureParam, Texture2D> m_textureCache = new Dictionary<GetTextureParam, Texture2D>();
public virtual Task<Texture2D> LoadTextureAsync(int index)
{
#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER
return UnityWebRequestTextureLoader.LoadTextureAsync(index);
#else
return GltfTextureLoader.LoadTextureAsync(m_gltf, m_storage, index);
#endif
}
/// <summary>
/// テクスチャーをロード、必要であれば変換して返す。
/// 同じものはキャッシュを返す
/// </summary>
/// <param name="texture_type">変換の有無を判断する: METALLIC_GLOSS_PROP</param>
/// <param name="roughnessFactor">METALLIC_GLOSS_PROPの追加パラメーター</param>
/// <param name="indices">gltf の texture index</param>
/// <returns></returns>
public async Task<Texture2D> GetTextureAsync(GetTextureParam param)
{
if (m_textureCache.TryGetValue(param, out Texture2D texture))
{
return texture;
}
{
var defaultParam = GetTextureParam.Create(param.Index0.Value);
if (!m_textureCache.TryGetValue(defaultParam, out texture))
{
texture = await LoadTextureAsync(param.Index0.Value);
m_textureCache.Add(defaultParam, texture);
}
}
switch (param.TextureType)
{
case GetTextureParam.NORMAL_PROP:
{
if (Application.isPlaying)
{
var converted = new NormalConverter().GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
else
{
#if UNITY_EDITOR
var textureAssetPath = AssetDatabase.GetAssetPath(texture);
if (!string.IsNullOrEmpty(textureAssetPath))
{
TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath);
}
else
{
Debug.LogWarningFormat("no asset for {0}", texture);
}
#endif
m_textureCache.Add(param, texture);
return texture;
}
}
case GetTextureParam.METALLIC_GLOSS_PROP:
{
// Bake roughnessFactor values into a texture.
var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
case GetTextureParam.OCCLUSION_PROP:
{
var converted = new OcclusionConverter().GetImportTexture(texture);
m_textureCache.Add(param, converted);
return converted;
}
default:
return texture;
}
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4d6069f2bfbfc0c4c9276e8a5f8b0789
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 54a405d31cce94643be8f76f805da8c8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -310,7 +310,7 @@ namespace VRM
meta.ContactInformation = gltfMeta.contactInformation;
meta.Reference = gltfMeta.reference;
meta.Title = gltfMeta.title;
meta.Thumbnail = await MaterialFactory.GetTextureAsync(GetTextureParam.Create(gltfMeta.texture));
meta.Thumbnail = await TextureFactory.GetTextureAsync(GetTextureParam.Create(gltfMeta.texture));
meta.AllowedUser = gltfMeta.allowedUser;
meta.ViolentUssage = gltfMeta.violentUssage;
meta.SexualUssage = gltfMeta.sexualUssage;