PhysicsManagerCompute.cs 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using System.Collections.Generic;
  5. using Unity.Burst;
  6. using Unity.Collections;
  7. using Unity.Jobs;
  8. using Unity.Mathematics;
  9. using UnityEngine.Jobs;
  10. using UnityEngine.Profiling;
  11. namespace MagicaCloth
  12. {
  13. /// <summary>
  14. /// 計算処理
  15. /// </summary>
  16. public class PhysicsManagerCompute : PhysicsManagerAccess
  17. {
  18. /// <summary>
  19. /// 拘束判定繰り返し回数
  20. /// </summary>
  21. //[Header("拘束全体の反復回数")]
  22. //[Range(1, 8)]
  23. //public int solverIteration = 2;
  24. private int solverIteration = 1;
  25. /// <summary>
  26. /// 拘束条件
  27. /// </summary>
  28. List<PhysicsManagerConstraint> constraints = new List<PhysicsManagerConstraint>();
  29. public ClampPositionConstraint ClampPosition { get; private set; }
  30. public ClampDistanceConstraint ClampDistance { get; private set; }
  31. //public ClampDistance2Constraint ClampDistance2 { get; private set; }
  32. public ClampRotationConstraint ClampRotation { get; private set; }
  33. public SpringConstraint Spring { get; private set; }
  34. public RestoreDistanceConstraint RestoreDistance { get; private set; }
  35. public RestoreRotationConstraint RestoreRotation { get; private set; }
  36. public TriangleBendConstraint TriangleBend { get; private set; }
  37. public ColliderCollisionConstraint Collision { get; private set; }
  38. public PenetrationConstraint Penetration { get; private set; }
  39. public ColliderExtrusionConstraint ColliderExtrusion { get; private set; }
  40. public TwistConstraint Twist { get; private set; }
  41. public CompositeRotationConstraint CompositeRotation { get; private set; }
  42. //public ColliderAfterCollisionConstraint AfterCollision { get; private set; }
  43. //public EdgeCollisionConstraint EdgeCollision { get; private set; }
  44. //public VolumeConstraint Volume { get; private set; }
  45. /// <summary>
  46. /// ワーカーリスト
  47. /// </summary>
  48. List<PhysicsManagerWorker> workers = new List<PhysicsManagerWorker>();
  49. public RenderMeshWorker RenderMeshWorker { get; private set; }
  50. public VirtualMeshWorker VirtualMeshWorker { get; private set; }
  51. public MeshParticleWorker MeshParticleWorker { get; private set; }
  52. public SpringMeshWorker SpringMeshWorker { get; private set; }
  53. public AdjustRotationWorker AdjustRotationWorker { get; private set; }
  54. public LineWorker LineWorker { get; private set; }
  55. public TriangleWorker TriangleWorker { get; private set; }
  56. public BaseSkinningWorker BaseSkinningWorker { get; private set; }
  57. /// <summary>
  58. /// マスタージョブハンドル
  59. /// すべてのジョブはこのハンドルに連結される
  60. /// </summary>
  61. JobHandle jobHandle;
  62. private bool runMasterJob = false;
  63. private int swapIndex = 0;
  64. /// <summary>
  65. /// プロファイラ用
  66. /// </summary>
  67. public CustomSampler SamplerCalcMesh { get; set; }
  68. public CustomSampler SamplerWriteMesh { get; set; }
  69. //=========================================================================================
  70. /// <summary>
  71. /// 初期設定
  72. /// </summary>
  73. public override void Create()
  74. {
  75. // 拘束の作成
  76. // ※この並び順が実行順番となります。
  77. // コリジョン
  78. ColliderExtrusion = new ColliderExtrusionConstraint();
  79. constraints.Add(ColliderExtrusion);
  80. Penetration = new PenetrationConstraint();
  81. constraints.Add(Penetration);
  82. Collision = new ColliderCollisionConstraint();
  83. constraints.Add(Collision);
  84. // 移動制限
  85. ClampDistance = new ClampDistanceConstraint();
  86. constraints.Add(ClampDistance);
  87. // 主なクロスシミュレーション
  88. Spring = new SpringConstraint();
  89. constraints.Add(Spring);
  90. Twist = new TwistConstraint();
  91. constraints.Add(Twist);
  92. RestoreDistance = new RestoreDistanceConstraint();
  93. constraints.Add(RestoreDistance);
  94. RestoreRotation = new RestoreRotationConstraint();
  95. constraints.Add(RestoreRotation);
  96. CompositeRotation = new CompositeRotationConstraint();
  97. constraints.Add(CompositeRotation);
  98. // 形状維持
  99. TriangleBend = new TriangleBendConstraint();
  100. constraints.Add(TriangleBend);
  101. //Volume = new VolumeConstraint();
  102. //constraints.Add(Volume);
  103. // 移動制限2
  104. ClampPosition = new ClampPositionConstraint();
  105. constraints.Add(ClampPosition);
  106. ClampRotation = new ClampRotationConstraint();
  107. constraints.Add(ClampRotation);
  108. foreach (var con in constraints)
  109. con.Init(manager);
  110. // ワーカーの作成
  111. // ※この並び順は変更してはいけません。
  112. RenderMeshWorker = new RenderMeshWorker();
  113. workers.Add(RenderMeshWorker);
  114. VirtualMeshWorker = new VirtualMeshWorker();
  115. workers.Add(VirtualMeshWorker);
  116. MeshParticleWorker = new MeshParticleWorker();
  117. workers.Add(MeshParticleWorker);
  118. SpringMeshWorker = new SpringMeshWorker();
  119. workers.Add(SpringMeshWorker);
  120. AdjustRotationWorker = new AdjustRotationWorker();
  121. workers.Add(AdjustRotationWorker);
  122. LineWorker = new LineWorker();
  123. workers.Add(LineWorker);
  124. TriangleWorker = new TriangleWorker();
  125. workers.Add(TriangleWorker);
  126. BaseSkinningWorker = new BaseSkinningWorker();
  127. workers.Add(BaseSkinningWorker);
  128. foreach (var worker in workers)
  129. worker.Init(manager);
  130. // プロファイラ用
  131. SamplerCalcMesh = CustomSampler.Create("CalcMesh");
  132. SamplerWriteMesh = CustomSampler.Create("WriteMesh");
  133. }
  134. /// <summary>
  135. /// 破棄
  136. /// </summary>
  137. public override void Dispose()
  138. {
  139. if (constraints != null)
  140. {
  141. foreach (var con in constraints)
  142. con.Release();
  143. }
  144. if (workers != null)
  145. {
  146. foreach (var worker in workers)
  147. worker.Release();
  148. }
  149. }
  150. /// <summary>
  151. /// 各コンストレイント/ワーカーから指定グループのデータを削除する
  152. /// </summary>
  153. /// <param name="teamId"></param>
  154. public void RemoveTeam(int teamId)
  155. {
  156. if (MagicaPhysicsManager.Instance.Team.IsValidData(teamId) == false)
  157. return;
  158. if (constraints != null)
  159. {
  160. foreach (var con in constraints)
  161. con.RemoveTeam(teamId);
  162. }
  163. if (workers != null)
  164. {
  165. foreach (var worker in workers)
  166. worker.RemoveGroup(teamId);
  167. }
  168. }
  169. //=========================================================================================
  170. /// <summary>
  171. /// ボーン姿勢を元の位置に復元する
  172. /// </summary>
  173. internal void UpdateRestoreBone(PhysicsTeam.TeamUpdateMode updateMode)
  174. {
  175. // 活動チームが1つ以上ある場合のみ更新
  176. if (Team.ActiveTeamCount > 0)
  177. {
  178. // トランスフォーム姿勢のリセット
  179. Bone.ResetBoneFromTransform(updateMode == PhysicsTeam.TeamUpdateMode.UnityPhysics);
  180. }
  181. }
  182. /// <summary>
  183. /// ボーン姿勢を読み込む
  184. /// </summary>
  185. internal void UpdateReadBone()
  186. {
  187. // 活動チームが1つ以上ある場合のみ更新
  188. if (Team.ActiveTeamCount > 0)
  189. {
  190. // トランスフォーム姿勢の読み込み
  191. Bone.ReadBoneFromTransform();
  192. }
  193. }
  194. /// <summary>
  195. /// メインスレッドで行うチームデータ更新処理
  196. /// </summary>
  197. internal void UpdateTeamAlways()
  198. {
  199. // 常に実行するチームデータ更新
  200. Team.PreUpdateTeamAlways();
  201. }
  202. /// <summary>
  203. /// クロスシミュレーション計算開始
  204. /// </summary>
  205. /// <param name="update"></param>
  206. internal void UpdateStartSimulation(UpdateTimeManager update)
  207. {
  208. // マネージャ非アクティブ時にはシミュレーション計算を完全に停止させる
  209. if (MagicaPhysicsManager.Instance.IsActive == false)
  210. return;
  211. // 時間
  212. float deltaTime = update.DeltaTime;
  213. float physicsDeltaTime = update.PhysicsDeltaTime;
  214. float updatePower = update.UpdatePower;
  215. float updateDeltaTime = update.UpdateIntervalTime;
  216. int ups = update.UpdatePerSecond;
  217. // 活動チームが1つ以上ある場合のみ更新
  218. if (Team.ActiveTeamCount > 0)
  219. {
  220. // 今回フレームの更新回数
  221. int updateCount = Team.CalcMaxUpdateCount(ups, deltaTime, physicsDeltaTime, updateDeltaTime);
  222. //Debug.Log($"updateCount:{updateCount} dtime:{deltaTime} pdtime:{physicsDeltaTime} fixedCount:{update.FixedUpdateCount}");
  223. // 風更新
  224. //Wind.UpdateWind();
  225. // チームデータ更新、更新回数確定、ワールド移動影響、テレポート
  226. Team.PreUpdateTeamData(deltaTime, physicsDeltaTime, updateDeltaTime, ups, updateCount);
  227. // ワーカー処理
  228. WarmupWorker();
  229. // ボーン姿勢をパーティクルにコピーする
  230. Particle.UpdateBoneToParticle();
  231. // 物理更新前ワーカー処理
  232. //MasterJob = RenderMeshWorker.PreUpdate(MasterJob); // 何もなし
  233. MasterJob = VirtualMeshWorker.PreUpdate(MasterJob); // 仮想メッシュをスキニングしワールド姿勢を求める
  234. MasterJob = MeshParticleWorker.PreUpdate(MasterJob); // 仮想メッシュ頂点姿勢を連動パーティクルにコピーする
  235. //MasterJob = SpringMeshWorker.PreUpdate(MasterJob); // 何もなし
  236. //MasterJob = AdjustRotationWorker.PreUpdate(MasterJob); // 何もなし
  237. //MasterJob = LineWorker.PreUpdate(MasterJob); // 何もなし
  238. MasterJob = BaseSkinningWorker.PreUpdate(MasterJob); // ベーススキニングによりbasePos/baseRotをスキニング
  239. // パーティクルのリセット判定
  240. Particle.UpdateResetParticle();
  241. // 物理更新
  242. for (int i = 0, cnt = updateCount; i < cnt; i++)
  243. {
  244. UpdatePhysics(updateCount, i, updatePower, updateDeltaTime);
  245. }
  246. // 物理演算後処理
  247. PostUpdatePhysics(updateDeltaTime);
  248. // 物理更新後ワーカー処理
  249. MasterJob = TriangleWorker.PostUpdate(MasterJob); // トライアングル回転調整
  250. MasterJob = LineWorker.PostUpdate(MasterJob); // ラインの回転調整
  251. MasterJob = AdjustRotationWorker.PostUpdate(MasterJob); // パーティクル回転調整(Adjust Rotation)
  252. Particle.UpdateParticleToBone(); // パーティクル姿勢をボーン姿勢に書き戻す(ここに挟まないと駄目)
  253. MasterJob = SpringMeshWorker.PostUpdate(MasterJob); // メッシュスプリング
  254. MasterJob = MeshParticleWorker.PostUpdate(MasterJob); // パーティクル姿勢を仮想メッシュに書き出す
  255. MasterJob = VirtualMeshWorker.PostUpdate(MasterJob); // 仮想メッシュ座標書き込み(仮想メッシュトライアングル法線計算)
  256. MasterJob = RenderMeshWorker.PostUpdate(MasterJob); // レンダーメッシュ座標書き込み(仮想メッシュからレンダーメッシュ座標計算)
  257. // 書き込みボーン姿勢をローカル姿勢に変換する
  258. Bone.ConvertWorldToLocal();
  259. // チームデータ後処理
  260. Team.PostUpdateTeamData();
  261. }
  262. }
  263. /// <summary>
  264. /// クロスシミュレーション完了待ち
  265. /// </summary>
  266. internal void UpdateCompleteSimulation()
  267. {
  268. // マスタージョブ完了待機
  269. CompleteJob();
  270. runMasterJob = true;
  271. #if UNITY_2021_2_OR_NEWER
  272. // 高速書き込みバッファの作業終了
  273. Mesh.FinishVertexBuffer();
  274. #endif
  275. //Debug.Log($"runMasterJob = true! F:{Time.frameCount}");
  276. }
  277. /// <summary>
  278. /// ボーン姿勢をトランスフォームに書き込む
  279. /// </summary>
  280. internal void UpdateWriteBone()
  281. {
  282. // ボーン姿勢をトランスフォームに書き出す
  283. Bone.WriteBoneToTransform(manager.IsDelay ? 1 : 0);
  284. }
  285. /// <summary>
  286. /// メッシュ書き込みの事前判定
  287. /// </summary>
  288. internal void MeshCalculation()
  289. {
  290. // プロファイラ計測開始
  291. SamplerCalcMesh.Begin();
  292. Mesh.ClearWritingList();
  293. if (Mesh.VirtualMeshCount > 0 && runMasterJob)
  294. {
  295. Mesh.MeshCalculation(manager.IsDelay ? 1 : 0);
  296. }
  297. // プロファイラ計測終了
  298. SamplerCalcMesh.End();
  299. }
  300. /// <summary>
  301. /// メッシュ姿勢をメッシュに書き込む
  302. /// </summary>
  303. internal void NormalWritingMesh()
  304. {
  305. // プロファイラ計測開始
  306. SamplerWriteMesh.Begin();
  307. // メッシュへの頂点書き戻し
  308. if (Mesh.VirtualMeshCount > 0 && runMasterJob)
  309. {
  310. Mesh.NormalWriting(manager.IsDelay ? 1 : 0);
  311. #if UNITY_2021_2_OR_NEWER
  312. Mesh.FasterWriting(manager.IsDelay ? 1 : 0);
  313. #endif
  314. }
  315. // プロファイラ計測終了
  316. SamplerWriteMesh.End();
  317. }
  318. /// <summary>
  319. /// 遅延実行時のボーン読み込みと前回のボーン結果の書き込み
  320. /// </summary>
  321. internal void UpdateReadWriteBone()
  322. {
  323. // 活動チームが1つ以上ある場合のみ更新
  324. if (Team.ActiveTeamCount > 0)
  325. {
  326. // トランスフォーム姿勢の読み込み
  327. Bone.ReadBoneFromTransform();
  328. if (runMasterJob)
  329. {
  330. // ボーン姿勢をトランスフォームに書き出す
  331. Bone.WriteBoneToTransform(manager.IsDelay ? 1 : 0);
  332. }
  333. }
  334. }
  335. /// <summary>
  336. /// 遅延実行時のみボーンの計算結果を書き込みバッファにコピーする
  337. /// </summary>
  338. internal void UpdateSyncBuffer()
  339. {
  340. Bone.writeBoneIndexList.SyncBuffer();
  341. Bone.writeBonePosList.SyncBuffer();
  342. Bone.writeBoneRotList.SyncBuffer();
  343. Bone.boneFlagList.SyncBuffer();
  344. InitJob();
  345. Bone.CopyBoneBuffer();
  346. CompleteJob();
  347. }
  348. /// <summary>
  349. /// 遅延実行時のみメッシュの計算結果をスワップする
  350. /// </summary>
  351. internal void UpdateSwapBuffer()
  352. {
  353. Mesh.renderPosList.SwapBuffer();
  354. Mesh.renderNormalList.SwapBuffer();
  355. Mesh.renderTangentList.SwapBuffer();
  356. Mesh.renderBoneWeightList.SwapBuffer();
  357. #if UNITY_2021_2_OR_NEWER
  358. // 高速書き込み用コンピュートバッファをスワップ
  359. Mesh.renderPosBuffer.Swap();
  360. Mesh.renderNormalBuffer.Swap();
  361. #endif
  362. swapIndex ^= 1;
  363. // 遅延実行計算済みフラグを立てる
  364. Mesh.SetDelayedCalculatedFlag();
  365. }
  366. //=========================================================================================
  367. public JobHandle MasterJob
  368. {
  369. get
  370. {
  371. return jobHandle;
  372. }
  373. set
  374. {
  375. jobHandle = value;
  376. }
  377. }
  378. /// <summary>
  379. /// マスタージョブハンドル初期化
  380. /// </summary>
  381. public void InitJob()
  382. {
  383. jobHandle = default(JobHandle);
  384. }
  385. public void ScheduleJob()
  386. {
  387. JobHandle.ScheduleBatchedJobs();
  388. }
  389. /// <summary>
  390. /// マスタージョブハンドル完了待機
  391. /// </summary>
  392. public void CompleteJob()
  393. {
  394. jobHandle.Complete();
  395. jobHandle = default(JobHandle);
  396. }
  397. /// <summary>
  398. /// 遅延実行時のダブルバッファのフロントインデックス
  399. /// </summary>
  400. public int SwapIndex
  401. {
  402. get
  403. {
  404. return swapIndex;
  405. }
  406. }
  407. //=========================================================================================
  408. /// <summary>
  409. /// 物理エンジン更新ループ処理
  410. /// これは1フレームにステップ回数分呼び出される
  411. /// 場合によっては1回も呼ばれないフレームも発生するので注意!
  412. /// </summary>
  413. /// <param name="updateCount"></param>
  414. /// <param name="runCount"></param>
  415. /// <param name="dtime"></param>
  416. void UpdatePhysics(int updateCount, int runCount, float updatePower, float updateDeltaTime)
  417. {
  418. if (Particle.Count == 0)
  419. return;
  420. // フォース影響+速度更新
  421. var job1 = new ForceAndVelocityJob()
  422. {
  423. updateDeltaTime = updateDeltaTime,
  424. updatePower = updatePower,
  425. runCount = runCount,
  426. teamDataList = Team.teamDataList.ToJobArray(),
  427. teamMassList = Team.teamMassList.ToJobArray(),
  428. teamGravityList = Team.teamGravityList.ToJobArray(),
  429. teamDragList = Team.teamDragList.ToJobArray(),
  430. teamDepthInfluenceList = Team.teamDepthInfluenceList.ToJobArray(),
  431. teamWindInfoList = Team.teamWindInfoList.ToJobArray(),
  432. //teamMaxVelocityList = Team.teamMaxVelocityList.ToJobArray(),
  433. //teamDirectionalDampingList = Team.teamDirectionalDampingList.ToJobArray(),
  434. flagList = Particle.flagList.ToJobArray(),
  435. teamIdList = Particle.teamIdList.ToJobArray(),
  436. depthList = Particle.depthList.ToJobArray(),
  437. snapBasePosList = Particle.snapBasePosList.ToJobArray(),
  438. snapBaseRotList = Particle.snapBaseRotList.ToJobArray(),
  439. basePosList = Particle.basePosList.ToJobArray(),
  440. baseRotList = Particle.baseRotList.ToJobArray(),
  441. oldBasePosList = Particle.oldBasePosList.ToJobArray(),
  442. oldBaseRotList = Particle.oldBaseRotList.ToJobArray(),
  443. nextPosList = Particle.InNextPosList.ToJobArray(),
  444. nextRotList = Particle.InNextRotList.ToJobArray(),
  445. oldPosList = Particle.oldPosList.ToJobArray(),
  446. oldRotList = Particle.oldRotList.ToJobArray(),
  447. frictionList = Particle.frictionList.ToJobArray(),
  448. //oldSlowPosList = Particle.oldSlowPosList.ToJobArray(),
  449. posList = Particle.posList.ToJobArray(),
  450. rotList = Particle.rotList.ToJobArray(),
  451. velocityList = Particle.velocityList.ToJobArray(),
  452. //boneRotList = Bone.boneRotList.ToJobArray(),
  453. // wind
  454. windDataList = Wind.windDataList.ToJobArray(),
  455. // bone
  456. bonePosList = Bone.bonePosList.ToJobArray(),
  457. boneRotList = Bone.boneRotList.ToJobArray(),
  458. };
  459. jobHandle = job1.Schedule(Particle.Length, 64, jobHandle);
  460. // 拘束条件解決
  461. if (constraints != null)
  462. {
  463. // 拘束解決反復数分ループ
  464. for (int i = 0; i < solverIteration; i++)
  465. {
  466. foreach (var con in constraints)
  467. {
  468. if (con != null /*&& con.enabled*/)
  469. {
  470. // 拘束ごとの反復回数
  471. for (int j = 0; j < con.GetIterationCount(); j++)
  472. {
  473. jobHandle = con.SolverConstraint(runCount, updateDeltaTime, updatePower, j, jobHandle);
  474. }
  475. }
  476. }
  477. }
  478. }
  479. // 座標確定
  480. var job2 = new FixPositionJob()
  481. {
  482. updatePower = updatePower,
  483. updateDeltaTime = updateDeltaTime,
  484. runCount = runCount,
  485. teamDataList = Team.teamDataList.ToJobArray(),
  486. teamMaxVelocityList = Team.teamMaxVelocityList.ToJobArray(),
  487. flagList = Particle.flagList.ToJobArray(),
  488. teamIdList = Particle.teamIdList.ToJobArray(),
  489. depthList = Particle.depthList.ToJobArray(),
  490. nextPosList = Particle.InNextPosList.ToJobArray(),
  491. nextRotList = Particle.InNextRotList.ToJobArray(),
  492. //basePosList = Particle.basePosList.ToJobArray(),
  493. //baseRotList = Particle.baseRotList.ToJobArray(),
  494. oldPosList = Particle.oldPosList.ToJobArray(),
  495. oldRotList = Particle.oldRotList.ToJobArray(),
  496. frictionList = Particle.frictionList.ToJobArray(),
  497. velocityList = Particle.velocityList.ToJobArray(),
  498. rotList = Particle.rotList.ToJobArray(),
  499. posList = Particle.posList.ToJobArray(),
  500. localPosList = Particle.localPosList.ToJobArray(),
  501. collisionNormalList = Particle.collisionNormalList.ToJobArray(),
  502. staticFrictionList = Particle.staticFrictionList.ToJobArray(),
  503. };
  504. jobHandle = job2.Schedule(Particle.Length, 64, jobHandle);
  505. }
  506. [BurstCompile]
  507. struct ForceAndVelocityJob : IJobParallelFor
  508. {
  509. public float updateDeltaTime;
  510. public float updatePower;
  511. public int runCount;
  512. // team
  513. [Unity.Collections.ReadOnly]
  514. public NativeArray<PhysicsManagerTeamData.TeamData> teamDataList;
  515. [Unity.Collections.ReadOnly]
  516. public NativeArray<CurveParam> teamMassList;
  517. [Unity.Collections.ReadOnly]
  518. public NativeArray<CurveParam> teamGravityList;
  519. [Unity.Collections.ReadOnly]
  520. public NativeArray<CurveParam> teamDragList;
  521. [Unity.Collections.ReadOnly]
  522. public NativeArray<CurveParam> teamDepthInfluenceList;
  523. [Unity.Collections.ReadOnly]
  524. public NativeArray<PhysicsManagerTeamData.WindInfo> teamWindInfoList;
  525. //[Unity.Collections.ReadOnly]
  526. //public NativeArray<CurveParam> teamMaxVelocityList;
  527. //[Unity.Collections.ReadOnly]
  528. //public NativeArray<CurveParam> teamDirectionalDampingList;
  529. // particle
  530. public NativeArray<PhysicsManagerParticleData.ParticleFlag> flagList;
  531. [Unity.Collections.ReadOnly]
  532. public NativeArray<int> teamIdList;
  533. [Unity.Collections.ReadOnly]
  534. public NativeArray<float> depthList;
  535. [Unity.Collections.ReadOnly]
  536. public NativeArray<float3> snapBasePosList;
  537. [Unity.Collections.ReadOnly]
  538. public NativeArray<quaternion> snapBaseRotList;
  539. [Unity.Collections.WriteOnly]
  540. public NativeArray<float3> basePosList;
  541. [Unity.Collections.WriteOnly]
  542. public NativeArray<quaternion> baseRotList;
  543. [Unity.Collections.ReadOnly]
  544. public NativeArray<float3> oldBasePosList;
  545. [Unity.Collections.ReadOnly]
  546. public NativeArray<quaternion> oldBaseRotList;
  547. public NativeArray<float3> nextPosList;
  548. public NativeArray<quaternion> nextRotList;
  549. public NativeArray<float> frictionList;
  550. [Unity.Collections.WriteOnly]
  551. public NativeArray<float3> posList;
  552. [Unity.Collections.WriteOnly]
  553. public NativeArray<quaternion> rotList;
  554. [Unity.Collections.ReadOnly]
  555. public NativeArray<float3> oldPosList;
  556. [Unity.Collections.ReadOnly]
  557. public NativeArray<quaternion> oldRotList;
  558. [Unity.Collections.ReadOnly]
  559. public NativeArray<float3> velocityList;
  560. // wind
  561. [Unity.Collections.ReadOnly]
  562. public NativeArray<PhysicsManagerWindData.WindData> windDataList;
  563. // bone
  564. [Unity.Collections.ReadOnly]
  565. public NativeArray<float3> bonePosList;
  566. [Unity.Collections.ReadOnly]
  567. public NativeArray<quaternion> boneRotList;
  568. // パーティクルごと
  569. public void Execute(int index)
  570. {
  571. var flag = flagList[index];
  572. if (flag.IsValid() == false)
  573. return;
  574. // チームデータ
  575. int teamId = teamIdList[index];
  576. var teamData = teamDataList[teamId];
  577. // ここからは更新がある場合のみ実行(グローバルチームは除く)
  578. if (teamId != 0 && teamData.IsUpdate(runCount) == false)
  579. return;
  580. var oldpos = oldPosList[index];
  581. var oldrot = oldRotList[index];
  582. float3 nextPos = oldpos;
  583. quaternion nextRot = oldrot;
  584. var friction = frictionList[index];
  585. // 基準姿勢のステップ補間(v1.11.1)
  586. var oldBasePos = oldBasePosList[index];
  587. var oldBaseRot = oldBaseRotList[index];
  588. var snapBasePos = snapBasePosList[index];
  589. var snapBaseRot = snapBaseRotList[index];
  590. float stime = teamData.startTime + updateDeltaTime * runCount;
  591. float oldtime = teamData.startTime - updateDeltaTime;
  592. float interval = teamData.time - oldtime;
  593. float step = interval >= 1e-06f ? math.saturate((stime - oldtime) / interval) : 0.0f;
  594. float3 basePos = math.lerp(oldBasePos, snapBasePos, step);
  595. quaternion baseRot = math.slerp(oldBaseRot, snapBaseRot, step);
  596. baseRot = math.normalize(baseRot); // 必要
  597. basePosList[index] = basePos;
  598. baseRotList[index] = baseRot;
  599. if (flag.IsFixed())
  600. {
  601. // キネマティックパーティクル
  602. nextPos = basePos;
  603. nextRot = baseRot;
  604. // nextPos/nextRotが1ステップ前の姿勢
  605. var oldNextPos = nextPosList[index];
  606. var oldNextRot = nextRotList[index];
  607. // 前回の姿勢をoldpos/rotとしてposList/rotListに格納する
  608. if (flag.IsCollider() && teamId == 0)
  609. {
  610. // グローバルコライダー
  611. // 移動量と回転量に制限をかける(1.7.5)
  612. // 制限をかけないと高速移動/回転時に遠く離れたパーティクルが押し出されてしまう問題が発生する。
  613. oldpos = MathUtility.ClampDistance(nextPos, oldNextPos, Define.Compute.GlobalColliderMaxMoveDistance);
  614. oldrot = MathUtility.ClampAngle(nextRot, oldNextRot, math.radians(Define.Compute.GlobalColliderMaxRotationAngle));
  615. }
  616. else
  617. {
  618. oldpos = oldNextPos;
  619. oldrot = oldNextRot;
  620. }
  621. #if false
  622. // nextPos/nextRotが1ステップ前の姿勢
  623. var oldNextPos = nextPosList[index];
  624. var oldNextRot = nextRotList[index];
  625. // oldpos/rotが前フレームの最終計算姿勢
  626. // oldpos/rot から BasePos/Rot に step で補間して現在姿勢とする
  627. float stime = teamData.startTime + updateDeltaTime * runCount;
  628. float oldtime = teamData.startTime - updateDeltaTime;
  629. float interval = teamData.time - oldtime;
  630. float step = interval >= 1e-06f ? math.saturate((stime - oldtime) / interval) : 0.0f;
  631. nextPos = math.lerp(oldpos, basePosList[index], step);
  632. nextRot = math.slerp(oldrot, baseRotList[index], step);
  633. nextRot = math.normalize(nextRot);
  634. // 前回の姿勢をoldpos/rotとしてposList/rotListに格納する
  635. if (flag.IsCollider() && teamId == 0)
  636. {
  637. // グローバルコライダー
  638. // 移動量と回転量に制限をかける(1.7.5)
  639. // 制限をかけないと高速移動/回転時に遠く離れたパーティクルが押し出されてしまう問題が発生する。
  640. oldpos = MathUtility.ClampDistance(nextPos, oldNextPos, Define.Compute.GlobalColliderMaxMoveDistance);
  641. oldrot = MathUtility.ClampAngle(nextRot, oldNextRot, math.radians(Define.Compute.GlobalColliderMaxRotationAngle));
  642. }
  643. else
  644. {
  645. oldpos = oldNextPos;
  646. oldrot = oldNextRot;
  647. }
  648. #endif
  649. // debug
  650. //nextPos = basePosList[index];
  651. //nextRot = baseRotList[index];
  652. }
  653. else
  654. {
  655. // 動的パーティクル
  656. var depth = depthList[index];
  657. //var maxVelocity = teamMaxVelocityList[teamId].Evaluate(depth);
  658. var drag = teamDragList[teamId].Evaluate(depth);
  659. var gravity = teamGravityList[teamId].Evaluate(depth);
  660. var gravityDirection = teamData.gravityDirection;
  661. var mass = teamMassList[teamId].Evaluate(depth);
  662. var depthInfluence = teamDepthInfluenceList[teamId].Evaluate(depth);
  663. var velocity = velocityList[index];
  664. // チームスケール倍率
  665. //maxVelocity *= teamData.scaleRatio;
  666. // massは主に伸縮を中心に調整されるので、フォース適用時は少し調整する
  667. //mass = (mass - 1.0f) * teamData.forceMassInfluence + 1.0f;
  668. // 安定化用の速度ウエイト
  669. velocity *= teamData.velocityWeight;
  670. // 最大速度
  671. //velocity = MathUtility.ClampVector(velocity, 0.0f, maxVelocity);
  672. // 空気抵抗(90ups基準)
  673. // 重力に影響させたくないので先に計算する(※通常はforce適用後に行うのが一般的)
  674. velocity *= math.pow(1.0f - drag, updatePower);
  675. // フォース
  676. // フォースは空気抵抗を無視して加算する
  677. float3 force = 0;
  678. // 重力(質量に関係なく一定)
  679. // (最後に質量で割るためここでは質量をかける)
  680. force += gravityDirection * (gravity * mass);
  681. // 外部フォース
  682. if (runCount == 0)
  683. {
  684. float3 exForce = 0;
  685. switch (teamData.forceMode)
  686. {
  687. case PhysicsManagerTeamData.ForceMode.VelocityAdd:
  688. exForce += teamData.impactForce;
  689. break;
  690. case PhysicsManagerTeamData.ForceMode.VelocityAddWithoutMass:
  691. exForce += teamData.impactForce * mass;
  692. break;
  693. case PhysicsManagerTeamData.ForceMode.VelocityChange:
  694. exForce += teamData.impactForce;
  695. velocity = 0;
  696. break;
  697. case PhysicsManagerTeamData.ForceMode.VelocityChangeWithoutMass:
  698. exForce += teamData.impactForce * mass;
  699. velocity = 0;
  700. break;
  701. }
  702. // 外力
  703. exForce += teamData.externalForce;
  704. // 風(重量に関係なく一定)
  705. if (teamData.IsFlag(PhysicsManagerTeamData.Flag_Wind))
  706. exForce += Wind(teamId, teamData, snapBasePos) * mass;
  707. // 外力深さ影響率
  708. exForce *= depthInfluence;
  709. force += exForce;
  710. }
  711. // 外力チームスケール倍率
  712. force *= teamData.scaleRatio;
  713. // 速度計算(質量で割る)
  714. velocity += (force / mass) * updateDeltaTime;
  715. // 速度を理想位置に反映させる
  716. nextPos = oldpos + velocity * updateDeltaTime;
  717. }
  718. // 予定座標更新 ==============================================================
  719. // 摩擦減衰
  720. friction = friction * Define.Compute.FrictionDampingRate;
  721. frictionList[index] = friction;
  722. //frictionList[index] = 0;
  723. // 移動前の姿勢
  724. posList[index] = oldpos;
  725. rotList[index] = oldrot;
  726. // 予測位置
  727. nextPosList[index] = nextPos;
  728. nextRotList[index] = nextRot;
  729. }
  730. /// <summary>
  731. /// 風の計算
  732. /// </summary>
  733. /// <param name="teamId"></param>
  734. /// <param name="teamData"></param>
  735. /// <param name="pos"></param>
  736. /// <returns></returns>
  737. float3 Wind(int teamId, in PhysicsManagerTeamData.TeamData teamData, in float3 pos)
  738. {
  739. var windInfo = teamWindInfoList[teamId];
  740. // ノイズ起点
  741. // ここをずらすと他のパーティクルと非同期になっていく
  742. float sync = math.lerp(3.0f, 0.1f, teamData.forceWindSynchronization);
  743. var noiseBasePos = new float2(pos.x, pos.z) * sync;
  744. float3 externalForce = 0;
  745. for (int i = 0; i < 4; i++)
  746. {
  747. int windId = windInfo.windDataIndexList[i];
  748. if (windId < 0)
  749. continue;
  750. var windData = windDataList[windId];
  751. float3 windForce = PhysicsManagerWindData.CalcWindForce(
  752. teamData.time,
  753. noiseBasePos,
  754. windInfo.windDirectionList[i],
  755. windInfo.windMainList[i],
  756. windData.turbulence,
  757. windData.frequency,
  758. teamData.forceWindRandomScale
  759. );
  760. externalForce += windForce;
  761. }
  762. // チームの風の影響率
  763. externalForce *= teamData.forceWindInfluence;
  764. return externalForce;
  765. }
  766. }
  767. [BurstCompile]
  768. struct FixPositionJob : IJobParallelFor
  769. {
  770. public float updatePower;
  771. public float updateDeltaTime;
  772. public int runCount;
  773. // チーム
  774. [Unity.Collections.ReadOnly]
  775. public NativeArray<PhysicsManagerTeamData.TeamData> teamDataList;
  776. [Unity.Collections.ReadOnly]
  777. public NativeArray<CurveParam> teamMaxVelocityList;
  778. // パーティクルごと
  779. [Unity.Collections.ReadOnly]
  780. public NativeArray<PhysicsManagerParticleData.ParticleFlag> flagList;
  781. [Unity.Collections.ReadOnly]
  782. public NativeArray<int> teamIdList;
  783. [Unity.Collections.ReadOnly]
  784. public NativeArray<float> depthList;
  785. [Unity.Collections.ReadOnly]
  786. public NativeArray<float3> nextPosList;
  787. [Unity.Collections.ReadOnly]
  788. public NativeArray<quaternion> nextRotList;
  789. [Unity.Collections.ReadOnly]
  790. public NativeArray<float> frictionList;
  791. //[Unity.Collections.ReadOnly]
  792. //public NativeArray<float3> basePosList;
  793. //[Unity.Collections.ReadOnly]
  794. //public NativeArray<quaternion> baseRotList;
  795. public NativeArray<float3> velocityList;
  796. [Unity.Collections.WriteOnly]
  797. public NativeArray<quaternion> rotList;
  798. public NativeArray<float3> oldPosList;
  799. public NativeArray<quaternion> oldRotList;
  800. public NativeArray<float3> posList;
  801. [Unity.Collections.WriteOnly]
  802. public NativeArray<float3> localPosList;
  803. [Unity.Collections.ReadOnly]
  804. public NativeArray<float3> collisionNormalList;
  805. public NativeArray<float> staticFrictionList;
  806. // パーティクルごと
  807. public void Execute(int index)
  808. {
  809. var flag = flagList[index];
  810. if (flag.IsValid() == false)
  811. return;
  812. // チームデータ
  813. int teamId = teamIdList[index];
  814. var teamData = teamDataList[teamId];
  815. // ここからは更新がある場合のみ実行
  816. if (teamData.IsUpdate(runCount) == false)
  817. return;
  818. // 速度更新(m/s)
  819. if (flag.IsFixed() == false)
  820. {
  821. // 移動パーティクルのみ
  822. var nextPos = nextPosList[index];
  823. var nextRot = nextRotList[index];
  824. nextRot = math.normalize(nextRot); // 回転蓄積で精度が落ちていくので正規化しておく
  825. float3 velocity = 0;
  826. // posListには移動影響を考慮した最終座標が入っている
  827. var pos = posList[index];
  828. var oldpos = oldPosList[index];
  829. // コライダー接触情報
  830. float friction = frictionList[index];
  831. var cn = collisionNormalList[index];
  832. bool isCollision = math.lengthsq(cn) > Define.Compute.Epsilon; // 接触の有無
  833. #if true
  834. // 静止摩擦
  835. float staticFriction = staticFrictionList[index];
  836. if (isCollision && friction > 0.0f)
  837. {
  838. // 接線方向の移動速度から計算する
  839. var v = nextPos - oldpos;
  840. v = v - MathUtility.Project(v, cn);
  841. float tangentVelocity = math.length(v) / updateDeltaTime; // 接線方向の移動速度
  842. float stopVelocity = teamData.staticFriction * teamData.scaleRatio; // 静止速度
  843. if (tangentVelocity < stopVelocity)
  844. {
  845. staticFriction = math.saturate(staticFriction + 0.02f * updatePower); // 係数増加
  846. }
  847. else
  848. {
  849. // 接線速度に応じて係数を減少
  850. var vel = tangentVelocity - stopVelocity;
  851. var value = math.max(vel / 0.2f, 0.05f) * updatePower;
  852. staticFriction = math.saturate(staticFriction - value);
  853. }
  854. // 現在の静止摩擦係数を使い接線方向の移動にブレーキをかける
  855. v *= staticFriction;
  856. nextPos -= v;
  857. pos -= v;
  858. }
  859. else
  860. {
  861. staticFriction = math.saturate(staticFriction - 0.05f * updatePower); // 係数減少
  862. }
  863. staticFrictionList[index] = staticFriction;
  864. #endif
  865. // 速度更新(m/s)
  866. velocity = (nextPos - pos) / updateDeltaTime;
  867. velocity *= teamData.velocityWeight; // 安定化用の速度ウエイト
  868. #if true
  869. // 動摩擦による速度減衰(衝突面との角度が大きいほど減衰が強くなる)
  870. if (friction > Define.Compute.Epsilon && isCollision && math.lengthsq(velocity) >= Define.Compute.Epsilon)
  871. {
  872. var dot = math.dot(cn, math.normalize(velocity));
  873. dot = 0.5f + 0.5f * dot; // 1.0(front) - 0.5(side) - 0.0(back)
  874. dot *= dot; // サイドを強めに
  875. dot = 1.0f - dot; // 0.0(front) - 0.75(side) - 1.0(back)
  876. velocity -= velocity * (dot * math.saturate(friction * teamData.dynamicFriction * 1.5f)); // 以前と同程度になるように補正
  877. }
  878. #else
  879. // 摩擦による速度減衰(旧)
  880. friction *= teamData.friction; // チームごとの摩擦係数
  881. velocity *= math.pow(1.0f - math.saturate(friction), updatePower);
  882. #endif
  883. // 最大速度
  884. var depth = depthList[index];
  885. var maxVelocity = teamMaxVelocityList[teamId].Evaluate(depth);
  886. maxVelocity *= teamData.scaleRatio; // チームスケール
  887. velocity = MathUtility.ClampVector(velocity, 0.0f, maxVelocity);
  888. // 実際の移動速度(localPosに格納)
  889. var realVelocity = (nextPos - oldpos) / updateDeltaTime;
  890. realVelocity = MathUtility.ClampVector(realVelocity, 0.0f, maxVelocity); // 最大速度は考慮する
  891. localPosList[index] = realVelocity;
  892. // 書き戻し
  893. velocityList[index] = velocity;
  894. oldPosList[index] = nextPos;
  895. oldRotList[index] = nextRot;
  896. }
  897. }
  898. }
  899. //=========================================================================================
  900. /// <summary>
  901. /// 物理演算後処理
  902. /// </summary>
  903. /// <param name="updateDeltaTime"></param>
  904. void PostUpdatePhysics(float updateDeltaTime)
  905. {
  906. if (Particle.Count == 0)
  907. return;
  908. var job = new PostUpdatePhysicsJob()
  909. {
  910. updateDeltaTime = updateDeltaTime,
  911. teamDataList = Team.teamDataList.ToJobArray(),
  912. flagList = Particle.flagList.ToJobArray(),
  913. teamIdList = Particle.teamIdList.ToJobArray(),
  914. snapBasePosList = Particle.snapBasePosList.ToJobArray(),
  915. snapBaseRotList = Particle.snapBaseRotList.ToJobArray(),
  916. basePosList = Particle.basePosList.ToJobArray(),
  917. baseRotList = Particle.baseRotList.ToJobArray(),
  918. oldBasePosList = Particle.oldBasePosList.ToJobArray(),
  919. oldBaseRotList = Particle.oldBaseRotList.ToJobArray(),
  920. oldPosList = Particle.oldPosList.ToJobArray(),
  921. oldRotList = Particle.oldRotList.ToJobArray(),
  922. velocityList = Particle.velocityList.ToJobArray(),
  923. localPosList = Particle.localPosList.ToJobArray(),
  924. posList = Particle.posList.ToJobArray(),
  925. rotList = Particle.rotList.ToJobArray(),
  926. nextPosList = Particle.InNextPosList.ToJobArray(),
  927. nextRotList = Particle.InNextRotList.ToJobArray(),
  928. oldSlowPosList = Particle.oldSlowPosList.ToJobArray(),
  929. };
  930. jobHandle = job.Schedule(Particle.Length, 64, jobHandle);
  931. }
  932. [BurstCompile]
  933. struct PostUpdatePhysicsJob : IJobParallelFor
  934. {
  935. public float updateDeltaTime;
  936. // チーム
  937. [Unity.Collections.ReadOnly]
  938. public NativeArray<PhysicsManagerTeamData.TeamData> teamDataList;
  939. // パーティクルごと
  940. [Unity.Collections.ReadOnly]
  941. public NativeArray<PhysicsManagerParticleData.ParticleFlag> flagList;
  942. [Unity.Collections.ReadOnly]
  943. public NativeArray<int> teamIdList;
  944. // パーティクルごと
  945. [Unity.Collections.ReadOnly]
  946. public NativeArray<float3> snapBasePosList;
  947. [Unity.Collections.ReadOnly]
  948. public NativeArray<quaternion> snapBaseRotList;
  949. [Unity.Collections.ReadOnly]
  950. public NativeArray<float3> basePosList;
  951. [Unity.Collections.ReadOnly]
  952. public NativeArray<quaternion> baseRotList;
  953. [Unity.Collections.WriteOnly]
  954. public NativeArray<float3> oldBasePosList;
  955. [Unity.Collections.WriteOnly]
  956. public NativeArray<quaternion> oldBaseRotList;
  957. [Unity.Collections.ReadOnly]
  958. public NativeArray<float3> velocityList;
  959. [Unity.Collections.ReadOnly]
  960. public NativeArray<float3> localPosList;
  961. public NativeArray<float3> oldPosList;
  962. public NativeArray<quaternion> oldRotList;
  963. [Unity.Collections.WriteOnly]
  964. public NativeArray<float3> posList;
  965. [Unity.Collections.WriteOnly]
  966. public NativeArray<quaternion> rotList;
  967. [Unity.Collections.ReadOnly]
  968. public NativeArray<float3> nextPosList;
  969. [Unity.Collections.ReadOnly]
  970. public NativeArray<quaternion> nextRotList;
  971. public NativeArray<float3> oldSlowPosList;
  972. // パーティクルごと
  973. public void Execute(int index)
  974. {
  975. var flag = flagList[index];
  976. if (flag.IsValid() == false)
  977. return;
  978. // チームデータ
  979. int teamId = teamIdList[index];
  980. var teamData = teamDataList[teamId];
  981. float3 viewPos = 0;
  982. quaternion viewRot = quaternion.identity;
  983. //var basePos = basePosList[index];
  984. //var baseRot = baseRotList[index];
  985. var snapBasePos = snapBasePosList[index];
  986. var snapBaseRot = snapBaseRotList[index];
  987. if (flag.IsFixed() == false)
  988. {
  989. // 未来予測
  990. // 1フレーム前の表示位置と将来の予測位置を、現在のフレーム位置で線形補間する
  991. //var velocity = velocityList[index]; // 従来
  992. //var velocity = posList[index]; // 実際の速度(どうもこっちだとカクつき?があるぞ)
  993. var velocity = localPosList[index]; // 実際の速度
  994. var futurePos = oldPosList[index] + velocity * updateDeltaTime;
  995. var oldViewPos = oldSlowPosList[index];
  996. float addTime = teamData.addTime;
  997. float oldTime = teamData.time - addTime;
  998. float futureTime = teamData.time + (updateDeltaTime - teamData.nowTime);
  999. float interval = futureTime - oldTime;
  1000. //Debug.Log($"addTime:{teamData.addTime} interval:{interval}");
  1001. if (addTime > 1e-06f && interval > 1e-06f)
  1002. {
  1003. float ratio = teamData.addTime / interval;
  1004. viewPos = math.lerp(oldViewPos, futurePos, ratio);
  1005. }
  1006. else
  1007. {
  1008. viewPos = oldViewPos;
  1009. }
  1010. viewRot = oldRotList[index];
  1011. viewRot = math.normalize(viewRot); // 回転蓄積で精度が落ちていくので正規化しておく
  1012. #if false
  1013. // 未来予測を切る
  1014. futurePos = oldPosList[index];
  1015. viewPos = futurePos;
  1016. #endif
  1017. oldSlowPosList[index] = viewPos;
  1018. }
  1019. else
  1020. {
  1021. // 固定パーティクルの表示位置は常にベース位置
  1022. //viewPos = basePos;
  1023. //viewRot = baseRot;
  1024. viewPos = snapBasePos;
  1025. viewRot = snapBaseRot;
  1026. // 固定パーティクルは今回のbasePosを記録する(更新時のみ)
  1027. if (teamData.IsRunning())
  1028. {
  1029. // 最終計算位置を格納する
  1030. oldPosList[index] = nextPosList[index];
  1031. oldRotList[index] = nextRotList[index];
  1032. }
  1033. }
  1034. // ブレンド
  1035. if (teamData.blendRatio < 0.99f)
  1036. {
  1037. //viewPos = math.lerp(basePos, viewPos, teamData.blendRatio);
  1038. //viewRot = math.slerp(baseRot, viewRot, teamData.blendRatio);
  1039. viewPos = math.lerp(snapBasePos, viewPos, teamData.blendRatio);
  1040. viewRot = math.slerp(snapBaseRot, viewRot, teamData.blendRatio);
  1041. viewRot = math.normalize(viewRot); // 回転蓄積で精度が落ちていくので正規化しておく
  1042. }
  1043. // test
  1044. //viewPos = snapBasePos;
  1045. //viewRot = snapBaseRot;
  1046. // 表示位置
  1047. posList[index] = viewPos;
  1048. rotList[index] = viewRot;
  1049. // 1つ前の基準位置を記録
  1050. if (teamData.IsRunning())
  1051. {
  1052. oldBasePosList[index] = basePosList[index];
  1053. oldBaseRotList[index] = baseRotList[index];
  1054. }
  1055. }
  1056. }
  1057. //=========================================================================================
  1058. /// <summary>
  1059. /// ワーカーウォームアップ処理実行
  1060. /// </summary>
  1061. void WarmupWorker()
  1062. {
  1063. if (workers == null || workers.Count == 0)
  1064. return;
  1065. for (int i = 0; i < workers.Count; i++)
  1066. {
  1067. var worker = workers[i];
  1068. worker.Warmup();
  1069. }
  1070. }
  1071. }
  1072. }