// Magica Cloth.
// Copyright (c) MagicaSoft, 2020-2022.
// https://magicasoft.jp
using UnityEngine;
namespace MagicaCloth
{
///
/// 面コライダー
/// トランスフォームのY+方向を面の法線として計算する
///
[HelpURL("https://magicasoft.jp/magica-cloth-plane-collider/")]
[AddComponentMenu("MagicaCloth/MagicaPlaneCollider")]
public class MagicaPlaneCollider : ColliderComponent
{
//=========================================================================================
public override ComponentType GetComponentType()
{
return ComponentType.PlaneCollider;
}
private void OnValidate()
{
if (Application.isPlaying)
DataUpdate();
}
///
/// パーティクルのデータ更新処理
///
internal override void DataUpdate()
{
base.DataUpdate();
// localPos
foreach (var c in particleDict.Values)
{
for (int i = 0; i < c.dataLength; i++)
{
MagicaPhysicsManager.Instance.Particle.SetLocalPos(c.startIndex + i, Center);
}
}
}
//=========================================================================================
protected override ChunkData CreateColliderParticleReal(int teamId)
{
uint flag = 0;
flag |= PhysicsManagerParticleData.Flag_Kinematic;
flag |= PhysicsManagerParticleData.Flag_Collider;
flag |= PhysicsManagerParticleData.Flag_Transform_Read_Pos;
flag |= PhysicsManagerParticleData.Flag_Transform_Read_Rot;
flag |= PhysicsManagerParticleData.Flag_Transform_Read_Base;
flag |= PhysicsManagerParticleData.Flag_Plane;
flag |= PhysicsManagerParticleData.Flag_Reset_Position;
flag |= PhysicsManagerParticleData.Flag_Transform_Read_Local;
var c = CreateParticle(
flag,
teamId, // team
0.0f, // depth
1.0f, // radius
Center
);
if (c.IsValid())
MagicaPhysicsManager.Instance.Team.AddCollider(teamId, c.startIndex);
return c;
}
///
/// 指定座標に最も近い衝突点pと、中心軸からのpへの方向dirを返す。
/// ※エディタ計算用
///
///
///
///
public override bool CalcNearPoint(Vector3 pos, out Vector3 p, out Vector3 dir, out Vector3 d, bool skinning)
{
dir = Vector3.zero;
// 平面姿勢
//var cpos = transform.position;
var cpos = transform.TransformPoint(Center);
// 平面法線
var cdir = transform.up;
// 平面法線に投影
var v = pos - cpos;
var gv = Vector3.Project(v, cdir);
p = pos - gv;
d = p;
dir = gv.normalized;
return Vector3.Dot(v, gv) <= 0.0f;
}
}
}