diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs index 071f61e98..ca62fabc0 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterEditorGUI.cs @@ -68,7 +68,7 @@ namespace UniVRM10 case Tabs.Materials: if (m_parser != null) { - EditorMaterial.OnGUI(m_importer, m_parser, Vrm10MaterialImporter.EnumerateAllTexturesDistinct); + EditorMaterial.OnGUI(m_importer, m_parser, Vrm10TextureEnumerator.EnumerateAllTexturesDistinct); } break; diff --git a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs index 1a9bcbceb..833bf8733 100644 --- a/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs +++ b/Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs @@ -99,7 +99,7 @@ namespace UniVRM10 using (var loader = new Vrm10Importer(parser, externalObjectMap)) { // settings TextureImporters - foreach (var (key, textureInfo) in Vrm10MaterialImporter.EnumerateAllTexturesDistinct(parser)) + foreach (var (key, textureInfo) in Vrm10TextureEnumerator.EnumerateAllTexturesDistinct(parser)) { VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap); } diff --git a/Assets/VRM10/Runtime/IO/Texture.meta b/Assets/VRM10/Runtime/IO/Texture.meta new file mode 100644 index 000000000..bd875b83e --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Texture.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7fe27001b96146d3bbc53044ff91b536 +timeCreated: 1620374936 \ No newline at end of file diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs new file mode 100644 index 000000000..d95003738 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using UniGLTF; +using UnityEngine; +using VRMShaders; + +namespace UniVRM10 +{ + public static class Vrm10TextureEnumerator + { + /// + /// glTF 全体で使うテクスチャーをユニークになるように列挙する + /// + public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser) + { + if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)) + { + throw new System.Exception("not vrm"); + } + + var usedTextures = new HashSet(); + + // Thumbnail Texture referenced by VRM Meta. + if (TryGetMetaThumbnailTextureImportParam(parser, vrm, out (SubAssetKey key, TextureImportParam) thumbnail)) + { + if (usedTextures.Add(thumbnail.key)) + { + yield return thumbnail; + } + } + + // Textures referenced by Materials. + for (int i = 0; i < parser.GLTF.materials.Count; ++i) + { + var param = Vrm10MaterialImporter.GetMaterialParam(parser, i); + foreach (var (key, value) in param.EnumerateSubAssetKeyValue()) + { + if (usedTextures.Add(key)) + { + yield return (key, value); + } + } + } + } + + /// + /// VRM-1 の thumbnail テクスチャー。gltf.textures ではなく gltf.images の参照であることに注意(sampler等の設定が無い) + /// + public static bool TryGetMetaThumbnailTextureImportParam(GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, out (SubAssetKey, TextureImportParam) value) + { + if (vrm?.Meta?.ThumbnailImage == null) + { + value = default; + return false; + } + + var imageIndex = vrm.Meta.ThumbnailImage.Value; + var gltfImage = parser.GLTF.images[imageIndex]; + var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfImage.name, gltfImage.uri); + + GetTextureBytesAsync getThumbnailImageBytesAsync = () => + { + var bytes = parser.GLTF.GetImageBytes(parser.Storage, imageIndex); + return Task.FromResult(GltfTextureImporter.ToArray(bytes)); + }; + var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default, + getThumbnailImageBytesAsync, default, default, + default, default, default + ); + var key = new SubAssetKey(typeof(Texture2D), name); + value = (key, param); + return true; + } + + /// + /// Material によって参照されている Texture を Enumerate する. + /// まず VRM Material だと仮定して処理し, 失敗すれば glTF Material だとして処理する. + /// + public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesReferencedByMaterials(GltfParser parser, int i) + { + // VRM + + // Fallback to GLTF + foreach (var kv in GltfTextureEnumerator.EnumerateTexturesReferencedByMaterials(parser, i)) + { + yield return kv; + } + } + } +} \ No newline at end of file diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs.meta b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs.meta new file mode 100644 index 000000000..aa9f50c2b --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureEnumerator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7763318be4064ecba712dcc012dd1cb1 +timeCreated: 1620374912 \ No newline at end of file diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index edd7cc3bd..53768eaba 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -280,7 +280,7 @@ namespace UniVRM10 { m_meta.Authors.AddRange(src.Authors); } - if (Vrm10MaterialImporter.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out (SubAssetKey, VRMShaders.TextureImportParam Param) kv)) + if (Vrm10TextureEnumerator.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out (SubAssetKey, VRMShaders.TextureImportParam Param) kv)) { var texture = await TextureFactory.GetTextureAsync(kv.Param); if (texture != null) diff --git a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs b/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs index 3f42855c1..605a81aa8 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs @@ -176,72 +176,5 @@ namespace UniVRM10 } return param; } - - /// - /// VRM-1 の thumbnail テクスチャー。gltf.textures ではなく gltf.images の参照であることに注意(sampler等の設定が無い) - /// - /// MToonとは無関係だがとりあえずここに - /// - /// - /// - /// - /// - public static bool TryGetMetaThumbnailTextureImportParam(GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, out (SubAssetKey, TextureImportParam) value) - { - if (vrm?.Meta == null || !vrm.Meta.ThumbnailImage.HasValue) - { - value = default; - return false; - } - - // thumbnail - var imageIndex = vrm.Meta.ThumbnailImage.Value; - var gltfImage = parser.GLTF.images[imageIndex]; - var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfImage.name, gltfImage.uri); - - GetTextureBytesAsync getBytesAsync = () => - { - var bytes = parser.GLTF.GetImageBytes(parser.Storage, imageIndex); - return Task.FromResult(GltfTextureImporter.ToArray(bytes)); - }; - var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default, - getBytesAsync, default, default, - default, default, default - ); - var key = new SubAssetKey(typeof(Texture2D), name); - value = (key, param); - return true; - } - - /// - /// glTF 全体で使うテクスチャーをユニークになるように列挙する - /// - /// - /// - public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser) - { - if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)) - { - throw new System.Exception("not vrm"); - } - - if (TryGetMetaThumbnailTextureImportParam(parser, vrm, out (SubAssetKey, TextureImportParam) thumbnail)) - { - yield return thumbnail; - } - - var used = new HashSet(); - for (int i = 0; i < parser.GLTF.materials.Count; ++i) - { - var param = GetMaterialParam(parser, i); - foreach (var (key, value) in param.EnumerateSubAssetKeyValue()) - { - if (used.Add(key)) - { - yield return (key, value); - } - } - } - } } }