// Magica Cloth. // Copyright (c) MagicaSoft, 2020-2022. // https://magicasoft.jp using System.Collections.Generic; using UnityEngine; namespace MagicaCloth { /// /// コライダーパーティクルオブジェクト基底クラス /// public abstract class ColliderComponent : ParticleComponent { /// /// グローバルフラグ /// [SerializeField] protected bool isGlobal; [SerializeField] private Vector3 center; //========================================================================================= public Vector3 Center { get { return center; } set { center = value; ReserveDataUpdate(); } } //========================================================================================= /// /// 初期化 /// protected override void OnInit() { base.OnInit(); // パーティクル初期化 if (isGlobal) { CreateColliderParticle(0); } } /// /// 破棄 /// protected override void OnDispose() { // チームからコライダーを解除する List teamList = new List(); foreach (var teamId in particleDict.Keys) { teamList.Add(teamId); } foreach (var teamId in teamList) { RemoveColliderParticle(teamId); } base.OnDispose(); } //========================================================================================= /// /// データハッシュ計算 /// /// public override int GetDataHash() { return isGlobal.GetDataHash(); } /// /// 指定座標に最も近い衝突点pと、中心軸からのpへの方向dirを返す。 /// ※エディタ計算用 /// /// /// 衝突点 /// 中心軸位置から衝突点へのベクトル /// 最も近い中心軸位置 public abstract bool CalcNearPoint(Vector3 pos, out Vector3 p, out Vector3 dir, out Vector3 d, bool skinning); /// /// 指定座標のローカル位置を返す /// ※エディタ計算用 /// /// /// public Vector3 CalcLocalPos(Vector3 pos) { // スケールは含めない var rot = transform.rotation; var v = pos - transform.position; return Quaternion.Inverse(rot) * v; } /// /// 指定方向のローカル方向を返す /// ※エディタ計算用 /// /// /// public Vector3 CalcLocalDir(Vector3 dir) { return transform.InverseTransformDirection(dir); } /// /// 指定チーム用のコライダーパーティクルを作成 /// /// /// public ChunkData CreateColliderParticle(int teamId) { var c = CreateColliderParticleReal(teamId); // すでにアクティブならばパーティクル有効化 if (c.IsValid() && Status.IsActive) EnableTeamParticle(teamId); return c; } /// /// 指定チームのコライダーパーティクルを削除 /// /// public void RemoveColliderParticle(int teamId) { if (MagicaPhysicsManager.IsInstance() == false) return; if (particleDict.ContainsKey(teamId)) { var c = particleDict[teamId]; for (int i = 0; i < c.dataLength; i++) { int pindex = c.startIndex + i; MagicaPhysicsManager.Instance.Team.RemoveCollider(teamId, pindex); } RemoveTeamParticle(teamId); } } //========================================================================================= /// /// 指定チーム用のコライダーパーティクル作成 /// /// /// protected abstract ChunkData CreateColliderParticleReal(int teamId); } }