ClothGizmoDrawer.cs 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using System.Collections.Generic;
  5. using UnityEditor;
  6. using UnityEngine;
  7. namespace MagicaCloth
  8. {
  9. /// <summary>
  10. /// クロスのギズモ表示
  11. /// </summary>
  12. public class ClothGizmoDrawer
  13. {
  14. /// <summary>
  15. /// 常に表示するデータ
  16. /// </summary>
  17. /// <param name="team"></param>
  18. /// <param name="param"></param>
  19. internal static void AlwaysDrawClothGizmo(
  20. PhysicsTeam team,
  21. ClothParams param
  22. )
  23. {
  24. if (ClothMonitorMenu.Monitor.UI.DrawCloth == false)
  25. return;
  26. // 無条件で表示するもの
  27. //DrawSkinningBone(team);
  28. }
  29. /// <summary>
  30. /// データ存在時の表示
  31. /// </summary>
  32. /// <param name="team"></param>
  33. /// <param name="clothData"></param>
  34. /// <param name="param"></param>
  35. /// <param name="setup"></param>
  36. /// <param name="editorMesh"></param>
  37. /// <param name="editorCloth"></param>
  38. /// <returns></returns>
  39. public static bool DrawClothGizmo(
  40. PhysicsTeam team,
  41. ClothData clothData,
  42. ClothParams param,
  43. ClothSetup setup,
  44. IEditorMesh editorMesh,
  45. IEditorCloth editorCloth
  46. )
  47. {
  48. if (ClothMonitorMenu.Monitor.UI.DrawCloth == false)
  49. return false;
  50. if (ClothMonitorMenu.Monitor.UI.DrawClothVertex == false
  51. && ClothMonitorMenu.Monitor.UI.DrawClothDepth == false
  52. && ClothMonitorMenu.Monitor.UI.DrawClothBase == false
  53. && ClothMonitorMenu.Monitor.UI.DrawClothCollider == false
  54. && ClothMonitorMenu.Monitor.UI.DrawClothStructDistanceLine == false
  55. && ClothMonitorMenu.Monitor.UI.DrawClothBendDistanceLine == false
  56. && ClothMonitorMenu.Monitor.UI.DrawClothNearDistanceLine == false
  57. && ClothMonitorMenu.Monitor.UI.DrawClothRotationLine == false
  58. && ClothMonitorMenu.Monitor.UI.DrawClothTriangleBend == false
  59. && ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false
  60. && ClothMonitorMenu.Monitor.UI.DrawClothAxis == false
  61. #if MAGICACLOTH_DEBUG
  62. && ClothMonitorMenu.Monitor.UI.DrawClothVertexNumber == false
  63. && ClothMonitorMenu.Monitor.UI.DrawClothVertexIndex == false
  64. && ClothMonitorMenu.Monitor.UI.DrawPenetrationOrigin == false
  65. #endif
  66. )
  67. return false;
  68. // 以下はデータが存在する場合のみ
  69. if (clothData == null)
  70. return false;
  71. if (Application.isPlaying)
  72. {
  73. if (clothData == null)
  74. return false;
  75. if (team.IsActive() == false)
  76. return false;
  77. if (team.IsCalculate == false)
  78. return false;
  79. // 頂点使用状態
  80. //var useList = editorCloth.GetUseList();
  81. var selList = editorCloth.GetSelectionList();
  82. // 頂点情報
  83. DrawVertexRuntime(team, clothData, param, setup, selList);
  84. // コライダー
  85. DrawCollider(team);
  86. // ライン
  87. DrawLineRuntime(team, clothData, setup, selList);
  88. // トライアングルベンド
  89. DrawTriangleBendRuntime(team, clothData, setup);
  90. // 回転ライン
  91. DrawRotationLineRuntime(team, clothData, setup, selList);
  92. // コライダー移動制限
  93. DrawPenetrationRuntime(team, param, clothData, selList);
  94. //DrawBonePenetrationRuntime(team, param, clothData, selList); // 一旦休眠
  95. // ボリューム
  96. //DrawVolumeRuntime(team, clothData, setup);
  97. // 回転調整ライン
  98. //DrawAdjustRotationLineRuntime(team, clothData);
  99. }
  100. else
  101. {
  102. // メッシュ頂点法線接線
  103. List<Vector3> posList;
  104. List<Vector3> norList;
  105. List<Vector3> tanList;
  106. int vcnt = editorMesh.GetEditorPositionNormalTangent(out posList, out norList, out tanList);
  107. // 頂点使用状態
  108. //var useList = editorCloth.GetUseList();
  109. var selList = editorCloth.GetSelectionList();
  110. // 頂点情報
  111. DrawVertexClothData(clothData, param, vcnt, posList, norList, tanList, selList);
  112. // コライダー
  113. DrawCollider(team);
  114. // ライン
  115. DrawLineClothData(clothData, posList, selList);
  116. // トライアングルベンド
  117. DrawTriangleBendClothData(clothData, posList);
  118. // 回転ライン
  119. DrawRotationLineClothData(clothData, posList, selList);
  120. // コライダー移動制限
  121. DrawPenetrationClothData(team, param, clothData, posList, norList, tanList, selList);
  122. //DrawBonePenetrationClothData(team, param, clothData, posList, norList, tanList, selList); // 一旦休眠
  123. // ベーススキニング
  124. //DrawBaseSkinningClothData(team, clothData, posList, selList);
  125. // ボリューム
  126. //DrawVolumeClothData(clothData, posList);
  127. // 回転調整ライン
  128. //DrawAdjustRotationLineClothData(clothData, posList);
  129. }
  130. return true;
  131. }
  132. //=========================================================================================
  133. /// <summary>
  134. /// ランタイム状態での頂点表示
  135. /// </summary>
  136. /// <param name="scr"></param>
  137. /// <param name="deformer"></param>
  138. /// <param name="clothData"></param>
  139. static void DrawVertexRuntime(
  140. PhysicsTeam team,
  141. ClothData clothData,
  142. ClothParams param,
  143. ClothSetup setup,
  144. List<int> selList
  145. )
  146. {
  147. bool drawVertex = ClothMonitorMenu.Monitor.UI.DrawClothVertex;
  148. bool drawRadius = ClothMonitorMenu.Monitor.UI.DrawClothRadius;
  149. bool drawDepth = ClothMonitorMenu.Monitor.UI.DrawClothDepth;
  150. bool drawAxis = ClothMonitorMenu.Monitor.UI.DrawClothAxis;
  151. #if MAGICACLOTH_DEBUG
  152. bool number = ClothMonitorMenu.Monitor.UI.DrawClothVertexNumber;
  153. bool drawIndex = ClothMonitorMenu.Monitor.UI.DrawClothVertexIndex;
  154. bool drawFriction = ClothMonitorMenu.Monitor.UI.DrawClothFriction;
  155. bool drawStaticFriction = ClothMonitorMenu.Monitor.UI.DrawClothStaticFriction;
  156. bool drawDepthNumber = ClothMonitorMenu.Monitor.UI.DrawClothDepthNumber;
  157. bool drawCollisionNormal = ClothMonitorMenu.Monitor.UI.DrawClothCollisionNormal;
  158. bool drawVelocity = ClothMonitorMenu.Monitor.UI.DrawClothVelocity;
  159. bool drawVelocityVector = ClothMonitorMenu.Monitor.UI.DrawClothVelocityVector;
  160. #else
  161. bool number = false;
  162. bool drawIndex = false;
  163. bool drawFriction = false;
  164. bool drawStaticFriction = false;
  165. bool drawDepthNumber = false;
  166. bool drawCollisionNormal = false;
  167. bool drawVelocity = false;
  168. bool drawVelocityVector = false;
  169. #endif
  170. if (!number && !drawVertex && !drawDepth && !drawAxis && !drawIndex && !drawFriction && !drawStaticFriction
  171. && !drawDepthNumber && !drawCollisionNormal && !drawVelocity && !drawVelocityVector)
  172. return;
  173. // チームスケール
  174. var teamTransform = team.InfluenceTarget ? team.InfluenceTarget : team.transform;
  175. float teamScale = clothData.initScale.magnitude > 0.0f ? teamTransform.lossyScale.magnitude / clothData.initScale.magnitude : 1.0f;
  176. float updateIntervalTime = MagicaPhysicsManager.Instance.UpdateTime.UpdateIntervalTime;
  177. int vcnt = clothData.useVertexList.Count;
  178. for (int i = 0; i < vcnt; i++)
  179. {
  180. int vindex = clothData.useVertexList[i];
  181. int pindex = team.ParticleChunk.startIndex + i;
  182. Vector3 pos = MagicaPhysicsManager.Instance.Particle.posList[pindex];
  183. float depth = MagicaPhysicsManager.Instance.Particle.depthList[pindex];
  184. //float radius = PhysicsManager.Instance.Particle.radiusList[pindex];
  185. float radius = drawRadius ? MagicaPhysicsManager.Instance.Particle.radiusList[pindex].x * teamScale : 0.001f;
  186. //float radius = param.GetRadius(depth);
  187. if (drawVertex || drawDepth || drawAxis)
  188. {
  189. Quaternion rot = MagicaPhysicsManager.Instance.Particle.rotList[pindex];
  190. Gizmos.color = GetVertexColor(vindex, depth, selList);
  191. GizmoUtility.DrawWireSphere(pos, rot, Vector3.one, radius, drawVertex || drawDepth, drawAxis);
  192. }
  193. if (drawCollisionNormal)
  194. {
  195. Vector3 cn = MagicaPhysicsManager.Instance.Particle.collisionNormalList[pindex];
  196. Gizmos.color = GizmoUtility.ColorCollisionNormal;
  197. Gizmos.DrawLine(pos, pos + cn * 0.03f);
  198. }
  199. if (drawVelocityVector)
  200. {
  201. Vector3 vel = MagicaPhysicsManager.Instance.Particle.velocityList[pindex];
  202. Gizmos.color = GizmoUtility.ColorVelocity;
  203. Gizmos.DrawLine(pos, pos + vel * updateIntervalTime);
  204. }
  205. if (number)
  206. {
  207. Handles.Label(pos, i.ToString());
  208. }
  209. if (drawIndex)
  210. {
  211. Handles.Label(pos, pindex.ToString());
  212. }
  213. if (drawFriction)
  214. {
  215. float friction = MagicaPhysicsManager.Instance.Particle.frictionList[pindex];
  216. Handles.Label(pos, string.Format("{0:#.##}", friction));
  217. }
  218. if (drawStaticFriction)
  219. {
  220. float staticFriction = MagicaPhysicsManager.Instance.Particle.staticFrictionList[pindex];
  221. Handles.Label(pos, string.Format("{0:#.##}", staticFriction));
  222. }
  223. //if (drawDepthNumber)
  224. if (drawDepth)
  225. {
  226. float d = MagicaPhysicsManager.Instance.Particle.depthList[pindex];
  227. Handles.Label(pos, string.Format("{0:#.##}", d));
  228. }
  229. if (drawVelocity)
  230. {
  231. Vector3 v = MagicaPhysicsManager.Instance.Particle.velocityList[pindex];
  232. Handles.Label(pos, string.Format("{0:#.##}", v.magnitude));
  233. }
  234. }
  235. }
  236. /// <summary>
  237. /// エディタ状態での頂点表示
  238. /// </summary>
  239. /// <param name="scr"></param>
  240. /// <param name="deformer"></param>
  241. /// <param name="clothData"></param>
  242. static void DrawVertexClothData(
  243. ClothData clothData,
  244. ClothParams param,
  245. int vcnt,
  246. List<Vector3> posList,
  247. List<Vector3> norList,
  248. List<Vector3> tanList,
  249. List<int> selList
  250. )
  251. {
  252. bool drawVertex = ClothMonitorMenu.Monitor.UI.DrawClothVertex;
  253. bool drawRadius = ClothMonitorMenu.Monitor.UI.DrawClothRadius;
  254. bool drawDepth = ClothMonitorMenu.Monitor.UI.DrawClothDepth;
  255. bool drawAxis = ClothMonitorMenu.Monitor.UI.DrawClothAxis;
  256. #if MAGICACLOTH_DEBUG
  257. bool number = ClothMonitorMenu.Monitor.UI.DrawClothVertexNumber;
  258. bool drawDepthNumber = ClothMonitorMenu.Monitor.UI.DrawClothDepthNumber;
  259. #else
  260. bool number = false;
  261. bool drawDepthNumber = false;
  262. #endif
  263. if (!number && !drawVertex && !drawDepth && !drawAxis && !drawDepthNumber)
  264. return;
  265. for (int i = 0; i < clothData.VertexUseCount; i++)
  266. {
  267. int vindex = clothData.useVertexList[i];
  268. if (vindex >= posList.Count)
  269. continue;
  270. Vector3 pos = posList[vindex];
  271. if (drawVertex || drawDepth || drawAxis)
  272. {
  273. Vector3 nor = norList[vindex];
  274. Vector3 tan = tanList[vindex];
  275. Quaternion rot = Quaternion.LookRotation(nor, tan);
  276. float depth = clothData == null ? 0.0f : clothData.vertexDepthList[i];
  277. //float radius = param.GetRadius(depth);
  278. float radius = drawRadius ? param.GetRadius(depth) : 0.001f;
  279. Gizmos.color = GetVertexColor(vindex, depth, selList);
  280. GizmoUtility.DrawWireSphere(pos, rot, Vector3.one, radius, drawVertex || drawDepth, drawAxis);
  281. }
  282. if (number)
  283. {
  284. Handles.Label(pos, i.ToString());
  285. }
  286. //if (drawDepthNumber)
  287. if (drawDepth)
  288. {
  289. float depth = clothData == null ? 0.0f : clothData.vertexDepthList[i];
  290. Handles.Label(pos, string.Format("{0:#.##}", depth));
  291. }
  292. }
  293. }
  294. /// <summary>
  295. /// クロス頂点カラー設定
  296. /// </summary>
  297. /// <param name="vindex"></param>
  298. /// <param name="depth"></param>
  299. /// <returns></returns>
  300. static Color GetVertexColor(int vindex, float depth, List<int> selList)
  301. {
  302. if (ClothMonitorMenu.Monitor.UI.DrawClothDepth)
  303. {
  304. return Color.Lerp(Color.red, Color.blue, depth);
  305. }
  306. else
  307. {
  308. if (selList == null || vindex >= selList.Count)
  309. return GizmoUtility.ColorDeformerPoint;
  310. else if (selList[vindex] == SelectionData.Fixed)
  311. return GizmoUtility.ColorKinematic;
  312. else if (selList[vindex] == SelectionData.Move)
  313. return GizmoUtility.ColorDynamic;
  314. else
  315. return GizmoUtility.ColorInvalid;
  316. }
  317. }
  318. static bool IsMove(int vindex, List<int> selList)
  319. {
  320. if (selList == null || vindex >= selList.Count)
  321. return false;
  322. return selList[vindex] == SelectionData.Move;
  323. }
  324. //=========================================================================================
  325. /// <summary>
  326. /// クロスに紐づくコライダーの表示
  327. /// </summary>
  328. /// <param name="scr"></param>
  329. public static void DrawCollider(PhysicsTeam team)
  330. {
  331. if (ClothMonitorMenu.Monitor.UI.DrawClothCollider == false)
  332. return;
  333. var colliderlist = team.TeamData.ColliderList;
  334. foreach (var collider in colliderlist)
  335. {
  336. if (collider == null || collider.isActiveAndEnabled == false)
  337. continue;
  338. if (collider is MagicaSphereCollider)
  339. MagicaSphereColliderGizmoDrawer.DrawGizmo(collider as MagicaSphereCollider, true);
  340. else if (collider is MagicaCapsuleCollider)
  341. MagicaCapsuleColliderGizmoDrawer.DrawGizmo(collider as MagicaCapsuleCollider, true);
  342. }
  343. }
  344. //=========================================================================================
  345. #if false
  346. /// <summary>
  347. /// エディタ状態でのベーススキニング表示
  348. /// </summary>
  349. /// <param name="team"></param>
  350. /// <param name="clothData"></param>
  351. /// <param name="posList"></param>
  352. /// <param name="selList"></param>
  353. static void DrawBaseSkinningClothData(
  354. PhysicsTeam team,
  355. ClothData clothData,
  356. List<Vector3> posList,
  357. List<int> selList
  358. )
  359. {
  360. if (ClothMonitorMenu.Monitor.UI.DrawClothBaseSkinning == false)
  361. return;
  362. if (clothData.baseSkinningDataList == null)
  363. return;
  364. //var boneList = team.TeamData.SkinningBoneList;
  365. var boneList = team.TeamData.ColliderList;
  366. //Gizmos.color = GizmoUtility.ColorPenetration;
  367. for (int i = 0; i < clothData.VertexUseCount; i++)
  368. {
  369. int vindex = clothData.useVertexList[i];
  370. if (vindex >= posList.Count)
  371. continue;
  372. if (IsMove(vindex, selList) == false)
  373. continue;
  374. Vector3 pos = posList[vindex];
  375. for (int j = 0; j < Define.Compute.BaseSkinningWeightCount; j++)
  376. {
  377. int dindex = i * Define.Compute.BaseSkinningWeightCount + j;
  378. if (dindex >= clothData.baseSkinningDataList.Length)
  379. return;
  380. var data = clothData.baseSkinningDataList[dindex];
  381. if (data.IsValid() == false)
  382. continue;
  383. int bindex = data.boneIndex;
  384. if (bindex >= boneList.Count)
  385. continue;
  386. var bone = boneList[bindex];
  387. if (bone == null)
  388. continue;
  389. //Gizmos.color = j == 0 ? Color.red : Color.yellow;
  390. Gizmos.color = Color.gray;
  391. #if true
  392. Vector3 p, dir, d;
  393. bone.CalcNearPoint(pos, out p, out dir, out d, true);
  394. Gizmos.DrawLine(pos, p);
  395. #else
  396. //var cp = bone.TransformPoint(data.localPos);
  397. Vector3 cp;
  398. MeshUtility.ClosestPtBoneLine(pos, bone, 0.03f, out cp);
  399. Gizmos.DrawLine(pos, cp);
  400. #endif
  401. }
  402. }
  403. }
  404. #endif
  405. #if false // 一旦休眠
  406. /// <summary>
  407. /// スキニング用ボーン構造の表示
  408. /// </summary>
  409. /// <param name="team"></param>
  410. static void DrawSkinningBone(
  411. PhysicsTeam team
  412. )
  413. {
  414. if (ClothMonitorMenu.Monitor.UI.DrawClothSkinningBones == false)
  415. return;
  416. // スキニング用ボーン
  417. var boneList = team.TeamData.SkinningBoneList;
  418. if (boneList.Count >= 2)
  419. {
  420. //Gizmos.color = new Color(0.0f, 0.717f, 0.933f);
  421. //Gizmos.color = Color.magenta;
  422. foreach (var bone in boneList)
  423. {
  424. if (bone == null)
  425. continue;
  426. for (int k = 0; k < bone.childCount; k++)
  427. {
  428. var cbone = bone.GetChild(k);
  429. if (boneList.Contains(cbone))
  430. {
  431. //Gizmos.DrawLine(bone.position, cbone.position);
  432. GizmoUtility.DrawBone(bone.position, cbone.position, 0.01f);
  433. }
  434. }
  435. }
  436. }
  437. }
  438. #endif
  439. //=========================================================================================
  440. /// <summary>
  441. /// ランタイム状態での浸透制限表示
  442. /// </summary>
  443. /// <param name="team"></param>
  444. /// <param name="clothData"></param>
  445. /// <param name="selList"></param>
  446. static void DrawPenetrationRuntime(
  447. PhysicsTeam team,
  448. ClothParams param,
  449. ClothData clothData,
  450. List<int> selList
  451. )
  452. {
  453. #if !MAGICACLOTH_DEBUG
  454. if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false)
  455. return;
  456. #else
  457. if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false && ClothMonitorMenu.Monitor.UI.DrawPenetrationOrigin == false)
  458. return;
  459. #endif
  460. if (clothData.penetrationDataList == null)
  461. return;
  462. if (clothData.penetrationReferenceList == null)
  463. return;
  464. //var mode = param.GetPenetrationMode();
  465. var mode = clothData.penetrationMode;
  466. // 一旦休眠
  467. //if (mode == ClothParams.PenetrationMode.BonePenetration)
  468. // return;
  469. var colliderlist = team.TeamData.ColliderList;
  470. int vcnt = clothData.useVertexList.Count;
  471. for (int i = 0; i < vcnt; i++)
  472. {
  473. int vindex = clothData.useVertexList[i];
  474. if (IsMove(vindex, selList) == false)
  475. continue;
  476. int pindex = team.ParticleChunk.startIndex + i;
  477. Vector3 pos = MagicaPhysicsManager.Instance.Particle.posList[pindex];
  478. if (i >= clothData.penetrationReferenceList.Length)
  479. return;
  480. #if MAGICACLOTH_DEBUG
  481. Vector3 cen = Vector3.zero;
  482. Vector3 cdir = Vector3.zero;
  483. int ccnt = 0;
  484. GUIStyle style = new GUIStyle();
  485. style.normal.textColor = Color.cyan;
  486. #endif
  487. var refdata = clothData.penetrationReferenceList[i];
  488. for (int j = 0; j < refdata.count; j++)
  489. {
  490. var dindex = refdata.startIndex + j;
  491. var data = clothData.penetrationDataList[dindex];
  492. if (data.IsValid() == false)
  493. continue;
  494. if (mode == ClothParams.PenetrationMode.SurfacePenetration)
  495. {
  496. Vector3 bpos = MagicaPhysicsManager.Instance.Particle.basePosList[pindex];
  497. Quaternion brot = MagicaPhysicsManager.Instance.Particle.baseRotList[pindex];
  498. var dir = brot * data.localDir;
  499. var depth = clothData.vertexDepthList[i];
  500. var dist = param.GetPenetrationDistance().Evaluate(depth);
  501. Gizmos.color = GizmoUtility.ColorPenetration;
  502. Gizmos.DrawLine(bpos, bpos + dir * dist);
  503. break;
  504. }
  505. else if (mode == ClothParams.PenetrationMode.ColliderPenetration)
  506. {
  507. int cindex = data.colliderIndex;
  508. if (cindex >= colliderlist.Count)
  509. continue;
  510. var col = colliderlist[cindex];
  511. if (col == null)
  512. continue;
  513. var cp = col.transform.TransformPoint(data.localPos);
  514. #if MAGICACLOTH_DEBUG
  515. var dir = col.transform.TransformDirection(data.localDir);
  516. var c = cp + dir * data.distance;
  517. cen += c;
  518. cdir += dir;
  519. ccnt++;
  520. #endif
  521. if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration)
  522. {
  523. Gizmos.color = GizmoUtility.ColorPenetration;
  524. Gizmos.DrawLine(pos, cp);
  525. }
  526. }
  527. }
  528. #if MAGICACLOTH_DEBUG
  529. if (ClothMonitorMenu.Monitor.UI.DrawPenetrationOrigin && ccnt > 0)
  530. {
  531. cen /= ccnt;
  532. cdir /= ccnt;
  533. Gizmos.color = new Color(0.0f, 1.0f, 1.0f);
  534. Gizmos.DrawSphere(cen, 0.002f);
  535. Gizmos.color = Color.yellow;
  536. Gizmos.DrawLine(cen, cen + cdir.normalized * 0.02f);
  537. //Handles.color = Color.cyan;
  538. Handles.Label(cen, i.ToString(), style);
  539. }
  540. #endif
  541. }
  542. }
  543. #if false // 一旦休眠
  544. static void DrawBonePenetrationRuntime(
  545. PhysicsTeam team,
  546. ClothParams param,
  547. ClothData clothData,
  548. List<int> selList
  549. )
  550. {
  551. if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false)
  552. return;
  553. var mode = clothData.penetrationMode;
  554. if (mode != ClothParams.PenetrationMode.BonePenetration)
  555. return;
  556. if (clothData.penetrationDirectionDataList == null)
  557. return;
  558. for (int i = 0; i < clothData.VertexUseCount; i++)
  559. {
  560. int vindex = clothData.useVertexList[i];
  561. if (IsMove(vindex, selList) == false)
  562. continue;
  563. if (i >= clothData.penetrationDirectionDataList.Length)
  564. return;
  565. var depth = clothData.vertexDepthList[i];
  566. if (depth > param.PenetrationMaxDepth)
  567. continue;
  568. int pindex = team.ParticleChunk.startIndex + i;
  569. Vector3 bpos = MagicaPhysicsManager.Instance.Particle.basePosList[pindex];
  570. Quaternion brot = MagicaPhysicsManager.Instance.Particle.baseRotList[pindex];
  571. var ldir = clothData.penetrationDirectionDataList[i];
  572. var dir = brot * ldir;
  573. Gizmos.color = Color.blue;
  574. //Gizmos.color = GizmoUtility.ColorPenetration;
  575. Gizmos.DrawLine(bpos, bpos + dir * 0.1f);
  576. }
  577. }
  578. #endif
  579. /// <summary>
  580. /// エディタ状態での浸透制限表示
  581. /// </summary>
  582. /// <param name="team"></param>
  583. /// <param name="clothData"></param>
  584. /// <param name="posList"></param>
  585. /// <param name="selList"></param>
  586. static void DrawPenetrationClothData(
  587. PhysicsTeam team,
  588. ClothParams param,
  589. ClothData clothData,
  590. List<Vector3> posList,
  591. List<Vector3> norList,
  592. List<Vector3> tanList,
  593. List<int> selList
  594. )
  595. {
  596. if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false)
  597. return;
  598. //var mode = param.GetPenetrationMode();
  599. var mode = clothData.penetrationMode;
  600. if (clothData.penetrationDataList == null)
  601. return;
  602. if (clothData.penetrationReferenceList == null)
  603. return;
  604. var colliderlist = team.TeamData.ColliderList;
  605. for (int i = 0; i < clothData.VertexUseCount; i++)
  606. {
  607. int vindex = clothData.useVertexList[i];
  608. if (vindex >= posList.Count)
  609. continue;
  610. if (IsMove(vindex, selList) == false)
  611. continue;
  612. //Vector3 pos = posList[vindex];
  613. if (i >= clothData.penetrationReferenceList.Length)
  614. return;
  615. var refdata = clothData.penetrationReferenceList[i];
  616. for (int j = 0; j < refdata.count; j++)
  617. {
  618. var dindex = refdata.startIndex + j;
  619. var data = clothData.penetrationDataList[dindex];
  620. if (data.IsValid() == false)
  621. continue;
  622. if (mode == ClothParams.PenetrationMode.SurfacePenetration)
  623. {
  624. var pos = posList[vindex];
  625. var rot = Quaternion.LookRotation(norList[vindex], tanList[vindex]);
  626. var dir = rot * data.localDir;
  627. var depth = clothData.vertexDepthList[i];
  628. var dist = param.GetPenetrationDistance().Evaluate(depth);
  629. Gizmos.color = GizmoUtility.ColorPenetration;
  630. Gizmos.DrawLine(pos, pos + dir * dist);
  631. break;
  632. }
  633. else if (mode == ClothParams.PenetrationMode.ColliderPenetration)
  634. {
  635. int cindex = data.colliderIndex;
  636. if (cindex >= colliderlist.Count)
  637. continue;
  638. var col = colliderlist[cindex];
  639. if (col == null)
  640. continue;
  641. var cp = col.transform.TransformPoint(data.localPos);
  642. var pos = cp + col.transform.TransformDirection(data.localDir) * data.distance;
  643. Gizmos.color = GizmoUtility.ColorPenetration;
  644. Gizmos.DrawLine(pos, cp);
  645. }
  646. }
  647. }
  648. }
  649. #if false // 一旦休眠
  650. static void DrawBonePenetrationClothData(
  651. PhysicsTeam team,
  652. ClothParams param,
  653. ClothData clothData,
  654. List<Vector3> posList,
  655. List<Vector3> norList,
  656. List<Vector3> tanList,
  657. List<int> selList
  658. )
  659. {
  660. if (ClothMonitorMenu.Monitor.UI.DrawClothPenetration == false)
  661. return;
  662. var mode = clothData.penetrationMode;
  663. if (mode != ClothParams.PenetrationMode.BonePenetration)
  664. return;
  665. if (clothData.penetrationDirectionDataList == null)
  666. return;
  667. for (int i = 0; i < clothData.VertexUseCount; i++)
  668. {
  669. int vindex = clothData.useVertexList[i];
  670. if (IsMove(vindex, selList) == false)
  671. continue;
  672. if (i >= clothData.penetrationDirectionDataList.Length)
  673. return;
  674. var depth = clothData.vertexDepthList[i];
  675. if (depth > param.PenetrationMaxDepth)
  676. continue;
  677. var pos = posList[vindex];
  678. var rot = Quaternion.LookRotation(norList[vindex], tanList[vindex]);
  679. var ldir = clothData.penetrationDirectionDataList[i];
  680. var dir = rot * ldir;
  681. Gizmos.color = Color.blue;
  682. //Gizmos.color = GizmoUtility.ColorPenetration;
  683. Gizmos.DrawLine(pos, pos + dir * 0.1f);
  684. }
  685. }
  686. #endif
  687. //=========================================================================================
  688. /// <summary>
  689. /// ランタイム状態でのライン表示
  690. /// </summary>
  691. /// <param name="scr"></param>
  692. /// <param name="deformer"></param>
  693. /// <param name="clothData"></param>
  694. static void DrawLineRuntime(
  695. PhysicsTeam team,
  696. ClothData clothData,
  697. ClothSetup setup,
  698. List<int> selList
  699. )
  700. {
  701. if (ClothMonitorMenu.Monitor.UI.DrawClothStructDistanceLine)
  702. {
  703. DrawLineRuntimeSub(team, GizmoUtility.ColorStructLine, clothData.structDistanceDataList, false);
  704. }
  705. if (ClothMonitorMenu.Monitor.UI.DrawClothBendDistanceLine)
  706. {
  707. DrawLineRuntimeSub(team, GizmoUtility.ColorBendLine, clothData.bendDistanceDataList, false);
  708. }
  709. if (ClothMonitorMenu.Monitor.UI.DrawClothNearDistanceLine)
  710. {
  711. DrawLineRuntimeSub(team, GizmoUtility.ColorNearLine, clothData.nearDistanceDataList, false);
  712. }
  713. if (ClothMonitorMenu.Monitor.UI.DrawClothBase)
  714. {
  715. DrawLineRuntimeSub(team, Color.red, clothData.structDistanceDataList, true);
  716. }
  717. }
  718. static void DrawLineRuntimeSub(
  719. PhysicsTeam team,
  720. Color color,
  721. RestoreDistanceConstraint.RestoreDistanceData[] distanceDataList,
  722. bool useBase
  723. )
  724. {
  725. if (distanceDataList == null || distanceDataList.Length == 0)
  726. return;
  727. var manager = MagicaPhysicsManager.Instance;
  728. Gizmos.color = color;
  729. int cnt = distanceDataList.Length;
  730. for (int i = 0; i < cnt; i++)
  731. {
  732. var data = distanceDataList[i];
  733. int vindex0, vindex1;
  734. vindex0 = data.vertexIndex;
  735. vindex1 = data.targetVertexIndex;
  736. int pindex0 = team.ParticleChunk.startIndex + vindex0;
  737. int pindex1 = team.ParticleChunk.startIndex + vindex1;
  738. Vector3 pos0 = useBase ? manager.Particle.basePosList[pindex0] : manager.Particle.posList[pindex0];
  739. Vector3 pos1 = useBase ? manager.Particle.basePosList[pindex1] : manager.Particle.posList[pindex1];
  740. Gizmos.DrawLine(pos0, pos1);
  741. }
  742. }
  743. /// <summary>
  744. /// エディタ状態でのライン表示
  745. /// </summary>
  746. /// <param name="scr"></param>
  747. /// <param name="deformer"></param>
  748. /// <param name="clothData"></param>
  749. static void DrawLineClothData(
  750. ClothData clothData,
  751. List<Vector3> posList,
  752. List<int> selList
  753. )
  754. {
  755. if (clothData == null)
  756. return;
  757. if (ClothMonitorMenu.Monitor.UI.DrawClothStructDistanceLine)
  758. {
  759. DrawLineClothDataSub(clothData, posList, GizmoUtility.ColorStructLine, clothData.structDistanceDataList);
  760. }
  761. if (ClothMonitorMenu.Monitor.UI.DrawClothBendDistanceLine)
  762. {
  763. DrawLineClothDataSub(clothData, posList, GizmoUtility.ColorBendLine, clothData.bendDistanceDataList);
  764. }
  765. if (ClothMonitorMenu.Monitor.UI.DrawClothNearDistanceLine)
  766. {
  767. DrawLineClothDataSub(clothData, posList, GizmoUtility.ColorNearLine, clothData.nearDistanceDataList);
  768. }
  769. if (ClothMonitorMenu.Monitor.UI.DrawClothBase)
  770. {
  771. DrawLineClothDataSub(clothData, posList, Color.red, clothData.structDistanceDataList);
  772. }
  773. }
  774. static void DrawLineClothDataSub(
  775. ClothData clothData,
  776. List<Vector3> posList,
  777. Color color,
  778. RestoreDistanceConstraint.RestoreDistanceData[] distanceDataList
  779. )
  780. {
  781. if (distanceDataList == null || distanceDataList.Length == 0)
  782. return;
  783. Gizmos.color = color;
  784. int cnt = distanceDataList.Length;
  785. for (int i = 0; i < cnt; i++)
  786. {
  787. var data = distanceDataList[i];
  788. int index0, index1;
  789. index0 = data.vertexIndex;
  790. index1 = data.targetVertexIndex;
  791. int vindex0 = clothData.useVertexList[index0];
  792. int vindex1 = clothData.useVertexList[index1];
  793. if (vindex0 >= posList.Count || vindex1 >= posList.Count)
  794. continue;
  795. Vector3 pos0 = posList[vindex0];
  796. Vector3 pos1 = posList[vindex1];
  797. Gizmos.DrawLine(pos0, pos1);
  798. }
  799. }
  800. //=========================================================================================
  801. /// <summary>
  802. /// ランタイム状態での回転ライン表示
  803. /// </summary>
  804. /// <param name="scr"></param>
  805. /// <param name="deformer"></param>
  806. /// <param name="clothData"></param>
  807. static void DrawRotationLineRuntime(
  808. PhysicsTeam team,
  809. ClothData clothData,
  810. ClothSetup setup,
  811. List<int> selList
  812. )
  813. {
  814. if (ClothMonitorMenu.Monitor.UI.DrawClothRotationLine == false)
  815. return;
  816. if (clothData == null)
  817. return;
  818. if (clothData.parentList == null || clothData.parentList.Count != clothData.VertexUseCount)
  819. return;
  820. var manager = MagicaPhysicsManager.Instance;
  821. Gizmos.color = GizmoUtility.ColorRotationLine;
  822. for (int i = 0; i < clothData.VertexUseCount; i++)
  823. {
  824. int pi = clothData.parentList[i];
  825. if (pi < 0)
  826. continue;
  827. int pindex0 = team.ParticleChunk.startIndex + i;
  828. int pindex1 = team.ParticleChunk.startIndex + pi;
  829. Vector3 pos0 = manager.Particle.posList[pindex0];
  830. Vector3 pos1 = manager.Particle.posList[pindex1];
  831. Gizmos.DrawLine(pos0, pos1);
  832. }
  833. }
  834. /// <summary>
  835. /// エディタ状態での回転ライン表示
  836. /// </summary>
  837. /// <param name="scr"></param>
  838. /// <param name="deformer"></param>
  839. /// <param name="clothData"></param>
  840. static void DrawRotationLineClothData(
  841. ClothData clothData,
  842. List<Vector3> posList,
  843. List<int> selList
  844. )
  845. {
  846. if (ClothMonitorMenu.Monitor.UI.DrawClothRotationLine == false)
  847. return;
  848. if (clothData == null)
  849. return;
  850. if (clothData.parentList == null || clothData.parentList.Count != clothData.VertexUseCount)
  851. return;
  852. Gizmos.color = GizmoUtility.ColorRotationLine;
  853. for (int i = 0; i < clothData.VertexUseCount; i++)
  854. {
  855. int pi = clothData.parentList[i];
  856. if (pi < 0)
  857. continue;
  858. int vindex0 = clothData.useVertexList[i];
  859. int vindex1 = clothData.useVertexList[pi];
  860. if (vindex0 >= posList.Count || vindex1 >= posList.Count)
  861. continue;
  862. Vector3 pos0 = posList[vindex0];
  863. Vector3 pos1 = posList[vindex1];
  864. Gizmos.DrawLine(pos0, pos1);
  865. }
  866. }
  867. //=========================================================================================
  868. #if false
  869. static void DrawAdjustRotationLineRuntime(
  870. PhysicsTeam team,
  871. ClothData clothData
  872. )
  873. {
  874. if (ClothMonitorMenu.Monitor.UI.DrawAdjustRotationLine == false)
  875. return;
  876. var manager = MagicaPhysicsManager.Instance;
  877. Gizmos.color = GizmoUtility.ColorAdjustLine;
  878. int cnt = clothData.AdjustRotationConstraintCount;
  879. for (int i = 0; i < cnt; i++)
  880. {
  881. var data = clothData.adjustRotationDataList[i];
  882. int tindex = data.targetIndex;
  883. if (tindex < 0)
  884. tindex = -tindex - 1;
  885. int pindex0 = team.ParticleChunk.startIndex + data.keyIndex;
  886. int pindex1 = team.ParticleChunk.startIndex + tindex;
  887. Vector3 pos0 = manager.Particle.posList[pindex0];
  888. Vector3 pos1 = manager.Particle.posList[pindex1];
  889. Gizmos.DrawLine(pos0, pos1);
  890. }
  891. }
  892. static void DrawAdjustRotationLineClothData(
  893. ClothData clothData,
  894. List<Vector3> posList
  895. )
  896. {
  897. if (ClothMonitorMenu.Monitor.UI.DrawAdjustRotationLine == false)
  898. return;
  899. if (clothData == null)
  900. return;
  901. Gizmos.color = GizmoUtility.ColorAdjustLine;
  902. int cnt = clothData.AdjustRotationConstraintCount;
  903. for (int i = 0; i < cnt; i++)
  904. {
  905. var data = clothData.adjustRotationDataList[i];
  906. int tindex = data.targetIndex;
  907. if (tindex < 0)
  908. tindex = -tindex - 1;
  909. int vindex0 = clothData.useVertexList[data.keyIndex];
  910. int vindex1 = clothData.useVertexList[tindex];
  911. Vector3 pos0 = posList[vindex0];
  912. Vector3 pos1 = posList[vindex1];
  913. Gizmos.DrawLine(pos0, pos1);
  914. }
  915. }
  916. #endif
  917. //=========================================================================================
  918. /// <summary>
  919. /// ランタイム状態でのトライアングルベンド表示
  920. /// </summary>
  921. /// <param name="scr"></param>
  922. /// <param name="deformer"></param>
  923. /// <param name="clothData"></param>
  924. static void DrawTriangleBendRuntime(
  925. PhysicsTeam team,
  926. ClothData clothData,
  927. ClothSetup setup
  928. )
  929. {
  930. if (ClothMonitorMenu.Monitor.UI.DrawClothTriangleBend == false)
  931. return;
  932. var manager = MagicaPhysicsManager.Instance;
  933. Gizmos.color = GizmoUtility.ColorTriangle;
  934. int cnt = clothData.TriangleBendConstraintCount;
  935. for (int i = 0; i < cnt; i++)
  936. {
  937. var data = clothData.triangleBendDataList[i];
  938. int pindex0 = team.ParticleChunk.startIndex + data.vindex0;
  939. int pindex1 = team.ParticleChunk.startIndex + data.vindex1;
  940. int pindex2 = team.ParticleChunk.startIndex + data.vindex2;
  941. Vector3 pos0 = manager.Particle.posList[pindex0];
  942. Vector3 pos1 = manager.Particle.posList[pindex1];
  943. Vector3 pos2 = manager.Particle.posList[pindex2];
  944. if (data.IsPositionBend() == false)
  945. {
  946. int pindex3 = team.ParticleChunk.startIndex + data.vindex3;
  947. Vector3 pos3 = manager.Particle.posList[pindex3];
  948. Gizmos.DrawLine(pos0, pos2);
  949. Gizmos.DrawLine(pos0, pos3);
  950. Gizmos.DrawLine(pos2, pos3);
  951. Gizmos.DrawLine(pos2, pos1);
  952. Gizmos.DrawLine(pos3, pos1);
  953. }
  954. else
  955. {
  956. Gizmos.DrawLine(pos0, pos1);
  957. Gizmos.DrawLine(pos0, pos2);
  958. Gizmos.DrawLine(pos1, pos2);
  959. }
  960. }
  961. }
  962. /// <summary>
  963. /// エディタ状態でのトライアングルベンド表示
  964. /// </summary>
  965. /// <param name="scr"></param>
  966. /// <param name="deformer"></param>
  967. /// <param name="clothData"></param>
  968. static void DrawTriangleBendClothData(
  969. ClothData clothData,
  970. List<Vector3> posList
  971. )
  972. {
  973. if (ClothMonitorMenu.Monitor.UI.DrawClothTriangleBend == false)
  974. return;
  975. if (clothData == null)
  976. return;
  977. Gizmos.color = GizmoUtility.ColorTriangle;
  978. int cnt = clothData.TriangleBendConstraintCount;
  979. for (int i = 0; i < cnt; i++)
  980. {
  981. var data = clothData.triangleBendDataList[i];
  982. int vindex0 = clothData.useVertexList[data.vindex0];
  983. int vindex1 = clothData.useVertexList[data.vindex1];
  984. int vindex2 = clothData.useVertexList[data.vindex2];
  985. Vector3 pos0 = posList[vindex0];
  986. Vector3 pos1 = posList[vindex1];
  987. Vector3 pos2 = posList[vindex2];
  988. if (data.IsPositionBend() == false)
  989. {
  990. int vindex3 = clothData.useVertexList[data.vindex3];
  991. Vector3 pos3 = posList[vindex3];
  992. Gizmos.DrawLine(pos0, pos2);
  993. Gizmos.DrawLine(pos0, pos3);
  994. Gizmos.DrawLine(pos2, pos3);
  995. Gizmos.DrawLine(pos2, pos1);
  996. Gizmos.DrawLine(pos3, pos1);
  997. }
  998. else
  999. {
  1000. Gizmos.DrawLine(pos0, pos1);
  1001. Gizmos.DrawLine(pos0, pos2);
  1002. Gizmos.DrawLine(pos1, pos2);
  1003. }
  1004. }
  1005. }
  1006. //=========================================================================================
  1007. #if false
  1008. /// <summary>
  1009. /// ランタイム状態でのボリューム表示
  1010. /// </summary>
  1011. /// <param name="scr"></param>
  1012. /// <param name="deformer"></param>
  1013. /// <param name="clothData"></param>
  1014. static void DrawVolumeRuntime(
  1015. PhysicsTeam team,
  1016. ClothData clothData,
  1017. ClothSetup setup
  1018. )
  1019. {
  1020. if (ClothMonitorMenu.Monitor.UI.DrawClothVolume == false)
  1021. return;
  1022. var manager = MagicaPhysicsManager.Instance;
  1023. Gizmos.color = GizmoUtility.ColorTriangle;
  1024. int cnt = clothData.VolumeConstraintCount;
  1025. for (int i = 0; i < cnt; i++)
  1026. {
  1027. var data = clothData.volumeDataList[i];
  1028. int pindex0 = team.ParticleChunk.startIndex + data.vindex0;
  1029. int pindex1 = team.ParticleChunk.startIndex + data.vindex1;
  1030. int pindex2 = team.ParticleChunk.startIndex + data.vindex2;
  1031. int pindex3 = team.ParticleChunk.startIndex + data.vindex3;
  1032. Vector3 pos0 = manager.Particle.posList[pindex0];
  1033. Vector3 pos1 = manager.Particle.posList[pindex1];
  1034. Vector3 pos2 = manager.Particle.posList[pindex2];
  1035. Vector3 pos3 = manager.Particle.posList[pindex3];
  1036. Gizmos.DrawLine(pos0, pos1);
  1037. Gizmos.DrawLine(pos0, pos2);
  1038. Gizmos.DrawLine(pos0, pos3);
  1039. Gizmos.DrawLine(pos1, pos2);
  1040. Gizmos.DrawLine(pos2, pos3);
  1041. Gizmos.DrawLine(pos3, pos1);
  1042. }
  1043. }
  1044. /// <summary>
  1045. /// エディタ状態でのボリューム表示
  1046. /// </summary>
  1047. /// <param name="scr"></param>
  1048. /// <param name="deformer"></param>
  1049. /// <param name="clothData"></param>
  1050. static void DrawVolumeClothData(
  1051. ClothData clothData,
  1052. List<Vector3> posList
  1053. )
  1054. {
  1055. if (ClothMonitorMenu.Monitor.UI.DrawClothVolume == false)
  1056. return;
  1057. if (clothData == null)
  1058. return;
  1059. Gizmos.color = GizmoUtility.ColorTriangle;
  1060. int cnt = clothData.VolumeConstraintCount;
  1061. for (int i = 0; i < cnt; i++)
  1062. {
  1063. var data = clothData.volumeDataList[i];
  1064. int vindex0 = clothData.useVertexList[data.vindex0];
  1065. int vindex1 = clothData.useVertexList[data.vindex1];
  1066. int vindex2 = clothData.useVertexList[data.vindex2];
  1067. int vindex3 = clothData.useVertexList[data.vindex3];
  1068. Vector3 pos0 = posList[vindex0];
  1069. Vector3 pos1 = posList[vindex1];
  1070. Vector3 pos2 = posList[vindex2];
  1071. Vector3 pos3 = posList[vindex3];
  1072. Gizmos.DrawLine(pos0, pos1);
  1073. Gizmos.DrawLine(pos0, pos2);
  1074. Gizmos.DrawLine(pos0, pos3);
  1075. Gizmos.DrawLine(pos1, pos2);
  1076. Gizmos.DrawLine(pos2, pos3);
  1077. Gizmos.DrawLine(pos3, pos1);
  1078. }
  1079. }
  1080. #endif
  1081. }
  1082. }