diff --git a/Assets/VRM10/Runtime/Components/Expression/ExpressionAccumulator.cs b/Assets/VRM10/Runtime/Components/Expression/ExpressionAccumulator.cs index 96717436e..5905c8d70 100644 --- a/Assets/VRM10/Runtime/Components/Expression/ExpressionAccumulator.cs +++ b/Assets/VRM10/Runtime/Components/Expression/ExpressionAccumulator.cs @@ -3,173 +3,101 @@ using System.Linq; namespace UniVRM10 { - /// - /// 1フレーム分の Expression を蓄える - /// - public interface IExpressionAccumulator - { - /// - /// 開始時に初期化する - /// - /// - void OnStart(VRM10ExpressionAvatar avatar); - - /// - /// 蓄えて処理(ignoreフラグなど)した結果を得る - /// - /// - IEnumerable> FrameExpression(); - - void SetValue(ExpressionKey key, float value); - void SetValues(IEnumerable> values); - float GetValue(ExpressionKey key); - IEnumerable> GetValues(); - - bool IgnoreBlink { get; } - bool IgnoreLookAt { get; } - bool IgnoreMouth { get; } - } - - public static class ExpressionAccumulatorExtensions - { - public static float GetPresetValue(this IExpressionAccumulator self, VrmLib.ExpressionPreset key) - { - var expressionKey = new ExpressionKey(key); - return self.GetValue(expressionKey); - } - - public static float GetCustomValue(this IExpressionAccumulator self, string key) - { - var expressionKey = ExpressionKey.CreateCustom(key); - return self.GetValue(expressionKey); - } - - public static void SetPresetValue(this IExpressionAccumulator self, VrmLib.ExpressionPreset key, float value) - { - var expressionKey = new ExpressionKey(key); - self.SetValue(expressionKey, value); - } - - public static void SetCustomValue(this IExpressionAccumulator self, string key, float value) - { - var expressionKey = ExpressionKey.CreateCustom(key); - self.SetValue(expressionKey, value); - } - } - public class DefaultExpressionAccumulator : IExpressionAccumulator { - bool m_ignoreBlink; - bool m_ignoreLookAt; - bool m_ignoreMouth; - - public bool IgnoreBlink => m_ignoreBlink; - public bool IgnoreLookAt => m_ignoreLookAt; - public bool IgnoreMouth => m_ignoreMouth; - - public Dictionary expressionKeyWeights = new Dictionary(); - - List m_blinkExpressionKeys = new List(); - List m_lookAtExpressionKeys = new List(); - List m_mouthExpressionKeys = new List(); - - /// - /// Key から Expression を得る - /// Dictionary m_clipMap; + Dictionary expressionKeyWeights = new Dictionary(); + + public bool IgnoreBlink { get; private set; } + public bool IgnoreLookAt { get; private set; } + public bool IgnoreMouth { get; private set; } + + /// + /// initilaize + /// + /// 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); - - m_blinkExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.Blink)); - m_blinkExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.BlinkLeft)); - m_blinkExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.BlinkRight)); - m_lookAtExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.LookUp)); - m_lookAtExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.LookDown)); - m_lookAtExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.LookLeft)); - m_lookAtExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.LookRight)); - m_mouthExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.Aa)); - m_mouthExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.Ih)); - m_mouthExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.Ou)); - m_mouthExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.Ee)); - m_mouthExpressionKeys.Add(m_clipMap.Keys.FirstOrDefault(x => x.Preset == VrmLib.ExpressionPreset.Oh)); - } - - public VRM10Expression GetClip(ExpressionKey key) - { - if (m_clipMap.ContainsKey(key)) - { - return m_clipMap[key]; - } - else - { - return null; - } - } - - public IEnumerable> FrameExpression() - { - var validateState = GetValidateState(); - m_ignoreBlink = validateState.ignoreBlink; - m_ignoreLookAt = validateState.ignoreLookAt; - m_ignoreMouth = validateState.ignoreMouth; - - return expressionKeyWeights - .Where(x => - { - // skip ignore - if (validateState.ignoreBlink) - { - switch (x.Key.Preset) - { - case VrmLib.ExpressionPreset.Blink: - case VrmLib.ExpressionPreset.BlinkLeft: - case VrmLib.ExpressionPreset.BlinkRight: - return false; - } - } - if (validateState.ignoreMouth) - { - switch (x.Key.Preset) - { - case VrmLib.ExpressionPreset.Aa: - case VrmLib.ExpressionPreset.Ih: - case VrmLib.ExpressionPreset.Ou: - case VrmLib.ExpressionPreset.Ee: - case VrmLib.ExpressionPreset.Oh: - return false; - } - } - if (validateState.ignoreLookAt) - { - switch (x.Key.Preset) - { - case VrmLib.ExpressionPreset.LookUp: - case VrmLib.ExpressionPreset.LookDown: - case VrmLib.ExpressionPreset.LookLeft: - case VrmLib.ExpressionPreset.LookRight: - return false; - } - } - - return true; - }) - .Select(x => new KeyValuePair(x.Key, x.Value)); } /// - /// SetValue + /// each frame /// - /// - /// - public void SetValue(ExpressionKey key, float value) + /// + public IEnumerable> FrameExpression() { - if (expressionKeyWeights.ContainsKey(key)) + IgnoreBlink = false; + IgnoreLookAt = false; + IgnoreMouth = false; + + // + // except blink, lookat, mouth + // + foreach (var kv in expressionKeyWeights) { - expressionKeyWeights[key] = value; + if (kv.Key.IsProcedual) + { + // 後で + continue; + } + + var expression = m_clipMap[kv.Key]; + + if (expression.IgnoreBlink && kv.Value > 0) + { + IgnoreBlink = true; + } + if (expression.IgnoreLookAt && kv.Value > 0) + { + IgnoreLookAt = true; + } + if (expression.IgnoreMouth && 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; } } @@ -196,9 +124,18 @@ namespace UniVRM10 } /// - /// Set expression values. + /// SetValue /// - /// + /// + /// + public void SetValue(ExpressionKey key, float value) + { + if (expressionKeyWeights.ContainsKey(key)) + { + expressionKeyWeights[key] = value; + } + } + public void SetValues(IEnumerable> values) { foreach (var keyValue in values) @@ -209,45 +146,5 @@ namespace UniVRM10 } } } - - public IEnumerable GetKeys() - { - return expressionKeyWeights.Keys; - } - - private (bool ignoreBlink, bool ignoreLookAt, bool ignoreMouth) GetValidateState() - { - var ignoreBlink = false; - var ignoreLookAt = false; - var ignoreMouth = false; - - foreach (var keyWeight in expressionKeyWeights) - { - if (keyWeight.Value <= 0.0f) - continue; - - // Blink - if (!ignoreBlink && GetClip(keyWeight.Key).IgnoreBlink && !m_blinkExpressionKeys.Contains(keyWeight.Key)) - { - ignoreBlink = true; - } - - // LookAt - if (!ignoreLookAt && GetClip(keyWeight.Key).IgnoreLookAt && !m_lookAtExpressionKeys.Contains(keyWeight.Key)) - { - ignoreLookAt = true; - } - - // Mouth - if (!ignoreMouth && GetClip(keyWeight.Key).IgnoreMouth && !m_mouthExpressionKeys.Contains(keyWeight.Key)) - { - ignoreMouth = true; - } - } - - return (ignoreBlink, ignoreLookAt, ignoreMouth); - } - } - } diff --git a/Assets/VRM10/Runtime/Components/Expression/ExpressionKey.cs b/Assets/VRM10/Runtime/Components/Expression/ExpressionKey.cs index 9237653e3..c09cd6b4f 100644 --- a/Assets/VRM10/Runtime/Components/Expression/ExpressionKey.cs +++ b/Assets/VRM10/Runtime/Components/Expression/ExpressionKey.cs @@ -27,6 +27,56 @@ namespace UniVRM10 public VrmLib.ExpressionPreset Preset; + public bool IsBlink + { + get + { + switch (Preset) + { + case VrmLib.ExpressionPreset.Blink: + case VrmLib.ExpressionPreset.BlinkLeft: + case VrmLib.ExpressionPreset.BlinkRight: + return true; + } + return false; + } + } + + public bool IsLookAt + { + get + { + switch (Preset) + { + case VrmLib.ExpressionPreset.LookUp: + case VrmLib.ExpressionPreset.LookDown: + case VrmLib.ExpressionPreset.LookLeft: + case VrmLib.ExpressionPreset.LookRight: + return true; + } + return false; + } + } + + public bool IsMouth + { + get + { + switch (Preset) + { + case VrmLib.ExpressionPreset.Aa: + case VrmLib.ExpressionPreset.Ih: + case VrmLib.ExpressionPreset.Ou: + case VrmLib.ExpressionPreset.Ee: + case VrmLib.ExpressionPreset.Oh: + return true; + } + return false; + } + } + + public bool IsProcedual => IsBlink || IsLookAt || IsMouth; + string m_id; string ID @@ -147,4 +197,5 @@ namespace UniVRM10 return 0; } } + } diff --git a/Assets/VRM10/Runtime/Components/Expression/IExpressionAccumulator.cs b/Assets/VRM10/Runtime/Components/Expression/IExpressionAccumulator.cs new file mode 100644 index 000000000..49c7301dc --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Expression/IExpressionAccumulator.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; + +namespace UniVRM10 +{ + /// + /// 1フレーム分の Expression を蓄える + /// + public interface IExpressionAccumulator + { + /// + /// 開始時に初期化する + /// + /// + void OnStart(VRM10ExpressionAvatar avatar); + + /// + /// 蓄えて処理(ignoreフラグなど)した結果を得る + /// + /// + IEnumerable> FrameExpression(); + + void SetValue(ExpressionKey key, float value); + void SetValues(IEnumerable> values); + float GetValue(ExpressionKey key); + IEnumerable> GetValues(); + + bool IgnoreBlink { get; } + bool IgnoreLookAt { get; } + bool IgnoreMouth { get; } + } + + public static class ExpressionAccumulatorExtensions + { + public static float GetPresetValue(this IExpressionAccumulator self, VrmLib.ExpressionPreset key) + { + var expressionKey = new ExpressionKey(key); + return self.GetValue(expressionKey); + } + + public static float GetCustomValue(this IExpressionAccumulator self, string key) + { + var expressionKey = ExpressionKey.CreateCustom(key); + return self.GetValue(expressionKey); + } + + public static void SetPresetValue(this IExpressionAccumulator self, VrmLib.ExpressionPreset key, float value) + { + var expressionKey = new ExpressionKey(key); + self.SetValue(expressionKey, value); + } + + public static void SetCustomValue(this IExpressionAccumulator self, string key, float value) + { + var expressionKey = ExpressionKey.CreateCustom(key); + self.SetValue(expressionKey, value); + } + } +} diff --git a/Assets/VRM10/Runtime/Components/Expression/IExpressionAccumulator.cs.meta b/Assets/VRM10/Runtime/Components/Expression/IExpressionAccumulator.cs.meta new file mode 100644 index 000000000..c855193a0 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Expression/IExpressionAccumulator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fdd7cdf6d59574348bb7336272ef5edf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: