// Magica Cloth. // Copyright (c) MagicaSoft, 2020-2022. // https://magicasoft.jp using System.Collections.Generic; using UnityEngine; namespace MagicaCloth { /// /// ボーンクロスのターゲットトランスフォーム /// [System.Serializable] public class BoneClothTarget : IDataHash, IBoneReplace { /// /// ルートトランスフォーム /// [SerializeField] private List rootList = new List(); /// /// 接続モード /// public enum ConnectionMode { Line = 0, MeshAutomatic = 1, MeshSequentialLoop = 2, MeshSequentialNoLoop = 3, } [SerializeField] private ConnectionMode connection = ConnectionMode.Line; /// /// メッシュ構築時に同一とみなす面角度(面法線方向に影響) /// [SerializeField] [Range(10.0f, 90.0f)] private float sameSurfaceAngle = 80.0f; //========================================================================================= /// /// ルートの親トランスフォームの登録インデックス /// private int[] parentIndexList = null; //========================================================================================= /// /// データを識別するハッシュコードを作成して返す /// /// public int GetDataHash() { int hash = 0; hash += rootList.GetDataHash(); return hash; } //========================================================================================= /// /// ルートトランスフォームの数 /// public int RootCount { get { return rootList.Count; } } /// /// ルートトランスフォーム取得 /// /// /// public Transform GetRoot(int index) { if (index < rootList.Count) return rootList[index]; return null; } /// /// ルートトランスフォームのインデックスを返す。無い場合は(-1) /// /// /// public int GetRootIndex(Transform root) { return rootList.IndexOf(root); } /// /// ルートの親トランスフォームをすべて登録する /// public void AddParentTransform() { if (rootList.Count > 0) { HashSet parentSet = new HashSet(); foreach (var t in rootList) { if (t && t.parent) parentSet.Add(t.parent); } parentIndexList = new int[parentSet.Count]; int i = 0; foreach (var parent in parentSet) { int index = -1; if (parent) { index = MagicaPhysicsManager.Instance.Bone.AddBone(parent); } parentIndexList[i] = index; i++; } } } /// /// ルートの親トランスフォームをすべて解除する /// public void RemoveParentTransform() { if (MagicaPhysicsManager.IsInstance()) { if (parentIndexList != null && parentIndexList.Length > 0) { for (int i = 0; i < parentIndexList.Length; i++) { var index = parentIndexList[i]; if (index >= 0) { MagicaPhysicsManager.Instance.Bone.RemoveBone(index); } } } } parentIndexList = null; } /// /// ルートの親トランスフォームの未来予測をリセットする /// public void ResetFuturePredictionParentTransform() { if (parentIndexList != null && parentIndexList.Length > 0) { for (int i = 0; i < parentIndexList.Length; i++) { var index = parentIndexList[i]; if (index >= 0) { MagicaPhysicsManager.Instance.Bone.ResetFuturePrediction(index); } } } } /// /// ボーンのUnityPhysics利用カウンタを増減させる /// /// public void ChangeUnityPhysicsCount(bool sw) { if (parentIndexList != null && parentIndexList.Length > 0) { for (int i = 0; i < parentIndexList.Length; i++) { var index = parentIndexList[i]; if (index >= 0) { MagicaPhysicsManager.Instance.Bone.ChangeUnityPhysicsCount(index, sw); } } } } /// /// 接続モード取得 /// public ConnectionMode Connection { get { return connection; } } public float SameSurfaceAngle { get { return sameSurfaceAngle; } } public bool IsMeshConnection { get { return connection == ConnectionMode.MeshAutomatic || connection == ConnectionMode.MeshSequentialLoop || connection == ConnectionMode.MeshSequentialNoLoop; } } //========================================================================================= /// /// ボーン置換 /// /// public void ReplaceBone(Dictionary boneReplaceDict) where T : class { for (int i = 0; i < rootList.Count; i++) { rootList[i] = MeshUtility.GetReplaceBone(rootList[i], boneReplaceDict); } } /// /// 現在使用しているボーンを格納して返す /// /// public HashSet GetUsedBones() { return new HashSet(rootList); } } }