// Magica Cloth.
// Copyright (c) MagicaSoft, 2020-2022.
// https://magicasoft.jp
using UnityEngine;
namespace MagicaCloth
{
///
/// BaseCloth API
///
public abstract partial class BaseCloth : PhysicsTeam
{
///
/// クロスの物理シミュレーションをリセットします
/// Reset cloth physics simulation.
///
public void ResetCloth()
{
ResetClothInternal(clothParams.TeleportResetMode, -1.0f);
}
///
/// クロスの物理シミュレーションをリセットします
/// Reset cloth physics simulation.
///
/// Time to stabilize simulation (s)
public void ResetCloth(float resetStabilizationTime)
{
ResetClothInternal(clothParams.TeleportResetMode, Mathf.Max(resetStabilizationTime, 0.0f));
}
///
/// クロスの物理シミュレーションをリセットします
/// Reset cloth physics simulation.
///
/// RESET...Resets all simulations. KEEP...Keep the simulation.
/// Time to stabilize simulation(s).If negative, the time set in the inspector.
public void ResetCloth(ClothParams.TeleportMode teleportMode, float resetStabilizationTime = -1.0f)
{
ResetClothInternal(teleportMode, resetStabilizationTime);
}
///
/// タイムスケールを変更します
/// Change the time scale.
///
/// 0.0-1.0
public void SetTimeScale(float timeScale)
{
if (IsValid())
MagicaPhysicsManager.Instance.Team.SetTimeScale(teamId, Mathf.Clamp01(timeScale));
}
///
/// タイムスケールを取得します
/// Get the time scale.
///
///
public float GetTimeScale()
{
if (IsValid())
return MagicaPhysicsManager.Instance.Team.GetTimeScale(teamId);
else
return 1.0f;
}
///
/// 外力を与えます
/// Add external force.
///
///
public void AddForce(Vector3 force, PhysicsManagerTeamData.ForceMode mode)
{
if (IsValid() && IsActive())
MagicaPhysicsManager.Instance.Team.SetImpactForce(teamId, force, mode);
}
///
/// 元の姿勢とシミュレーション結果とのブレンド率
/// Blend ratio between original posture and simulation result.
/// (0.0 = 0%, 1.0 = 100%)
///
public float BlendWeight
{
get
{
return UserBlendWeight;
}
set
{
UserBlendWeight = value;
}
}
///
/// コライダーをチームに追加します
/// Add collider to the team.
///
///
public void AddCollider(ColliderComponent collider)
{
Init(); // チームが初期化されていない可能性があるので.
if (IsValid() && collider)
{
var c = collider.CreateColliderParticle(teamId);
if (c.IsValid())
TeamData.AddCollider(collider);
}
}
///
/// コライダーをチームから削除します
/// Remove collider from the team.
///
///
public void RemoveCollider(ColliderComponent collider)
{
if (IsValid() && collider)
{
collider.RemoveColliderParticle(teamId);
TeamData.RemoveCollider(collider);
}
}
///
/// 更新モードを変更します
/// Change the update mode.
///
///
public void SetUpdateMode(TeamUpdateMode updateMode)
{
UpdateMode = updateMode;
}
///
/// カリングモードを変更します
/// Change the culling mode.
///
///
public void SetCullingMode(TeamCullingMode cullingMode)
{
CullingMode = cullingMode;
}
//=========================================================================================
// [Radius] Parameters access.
//=========================================================================================
///
/// パーティクル半径の設定
/// Setting up a particle radius.
///
/// 0.001 ~
/// 0.001 ~
/// -1.0 ~ +1.0
public void Radius_SetRadius(float startVal, float endVal, float curveVal = 0)
{
var b = clothParams.GetRadius().AutoSetup(Mathf.Max(startVal, 0.001f), Mathf.Max(endVal, 0.001f), curveVal);
// update team particles.
var manager = MagicaPhysicsManager.Instance;
for (int i = 0; i < ParticleChunk.dataLength; i++)
{
int pindex = ParticleChunk.startIndex + i;
float depth = manager.Particle.depthList[pindex];
float radius = b.Evaluate(depth);
manager.Particle.SetRadius(pindex, radius);
}
}
//=========================================================================================
// [Mass] Parameters access.
//=========================================================================================
///
/// 重量の設定
/// Setting up a mass.
///
/// 1.0 ~
/// 1.0 ~
/// -1.0 ~ +1.0
public void Mass_SetMass(float startVal, float endVal, float curveVal = 0)
{
var b = clothParams.GetMass().AutoSetup(Mathf.Max(startVal, 1.0f), Mathf.Max(endVal, 1.0f), curveVal);
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetMass(TeamId, b);
// Parameters related to mass
MagicaPhysicsManager.Instance.Compute.RestoreDistance.ChangeParam(
TeamId,
clothParams.GetMass(),
clothParams.RestoreDistanceVelocityInfluence,
clothParams.GetStructDistanceStiffness(),
clothParams.UseBendDistance,
clothParams.GetBendDistanceStiffness(),
clothParams.UseNearDistance,
clothParams.GetNearDistanceStiffness()
);
}
}
//=========================================================================================
// [Clamp Position] Parameters access.
//=========================================================================================
///
/// 移動範囲距離の設定
/// Movement range distance setting.
///
/// 0.0 ~ 1.0
/// 0.0 ~ 1.0
/// -1.0 ~ +1.0
public void ClampPosition_SetPositionLength(float startVal, float endVal, float curveVal = 0)
{
var b = clothParams.GetClampPositionLength().AutoSetup(Mathf.Max(startVal, 1.0f), Mathf.Max(endVal, 1.0f), curveVal);
if (IsValid())
{
MagicaPhysicsManager.Instance.Compute.ClampPosition.ChangeParam(
TeamId,
clothParams.UseClampPositionLength,
clothParams.GetClampPositionLength(),
clothParams.ClampPositionAxisRatio,
clothParams.ClampPositionVelocityInfluence
);
}
}
//=========================================================================================
// [Gravity] Parameters access.
//=========================================================================================
///
/// 重力加速度の設定
/// Setting up a gravity.
///
///
///
/// -1.0 ~ +1.0
public void Gravity_SetGravity(float startVal, float endVal, float curveVal = 0)
{
var b = clothParams.GetGravity().AutoSetup(startVal, endVal, curveVal);
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetGravity(TeamId, b);
}
}
///
/// 重力方向の設定.天井方向を指定します.
/// Gravity direction setting. Specify the ceiling direction.
///
public Vector3 Gravity_GravityDirection
{
get
{
return clothParams.GravityDirection;
}
set
{
clothParams.GravityDirection = value;
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetGravityDirection(TeamId, value);
}
}
}
//=========================================================================================
// [Drag] Parameters access.
//=========================================================================================
///
/// 空気抵抗の設定
/// Setting up a drag.
///
/// 0.0 ~ 1.0
/// 0.0 ~ 1.0
/// -1.0 ~ +1.0
public void Drag_SetDrag(float startVal, float endVal, float curveVal = 0)
{
var b = clothParams.GetDrag().AutoSetup(startVal, endVal, curveVal);
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetDrag(TeamId, b);
}
}
//=========================================================================================
// [Distance Disable] Parameters access.
//=========================================================================================
///
/// アクティブ設定
/// Active settings.
///
public bool DistanceDisable_Active
{
get
{
return clothParams.UseDistanceDisable;
}
set
{
clothParams.UseDistanceDisable = value;
}
}
///
/// 距離計測の対象設定
/// nullを指定するとメインカメラが参照されます。
/// Target setting for distance measurement.
/// If null is specified, the main camera is referred.
///
public Transform DistanceDisable_ReferenceObject
{
get
{
return clothParams.DisableReferenceObject;
}
set
{
clothParams.DisableReferenceObject = value;
}
}
///
/// シミュレーションを無効化する距離
/// Distance to disable simulation.
///
public float DistanceDisable_Distance
{
get
{
return clothParams.DisableDistance;
}
set
{
clothParams.DisableDistance = Mathf.Max(value, 0.0f);
}
}
///
/// シミュレーションを無効化するフェード距離
/// DistanceDisable_DistanceからDistanceDisable_FadeDistanceの距離を引いた位置からフェードが開始します。
/// Fade distance to disable simulation.
/// Fade from DistanceDisable_Distance minus DistanceDisable_FadeDistance distance.
///
public float DistanceDisable_FadeDistance
{
get
{
return clothParams.DisableFadeDistance;
}
set
{
clothParams.DisableFadeDistance = Mathf.Max(value, 0.0f);
}
}
//=========================================================================================
// [External Force] Parameter access.
//=========================================================================================
///
/// パーティクル重量の影響率(0.0-1.0).v1.12.0で廃止
/// Particle weight effect rate (0.0-1.0).
/// Abolished in v1.12.0.
///
//public float ExternalForce_MassInfluence
//{
// get
// {
// return clothParams.MassInfluence;
// }
// set
// {
// clothParams.MassInfluence = value;
// if (IsValid())
// {
// MagicaPhysicsManager.Instance.Team.SetExternalForce(TeamId, clothParams.MassInfluence, clothParams.WindInfluence, clothParams.WindRandomScale, clothParams.WindSynchronization);
// }
// }
//}
///
/// 深さによる外力の影響率(0.0-1.0)
/// Impact of external force on depth.(0.0 - 1.0)
///
/// 0.0 ~ 1.0
/// 0.0 ~ 1.0
/// -1.0 ~ +1.0
public void ExternalForce_DepthInfluence(float startVal, float endVal, float curveVal = 0)
{
var b = clothParams.GetDepthInfluence().AutoSetup(startVal, endVal, curveVal);
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetDepthInfluence(TeamId, b);
}
}
///
/// 風の影響率(1.0 = 100%)
/// Wind influence rate (1.0 = 100%).
///
public float ExternalForce_WindInfluence
{
get
{
return clothParams.WindInfluence;
}
set
{
clothParams.WindInfluence = value;
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetExternalForce(TeamId, clothParams.MassInfluence, clothParams.WindInfluence, clothParams.WindRandomScale, clothParams.WindSynchronization);
}
}
}
///
/// 風のランダム率(1.0 = 100%)
/// Wind random rate (1.0 = 100%).
///
public float ExternalForce_WindRandomScale
{
get
{
return clothParams.WindRandomScale;
}
set
{
clothParams.WindRandomScale = value;
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetExternalForce(TeamId, clothParams.MassInfluence, clothParams.WindInfluence, clothParams.WindRandomScale, clothParams.WindSynchronization);
}
}
}
//=========================================================================================
// [World Influence] Parameter access.
//=========================================================================================
///
/// 移動影響の設定
/// Setting up a moving influence.
///
/// 0.0 ~ 1.0
/// 0.0 ~ 1.0
/// -1.0 ~ +1.0
public void WorldInfluence_SetMovementInfluence(float startVal, float endVal, float curveVal = 0)
{
var b = clothParams.GetWorldMoveInfluence().AutoSetup(startVal, endVal, curveVal);
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetWorldInfluence(TeamId, clothParams.MaxMoveSpeed, clothParams.MaxRotationSpeed, b, clothParams.GetWorldRotationInfluence());
}
}
///
/// 回転影響の設定
/// Setting up a rotation influence.
///
/// 0.0 ~ 1.0
/// 0.0 ~ 1.0
/// -1.0 ~ +1.0
public void WorldInfluence_SetRotationInfluence(float startVal, float endVal, float curveVal = 0)
{
var b = clothParams.GetWorldRotationInfluence().AutoSetup(startVal, endVal, curveVal);
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetWorldInfluence(TeamId, clothParams.MaxMoveSpeed, clothParams.MaxRotationSpeed, clothParams.GetWorldMoveInfluence(), b);
}
}
///
/// 最大速度の設定
/// Setting up a max move speed.(m/s)
///
public float WorldInfluence_MaxMoveSpeed
{
get
{
return clothParams.MaxMoveSpeed;
}
set
{
clothParams.MaxMoveSpeed = Mathf.Max(value, 0.0f);
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetWorldInfluence(TeamId, clothParams.MaxMoveSpeed, clothParams.MaxRotationSpeed, clothParams.GetWorldMoveInfluence(), clothParams.GetWorldRotationInfluence());
}
}
}
///
/// 自動テレポートの有効設定
/// Enable automatic teleportation.
///
public bool WorldInfluence_ResetAfterTeleport
{
get
{
return clothParams.UseResetTeleport;
}
set
{
clothParams.UseResetTeleport = value;
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetAfterTeleport(TeamId, clothParams.UseResetTeleport, clothParams.TeleportDistance, clothParams.TeleportRotation, clothParams.TeleportResetMode);
}
}
}
///
/// 自動テレポートと検出する1フレームの移動距離
/// Travel distance in one frame to be judged as automatic teleport.
///
public float WorldInfluence_TeleportDistance
{
get
{
return clothParams.TeleportDistance;
}
set
{
clothParams.TeleportDistance = value;
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetAfterTeleport(TeamId, clothParams.UseResetTeleport, clothParams.TeleportDistance, clothParams.TeleportRotation, clothParams.TeleportResetMode);
}
}
}
///
/// 自動テレポートと検出する1フレームの回転角度(0.0 ~ 360.0)
/// Rotation angle of one frame to be judged as automatic teleport.(0.0 ~ 360.0)
///
public float WorldInfluence_TeleportRotation
{
get
{
return clothParams.TeleportRotation;
}
set
{
clothParams.TeleportRotation = value;
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetAfterTeleport(TeamId, clothParams.UseResetTeleport, clothParams.TeleportDistance, clothParams.TeleportRotation, clothParams.TeleportResetMode);
}
}
}
///
/// テレポートのモードを設定
/// Setting up a teleport mode.
///
public ClothParams.TeleportMode WorldInfluence_TeleportMode
{
get
{
return clothParams.TeleportResetMode;
}
set
{
clothParams.TeleportResetMode = value;
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetAfterTeleport(TeamId, clothParams.UseResetTeleport, clothParams.TeleportDistance, clothParams.TeleportRotation, clothParams.TeleportResetMode);
}
}
}
///
/// リセット後の安定時間を設定(s)
/// Set stabilization time after reset.
///
public float WorldInfluence_StabilizationTime
{
get
{
return clothParams.ResetStabilizationTime;
}
set
{
clothParams.ResetStabilizationTime = Mathf.Max(value, 0.0f);
if (IsValid())
{
MagicaPhysicsManager.Instance.Team.SetStabilizationTime(TeamId, clothParams.ResetStabilizationTime);
}
}
}
///
/// InfluenceTargetを置換する
/// Replace InfluenceTarget.
///
///
public void WorldInfluence_ReplaceInfluenceTarget(Transform target)
{
bool active = status.IsActive;
if (active)
{
Setup.ClothInactive(this);
}
// InfluenceTarget
Params.SetInfluenceTarget(target);
MagicaPhysicsManager.Instance.Team.ResetWorldInfluenceTarget(TeamId, target ? target : transform);
if (active)
{
Setup.ClothActive(this, Params, ClothData);
}
}
//=========================================================================================
// [Collider Collision] Parameter access.
//=========================================================================================
///
/// アクティブ設定
/// Active settings.
///
public bool ColliderCollision_Active
{
get
{
return clothParams.UseCollision;
}
set
{
clothParams.SetCollision(value, clothParams.DynamicFriction, clothParams.StaticFriction);
if (IsValid())
{
MagicaPhysicsManager.Instance.Compute.Collision.ChangeParam(TeamId, clothParams.UseCollision);
}
}
}
//=========================================================================================
// [Penetration] Parameter access.
//=========================================================================================
///
/// アクティブ設定
/// Active settings.
///
public bool Penetration_Active
{
get
{
return clothParams.UsePenetration;
}
set
{
clothParams.UsePenetration = value;
if (IsValid())
{
MagicaPhysicsManager.Instance.Compute.Penetration.ChangeParam(
TeamId,
clothParams.UsePenetration,
clothParams.GetPenetrationDistance(),
clothParams.GetPenetrationRadius(),
clothParams.PenetrationMaxDepth
);
}
}
}
///
/// 移動範囲球の設定
/// Setting up a moving radius.
///
/// 0.0 ~
/// 0.0 ~
/// -1.0 ~ +1.0
public void Penetration_SetMovingRadius(float startVal, float endVal, float curveVal = 0)
{
clothParams.GetPenetrationRadius().AutoSetup(Mathf.Max(startVal, 0.0f), Mathf.Max(endVal, 0.0f), curveVal);
if (IsValid())
{
MagicaPhysicsManager.Instance.Compute.Penetration.ChangeParam(
TeamId,
clothParams.UsePenetration,
clothParams.GetPenetrationDistance(),
clothParams.GetPenetrationRadius(),
clothParams.PenetrationMaxDepth
);
}
}
}
}