RuntimeGizmoManager.cs 9.3 KB

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