From 744221f847fcccc0ae3c5b4db77a6b4455537b40 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 27 Oct 2021 22:00:31 +0900 Subject: [PATCH] Add MigrationVrmExpression.Check --- .../VRM10/Runtime/Migration/MigrationVrm.cs | 3 +- .../Migration/MigrationVrmExpression.cs | 84 +++++++++++++++++++ Assets/VRM10/Tests/MigrationTests.cs | 15 +++- 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs index 3e736a4a4..5f0d7472e 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs @@ -119,10 +119,11 @@ namespace UniVRM10 return Glb.Create(vrm1Json, bin).ToBytes(); } - public static void Check(JsonNode vrm0, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm1) + public static void Check(JsonNode vrm0, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm1, Func MeshToNode) { MigrationVrmMeta.Check(vrm0["meta"], vrm1.Meta); MigrationVrmHumanoid.Check(vrm0["humanoid"], vrm1.Humanoid); + MigrationVrmExpression.Check(vrm0["blendShapeMaster"], vrm1.Expressions, MeshToNode); } public static void Check(JsonNode vrm0, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone vrm1, List nodes) diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs b/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs index 427bb1cbe..ffe0d5d7e 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs @@ -221,5 +221,89 @@ namespace UniVRM10 yield return (preset, name, expression); } } + + static void Check(string name, JsonNode vrm0, UniGLTF.Extensions.VRMC_vrm.Expression vrm1, Func MeshToNode) + { + if (vrm0["binds"].GetArrayCount() == 0) + { + if (vrm1.MorphTargetBinds == null) + { + // OK + return; + } + else + { + throw new MigrationException($"expression.{name}.binds", "different count"); + } + } + + foreach (var (l, r) in Enumerable.Zip(vrm0["binds"].ArrayItems(), vrm1.MorphTargetBinds, (x, y) => (x, y))) + { + var mesh = l["mesh"].GetInt32(); + var node = MeshToNode(mesh); + if (node != r.Node) + { + throw new MigrationException($"expression.{name}.binds.node", $"{node} != {r.Node}"); + } + + var index = l["index"].GetInt32(); + if (index != r.Index) + { + throw new MigrationException($"expression.{name}.binds.index", $"{index} != {r.Index}"); + } + + var weight = l["weight"].GetSingle(); + if (weight != r.Weight) + { + throw new MigrationException($"expression.{name}.binds.weight", $"{weight} != {r.Weight}"); + } + } + } + + public static void Check(JsonNode vrm0, UniGLTF.Extensions.VRMC_vrm.Expressions vrm1, Func MeshToNode) + { + foreach (var blendShape in vrm0["blendShapeGroups"].ArrayItems()) + { + Debug.Log($"{blendShape}"); + var name = blendShape["presetName"].GetString().ToLower(); + switch (name) + { + case "a": Check(name, blendShape, vrm1.Preset.Aa, MeshToNode); break; + case "i": Check(name, blendShape, vrm1.Preset.Ih, MeshToNode); break; + case "u": Check(name, blendShape, vrm1.Preset.Ou, MeshToNode); break; + case "e": Check(name, blendShape, vrm1.Preset.Ee, MeshToNode); break; + case "o": Check(name, blendShape, vrm1.Preset.Oh, MeshToNode); break; + case "blink": Check(name, blendShape, vrm1.Preset.Blink, MeshToNode); break; + case "joy": Check(name, blendShape, vrm1.Preset.Happy, MeshToNode); break; + case "angry": Check(name, blendShape, vrm1.Preset.Angry, MeshToNode); break; + case "sorrow": Check(name, blendShape, vrm1.Preset.Sad, MeshToNode); break; + case "fun": Check(name, blendShape, vrm1.Preset.Relaxed, MeshToNode); break; + case "lookup": Check(name, blendShape, vrm1.Preset.LookUp, MeshToNode); break; + case "lookdown": Check(name, blendShape, vrm1.Preset.LookDown, MeshToNode); break; + case "lookleft": Check(name, blendShape, vrm1.Preset.LookLeft, MeshToNode); break; + case "lookright": Check(name, blendShape, vrm1.Preset.LookRight, MeshToNode); break; + case "blink_l": Check(name, blendShape, vrm1.Preset.BlinkLeft, MeshToNode); break; + case "blink_r": Check(name, blendShape, vrm1.Preset.BlinkRight, MeshToNode); break; + default: + { + string found = default; + foreach (var kv in vrm1.Custom) + { + if (kv.Key.ToLower() == name) + { + Check(name, blendShape, kv.Value, MeshToNode); + found = kv.Key; + break; + } + } + if (found == null) + { + throw new MigrationException(name, $"expression not migrated"); + } + break; + } + } + } + } } } diff --git a/Assets/VRM10/Tests/MigrationTests.cs b/Assets/VRM10/Tests/MigrationTests.cs index d06b496a2..8a68cbfe8 100644 --- a/Assets/VRM10/Tests/MigrationTests.cs +++ b/Assets/VRM10/Tests/MigrationTests.cs @@ -54,8 +54,21 @@ namespace UniVRM10 var json = glb.Json.Bytes.ParseAsJson(); var gltf = UniGLTF.GltfDeserializer.Deserialize(json); + Func meshToNode = (int mesh) => + { + for (int i = 0; i < gltf.nodes.Count; ++i) + { + var node = gltf.nodes[i]; + if (node.mesh == mesh) + { + return i; + } + } + throw new KeyNotFoundException(); + }; + MigrationVrm.Check(vrm0Json, GetExtension(gltf.extensions, UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.ExtensionNameUtf8, - UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.Deserialize)); + UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.Deserialize), meshToNode); MigrationVrm.Check(vrm0Json, GetExtension(gltf.extensions, UniGLTF.Extensions.VRMC_springBone.GltfDeserializer.ExtensionNameUtf8, UniGLTF.Extensions.VRMC_springBone.GltfDeserializer.Deserialize), gltf.nodes); }