You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
6.6 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEditor;
  6. namespace AmplifyShaderEditor
  7. {
  8. public class NodeGrid
  9. {
  10. private bool m_debugGrid = false;
  11. private const float GRID_SIZE_X = 100;
  12. private const float GRID_SIZE_Y = 100;
  13. private const float GRID_AREA_X = 1000;
  14. private const float GRID_AREA_Y = 1000;
  15. private Dictionary<int, Dictionary<int, List<ParentNode>>> m_grid;
  16. private int m_xMin = int.MaxValue;
  17. private int m_yMin = int.MaxValue;
  18. private int m_xMax = int.MinValue;
  19. private int m_yMax = int.MinValue;
  20. public NodeGrid()
  21. {
  22. m_grid = new Dictionary<int, Dictionary<int, List<ParentNode>>>();
  23. }
  24. public void AddNodeToGrid( ParentNode node )
  25. {
  26. Rect pos = node.Position;
  27. if ( Mathf.Abs( pos.width ) < 0.001f || Mathf.Abs( pos.height ) < 0.001f )
  28. {
  29. return;
  30. }
  31. float initialXf = pos.x / GRID_SIZE_X;
  32. float initialYf = pos.y / GRID_SIZE_Y;
  33. int endX = Mathf.CeilToInt( initialXf + pos.width / GRID_SIZE_X );
  34. int endY = Mathf.CeilToInt( initialYf + pos.height / GRID_SIZE_Y );
  35. int initialX = Mathf.FloorToInt( initialXf );
  36. int initialY = Mathf.FloorToInt( initialYf );
  37. if ( initialX < m_xMin )
  38. {
  39. m_xMin = initialX;
  40. }
  41. if ( initialY < m_yMin )
  42. {
  43. m_yMin = initialY;
  44. }
  45. if ( endX > m_xMax )
  46. {
  47. m_xMax = endX;
  48. }
  49. if ( endY > m_yMax )
  50. {
  51. m_yMax = endY;
  52. }
  53. for ( int x = initialX; x < endX; x += 1 )
  54. {
  55. for ( int y = initialY; y < endY; y += 1 )
  56. {
  57. if ( !m_grid.ContainsKey( x ) )
  58. {
  59. m_grid.Add( x, new Dictionary<int, List<ParentNode>>() );
  60. }
  61. if ( !m_grid[ x ].ContainsKey( y ) )
  62. {
  63. m_grid[ x ].Add( y, new List<ParentNode>() );
  64. }
  65. m_grid[ x ][ y ].Add( node );
  66. }
  67. }
  68. node.IsOnGrid = true;
  69. //DebugLimits();
  70. }
  71. public void RemoveNodeFromGrid( ParentNode node, bool useCachedPos )
  72. {
  73. Rect pos = useCachedPos ? node.CachedPos : node.Position;
  74. if ( Mathf.Abs( pos.width ) < 0.001f || Mathf.Abs( pos.height ) < 0.001f )
  75. {
  76. return;
  77. }
  78. float initialXf = pos.x / GRID_SIZE_X;
  79. float initialYf = pos.y / GRID_SIZE_Y;
  80. int endX = Mathf.CeilToInt( initialXf + pos.width / GRID_SIZE_X );
  81. int endY = Mathf.CeilToInt( initialYf + pos.height / GRID_SIZE_Y );
  82. int initialX = Mathf.FloorToInt( initialXf );
  83. int initialY = Mathf.FloorToInt( initialYf );
  84. bool testLimits = false;
  85. int xMinCount = 0;
  86. int xMaxCount = 0;
  87. int yMinCount = 0;
  88. int yMaxCount = 0;
  89. for ( int x = initialX; x < endX; x += 1 )
  90. {
  91. for ( int y = initialY; y < endY; y += 1 )
  92. {
  93. if ( m_grid.ContainsKey( x ) )
  94. {
  95. if ( m_grid[ x ].ContainsKey( y ) )
  96. {
  97. m_grid[ x ][ y ].Remove( node );
  98. node.IsOnGrid = false;
  99. if ( initialX == m_xMin && x == initialX )
  100. {
  101. testLimits = true;
  102. if ( m_grid[ x ][ y ].Count != 0 )
  103. {
  104. xMinCount += 1;
  105. }
  106. }
  107. if ( endX == m_xMax && x == endX )
  108. {
  109. testLimits = true;
  110. if ( m_grid[ x ][ y ].Count != 0 )
  111. {
  112. xMaxCount += 1;
  113. }
  114. }
  115. if ( initialY == m_yMin && y == initialY )
  116. {
  117. testLimits = true;
  118. if ( m_grid[ x ][ y ].Count != 0 )
  119. {
  120. yMinCount += 1;
  121. }
  122. }
  123. if ( endY == m_yMax && y == endY )
  124. {
  125. testLimits = true;
  126. if ( m_grid[ x ][ y ].Count != 0 )
  127. {
  128. yMaxCount += 1;
  129. }
  130. }
  131. }
  132. }
  133. }
  134. }
  135. if ( testLimits )
  136. {
  137. if ( xMinCount == 0 || xMaxCount == 0 || yMinCount == 0 || yMaxCount == 0 )
  138. {
  139. m_xMin = int.MaxValue;
  140. m_yMin = int.MaxValue;
  141. m_xMax = int.MinValue;
  142. m_yMax = int.MinValue;
  143. foreach ( KeyValuePair<int, Dictionary<int, List<ParentNode>>> entryX in m_grid )
  144. {
  145. foreach ( KeyValuePair<int, List<ParentNode>> entryY in entryX.Value )
  146. {
  147. if ( entryY.Value.Count > 0 )
  148. {
  149. if ( entryX.Key < m_xMin )
  150. {
  151. m_xMin = entryX.Key;
  152. }
  153. if ( entryY.Key < m_yMin )
  154. {
  155. m_yMin = entryY.Key;
  156. }
  157. if ( entryX.Key > m_xMax )
  158. {
  159. m_xMax = entryX.Key;
  160. }
  161. if ( entryY.Key > m_yMax )
  162. {
  163. m_yMax = entryY.Key;
  164. }
  165. }
  166. }
  167. }
  168. // The += 1 is to maintain consistence with AddNodeToGrid() ceil op on max values
  169. m_xMax += 1;
  170. m_yMax += 1;
  171. }
  172. }
  173. //DebugLimits();
  174. }
  175. public void DebugLimits()
  176. {
  177. Debug.Log( "[ " + m_xMin + " , " + m_yMin + " ] " + "[ " + m_xMax + " , " + m_yMax + " ] " );
  178. }
  179. //pos must be the transformed mouse position to local canvas coordinates
  180. public List<ParentNode> GetNodesOn( Vector2 pos )
  181. {
  182. int x = Mathf.FloorToInt( pos.x / GRID_SIZE_X );
  183. int y = Mathf.FloorToInt( pos.y / GRID_SIZE_Y );
  184. if ( m_grid.ContainsKey( x ) )
  185. {
  186. if ( m_grid[ x ].ContainsKey( y ) )
  187. {
  188. return m_grid[ x ][ y ];
  189. }
  190. }
  191. return null;
  192. }
  193. public List<ParentNode> GetNodesOn( int x, int y )
  194. {
  195. if ( m_grid.ContainsKey( x ) )
  196. {
  197. if ( m_grid[ x ].ContainsKey( y ) )
  198. {
  199. return m_grid[ x ][ y ];
  200. }
  201. }
  202. return null;
  203. }
  204. public void DrawGrid( DrawInfo drawInfo )
  205. {
  206. if ( m_debugGrid )
  207. {
  208. Handles.CircleHandleCap( 0, drawInfo.InvertedZoom * ( new Vector3( drawInfo.CameraOffset.x, drawInfo.CameraOffset.y, 0f ) ), Quaternion.identity, 5,EventType.Layout );
  209. for ( int x = -( int ) GRID_AREA_X; x < GRID_AREA_X; x += ( int ) GRID_SIZE_X )
  210. {
  211. Handles.DrawLine( drawInfo.InvertedZoom * ( new Vector3( x + drawInfo.CameraOffset.x, drawInfo.CameraOffset.y - GRID_AREA_Y, 0 ) ), drawInfo.InvertedZoom * ( new Vector3( drawInfo.CameraOffset.x + x, drawInfo.CameraOffset.y + GRID_AREA_Y, 0 ) ) );
  212. }
  213. for ( int y = -( int ) GRID_AREA_Y; y < GRID_AREA_X; y += ( int ) GRID_SIZE_Y )
  214. {
  215. Handles.DrawLine( drawInfo.InvertedZoom * ( new Vector3( drawInfo.CameraOffset.x - GRID_AREA_X, drawInfo.CameraOffset.y + y, 0 ) ), drawInfo.InvertedZoom * ( new Vector3( drawInfo.CameraOffset.x + GRID_AREA_X, drawInfo.CameraOffset.y + y, 0 ) ) );
  216. }
  217. }
  218. }
  219. public void Destroy()
  220. {
  221. foreach ( KeyValuePair<int, Dictionary<int, List<ParentNode>>> entryX in m_grid )
  222. {
  223. foreach ( KeyValuePair<int, List<ParentNode>> entryY in entryX.Value )
  224. {
  225. entryY.Value.Clear();
  226. }
  227. entryX.Value.Clear();
  228. }
  229. m_grid.Clear();
  230. }
  231. public float MaxNodeDist
  232. {
  233. get { return Mathf.Max( ( m_xMax - m_xMin )*GRID_SIZE_X, ( m_yMax - m_yMin )*GRID_SIZE_Y ); }
  234. }
  235. }
  236. }