Advertisement
Guest User

Untitled

a guest
Jun 25th, 2016
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.84 KB | None | 0 0
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections;
  4. using System;
  5.  
  6. public class MeshVisualizeWindow : EditorWindow
  7. {
  8. [MenuItem("Window/Mesh visualizer")]
  9. public static void OpenWindow()
  10. {
  11. GetWindow<MeshVisualizeWindow>().Focus();
  12. }
  13.  
  14. private Mesh selectedMesh;
  15. private Vector3[] selectedVertices, selectedNormals;
  16. private Color[] selectedColors, randomColors;
  17. private int[] selectedTriangles;
  18.  
  19. private int startVertIndex, endVertIndex, startTriIndex, endTriIndex;
  20.  
  21. private bool shouldVisualizeVertices = true, shouldVisualizeTriangles = false;
  22. private bool useVertexColors = true;
  23. private bool hasVertexColors { get { return selectedMesh.colors != null && selectedMesh.colors.Length > 0; } }
  24.  
  25. void OnEnable()
  26. {
  27. SceneView.onSceneGUIDelegate -= OnSceneGUI;
  28. SceneView.onSceneGUIDelegate += OnSceneGUI;
  29.  
  30. init();
  31. randomColors = generateColors(255);
  32. }
  33.  
  34. void OnDisable()
  35. {
  36. SceneView.onSceneGUIDelegate -= OnSceneGUI;
  37.  
  38. }
  39. void OnSelectionChange()
  40. {
  41. init();
  42. //Force to repaint UI, otherwise the new values arent visible until you interact with the window
  43. Repaint();
  44. }
  45.  
  46. //Initialises the variables for the current selection.
  47. private void init()
  48. {
  49. //Reset to default
  50. selectedMesh = null;
  51.  
  52. if (Selection.activeGameObject == null)
  53. return;
  54.  
  55. MeshFilter mFilter;
  56. SkinnedMeshRenderer mSkinRender;
  57.  
  58. if ((mFilter = Selection.activeGameObject.GetComponent<MeshFilter>()) != null)
  59. selectedMesh = mFilter.sharedMesh;
  60.  
  61. if ((mSkinRender = Selection.activeGameObject.GetComponent<SkinnedMeshRenderer>()) != null)
  62. selectedMesh = mSkinRender.sharedMesh;
  63.  
  64. if (selectedMesh == null || (selectedVertices != null && selectedMesh.vertices.Length == selectedVertices.Length))
  65. return;
  66.  
  67. selectedVertices = selectedMesh.vertices;
  68. selectedNormals = selectedMesh.normals;
  69. selectedTriangles = selectedMesh.triangles;
  70. selectedColors = validateColors(selectedMesh.colors);
  71. if (!hasVertexColors || !useVertexColors)
  72. selectedColors = generateColors(selectedVertices.Length);
  73.  
  74. startVertIndex = 0;
  75. endVertIndex = selectedVertices.Length;
  76. endTriIndex = selectedTriangles.Length / 3;
  77. }
  78.  
  79. private Color[] validateColors(Color[] colors)
  80. {
  81. for (int i = 0; i < colors.Length; i++)
  82. {
  83. if (colors[i].a < .5f)
  84. colors[i].a = 1f;
  85. }
  86.  
  87. return colors;
  88. }
  89.  
  90. private Color[] generateColors(int size)
  91. {
  92. Color[] cols = new Color[size];
  93. for (int i = 0; i < cols.Length; i++)
  94. cols[i] = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value);
  95. return cols;
  96. }
  97.  
  98.  
  99. #region GUI
  100.  
  101. void OnGUI()
  102. {
  103. if (selectedMesh == null)
  104. {
  105. EditorGUILayout.HelpBox("Please select a meshfilter or skinnedmeshrenderer!", MessageType.Error);
  106. return;
  107. }
  108.  
  109. drawGeneralGUI();
  110. EditorGUILayout.Space();
  111. drawVertexGUI();
  112. EditorGUILayout.Space();
  113. drawTriangleGUI();
  114.  
  115. if (GUI.changed)
  116. SceneView.RepaintAll();
  117. }
  118.  
  119. private void drawGeneralGUI()
  120. {
  121. EditorGUILayout.LabelField("General settings", EditorStyles.boldLabel);
  122.  
  123. EditorGUI.indentLevel++;
  124. EditorGUILayout.LabelField(string.Format("Vertex count: {0}, triangle count: {1}", selectedVertices.Length, selectedMesh.triangles.Length));
  125.  
  126. if (hasVertexColors)
  127. {
  128. useVertexColors = EditorGUILayout.Toggle("Use vertex colors", useVertexColors);
  129.  
  130. if (GUI.changed && useVertexColors)
  131. selectedColors = validateColors(selectedMesh.colors);
  132. else if (GUI.changed && !useVertexColors)
  133. selectedColors = generateColors(selectedVertices.Length);
  134. }
  135.  
  136. EditorGUI.indentLevel--;
  137. }
  138. private void drawVertexGUI()
  139. {
  140. shouldVisualizeVertices = EditorGUILayout.BeginToggleGroup("Show vertices", shouldVisualizeVertices);
  141.  
  142. EditorGUI.indentLevel++;
  143. EditorGUILayout.LabelField("Visualise from index: " + startVertIndex + " to " + endVertIndex);
  144.  
  145. //Lame, MinMaxSlider only has a float version!
  146. float tmpStart = startVertIndex, tmpEnd = endVertIndex;
  147. EditorGUILayout.MinMaxSlider(ref tmpStart, ref tmpEnd, 0, selectedVertices.Length);
  148. startVertIndex = (int)tmpStart;
  149. endVertIndex = (int)tmpEnd;
  150.  
  151. EditorGUILayout.BeginHorizontal();
  152. EditorGUILayout.LabelField("Min");
  153.  
  154. if (GUILayout.Button("-"))
  155. startVertIndex = Mathf.Clamp(startVertIndex - 1, 0, endVertIndex);
  156. if (GUILayout.Button("+"))
  157. startVertIndex = Mathf.Clamp(startVertIndex + 1, 0, endVertIndex);
  158.  
  159. EditorGUILayout.EndHorizontal();
  160.  
  161. EditorGUILayout.BeginHorizontal();
  162. EditorGUILayout.LabelField("Max");
  163.  
  164. if (GUILayout.Button("-"))
  165. endVertIndex = Mathf.Clamp(endVertIndex - 1, startVertIndex, selectedVertices.Length);
  166. if (GUILayout.Button("+"))
  167. endVertIndex = Mathf.Clamp(endVertIndex + 1, startVertIndex, selectedVertices.Length);
  168.  
  169. EditorGUILayout.EndHorizontal();
  170.  
  171. EditorGUILayout.EndToggleGroup();
  172.  
  173. EditorGUI.indentLevel--;
  174. }
  175. private void drawTriangleGUI()
  176. {
  177. shouldVisualizeTriangles = EditorGUILayout.BeginToggleGroup("Show triangles", shouldVisualizeTriangles);
  178.  
  179. EditorGUILayout.LabelField("Visualise from index: " + startTriIndex + " to " + endTriIndex);
  180. EditorGUI.indentLevel++;
  181.  
  182. //Lame, MinMaxSlider only has a float version!
  183. float tmpStart = startTriIndex, tmpEnd = endTriIndex;
  184. EditorGUILayout.MinMaxSlider(ref tmpStart, ref tmpEnd, 0, selectedTriangles.Length / 3f);
  185. startTriIndex = (int)tmpStart;
  186. endTriIndex = (int)tmpEnd;
  187.  
  188. EditorGUILayout.BeginHorizontal();
  189. EditorGUILayout.LabelField("Min");
  190.  
  191. if (GUILayout.Button("-"))
  192. startTriIndex = Mathf.Clamp(startTriIndex - 1, 0, endTriIndex);
  193. if (GUILayout.Button("+"))
  194. startTriIndex = Mathf.Clamp(startTriIndex + 1, 0, endTriIndex);
  195.  
  196. EditorGUILayout.EndHorizontal();
  197.  
  198. EditorGUILayout.BeginHorizontal();
  199. EditorGUILayout.LabelField("Max");
  200.  
  201. if (GUILayout.Button("-"))
  202. endTriIndex = Mathf.Clamp(endTriIndex - 1, startTriIndex, selectedTriangles.Length / 3);
  203. if (GUILayout.Button("+"))
  204. endTriIndex = Mathf.Clamp(endTriIndex + 1, startTriIndex, selectedTriangles.Length / 3);
  205.  
  206. EditorGUILayout.EndHorizontal();
  207.  
  208. EditorGUILayout.EndToggleGroup();
  209. EditorGUI.indentLevel--;
  210. }
  211. #endregion
  212.  
  213. #region Scene
  214. private void OnSceneGUI(SceneView sceneView)
  215. {
  216. if (selectedMesh == null || Selection.activeGameObject == null)
  217. return;
  218. //Everything we do is in local space
  219. Handles.matrix = Selection.activeGameObject.transform.localToWorldMatrix;
  220.  
  221. if (shouldVisualizeVertices)
  222. visualizeVertices();
  223.  
  224. if (shouldVisualizeTriangles)
  225. visualizeTriangles();
  226.  
  227. }
  228.  
  229. private void visualizeVertices()
  230. {
  231. for (int i = startVertIndex; i < endVertIndex; i++)
  232. {
  233. Handles.color = selectedColors[i];
  234.  
  235. DrawRay(selectedVertices[i], selectedNormals[i]);
  236. Handles.Label(selectedVertices[i] + selectedNormals[i] * 1.1f, i.ToString());
  237. }
  238. }
  239.  
  240. private void visualizeTriangles()
  241. {
  242. for (int i = startTriIndex * 3; i <= endTriIndex * 3; i += 3)
  243. {
  244. Handles.color = randomColors[i % randomColors.Length];
  245. Vector3 p1 = selectedVertices[selectedTriangles[i + 0]],
  246. p2 = selectedVertices[selectedTriangles[i + 1]],
  247. p3 = selectedVertices[selectedTriangles[i + 2]];
  248.  
  249. DrawArrow(p1, p2 - p1);
  250. DrawArrow(p2, p3 - p2);
  251. DrawArrow(p3, p1 - p3);
  252.  
  253. Handles.Label((p1 + p2 + p3) / 3f, (i / 3).ToString());
  254. }
  255.  
  256. }
  257.  
  258. //Draws an arrow in the handles. `arrowatpercent` determines where the arrow cap is, 1 means at the end 0 at the beginning
  259. static void DrawArrow(Vector3 origin, Vector3 direction, float arrowAtPercent = .8f)
  260. {
  261. DrawRay(origin, direction);
  262. DrawRay(origin + direction * arrowAtPercent, Quaternion.LookRotation(direction) * Quaternion.Euler(0, 200f, 0) * Vector3.forward * 0.25f);
  263. DrawRay(origin + direction * arrowAtPercent, Quaternion.LookRotation(direction) * Quaternion.Euler(0, 160f, 0) * Vector3.forward * 0.25f);
  264. }
  265. //Draws a line that starts at origin and ends at origin+direction
  266. static void DrawRay(Vector3 origin, Vector3 direction)
  267. {
  268. Handles.DrawLine(origin, origin + direction);
  269. }
  270.  
  271. #endregion
  272. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement