RuntimeGizmoManager.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using UnityEngine;
  5. using UnityEngine.SceneManagement;
  6. namespace Leap.Unity.RuntimeGizmos
  7. {
  8. [ExecuteInEditMode]
  9. public class RuntimeGizmoManager : MonoBehaviour
  10. {
  11. [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  12. public static event Action<RuntimeGizmoDrawer> OnPostRenderGizmos;
  13. public static bool TryGetGizmoDrawer(out RuntimeGizmoDrawer drawer)
  14. {
  15. drawer = RuntimeGizmoManager._backDrawer;
  16. if (drawer != null)
  17. {
  18. drawer.ResetMatrixAndColorState();
  19. return true;
  20. }
  21. return false;
  22. }
  23. public static bool TryGetGizmoDrawer(GameObject attatchedGameObject, out RuntimeGizmoDrawer drawer)
  24. {
  25. drawer = RuntimeGizmoManager._backDrawer;
  26. if (drawer != null && !RuntimeGizmoManager.areGizmosDisabled(attatchedGameObject.transform))
  27. {
  28. drawer.ResetMatrixAndColorState();
  29. return true;
  30. }
  31. return false;
  32. }
  33. protected virtual void OnValidate()
  34. {
  35. if (this._gizmoShader == null)
  36. {
  37. this._gizmoShader = Shader.Find("Hidden/Runtime Gizmos");
  38. }
  39. if (new Material(this._gizmoShader)
  40. {
  41. hideFlags = HideFlags.HideAndDontSave
  42. }.passCount != 4)
  43. {
  44. UnityEngine.Debug.LogError("Shader " + this._gizmoShader + " does not have 4 passes and cannot be used as a gizmo shader.");
  45. this._gizmoShader = Shader.Find("Hidden/Runtime Gizmos");
  46. }
  47. if (this._sphereMesh == null)
  48. {
  49. GameObject gameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
  50. gameObject.hideFlags = HideFlags.HideAndDontSave;
  51. this._sphereMesh = gameObject.GetComponent<MeshFilter>().sharedMesh;
  52. gameObject.GetComponent<MeshFilter>().sharedMesh = null;
  53. }
  54. if (RuntimeGizmoManager._frontDrawer != null && RuntimeGizmoManager._backDrawer != null)
  55. {
  56. this.assignDrawerParams();
  57. }
  58. }
  59. protected virtual void Reset()
  60. {
  61. this._gizmoShader = Shader.Find("Hidden/Runtime Gizmos");
  62. }
  63. protected virtual void OnEnable()
  64. {
  65. if (!this._enabledForBuild)
  66. {
  67. base.enabled = false;
  68. return;
  69. }
  70. RuntimeGizmoManager._frontDrawer = new RuntimeGizmoDrawer();
  71. RuntimeGizmoManager._backDrawer = new RuntimeGizmoDrawer();
  72. RuntimeGizmoManager._frontDrawer.BeginGuard();
  73. if (this._gizmoShader == null)
  74. {
  75. this._gizmoShader = Shader.Find("Hidden/Runtime Gizmos");
  76. }
  77. this.generateMeshes();
  78. this.assignDrawerParams();
  79. Camera.onPostRender = (Camera.CameraCallback)Delegate.Remove(Camera.onPostRender, new Camera.CameraCallback(this.onPostRender));
  80. Camera.onPostRender = (Camera.CameraCallback)Delegate.Combine(Camera.onPostRender, new Camera.CameraCallback(this.onPostRender));
  81. }
  82. protected virtual void OnDisable()
  83. {
  84. RuntimeGizmoManager._frontDrawer = null;
  85. RuntimeGizmoManager._backDrawer = null;
  86. Camera.onPostRender = (Camera.CameraCallback)Delegate.Remove(Camera.onPostRender, new Camera.CameraCallback(this.onPostRender));
  87. }
  88. protected virtual void Update()
  89. {
  90. SceneManager.GetActiveScene().GetRootGameObjects(this._objList);
  91. for (int i = 0; i < this._objList.Count; i++)
  92. {
  93. GameObject gameObject = this._objList[i];
  94. gameObject.GetComponentsInChildren<IRuntimeGizmoComponent>(false, this._gizmoList);
  95. for (int j = 0; j < this._gizmoList.Count; j++)
  96. {
  97. if (!RuntimeGizmoManager.areGizmosDisabled((this._gizmoList[j] as Component).transform))
  98. {
  99. RuntimeGizmoManager._backDrawer.ResetMatrixAndColorState();
  100. try
  101. {
  102. this._gizmoList[j].OnDrawRuntimeGizmos(RuntimeGizmoManager._backDrawer);
  103. }
  104. catch (Exception exception)
  105. {
  106. UnityEngine.Debug.LogException(exception);
  107. }
  108. }
  109. }
  110. }
  111. this._readyForSwap = true;
  112. }
  113. protected void onPostRender(Camera camera)
  114. {
  115. if (this._readyForSwap)
  116. {
  117. if (RuntimeGizmoManager.OnPostRenderGizmos != null)
  118. {
  119. RuntimeGizmoManager._backDrawer.ResetMatrixAndColorState();
  120. RuntimeGizmoManager.OnPostRenderGizmos(RuntimeGizmoManager._backDrawer);
  121. }
  122. RuntimeGizmoDrawer backDrawer = RuntimeGizmoManager._backDrawer;
  123. RuntimeGizmoManager._backDrawer = RuntimeGizmoManager._frontDrawer;
  124. RuntimeGizmoManager._frontDrawer = backDrawer;
  125. RuntimeGizmoManager._frontDrawer.BeginGuard();
  126. RuntimeGizmoManager._backDrawer.EndGuard();
  127. this._readyForSwap = false;
  128. RuntimeGizmoManager._backDrawer.ClearAllGizmos();
  129. }
  130. RuntimeGizmoManager._frontDrawer.DrawAllGizmosToScreen();
  131. }
  132. protected static bool areGizmosDisabled(Transform transform)
  133. {
  134. bool result = false;
  135. do
  136. {
  137. RuntimeGizmoToggle componentInParent = transform.GetComponentInParent<RuntimeGizmoToggle>();
  138. if (componentInParent == null)
  139. {
  140. break;
  141. }
  142. if (!componentInParent.enabled)
  143. {
  144. goto Block_2;
  145. }
  146. transform = transform.parent;
  147. }
  148. while (transform != null);
  149. return result;
  150. Block_2:
  151. result = true;
  152. return result;
  153. }
  154. private void assignDrawerParams()
  155. {
  156. if (this._gizmoShader != null)
  157. {
  158. RuntimeGizmoManager._frontDrawer.gizmoShader = this._gizmoShader;
  159. RuntimeGizmoManager._backDrawer.gizmoShader = this._gizmoShader;
  160. }
  161. RuntimeGizmoManager._frontDrawer.sphereMesh = this._sphereMesh;
  162. RuntimeGizmoManager._frontDrawer.cubeMesh = this._cubeMesh;
  163. RuntimeGizmoManager._frontDrawer.wireSphereMesh = this._wireSphereMesh;
  164. RuntimeGizmoManager._frontDrawer.wireCubeMesh = this._wireCubeMesh;
  165. RuntimeGizmoManager._backDrawer.sphereMesh = this._sphereMesh;
  166. RuntimeGizmoManager._backDrawer.cubeMesh = this._cubeMesh;
  167. RuntimeGizmoManager._backDrawer.wireSphereMesh = this._wireSphereMesh;
  168. RuntimeGizmoManager._backDrawer.wireCubeMesh = this._wireCubeMesh;
  169. }
  170. private void generateMeshes()
  171. {
  172. this._cubeMesh = new Mesh();
  173. this._cubeMesh.name = "RuntimeGizmoCube";
  174. this._cubeMesh.hideFlags = HideFlags.HideAndDontSave;
  175. List<Vector3> list = new List<Vector3>();
  176. List<int> list2 = new List<int>();
  177. Vector3[] array = new Vector3[]
  178. {
  179. Vector3.forward,
  180. Vector3.right,
  181. Vector3.up
  182. };
  183. for (int i = 0; i < 3; i++)
  184. {
  185. this.addQuad(list, list2, array[i % 3], -array[(i + 1) % 3], array[(i + 2) % 3]);
  186. this.addQuad(list, list2, -array[i % 3], array[(i + 1) % 3], array[(i + 2) % 3]);
  187. }
  188. this._cubeMesh.SetVertices(list);
  189. this._cubeMesh.SetIndices(list2.ToArray(), MeshTopology.Quads, 0);
  190. this._cubeMesh.RecalculateNormals();
  191. this._cubeMesh.RecalculateBounds();
  192. this._cubeMesh.UploadMeshData(true);
  193. this._wireCubeMesh = new Mesh();
  194. this._wireCubeMesh.name = "RuntimeWireCubeMesh";
  195. this._wireCubeMesh.hideFlags = HideFlags.HideAndDontSave;
  196. list.Clear();
  197. list2.Clear();
  198. for (int j = 1; j >= -1; j -= 2)
  199. {
  200. for (int k = 1; k >= -1; k -= 2)
  201. {
  202. for (int l = 1; l >= -1; l -= 2)
  203. {
  204. list.Add(0.5f * new Vector3((float)j, (float)k, (float)l));
  205. }
  206. }
  207. }
  208. this.addCorner(list2, 0, 1, 2, 4);
  209. this.addCorner(list2, 3, 1, 2, 7);
  210. this.addCorner(list2, 5, 1, 4, 7);
  211. this.addCorner(list2, 6, 2, 4, 7);
  212. this._wireCubeMesh.SetVertices(list);
  213. this._wireCubeMesh.SetIndices(list2.ToArray(), MeshTopology.Lines, 0);
  214. this._wireCubeMesh.RecalculateBounds();
  215. this._wireCubeMesh.UploadMeshData(true);
  216. this._wireSphereMesh = new Mesh();
  217. this._wireSphereMesh.name = "RuntimeWireSphereMesh";
  218. this._wireSphereMesh.hideFlags = HideFlags.HideAndDontSave;
  219. list.Clear();
  220. list2.Clear();
  221. int num = 96;
  222. for (int m = 0; m < 32; m++)
  223. {
  224. float f = 6.2831855f * (float)m / 32f;
  225. float num2 = 0.5f * Mathf.Cos(f);
  226. float num3 = 0.5f * Mathf.Sin(f);
  227. for (int n = 0; n < 3; n++)
  228. {
  229. list2.Add((m * 3 + n) % num);
  230. list2.Add((m * 3 + n + 3) % num);
  231. }
  232. list.Add(new Vector3(num2, num3, 0f));
  233. list.Add(new Vector3(0f, num2, num3));
  234. list.Add(new Vector3(num2, 0f, num3));
  235. }
  236. this._wireSphereMesh.SetVertices(list);
  237. this._wireSphereMesh.SetIndices(list2.ToArray(), MeshTopology.Lines, 0);
  238. this._wireSphereMesh.RecalculateBounds();
  239. this._wireSphereMesh.UploadMeshData(true);
  240. }
  241. private void addQuad(List<Vector3> verts, List<int> indexes, Vector3 normal, Vector3 axis1, Vector3 axis2)
  242. {
  243. indexes.Add(verts.Count);
  244. indexes.Add(verts.Count + 1);
  245. indexes.Add(verts.Count + 2);
  246. indexes.Add(verts.Count + 3);
  247. verts.Add(0.5f * (normal + axis1 + axis2));
  248. verts.Add(0.5f * (normal + axis1 - axis2));
  249. verts.Add(0.5f * (normal - axis1 - axis2));
  250. verts.Add(0.5f * (normal - axis1 + axis2));
  251. }
  252. private void addCorner(List<int> indexes, int a, int b, int c, int d)
  253. {
  254. indexes.Add(a);
  255. indexes.Add(b);
  256. indexes.Add(a);
  257. indexes.Add(c);
  258. indexes.Add(a);
  259. indexes.Add(d);
  260. }
  261. public const string DEFAULT_SHADER_NAME = "Hidden/Runtime Gizmos";
  262. public const int CIRCLE_RESOLUTION = 32;
  263. [Tooltip("Should the gizmos be visible in the game view.")]
  264. [SerializeField]
  265. protected bool _displayInGameView = true;
  266. [Tooltip("Should the gizmos be visible in a build.")]
  267. [SerializeField]
  268. protected bool _enabledForBuild = true;
  269. [Tooltip("The mesh to use for the filled sphere gizmo.")]
  270. [SerializeField]
  271. protected Mesh _sphereMesh;
  272. [Tooltip("The shader to use for rendering gizmos.")]
  273. [SerializeField]
  274. protected Shader _gizmoShader;
  275. protected Mesh _cubeMesh;
  276. protected Mesh _wireCubeMesh;
  277. protected Mesh _wireSphereMesh;
  278. protected static RuntimeGizmoDrawer _backDrawer;
  279. protected static RuntimeGizmoDrawer _frontDrawer;
  280. private bool _readyForSwap;
  281. private List<GameObject> _objList = new List<GameObject>();
  282. private List<IRuntimeGizmoComponent> _gizmoList = new List<IRuntimeGizmoComponent>();
  283. }
  284. }