mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-07 05:36:56 -05:00
151 lines
4.3 KiB
C#
151 lines
4.3 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace UniVRM10
|
|
{
|
|
public class DefaultExpressionAccumulator : IExpressionAccumulator
|
|
{
|
|
Dictionary<ExpressionKey, VRM10Expression> m_clipMap;
|
|
|
|
Dictionary<ExpressionKey, float> expressionKeyWeights = new Dictionary<ExpressionKey, float>();
|
|
|
|
public bool IgnoreBlink { get; private set; }
|
|
public bool IgnoreLookAt { get; private set; }
|
|
public bool IgnoreMouth { get; private set; }
|
|
|
|
/// <summary>
|
|
/// initilaize
|
|
/// </summary>
|
|
/// <param name="avatar"></param>
|
|
public void OnStart(VRM10ExpressionAvatar avatar)
|
|
{
|
|
m_clipMap = avatar.Clips.ToDictionary(x => ExpressionKey.CreateFromClip(x), x => x);
|
|
expressionKeyWeights = m_clipMap.Keys.ToDictionary(x => x, x => 0.0f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// each frame
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public IEnumerable<KeyValuePair<ExpressionKey, float>> FrameExpression()
|
|
{
|
|
IgnoreBlink = false;
|
|
IgnoreLookAt = false;
|
|
IgnoreMouth = false;
|
|
|
|
//
|
|
// except blink, lookat, mouth
|
|
//
|
|
foreach (var kv in expressionKeyWeights)
|
|
{
|
|
if (kv.Key.IsProcedual)
|
|
{
|
|
// 後で
|
|
continue;
|
|
}
|
|
|
|
var expression = m_clipMap[kv.Key];
|
|
|
|
if (expression.OverrideBlink == VrmLib.ExpressionOverrideType.Block && kv.Value > 0)
|
|
{
|
|
IgnoreBlink = true;
|
|
}
|
|
if (expression.OverrideLookAt == VrmLib.ExpressionOverrideType.Block && kv.Value > 0)
|
|
{
|
|
IgnoreLookAt = true;
|
|
}
|
|
if (expression.OverrideMouth == VrmLib.ExpressionOverrideType.Block && kv.Value > 0)
|
|
{
|
|
IgnoreMouth = true;
|
|
}
|
|
|
|
yield return kv;
|
|
}
|
|
|
|
//
|
|
// blink, lookat, mouth
|
|
//
|
|
foreach (var kv in expressionKeyWeights)
|
|
{
|
|
if (kv.Key.IsBlink)
|
|
{
|
|
if (IgnoreBlink)
|
|
{
|
|
// skip
|
|
continue;
|
|
}
|
|
}
|
|
else if (kv.Key.IsLookAt)
|
|
{
|
|
if (IgnoreLookAt)
|
|
{
|
|
// skip
|
|
continue;
|
|
}
|
|
}
|
|
else if (kv.Key.IsMouth)
|
|
{
|
|
if (IgnoreMouth)
|
|
{
|
|
// skip
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// already return
|
|
continue;
|
|
}
|
|
|
|
yield return kv;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a expression value
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
public float GetValue(ExpressionKey key)
|
|
{
|
|
if (expressionKeyWeights.ContainsKey(key))
|
|
{
|
|
return expressionKeyWeights[key];
|
|
}
|
|
else
|
|
{
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
public IEnumerable<KeyValuePair<ExpressionKey, float>> GetValues()
|
|
{
|
|
return expressionKeyWeights.Select(x => new KeyValuePair<ExpressionKey, float>(x.Key, x.Value));
|
|
}
|
|
|
|
/// <summary>
|
|
/// SetValue
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="value"></param>
|
|
public void SetValue(ExpressionKey key, float value)
|
|
{
|
|
if (expressionKeyWeights.ContainsKey(key))
|
|
{
|
|
expressionKeyWeights[key] = value;
|
|
}
|
|
}
|
|
|
|
public void SetValues(IEnumerable<KeyValuePair<ExpressionKey, float>> values)
|
|
{
|
|
foreach (var keyValue in values)
|
|
{
|
|
if (expressionKeyWeights.ContainsKey(keyValue.Key))
|
|
{
|
|
expressionKeyWeights[keyValue.Key] = keyValue.Value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|