DeformerGizmoDrawer.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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. /// Deformerのギズモ表示
  11. /// </summary>
  12. public class DeformerGizmoDrawer
  13. {
  14. //=========================================================================================
  15. /// <summary>
  16. /// デフォーマーギズモの表示
  17. /// </summary>
  18. /// <param name="editorMesh"></param>
  19. /// <param name="meshData">nullの場合はすべての頂点を表示</param>
  20. /// <param name="clothSelection"></param>
  21. /// <param name="size"></param>
  22. public static void DrawDeformerGizmo(
  23. IEditorMesh editorMesh,
  24. IEditorCloth editorCloth,
  25. float size = 0.005f
  26. )
  27. {
  28. if (ClothMonitorMenu.Monitor == null)
  29. return;
  30. if (ClothMonitorMenu.Monitor.UI.DrawDeformer == false)
  31. return;
  32. if (ClothMonitorMenu.Monitor.UI.DrawDeformerVertexPosition == false
  33. && ClothMonitorMenu.Monitor.UI.DrawDeformerTriangle == false
  34. && ClothMonitorMenu.Monitor.UI.DrawDeformerLine == false
  35. && ClothMonitorMenu.Monitor.UI.DrawDeformerVertexAxis == false
  36. #if MAGICACLOTH_DEBUG
  37. && ClothMonitorMenu.Monitor.UI.DrawDeformerVertexNumber == false
  38. && ClothMonitorMenu.Monitor.UI.DrawDeformerTriangleNormal == false
  39. #endif
  40. )
  41. return;
  42. // メッシュ頂点法線接線
  43. List<Vector3> posList;
  44. List<Vector3> norList;
  45. List<Vector3> tanList;
  46. int vcnt = editorMesh.GetEditorPositionNormalTangent(out posList, out norList, out tanList);
  47. if (posList.Count == 0)
  48. return;
  49. // 頂点使用状態
  50. List<int> useList = null;
  51. List<int> selList = null;
  52. if (editorCloth != null)
  53. {
  54. useList = editorCloth.GetUseList();
  55. selList = editorCloth.GetSelectionList();
  56. }
  57. // 頂点
  58. DrawVertex(vcnt, posList, norList, tanList, useList, selList, size);
  59. // トライアングル
  60. DrawTriangle(editorMesh, posList, norList, tanList, useList);
  61. // ライン
  62. DrawLine(editorMesh, posList, norList, tanList, useList);
  63. }
  64. //=========================================================================================
  65. /// <summary>
  66. /// 頂点情報の表示
  67. /// </summary>
  68. /// <param name="editorMesh"></param>
  69. /// <param name="meshData"></param>
  70. /// <param name="clothSelection"></param>
  71. /// <param name="size"></param>
  72. static void DrawVertex(
  73. int vcnt,
  74. List<Vector3> posList,
  75. List<Vector3> norList,
  76. List<Vector3> tanList,
  77. List<int> useList,
  78. List<int> selList,
  79. float size
  80. )
  81. {
  82. bool position = ClothMonitorMenu.Monitor.UI.DrawDeformerVertexPosition;
  83. bool axis = ClothMonitorMenu.Monitor.UI.DrawDeformerVertexAxis;
  84. #if MAGICACLOTH_DEBUG
  85. bool number = ClothMonitorMenu.Monitor.UI.DrawDeformerVertexNumber;
  86. if (position == false && axis == false && number == false)
  87. return;
  88. #else
  89. if (position == false && axis == false)
  90. return;
  91. #endif
  92. #if MAGICACLOTH_DEBUG
  93. float radius = -1;
  94. Vector3 center = Vector3.zero;
  95. if (ClothMonitorMenu.Monitor.UI.DebugDrawDeformerVertexNumber >= 0)
  96. {
  97. int vindex = ClothMonitorMenu.Monitor.UI.DebugDrawDeformerVertexNumber;
  98. if (vindex >= 0 && vindex < vcnt)
  99. {
  100. center = posList[vindex];
  101. radius = 0.05f;
  102. }
  103. }
  104. #endif
  105. bool hasNormal = norList.Count > 0;
  106. bool hasTangent = tanList.Count > 0;
  107. for (int i = 0; i < vcnt; i++)
  108. {
  109. // 使用頂点のみ
  110. if (useList != null && vcnt <= useList.Count && useList[i] == 0)
  111. continue;
  112. Vector3 pos = posList[i];
  113. // 表示範囲
  114. #if MAGICACLOTH_DEBUG
  115. // 表示半径判定
  116. if (radius > 0 && Vector3.Distance(pos, center) > radius)
  117. continue;
  118. #endif
  119. if (position)
  120. {
  121. Gizmos.color = GetVertexColor(selList, i);
  122. Gizmos.DrawSphere(pos, size);
  123. }
  124. if (axis && (hasNormal || hasTangent))
  125. {
  126. const float axisSize = 0.03f;
  127. if (hasNormal)
  128. {
  129. Vector3 nor = norList[i];
  130. Gizmos.color = Color.blue;
  131. Gizmos.DrawLine(pos, pos + nor * axisSize);
  132. }
  133. if (hasTangent)
  134. {
  135. Vector3 tan = tanList[i];
  136. Gizmos.color = Color.green;
  137. Gizmos.DrawLine(pos, pos + tan * axisSize);
  138. }
  139. if (hasNormal && hasTangent)
  140. {
  141. Vector3 nor = norList[i];
  142. Vector3 tan = tanList[i];
  143. Vector3 bin = Vector3.Cross(tan, nor).normalized;
  144. Gizmos.color = Color.red;
  145. Gizmos.DrawLine(pos, pos + bin * axisSize);
  146. }
  147. }
  148. #if MAGICACLOTH_DEBUG
  149. if (number)
  150. {
  151. Handles.Label(pos, i.ToString());
  152. }
  153. #endif
  154. }
  155. }
  156. private static Color GetVertexColor(List<int> selList, int vindex)
  157. {
  158. if (selList == null || vindex >= selList.Count)
  159. return GizmoUtility.ColorDeformerPoint;
  160. if (selList[vindex] == SelectionData.Move)
  161. return Color.green;
  162. if (selList[vindex] == SelectionData.Fixed)
  163. return Color.red;
  164. return GizmoUtility.ColorDeformerPoint;
  165. }
  166. //=========================================================================================
  167. /// <summary>
  168. /// トライアングル情報の表示
  169. /// </summary>
  170. /// <param name="editorMesh"></param>
  171. static void DrawTriangle(
  172. IEditorMesh editorMesh,
  173. List<Vector3> posList,
  174. List<Vector3> norList,
  175. List<Vector3> tanList,
  176. List<int> useList
  177. )
  178. {
  179. bool drawTriangle = ClothMonitorMenu.Monitor.UI.DrawDeformerTriangle;
  180. #if MAGICACLOTH_DEBUG
  181. bool drawNormal = ClothMonitorMenu.Monitor.UI.DrawDeformerTriangleNormal;
  182. bool drawNumber = ClothMonitorMenu.Monitor.UI.DrawDeformerTriangleNumber;
  183. #else
  184. bool drawNormal = false;
  185. bool drawNumber = false;
  186. #endif
  187. if (!drawTriangle && !drawNormal && !drawNumber)
  188. return;
  189. var triangles = editorMesh.GetEditorTriangleList();
  190. if (triangles == null || triangles.Count == 0)
  191. return;
  192. //Gizmos.color = GizmoUtility.ColorTriangle;
  193. int tcnt = triangles.Count / 3;
  194. // 表示半径
  195. float radius = -1;
  196. Vector3 center = Vector3.zero;
  197. #if MAGICACLOTH_DEBUG
  198. if (ClothMonitorMenu.Monitor.UI.DebugDrawDeformerTriangleNumber >= 0)
  199. {
  200. int tindex = ClothMonitorMenu.Monitor.UI.DebugDrawDeformerTriangleNumber;
  201. if (tindex >= 0 && tindex < tcnt)
  202. {
  203. int index = tindex * 3;
  204. int i0 = triangles[index];
  205. int i1 = triangles[index + 1];
  206. int i2 = triangles[index + 2];
  207. Vector3 pos0 = posList[i0];
  208. Vector3 pos1 = posList[i1];
  209. Vector3 pos2 = posList[i2];
  210. center = (pos0 + pos1 + pos2) / 3.0f;
  211. radius = 0.05f;
  212. }
  213. }
  214. #endif
  215. // 表示
  216. for (int tindex = 0; tindex < tcnt; tindex++)
  217. {
  218. DrawTriangle1(tindex, triangles, posList, useList, center, radius, drawTriangle, drawNormal, drawNumber);
  219. }
  220. }
  221. /// <summary>
  222. /// トライアングル1つ表示
  223. /// </summary>
  224. /// <param name="tindex"></param>
  225. /// <param name="triangles"></param>
  226. /// <param name="posList"></param>
  227. /// <param name="useList"></param>
  228. /// <param name="center"></param>
  229. /// <param name="radius"></param>
  230. /// <param name="drawTriangle"></param>
  231. /// <param name="drawNormal"></param>
  232. /// <param name="drawNumber"></param>
  233. static void DrawTriangle1(
  234. int tindex, List<int> triangles, List<Vector3> posList, List<int> useList,
  235. Vector3 center, float radius,
  236. bool drawTriangle, bool drawNormal, bool drawNumber
  237. )
  238. {
  239. int index = tindex * 3;
  240. int i0 = triangles[index];
  241. int i1 = triangles[index + 1];
  242. int i2 = triangles[index + 2];
  243. // 使用頂点のみ
  244. if (useList != null)
  245. {
  246. if (useList[i0] == 0 || useList[i1] == 0 || useList[i2] == 0)
  247. return;
  248. }
  249. Vector3 pos0 = posList[i0];
  250. Vector3 pos1 = posList[i1];
  251. Vector3 pos2 = posList[i2];
  252. var pos = (pos0 + pos1 + pos2) / 3.0f;
  253. // 表示半径判定
  254. if (radius > 0 && Vector3.Distance(pos, center) > radius)
  255. return;
  256. if (drawTriangle)
  257. {
  258. Gizmos.color = GizmoUtility.ColorTriangle;
  259. Gizmos.DrawLine(pos0, pos1);
  260. Gizmos.DrawLine(pos0, pos2);
  261. Gizmos.DrawLine(pos1, pos2);
  262. }
  263. if (drawNormal)
  264. {
  265. var vn1 = pos1 - pos0;
  266. var vn2 = pos2 - pos0;
  267. var nor = Vector3.Cross(vn1, vn2).normalized;
  268. Gizmos.color = Color.blue;
  269. Gizmos.DrawLine(pos, pos + nor * 0.02f);
  270. }
  271. if (drawNumber)
  272. {
  273. Handles.Label(pos, tindex.ToString());
  274. }
  275. }
  276. //=========================================================================================
  277. /// <summary>
  278. /// ライン情報の表示
  279. /// </summary>
  280. /// <param name="editorMesh"></param>
  281. static void DrawLine(
  282. IEditorMesh editorMesh,
  283. List<Vector3> posList,
  284. List<Vector3> norList,
  285. List<Vector3> tanList,
  286. List<int> useList
  287. )
  288. {
  289. if (ClothMonitorMenu.Monitor.UI.DrawDeformerLine == false)
  290. return;
  291. var lines = editorMesh.GetEditorLineList();
  292. if (lines == null || lines.Count == 0)
  293. return;
  294. Gizmos.color = GizmoUtility.ColorStructLine;
  295. int lcnt = lines.Count / 2;
  296. for (int i = 0; i < lcnt; i++)
  297. {
  298. int index = i * 2;
  299. int i0 = lines[index];
  300. int i1 = lines[index + 1];
  301. // 利用頂点のみ
  302. if (useList != null)
  303. {
  304. if (i0 >= useList.Count || i1 >= useList.Count)
  305. continue;
  306. if (useList[i0] == 0 || useList[i1] == 0)
  307. continue;
  308. }
  309. if (i0 >= posList.Count || i1 >= posList.Count)
  310. continue;
  311. Vector3 pos0 = posList[i0];
  312. Vector3 pos1 = posList[i1];
  313. Gizmos.DrawLine(pos0, pos1);
  314. }
  315. }
  316. }
  317. }