mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-07 22:04:50 -05:00
88 lines
2.8 KiB
C#
88 lines
2.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UniGLTF.Utils;
|
|
using UnityEngine;
|
|
|
|
namespace UniVRM10
|
|
{
|
|
|
|
/// <summary>
|
|
/// ブレンドシェイプを蓄えてまとめて適用するクラス
|
|
/// </summary>
|
|
internal sealed class ExpressionMerger : IDisposable
|
|
{
|
|
/// <summary>
|
|
/// Key から Expression を得る
|
|
/// </summary>
|
|
Dictionary<ExpressionKey, VRM10Expression> m_clipMap;
|
|
|
|
/// <summary>
|
|
/// Expression のWeightを記録する
|
|
/// </summary>
|
|
Dictionary<ExpressionKey, float> m_valueMap;
|
|
|
|
MorphTargetBindingMerger m_morphTargetBindingMerger;
|
|
MaterialValueBindingMerger m_materialValueBindingMerger;
|
|
NodeTransformBindingMerger m_boneTransformBindingMerger;
|
|
|
|
|
|
public ExpressionMerger(VRM10ObjectExpression expressions,
|
|
Transform root,
|
|
bool isPrefabInstance,
|
|
IReadOnlyDictionary<Transform, TransformState> initPose)
|
|
{
|
|
m_clipMap = expressions.Clips.ToDictionary(
|
|
x => expressions.CreateKey(x.Clip),
|
|
x => x.Clip,
|
|
ExpressionKey.Comparer
|
|
);
|
|
m_valueMap = new Dictionary<ExpressionKey, float>(ExpressionKey.Comparer);
|
|
m_morphTargetBindingMerger = new MorphTargetBindingMerger(m_clipMap, root);
|
|
m_materialValueBindingMerger = new MaterialValueBindingMerger(m_clipMap, root, isPrefabInstance);
|
|
m_boneTransformBindingMerger = new NodeTransformBindingMerger(m_clipMap, root, initPose);
|
|
}
|
|
|
|
/// <summary>
|
|
/// まとめて反映する。1フレームに1回呼び出されることを想定
|
|
/// </summary>
|
|
/// <param name="expressionWeights"></param>
|
|
public void SetValues(Dictionary<ExpressionKey, float> expressionWeights)
|
|
{
|
|
foreach (var (key, weight) in expressionWeights)
|
|
{
|
|
AccumulateValue(key, weight);
|
|
}
|
|
|
|
m_morphTargetBindingMerger.Apply();
|
|
m_materialValueBindingMerger.Apply();
|
|
m_boneTransformBindingMerger.Apply();
|
|
}
|
|
|
|
private void AccumulateValue(ExpressionKey key, float value)
|
|
{
|
|
m_valueMap[key] = value;
|
|
|
|
VRM10Expression clip;
|
|
if (!m_clipMap.TryGetValue(key, out clip))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (clip.IsBinary)
|
|
{
|
|
value = value > 0.5f ? 1 : 0;
|
|
}
|
|
|
|
m_morphTargetBindingMerger.AccumulateValue(key, value);
|
|
m_materialValueBindingMerger.AccumulateValue(clip, value);
|
|
m_boneTransformBindingMerger.AccumulateValue(key, value);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
m_materialValueBindingMerger.Dispose();
|
|
}
|
|
}
|
|
}
|