diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs index 53fa5b0d1..f8d7826f5 100644 --- a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs +++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using UniGLTF; using UnityEngine; @@ -68,6 +69,8 @@ namespace UniVRM10 } } + public const string THUMBNAIL_NAME = "__VRM10_thumbnail__"; + /// /// VRM-1 の thumbnail テクスチャー。gltf.textures ではなく gltf.images の参照であることに注意(sampler等の設定が無い) /// @@ -81,14 +84,25 @@ namespace UniVRM10 var imageIndex = vrm.Meta.ThumbnailImage.Value; var gltfImage = data.GLTF.images[imageIndex]; - var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfImage.name, gltfImage.uri); + + // data.GLTF.textures は前処理によりユニーク性がある + // unique な名前を振り出す + var used = new HashSet(data.GLTF.textures.Select(x => x.name)); + var imageName = gltfImage.name; + if (string.IsNullOrEmpty(imageName)) + { + imageName = THUMBNAIL_NAME; + } + var uniqueName = GlbLowLevelParser.FixNameUnique(used, imageName); + + var objectName = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, uniqueName, gltfImage.uri); GetTextureBytesAsync getThumbnailImageBytesAsync = () => { var bytes = data.GLTF.GetImageBytes(data.Storage, imageIndex); return Task.FromResult(GltfTextureImporter.ToArray(bytes)); }; - var texDesc = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default, + var texDesc = new TextureDescriptor(objectName, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default, getThumbnailImageBytesAsync, default, default, default, default, default ); diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs index da0bdfe14..5d027fa91 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs @@ -38,7 +38,7 @@ namespace UniVRM10 var vrm1 = new UniGLTF.Extensions.VRMC_vrm.VRMC_vrm(); // meta (required) - vrm1.Meta = MigrationVrmMeta.Migrate(vrm0["meta"]); + vrm1.Meta = MigrationVrmMeta.Migrate(gltf, vrm0["meta"]); // humanoid (required) vrm1.Humanoid = MigrationVrmHumanoid.Migrate(vrm0["humanoid"]); diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrmMeta.cs b/Assets/VRM10/Runtime/Migration/MigrationVrmMeta.cs index db803c9ea..5756bc275 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrmMeta.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrmMeta.cs @@ -27,7 +27,7 @@ namespace UniVRM10 // }, public static class MigrationVrmMeta { - public static UniGLTF.Extensions.VRMC_vrm.Meta Migrate(JsonNode vrm0) + public static UniGLTF.Extensions.VRMC_vrm.Meta Migrate(UniGLTF.glTF gltf, JsonNode vrm0) { var meta = new UniGLTF.Extensions.VRMC_vrm.Meta { @@ -54,7 +54,21 @@ namespace UniVRM10 case "author": meta.Authors = new List() { kv.Value.GetString() }; break; case "contactInformation": meta.ContactInformation = kv.Value.GetString(); break; case "reference": meta.References = new List() { kv.Value.GetString() }; break; - case "texture": meta.ThumbnailImage = kv.Value.GetInt32(); break; + case "texture": + { + // vrm0x use texture. vrm10 use image + var textureIndex = kv.Value.GetInt32(); + if (textureIndex == -1) + { + meta.ThumbnailImage = -1; + } + else + { + var gltfTexture = gltf.textures[textureIndex]; + meta.ThumbnailImage = gltfTexture.source; + } + break; + } case "allowedUserName": { diff --git a/Assets/VRM10/Tests/ExpressionTests.cs b/Assets/VRM10/Tests/ExpressionTests.cs index 5d2a86592..2095f4438 100644 --- a/Assets/VRM10/Tests/ExpressionTests.cs +++ b/Assets/VRM10/Tests/ExpressionTests.cs @@ -1,4 +1,3 @@ -using System.IO; using System.Linq; using NUnit.Framework; using UnityEngine; @@ -7,34 +6,10 @@ namespace UniVRM10.Test { public class ExpressionTests { - static string AliciaPath - { - get - { - return Path.GetFullPath(Application.dataPath + "/../Tests/Models/Alicia_vrm-0.51/AliciaSolid_vrm-0.51.vrm") - .Replace("\\", "/"); - } - } - - static VRM10Controller Load() - { - Vrm10Data.TryParseOrMigrate(AliciaPath, true, out Vrm10Data vrm); - using (var loader = new Vrm10Importer(vrm)) - { - var task = loader.LoadAsync(new VRMShaders.ImmediateCaller()); - task.Wait(); - - var instance = task.Result; - - return instance.GetComponent(); - } - - } - [Test] public void DuplicatedMaterialColorBindings() { - var controller = Load(); + var controller = TestAsset.LoadAlicia(); var src = controller.Vrm.Expression.Aa.MaterialColorBindings.ToList(); @@ -63,7 +38,7 @@ namespace UniVRM10.Test [Test] public void DuplicatedMaterialUVBindings() { - var controller = Load(); + var controller = TestAsset.LoadAlicia(); var renderers = controller.GetComponentsInChildren(); var name = renderers[0].sharedMaterials[0].name; diff --git a/Assets/VRM10/Tests/LoadTests.cs b/Assets/VRM10/Tests/LoadTests.cs new file mode 100644 index 000000000..4f88785ef --- /dev/null +++ b/Assets/VRM10/Tests/LoadTests.cs @@ -0,0 +1,23 @@ +using NUnit.Framework; + +namespace UniVRM10.Test +{ + public class LoadTests + { + [Test] + public void EmptyThumbnailName() + { + Assert.True(Vrm10Data.TryParseOrMigrate(TestAsset.AliciaPath, true, out Vrm10Data vrm)); + + var index = vrm.VrmExtension.Meta.ThumbnailImage.Value; + + // empty thumbnail name + vrm.Data.GLTF.images[index].name = null; + + using (var loader = new Vrm10Importer(vrm)) + { + loader.LoadAsync(new VRMShaders.ImmediateCaller()).Wait(); + } + } + } +} diff --git a/Assets/VRM10/Tests/LoadTests.cs.meta b/Assets/VRM10/Tests/LoadTests.cs.meta new file mode 100644 index 000000000..2dc13ac5f --- /dev/null +++ b/Assets/VRM10/Tests/LoadTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9a9a3ce2deae9c4791d816aa189df3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Tests/TestAsset.cs b/Assets/VRM10/Tests/TestAsset.cs new file mode 100644 index 000000000..a9ef5e72c --- /dev/null +++ b/Assets/VRM10/Tests/TestAsset.cs @@ -0,0 +1,31 @@ +using System.IO; +using UnityEngine; + +namespace UniVRM10 +{ + public static class TestAsset + { + public static string AliciaPath + { + get + { + return Path.GetFullPath(Application.dataPath + "/../Tests/Models/Alicia_vrm-0.51/AliciaSolid_vrm-0.51.vrm") + .Replace("\\", "/"); + } + } + + public static VRM10Controller LoadAlicia() + { + Vrm10Data.TryParseOrMigrate(AliciaPath, true, out Vrm10Data vrm); + using (var loader = new Vrm10Importer(vrm)) + { + var task = loader.LoadAsync(new VRMShaders.ImmediateCaller()); + task.Wait(); + + var instance = task.Result; + + return instance.GetComponent(); + } + } + } +} diff --git a/Assets/VRM10/Tests/TestAsset.cs.meta b/Assets/VRM10/Tests/TestAsset.cs.meta new file mode 100644 index 000000000..f9145dda7 --- /dev/null +++ b/Assets/VRM10/Tests/TestAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b18f57dcd7d3c19469aa4842b2ee6ae1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: