diff --git a/Scripts/BlendShape/BlendShapeMerger.cs b/Scripts/BlendShape/BlendShapeMerger.cs
index 8a8c514a3..8c88b41fe 100644
--- a/Scripts/BlendShape/BlendShapeMerger.cs
+++ b/Scripts/BlendShape/BlendShapeMerger.cs
@@ -12,15 +12,43 @@ namespace VRM
///
class BlendShapeMerger
{
+ ///
+ /// KeyからBlendShapeClipを得る
+ ///
Dictionary m_clipMap;
+
+ ///
+ /// BlendShapeのWeightを蓄積する
+ ///
Dictionary m_valueMap;
+ ///
+ /// 名前とmaterialのマッピング
+ ///
Dictionary m_materialMap;
+ ///
+ /// BlendShapeの適用値を蓄積する
+ ///
+ ///
+ ///
+ ///
Dictionary m_blendShapeValueMap = new Dictionary();
+
+ ///
+ ///
+ ///
+ ///
Dictionary> m_blendShapeSetterMap = new Dictionary>();
+ ///
+ /// MaterialValueの適用値を蓄積する
+ ///
+ ///
+ ///
+ ///
Dictionary m_materialValueMap = new Dictionary();
+
Dictionary> m_materialSetterMap = new Dictionary>();
public BlendShapeMerger(IEnumerable clips, Transform root)
@@ -102,7 +130,7 @@ namespace VRM
};
m_materialSetterMap.Add(binding, setter);
}
- else if(binding.ValueName.EndsWith("_ST_T"))
+ else if (binding.ValueName.EndsWith("_ST_T"))
{
var valueName = binding.ValueName.Substring(0, binding.ValueName.Length - 2);
Action setter = value =>
@@ -143,6 +171,9 @@ namespace VRM
Apply();
}
+ ///
+ /// 蓄積した値を適用する
+ ///
public void Apply()
{
foreach (var kv in m_blendShapeValueMap)
@@ -166,16 +197,25 @@ namespace VRM
m_materialValueMap.Clear();
}
+ ///
+ /// まとめて反映する。1フレームに1回呼び出されることを想定
+ ///
+ ///
public void SetValues(IEnumerable> values)
{
foreach (var kv in values)
{
- SetValue(kv.Key, kv.Value, false);
+ AccumulateValue(kv.Key, kv.Value);
}
Apply();
}
- public void SetValue(BlendShapeKey key, float value, bool replace)
+ ///
+ /// 即時に反映しない。後にApplyによって反映する
+ ///
+ ///
+ ///
+ public void AccumulateValue(BlendShapeKey key, float value)
{
m_valueMap[key] = value;
@@ -185,60 +225,91 @@ namespace VRM
return;
}
+ if (clip.IsBinary)
+ {
+ value = Mathf.Round(value);
+ }
+
foreach (var binding in clip.Values)
{
- if (replace)
+ // 積算
+ float acc;
+ if (m_blendShapeValueMap.TryGetValue(binding, out acc))
{
- // 値置き換え
- Action setter;
- if (m_blendShapeSetterMap.TryGetValue(binding, out setter))
- {
- setter(binding.Weight * value);
- }
+ m_blendShapeValueMap[binding] = acc + binding.Weight * value;
}
else
{
- // 積算
- float acc;
- if (m_blendShapeValueMap.TryGetValue(binding, out acc))
- {
- m_blendShapeValueMap[binding] = acc + binding.Weight * value;
- }
- else
- {
- m_blendShapeValueMap[binding] = binding.Weight * value;
- }
+ m_blendShapeValueMap[binding] = binding.Weight * value;
}
}
- // materialの更新
foreach (var binding in clip.MaterialValues)
{
- if (replace)
+ // 積算
+ float acc;
+ if (m_materialValueMap.TryGetValue(binding, out acc))
{
- // 値置き換え
- Action setter;
- if (m_materialSetterMap.TryGetValue(binding, out setter))
- {
- setter(value);
- }
+ m_materialValueMap[binding] = acc + value;
}
else
{
- // 積算
- float acc;
- if (m_materialValueMap.TryGetValue(binding, out acc))
- {
- m_materialValueMap[binding] = acc + value;
- }
- else
- {
- m_materialValueMap[binding] = value;
- }
+ m_materialValueMap[binding] = value;
}
}
}
+ ///
+ /// 即時に反映する
+ ///
+ ///
+ ///
+ public void ImmediatelySetValue(BlendShapeKey key, float value)
+ {
+ m_valueMap[key] = value;
+
+ BlendShapeClip clip;
+ if (!m_clipMap.TryGetValue(key, out clip))
+ {
+ return;
+ }
+
+ if (clip.IsBinary)
+ {
+ value = Mathf.Round(value);
+ }
+
+ foreach (var binding in clip.Values)
+ {
+ Action setter;
+ if (m_blendShapeSetterMap.TryGetValue(binding, out setter))
+ {
+ setter(binding.Weight * value);
+ }
+ }
+
+ foreach (var binding in clip.MaterialValues)
+ {
+ Action setter;
+ if (m_materialSetterMap.TryGetValue(binding, out setter))
+ {
+ setter(value);
+ }
+ }
+ }
+
+ public void SetValue(BlendShapeKey key, float value, bool replace)
+ {
+ if (replace)
+ {
+ ImmediatelySetValue(key, value);
+ }
+ else
+ {
+ AccumulateValue(key, value);
+ }
+ }
+
public float GetValue(BlendShapeKey key)
{
float value;
@@ -259,7 +330,7 @@ namespace VRM
{
// restore values
Material material;
- if(m_materialMap.TryGetValue(y.MaterialName, out material))
+ if (m_materialMap.TryGetValue(y.MaterialName, out material))
{
material.SetColor(y.ValueName, y.BaseValue);
}