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.

263 lines
7.5 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using UnityEngine;
  5. namespace AmplifyShaderEditor
  6. {
  7. [Serializable]
  8. [NodeAttributes( "Break To Components", "Vector Operators", "Breaks the input data into its individual components", null, KeyCode.B )]
  9. public sealed class BreakToComponentsNode : ParentNode
  10. {
  11. private WirePortDataType m_currentType = WirePortDataType.FLOAT;
  12. private readonly string[] ColorPortNames = { "R", "G", "B", "A" };
  13. private readonly string[] VectorPortNames = { "X", "Y", "Z", "W" };
  14. protected override void CommonInit( int uniqueId )
  15. {
  16. base.CommonInit( uniqueId );
  17. AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue );
  18. for( int i = 0; i < 16; i++ )
  19. {
  20. AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
  21. m_outputPorts[ i ].IndexPreviewOffset = 1;
  22. if( i != 0 )
  23. {
  24. m_outputPorts[ i ].Visible = false;
  25. }
  26. }
  27. m_previewShaderGUID = "5f58f74a202ba804daddec838b75207d";
  28. }
  29. public override void RenderNodePreview()
  30. {
  31. if( !m_initialized )
  32. return;
  33. SetPreviewInputs();
  34. int count = m_outputPorts.Count;
  35. for( int i = 0; i < count; i++ )
  36. {
  37. RenderTexture temp = RenderTexture.active;
  38. RenderTexture.active = m_outputPorts[ i ].OutputPreviewTexture;
  39. Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, Mathf.Min( i, 3 ) );
  40. RenderTexture.active = temp;
  41. }
  42. }
  43. public override RenderTexture PreviewTexture
  44. {
  45. get
  46. {
  47. return m_inputPorts[ 0 ].InputPreviewTexture;
  48. }
  49. }
  50. void UpdateOutputs( WirePortDataType newType )
  51. {
  52. //this only happens when on initial load
  53. if( newType == WirePortDataType.OBJECT )
  54. return;
  55. m_currentType = newType;
  56. switch( newType )
  57. {
  58. case WirePortDataType.OBJECT:
  59. {
  60. m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.OBJECT, false );
  61. m_outputPorts[ 0 ].Visible = true;
  62. for( int i = 1; i < m_outputPorts.Count; i++ )
  63. {
  64. m_outputPorts[ i ].Visible = false;
  65. }
  66. }
  67. break;
  68. case WirePortDataType.FLOAT:
  69. {
  70. m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.FLOAT, false );
  71. m_outputPorts[ 0 ].Visible = true;
  72. for( int i = 1; i < m_outputPorts.Count; i++ )
  73. {
  74. m_outputPorts[ i ].Visible = false;
  75. }
  76. }
  77. break;
  78. case WirePortDataType.FLOAT2:
  79. {
  80. for( int i = 0; i < 2; i++ )
  81. {
  82. m_outputPorts[ i ].ChangeProperties( VectorPortNames[ i ], WirePortDataType.FLOAT, false );
  83. m_outputPorts[ i ].Visible = true;
  84. }
  85. for( int i = 2; i < m_outputPorts.Count; i++ )
  86. {
  87. m_outputPorts[ i ].Visible = false;
  88. }
  89. }
  90. break;
  91. case WirePortDataType.FLOAT3:
  92. {
  93. for( int i = 0; i < 3; i++ )
  94. {
  95. m_outputPorts[ i ].ChangeProperties( VectorPortNames[ i ], WirePortDataType.FLOAT, false );
  96. m_outputPorts[ i ].Visible = true;
  97. }
  98. for( int i = 3; i < m_outputPorts.Count; i++ )
  99. {
  100. m_outputPorts[ i ].Visible = false;
  101. }
  102. }
  103. break;
  104. case WirePortDataType.FLOAT4:
  105. {
  106. for( int i = 0; i < 4; i++ )
  107. {
  108. m_outputPorts[ i ].ChangeProperties( VectorPortNames[ i ], WirePortDataType.FLOAT, false );
  109. m_outputPorts[ i ].Visible = true;
  110. }
  111. for( int i = 4; i < m_outputPorts.Count; i++ )
  112. {
  113. m_outputPorts[ i ].Visible = false;
  114. }
  115. }
  116. break;
  117. case WirePortDataType.FLOAT3x3:
  118. {
  119. for( int i = 0; i < 9; i++ )
  120. {
  121. m_outputPorts[ i ].ChangeProperties( "[" + (int)( i / 3 ) + "][" + i % 3 + "]", WirePortDataType.FLOAT, false );
  122. m_outputPorts[ i ].Visible = true;
  123. }
  124. for( int i = 9; i < m_outputPorts.Count; i++ )
  125. {
  126. m_outputPorts[ i ].Visible = false;
  127. }
  128. }
  129. break;
  130. case WirePortDataType.FLOAT4x4:
  131. {
  132. for( int i = 0; i < 16; i++ )
  133. {
  134. m_outputPorts[ i ].ChangeProperties( "[" + (int)( i / 4 ) + "][" + i % 4 + "]", WirePortDataType.FLOAT, false );
  135. m_outputPorts[ i ].Visible = true;
  136. }
  137. }
  138. break;
  139. case WirePortDataType.COLOR:
  140. {
  141. for( int i = 0; i < 4; i++ )
  142. {
  143. m_outputPorts[ i ].ChangeProperties( ColorPortNames[ i ], WirePortDataType.FLOAT, false );
  144. m_outputPorts[ i ].Visible = true;
  145. }
  146. for( int i = 4; i < m_outputPorts.Count; i++ )
  147. {
  148. m_outputPorts[ i ].Visible = false;
  149. }
  150. }
  151. break;
  152. case WirePortDataType.INT:
  153. {
  154. m_outputPorts[ 0 ].Visible = true;
  155. m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.INT, false );
  156. for( int i = 1; i < m_outputPorts.Count; i++ )
  157. {
  158. m_outputPorts[ i ].Visible = false;
  159. }
  160. }
  161. break;
  162. }
  163. m_sizeIsDirty = true;
  164. }
  165. public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
  166. {
  167. base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type );
  168. m_inputPorts[ 0 ].MatchPortToConnection();
  169. UpdateOutputs( m_inputPorts[ 0 ].DataType );
  170. }
  171. public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
  172. {
  173. base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode );
  174. m_inputPorts[ 0 ].MatchPortToConnection();
  175. UpdateOutputs( m_inputPorts[ 0 ].DataType );
  176. }
  177. public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  178. {
  179. base.WriteToString( ref nodeInfo, ref connectionsInfo );
  180. IOUtils.AddFieldValueToString( ref nodeInfo, m_currentType );
  181. }
  182. public override void ReadFromString( ref string[] nodeParams )
  183. {
  184. base.ReadFromString( ref nodeParams );
  185. UpdateOutputs( (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), GetCurrentParam( ref nodeParams ) ) );
  186. }
  187. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  188. {
  189. if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
  190. {
  191. return ReturnByType( m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ), outputId );
  192. }
  193. string value = string.Empty;
  194. value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
  195. int channelsUsed = 0;
  196. for( int i = 0; i < m_outputPorts.Count; i++ )
  197. {
  198. if( m_outputPorts[ i ].IsConnected )
  199. channelsUsed++;
  200. }
  201. string varName = "break" + OutputId;
  202. if( channelsUsed > 1 )
  203. {
  204. //RegisterLocalVariable( 0, value, ref dataCollector, varName );
  205. dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ 0 ].DataType, varName, value );
  206. m_outputPorts[ 0 ].SetLocalValue( varName, dataCollector.PortCategory );
  207. value = varName;
  208. }
  209. return ReturnByType( value, outputId );
  210. }
  211. private string ReturnByType( string value, int outputId )
  212. {
  213. switch( m_inputPorts[ 0 ].DataType )
  214. {
  215. case WirePortDataType.OBJECT:
  216. case WirePortDataType.FLOAT:
  217. case WirePortDataType.INT:
  218. {
  219. return value;
  220. }
  221. case WirePortDataType.FLOAT2:
  222. case WirePortDataType.FLOAT3:
  223. case WirePortDataType.FLOAT4:
  224. {
  225. return GetOutputVectorItem( 0, outputId + 1, value );
  226. }
  227. case WirePortDataType.COLOR:
  228. {
  229. return GetOutputColorItem( 0, outputId + 1, value );
  230. }
  231. case WirePortDataType.FLOAT3x3:
  232. {
  233. return value + "[ " + ( (int)( outputId / 3 ) ) + " ][ " + ( outputId % 3 ) + " ]";
  234. }
  235. case WirePortDataType.FLOAT4x4:
  236. {
  237. return value + "[ " + ( (int)( outputId / 4 ) ) + " ][ " + ( outputId % 4 ) + " ]";
  238. }
  239. }
  240. return value;
  241. }
  242. }
  243. }