From 21f96a5bac313bcb55d7ad2fe8ab017623ee49e2 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 16 Apr 2025 15:03:48 +0900 Subject: [PATCH] add virtual ImporterContext.PreprocessAsync --- Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs | 49 ++++ .../Runtime/UniGLTF/IO/ImporterContext.cs | 20 +- .../UniGLTF/IO/Parser/GlbLowLevelParser.cs | 218 --------------- .../UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs | 260 ++++++++++++++++++ .../Runtime/UniGLTF/IO/RenameUtil.cs.meta | 11 + .../Runtime/UniGLTF/IO/gltfExporter.cs | 31 +-- Assets/VRM/Runtime/IO/VRMImporterContext.cs | 7 + .../Vrm10TextureDescriptorGenerator.cs | 2 +- Assets/VRM10/Runtime/IO/Vrm10Exporter.cs | 3 +- Assets/VRM10/Runtime/IO/Vrm10Importer.cs | 7 + .../VRM10/Runtime/IO/VrmAnimationImporter.cs | 7 + 11 files changed, 363 insertions(+), 252 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs index 2841754fd..95b90e9bd 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs @@ -81,6 +81,14 @@ namespace UniGLTF _storage = storage; MigrationFlags = migrationFlags; + // Version Compatibility + RestoreOlderVersionValues(json, GLTF); + + foreach (var image in GLTF.images) + { + image.uri = PrepareImageUri(image.uri); + } + // init if (Chunks != null) { @@ -97,6 +105,47 @@ namespace UniGLTF _UriCache.Clear(); } + private static void RestoreOlderVersionValues(string Json, glTF GLTF) + { + var parsed = UniJSON.JsonParser.Parse(Json); + for (int i = 0; i < GLTF.images.Count; ++i) + { + if (string.IsNullOrEmpty(GLTF.images[i].name)) + { + try + { + var extraName = parsed["images"][i]["extra"]["name"].Value.GetString(); + if (!string.IsNullOrEmpty(extraName)) + { + GLTF.images[i].name = extraName; + } + } + catch (Exception) + { + // do nothing + } + } + } + } + + static string PrepareImageUri(string uri) + { + if (string.IsNullOrEmpty(uri)) + { + return uri; + } + + if (uri.StartsWith("./")) + { + // skip + uri = uri.Substring(2); + } + + // %20 to ' ' etc... + var unescape = Uri.UnescapeDataString(uri); + return unescape; + } + public static GltfData CreateFromExportForTest(ExportingGltfData data) { return CreateFromGltfDataForTest(data.Gltf, data.BinBytes); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index cebd8c4a3..c000df310 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -14,7 +14,7 @@ namespace UniGLTF { public readonly bool IsAssetImport; private readonly ImporterContextSettings _settings; - + public ITextureDescriptorGenerator TextureDescriptorGenerator { get; protected set; } public IMaterialDescriptorGenerator MaterialDescriptorGenerator { get; protected set; } public TextureFactory TextureFactory { get; } @@ -95,6 +95,9 @@ namespace UniGLTF MeasureTime = new ImporterContextSpeedLog().MeasureTime; } + // 前処理 + await PreprocessAsync(); + if (GLTF.extensionsRequired != null) { var sb = new List(); @@ -142,6 +145,21 @@ namespace UniGLTF return instance; } + /// + /// GlbLowLevelParser.Parse からこちらに移動 + /// + /// + protected virtual Task PreprocessAsync() + { + RenameUtil.FixMeshNameUnique(GLTF); + RenameUtil.FixTextureNameUnique(GLTF); + RenameUtil.FixMaterialNameUnique(GLTF); + RenameUtil.FixNodeName(GLTF); + RenameUtil.FixAnimationNameUnique(GLTF); + + return Task.CompletedTask; + } + public virtual async Task LoadAnimationAsync(IAwaitCaller awaitCaller) { if (GLTF.animations != null && GLTF.animations.Any()) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/Parser/GlbLowLevelParser.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/Parser/GlbLowLevelParser.cs index c1b8798d9..a8c204fd8 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/Parser/GlbLowLevelParser.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/Parser/GlbLowLevelParser.cs @@ -13,9 +13,6 @@ namespace UniGLTF /// public sealed class GlbLowLevelParser { - public static readonly string UniqueFixResourceSuffix = "__UNIGLTF__DUPLICATED__"; - private static readonly Regex _removeUniqueFixResourceSuffix = new Regex($@"^(.+){UniqueFixResourceSuffix}(\d+)$"); - private readonly string _path; private readonly byte[] _binary; @@ -79,191 +76,9 @@ namespace UniGLTF throw new UniGLTFException("unknown gltf version {0}", GLTF.asset.version); } - // Version Compatibility - RestoreOlderVersionValues(json, GLTF); - - FixMeshNameUnique(GLTF); - foreach (var image in GLTF.images) - { - image.uri = PrepareUri(image.uri); - } - FixTextureNameUnique(GLTF); - FixMaterialNameUnique(GLTF); - FixNodeName(GLTF); - FixAnimationNameUnique(GLTF); - return new GltfData(path, json, GLTF, chunks, storage, migrationFlags); } - private static void FixMeshNameUnique(glTF GLTF) - { - var used = new HashSet(); - foreach (var mesh in GLTF.meshes) - { - if (string.IsNullOrEmpty(mesh.name)) - { - // empty - mesh.name = "mesh_" + Guid.NewGuid().ToString("N"); - used.Add(mesh.name); - } - else - { - var lower = mesh.name.ToLower(); - if (used.Contains(lower)) - { - // rename - var uname = lower + "_" + Guid.NewGuid().ToString("N"); - mesh.name = uname; - lower = uname; - } - used.Add(lower); - } - } - } - - private static void RenameImageFromTexture(glTF GLTF, int i) - { - foreach (var texture in GLTF.textures) - { - if (texture.source == i) - { - if (!string.IsNullOrEmpty(texture.name)) - { - GLTF.images[i].name = texture.name; - return; - } - } - } - } - - /// - /// image.uri を前理 - /// - /// - /// - public static string PrepareUri(string uri) - { - if (string.IsNullOrEmpty(uri)) - { - return uri; - } - - if (uri.StartsWith("./")) - { - // skip - uri = uri.Substring(2); - } - - // %20 to ' ' etc... - var unescape = Uri.UnescapeDataString(uri); - return unescape; - } - - /// - /// gltfTexture.name を Unity Asset 名として運用する。 - /// ユニークである必要がある。 - /// - private static void FixTextureNameUnique(glTF GLTF) - { - // NOTE: Windows FileSystem は大文字小文字の違いは同名ファイルとして扱ってしまうため, IgnoreCase で評価する. - var used = new HashSet(StringComparer.OrdinalIgnoreCase); - for (var textureIdx = 0; textureIdx < GLTF.textures.Count; ++textureIdx) - { - var gltfTexture = GLTF.textures[textureIdx]; - if (gltfTexture.source.HasValidIndex()) - { - var gltfImage = GLTF.images[gltfTexture.source.Value]; - if (!string.IsNullOrEmpty(gltfImage.uri) && !gltfImage.uri.StartsWith("data:")) - { - // from image uri - gltfTexture.name = Path.GetFileNameWithoutExtension(gltfImage.uri); - } - if (string.IsNullOrEmpty(gltfTexture.name)) - { - // use image name - gltfTexture.name = gltfImage.name; - } - } - if (string.IsNullOrEmpty(gltfTexture.name)) - { - gltfTexture.name = $"texture_{textureIdx}"; - } - - gltfTexture.name = FixNameUnique(used, gltfTexture.name); - } - } - - private static void FixMaterialNameUnique(glTF GLTF) - { - // NOTE: Windows FileSystem は大文字小文字の違いは同名ファイルとして扱ってしまうため, IgnoreCase で評価する. - var used = new HashSet(StringComparer.OrdinalIgnoreCase); - for (var materialIdx = 0; materialIdx < GLTF.materials.Count; ++materialIdx) - { - var material = GLTF.materials[materialIdx]; - - if (string.IsNullOrEmpty(material.name)) - { - material.name = $"material_{materialIdx}"; - } - - material.name = FixNameUnique(used, material.name); - } - } - - /// - /// rename empty name to $"{index}" - /// - private static void FixNodeName(glTF GLTF) - { - for (var i = 0; i < GLTF.nodes.Count; ++i) - { - var node = GLTF.nodes[i]; - if (string.IsNullOrWhiteSpace(node.name)) - { - node.name = $"{i}"; - } - } - } - - private static void FixAnimationNameUnique(glTF GLTF) - { - // NOTE: Windows FileSystem は大文字小文字の違いは同名ファイルとして扱ってしまうため, IgnoreCase で評価する. - var used = new HashSet(StringComparer.OrdinalIgnoreCase); - for (int i = 0; i < GLTF.animations.Count; ++i) - { - var animation = GLTF.animations[i]; - - if (string.IsNullOrEmpty(animation.name)) - { - animation.name = $"animation_{i}"; - } - - animation.name = FixNameUnique(used, animation.name); - } - } - - private static void RestoreOlderVersionValues(string Json, glTF GLTF) - { - var parsed = UniJSON.JsonParser.Parse(Json); - for (int i = 0; i < GLTF.images.Count; ++i) - { - if (string.IsNullOrEmpty(GLTF.images[i].name)) - { - try - { - var extraName = parsed["images"][i]["extra"]["name"].Value.GetString(); - if (!string.IsNullOrEmpty(extraName)) - { - GLTF.images[i].name = extraName; - } - } - catch (Exception) - { - // do nothing - } - } - } - } public static void AppendImageExtension(glTFImage texture, string extension) { @@ -272,38 +87,5 @@ namespace UniGLTF texture.name = texture.name + extension; } } - - public static string FixNameUnique(HashSet used, string originalName) - { - if (used.Add(originalName)) - { - return originalName; - } - - var duplicatedIdx = 2; - while (true) - { - var newName = $"{originalName}{UniqueFixResourceSuffix}{duplicatedIdx++}"; - if (used.Add(newName)) - { - return newName; - } - } - } - - public static bool TryGetOriginalName(string name, out string originalName) - { - var match = _removeUniqueFixResourceSuffix.Match(name); - if (match.Success) - { - originalName = match.Groups[1].Value; - return true; - } - else - { - originalName = name; - return false; - } - } } } \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs new file mode 100644 index 000000000..77433b962 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs @@ -0,0 +1,260 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + +namespace UniGLTF +{ + public static class RenameUtil + { + public static readonly string UniqueFixResourceSuffix = "__UNIGLTF__DUPLICATED__"; + private static readonly Regex _removeUniqueFixResourceSuffix = new Regex($@"^(.+){UniqueFixResourceSuffix}(\d+)$"); + + public static string FixNameUnique(HashSet used, string originalName) + { + if (used.Add(originalName)) + { + return originalName; + } + + var duplicatedIdx = 2; + while (true) + { + var newName = $"{originalName}{UniqueFixResourceSuffix}{duplicatedIdx++}"; + if (used.Add(newName)) + { + return newName; + } + } + } + + /// + /// GlbLowLevelParser.FixNameUnique で付与した Suffix を remove + /// + public static void FixName(glTF gltf) + { + var regex = new Regex($@"{UniqueFixResourceSuffix}\d+$"); + foreach (var gltfImages in gltf.images) + { + if (regex.IsMatch(gltfImages.name)) + { + gltfImages.name = regex.Replace(gltfImages.name, string.Empty); + } + } + foreach (var gltfMaterial in gltf.materials) + { + if (regex.IsMatch(gltfMaterial.name)) + { + gltfMaterial.name = regex.Replace(gltfMaterial.name, string.Empty); + } + } + foreach (var gltfAnimation in gltf.animations) + { + if (regex.IsMatch(gltfAnimation.name)) + { + gltfAnimation.name = regex.Replace(gltfAnimation.name, string.Empty); + } + } + } + + [Obsolete] + public static bool TryGetOriginalName(string name, out string originalName) + { + var match = _removeUniqueFixResourceSuffix.Match(name); + if (match.Success) + { + originalName = match.Groups[1].Value; + return true; + } + else + { + originalName = name; + return false; + } + } + + public static void FixMeshNameUnique(glTF GLTF) + { + var used = new HashSet(); + foreach (var mesh in GLTF.meshes) + { + if (string.IsNullOrEmpty(mesh.name)) + { + // empty + mesh.name = "mesh_" + Guid.NewGuid().ToString("N"); + used.Add(mesh.name); + } + else + { + var lower = mesh.name.ToLower(); + if (used.Contains(lower)) + { + // rename + var uname = lower + "_" + Guid.NewGuid().ToString("N"); + mesh.name = uname; + lower = uname; + } + used.Add(lower); + } + } + } + + [Obsolete] + public static void RenameImageFromTexture(glTF GLTF, int i) + { + foreach (var texture in GLTF.textures) + { + if (texture.source == i) + { + if (!string.IsNullOrEmpty(texture.name)) + { + GLTF.images[i].name = texture.name; + return; + } + } + } + } + + /// + /// gltfTexture.name を Unity Asset 名として運用する。 + /// ユニークである必要がある。 + /// + public static void FixTextureNameUnique(glTF GLTF) + { + // NOTE: Windows FileSystem は大文字小文字の違いは同名ファイルとして扱ってしまうため, IgnoreCase で評価する. + var used = new HashSet(StringComparer.OrdinalIgnoreCase); + for (var textureIdx = 0; textureIdx < GLTF.textures.Count; ++textureIdx) + { + var gltfTexture = GLTF.textures[textureIdx]; + if (gltfTexture.source.HasValidIndex()) + { + var gltfImage = GLTF.images[gltfTexture.source.Value]; + if (!string.IsNullOrEmpty(gltfImage.uri) && !gltfImage.uri.StartsWith("data:")) + { + // from image uri + gltfTexture.name = Path.GetFileNameWithoutExtension(gltfImage.uri); + } + if (string.IsNullOrEmpty(gltfTexture.name)) + { + // use image name + gltfTexture.name = gltfImage.name; + } + } + if (string.IsNullOrEmpty(gltfTexture.name)) + { + gltfTexture.name = $"texture_{textureIdx}"; + } + + gltfTexture.name = FixNameUnique(used, gltfTexture.name); + } + } + + public static void FixMaterialNameUnique(glTF GLTF) + { + // NOTE: Windows FileSystem は大文字小文字の違いは同名ファイルとして扱ってしまうため, IgnoreCase で評価する. + var used = new HashSet(StringComparer.OrdinalIgnoreCase); + for (var materialIdx = 0; materialIdx < GLTF.materials.Count; ++materialIdx) + { + var material = GLTF.materials[materialIdx]; + + if (string.IsNullOrEmpty(material.name)) + { + material.name = $"material_{materialIdx}"; + } + + material.name = FixNameUnique(used, material.name); + } + } + + /// + /// rename empty name to $"{index}" + /// + public static void FixNodeName(glTF GLTF) + { + for (var i = 0; i < GLTF.nodes.Count; ++i) + { + var node = GLTF.nodes[i]; + if (string.IsNullOrWhiteSpace(node.name)) + { + node.name = $"{i}"; + } + } + } + + public static void FixAnimationNameUnique(glTF GLTF) + { + // NOTE: Windows FileSystem は大文字小文字の違いは同名ファイルとして扱ってしまうため, IgnoreCase で評価する. + var used = new HashSet(StringComparer.OrdinalIgnoreCase); + for (int i = 0; i < GLTF.animations.Count; ++i) + { + var animation = GLTF.animations[i]; + + if (string.IsNullOrEmpty(animation.name)) + { + animation.name = $"animation_{i}"; + } + + animation.name = FixNameUnique(used, animation.name); + } + } + + public static void FixNodeNameUnique(glTF GLTF) + { + var m_uniqueNameSet = new HashSet(); + int counter = 1; + for (var i = 0; i < GLTF.nodes.Count; ++i) + { + RenameIfDupName(GLTF.nodes, i, m_uniqueNameSet, ref counter); + } + } + + static void RenameIfDupName(List nodes, int index, HashSet m_uniqueNameSet, ref int m_counter) + { + var t = nodes[index]; + + if (!m_uniqueNameSet.Contains(t.name)) + { + m_uniqueNameSet.Add(t.name); + return; + } + + var parent = nodes.FirstOrDefault(x => x.children.Contains(index)); + if (parent != null && t.children.Length == 0) + { + /// AvatarBuilder:BuildHumanAvatar で同名の Transform があるとエラーになる。 + /// + /// AvatarBuilder 'GLTF': Ambiguous Transform '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/neck_1/neck_2/head/ENDSITE' and '32/root/torso_1/torso_2/torso_3/torso_4/torso_5/torso_6/torso_7/l_shoulder/l_up_arm/l_low_arm/l_hand/ENDSITE' found in hierarchy for human bone 'Head'. Transform name mapped to a human bone must be unique. + /// UnityEngine.AvatarBuilder:BuildHumanAvatar (UnityEngine.GameObject,UnityEngine.HumanDescription) + /// UniHumanoid.AvatarDescription:CreateAvatar (UnityEngine.Transform) + /// + /// 主に BVH の EndSite 由来の GameObject 名が重複することへの対策 + /// ex: parent-ENDSITE + var newName = $"{parent.name}-{t.name}"; + if (!m_uniqueNameSet.Contains(newName)) + { + UniGLTFLogger.Warning($"force rename !!: {t.name} => {newName}"); + t.name = newName; + m_uniqueNameSet.Add(newName); + return; + } + } + + // 連番 + for (int i = 0; i < 100; ++i) + { + // ex: name.1 + var newName = $"{t.name}{m_counter++}"; + if (!m_uniqueNameSet.Contains(newName)) + { + UniGLTFLogger.Warning($"force rename: {t.name} => {newName}"); + t.name = newName; + m_uniqueNameSet.Add(newName); + return; + } + } + + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs.meta new file mode 100644 index 000000000..41b3ab0b0 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/RenameUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ded08d75fb22a94f80265d4403d5b3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index e2d09bb06..54a3f5e76 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -366,36 +366,7 @@ namespace UniGLTF GltfTextureExporter.PushGltfTexture(_data, unityTexture, colorSpace, m_textureSerializer); } - FixName(_gltf); - } - - /// - /// GlbLowLevelParser.FixNameUnique で付与した Suffix を remove - /// - public static void FixName(glTF gltf) - { - var regex = new Regex($@"{GlbLowLevelParser.UniqueFixResourceSuffix}\d+$"); - foreach (var gltfImages in gltf.images) - { - if (regex.IsMatch(gltfImages.name)) - { - gltfImages.name = regex.Replace(gltfImages.name, string.Empty); - } - } - foreach (var gltfMaterial in gltf.materials) - { - if (regex.IsMatch(gltfMaterial.name)) - { - gltfMaterial.name = regex.Replace(gltfMaterial.name, string.Empty); - } - } - foreach (var gltfAnimation in gltf.animations) - { - if (regex.IsMatch(gltfAnimation.name)) - { - gltfAnimation.name = regex.Replace(gltfAnimation.name, string.Empty); - } - } + RenameUtil.FixName(_gltf); } #endregion } diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index 98dc2bf7a..b19da5945 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -36,6 +36,13 @@ namespace VRM _springBoneRuntime = springboneRuntime ?? new Vrm0XSpringBoneDefaultRuntime(); } + protected override Task PreprocessAsync() + { + base.PreprocessAsync(); + RenameUtil.FixNodeNameUnique(GLTF); + return Task.CompletedTask; + } + #region OnLoad protected override async Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func MeasureTime) { diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs index ed7ea65c0..2d1a1092c 100644 --- a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs +++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs @@ -95,7 +95,7 @@ namespace UniVRM10 // data.GLTF.textures は前処理によりユニーク性がある // unique な名前を振り出す var used = new HashSet(data.GLTF.textures.Select(x => x.name)); - var uniqueName = GlbLowLevelParser.FixNameUnique(used, UniqueThumbnailName); + var uniqueName = RenameUtil.FixNameUnique(used, UniqueThumbnailName); value = GltfTextureImporter.CreateSrgbFromOnlyImage(data, imageIndex, uniqueName, gltfImage.uri); return true; diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index db12de492..35d8ccf4b 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -235,10 +235,9 @@ namespace UniVRM10 } // Fix Duplicated name - gltfExporter.FixName(Storage.Gltf); + RenameUtil.FixName(Storage.Gltf); } - /// /// VRMコンポーネントのエクスポート /// diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 3c28d48e2..def5742ba 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -79,6 +79,13 @@ namespace UniVRM10 m_springboneRuntime = springboneRuntime; } + protected override Task PreprocessAsync() + { + base.PreprocessAsync(); + RenameUtil.FixNodeNameUnique(GLTF); + return Task.CompletedTask; + } + static void AssignHumanoid(List nodes, UniGLTF.Extensions.VRMC_vrm.HumanBone humanBone, VrmLib.HumanoidBones key) { if (nodes == null) diff --git a/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs b/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs index b46c8f2d5..21223d9ee 100644 --- a/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs +++ b/Assets/VRM10/Runtime/IO/VrmAnimationImporter.cs @@ -26,6 +26,13 @@ namespace UniVRM10 m_vrma = GetExtension(Data); } + protected override Task PreprocessAsync() + { + base.PreprocessAsync(); + RenameUtil.FixNodeNameUnique(GLTF); + return Task.CompletedTask; + } + private static VRMC_vrm_animation GetExtension(GltfData data) { if (data.GLTF.extensions is UniGLTF.glTFExtensionImport extensions)