BlendShapeMerger.cs
4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Collections.Generic;
using System.Linq;
using UniGLTF;
using UnityEngine;
namespace VRM
{
/// <summary>
/// ブレンドシェイプを蓄えてまとめて適用するクラス
/// </summary>
class BlendShapeMerger
{
/// <summary>
/// Key からBlendShapeClipを得る
/// </summary>
Dictionary<BlendShapeKey, BlendShapeClip> m_clipMap;
/// <summary>
/// BlendShape のWeightを記録する
/// </summary>
Dictionary<BlendShapeKey, float> m_valueMap;
BlendShapeBindingMerger m_blendShapeBindingMerger;
MaterialValueBindingMerger m_materialValueBindingMerger;
public BlendShapeMerger(IEnumerable<BlendShapeClip> clips, Transform root)
{
m_clipMap = clips.ToDictionary(x => BlendShapeKey.CreateFrom(x), x => x);
m_valueMap = new Dictionary<BlendShapeKey, float>();
m_blendShapeBindingMerger = new BlendShapeBindingMerger(m_clipMap, root);
m_materialValueBindingMerger = new MaterialValueBindingMerger(m_clipMap, root);
}
/*
public void Clear()
{
foreach (var kv in m_valueMap.ToArray())
{
SetValue(kv.Key, kv.Value, false);
}
Apply();
}
*/
/// <summary>
/// 蓄積した値を適用する
/// </summary>
public void Apply()
{
m_blendShapeBindingMerger.Apply();
m_materialValueBindingMerger.Apply();
}
/// <summary>
/// まとめて反映する。1フレームに1回呼び出されることを想定
/// </summary>
/// <param name="values"></param>
public void SetValues(IEnumerable<KeyValuePair<BlendShapeKey, float>> values)
{
foreach (var kv in values)
{
AccumulateValue(kv.Key, kv.Value);
}
Apply();
}
/// <summary>
/// 即時に反映しない。後にApplyによって反映する
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void AccumulateValue(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);
}
m_blendShapeBindingMerger.AccumulateValue(clip, value);
m_materialValueBindingMerger.AccumulateValue(clip, value);
}
/// <summary>
/// 即時に反映する
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
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);
}
m_blendShapeBindingMerger.ImmediatelySetValue(clip, value);
m_materialValueBindingMerger.ImmediatelySetValue(clip, value);
}
public void SetValue(BlendShapeKey key, float value, bool immediately)
{
if (immediately)
{
ImmediatelySetValue(key, value);
}
else
{
AccumulateValue(key, value);
}
}
public float GetValue(BlendShapeKey key)
{
float value;
if (!m_valueMap.TryGetValue(key, out value))
{
return 0;
}
return value;
}
public void RestoreMaterialInitialValues(IEnumerable<BlendShapeClip> clips)
{
m_materialValueBindingMerger.RestoreMaterialInitialValues(clips);
}
}
}