diff --git a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs index 76273b504..92ebdd232 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ScriptedImporter/GltfScriptedImporter.cs @@ -39,7 +39,11 @@ namespace UniGLTF // Texture foreach (var info in context.TextureFactory.Textures) { - if (!info.UseExternal) + if (!info.IsUsed) + { + continue; + } + if (!info.IsExternal) { var texture = info.Texture; ctx.AddObjectToAsset(texture.name, texture); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs index f4ad2a21e..b3b4048b4 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs @@ -108,12 +108,11 @@ namespace UniGLTF if (TryGetExternal(i, out Material material)) { m_materials.Add(new MaterialLoadInfo(material, true)); + continue; } - else - { - material = await CreateMaterialAsync(m_gltf, i, getTexture); - m_materials.Add(new MaterialLoadInfo(material, false)); - } + + material = await CreateMaterialAsync(m_gltf, i, getTexture); + m_materials.Add(new MaterialLoadInfo(material, false)); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs index 8063ba702..9e156fe4e 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureLoader/TextureFactory.cs @@ -9,15 +9,34 @@ using UnityEditor; namespace UniGLTF { + [Flags] + public enum TextureLoadFlags + { + None = 0, + Used = 1, + External = 1 << 1, + } + public struct TextureLoadInfo { public readonly Texture2D Texture; - public readonly bool UseExternal; + public readonly TextureLoadFlags Flags; + public bool IsUsed => Flags.HasFlag(TextureLoadFlags.Used); + public bool IsExternal => Flags.HasFlag(TextureLoadFlags.External); - public TextureLoadInfo(Texture2D texture, bool useExternal) + public TextureLoadInfo(Texture2D texture, bool used, bool isExternal) { Texture = texture; - UseExternal = useExternal; + var flags = TextureLoadFlags.None; + if (used) + { + flags |= TextureLoadFlags.Used; + } + if (isExternal) + { + flags |= TextureLoadFlags.External; + } + Flags = flags; } } @@ -27,7 +46,7 @@ namespace UniGLTF glTF m_gltf; IStorage m_storage; Dictionary m_externalMap; - public bool TryGetExternal(GetTextureParam param, out Texture2D external) + public bool TryGetExternal(GetTextureParam param, bool used, out Texture2D external) { if (param.Index0.HasValue && m_externalMap != null) { @@ -37,7 +56,7 @@ namespace UniGLTF if (m_externalMap.TryGetValue(textureName, out external)) { Debug.Log($"use external: {textureName}"); - m_textureCache.Add(param, new TextureLoadInfo(external, true)); + m_textureCache.Add(param, new TextureLoadInfo(external, used, true)); return external; } } @@ -81,16 +100,27 @@ namespace UniGLTF public IEnumerable Textures => m_textureCache.Values; - public virtual async Awaitable LoadTextureAsync(int index) + public virtual async Awaitable LoadTextureAsync(int index, bool used) { #if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER return UnityWebRequestTextureLoader.LoadTextureAsync(index); #else var texture = await GltfTextureLoader.LoadTextureAsync(m_gltf, m_storage, index); - return new TextureLoadInfo(texture, false); + return new TextureLoadInfo(texture, used, false); #endif } + async Awaitable GetOrCreateBaseTexture(glTF gltf, int index, bool used) + { + var defaultParam = GetTextureParam.Create(gltf, index); + if (!m_textureCache.TryGetValue(defaultParam, out TextureLoadInfo cacheInfo)) + { + cacheInfo = await LoadTextureAsync(index, used); + m_textureCache.Add(defaultParam, cacheInfo); + } + return cacheInfo.Texture; + } + /// /// テクスチャーをロード、必要であれば変換して返す。 /// 同じものはキャッシュを返す @@ -101,22 +131,14 @@ namespace UniGLTF /// public async Awaitable GetTextureAsync(glTF gltf, GetTextureParam param) { - if (m_textureCache.TryGetValue(param, out TextureLoadInfo info)) - { - return info.Texture; - } - if (TryGetExternal(param, out Texture2D external)) + if (TryGetExternal(param, true, out Texture2D external)) { return external; } + if (m_textureCache.TryGetValue(param, out TextureLoadInfo cacheInfo)) { - var defaultParam = GetTextureParam.Create(gltf, param.Index0.Value); - if (!m_textureCache.TryGetValue(defaultParam, out info)) - { - info = await LoadTextureAsync(param.Index0.Value); - m_textureCache.Add(defaultParam, info); - } + return cacheInfo.Texture; } switch (param.TextureType) @@ -125,27 +147,23 @@ namespace UniGLTF { if (Application.isPlaying) { - var converted = new NormalConverter().GetImportTexture(info.Texture); + var baseTexture = await GetOrCreateBaseTexture(gltf, param.Index0.Value, false); + var converted = new NormalConverter().GetImportTexture(baseTexture); converted.name = $"{converted.name}.{GetTextureParam.NORMAL_PROP}"; - info = new TextureLoadInfo(converted, false); + var info = new TextureLoadInfo(converted, true, false); m_textureCache.Add(param, info); return info.Texture; } else { #if UNITY_EDITOR + var info = await LoadTextureAsync(param.Index0.Value, true); + m_textureCache.Add(GetTextureParam.CreateNormal(gltf, param.Index0.Value), info); + var textureAssetPath = AssetDatabase.GetAssetPath(info.Texture); - if (!string.IsNullOrEmpty(textureAssetPath)) - { - TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath); - info.Texture.name = $"{info.Texture.name}.{GetTextureParam.NORMAL_PROP}"; - } - else - { - Debug.LogWarningFormat("no asset for {0}", info); - } + TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath); + info.Texture.name = $"{info.Texture.name}.{GetTextureParam.NORMAL_PROP}"; #endif - m_textureCache.Add(param, info); return info.Texture; } } @@ -153,27 +171,32 @@ namespace UniGLTF case GetTextureParam.METALLIC_GLOSS_PROP: { // Bake roughnessFactor values into a texture. - var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(info.Texture); + var baseTexture = await GetOrCreateBaseTexture(gltf, param.Index0.Value, false); + var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(baseTexture); converted.name = $"{converted.name}.{GetTextureParam.METALLIC_GLOSS_PROP}"; - info = new TextureLoadInfo(converted, false); + var info = new TextureLoadInfo(converted, true, false); m_textureCache.Add(param, info); return info.Texture; } case GetTextureParam.OCCLUSION_PROP: { - var converted = new OcclusionConverter().GetImportTexture(info.Texture); + var baseTexture = await GetOrCreateBaseTexture(gltf, param.Index0.Value, false); + var converted = new OcclusionConverter().GetImportTexture(baseTexture); converted.name = $"{converted.name}.{GetTextureParam.OCCLUSION_PROP}"; - info = new TextureLoadInfo(converted, false); + var info = new TextureLoadInfo(converted, true, false); m_textureCache.Add(param, info); return info.Texture; } default: - return info.Texture; - } + { + var baseTexture = await GetOrCreateBaseTexture(gltf, param.Index0.Value, true); + return baseTexture; + } - throw new NotImplementedException(); + throw new NotImplementedException(); + } } } }