using System; using UnityEngine; namespace UniVRM10 { [Serializable] public struct MorphTargetBinding : IEquatable { /// /// Unity の BlendShape の値域は 0-100 /// public const float VRM_TO_UNITY = 100.0f; /// /// VRM-1.0 の MorphTargetBinding.Weight の値域は 0-1.0 /// public const float UNITY_TO_VRM = 0.01f; public const float MAX_WEIGHT = 1.0f; /// /// SkinnedMeshRenderer.BlendShape[Index].Weight を 指し示す。 /// /// [トレードオフ] /// /// * SkinnedMeshRenderer そのものの方がわかりやすい /// * Prefab 生成時の順番問題 /// * Prefabの中で、Prefab自体を参照するので String の方が扱いが楽(Prefab生成時にトラブルになりがち。Runtimeロードでは問題ない) /// * モデル変更時の改変への強さ /// /// // シリアライズしてEditorから変更するので readonly 不可 public /*readonly*/ String RelativePath; public /*readonly*/ int Index; public /*readonly*/ float Weight; /// /// /// /// /// /// 0 to 1.0 public MorphTargetBinding(string path, int index, float weight) { RelativePath = path; Index = index; if (weight > MAX_WEIGHT) { Debug.LogWarning($"MorphTargetBinding: {weight} > {MAX_WEIGHT}"); } Weight = weight; } public override string ToString() { return string.Format("{0}[{1}]=>{2}", RelativePath, Index, Weight); } public bool Equals(MorphTargetBinding other) { return string.Equals(RelativePath, other.RelativePath) && Index == other.Index && Weight.Equals(other.Weight); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; return obj is MorphTargetBinding && Equals((MorphTargetBinding)obj); } public override int GetHashCode() { unchecked { var hashCode = (RelativePath != null ? RelativePath.GetHashCode() : 0); hashCode = (hashCode * 397) ^ Index; hashCode = (hashCode * 397) ^ Weight.GetHashCode(); return hashCode; } } } }