From 612566ed6d70db1b234cba648cc3f9c5b33fcf9c Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 10 Nov 2020 19:17:19 +0900 Subject: [PATCH 1/6] =?UTF-8?q?=E6=96=87=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Editor/ExportDialog/Valildators/HumanoidValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs b/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs index a1100d465..69fff4517 100644 --- a/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs +++ b/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs @@ -37,7 +37,7 @@ namespace MeshUtility.Validators [LangMsg(Languages.en, "Animator.avatar is not humanoid. Please change model's AnimationType to humanoid")] AVATAR_IS_NOT_HUMANOID, - [LangMsg(Languages.ja, "humanoid設定に顎が含まれている。FBX importer の rig 設定に戻って設定を解除することをおすすめします")] + [LangMsg(Languages.ja, "Jaw(顎)ボーンが含まれています。意図していない場合は設定解除をおすすめします。FBX importer の rig 設定から変更できます")] [LangMsg(Languages.en, "Jaw bone is included. It may not what you intended. Please check the humanoid avatar setting screen")] JAW_BONE_IS_INCLUDED, } From 00489d18620684d7d2e6bfe733e140f913bac1d3 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 10 Nov 2020 19:42:44 +0900 Subject: [PATCH 2/6] =?UTF-8?q?Force=20T-Pose=20check=20box=20=E3=82=92=20?= =?UTF-8?q?T-Pose=20=E3=83=9C=E3=82=BF=E3=83=B3=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UniVRM/Editor/Format/VRMExportSettings.cs | 2 ++ .../Editor/Format/VRMExportSettingsEditor.cs | 34 ++++++++++++++----- .../UniVRM/Editor/Format/VRMExporterWizard.cs | 3 +- .../SkinnedMeshUtility/VRMBoneNormalizer.cs | 2 +- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Assets/VRM/UniVRM/Editor/Format/VRMExportSettings.cs b/Assets/VRM/UniVRM/Editor/Format/VRMExportSettings.cs index 35205b54a..2e0f2e89e 100644 --- a/Assets/VRM/UniVRM/Editor/Format/VRMExportSettings.cs +++ b/Assets/VRM/UniVRM/Editor/Format/VRMExportSettings.cs @@ -48,5 +48,7 @@ namespace VRM UseSparseAccessorForMorphTarget = UseSparseAccessor, ExportOnlyBlendShapePosition = OnlyBlendshapePosition, }; + + public GameObject Root { get; set; } } } diff --git a/Assets/VRM/UniVRM/Editor/Format/VRMExportSettingsEditor.cs b/Assets/VRM/UniVRM/Editor/Format/VRMExportSettingsEditor.cs index e5853dbbb..fa9cf1afb 100644 --- a/Assets/VRM/UniVRM/Editor/Format/VRMExportSettingsEditor.cs +++ b/Assets/VRM/UniVRM/Editor/Format/VRMExportSettingsEditor.cs @@ -36,12 +36,6 @@ namespace VRM } } - /// - /// エクスポート時に強制的にT-Pose化する - /// - [Tooltip("Option")] - public bool ForceTPose = false; - /// /// エクスポート時にヒエラルキーの正規化を実施する /// @@ -78,7 +72,6 @@ namespace VRM [Tooltip("Remove blendShapeClip that preset is Unknown")] public bool ReduceBlendshapeClip = false; - CheckBoxProp m_forceTPose; CheckBoxProp m_poseFreeze; CheckBoxProp m_useSparseAccessor; CheckBoxProp m_onlyBlendShapePosition; @@ -127,7 +120,6 @@ namespace VRM private void OnEnable() { - m_forceTPose = new CheckBoxProp(serializedObject.FindProperty(nameof(ForceTPose)), Options.FORCE_T_POSE); m_poseFreeze = new CheckBoxProp(serializedObject.FindProperty(nameof(PoseFreeze)), Options.NORMALIZE); m_useSparseAccessor = new CheckBoxProp(serializedObject.FindProperty(nameof(UseSparseAccessor)), Options.BLENDSHAPE_USE_SPARSE); m_onlyBlendShapePosition = new CheckBoxProp(serializedObject.FindProperty(nameof(OnlyBlendshapePosition)), Options.BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT); @@ -137,9 +129,33 @@ namespace VRM public override void OnInspectorGUI() { + GUILayout.Space(20); + var settings = (VRMExportSettings)target; + var root = settings.Root; + var backup = GUI.enabled; + GUI.enabled = root.scene.IsValid(); + if (GUI.enabled) + { + EditorGUILayout.HelpBox("このボタンで自動で T-Pose にできます。手動で T-Pose にしたり、ボタンの後で手直ししてもOKです。", MessageType.Info); + } + else + { + EditorGUILayout.HelpBox("このボタンで自動で T-Pose にできます。prefab には実行できません。", MessageType.Warning); + } + if (GUILayout.Button("T Pose にする")) + { + if (settings.Root) + { + VRMBoneNormalizer.EnforceTPose(settings.Root); + } + } + GUI.enabled = backup; + GUILayout.Space(20); + + // ToDo: 任意の BlendShapeClip を適用する + EditorGUIUtility.labelWidth = 160; serializedObject.Update(); - m_forceTPose.Draw(); m_poseFreeze.Draw(); m_useSparseAccessor.Draw(); m_onlyBlendShapePosition.Draw(); diff --git a/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs b/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs index 1eefffcbf..ef22c9578 100644 --- a/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs +++ b/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs @@ -302,10 +302,11 @@ namespace VRM break; case Tabs.ExportSettings: + m_settings.Root = m_state.ExportRoot; m_settingsInspector.OnInspectorGUI(); break; - case Tabs.Mesh: + case Tabs.Mesh: m_meshesInspector.OnInspectorGUI(); break; } diff --git a/Assets/VRM/UniVRM/Scripts/SkinnedMeshUtility/VRMBoneNormalizer.cs b/Assets/VRM/UniVRM/Scripts/SkinnedMeshUtility/VRMBoneNormalizer.cs index cc6b6cdd9..6f59bb922 100644 --- a/Assets/VRM/UniVRM/Scripts/SkinnedMeshUtility/VRMBoneNormalizer.cs +++ b/Assets/VRM/UniVRM/Scripts/SkinnedMeshUtility/VRMBoneNormalizer.cs @@ -9,7 +9,7 @@ namespace VRM { public static class VRMBoneNormalizer { - static void EnforceTPose(GameObject go) + public static void EnforceTPose(GameObject go) { var animator = go.GetComponent(); if (animator == null) From 0fbcb7c9186431f133d27b7184abd15c5b406d65 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 10 Nov 2020 19:49:33 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=E4=B8=8A=E8=85=95=E3=81=AE=E6=B0=B4?= =?UTF-8?q?=E5=B9=B3=E3=82=92=E8=A6=8B=E3=81=A6=20T-Pose=20=E5=88=A4?= =?UTF-8?q?=E5=AE=9A=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ExportDialog/Valildators/HumanoidValidator.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs b/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs index 69fff4517..634e73ddd 100644 --- a/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs +++ b/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs @@ -25,6 +25,10 @@ namespace MeshUtility.Validators [LangMsg(Languages.en, "The model needs to face the positive Z-axis")] FACE_Z_POSITIVE_DIRECTION, + [LangMsg(Languages.ja, "T-Pose にしてください")] + [LangMsg(Languages.en, "Set T-Pose")] + NOT_TPOSE, + [LangMsg(Languages.ja, "ExportRootの Animator に Avatar がありません")] [LangMsg(Languages.en, "No Avatar in ExportRoot's Animator")] NO_AVATAR_IN_ANIMATOR, @@ -150,6 +154,17 @@ namespace MeshUtility.Validators } } + { + var lu = animator.GetBoneTransform(HumanBodyBones.LeftUpperArm); + var ll = animator.GetBoneTransform(HumanBodyBones.LeftLowerArm); + var ru = animator.GetBoneTransform(HumanBodyBones.RightUpperArm); + var rl = animator.GetBoneTransform(HumanBodyBones.RightLowerArm); + if (Vector3.Dot((ll.position - lu.position).normalized, Vector3.left) < 0.8f + || Vector3.Dot((rl.position - ru.position).normalized, Vector3.right) < 0.8f) + { + yield return Validation.Warning(ValidationMessages.NOT_TPOSE.Msg()); + } + } var jaw = animator.GetBoneTransform(HumanBodyBones.Jaw); if (jaw != null) { From 2d0d6737d7076d872e234c4cd0518f13474f6549 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 10 Nov 2020 19:51:34 +0900 Subject: [PATCH 4/6] check T-Pose --- .../Editor/ExportDialog/Valildators/HumanoidValidator.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs b/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs index 634e73ddd..cc89267b5 100644 --- a/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs +++ b/Assets/MeshUtility/Editor/ExportDialog/Valildators/HumanoidValidator.cs @@ -162,18 +162,15 @@ namespace MeshUtility.Validators if (Vector3.Dot((ll.position - lu.position).normalized, Vector3.left) < 0.8f || Vector3.Dot((rl.position - ru.position).normalized, Vector3.right) < 0.8f) { - yield return Validation.Warning(ValidationMessages.NOT_TPOSE.Msg()); + yield return Validation.Error(ValidationMessages.NOT_TPOSE.Msg()); } } + var jaw = animator.GetBoneTransform(HumanBodyBones.Jaw); if (jaw != null) { yield return Validation.Warning(ValidationMessages.JAW_BONE_IS_INCLUDED.Msg()); } - else - { - yield return Validation.Info("Animator OK"); - } } } } From a5c9a63e8c3079c8eb5c467917549c036577738b Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 10 Nov 2020 19:58:37 +0900 Subject: [PATCH 5/6] English message --- .../Editor/Format/VRMExportSettingsEditor.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Assets/VRM/UniVRM/Editor/Format/VRMExportSettingsEditor.cs b/Assets/VRM/UniVRM/Editor/Format/VRMExportSettingsEditor.cs index fa9cf1afb..a4c3512a8 100644 --- a/Assets/VRM/UniVRM/Editor/Format/VRMExportSettingsEditor.cs +++ b/Assets/VRM/UniVRM/Editor/Format/VRMExportSettingsEditor.cs @@ -116,6 +116,18 @@ namespace VRM [LangMsg(Languages.ja, "エクスポートに頂点カラーを含めない")] [LangMsg(Languages.en, "Vertex color will not be exported")] REMOVE_VERTEX_COLOR, + + [LangMsg(Languages.ja, "このボタンで自動で T-Pose にできます。手動で T-Pose にしたり、ボタンの後で手直ししてもOKです。")] + [LangMsg(Languages.en, "You can automatically set the T pose with this button. You can change it manually to T-pose or after the button.")] + ENALBE_TPOSE_BUTTON, + + [LangMsg(Languages.ja, "このボタンで自動で T-Pose にできます。prefab には実行できません。")] + [LangMsg(Languages.en, "You can set the T pose automatically with this button. It cannot be run on prefabs.")] + DISABLE_TPOSE_BUTTON, + + [LangMsg(Languages.ja, "T-Pose にする")] + [LangMsg(Languages.en, "Make T-Pose")] + DO_TPOSE, } private void OnEnable() @@ -136,13 +148,13 @@ namespace VRM GUI.enabled = root.scene.IsValid(); if (GUI.enabled) { - EditorGUILayout.HelpBox("このボタンで自動で T-Pose にできます。手動で T-Pose にしたり、ボタンの後で手直ししてもOKです。", MessageType.Info); + EditorGUILayout.HelpBox(Options.ENALBE_TPOSE_BUTTON.Msg(), MessageType.Info); } else { - EditorGUILayout.HelpBox("このボタンで自動で T-Pose にできます。prefab には実行できません。", MessageType.Warning); + EditorGUILayout.HelpBox(Options.DISABLE_TPOSE_BUTTON.Msg(), MessageType.Warning); } - if (GUILayout.Button("T Pose にする")) + if (GUILayout.Button(Options.DO_TPOSE.Msg())) { if (settings.Root) { From 743340e7e24e03ba07ddcccdb23053955f7535d5 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Wed, 11 Nov 2020 18:17:41 +0900 Subject: [PATCH 6/6] BlendShape tab --- .../UniVRM/Editor/Format/VRMExporterWizard.cs | 61 +++++++++++++++++-- .../Scripts/BlendShape/BlendShapeMerger.cs | 2 +- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs b/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs index ef22c9578..c13794e1f 100644 --- a/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs +++ b/Assets/VRM/UniVRM/Editor/Format/VRMExporterWizard.cs @@ -23,6 +23,7 @@ namespace VRM { Meta, Mesh, + BlendShape, ExportSettings, } Tabs _tab; @@ -301,19 +302,71 @@ namespace VRM m_metaEditor.OnInspectorGUI(); break; + case Tabs.Mesh: + m_meshesInspector.OnInspectorGUI(); + break; + + case Tabs.BlendShape: + if (m_state.ExportRoot) + { + OnBlendShapeGUI(m_state.ExportRoot.GetComponent()); + } + break; + case Tabs.ExportSettings: m_settings.Root = m_state.ExportRoot; m_settingsInspector.OnInspectorGUI(); break; - - case Tabs.Mesh: - m_meshesInspector.OnInspectorGUI(); - break; } return true; } + BlendShapeMerger m_merger; + + int m_selected = 0; + void OnBlendShapeGUI(VRMBlendShapeProxy proxy) + { + if (!m_state.ExportRoot.scene.IsValid()) + { + EditorGUILayout.HelpBox("prefab は操作できません", MessageType.Warning); + return; + } + + if (!proxy) + { + return; + } + var avatar = proxy.BlendShapeAvatar; + if (!avatar) + { + return; + } + + m_merger = new BlendShapeMerger(avatar.Clips, proxy.transform); + + + GUILayout.Space(20); + + EditorGUILayout.HelpBox("シーン上のExportRootにBlendShapeを適用します。Exportすると適用された状態がBakeされます。", MessageType.Info); + + var options = avatar.Clips.Select(x => x.ToString()).ToArray(); + m_selected = EditorGUILayout.Popup("select blendshape", m_selected, options); + + if (GUILayout.Button("選択されたBlendShapeを適用する")) + { + m_merger.SetValues(avatar.Clips.Select((x, i) => new KeyValuePair(x.Key, i == m_selected ? 1 : 0))); + m_merger.Apply(); + m_settings.PoseFreeze = true; + } + + if (GUILayout.Button("BlendShapeをClearする")) + { + m_merger.SetValues(avatar.Clips.Select(x => new KeyValuePair(x.Key, 0))); + m_merger.Apply(); + } + } + const string EXTENSION = ".vrm"; private static string m_lastExportDir; static void OnExportClicked(GameObject root, VRMMetaObject meta, VRMExportSettings settings, VRMExportMeshes meshes) diff --git a/Assets/VRM/UniVRM/Scripts/BlendShape/BlendShapeMerger.cs b/Assets/VRM/UniVRM/Scripts/BlendShape/BlendShapeMerger.cs index 02e60ab7b..6fb388ad8 100644 --- a/Assets/VRM/UniVRM/Scripts/BlendShape/BlendShapeMerger.cs +++ b/Assets/VRM/UniVRM/Scripts/BlendShape/BlendShapeMerger.cs @@ -11,7 +11,7 @@ namespace VRM /// /// ブレンドシェイプを蓄えてまとめて適用するクラス /// - class BlendShapeMerger + public class BlendShapeMerger { /// /// Key からBlendShapeClipを得る