diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs index bb597579d..c404a269e 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs @@ -25,28 +25,25 @@ namespace UniGLTF parser.ParsePath(ctx.assetPath); // Build Unity Model - var context = new ImporterContext(parser); + var context = new ImporterContext(parser, GetExternalObjectMap() + .Select(kv => new KeyValuePair(kv.Key.name, kv.Value))); context.Load(); context.ShowMeshes(); // Texture var externalTextures = this.GetExternalUnityObjects(); - foreach (var texture in context.Textures) + foreach (var info in context.TextureFactory.Textures) { - if (texture == null) - { - throw new Exception(); - } - - if (!externalTextures.ContainsValue(texture)) + if (!info.UseExternal) { + var texture = info.Texture; ctx.AddObjectToAsset(texture.name, texture); } } // Material var externalMaterials = this.GetExternalUnityObjects(); - foreach (var material in context.Materials) + foreach (var material in context.MaterialFactory.Materials) { if (material == null) { diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs index 50c283c1a..26a58b739 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporterEditorGUI.cs @@ -19,19 +19,15 @@ namespace UniGLTF EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Materials And Textures"); - GUI.enabled = !(importer.GetExternalUnityObjects().Any() - && importer.GetExternalUnityObjects().Any()); if (GUILayout.Button("Extract")) { importer.ExtractMaterialsAndTextures(); } - GUI.enabled = !GUI.enabled; if (GUILayout.Button("Clear")) { importer.ClearExternalObjects(); importer.ClearExternalObjects(); } - GUI.enabled = true; EditorGUILayout.EndHorizontal(); // ObjectMap diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index d6b83974f..ecd01367a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -37,16 +37,14 @@ namespace UniGLTF MaterialFactory m_materialFactory; public MaterialFactory MaterialFactory => m_materialFactory; - public IEnumerable Materials => m_materialFactory.Materials; TextureFactory m_textureFactory; public TextureFactory TextureFactory => m_textureFactory; - public IEnumerable Textures => m_textureFactory.Textures; - public ImporterContext(GltfParser parser) + public ImporterContext(GltfParser parser, IEnumerable> externalObjectMap = null) { m_parser = parser; - m_textureFactory = new TextureFactory(GLTF, Storage); + m_textureFactory = new TextureFactory(GLTF, Storage, externalObjectMap); m_materialFactory = new MaterialFactory(GLTF, Storage); } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/UnlitMaterialItem.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/UnlitMaterialItem.cs index f1f9ea2f1..007d905b5 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/UnlitMaterialItem.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/UnlitMaterialItem.cs @@ -11,7 +11,7 @@ namespace UniGLTF { if (getTexture == null) { - getTexture = _ => Awaitable.FromResult(null); + getTexture = _ => Awaitable.FromResult(default); } var material = MaterialFactory.CreateMaterial(i, src, ShaderName); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs index 22cd8a31a..410a81ce3 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs @@ -1,23 +1,43 @@ using System; using System.Collections.Generic; using UniGLTF.AltTask; -using UnityEditor; using UnityEngine; +using System.Linq; +#if UNITY_EDITOR +using UnityEditor; +#endif namespace UniGLTF { + public struct TextureLoadInfo + { + public readonly Texture2D Texture; + public readonly bool UseExternal; + + public TextureLoadInfo(Texture2D texture, bool useExternal) + { + Texture = texture; + UseExternal = useExternal; + } + } + public delegate Awaitable GetTextureAsyncFunc(GetTextureParam param); public class TextureFactory : IDisposable { glTF m_gltf; IStorage m_storage; + Dictionary m_externalMap; public UnityPath ImageBaseDir { get; set; } - public TextureFactory(glTF gltf, IStorage storage) + public TextureFactory(glTF gltf, IStorage storage, IEnumerable> externalMap) { m_gltf = gltf; m_storage = storage; + m_externalMap = externalMap + .Select(kv => (kv.Key, kv.Value as Texture2D)) + .Where(kv => kv.Item2 != null) + .ToDictionary(kv => kv.Item1, kv => kv.Item2); } public void Dispose() @@ -32,22 +52,42 @@ namespace UniGLTF { foreach (var kv in m_textureCache) { - yield return kv.Value; + yield return kv.Value.Texture; } } - Dictionary m_textureCache = new Dictionary(); - public IEnumerable Textures => m_textureCache.Values; + Dictionary m_textureCache = new Dictionary(); - public virtual Awaitable LoadTextureAsync(int index) + public IEnumerable Textures => m_textureCache.Values; + + public virtual async Awaitable LoadTextureAsync(int index) { #if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER return UnityWebRequestTextureLoader.LoadTextureAsync(index); #else - return GltfTextureLoader.LoadTextureAsync(m_gltf, m_storage, index); + var texture = await GltfTextureLoader.LoadTextureAsync(m_gltf, m_storage, index); + return new TextureLoadInfo(texture, false); #endif } + public bool TryGetExternal(GetTextureParam param, out Texture2D external) + { + if (param.Index0.HasValue && m_externalMap != null) + { + var gltfTexture = m_gltf.textures[param.Index0.Value]; + m_gltf.GetImageBytes(m_storage, gltfTexture.source, out string textureName); + + if (m_externalMap.TryGetValue(textureName, out external)) + { + Debug.Log($"use external: {textureName}"); + m_textureCache.Add(param, new TextureLoadInfo(external, true)); + return external; + } + } + external = default; + return false; + } + /// /// テクスチャーをロード、必要であれば変換して返す。 /// 同じものはキャッシュを返す @@ -58,17 +98,21 @@ namespace UniGLTF /// public async Awaitable GetTextureAsync(GetTextureParam param) { - if (m_textureCache.TryGetValue(param, out Texture2D texture)) + if (m_textureCache.TryGetValue(param, out TextureLoadInfo info)) { - return texture; + return info.Texture; + } + if (TryGetExternal(param, out Texture2D external)) + { + return external; } { var defaultParam = GetTextureParam.Create(param.Index0.Value); - if (!m_textureCache.TryGetValue(defaultParam, out texture)) + if (!m_textureCache.TryGetValue(defaultParam, out info)) { - texture = await LoadTextureAsync(param.Index0.Value); - m_textureCache.Add(defaultParam, texture); + info = await LoadTextureAsync(param.Index0.Value); + m_textureCache.Add(defaultParam, info); } } @@ -78,49 +122,52 @@ namespace UniGLTF { if (Application.isPlaying) { - var converted = new NormalConverter().GetImportTexture(texture); - m_textureCache.Add(param, converted); + var converted = new NormalConverter().GetImportTexture(info.Texture); converted.name = $"{converted.name}.{GetTextureParam.NORMAL_PROP}"; - return converted; + info = new TextureLoadInfo(converted, false); + m_textureCache.Add(param, info); + return info.Texture; } else { #if UNITY_EDITOR - var textureAssetPath = AssetDatabase.GetAssetPath(texture); + var textureAssetPath = AssetDatabase.GetAssetPath(info.Texture); if (!string.IsNullOrEmpty(textureAssetPath)) { TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath); - texture.name = $"{texture.name}.{GetTextureParam.NORMAL_PROP}"; + info.Texture.name = $"{info.Texture.name}.{GetTextureParam.NORMAL_PROP}"; } else { - Debug.LogWarningFormat("no asset for {0}", texture); + Debug.LogWarningFormat("no asset for {0}", info); } #endif - m_textureCache.Add(param, texture); - return texture; + m_textureCache.Add(param, info); + return info.Texture; } } case GetTextureParam.METALLIC_GLOSS_PROP: { // Bake roughnessFactor values into a texture. - var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(texture); + var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(info.Texture); converted.name = $"{converted.name}.{GetTextureParam.METALLIC_GLOSS_PROP}"; - m_textureCache.Add(param, converted); - return converted; + info = new TextureLoadInfo(converted, false); + m_textureCache.Add(param, info); + return info.Texture; } case GetTextureParam.OCCLUSION_PROP: { - var converted = new OcclusionConverter().GetImportTexture(texture); + var converted = new OcclusionConverter().GetImportTexture(info.Texture); converted.name = $"{converted.name}.{GetTextureParam.OCCLUSION_PROP}"; - m_textureCache.Add(param, converted); - return converted; + info = new TextureLoadInfo(converted, false); + m_textureCache.Add(param, info); + return info.Texture; } default: - return texture; + return info.Texture; } throw new NotImplementedException();