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