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