diff --git a/Scripts/BlendShape/BlendShapeMerger.cs b/Scripts/BlendShape/BlendShapeMerger.cs index 9df1b76b3..939d555cd 100644 --- a/Scripts/BlendShape/BlendShapeMerger.cs +++ b/Scripts/BlendShape/BlendShapeMerger.cs @@ -1,21 +1,23 @@ -using System.Collections.Generic; -using UnityEngine; +using System; +using System.Collections.Generic; using System.Linq; using UniGLTF; +using UnityEngine; namespace VRM { + /// + /// ブレンドシェイプを蓄えてまとめて適用するクラス + /// class BlendShapeMerger { - delegate void BlendShapeSetter(float value); - Dictionary m_clipMap; Dictionary m_valueMap; - class BlendShapePathHandler + class AccumulatingSetter { - public BlendShapeSetter Setter; + public Action Setter; float m_value; public void AddValue(float value) @@ -41,8 +43,9 @@ namespace VRM Apply(); } } - Dictionary m_setterMap = new Dictionary(); + Dictionary m_setterMap; Dictionary m_materialMap; + Dictionary m_materialSetterMap; public BlendShapeMerger(IEnumerable clips, Transform root) { @@ -66,12 +69,14 @@ namespace VRM } m_clipMap = clips.ToDictionary(x => BlendShapeKey.CreateFrom(x), x => x); + m_valueMap = new Dictionary(); + m_setterMap = new Dictionary(); + m_materialSetterMap = new Dictionary(); foreach (var kv in m_clipMap) { foreach (var binding in kv.Value.Values) { - if (!m_setterMap.ContainsKey(binding)) { var _target = root.Find(binding.RelativePath); @@ -82,7 +87,7 @@ namespace VRM } if (target != null) { - m_setterMap.Add(binding, new BlendShapePathHandler + m_setterMap.Add(binding, new AccumulatingSetter { Setter = x => { @@ -92,7 +97,31 @@ namespace VRM } else { - Debug.LogWarningFormat("{0} not found", binding.RelativePath); + Debug.LogWarningFormat("SkinnedMeshRenderer: {0} not found", binding.RelativePath); + } + } + } + + foreach(var binding in kv.Value.MaterialValues) + { + if (!m_materialSetterMap.ContainsKey(binding)) + { + Material target; + if(m_materialMap.TryGetValue(binding.MaterialName, out target)) + { + m_materialSetterMap.Add(binding, new AccumulatingSetter + { + Setter = x => + { + //target.SetBlendShapeWeight(binding.Index, x); + var propValue = binding.BaseValue + (binding.TargetValue - binding.BaseValue) * x; + target.SetColor(binding.ValueName, propValue); + } + }); + } + else + { + Debug.LogWarningFormat("material: {0} not found", binding.MaterialName); } } } @@ -135,13 +164,12 @@ namespace VRM foreach (var binding in clip.Values) { - BlendShapePathHandler handler; + AccumulatingSetter handler; if (m_setterMap.TryGetValue(binding, out handler)) { if (replace) { // 値置き換え - //handler.ReplaceValue(); handler.Apply(binding.Weight * value); } else @@ -159,8 +187,24 @@ namespace VRM // materialの更新 foreach (var binding in clip.MaterialValues) { - var propValue = binding.BaseValue + (binding.TargetValue - binding.BaseValue) * value; - m_materialMap[binding.MaterialName].SetColor(binding.ValueName, propValue); + AccumulatingSetter handler; + if(m_materialSetterMap.TryGetValue(binding, out handler)) + { + if (replace) + { + // 値置き換え + handler.Apply(value); + } + else + { + // 積算 + handler.AddValue(value); + } + } + else + { + Debug.LogWarningFormat("'{0}' not found", binding); + } } } @@ -174,7 +218,7 @@ namespace VRM return value; } - public void RestoreMaterialValues(IEnumerable clips) + public void RestoreMaterialInitialValues(IEnumerable clips) { if (m_materialMap != null) { diff --git a/Scripts/BlendShape/VRMBlendShapeProxy.cs b/Scripts/BlendShape/VRMBlendShapeProxy.cs index 20cac7c18..b103102cf 100644 --- a/Scripts/BlendShape/VRMBlendShapeProxy.cs +++ b/Scripts/BlendShape/VRMBlendShapeProxy.cs @@ -21,7 +21,7 @@ namespace VRM { if (m_merger != null) { - m_merger.RestoreMaterialValues(BlendShapeAvatar.Clips); + m_merger.RestoreMaterialInitialValues(BlendShapeAvatar.Clips); } }