diff --git a/Assets/VRM10/Editor/Components/Expression/SerializedExpressionEditor.cs b/Assets/VRM10/Editor/Components/Expression/SerializedExpressionEditor.cs index e1218b443..385e989ca 100644 --- a/Assets/VRM10/Editor/Components/Expression/SerializedExpressionEditor.cs +++ b/Assets/VRM10/Editor/Components/Expression/SerializedExpressionEditor.cs @@ -16,9 +16,6 @@ namespace UniVRM10 #region Properties SerializedProperty m_thumbnail; - SerializedProperty m_expressionNameProp; - SerializedProperty m_presetProp; - SerializedProperty m_isBinaryProp; public bool IsBinary => m_isBinaryProp.boolValue; @@ -77,8 +74,6 @@ namespace UniVRM10 this.m_serializedObject = serializedObject; this.m_targetObject = targetObject; - m_expressionNameProp = serializedObject.FindProperty(nameof(targetObject.ExpressionName)); - m_presetProp = serializedObject.FindProperty(nameof(targetObject.Preset)); m_isBinaryProp = serializedObject.FindProperty(nameof(targetObject.IsBinary)); m_ignoreBlinkProp = serializedObject.FindProperty(nameof(targetObject.OverrideBlink)); m_ignoreLookAtProp = serializedObject.FindProperty(nameof(targetObject.OverrideLookAt)); @@ -105,9 +100,6 @@ namespace UniVRM10 m_targetObject, typeof(VRM10Expression), false); GUI.enabled = true; - EditorGUILayout.PropertyField(m_expressionNameProp, true); - EditorGUILayout.PropertyField(m_presetProp, true); - m_status.MorphTargetFoldout = CustomUI.Foldout(Status.MorphTargetFoldout, "MorphTarget"); if (Status.MorphTargetFoldout) { diff --git a/Assets/VRM10/Editor/Components/Expression/VRM10ControllerEditorExpression.cs b/Assets/VRM10/Editor/Components/Expression/VRM10ControllerEditorExpression.cs index 569c89831..1fda82748 100644 --- a/Assets/VRM10/Editor/Components/Expression/VRM10ControllerEditorExpression.cs +++ b/Assets/VRM10/Editor/Components/Expression/VRM10ControllerEditorExpression.cs @@ -20,10 +20,10 @@ namespace UniVRM10 { m_target = target; - m_expressionKeyWeights = m_target.Vrm.Expression.Clips.ToDictionary(x => ExpressionKey.CreateFromClip(x), x => 0.0f); + m_expressionKeyWeights = m_target.Vrm.Expression.Clips.ToDictionary(x => target.Vrm.Expression.CreateKey(x.Clip), x => 0.0f); m_sliders = m_target.Vrm.Expression.Clips - .Where(x => x != null) - .Select(x => new ExpressionSlider(m_expressionKeyWeights, ExpressionKey.CreateFromClip(x))) + .Where(x => x.Clip != null) + .Select(x => new ExpressionSlider(m_expressionKeyWeights, target.Vrm.Expression.CreateKey(x.Clip))) .ToList() ; } diff --git a/Assets/VRM10/Editor/Components/Expression/VRM10ExpressionEditor.cs b/Assets/VRM10/Editor/Components/Expression/VRM10ExpressionEditor.cs index 117ffcfb4..b8ef32321 100644 --- a/Assets/VRM10/Editor/Components/Expression/VRM10ExpressionEditor.cs +++ b/Assets/VRM10/Editor/Components/Expression/VRM10ExpressionEditor.cs @@ -214,18 +214,18 @@ namespace UniVRM10 } } - public static VRM10Expression CreateExpression(string path) - { - //Debug.LogFormat("{0}", path); - var clip = ScriptableObject.CreateInstance(); - clip.ExpressionName = Path.GetFileNameWithoutExtension(path); - AssetDatabase.CreateAsset(clip, path); - AssetDatabase.ImportAsset(path); - return clip; - //Clips.Add(clip); - //EditorUtility.SetDirty(this); - //AssetDatabase.SaveAssets(); - } + // public static VRM10Expression CreateExpression(string path) + // { + // //Debug.LogFormat("{0}", path); + // var clip = ScriptableObject.CreateInstance(); + // clip.name = Path.GetFileNameWithoutExtension(path); + // AssetDatabase.CreateAsset(clip, path); + // AssetDatabase.ImportAsset(path); + // return clip; + // //Clips.Add(clip); + // //EditorUtility.SetDirty(this); + // //AssetDatabase.SaveAssets(); + // } SerializedExpressionEditor m_serializedEditor; diff --git a/Assets/VRM10/Runtime/Components/Expression/DefaultExpressionValidator.cs b/Assets/VRM10/Runtime/Components/Expression/DefaultExpressionValidator.cs index 561825049..6dec633aa 100644 --- a/Assets/VRM10/Runtime/Components/Expression/DefaultExpressionValidator.cs +++ b/Assets/VRM10/Runtime/Components/Expression/DefaultExpressionValidator.cs @@ -14,8 +14,8 @@ namespace UniVRM10 private DefaultExpressionValidator(VRM10ObjectExpression expressionAvatar) { - _keys = expressionAvatar.Clips.Select(ExpressionKey.CreateFromClip).ToArray(); - _expressions = expressionAvatar.Clips.ToDictionary(ExpressionKey.CreateFromClip, x => x); + _keys = expressionAvatar.Clips.Select(x => expressionAvatar.CreateKey(x.Clip)).ToArray(); + _expressions = expressionAvatar.Clips.ToDictionary(x => expressionAvatar.CreateKey(x.Clip), x => x.Clip); } public void Validate(IReadOnlyDictionary inputWeights, IDictionary actualWeights, diff --git a/Assets/VRM10/Runtime/Components/Expression/ExpressionKey.cs b/Assets/VRM10/Runtime/Components/Expression/ExpressionKey.cs index 99c098e81..a79b69279 100644 --- a/Assets/VRM10/Runtime/Components/Expression/ExpressionKey.cs +++ b/Assets/VRM10/Runtime/Components/Expression/ExpressionKey.cs @@ -123,16 +123,6 @@ namespace UniVRM10 return new ExpressionKey(preset); } - public static ExpressionKey CreateFromClip(VRM10Expression clip) - { - if (clip == null) - { - return default(ExpressionKey); - } - - return new ExpressionKey(clip.Preset, clip.ExpressionName); - } - public static ExpressionKey Happy => CreateFromPreset(ExpressionPreset.happy); public static ExpressionKey Angry => CreateFromPreset(ExpressionPreset.angry); public static ExpressionKey Sad => CreateFromPreset(ExpressionPreset.sad); @@ -180,10 +170,10 @@ namespace UniVRM10 return _id.GetHashCode(); } - public bool Match(VRM10Expression clip) - { - return this.Equals(CreateFromClip(clip)); - } + // public bool Match(VRM10Expression clip) + // { + // return this.Equals(CreateFromClip(clip)); + // } public int CompareTo(ExpressionKey other) { diff --git a/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs b/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs index b4c337afe..b8ec76ec4 100644 --- a/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs +++ b/Assets/VRM10/Runtime/Components/Expression/ExpressionMerger.cs @@ -26,9 +26,9 @@ namespace UniVRM10 MaterialValueBindingMerger m_materialValueBindingMerger; - public ExpressionMerger(IEnumerable clips, Transform root) + public ExpressionMerger(VRM10ObjectExpression expressions, Transform root) { - m_clipMap = clips.ToDictionary(x => ExpressionKey.CreateFromClip(x), x => x); + m_clipMap = expressions.Clips.ToDictionary(x => expressions.CreateKey(x.Clip), x => x.Clip); m_valueMap = new Dictionary(); @@ -46,7 +46,7 @@ namespace UniVRM10 { AccumulateValue(key, weight); } - + m_morphTargetBindingMerger.Apply(); m_materialValueBindingMerger.Apply(); } diff --git a/Assets/VRM10/Runtime/Components/Expression/VRM10Expression.cs b/Assets/VRM10/Runtime/Components/Expression/VRM10Expression.cs index 74cf99041..b75473e24 100644 --- a/Assets/VRM10/Runtime/Components/Expression/VRM10Expression.cs +++ b/Assets/VRM10/Runtime/Components/Expression/VRM10Expression.cs @@ -1,23 +1,10 @@ -using UniGLTF; -using UnityEngine; +using UnityEngine; namespace UniVRM10 { [CreateAssetMenu(menuName = "VRM10/Expression")] public sealed class VRM10Expression : PrefabRelatedScriptableObject { - /// - /// ExpressionPreset が Unknown 場合の識別子 - /// - [SerializeField] - public string ExpressionName; - - /// - /// ExpressionPreset を識別する。 Unknown の場合は、 ExpressionName で識別する - /// - [SerializeField] - public ExpressionPreset Preset; - /// /// 対象メッシュの Expression を操作する /// @@ -59,21 +46,5 @@ namespace UniVRM10 /// [SerializeField] public UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType OverrideMouth; - - void Reset() - { - OnValidate(); - } - - void OnValidate() - { - if (Preset == ExpressionPreset.custom) - { - if (string.IsNullOrEmpty(ExpressionName)) - { - ExpressionName = "custom"; - } - } - } } } diff --git a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectExpression.cs b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectExpression.cs index 304350c4c..1a7e0e11d 100644 --- a/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectExpression.cs +++ b/Assets/VRM10/Runtime/Components/VRM10Object/VRM10ObjectExpression.cs @@ -68,41 +68,56 @@ namespace UniVRM10 [SerializeField] public List CustomClips = new List(); - public IEnumerable Clips + public IEnumerable<(ExpressionPreset Preset, VRM10Expression Clip)> Clips { get { - if (Happy != null) yield return Happy; - if (Angry != null) yield return Angry; - if (Sad != null) yield return Sad; - if (Relaxed != null) yield return Relaxed; - if (Surprised != null) yield return Surprised; - if (Aa != null) yield return Aa; - if (Ih != null) yield return Ih; - if (Ou != null) yield return Ou; - if (Ee != null) yield return Ee; - if (Oh != null) yield return Oh; - if (Blink != null) yield return Blink; - if (BlinkLeft != null) yield return BlinkLeft; - if (BlinkRight != null) yield return BlinkRight; - if (LookUp != null) yield return LookUp; - if (LookDown != null) yield return LookDown; - if (LookLeft != null) yield return LookLeft; - if (LookRight != null) yield return LookRight; - if (Neutral != null) yield return Neutral; + if (Happy != null) yield return (ExpressionPreset.happy, Happy); + if (Angry != null) yield return (ExpressionPreset.angry, Angry); + if (Sad != null) yield return (ExpressionPreset.sad, Sad); + if (Relaxed != null) yield return (ExpressionPreset.relaxed, Relaxed); + if (Surprised != null) yield return (ExpressionPreset.surprised, Surprised); + if (Aa != null) yield return (ExpressionPreset.aa, Aa); + if (Ih != null) yield return (ExpressionPreset.ih, Ih); + if (Ou != null) yield return (ExpressionPreset.ou, Ou); + if (Ee != null) yield return (ExpressionPreset.ee, Ee); + if (Oh != null) yield return (ExpressionPreset.oh, Oh); + if (Blink != null) yield return (ExpressionPreset.blink, Blink); + if (BlinkLeft != null) yield return (ExpressionPreset.blinkLeft, BlinkLeft); + if (BlinkRight != null) yield return (ExpressionPreset.blinkRight, BlinkRight); + if (LookUp != null) yield return (ExpressionPreset.lookUp, LookUp); + if (LookDown != null) yield return (ExpressionPreset.lookDown, LookDown); + if (LookLeft != null) yield return (ExpressionPreset.lookLeft, LookLeft); + if (LookRight != null) yield return (ExpressionPreset.lookRight, LookRight); + if (Neutral != null) yield return (ExpressionPreset.neutral, Neutral); foreach (var clip in CustomClips) { if (clip != null) { - yield return clip; + yield return (ExpressionPreset.custom, clip); } } } } - public void AddClip(VRM10Expression clip) + public ExpressionKey CreateKey(VRM10Expression clip) { - switch (clip.Preset) + foreach (var (preset, c) in Clips) + { + if (c == clip) + { + return new ExpressionKey(preset, clip.name); + } + } + + // not found + // return default(ExpressionKey); + throw new KeyNotFoundException(); + } + + public void AddClip(ExpressionPreset preset, VRM10Expression clip) + { + switch (preset) { case ExpressionPreset.happy: Happy = clip; break; case ExpressionPreset.angry: Angry = clip; break; @@ -275,8 +290,8 @@ namespace UniVRM10 { Restore(); - _merger = new ExpressionMerger(Clips, target.transform); - _keys = Clips.Select(ExpressionKey.CreateFromClip).ToList(); + _merger = new ExpressionMerger(this, target.transform); + _keys = Clips.Select(x => CreateKey(x.Clip)).ToList(); var oldInputWeights = _inputWeights; _inputWeights = _keys.ToDictionary(x => x, x => 0f); foreach (var key in _keys) diff --git a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs index 815c8297e..729d2562d 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Exporter.cs @@ -662,7 +662,7 @@ namespace UniVRM10 LookLeft = ExportExpression(vrmController.Vrm.Expression.LookLeft, vrmController, model, converter), LookRight = ExportExpression(vrmController.Vrm.Expression.LookRight, vrmController, model, converter), }, - Custom = vrmController.Vrm.Expression.CustomClips.ToDictionary(c => c.ExpressionName, c => ExportExpression(c, vrmController, model, converter)), + Custom = vrmController.Vrm.Expression.CustomClips.ToDictionary(c => c.name, c => ExportExpression(c, vrmController, model, converter)), }; } diff --git a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs index 822f0aaba..f2872b8c7 100644 --- a/Assets/VRM10/Runtime/IO/Vrm10Importer.cs +++ b/Assets/VRM10/Runtime/IO/Vrm10Importer.cs @@ -215,7 +215,7 @@ namespace UniVRM10 UnityEngine.Avatar m_humanoid; VRM10Object m_vrmObject; - List m_expressions = new List(); + List<(ExpressionPreset Preset, VRM10Expression Clip)> m_expressions = new List<(ExpressionPreset, VRM10Expression)>(); protected override async Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func MeasureTime) { @@ -244,7 +244,7 @@ namespace UniVRM10 await LoadConstraintAsync(awaitCaller, controller); } - VRM10Expression GetOrLoadExpression(in SubAssetKey key, UniGLTF.Extensions.VRMC_vrm.Expression expression) + VRM10Expression GetOrLoadExpression(in SubAssetKey key, ExpressionPreset preset, UniGLTF.Extensions.VRMC_vrm.Expression expression) { VRM10Expression clip = default; if (m_externalMap.TryGetValue(key, out UnityEngine.Object expressionObj)) @@ -265,8 +265,6 @@ namespace UniVRM10 }; } clip = ScriptableObject.CreateInstance(); - clip.Preset = ExpressionPreset.custom; - clip.ExpressionName = key.Name; clip.name = key.Name; clip.IsBinary = expression.IsBinary.GetValueOrDefault(); clip.OverrideBlink = expression.OverrideBlink; @@ -307,7 +305,7 @@ namespace UniVRM10 clip.MaterialUVBindings = new MaterialUVBinding[] { }; } - m_expressions.Add(clip); + m_expressions.Add((preset, clip)); } return clip; } @@ -365,32 +363,33 @@ namespace UniVRM10 // expression { - vrm.Expression.Happy = GetOrLoadExpression(ExpressionKey.Happy.SubAssetKey, vrmExtension.Expressions?.Preset?.Happy); - vrm.Expression.Angry = GetOrLoadExpression(ExpressionKey.Angry.SubAssetKey, vrmExtension.Expressions?.Preset?.Angry); - vrm.Expression.Sad = GetOrLoadExpression(ExpressionKey.Sad.SubAssetKey, vrmExtension.Expressions?.Preset?.Sad); - vrm.Expression.Relaxed = GetOrLoadExpression(ExpressionKey.Relaxed.SubAssetKey, vrmExtension.Expressions?.Preset?.Relaxed); - vrm.Expression.Surprised = GetOrLoadExpression(ExpressionKey.Surprised.SubAssetKey, vrmExtension.Expressions?.Preset?.Surprised); - vrm.Expression.Aa = GetOrLoadExpression(ExpressionKey.Aa.SubAssetKey, vrmExtension.Expressions?.Preset?.Aa); - vrm.Expression.Ih = GetOrLoadExpression(ExpressionKey.Ih.SubAssetKey, vrmExtension.Expressions?.Preset?.Ih); - vrm.Expression.Ou = GetOrLoadExpression(ExpressionKey.Ou.SubAssetKey, vrmExtension.Expressions?.Preset?.Ou); - vrm.Expression.Ee = GetOrLoadExpression(ExpressionKey.Ee.SubAssetKey, vrmExtension.Expressions?.Preset?.Ee); - vrm.Expression.Oh = GetOrLoadExpression(ExpressionKey.Oh.SubAssetKey, vrmExtension.Expressions?.Preset?.Oh); - vrm.Expression.Blink = GetOrLoadExpression(ExpressionKey.Blink.SubAssetKey, vrmExtension.Expressions?.Preset?.Blink); - vrm.Expression.BlinkLeft = GetOrLoadExpression(ExpressionKey.BlinkLeft.SubAssetKey, vrmExtension.Expressions?.Preset?.BlinkLeft); - vrm.Expression.BlinkRight = GetOrLoadExpression(ExpressionKey.BlinkRight.SubAssetKey, vrmExtension.Expressions?.Preset?.BlinkRight); - vrm.Expression.LookUp = GetOrLoadExpression(ExpressionKey.LookUp.SubAssetKey, vrmExtension.Expressions?.Preset?.LookUp); - vrm.Expression.LookDown = GetOrLoadExpression(ExpressionKey.LookDown.SubAssetKey, vrmExtension.Expressions?.Preset?.LookDown); - vrm.Expression.LookLeft = GetOrLoadExpression(ExpressionKey.LookLeft.SubAssetKey, vrmExtension.Expressions?.Preset?.LookLeft); - vrm.Expression.LookRight = GetOrLoadExpression(ExpressionKey.LookRight.SubAssetKey, vrmExtension.Expressions?.Preset?.LookRight); + vrm.Expression.Happy = GetOrLoadExpression(ExpressionKey.Happy.SubAssetKey, ExpressionPreset.happy, vrmExtension.Expressions?.Preset?.Happy); + vrm.Expression.Angry = GetOrLoadExpression(ExpressionKey.Angry.SubAssetKey, ExpressionPreset.angry, vrmExtension.Expressions?.Preset?.Angry); + vrm.Expression.Sad = GetOrLoadExpression(ExpressionKey.Sad.SubAssetKey, ExpressionPreset.sad, vrmExtension.Expressions?.Preset?.Sad); + vrm.Expression.Relaxed = GetOrLoadExpression(ExpressionKey.Relaxed.SubAssetKey, ExpressionPreset.relaxed, vrmExtension.Expressions?.Preset?.Relaxed); + vrm.Expression.Surprised = GetOrLoadExpression(ExpressionKey.Surprised.SubAssetKey, ExpressionPreset.surprised, vrmExtension.Expressions?.Preset?.Surprised); + vrm.Expression.Aa = GetOrLoadExpression(ExpressionKey.Aa.SubAssetKey, ExpressionPreset.aa, vrmExtension.Expressions?.Preset?.Aa); + vrm.Expression.Ih = GetOrLoadExpression(ExpressionKey.Ih.SubAssetKey, ExpressionPreset.ih, vrmExtension.Expressions?.Preset?.Ih); + vrm.Expression.Ou = GetOrLoadExpression(ExpressionKey.Ou.SubAssetKey, ExpressionPreset.ou, vrmExtension.Expressions?.Preset?.Ou); + vrm.Expression.Ee = GetOrLoadExpression(ExpressionKey.Ee.SubAssetKey, ExpressionPreset.ee, vrmExtension.Expressions?.Preset?.Ee); + vrm.Expression.Oh = GetOrLoadExpression(ExpressionKey.Oh.SubAssetKey, ExpressionPreset.oh, vrmExtension.Expressions?.Preset?.Oh); + vrm.Expression.Blink = GetOrLoadExpression(ExpressionKey.Blink.SubAssetKey, ExpressionPreset.blink, vrmExtension.Expressions?.Preset?.Blink); + vrm.Expression.BlinkLeft = GetOrLoadExpression(ExpressionKey.BlinkLeft.SubAssetKey, ExpressionPreset.blinkLeft, vrmExtension.Expressions?.Preset?.BlinkLeft); + vrm.Expression.BlinkRight = GetOrLoadExpression(ExpressionKey.BlinkRight.SubAssetKey, ExpressionPreset.blinkRight, vrmExtension.Expressions?.Preset?.BlinkRight); + vrm.Expression.LookUp = GetOrLoadExpression(ExpressionKey.LookUp.SubAssetKey, ExpressionPreset.lookUp, vrmExtension.Expressions?.Preset?.LookUp); + vrm.Expression.LookDown = GetOrLoadExpression(ExpressionKey.LookDown.SubAssetKey, ExpressionPreset.lookDown, vrmExtension.Expressions?.Preset?.LookDown); + vrm.Expression.LookLeft = GetOrLoadExpression(ExpressionKey.LookLeft.SubAssetKey, ExpressionPreset.lookLeft, vrmExtension.Expressions?.Preset?.LookLeft); + vrm.Expression.LookRight = GetOrLoadExpression(ExpressionKey.LookRight.SubAssetKey, ExpressionPreset.lookRight, vrmExtension.Expressions?.Preset?.LookRight); if (vrmExtension?.Expressions?.Custom != null) { foreach (var (name, expression) in vrmExtension.Expressions.Custom) { var key = ExpressionKey.CreateCustom(name); - var clip = GetOrLoadExpression(key.SubAssetKey, expression); + var preset = ExpressionPreset.custom; + var clip = GetOrLoadExpression(key.SubAssetKey, preset, expression); if (clip != null) { - vrm.Expression.AddClip(clip); + vrm.Expression.AddClip(preset, clip); } } } @@ -694,9 +693,9 @@ namespace UniVRM10 m_vrmObject = null; } - foreach (var x in m_expressions) + foreach (var (preset, x) in m_expressions) { - take(ExpressionKey.CreateFromClip(x).SubAssetKey, x); + take(new ExpressionKey(preset, x.name).SubAssetKey, x); // do nothing } m_expressions.Clear(); @@ -720,7 +719,7 @@ namespace UniVRM10 m_vrmObject = null; } - foreach (var clip in m_expressions) + foreach (var (preset, clip) in m_expressions) { UnityObjectDestoyer.DestroyRuntimeOrEditor(clip); }