mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-12 21:45:06 -05:00
add BlendShapeMerger
This commit is contained in:
parent
669fedd935
commit
8fb64eb6cd
|
|
@ -177,7 +177,8 @@ namespace VRM
|
|||
ClearBlendShape();
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
m_target.Reload();
|
||||
m_target.Restore();
|
||||
m_target.Apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,89 +4,234 @@ using System.Linq;
|
|||
using UnityEngine;
|
||||
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public class VRMBlendShapeProxy : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public BlendShapeAvatar BlendShapeAvatar;
|
||||
|
||||
Dictionary<BlendShapeKey, BlendShapeClipHandler> m_handlerMap;
|
||||
public Dictionary<BlendShapeKey, BlendShapeClipHandler> CreateHandlerMap()
|
||||
struct BlendShapePath
|
||||
{
|
||||
var handlerMap = new Dictionary<BlendShapeKey, BlendShapeClipHandler>(
|
||||
new BlendShapeKey.CustomerEqualityComparer());
|
||||
foreach (var x in BlendShapeAvatar.Clips)
|
||||
{
|
||||
handlerMap.Add(BlendShapeKey.CreateFrom(x), new BlendShapeClipHandler(x, transform));
|
||||
;
|
||||
}
|
||||
return handlerMap;
|
||||
public String RelativePath;
|
||||
public int Index;
|
||||
}
|
||||
|
||||
delegate void BlendShapeSetter(float value);
|
||||
|
||||
class BlendShapePathHandler
|
||||
{
|
||||
public BlendShapeSetter Setter;
|
||||
float m_value;
|
||||
|
||||
/*
|
||||
public void ReplaceValue(float value)
|
||||
{
|
||||
m_value = value;
|
||||
}
|
||||
*/
|
||||
|
||||
public void AddValue(float value)
|
||||
{
|
||||
m_value += value;
|
||||
}
|
||||
|
||||
public void Apply(float value)
|
||||
{
|
||||
Setter(value);
|
||||
m_value = 0;
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
Setter(m_value);
|
||||
m_value = 0;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_value = 0;
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
|
||||
class BlendShapeMerger
|
||||
{
|
||||
Dictionary<BlendShapeKey, BlendShapeClip> m_clipMap;
|
||||
Dictionary<BlendShapeKey, float> m_valueMap;
|
||||
Dictionary<BlendShapeBinding, BlendShapePathHandler> m_setterMap = new Dictionary<BlendShapeBinding, BlendShapePathHandler>();
|
||||
|
||||
public BlendShapeMerger(IEnumerable<BlendShapeClip> clips, Transform root)
|
||||
{
|
||||
m_clipMap = clips.ToDictionary(x => BlendShapeKey.CreateFrom(x), x => x, new BlendShapeKey.CustomerEqualityComparer());
|
||||
m_valueMap = new Dictionary<BlendShapeKey, float>(new BlendShapeKey.CustomerEqualityComparer());
|
||||
foreach (var kv in m_clipMap)
|
||||
{
|
||||
foreach (var binding in kv.Value.Values) {
|
||||
|
||||
if (!m_setterMap.ContainsKey(binding))
|
||||
{
|
||||
var _target = root.Find(binding.RelativePath);
|
||||
SkinnedMeshRenderer target = null;
|
||||
if (_target != null)
|
||||
{
|
||||
target = _target.GetComponent<SkinnedMeshRenderer>();
|
||||
}
|
||||
if (target != null)
|
||||
{
|
||||
m_setterMap.Add(binding, new BlendShapePathHandler
|
||||
{
|
||||
Setter = x =>
|
||||
{
|
||||
target.SetBlendShapeWeight(binding.Index, x);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarningFormat("{0} not found", binding.RelativePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach(var kv in m_setterMap)
|
||||
{
|
||||
kv.Value.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Restore()
|
||||
{
|
||||
foreach (var kv in m_valueMap.ToArray())
|
||||
{
|
||||
SetValue(kv.Key, kv.Value, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
foreach(var kv in m_setterMap)
|
||||
{
|
||||
kv.Value.Apply();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValue(BlendShapeKey key, float value, bool replace)
|
||||
{
|
||||
m_valueMap[key] = value;
|
||||
|
||||
BlendShapeClip clip;
|
||||
if(!m_clipMap.TryGetValue(key, out clip))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(var binding in clip.Values)
|
||||
{
|
||||
BlendShapePathHandler handler;
|
||||
if(m_setterMap.TryGetValue(binding, out handler))
|
||||
{
|
||||
if (replace)
|
||||
{
|
||||
// 値置き換え
|
||||
//handler.ReplaceValue();
|
||||
handler.Apply(binding.Weight * value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 積算
|
||||
handler.AddValue(binding.Weight * value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarningFormat("'{0}' not found", binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetValue(BlendShapeKey key)
|
||||
{
|
||||
float value;
|
||||
if (!m_valueMap.TryGetValue(key, out value))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
BlendShapeMerger m_merger;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (BlendShapeAvatar != null)
|
||||
{
|
||||
if (m_handlerMap == null)
|
||||
if (m_merger == null)
|
||||
{
|
||||
m_handlerMap = CreateHandlerMap();
|
||||
m_merger = new BlendShapeMerger(BlendShapeAvatar.Clips, transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
public void SetValue(BlendShapePreset key, float value, bool apply=true)
|
||||
{
|
||||
if (BlendShapeAvatar == null) return;
|
||||
|
||||
foreach (var kv in m_handlerMap)
|
||||
{
|
||||
SetValue(kv.Key, GetValue(kv.Key));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValue(BlendShapePreset key, float value)
|
||||
{
|
||||
SetValue(new BlendShapeKey(key), value);
|
||||
SetValue(new BlendShapeKey(key), value, apply);
|
||||
}
|
||||
public float GetValue(BlendShapePreset key)
|
||||
{
|
||||
return GetValue(new BlendShapeKey(key));
|
||||
}
|
||||
public void SetValue(String key, float value)
|
||||
public void SetValue(String key, float value, bool apply=true)
|
||||
{
|
||||
SetValue(new BlendShapeKey(key), value);
|
||||
SetValue(new BlendShapeKey(key), value, apply);
|
||||
}
|
||||
public float GetValue(String key)
|
||||
{
|
||||
return GetValue(new BlendShapeKey(key));
|
||||
}
|
||||
public void SetValue(BlendShapeKey key, float value)
|
||||
public void SetValue(BlendShapeKey key, float value, bool apply=true)
|
||||
{
|
||||
if (m_handlerMap == null) return;
|
||||
BlendShapeClipHandler handler;
|
||||
if (m_handlerMap.TryGetValue(key, out handler))
|
||||
if (m_merger != null)
|
||||
{
|
||||
handler.Apply(value);
|
||||
m_merger.SetValue(key, value, apply);
|
||||
}
|
||||
}
|
||||
public float GetValue(BlendShapeKey key)
|
||||
{
|
||||
if (m_handlerMap == null) return 0;
|
||||
BlendShapeClipHandler handler;
|
||||
if (!m_handlerMap.TryGetValue(key, out handler))
|
||||
if (m_merger == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return handler.LastValue;
|
||||
return m_merger.GetValue(key);
|
||||
}
|
||||
|
||||
public void ClearKeys()
|
||||
{
|
||||
if (m_handlerMap == null) return;
|
||||
foreach(var kv in m_handlerMap)
|
||||
if (m_merger != null)
|
||||
{
|
||||
kv.Value.Apply(0);
|
||||
m_merger.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Restore()
|
||||
{
|
||||
if (m_merger != null)
|
||||
{
|
||||
m_merger.Restore();
|
||||
}
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
if (m_merger != null)
|
||||
{
|
||||
m_merger.Apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ namespace VRM
|
|||
public static class VRMVersion
|
||||
{
|
||||
public const int MAJOR = 0;
|
||||
public const int MINOR = 10;
|
||||
public const int MINOR = 11;
|
||||
|
||||
public const string VERSION = "0.10";
|
||||
public const string VERSION = "0.11";
|
||||
|
||||
public const string DecrementMenuName = "VRM/Version(0.10) Decrement";
|
||||
public const string IncrementMenuName = "VRM/Version(0.10) Increment";
|
||||
public const string DecrementMenuName = "VRM/Version(0.11) Decrement";
|
||||
public const string IncrementMenuName = "VRM/Version(0.11) Increment";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user