From 9219612b74e848a399acc084a311a29cc36bb79d Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 13 Aug 2020 16:32:20 +0900 Subject: [PATCH 1/2] * implement SpringBone validation #474 --- .../UniVRM/Editor/Format/VRMExporterWizard.cs | 1 + .../SpringBone/VRMSpringBoneValidator.cs | 70 +++++++++++++++++++ .../SpringBone/VRMSpringBoneValidator.cs.meta | 11 +++ 3 files changed, 82 insertions(+) create mode 100644 Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs create mode 100644 Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs.meta diff --git a/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs b/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs index 0614e9dcf..30969bba7 100644 --- a/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs +++ b/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs @@ -700,6 +700,7 @@ namespace VRM m_validations.Clear(); m_validations.AddRange(Validate()); + m_validations.AddRange(VRMSpringBoneValidator.Validate(ExportRoot)); var hasError = m_validations.Any(x => !x.CanExport); m_IsValid = !hasError && !MetaHasError; diff --git a/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs b/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs new file mode 100644 index 000000000..1f7b58fb6 --- /dev/null +++ b/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace VRM +{ + static class VRMSpringBoneValidator + { + // https://github.com/vrm-c/UniVRM/issues/474 + public static IEnumerable Validate(GameObject root) + { + if (root == null) + { + yield break; + } + + Dictionary> rootMap = new Dictionary>(); + + foreach (var sb in root.GetComponentsInChildren()) + { + foreach (var springRoot in sb.RootBones) + { + if (!rootMap.TryGetValue(springRoot, out List list)) + { + list = new List(); + rootMap.Add(springRoot, list); + } + list.Add(sb); + } + } + + foreach (var kv in rootMap) + { + if (kv.Value.Count > 1) + { + // * GameObjectが複数回ルートとして指定されてる(SpringBoneが同じでも別でも) + var list = string.Join(", ", kv.Value.Select(x => string.IsNullOrEmpty(x.m_comment) ? x.name : x.m_comment)); + yield return Validation.Error($"{kv.Key} found multiple. {list}"); + } + + var rootInRootMap = new Dictionary>(); + foreach (var child in kv.Key.GetComponentsInChildren()) + { + // * Rootから子をだどって、別のRootが現れる + if (child == kv.Key) + { + continue; + } + + if (!rootMap.ContainsKey(child)) + { + continue; + } + + if (!rootInRootMap.TryGetValue(kv.Key, out List rootInRoot)) + { + rootInRoot = new List(); + rootInRootMap.Add(kv.Key, rootInRoot); + } + rootInRoot.Add(child); + } + foreach (var rootList in rootInRootMap) + { + var list = string.Join(", ", rootList.Value.Select(x => x.name)); + yield return Validation.Error($"{rootList.Key} hierarchy contains other root: {list}"); + } + } + } + } +} diff --git a/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs.meta b/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs.meta new file mode 100644 index 000000000..1a9e37b00 --- /dev/null +++ b/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc588ccd280c0e2429d1d3cc3db5d950 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 8379a35357e24ac38c4ffe4d7aaf12dff5cbf55f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 13 Aug 2020 16:39:32 +0900 Subject: [PATCH 2/2] Warning --- Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs b/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs index 1f7b58fb6..d4abef440 100644 --- a/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs +++ b/Assets/VRM/UniVRM/Editor/SpringBone/VRMSpringBoneValidator.cs @@ -35,7 +35,7 @@ namespace VRM { // * GameObjectが複数回ルートとして指定されてる(SpringBoneが同じでも別でも) var list = string.Join(", ", kv.Value.Select(x => string.IsNullOrEmpty(x.m_comment) ? x.name : x.m_comment)); - yield return Validation.Error($"{kv.Key} found multiple. {list}"); + yield return Validation.Warning($"{kv.Key} found multiple. {list}"); } var rootInRootMap = new Dictionary>(); @@ -62,7 +62,7 @@ namespace VRM foreach (var rootList in rootInRootMap) { var list = string.Join(", ", rootList.Value.Select(x => x.name)); - yield return Validation.Error($"{rootList.Key} hierarchy contains other root: {list}"); + yield return Validation.Warning($"{rootList.Key} hierarchy contains other root: {list}"); } } }