From 1fef3fcce818c0b7155712df8de8405f8bcb9dc6 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 18 Jan 2022 15:45:25 +0900 Subject: [PATCH 1/4] =?UTF-8?q?vrm-0.x=20=E3=81=AE=E4=BB=95=E6=A7=98?= =?UTF-8?q?=E3=81=A7=E3=80=81preset:=20unknown=20=E3=81=AE=E3=81=A8?= =?UTF-8?q?=E3=81=8D=E3=81=AB=20name=20=E3=82=92=20preset=20=E3=81=A8?= =?UTF-8?q?=E3=81=97=E3=81=A6=E8=A7=A3=E9=87=88=E3=81=99=E3=82=8B=E3=81=AB?= =?UTF-8?q?=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/Migration/MigrationVrmExpression.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs b/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs index b0eb44603..c2f362817 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs @@ -8,12 +8,17 @@ namespace UniVRM10 { public static class MigrationVrmExpression { - static ExpressionPreset ToPreset(JsonNode json) + static ExpressionPreset ToPreset(JsonNode json, string name) { - switch (json.GetString().ToLower()) + var src = json.GetString().ToLower(); + if (src == "unknown") { - case "unknown": return ExpressionPreset.custom; + // fallback + src = name.ToLower(); + } + switch (src) + { // https://github.com/vrm-c/vrm-specification/issues/185 case "neutral": return ExpressionPreset.neutral; @@ -39,7 +44,7 @@ namespace UniVRM10 case "lookright": return ExpressionPreset.lookRight; } - throw new NotImplementedException(); + return ExpressionPreset.custom; } static IEnumerable ToMorphTargetBinds(JsonNode json, @@ -199,7 +204,7 @@ namespace UniVRM10 { isBinary = isBinaryNode.GetBoolean(); } - var preset = ToPreset(blendShapeClip["presetName"]); + var preset = ToPreset(blendShapeClip["presetName"], name); var expression = new UniGLTF.Extensions.VRMC_vrm.Expression { IsBinary = isBinary, From 7abe05827b4667f586c6771990f2aafc0cd6171e Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 18 Jan 2022 20:35:01 +0900 Subject: [PATCH 2/4] ToLowerInvariant --- Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs b/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs index c2f362817..3ef95c2ec 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs @@ -10,11 +10,11 @@ namespace UniVRM10 { static ExpressionPreset ToPreset(JsonNode json, string name) { - var src = json.GetString().ToLower(); + var src = json.GetString().ToLowerInvariant(); if (src == "unknown") { // fallback - src = name.ToLower(); + src = name.ToLowerInvariant(); } switch (src) From cca4a54b0b69274f09169d71877971841198071b Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 18 Jan 2022 20:50:10 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=E5=90=8C=E5=90=8D=E3=81=8C=E8=A4=87?= =?UTF-8?q?=E6=95=B0=E3=81=AE=E6=99=82=E3=80=81=E5=85=88=E3=81=AB=E6=9D=A5?= =?UTF-8?q?=E3=81=9F=E6=96=B9=E3=81=8C=E5=8B=9D=E3=81=A4=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit コメント増量 --- .../VRM10/Runtime/Migration/MigrationVrm.cs | 67 +++++++++++++------ .../Migration/MigrationVrmExpression.cs | 14 +++- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs index e0039714f..6bfe09f92 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs @@ -10,6 +10,8 @@ namespace UniVRM10 /// public static class MigrationVrm { + const string NEUTRAL_KEY = "Neutral"; + public static byte[] Migrate(byte[] src) { var data = new GlbBinaryParser(src, "migration").Parse(); @@ -40,6 +42,20 @@ namespace UniVRM10 return MigrateVrm(gltf, bin, data.Json.ParseAsJson()["extensions"]["VRM"]); } + /// + /// dst が null の場合だけ代入する。 + /// 先に来た方を有効にしたい。 + /// + /// + /// + static void SetIfNull(ref UniGLTF.Extensions.VRMC_vrm.Expression dst, UniGLTF.Extensions.VRMC_vrm.Expression src) + { + if (dst == null) + { + dst = src; + } + } + static byte[] MigrateVrm(glTF gltf, ArraySegment bin, JsonNode vrm0) { var meshToNode = CreateMeshToNode(gltf); @@ -65,25 +81,38 @@ namespace UniVRM10 { switch (preset) { - case ExpressionPreset.happy: vrm1.Expressions.Preset.Happy = expression; break; - case ExpressionPreset.angry: vrm1.Expressions.Preset.Angry = expression; break; - case ExpressionPreset.sad: vrm1.Expressions.Preset.Sad = expression; break; - case ExpressionPreset.relaxed: vrm1.Expressions.Preset.Relaxed = expression; break; - case ExpressionPreset.surprised: vrm1.Expressions.Preset.Surprised = expression; break; - case ExpressionPreset.aa: vrm1.Expressions.Preset.Aa = expression; break; - case ExpressionPreset.ih: vrm1.Expressions.Preset.Ih = expression; break; - case ExpressionPreset.ou: vrm1.Expressions.Preset.Ou = expression; break; - case ExpressionPreset.ee: vrm1.Expressions.Preset.Ee = expression; break; - case ExpressionPreset.oh: vrm1.Expressions.Preset.Oh = expression; break; - case ExpressionPreset.blink: vrm1.Expressions.Preset.Blink = expression; break; - case ExpressionPreset.blinkLeft: vrm1.Expressions.Preset.BlinkLeft = expression; break; - case ExpressionPreset.blinkRight: vrm1.Expressions.Preset.BlinkRight = expression; break; - case ExpressionPreset.lookUp: vrm1.Expressions.Preset.LookUp = expression; break; - case ExpressionPreset.lookDown: vrm1.Expressions.Preset.LookDown = expression; break; - case ExpressionPreset.lookLeft: vrm1.Expressions.Preset.LookLeft = expression; break; - case ExpressionPreset.lookRight: vrm1.Expressions.Preset.LookRight = expression; break; - case ExpressionPreset.neutral: vrm1.Expressions.Custom[customName] = expression; break; - case ExpressionPreset.custom: vrm1.Expressions.Custom[customName] = expression; break; + case ExpressionPreset.happy: SetIfNull(ref vrm1.Expressions.Preset.Happy, expression); break; + case ExpressionPreset.angry: SetIfNull(ref vrm1.Expressions.Preset.Angry, expression); break; + case ExpressionPreset.sad: SetIfNull(ref vrm1.Expressions.Preset.Sad, expression); break; + case ExpressionPreset.relaxed: SetIfNull(ref vrm1.Expressions.Preset.Relaxed, expression); break; + case ExpressionPreset.surprised: SetIfNull(ref vrm1.Expressions.Preset.Surprised, expression); break; + case ExpressionPreset.aa: SetIfNull(ref vrm1.Expressions.Preset.Aa, expression); break; + case ExpressionPreset.ih: SetIfNull(ref vrm1.Expressions.Preset.Ih, expression); break; + case ExpressionPreset.ou: SetIfNull(ref vrm1.Expressions.Preset.Ou, expression); break; + case ExpressionPreset.ee: SetIfNull(ref vrm1.Expressions.Preset.Ee, expression); break; + case ExpressionPreset.oh: SetIfNull(ref vrm1.Expressions.Preset.Oh, expression); break; + case ExpressionPreset.blink: SetIfNull(ref vrm1.Expressions.Preset.Blink, expression); break; + case ExpressionPreset.blinkLeft: SetIfNull(ref vrm1.Expressions.Preset.BlinkLeft, expression); break; + case ExpressionPreset.blinkRight: SetIfNull(ref vrm1.Expressions.Preset.BlinkRight, expression); break; + case ExpressionPreset.lookUp: SetIfNull(ref vrm1.Expressions.Preset.LookUp, expression); break; + case ExpressionPreset.lookDown: SetIfNull(ref vrm1.Expressions.Preset.LookDown, expression); break; + case ExpressionPreset.lookLeft: SetIfNull(ref vrm1.Expressions.Preset.LookLeft, expression); break; + case ExpressionPreset.lookRight: SetIfNull(ref vrm1.Expressions.Preset.LookRight, expression); break; + case ExpressionPreset.neutral: + // TODO: 仕様確定待ち + // Presetに格上げするか、小文字にする + vrm1.Expressions.Custom[NEUTRAL_KEY] = expression; + break; + case ExpressionPreset.custom: + if (vrm1.Expressions.Custom.ContainsKey(customName)) + { + // 同名が既存。不採用 + } + else + { + vrm1.Expressions.Custom[customName] = expression; + } + break; default: throw new NotImplementedException(); } } diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs b/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs index 3ef95c2ec..628863a98 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrmExpression.cs @@ -8,12 +8,24 @@ namespace UniVRM10 { public static class MigrationVrmExpression { + /// + /// preset 名の文字列から ExpressionPreset を確定させる。 + /// + /// 0.x の特殊な挙動として、 + /// preset名が "unknown" の場合に、 + /// "name" を preset 名として解釈を試みる。 + /// + /// + /// + /// static ExpressionPreset ToPreset(JsonNode json, string name) { var src = json.GetString().ToLowerInvariant(); if (src == "unknown") { - // fallback + // VRM 0.x では以下の実装が存在した。 + // Preset が unknown で Name が Joy の表情があったときに + // それは Preset が Joy であるとみなしてロードしていた。 src = name.ToLowerInvariant(); } From bc7b6ffda16f0e26f42e267404b47cd5b96720fe Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 18 Jan 2022 21:07:26 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Vrm10Importer=20=E3=81=A7=20Neutral=20?= =?UTF-8?q?=E3=82=92=E3=80=80Custom=20=E3=81=8B=E3=82=89=E6=95=91=E5=87=BA?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/VRM10Object/VRM10ObjectExpression.cs | 2 ++ Assets/VRM10/Runtime/IO/Vrm10Importer.cs | 8 ++++++++ Assets/VRM10/Runtime/Migration/MigrationVrm.cs | 4 +--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectExpression.cs b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectExpression.cs index e9a99e213..ca4b8bc99 100644 --- a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectExpression.cs +++ b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectExpression.cs @@ -9,6 +9,8 @@ namespace UniVRM10 [Serializable] public sealed class VRM10ObjectExpression { + public const string NEUTRAL_KEY = "Neutral"; + #region Preset [SerializeField, Header("Emotion")] public VRM10Expression Happy; diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 0468fd08a..82dcc4a3b 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -427,6 +427,14 @@ namespace UniVRM10 { var key = ExpressionKey.CreateCustom(name); var preset = ExpressionPreset.custom; + if (preset == ExpressionPreset.custom && name == VRM10ObjectExpression.NEUTRAL_KEY) + { + // TODO: + // 注意!JsonSchema の更新待ち? + key = ExpressionKey.CreateFromPreset(ExpressionPreset.neutral); + Debug.Log($"set neutral"); + preset = ExpressionPreset.neutral; + } var clip = GetOrLoadExpression(key.SubAssetKey, preset, expression); if (clip != null) { diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs index 6bfe09f92..294ac93dd 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs @@ -10,8 +10,6 @@ namespace UniVRM10 /// public static class MigrationVrm { - const string NEUTRAL_KEY = "Neutral"; - public static byte[] Migrate(byte[] src) { var data = new GlbBinaryParser(src, "migration").Parse(); @@ -101,7 +99,7 @@ namespace UniVRM10 case ExpressionPreset.neutral: // TODO: 仕様確定待ち // Presetに格上げするか、小文字にする - vrm1.Expressions.Custom[NEUTRAL_KEY] = expression; + vrm1.Expressions.Custom[VRM10ObjectExpression.NEUTRAL_KEY] = expression; break; case ExpressionPreset.custom: if (vrm1.Expressions.Custom.ContainsKey(customName))