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.

316 lines
9.8 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System;
  6. using System.Collections.Generic;
  7. namespace AmplifyShaderEditor
  8. {
  9. [Serializable]
  10. [NodeAttributes( "Register Local Var", "Miscellaneous", "Forces a local variable to be written with the given name. Can then be fetched at any place with a <b>Get Local Var</b> node.", null, KeyCode.R )]
  11. public sealed class RegisterLocalVarNode : ParentNode
  12. {
  13. private const string LocalDefaultNameStr = "myVarName";
  14. private const string LocalVarNameStr = "Var Name";
  15. private const string OrderIndexStr = "Order Index";
  16. private const string AutoOrderIndexStr = "Auto Order";
  17. private const string ReferencesStr = "References";
  18. private const string GetLocalVarLabel = "( {0} ) Get Local Var";
  19. private string m_oldName = string.Empty;
  20. private bool m_reRegisterName = false;
  21. private int m_autoOrderIndex = int.MaxValue;
  22. private bool m_forceUpdate = true;
  23. private bool m_refSelect = false;
  24. private bool m_referencesVisible = false;
  25. [SerializeField]
  26. private string m_variableName = LocalDefaultNameStr;
  27. [SerializeField]
  28. private int m_orderIndex = -1;
  29. [SerializeField]
  30. private bool m_autoIndexActive = true;
  31. [SerializeField]
  32. private List<GetLocalVarNode> m_registeredGetLocalVars = new List<GetLocalVarNode>();
  33. protected override void CommonInit( int uniqueId )
  34. {
  35. base.CommonInit( uniqueId );
  36. AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue );
  37. AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
  38. m_textLabelWidth = 85;
  39. if( m_containerGraph != null )
  40. m_variableName += m_containerGraph.LocalVarNodes.NodesList.Count;
  41. m_oldName = m_variableName;
  42. UpdateTitle();
  43. m_previewShaderGUID = "5aaa1d3ea9e1fa64781647e035a82334";
  44. }
  45. protected override void OnUniqueIDAssigned()
  46. {
  47. base.OnUniqueIDAssigned();
  48. m_containerGraph.LocalVarNodes.AddNode( this );
  49. }
  50. public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
  51. {
  52. base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode );
  53. m_inputPorts[ 0 ].MatchPortToConnection();
  54. m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false );
  55. }
  56. public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
  57. {
  58. base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type );
  59. m_inputPorts[ 0 ].MatchPortToConnection();
  60. m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false );
  61. }
  62. void UpdateTitle()
  63. {
  64. SetAdditonalTitleText( string.Format( Constants.SubTitleVarNameFormatStr, m_variableName ) );
  65. }
  66. void DrawMainProperties()
  67. {
  68. EditorGUI.BeginChangeCheck();
  69. m_variableName = EditorGUILayoutTextField( LocalVarNameStr, m_variableName );
  70. if( EditorGUI.EndChangeCheck() )
  71. {
  72. CheckAndChangeName();
  73. }
  74. DrawPrecisionProperty();
  75. }
  76. public override void AfterDuplication()
  77. {
  78. base.AfterDuplication();
  79. CheckAndChangeName();
  80. }
  81. void CheckAndChangeName()
  82. {
  83. m_variableName = UIUtils.RemoveInvalidCharacters( m_variableName );
  84. if( string.IsNullOrEmpty( m_variableName ) )
  85. {
  86. m_variableName = LocalDefaultNameStr + OutputId;
  87. }
  88. bool isNumericName = UIUtils.IsNumericName( m_variableName );
  89. if( !isNumericName && m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.IsLocalvariableNameAvailable( m_variableName ) )
  90. {
  91. m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.ReleaseLocalVariableName( UniqueId, m_oldName );
  92. m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.RegisterLocalVariableName( UniqueId, m_variableName );
  93. m_oldName = m_variableName;
  94. m_containerGraph.LocalVarNodes.UpdateDataOnNode( UniqueId, m_variableName );
  95. UpdateTitle();
  96. m_forceUpdate = true;
  97. }
  98. else
  99. {
  100. //if( isNumericName )
  101. //{
  102. // UIUtils.ShowMessage( "Local variable name cannot start or be numerical values" );
  103. //}
  104. m_variableName = m_oldName;
  105. m_containerGraph.LocalVarNodes.UpdateDataOnNode( UniqueId, m_variableName );
  106. }
  107. }
  108. void DrawReferences()
  109. {
  110. int count = m_registeredGetLocalVars.Count;
  111. if( m_registeredGetLocalVars.Count > 0 )
  112. {
  113. for( int i = 0; i < count; i++ )
  114. {
  115. EditorGUILayout.BeginHorizontal();
  116. EditorGUILayout.LabelField( string.Format( GetLocalVarLabel, m_registeredGetLocalVars[ i ].UniqueId ) );
  117. if( GUILayout.Button( "\u25BA", "minibutton", GUILayout.Width( 17 ) ) )
  118. {
  119. m_containerGraph.ParentWindow.FocusOnNode( m_registeredGetLocalVars[ i ], 0, false );
  120. }
  121. EditorGUILayout.EndHorizontal();
  122. }
  123. if( GUILayout.Button( "Back" ) )
  124. {
  125. m_containerGraph.ParentWindow.FocusOnNode( this, 0, false );
  126. }
  127. }
  128. else
  129. {
  130. EditorGUILayout.HelpBox( "This node is not being referenced by any Get Local Var.", MessageType.Info );
  131. }
  132. }
  133. public override void DrawProperties()
  134. {
  135. NodeUtils.DrawPropertyGroup( ref m_propertiesFoldout, Constants.ParameterLabelStr, DrawMainProperties );
  136. NodeUtils.DrawPropertyGroup( ref m_referencesVisible, ReferencesStr, DrawReferences );
  137. //EditorGUILayout.LabelField(ConnStatus.ToString()+" "+m_activeConnections);
  138. }
  139. public override void OnEnable()
  140. {
  141. base.OnEnable();
  142. m_reRegisterName = true;
  143. }
  144. public void CheckReferenceSelection()
  145. {
  146. m_refSelect = false;
  147. int count = m_registeredGetLocalVars.Count;
  148. for( int i = 0; i < count; i++ )
  149. {
  150. if( m_registeredGetLocalVars[ i ].Selected )
  151. m_refSelect = true;
  152. }
  153. }
  154. public override void OnNodeRepaint( DrawInfo drawInfo )
  155. {
  156. base.OnNodeRepaint( drawInfo );
  157. if( m_isVisible && m_refSelect && !m_selected )
  158. {
  159. GUI.color = Constants.SpecialRegisterLocalVarSelectionColor;
  160. GUI.Label( m_globalPosition, string.Empty, UIUtils.GetCustomStyle( CustomStyle.NodeWindowOn ) );
  161. GUI.color = m_colorBuffer;
  162. }
  163. }
  164. public override void Draw( DrawInfo drawInfo )
  165. {
  166. base.Draw( drawInfo );
  167. if( m_reRegisterName )
  168. {
  169. m_reRegisterName = false;
  170. m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.RegisterLocalVariableName( UniqueId, m_variableName );
  171. }
  172. if( m_forceUpdate )
  173. {
  174. m_forceUpdate = false;
  175. UpdateTitle();
  176. }
  177. }
  178. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  179. {
  180. if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
  181. {
  182. return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
  183. }
  184. string result = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
  185. RegisterLocalVariable( 0, result, ref dataCollector, m_variableName + OutputId );
  186. return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
  187. }
  188. public override void ReadFromString( ref string[] nodeParams )
  189. {
  190. base.ReadFromString( ref nodeParams );
  191. m_variableName = GetCurrentParam( ref nodeParams );
  192. if( UIUtils.CurrentShaderVersion() > 14 )
  193. m_orderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  194. if( UIUtils.CurrentShaderVersion() > 3106 )
  195. {
  196. m_autoIndexActive = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
  197. }
  198. else
  199. {
  200. m_autoIndexActive = false;
  201. }
  202. if( !m_isNodeBeingCopied )
  203. {
  204. m_containerGraph.LocalVarNodes.UpdateDataOnNode( UniqueId, m_variableName );
  205. m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.ReleaseLocalVariableName( UniqueId, m_oldName );
  206. m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.RegisterLocalVariableName( UniqueId, m_variableName );
  207. }
  208. m_forceUpdate = true;
  209. }
  210. public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  211. {
  212. base.WriteToString( ref nodeInfo, ref connectionsInfo );
  213. IOUtils.AddFieldValueToString( ref nodeInfo, m_variableName );
  214. IOUtils.AddFieldValueToString( ref nodeInfo, m_orderIndex );
  215. IOUtils.AddFieldValueToString( ref nodeInfo, m_autoIndexActive );
  216. }
  217. public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector )
  218. {
  219. if( m_autoOrderIndex < nodeData.OrderIndex )
  220. {
  221. nodeData.OrderIndex = m_autoOrderIndex - 1;
  222. }
  223. else
  224. {
  225. m_autoOrderIndex = nodeData.OrderIndex;
  226. nodeData.OrderIndex -= 1;
  227. }
  228. base.PropagateNodeData( nodeData, ref dataCollector );
  229. }
  230. public override void ResetNodeData()
  231. {
  232. base.ResetNodeData();
  233. m_autoOrderIndex = int.MaxValue;
  234. }
  235. public void RegisterGetLocalVar( GetLocalVarNode node )
  236. {
  237. if( !m_registeredGetLocalVars.Contains( node ) )
  238. {
  239. m_registeredGetLocalVars.Add( node );
  240. CheckReferenceSelection();
  241. }
  242. }
  243. public void UnregisterGetLocalVar( GetLocalVarNode node )
  244. {
  245. if( m_registeredGetLocalVars.Contains( node ) )
  246. {
  247. m_registeredGetLocalVars.Remove( node );
  248. CheckReferenceSelection();
  249. }
  250. }
  251. public override void Destroy()
  252. {
  253. base.Destroy();
  254. m_containerGraph.LocalVarNodes.RemoveNode( this );
  255. m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.ReleaseLocalVariableName( UniqueId, m_variableName );
  256. int count = m_registeredGetLocalVars.Count;
  257. for( int i = 0; i < count; i++ )
  258. {
  259. //GetLocalVarNode node = m_containerGraph.GetNode( m_registeredGetLocalVars[ i ] ) as GetLocalVarNode;
  260. if( m_registeredGetLocalVars[ i ] != null )
  261. m_registeredGetLocalVars[ i ].ResetReference();
  262. }
  263. m_registeredGetLocalVars.Clear();
  264. m_registeredGetLocalVars = null;
  265. m_containerGraph.LocalVarNodes.RemoveNode( this );
  266. }
  267. public override void ActivateNode( int signalGenNodeId, int signalGenPortId, Type signalGenNodeType )
  268. {
  269. base.ActivateNode( signalGenNodeId, signalGenPortId, signalGenNodeType );
  270. }
  271. public override string DataToArray { get { return m_variableName; } }
  272. public List<GetLocalVarNode> NodeReferences { get { return m_registeredGetLocalVars; } }
  273. }
  274. }