GraphGizmoHelper.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using UnityEngine;
  2. namespace Pathfinding.Util {
  3. public class GraphGizmoHelper : IAstarPooledObject, System.IDisposable {
  4. public RetainedGizmos.Hasher hasher { get; private set; }
  5. Pathfinding.Util.RetainedGizmos gizmos;
  6. PathHandler debugData;
  7. ushort debugPathID;
  8. GraphDebugMode debugMode;
  9. bool showSearchTree;
  10. float debugFloor;
  11. float debugRoof;
  12. public RetainedGizmos.Builder builder { get; private set; }
  13. Vector3 drawConnectionStart;
  14. Color drawConnectionColor;
  15. readonly System.Action<GraphNode> drawConnection;
  16. public GraphGizmoHelper () {
  17. // Cache a delegate to avoid allocating memory for it every time
  18. drawConnection = DrawConnection;
  19. }
  20. public void Init (AstarPath active, RetainedGizmos.Hasher hasher, RetainedGizmos gizmos) {
  21. if (active != null) {
  22. debugData = active.debugPathData;
  23. debugPathID = active.debugPathID;
  24. debugMode = active.debugMode;
  25. debugFloor = active.debugFloor;
  26. debugRoof = active.debugRoof;
  27. showSearchTree = active.showSearchTree && debugData != null;
  28. }
  29. this.gizmos = gizmos;
  30. this.hasher = hasher;
  31. builder = ObjectPool<RetainedGizmos.Builder>.Claim();
  32. }
  33. public void OnEnterPool () {
  34. // Will cause pretty much all calls to throw null ref exceptions until Init is called
  35. var bld = builder;
  36. ObjectPool<RetainedGizmos.Builder>.Release(ref bld);
  37. builder = null;
  38. debugData = null;
  39. }
  40. public void DrawConnections (GraphNode node) {
  41. if (showSearchTree) {
  42. if (InSearchTree(node, debugData, debugPathID)) {
  43. var pnode = debugData.GetPathNode(node);
  44. if (pnode.parent != null) {
  45. builder.DrawLine((Vector3)node.position, (Vector3)debugData.GetPathNode(node).parent.node.position, NodeColor(node));
  46. }
  47. }
  48. } else {
  49. // Calculate which color to use for drawing the node
  50. // based on the settings specified in the editor
  51. drawConnectionColor = NodeColor(node);
  52. // Get the node position
  53. // Cast it here to avoid doing it for every neighbour
  54. drawConnectionStart = (Vector3)node.position;
  55. node.GetConnections(drawConnection);
  56. }
  57. }
  58. void DrawConnection (GraphNode other) {
  59. builder.DrawLine(drawConnectionStart, Vector3.Lerp((Vector3)other.position, drawConnectionStart, 0.5f), drawConnectionColor);
  60. }
  61. /// <summary>
  62. /// Color to use for gizmos.
  63. /// Returns a color to be used for the specified node with the current debug settings (editor only).
  64. ///
  65. /// Version: Since 3.6.1 this method will not handle null nodes
  66. /// </summary>
  67. public Color NodeColor (GraphNode node) {
  68. if (showSearchTree && !InSearchTree(node, debugData, debugPathID)) return Color.clear;
  69. Color color;
  70. if (node.Walkable) {
  71. switch (debugMode) {
  72. case GraphDebugMode.Areas:
  73. color = AstarColor.GetAreaColor(node.Area);
  74. break;
  75. case GraphDebugMode.HierarchicalNode:
  76. color = AstarColor.GetTagColor((uint)node.HierarchicalNodeIndex);
  77. break;
  78. case GraphDebugMode.Penalty:
  79. color = Color.Lerp(AstarColor.ConnectionLowLerp, AstarColor.ConnectionHighLerp, ((float)node.Penalty-debugFloor) / (debugRoof-debugFloor));
  80. break;
  81. case GraphDebugMode.Tags:
  82. color = AstarColor.GetTagColor(node.Tag);
  83. break;
  84. case GraphDebugMode.SolidColor:
  85. color = AstarColor.SolidColor;
  86. break;
  87. default:
  88. if (debugData == null) {
  89. color = AstarColor.SolidColor;
  90. break;
  91. }
  92. PathNode pathNode = debugData.GetPathNode(node);
  93. float value;
  94. if (debugMode == GraphDebugMode.G) {
  95. value = pathNode.G;
  96. } else if (debugMode == GraphDebugMode.H) {
  97. value = pathNode.H;
  98. } else {
  99. // mode == F
  100. value = pathNode.F;
  101. }
  102. color = Color.Lerp(AstarColor.ConnectionLowLerp, AstarColor.ConnectionHighLerp, (value-debugFloor) / (debugRoof-debugFloor));
  103. break;
  104. }
  105. } else {
  106. color = AstarColor.UnwalkableNode;
  107. }
  108. return color;
  109. }
  110. /// <summary>
  111. /// Returns if the node is in the search tree of the path.
  112. /// Only guaranteed to be correct if path is the latest path calculated.
  113. /// Use for gizmo drawing only.
  114. /// </summary>
  115. public static bool InSearchTree (GraphNode node, PathHandler handler, ushort pathID) {
  116. return handler.GetPathNode(node).pathID == pathID;
  117. }
  118. public void DrawWireTriangle (Vector3 a, Vector3 b, Vector3 c, Color color) {
  119. builder.DrawLine(a, b, color);
  120. builder.DrawLine(b, c, color);
  121. builder.DrawLine(c, a, color);
  122. }
  123. public void DrawTriangles (Vector3[] vertices, Color[] colors, int numTriangles) {
  124. var triangles = ListPool<int>.Claim(numTriangles);
  125. for (int i = 0; i < numTriangles*3; i++) triangles.Add(i);
  126. builder.DrawMesh(gizmos, vertices, triangles, colors);
  127. ListPool<int>.Release(ref triangles);
  128. }
  129. public void DrawWireTriangles (Vector3[] vertices, Color[] colors, int numTriangles) {
  130. for (int i = 0; i < numTriangles; i++) {
  131. DrawWireTriangle(vertices[i*3+0], vertices[i*3+1], vertices[i*3+2], colors[i*3+0]);
  132. }
  133. }
  134. public void Submit () {
  135. builder.Submit(gizmos, hasher);
  136. }
  137. void System.IDisposable.Dispose () {
  138. var tmp = this;
  139. Submit();
  140. ObjectPool<GraphGizmoHelper>.Release(ref tmp);
  141. }
  142. }
  143. }