| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 | // 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{	[Serializable]	public class InputSwitchMPHelper	{		public int SubShaderIdx;		public int PassIdx;		public InputSwitchMPHelper( int subShaderIdx , int passIdx )		{			SubShaderIdx = subShaderIdx;			PassIdx = passIdx;		}	}	[Serializable]	[NodeAttributes( "Template Multi-Pass Switch" , "Logical Operators" , "Relays, in compile time, the correct input port according to current analyzed sub-shader/pass." )]	public sealed class TemplateMultiPassSwitchNode : TemplateNodeParent	{		private const string InputLabelStr = "SubShader {0} Pass {1}";		[SerializeField]		private List<InputSwitchMPHelper> m_inputHelper = new List<InputSwitchMPHelper>();		[SerializeField]		private int m_inputCountHelper = -1;		protected override void CommonInit( int uniqueId )		{			m_createAllOutputs = false;			base.CommonInit( uniqueId );		}		public override void OnInputPortConnected( int portId , int otherNodeId , int otherPortId , bool activateNode = true )		{			base.OnInputPortConnected( portId , otherNodeId , otherPortId , activateNode );			UpdateConnections();		}		public override void OnConnectedOutputNodeChanges( int inputPortId , int otherNodeId , int otherPortId , string name , WirePortDataType type )		{			base.OnConnectedOutputNodeChanges( inputPortId , otherNodeId , otherPortId , name , type );			UpdateConnections();		}		public override void OnInputPortDisconnected( int portId )		{			base.OnInputPortDisconnected( portId );			UpdateConnections();		}		private void UpdateConnections()		{			WirePortDataType mainType = WirePortDataType.FLOAT;			int highest = UIUtils.GetPriority( mainType );			for( int i = 0 ; i < m_inputPorts.Count ; i++ )			{				if( m_inputPorts[ i ].IsConnected )				{					WirePortDataType portType = m_inputPorts[ i ].GetOutputConnection().DataType;					if( UIUtils.GetPriority( portType ) > highest )					{						mainType = portType;						highest = UIUtils.GetPriority( portType );					}				}			}			for( int i = 0 ; i < m_inputPorts.Count ; i++ )			{				m_inputPorts[ i ].ChangeType( mainType , false );			}			m_outputPorts[ 0 ].ChangeType( mainType , false );		}		public override void Draw( DrawInfo drawInfo )		{			base.Draw( drawInfo );			if( m_templateMPData == null )			{				FetchMultiPassTemplate();				if( m_inputPorts.Count != m_inputCountHelper )				{					CreateInputPorts();				}				else				{					RefreshInputPorts();				}			}		}		public void RefreshInputPorts()		{			if( m_multiPassMode )			{				m_inputHelper.Clear();				if( m_templateMPData != null )				{					int index = 0;					int subShaderCount = m_templateMPData.SubShaders.Count;					for( int subShaderIdx = 0 ; subShaderIdx < subShaderCount ; subShaderIdx++ )					{						int passCount = m_templateMPData.SubShaders[ subShaderIdx ].Passes.Count;						for( int passIdx = 0 ; passIdx < passCount ; passIdx++ )						{							if( m_templateMPData.SubShaders[ subShaderIdx ].Passes[ passIdx ].HasValidFunctionBody )							{								m_inputPorts[ index ].Name = string.Format( InputLabelStr , subShaderIdx , passIdx );								m_inputHelper.Add( new InputSwitchMPHelper( subShaderIdx , passIdx ) );								index += 1;							}						}					}				}			}			else			{				m_inputPorts[ 0 ].Name = "In";			}		}		public int RefreshInputCountHelper()		{			int inputCountHelper = 0;			if( m_multiPassMode )			{				if( m_templateMPData != null )				{					int subShaderCount = m_templateMPData.SubShaders.Count;					for( int subShaderIdx = 0 ; subShaderIdx < subShaderCount ; subShaderIdx++ )					{						int passCount = m_templateMPData.SubShaders[ subShaderIdx ].Passes.Count;						for( int passIdx = 0 ; passIdx < passCount ; passIdx++ )						{							if( m_templateMPData.SubShaders[ subShaderIdx ].Passes[ passIdx ].HasValidFunctionBody )								inputCountHelper += 1;						}					}				}			}			else			{				inputCountHelper += 1;			}			return inputCountHelper;		}		public void CreateInputPorts()		{			m_inputCountHelper = 0;			DeleteAllInputConnections( true );			if( m_multiPassMode )			{				m_inputHelper.Clear();				if( m_templateMPData != null )				{					int subShaderCount = m_templateMPData.SubShaders.Count;					for( int subShaderIdx = 0 ; subShaderIdx < subShaderCount ; subShaderIdx++ )					{						int passCount = m_templateMPData.SubShaders[ subShaderIdx ].Passes.Count;						for( int passIdx = 0 ; passIdx < passCount ; passIdx++ )						{							if( m_templateMPData.SubShaders[ subShaderIdx ].Passes[ passIdx ].HasValidFunctionBody )							{								AddInputPort( WirePortDataType.FLOAT , false , string.Format( InputLabelStr , subShaderIdx , passIdx ) );								m_inputHelper.Add( new InputSwitchMPHelper( subShaderIdx , passIdx ) );								m_inputCountHelper += 1;							}						}					}				}			}			else			{				AddInputPort( WirePortDataType.FLOAT , false , "In" );				m_inputCountHelper += 1;			}		}		public override string GenerateShaderForOutput( int outputId , ref MasterNodeDataCollector dataCollector , bool ignoreLocalvar )		{			if( dataCollector.MasterNodeCategory != AvailableShaderTypes.Template )			{				UIUtils.ShowMessage( "Template Multi-Pass Switch Data node is only intended for templates use only" , MessageSeverity.Error );				return m_outputPorts[ 0 ].ErrorValue;			}			int currSubShaderIdx = dataCollector.TemplateDataCollectorInstance.MultipassSubshaderIdx;			int currPassIdx = dataCollector.TemplateDataCollectorInstance.MultipassPassIdx;			int inputHelperCount = m_inputHelper.Count;			for( int i = 0 ; i < inputHelperCount ; i++ )			{				if( m_inputHelper[ i ].SubShaderIdx == currSubShaderIdx && m_inputHelper[ i ].PassIdx == currPassIdx )					return m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector );			}			UIUtils.ShowMessage( "Invalid subshader or pass on Template Multi-Pass Switch Data" );			return m_outputPorts[ 0 ].ErrorValue;		}		public override void OnMasterNodeReplaced( MasterNode newMasterNode )		{			base.OnMasterNodeReplaced( newMasterNode );			m_autoWrapProperties = false;			if( newMasterNode.CurrentMasterNodeCategory == AvailableShaderTypes.Template )			{				FetchMultiPassTemplate( newMasterNode );				m_inputCountHelper = RefreshInputCountHelper();				if( m_inputPorts.Count != m_inputCountHelper )				{					CreateInputPorts();				}				else				{					RefreshInputPorts();				}			}			else			{				DeleteAllInputConnections( true );			}		}		public override void ReadFromString( ref string[] nodeParams )		{			base.ReadFromString( ref nodeParams );			m_inputCountHelper = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );			// Need to add ports here so read internal data is correct			for( int i = 0 ; i < m_inputCountHelper ; i++ )			{				AddInputPort( WirePortDataType.FLOAT , false , Constants.EmptyPortValue );			}		}		public override void WriteToString( ref string nodeInfo , ref string connectionsInfo )		{			base.WriteToString( ref nodeInfo , ref connectionsInfo );			IOUtils.AddFieldValueToString( ref nodeInfo , m_inputCountHelper );		}		public override void Destroy()		{			base.Destroy();			m_inputHelper.Clear();			m_inputHelper = null;		}		public override void RefreshExternalReferences()		{			base.RefreshExternalReferences();			FetchMultiPassTemplate();			bool create = false;			if( m_inputCountHelper == -1 )			{				create = true;			}			else			{				int newInputCount = RefreshInputCountHelper();				if( newInputCount != m_inputCountHelper )				{					create = true;				}			}			if( m_multiPassMode )			{				if( m_templateMPData != null )				{					if( create )					{						CreateInputPorts();					}					else					{						m_inputHelper.Clear();						int index = 0;						int subShaderCount = m_templateMPData.SubShaders.Count;						for( int subShaderIdx = 0 ; subShaderIdx < subShaderCount ; subShaderIdx++ )						{							int passCount = m_templateMPData.SubShaders[ subShaderIdx ].Passes.Count;							for( int passIdx = 0 ; passIdx < passCount ; passIdx++ )							{								if( m_templateMPData.SubShaders[ subShaderIdx ].Passes[ passIdx ].HasValidFunctionBody )								{									m_inputPorts[ index ].Name = string.Format( InputLabelStr , subShaderIdx , passIdx );									m_inputHelper.Add( new InputSwitchMPHelper( subShaderIdx , passIdx ) );									index += 1;								}							}						}						if( index != m_inputCountHelper )						{							Debug.LogWarning( "Something wrong occured in reading MultiPass Switch node" );						}					}				}			}			else			{				if( create )				{					AddInputPort( WirePortDataType.FLOAT , false , "In" );				}				else				{					m_inputPorts[ 0 ].Name = "In";				}			}		}	}}
 |