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.

297 lines
10 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using UnityEngine;
  4. using System;
  5. //using System.Collections.Generic;
  6. //using UnityEditor;
  7. namespace AmplifyShaderEditor
  8. {
  9. [Serializable]
  10. [NodeAttributes( "If", "Logical Operators", "Conditional comparison between A with B." )]
  11. public sealed class ConditionalIfNode : ParentNode
  12. {
  13. private const string UseUnityBranchesStr = "Dynamic Branching";
  14. private const string UnityBranchStr = "UNITY_BRANCH ";
  15. private readonly string[] IfOps = { "if( {0} > {1} )",
  16. "if( {0} == {1} )",
  17. "if( {0} < {1} )",
  18. "if( {0} >= {1} )",
  19. "if( {0} <= {1} )",
  20. "if( {0} != {1} )" };
  21. //private WirePortDataType m_inputMainDataType = WirePortDataType.FLOAT;
  22. private WirePortDataType m_outputMainDataType = WirePortDataType.FLOAT;
  23. private string[] m_results = { string.Empty, string.Empty, string.Empty };
  24. [SerializeField]
  25. private bool m_useUnityBranch = false;
  26. protected override void CommonInit( int uniqueId )
  27. {
  28. base.CommonInit( uniqueId );
  29. AddInputPort( WirePortDataType.FLOAT, false, "A" );
  30. AddInputPort( WirePortDataType.FLOAT, false, "B" );
  31. m_inputPorts[ 0 ].AddPortRestrictions( WirePortDataType.FLOAT, WirePortDataType.INT );
  32. m_inputPorts[ 1 ].AddPortRestrictions( WirePortDataType.FLOAT, WirePortDataType.INT );
  33. AddInputPort( WirePortDataType.FLOAT, false, "A > B" );
  34. AddInputPort( WirePortDataType.FLOAT, false, "A == B" );
  35. AddInputPort( WirePortDataType.FLOAT, false, "A < B" );
  36. AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
  37. m_inputPorts[ 0 ].AutoDrawInternalData = true;
  38. m_inputPorts[ 1 ].AutoDrawInternalData = true;
  39. m_textLabelWidth = 131;
  40. //m_useInternalPortData = true;
  41. m_autoWrapProperties = true;
  42. m_previewShaderGUID = "f6fb4d46bddf29e45a8a3ddfed75d0c0";
  43. }
  44. public override void OnConnectedOutputNodeChanges( int inputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
  45. {
  46. base.OnConnectedOutputNodeChanges( inputPortId, otherNodeId, otherPortId, name, type );
  47. UpdateConnection( inputPortId );
  48. }
  49. public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
  50. {
  51. base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode );
  52. UpdateConnection( portId );
  53. }
  54. public override void DrawProperties()
  55. {
  56. base.DrawProperties();
  57. if( !m_inputPorts[ 0 ].IsConnected )
  58. m_inputPorts[ 0 ].FloatInternalData = EditorGUILayoutFloatField( m_inputPorts[ 0 ].Name, m_inputPorts[ 0 ].FloatInternalData );
  59. if( !m_inputPorts[ 1 ].IsConnected )
  60. m_inputPorts[ 1 ].FloatInternalData = EditorGUILayoutFloatField( m_inputPorts[ 1 ].Name, m_inputPorts[ 1 ].FloatInternalData );
  61. m_useUnityBranch = EditorGUILayoutToggle( UseUnityBranchesStr, m_useUnityBranch );
  62. }
  63. public override void OnInputPortDisconnected( int portId )
  64. {
  65. base.OnInputPortDisconnected( portId );
  66. UpdateConnection( portId );
  67. }
  68. //void TestMainInputDataType()
  69. //{
  70. // WirePortDataType newType = WirePortDataType.FLOAT;
  71. // if ( m_inputPorts[ 0 ].IsConnected && UIUtils.GetPriority( m_inputPorts[ 0 ].DataType ) > UIUtils.GetPriority( newType ) )
  72. // {
  73. // newType = m_inputPorts[ 0 ].DataType;
  74. // }
  75. // if ( m_inputPorts[ 1 ].IsConnected && ( UIUtils.GetPriority( m_inputPorts[ 1 ].DataType ) > UIUtils.GetPriority( newType ) ) )
  76. // {
  77. // newType = m_inputPorts[ 1 ].DataType;
  78. // }
  79. // m_inputMainDataType = newType;
  80. //}
  81. void TestMainOutputDataType()
  82. {
  83. WirePortDataType newType = WirePortDataType.FLOAT;
  84. for( int i = 2; i < 5; i++ )
  85. {
  86. if( m_inputPorts[ i ].IsConnected && ( UIUtils.GetPriority( m_inputPorts[ i ].DataType ) > UIUtils.GetPriority( newType ) ) )
  87. {
  88. newType = m_inputPorts[ i ].DataType;
  89. }
  90. }
  91. if( newType != m_outputMainDataType )
  92. {
  93. m_outputMainDataType = newType;
  94. }
  95. m_outputPorts[ 0 ].ChangeType( m_outputMainDataType, false );
  96. }
  97. public void UpdateConnection( int portId )
  98. {
  99. m_inputPorts[ portId ].MatchPortToConnection();
  100. switch( portId )
  101. {
  102. //case 0:
  103. //case 1:
  104. //{
  105. // TestMainInputDataType();
  106. //}
  107. //break;
  108. case 2:
  109. case 3:
  110. case 4:
  111. {
  112. TestMainOutputDataType();
  113. }
  114. break;
  115. }
  116. }
  117. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  118. {
  119. if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
  120. return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
  121. string AValue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector);
  122. string BValue = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
  123. m_results[ 0 ] = m_inputPorts[ 2 ].GenerateShaderForOutput( ref dataCollector, m_outputMainDataType, ignoreLocalvar, true );
  124. m_results[ 1 ] = m_inputPorts[ 3 ].GenerateShaderForOutput( ref dataCollector, m_outputMainDataType, ignoreLocalvar, true );
  125. m_results[ 2 ] = m_inputPorts[ 4 ].GenerateShaderForOutput( ref dataCollector, m_outputMainDataType, ignoreLocalvar, true );
  126. string localVarName = "ifLocalVar" + OutputId;
  127. string localVarDec = string.Format( "{0} {1} = 0;", UIUtils.FinalPrecisionWirePortToCgType( m_currentPrecisionType, m_outputPorts[ 0 ].DataType ), localVarName );
  128. bool lequal = false;
  129. bool greater = false;
  130. bool lesser = false;
  131. bool gequal = false;
  132. bool equal = false;
  133. bool nequal = false;
  134. bool welse = false;
  135. bool midCon = false;
  136. if( m_inputPorts[ 2 ].IsConnected )
  137. {
  138. greater = true;
  139. }
  140. if( m_inputPorts[ 4 ].IsConnected )
  141. {
  142. lesser = true;
  143. }
  144. if( greater && m_inputPorts[ 2 ].GetOutputConnection() == m_inputPorts[ 3 ].GetOutputConnection() )
  145. {
  146. gequal = true;
  147. }
  148. if( lesser && m_inputPorts[ 4 ].GetOutputConnection() == m_inputPorts[ 3 ].GetOutputConnection() )
  149. {
  150. lequal = true;
  151. }
  152. if( m_inputPorts[ 2 ].GetOutputConnection() == m_inputPorts[ 4 ].GetOutputConnection() )
  153. {
  154. if( m_inputPorts[ 3 ].IsConnected )
  155. equal = true;
  156. else if( m_inputPorts[ 2 ].IsConnected )
  157. nequal = true;
  158. }
  159. if( m_inputPorts[ 3 ].IsConnected )
  160. {
  161. midCon = true;
  162. if( greater && lesser )
  163. welse = true;
  164. }
  165. dataCollector.AddLocalVariable( UniqueId, localVarDec, true );
  166. if ( m_useUnityBranch && !( lequal && gequal ) && !( !greater && !midCon && !lesser ) )
  167. dataCollector.AddLocalVariable( UniqueId, UnityBranchStr, true );
  168. if( lequal && gequal ) // all equal
  169. {
  170. dataCollector.AddLocalVariable( UniqueId, string.Format( "{0} = {1};", localVarName, m_results[ 1 ] ), true );
  171. }
  172. else if( !lequal && gequal ) // greater or equal
  173. {
  174. dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 3 ], AValue, BValue ), true );
  175. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
  176. if( welse )
  177. {
  178. dataCollector.AddLocalVariable( UniqueId, "else", true );
  179. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 2 ] ), true );
  180. }
  181. }
  182. else if( lequal && !gequal )// lesser or equal
  183. {
  184. dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 4 ], AValue, BValue ), true );
  185. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 2 ] ), true );
  186. if( welse )
  187. {
  188. dataCollector.AddLocalVariable( UniqueId, "else", true );
  189. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
  190. }
  191. }
  192. else if( nequal )// not equal
  193. {
  194. dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 5 ], AValue, BValue ), true );
  195. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
  196. }
  197. else if( equal )// equal
  198. {
  199. dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 1 ], AValue, BValue ), true );
  200. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 1 ] ), true );
  201. if( welse )
  202. {
  203. dataCollector.AddLocalVariable( UniqueId, "else", true );
  204. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
  205. }
  206. }
  207. else if( lesser && !midCon && !greater ) // lesser
  208. {
  209. dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 2 ], AValue, BValue ), true );
  210. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 2 ] ), true );
  211. }
  212. else if( greater && !midCon && !lesser ) // greater
  213. {
  214. dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 0 ], AValue, BValue ), true );
  215. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
  216. }
  217. else if( !greater && !midCon && !lesser ) // none
  218. {
  219. //dataCollector.AddLocalVariable( UniqueId, localVarDec );
  220. }
  221. else // all different
  222. {
  223. bool ifStarted = false;
  224. if( greater )
  225. {
  226. dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 0 ], AValue, BValue ), true );
  227. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
  228. ifStarted = true;
  229. }
  230. if( midCon )
  231. {
  232. dataCollector.AddLocalVariable( UniqueId, ( ifStarted ? "else " : string.Empty ) +string.Format( IfOps[ 1 ], AValue, BValue ), true );
  233. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 1 ] ), true );
  234. ifStarted = true;
  235. }
  236. if( lesser )
  237. {
  238. dataCollector.AddLocalVariable( UniqueId, "else " + string.Format( IfOps[ 2 ], AValue, BValue ), true );
  239. dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 2 ] ), true );
  240. }
  241. }
  242. m_outputPorts[ 0 ].SetLocalValue( localVarName, dataCollector.PortCategory );
  243. return localVarName;
  244. }
  245. public override void ReadFromString( ref string[] nodeParams )
  246. {
  247. base.ReadFromString( ref nodeParams );
  248. if( UIUtils.CurrentShaderVersion() > 4103 )
  249. {
  250. m_useUnityBranch = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
  251. }
  252. }
  253. public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  254. {
  255. base.WriteToString( ref nodeInfo, ref connectionsInfo );
  256. IOUtils.AddFieldValueToString( ref nodeInfo, m_useUnityBranch );
  257. }
  258. }
  259. }