// 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);
}
}
}