summaryrefslogtreecommitdiff
path: root/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs')
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs475
1 files changed, 475 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs
new file mode 100644
index 00000000..64cc8ebe
--- /dev/null
+++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs
@@ -0,0 +1,475 @@
+// Amplify Shader Editor - Visual Shader Editing Tool
+// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
+using UnityEngine;
+using UnityEditor;
+using System;
+using System.Collections.Generic;
+
+namespace AmplifyShaderEditor
+{
+
+ public struct AppendData
+ {
+ public WirePortDataType PortType;
+ public int OldPortId;
+ public int NewPortId;
+ public AppendData( WirePortDataType portType, int oldPortId, int newPortId )
+ {
+ PortType = portType;
+ OldPortId = oldPortId;
+ NewPortId = newPortId;
+ }
+ }
+
+ [Serializable]
+ [NodeAttributes( "Append", "Vector Operators", "Append channels to create a new component", null, KeyCode.V, tags: "combine" )]
+ public sealed class DynamicAppendNode : ParentNode
+ {
+ private const string OutputTypeStr = "Output type";
+ private const string OutputFormatStr = "({0}({1}))";
+
+ [SerializeField]
+ private WirePortDataType m_selectedOutputType = WirePortDataType.FLOAT4;
+
+ [SerializeField]
+ private int m_selectedOutputTypeInt = 2;
+
+ private readonly string[] m_outputValueTypes ={ "Vector2",
+ "Vector3",
+ "Vector4",
+ "Color"};
+
+ [SerializeField]
+ private int[] m_occupiedChannels = { -1, -1, -1, -1 };
+
+ [SerializeField]
+ private int m_maskId;
+
+ [SerializeField]
+ private Vector4 m_maskValue = Vector4.one;
+
+ protected override void CommonInit( int uniqueId )
+ {
+ base.CommonInit( uniqueId );
+ AddInputPort( WirePortDataType.FLOAT, false, Constants.ChannelNamesVector[ 0 ] );
+ AddInputPort( WirePortDataType.FLOAT, false, Constants.ChannelNamesVector[ 1 ] );
+ AddInputPort( WirePortDataType.FLOAT, false, Constants.ChannelNamesVector[ 2 ] );
+ AddInputPort( WirePortDataType.FLOAT, false, Constants.ChannelNamesVector[ 3 ] );
+ AddOutputPort( m_selectedOutputType, Constants.EmptyPortValue );
+ m_textLabelWidth = 90;
+ m_autoWrapProperties = true;
+ m_useInternalPortData = true;
+ m_hasLeftDropdown = true;
+ m_previewShaderGUID = "bfcd2919fe75bbf428fbbe583f463a9e";
+ }
+
+ public override void OnEnable()
+ {
+ base.OnEnable();
+ m_maskId = Shader.PropertyToID( "_Mask" );
+ }
+
+ void NewUpdateBehaviorConn( int portId, bool onLoading )
+ {
+ InputPort inputPort = GetInputPortByUniqueId( portId );
+ int channelsRequired = UIUtils.GetChannelsAmount( onLoading ? inputPort.DataType : inputPort.ConnectionType( 0 ) );
+ int availableChannels = UIUtils.GetChannelsAmount( m_selectedOutputType );
+
+ // Invalidate previously used channels
+ for( int i = 0; i < availableChannels; i++ )
+ {
+ if( m_occupiedChannels[ i ] == portId )
+ {
+ m_occupiedChannels[ i ] = -1;
+ m_inputPorts[ i ].Visible = true;
+ }
+ }
+ // Lock available channels to port
+ int len = Mathf.Min( portId + channelsRequired, availableChannels );
+
+ int channelsUsed = 0;
+ for( int i = portId; i < len; i++ )
+ {
+ if( m_occupiedChannels[ i ] == -1 )
+ {
+ m_occupiedChannels[ i ] = portId;
+ channelsUsed += 1;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if( !onLoading )
+ inputPort.ChangeType( UIUtils.GetWireTypeForChannelAmount( channelsUsed ), false );
+
+ if( channelsUsed > 1 && portId < availableChannels - 1 )
+ {
+ channelsUsed -= 1;
+ int i = portId + 1;
+ for( ; channelsUsed > 0; i++, --channelsUsed )
+ {
+ m_inputPorts[ i ].Visible = false;
+ }
+
+ }
+ m_sizeIsDirty = true;
+ }
+
+ void NewUpdateBehaviorDisconn( int portId )
+ {
+ int availableChannels = UIUtils.GetChannelsAmount( m_selectedOutputType );
+ // Invalidate previously used channels
+ for( int i = 0; i < availableChannels; i++ )
+ {
+ if( m_occupiedChannels[ i ] == portId )
+ {
+ m_occupiedChannels[ i ] = -1;
+ m_inputPorts[ i ].Visible = true;
+ m_inputPorts[ i ].ChangeType( WirePortDataType.FLOAT, false );
+ }
+ }
+ m_sizeIsDirty = true;
+ }
+
+ void RenamePorts()
+ {
+ int channel = 0;
+ for( int i = 0; i < 4; i++ )
+ {
+ if( m_inputPorts[ i ].Visible )
+ {
+ string name = string.Empty;
+ int usedChannels = UIUtils.GetChannelsAmount( m_inputPorts[ i ].DataType );
+ bool isColor = ( m_selectedOutputType == WirePortDataType.COLOR );
+ for( int j = 0; j < usedChannels; j++ )
+ {
+ if( channel < Constants.ChannelNamesVector.Length )
+ name += isColor ? Constants.ChannelNamesColor[ channel++ ] : Constants.ChannelNamesVector[ channel++ ];
+ }
+ m_inputPorts[ i ].Name = name;
+ }
+ }
+
+ CalculatePreviewData();
+ }
+
+ void UpdatePortTypes()
+ {
+ ChangeOutputType( m_selectedOutputType, false );
+ int availableChannels = UIUtils.GetChannelsAmount( m_selectedOutputType );
+ int usedChannels = 0;
+ while( usedChannels < availableChannels )
+ {
+ int channelsRequired = m_inputPorts[ usedChannels ].IsConnected ? UIUtils.GetChannelsAmount( m_inputPorts[ usedChannels ].DataType ) : 0;
+ if( channelsRequired > 0 )
+ {
+
+ if( ( usedChannels + channelsRequired ) < availableChannels )
+ {
+ usedChannels += channelsRequired;
+ }
+ else
+ {
+ m_inputPorts[ usedChannels ].Visible = true;
+ WirePortDataType newType = UIUtils.GetWireTypeForChannelAmount( availableChannels - usedChannels );
+ m_inputPorts[ usedChannels ].ChangeType( newType, false );
+ usedChannels = availableChannels;
+ break;
+ }
+ }
+ else
+ {
+ m_occupiedChannels[ usedChannels ] = -1;
+ m_inputPorts[ usedChannels ].Visible = true;
+ m_inputPorts[ usedChannels ].ChangeType( WirePortDataType.FLOAT, false );
+ usedChannels += 1;
+ }
+ }
+
+ for( int i = usedChannels; i < availableChannels; i++ )
+ {
+ m_occupiedChannels[ i ] = -1;
+ m_inputPorts[ i ].Visible = true;
+ m_inputPorts[ i ].ChangeType( WirePortDataType.FLOAT, false );
+ }
+
+ for( int i = availableChannels; i < 4; i++ )
+ {
+ m_occupiedChannels[ i ] = -1;
+ m_inputPorts[ i ].Visible = false;
+ m_inputPorts[ i ].ChangeType( WirePortDataType.FLOAT, false );
+ }
+ m_sizeIsDirty = true;
+ }
+
+ public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
+ {
+ base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode );
+
+ if( ( m_containerGraph.IsLoading || m_isNodeBeingCopied ) && UIUtils.CurrentShaderVersion() < 13206 )
+ return;
+
+ NewUpdateBehaviorConn( portId, ( UIUtils.IsLoading|| m_isNodeBeingCopied ) );
+ RenamePorts();
+
+ }
+
+ public override void OnInputPortDisconnected( int portId )
+ {
+ base.OnInputPortDisconnected( portId );
+
+ if( ( UIUtils.IsLoading || m_isNodeBeingCopied ) && UIUtils.CurrentShaderVersion() < 13206 )
+ return;
+
+ NewUpdateBehaviorDisconn( portId );
+ RenamePorts();
+ }
+
+ public override void OnConnectedOutputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
+ {
+ base.OnConnectedOutputNodeChanges( portId, otherNodeId, otherPortId, name, type );
+
+ if( ( UIUtils.IsLoading || m_isNodeBeingCopied ) && UIUtils.CurrentShaderVersion() < 13206 )
+ return;
+
+ NewUpdateBehaviorConn( portId, ( UIUtils.IsLoading || m_isNodeBeingCopied ) );
+ RenamePorts();
+ }
+
+ void SetupPorts()
+ {
+ switch( m_selectedOutputTypeInt )
+ {
+ case 0: m_selectedOutputType = WirePortDataType.FLOAT2; break;
+ case 1: m_selectedOutputType = WirePortDataType.FLOAT3; break;
+ case 2: m_selectedOutputType = WirePortDataType.FLOAT4; break;
+ case 3: m_selectedOutputType = WirePortDataType.COLOR; break;
+ }
+ UpdatePortTypes();
+ RenamePorts();
+ }
+
+ public override void Draw( DrawInfo drawInfo )
+ {
+ base.Draw( drawInfo );
+
+ if( m_dropdownEditing )
+ {
+ EditorGUI.BeginChangeCheck();
+ m_selectedOutputTypeInt = EditorGUIPopup( m_dropdownRect, m_selectedOutputTypeInt, m_outputValueTypes, UIUtils.PropertyPopUp );
+ if( EditorGUI.EndChangeCheck() )
+ {
+ SetupPorts();
+ DropdownEditing = false;
+ }
+ }
+ }
+
+ public override void DrawProperties()
+ {
+ base.DrawProperties();
+ EditorGUILayout.BeginVertical();
+
+ EditorGUI.BeginChangeCheck();
+ m_selectedOutputTypeInt = EditorGUILayoutPopup( OutputTypeStr, m_selectedOutputTypeInt, m_outputValueTypes );
+ if( EditorGUI.EndChangeCheck() )
+ {
+ SetupPorts();
+ }
+
+ EditorGUILayout.EndVertical();
+ }
+
+ public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar )
+ {
+ if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
+ return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
+ string result = string.Empty;
+ for( int i = 0; i < 4; i++ )
+ {
+ if( m_inputPorts[ i ].Visible )
+ {
+ if( i > 0 )
+ {
+ result += " , ";
+ }
+ result += m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector );
+ }
+ }
+
+ result = string.Format( OutputFormatStr,
+ UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, m_selectedOutputType ),
+ result );
+
+ RegisterLocalVariable( 0, result, ref dataCollector, "appendResult" + OutputId );
+ return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
+ }
+
+ public override void ReadFromString( ref string[] nodeParams )
+ {
+ base.ReadFromString( ref nodeParams );
+ m_selectedOutputType = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), GetCurrentParam( ref nodeParams ) );
+ switch( m_selectedOutputType )
+ {
+ case WirePortDataType.FLOAT2: m_selectedOutputTypeInt = 0; break;
+ case WirePortDataType.FLOAT3: m_selectedOutputTypeInt = 1; break;
+ case WirePortDataType.FLOAT4: m_selectedOutputTypeInt = 2; break;
+ case WirePortDataType.COLOR: m_selectedOutputTypeInt = 3; break;
+ }
+ }
+
+ public override void ReadFromDeprecated( ref string[] nodeParams, Type oldType = null )
+ {
+ m_selectedOutputType = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), GetCurrentParam( ref nodeParams ) );
+ switch( m_selectedOutputType )
+ {
+ case WirePortDataType.FLOAT2: m_selectedOutputTypeInt = 0; break;
+ case WirePortDataType.FLOAT3: m_selectedOutputTypeInt = 1; break;
+ case WirePortDataType.FLOAT4: m_selectedOutputTypeInt = 2; break;
+ case WirePortDataType.COLOR: m_selectedOutputTypeInt = 3; break;
+ }
+ for( int i = 0; i < 4; i++ )
+ {
+ m_inputPorts[i].FloatInternalData = Convert.ToSingle( GetCurrentParam( ref nodeParams ) );
+ }
+ }
+
+ public override void RefreshExternalReferences()
+ {
+ base.RefreshExternalReferences();
+
+ if( UIUtils.CurrentShaderVersion() < 13206 )
+ {
+ //TODO: MAKE THIS LESS BRUTE FORCE
+ List<AppendData> reroutes = new List<AppendData>();
+ int availableChannel = 0;
+ for( int i = 0; i < 4 && availableChannel < 4; i++ )
+ {
+ int channelsAmount = UIUtils.GetChannelsAmount( m_inputPorts[ i ].DataType );
+ if( m_inputPorts[ i ].IsConnected /*&& availableChannel != i*/ )
+ {
+ reroutes.Add( new AppendData( m_inputPorts[ i ].DataType, i, availableChannel ) );
+ }
+
+ availableChannel += channelsAmount;
+ }
+
+ if( reroutes.Count > 0 )
+ {
+ for( int i = reroutes.Count - 1; i > -1; i-- )
+ {
+ int nodeId = m_inputPorts[ reroutes[ i ].OldPortId ].ExternalReferences[ 0 ].NodeId;
+ int portId = m_inputPorts[ reroutes[ i ].OldPortId ].ExternalReferences[ 0 ].PortId;
+
+ m_containerGraph.DeleteConnection( true, UniqueId, reroutes[ i ].OldPortId, false, false, false );
+ m_containerGraph.CreateConnection( UniqueId, reroutes[ i ].NewPortId, nodeId, portId, false );
+ NewUpdateBehaviorConn( reroutes[ i ].NewPortId, true );
+ }
+ }
+
+ availableChannel = UIUtils.GetChannelsAmount( m_selectedOutputType );
+ int currChannelIdx = 0;
+ for( ; currChannelIdx < availableChannel; currChannelIdx++ )
+ {
+ if( m_inputPorts[ currChannelIdx ].Visible )
+ {
+ int channelsAmount = UIUtils.GetChannelsAmount( m_inputPorts[ currChannelIdx ].DataType );
+ for( int j = currChannelIdx + 1; j < currChannelIdx + channelsAmount; j++ )
+ {
+ m_inputPorts[ j ].Visible = false;
+ }
+ }
+ }
+
+ for( ; currChannelIdx < 4; currChannelIdx++ )
+ {
+ m_inputPorts[ currChannelIdx ].Visible = false;
+ }
+ }
+ SetupPorts();
+ m_sizeIsDirty = true;
+ }
+
+
+ void CalculatePreviewData()
+ {
+ switch( m_outputPorts[ 0 ].DataType )
+ {
+ default: m_maskValue = Vector4.zero; break;
+ case WirePortDataType.INT:
+ case WirePortDataType.FLOAT: m_maskValue = new Vector4( 1, 0, 0, 0 ); break;
+ case WirePortDataType.FLOAT2: m_maskValue = new Vector4( 1, 1, 0, 0 ); break;
+ case WirePortDataType.FLOAT3: m_maskValue = new Vector4( 1, 1, 1, 0 ); break;
+ case WirePortDataType.FLOAT4:
+ case WirePortDataType.COLOR: m_maskValue = Vector4.one; break;
+ }
+
+ m_previewMaterialPassId = -1;
+ switch( m_inputPorts[ 0 ].DataType )
+ {
+ case WirePortDataType.INT:
+ case WirePortDataType.FLOAT:
+ {
+ switch( m_inputPorts[ 1 ].DataType )
+ {
+ case WirePortDataType.FLOAT:
+ case WirePortDataType.INT:
+ {
+ if( m_inputPorts[ 2 ].DataType == WirePortDataType.FLOAT ||
+ m_inputPorts[ 2 ].DataType == WirePortDataType.INT )
+ {
+ m_previewMaterialPassId = 0;
+ }
+ else if( m_inputPorts[ 2 ].DataType == WirePortDataType.FLOAT2 )
+ {
+ m_previewMaterialPassId = 1;
+ }
+ }
+ break;
+ case WirePortDataType.FLOAT2: m_previewMaterialPassId = 2; break;
+ case WirePortDataType.FLOAT3: m_previewMaterialPassId = 3; break;
+ }
+
+ }; break;
+ case WirePortDataType.FLOAT2:
+ {
+ if( m_inputPorts[ 2 ].DataType == WirePortDataType.FLOAT ||
+ m_inputPorts[ 2 ].DataType == WirePortDataType.INT )
+ {
+ m_previewMaterialPassId = 4;
+ }
+ else if( m_inputPorts[ 2 ].DataType == WirePortDataType.FLOAT2 )
+ {
+ m_previewMaterialPassId = 5;
+ }
+ }; break;
+ case WirePortDataType.FLOAT3: m_previewMaterialPassId = 6; break;
+ case WirePortDataType.FLOAT4:
+ case WirePortDataType.COLOR: m_previewMaterialPassId = 7; break;
+ }
+
+ if( m_previewMaterialPassId == -1 )
+ {
+ m_previewMaterialPassId = 0;
+ if( DebugConsoleWindow.DeveloperMode )
+ {
+ UIUtils.ShowMessage( UniqueId, "Could not find pass ID for append" , MessageSeverity.Error );
+ }
+ }
+ }
+
+ public override void SetPreviewInputs()
+ {
+ base.SetPreviewInputs();
+ PreviewMaterial.SetVector( m_maskId, m_maskValue );
+ }
+
+ public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
+ {
+ base.WriteToString( ref nodeInfo, ref connectionsInfo );
+ IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedOutputType );
+ }
+ }
+}