// Magica Cloth.
// Copyright (c) MagicaSoft, 2020-2022.
// https://magicasoft.jp
using Unity.Mathematics;
using UnityEngine;
namespace MagicaCloth
{
///
/// 物理チーム
/// 特定のパーティクルと機能を1つのチームとして管理します。
/// 当たり判定はチーム内部のパーティクルに対してのみ有効です。
/// これによりチームごとに独立した環境を構築することが可能です。
/// 例:キャラクタAとBは当たり判定が干渉しないようにする
///
public abstract class PhysicsTeam : CoreComponent
{
[SerializeField]
protected PhysicsTeamData teamData = new PhysicsTeamData();
///
/// ユーザー設定ブレンド率
///
[SerializeField]
private float userBlendWeight = 1.0f;
///
/// 更新モード
///
public enum TeamUpdateMode
{
Normal = 0,
UnityPhysics = 1,
}
[SerializeField]
private TeamUpdateMode updateMode = TeamUpdateMode.Normal;
///
/// カリングモード(数値が高いほど優先)
///
public enum TeamCullingMode
{
Reset = 0,
Pause = 10,
Off = 100,
}
[SerializeField]
private TeamCullingMode cullingMode = TeamCullingMode.Reset;
///
/// スキニングモード
/// さらにNone以外の設定では計算時にアニメーション化された姿勢を利用するようになる(旧UseAnimatedDistanceフラグ)
///
public enum TeamSkinningMode
{
None = 0,
UserAnimation = 1,
//GenerateFromBones = 2,
}
[SerializeField]
private TeamSkinningMode skinningMode = TeamSkinningMode.UserAnimation;
//[SerializeField]
//private bool skinningUpdateFixed = false;
//=========================================================================================
///
/// この物理チームのID
///
protected int teamId = -1;
///
/// この物理チームで管理するパーティクル
///
protected ChunkData particleChunk = new ChunkData();
///
/// 速度影響/ワープ判定トランスフォーム
///
protected Transform influenceTarget;
//=========================================================================================
///
/// データハッシュを求める
///
///
public override int GetDataHash()
{
int hash = teamData.GetDataHash();
return hash;
}
//=========================================================================================
public int TeamId
{
get
{
return teamId;
}
}
public PhysicsTeamData TeamData
{
get
{
return teamData;
}
}
public ChunkData ParticleChunk
{
get
{
return particleChunk;
}
}
public Transform InfluenceTarget
{
set
{
influenceTarget = value;
}
get
{
return influenceTarget;
}
}
public float UserBlendWeight
{
get
{
return userBlendWeight;
}
set
{
userBlendWeight = Mathf.Clamp01(value);
}
}
public TeamUpdateMode UpdateMode
{
get
{
return updateMode;
}
protected set
{
updateMode = value;
}
}
public TeamCullingMode CullingMode
{
get
{
return cullingMode;
}
set
{
cullingMode = value;
}
}
public TeamSkinningMode SkinningMode
{
get => skinningMode;
set => skinningMode = value;
}
//public bool SkinningUpdateFixed
//{
// get => skinningUpdateFixed;
// set => skinningUpdateFixed = value;
//}
///
/// 計算に使用する距離/回転を常にアニメーション後の姿勢から取得するかどうか
///
internal bool UseAnimatedPose
{
get
{
//return skinningMode == TeamSkinningMode.UserAnimation || skinningMode == TeamSkinningMode.GenerateFromBones;
return skinningMode == TeamSkinningMode.UserAnimation;
}
}
//=========================================================================================
protected override void OnInit()
{
// チーム作成
teamId = MagicaPhysicsManager.Instance.Team.CreateTeam(this, 0);
TeamData.Init(TeamId);
}
///
/// 破棄
/// 通常はOnDestroy()で呼ぶ
///
protected override void OnDispose()
{
// 破棄
if (TeamId >= 0)
{
TeamData.Dispose(TeamId);
// チーム削除
if (MagicaPhysicsManager.IsInstance())
MagicaPhysicsManager.Instance.Team.RemoveTeam(teamId);
}
}
///
/// 更新
///
protected override void OnUpdate()
{
}
///
/// 実行状態に入った場合に呼ばれます
///
protected override void OnActive()
{
// チーム有効化
MagicaPhysicsManager.Instance.Team.SetEnable(teamId, true);
}
///
/// 実行状態から抜けた場合に呼ばれます
///
protected override void OnInactive()
{
if (MagicaPhysicsManager.IsInstance())
{
// チーム無効化
MagicaPhysicsManager.Instance.Team.SetEnable(teamId, false);
}
}
//=========================================================================================
///
/// 実行状態を取得
///
///
public bool IsActive()
{
if (MagicaPhysicsManager.IsInstance())
return MagicaPhysicsManager.Instance.Team.IsActive(teamId);
else
return false;
}
///
/// チームデータが存在するか判定
///
///
public bool IsValid()
{
if (MagicaPhysicsManager.IsInstance())
return MagicaPhysicsManager.Instance.Team.IsValid(teamId);
else
return false;
}
//=========================================================================================
///
/// パーティクルを1つ追加
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
//public ChunkData CreateParticle(
// uint flag,
// int team,
// float3 wpos, quaternion wrot,
// float3 lpos, quaternion lrot,
// float depth,
// float radius,
// Transform target, float3 targetLocalPos
// )
//{
// var c = MagicaPhysicsManager.Instance.Particle.CreateParticle(
// flag,
// team,
// wpos, wrot,
// lpos, lrot,
// depth,
// radius,
// target, targetLocalPos
// );
// // チームパーティクルとして管理する
// particleChunk = c;
// return c;
//}
///
/// パーティクルをグループで追加
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
///
public ChunkData CreateParticle(
int team,
int count,
System.Func funcFlag,
System.Func funcWpos,
System.Func funcWrot,
System.Func funcDepth,
System.Func funcRadius,
System.Func funcTargetLocalPos
)
{
var c = MagicaPhysicsManager.Instance.Particle.CreateParticle(
team,
count,
funcFlag,
funcWpos,
funcWrot,
funcDepth,
funcRadius,
funcTargetLocalPos
);
// チームパーティクルとして管理する
particleChunk = c;
return c;
}
///
/// パーティクル削除(全体のみ)
///
public void RemoveAllParticle()
{
MagicaPhysicsManager.Instance.Particle.RemoveParticle(particleChunk);
particleChunk.Clear();
}
///
/// 管理するパーティクルを有効化する
///
public void EnableParticle(
System.Func funcTarget,
System.Func funcLpos,
System.Func funcLrot
)
{
MagicaPhysicsManager.Instance.Particle.SetEnable(particleChunk, true, funcTarget, funcLpos, funcLrot);
}
///
/// 管理するパーティクルを無効化する
///
public void DisableParticle(
System.Func funcTarget,
System.Func funcLpos,
System.Func funcLrot
)
{
if (MagicaPhysicsManager.IsInstance())
{
MagicaPhysicsManager.Instance.Particle.SetEnable(particleChunk, false, funcTarget, funcLpos, funcLrot);
}
}
//=========================================================================================
///
/// 現在のデータが正常(実行できる状態)か返す
///
///
public override Define.Error VerifyData()
{
return base.VerifyData();
}
}
}