MagicaMeshCloth.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using System.Collections.Generic;
  5. using Unity.Mathematics;
  6. using UnityEngine;
  7. namespace MagicaCloth
  8. {
  9. /// <summary>
  10. /// メッシュクロス
  11. /// </summary>
  12. [HelpURL("https://magicasoft.jp/magica-cloth-mesh-cloth/")]
  13. [AddComponentMenu("MagicaCloth/MagicaMeshCloth", 100)]
  14. public class MagicaMeshCloth : BaseCloth
  15. {
  16. /// <summary>
  17. /// データバージョン
  18. /// </summary>
  19. private const int DATA_VERSION = 7;
  20. /// <summary>
  21. /// エラーデータバージョン
  22. /// </summary>
  23. private const int ERR_DATA_VERSION = 3;
  24. /// <summary>
  25. /// 仮想メッシュデフォーマー
  26. /// </summary>
  27. [SerializeField]
  28. private MagicaVirtualDeformer virtualDeformer = null;
  29. [SerializeField]
  30. private int virtualDeformerHash;
  31. [SerializeField]
  32. private int virtualDeformerVersion;
  33. //=========================================================================================
  34. public override ComponentType GetComponentType()
  35. {
  36. return ComponentType.MeshCloth;
  37. }
  38. //=========================================================================================
  39. /// <summary>
  40. /// データハッシュを求める
  41. /// </summary>
  42. /// <returns></returns>
  43. public override int GetDataHash()
  44. {
  45. int hash = base.GetDataHash();
  46. hash += virtualDeformer.GetDataHash();
  47. return hash;
  48. }
  49. //=========================================================================================
  50. public VirtualMeshDeformer Deformer
  51. {
  52. get
  53. {
  54. if (virtualDeformer != null)
  55. return virtualDeformer.Deformer;
  56. return null;
  57. }
  58. }
  59. //=========================================================================================
  60. protected override void Reset()
  61. {
  62. base.Reset();
  63. ResetParams();
  64. }
  65. protected override void OnValidate()
  66. {
  67. base.OnValidate();
  68. }
  69. protected override void OnInit()
  70. {
  71. base.OnInit();
  72. }
  73. protected override void OnActive()
  74. {
  75. base.OnActive();
  76. }
  77. protected override void OnInactive()
  78. {
  79. base.OnInactive();
  80. }
  81. protected override void OnDispose()
  82. {
  83. base.OnDispose();
  84. }
  85. //=========================================================================================
  86. /// <summary>
  87. /// 頂点ごとのパーティクルフラグ設定(不要な場合は0)
  88. /// </summary>
  89. /// <param name="vindex"></param>
  90. /// <returns></returns>
  91. protected override uint UserFlag(int index)
  92. {
  93. // メッシュクロスでは不要
  94. return 0;
  95. }
  96. /// <summary>
  97. /// 頂点ごとの連動トランスフォーム設定(不要な場合はnull)
  98. /// </summary>
  99. /// <param name="vindex"></param>
  100. /// <returns></returns>
  101. protected override Transform UserTransform(int index)
  102. {
  103. // メッシュクロスでは不要
  104. return null;
  105. }
  106. /// <summary>
  107. /// 頂点ごとの連動トランスフォームのLocalPositionを返す(不要な場合は0)
  108. /// </summary>
  109. /// <param name="vindex"></param>
  110. /// <returns></returns>
  111. protected override float3 UserTransformLocalPosition(int vindex)
  112. {
  113. // メッシュクロスでは不要
  114. return 0;
  115. }
  116. /// <summary>
  117. /// 頂点ごとの連動トランスフォームのLocalRotationを返す(不要な場合はquaternion.identity)
  118. /// </summary>
  119. /// <param name="vindex"></param>
  120. /// <returns></returns>
  121. protected override quaternion UserTransformLocalRotation(int vindex)
  122. {
  123. // メッシュクロスでは不要
  124. return quaternion.identity;
  125. }
  126. /// <summary>
  127. /// デフォーマーが必須か返す
  128. /// </summary>
  129. /// <returns></returns>
  130. public override bool IsRequiresDeformer()
  131. {
  132. return true;
  133. }
  134. /// <summary>
  135. /// デフォーマーを返す
  136. /// </summary>
  137. /// <param name="index"></param>
  138. /// <returns></returns>
  139. public override BaseMeshDeformer GetDeformer()
  140. {
  141. return Deformer;
  142. }
  143. /// <summary>
  144. /// クロス初期化時に必要なMeshDataを返す(不要ならnull)
  145. /// </summary>
  146. /// <returns></returns>
  147. protected override MeshData GetMeshData()
  148. {
  149. return Deformer.MeshData;
  150. }
  151. /// <summary>
  152. /// クロス初期化の主にワーカーへの登録
  153. /// </summary>
  154. protected override void WorkerInit()
  155. {
  156. // デフォーマー頂点とパーティクルの連動登録
  157. var meshParticleWorker = MagicaPhysicsManager.Instance.Compute.MeshParticleWorker;
  158. var minfo = MagicaPhysicsManager.Instance.Mesh.GetVirtualMeshInfo(Deformer.MeshIndex);
  159. var cdata = ClothData;
  160. for (int i = 0; i < cdata.VertexUseCount; i++)
  161. {
  162. int pindex = particleChunk.startIndex + i;
  163. int vindex = minfo.vertexChunk.startIndex + cdata.useVertexList[i];
  164. if (pindex >= 0)
  165. meshParticleWorker.Add(TeamId, vindex, pindex);
  166. }
  167. }
  168. /// <summary>
  169. /// デフォーマーごとの使用頂点設定
  170. /// 使用頂点に対して AddUseVertex() / RemoveUseVertex() を実行する
  171. /// </summary>
  172. /// <param name="sw"></param>
  173. /// <param name="deformer"></param>
  174. protected override void SetDeformerUseVertex(bool sw, BaseMeshDeformer deformer)
  175. {
  176. var cdata = ClothData;
  177. for (int i = 0; i < cdata.VertexUseCount; i++)
  178. {
  179. // 未使用頂点は除く
  180. if (ClothData.IsInvalidVertex(i))
  181. continue;
  182. int vindex = cdata.useVertexList[i];
  183. bool fix = !ClothData.IsMoveVertex(i);
  184. if (sw)
  185. deformer.AddUseVertex(vindex, fix);
  186. else
  187. deformer.RemoveUseVertex(vindex, fix);
  188. }
  189. }
  190. /// <summary>
  191. /// UnityPhyiscsでの更新の変更
  192. /// 継承クラスは自身の使用するボーンの状態更新などを記述する
  193. /// </summary>
  194. /// <param name="sw"></param>
  195. protected override void ChangeUseUnityPhysics(bool sw)
  196. {
  197. base.ChangeUseUnityPhysics(sw);
  198. // デフォーマに伝達
  199. virtualDeformer?.SetUseUnityPhysics(sw);
  200. }
  201. //=========================================================================================
  202. public override int GetVersion()
  203. {
  204. return DATA_VERSION;
  205. }
  206. /// <summary>
  207. /// エラーとするデータバージョンを取得する
  208. /// </summary>
  209. /// <returns></returns>
  210. public override int GetErrorVersion()
  211. {
  212. return ERR_DATA_VERSION;
  213. }
  214. /// <summary>
  215. /// データを検証して結果を格納する
  216. /// </summary>
  217. /// <returns></returns>
  218. public override void CreateVerifyData()
  219. {
  220. base.CreateVerifyData();
  221. virtualDeformerHash = virtualDeformer.SaveDataHash;
  222. virtualDeformerVersion = virtualDeformer.SaveDataVersion;
  223. }
  224. /// <summary>
  225. /// 現在のデータが正常(実行できる状態)か返す
  226. /// </summary>
  227. /// <returns></returns>
  228. public override Define.Error VerifyData()
  229. {
  230. var baseError = base.VerifyData();
  231. if (baseError != Define.Error.None)
  232. return baseError;
  233. if (ClothData == null)
  234. return Define.Error.ClothDataNull;
  235. if (virtualDeformer == null)
  236. return Define.Error.DeformerNull;
  237. var vdeformerError = virtualDeformer.VerifyData();
  238. if (vdeformerError != Define.Error.None)
  239. return vdeformerError;
  240. if (virtualDeformerHash != virtualDeformer.SaveDataHash)
  241. return Define.Error.DeformerHashMismatch;
  242. if (virtualDeformerVersion != virtualDeformer.SaveDataVersion)
  243. return Define.Error.DeformerVersionMismatch;
  244. return Define.Error.None;
  245. }
  246. /// <summary>
  247. /// データ検証の結果テキストを取得する
  248. /// </summary>
  249. /// <returns></returns>
  250. public override string GetInformation()
  251. {
  252. // 仮想デフォーマー情報
  253. StaticStringBuilder.Clear();
  254. var err = VerifyData();
  255. if (err == Define.Error.None)
  256. {
  257. // OK
  258. var cdata = ClothData;
  259. StaticStringBuilder.AppendLine("Active: ", Status.IsActive);
  260. StaticStringBuilder.AppendLine($"Visible: {IsVisible}");
  261. StaticStringBuilder.AppendLine($"Calculation:{IsCalculate}");
  262. StaticStringBuilder.AppendLine("Vertex: ", cdata.VertexUseCount);
  263. StaticStringBuilder.AppendLine("Clamp Distance: ", cdata.ClampDistanceConstraintCount);
  264. StaticStringBuilder.AppendLine("Clamp Position: ", clothParams.UseClampPositionLength ? cdata.VertexUseCount : 0);
  265. StaticStringBuilder.AppendLine("Clamp Rotation [", cdata.clampRotationAlgorithm, "] : ", cdata.GetClampRotationCount());
  266. StaticStringBuilder.AppendLine("Struct Distance: ", cdata.StructDistanceConstraintCount / 2);
  267. StaticStringBuilder.AppendLine("Bend Distance: ", cdata.BendDistanceConstraintCount / 2);
  268. StaticStringBuilder.AppendLine("Near Distance: ", cdata.NearDistanceConstraintCount / 2);
  269. StaticStringBuilder.AppendLine("Restore Rotation [", cdata.restoreRotationAlgorithm, "] : ", cdata.GetRestoreRotationCount());
  270. StaticStringBuilder.AppendLine("Triangle Bend [", cdata.triangleBendAlgorithm, "] : ", cdata.TriangleBendConstraintCount);
  271. StaticStringBuilder.AppendLine("Collider: ", teamData.ColliderCount);
  272. StaticStringBuilder.Append("Line Rotation: ", cdata.LineRotationWorkerCount);
  273. }
  274. else if (err == Define.Error.EmptyData)
  275. {
  276. StaticStringBuilder.Append(Define.GetErrorMessage(err));
  277. }
  278. else
  279. {
  280. // エラー
  281. StaticStringBuilder.AppendLine("This mesh cloth is in a state error!");
  282. if (Application.isPlaying)
  283. {
  284. StaticStringBuilder.AppendLine("Execution stopped.");
  285. }
  286. else
  287. {
  288. StaticStringBuilder.AppendLine("Please recreate the cloth data.");
  289. }
  290. StaticStringBuilder.Append(Define.GetErrorMessage(err));
  291. }
  292. return StaticStringBuilder.ToString();
  293. }
  294. public bool IsValidPointSelect()
  295. {
  296. if (ClothSelection == null)
  297. return false;
  298. if (Deformer.MeshData.ChildCount != ClothSelection.DeformerCount)
  299. return false;
  300. return true;
  301. }
  302. //=========================================================================================
  303. /// <summary>
  304. /// メッシュのワールド座標/法線/接線を返す(エディタ用)
  305. /// </summary>
  306. /// <param name="wposList"></param>
  307. /// <param name="wnorList"></param>
  308. /// <param name="wtanList"></param>
  309. /// <returns>頂点数</returns>
  310. public override int GetEditorPositionNormalTangent(out List<Vector3> wposList, out List<Vector3> wnorList, out List<Vector3> wtanList)
  311. {
  312. return Deformer.GetEditorPositionNormalTangent(out wposList, out wnorList, out wtanList);
  313. }
  314. /// <summary>
  315. /// メッシュのトライアングルリストを返す(エディタ用)
  316. /// </summary>
  317. /// <returns></returns>
  318. public override List<int> GetEditorTriangleList()
  319. {
  320. return Deformer.GetEditorTriangleList();
  321. }
  322. /// <summary>
  323. /// メッシュのラインリストを返す(エディタ用)
  324. /// </summary>
  325. /// <returns></returns>
  326. public override List<int> GetEditorLineList()
  327. {
  328. return Deformer.GetEditorLineList();
  329. }
  330. //=========================================================================================
  331. /// <summary>
  332. /// 頂点の選択状態をリストにして返す(エディタ用)
  333. /// 選択状態は ClothSelection.Invalid / ClothSelection.Fixed / ClothSelection.Move
  334. /// すべてがInvalidならばnullを返す
  335. /// </summary>
  336. /// <returns></returns>
  337. public override List<int> GetSelectionList()
  338. {
  339. if (ClothSelection != null && virtualDeformer != null && Deformer.MeshData != null)
  340. return ClothSelection.GetSelectionData(Deformer.MeshData, Deformer.GetRenderDeformerMeshList());
  341. else
  342. return null;
  343. }
  344. /// <summary>
  345. /// 頂点の使用状態をリストにして返す(エディタ用)
  346. /// 数値が1以上ならば使用中とみなす
  347. /// すべて使用状態ならばnullを返す
  348. /// </summary>
  349. /// <returns></returns>
  350. public override List<int> GetUseList()
  351. {
  352. if (Application.isPlaying && virtualDeformer != null)
  353. {
  354. if (Deformer != null)
  355. {
  356. var minfo = MagicaPhysicsManager.Instance.Mesh.GetVirtualMeshInfo(Deformer.MeshIndex);
  357. //var infoList = MagicaPhysicsManager.Instance.Mesh.virtualVertexInfoList;
  358. var vertexUseList = MagicaPhysicsManager.Instance.Mesh.virtualVertexUseList;
  359. var useList = new List<int>();
  360. for (int i = 0; i < minfo.vertexChunk.dataLength; i++)
  361. {
  362. //uint data = infoList[minfo.vertexChunk.startIndex + i];
  363. //useList.Add((int)(data & 0xffff));
  364. useList.Add(vertexUseList[minfo.vertexChunk.startIndex + i]);
  365. }
  366. return useList;
  367. }
  368. }
  369. return null;
  370. }
  371. //=========================================================================================
  372. /// <summary>
  373. /// 共有データオブジェクト収集
  374. /// </summary>
  375. /// <returns></returns>
  376. public override List<ShareDataObject> GetAllShareDataObject()
  377. {
  378. var sdata = base.GetAllShareDataObject();
  379. if (Deformer != null)
  380. sdata.Add(Deformer.MeshData);
  381. return sdata;
  382. }
  383. /// <summary>
  384. /// sourceの共有データを複製して再セットする
  385. /// 再セットした共有データを返す
  386. /// </summary>
  387. /// <param name="source"></param>
  388. /// <returns></returns>
  389. public override ShareDataObject DuplicateShareDataObject(ShareDataObject source)
  390. {
  391. var sdata = base.DuplicateShareDataObject(source);
  392. if (sdata != null)
  393. return sdata;
  394. if (Deformer.MeshData == source)
  395. {
  396. //Deformer.MeshData = Instantiate(Deformer.MeshData);
  397. Deformer.MeshData = ShareDataObject.Clone(Deformer.MeshData);
  398. return Deformer.MeshData;
  399. }
  400. return null;
  401. }
  402. //=========================================================================================
  403. /// <summary>
  404. /// パラメータ初期化
  405. /// </summary>
  406. void ResetParams()
  407. {
  408. clothParams.AlgorithmType = ClothParams.Algorithm.Algorithm_2;
  409. clothParams.SetRadius(0.02f, 0.02f);
  410. clothParams.SetMass(10.0f, 1.0f, true, -0.5f, true);
  411. clothParams.SetGravity(true, -5.0f, -5.0f);
  412. clothParams.SetDrag(true, 0.01f, 0.01f);
  413. clothParams.SetMaxVelocity(true, 3.0f, 3.0f);
  414. clothParams.SetWorldInfluence(3.0f, 0.5f, 1.0f);
  415. clothParams.SetTeleport(false);
  416. clothParams.SetClampDistanceRatio(true, 0.5f, 1.05f, 0.1f);
  417. clothParams.SetClampPositionLength(false, 0.0f, 0.4f);
  418. clothParams.SetClampRotationAngle(false, 0.0f, 180.0f, 0.2f);
  419. clothParams.SetRestoreDistance(1.0f);
  420. clothParams.SetRestoreRotation(false, 0.03f, 0.005f, 0.3f);
  421. clothParams.SetSpring(false);
  422. clothParams.SetAdjustRotation();
  423. clothParams.SetTriangleBend(true, 1.0f, 1.0f);
  424. clothParams.SetVolume(false);
  425. clothParams.SetCollision(false, 0.1f, 0.03f);
  426. clothParams.SetExternalForce(0.3f, 1.0f, 0.7f, 0.6f);
  427. }
  428. }
  429. }