SpringConstraint.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using Unity.Burst;
  5. using Unity.Collections;
  6. using Unity.Jobs;
  7. using Unity.Mathematics;
  8. namespace MagicaCloth
  9. {
  10. /// <summary>
  11. /// スプリング拘束
  12. /// BasePosに戻る動作を行う
  13. /// </summary>
  14. public class SpringConstraint : PhysicsManagerConstraint
  15. {
  16. /// <summary>
  17. /// グループごとの拘束データ
  18. /// </summary>
  19. public struct GroupData
  20. {
  21. public int teamId;
  22. public int active;
  23. /// <summary>
  24. /// スプリング力
  25. /// </summary>
  26. public float spring;
  27. }
  28. public FixedNativeList<GroupData> groupList;
  29. //=========================================================================================
  30. public override void Create()
  31. {
  32. groupList = new FixedNativeList<GroupData>();
  33. }
  34. public override void Release()
  35. {
  36. groupList.Dispose();
  37. }
  38. //=========================================================================================
  39. public int AddGroup(int teamId, bool active, float spring)
  40. {
  41. var teamData = MagicaPhysicsManager.Instance.Team.teamDataList[teamId];
  42. var gdata = new GroupData();
  43. gdata.teamId = teamId;
  44. gdata.active = active ? 1 : 0;
  45. gdata.spring = spring;
  46. int group = groupList.Add(gdata);
  47. return group;
  48. }
  49. public override void RemoveTeam(int teamId)
  50. {
  51. var teamData = MagicaPhysicsManager.Instance.Team.teamDataList[teamId];
  52. int group = teamData.springGroupIndex;
  53. if (group < 0)
  54. return;
  55. // データ削除
  56. groupList.Remove(group);
  57. }
  58. public void ChangeParam(int teamId, bool active, float spring)
  59. {
  60. var teamData = MagicaPhysicsManager.Instance.Team.teamDataList[teamId];
  61. int group = teamData.springGroupIndex;
  62. if (group < 0)
  63. return;
  64. var gdata = groupList[group];
  65. gdata.active = active ? 1 : 0;
  66. gdata.spring = spring;
  67. groupList[group] = gdata;
  68. }
  69. //public int ActiveCount
  70. //{
  71. // get
  72. // {
  73. // int cnt = 0;
  74. // for (int i = 0; i < groupList.Length; i++)
  75. // if (groupList[i].active == 1)
  76. // cnt++;
  77. // return cnt;
  78. // }
  79. //}
  80. //=========================================================================================
  81. /// <summary>
  82. /// 拘束の解決
  83. /// </summary>
  84. /// <param name="dtime"></param>
  85. /// <param name="jobHandle"></param>
  86. /// <returns></returns>
  87. public override JobHandle SolverConstraint(int runCount, float dtime, float updatePower, int iteration, JobHandle jobHandle)
  88. {
  89. //if (ActiveCount == 0)
  90. if (groupList.Count == 0)
  91. return jobHandle;
  92. // スプリング拘束(パーティクルごとに実行する)
  93. var job1 = new SpringJob()
  94. {
  95. updatePower = updatePower,
  96. runCount = runCount,
  97. groupList = groupList.ToJobArray(),
  98. teamDataList = Manager.Team.teamDataList.ToJobArray(),
  99. teamIdList = Manager.Particle.teamIdList.ToJobArray(),
  100. flagList = Manager.Particle.flagList.ToJobArray(),
  101. basePosList = Manager.Particle.basePosList.ToJobArray(),
  102. nextPosList = Manager.Particle.InNextPosList.ToJobArray()
  103. };
  104. jobHandle = job1.Schedule(Manager.Particle.Length, 64, jobHandle);
  105. return jobHandle;
  106. }
  107. /// <summary>
  108. /// スプリング拘束ジョブ
  109. /// パーティクルごとに計算
  110. /// </summary>
  111. [BurstCompile]
  112. struct SpringJob : IJobParallelFor
  113. {
  114. public float updatePower;
  115. public int runCount;
  116. [Unity.Collections.ReadOnly]
  117. public NativeArray<GroupData> groupList;
  118. // チーム
  119. [Unity.Collections.ReadOnly]
  120. public NativeArray<PhysicsManagerTeamData.TeamData> teamDataList;
  121. [Unity.Collections.ReadOnly]
  122. public NativeArray<int> teamIdList;
  123. [Unity.Collections.ReadOnly]
  124. public NativeArray<PhysicsManagerParticleData.ParticleFlag> flagList;
  125. [Unity.Collections.ReadOnly]
  126. public NativeArray<float3> basePosList;
  127. public NativeArray<float3> nextPosList;
  128. // パーティクルごと
  129. public void Execute(int index)
  130. {
  131. var flag = flagList[index];
  132. if (flag.IsValid() == false || flag.IsFixed())
  133. return;
  134. var team = teamDataList[teamIdList[index]];
  135. if (team.IsActive() == false)
  136. return;
  137. if (team.springGroupIndex < 0)
  138. return;
  139. // 更新確認
  140. if (team.IsUpdate(runCount) == false)
  141. return;
  142. // グループデータ
  143. var gdata = groupList[team.springGroupIndex];
  144. if (gdata.active == 0)
  145. return;
  146. var nextpos = nextPosList[index];
  147. // baseposに戻る移動を行う
  148. var basepos = basePosList[index];
  149. float power = 1.0f - math.pow(1.0f - gdata.spring, updatePower);
  150. nextpos = math.lerp(nextpos, basepos, power);
  151. // 書き出し
  152. nextPosList[index] = nextpos;
  153. }
  154. }
  155. }
  156. }