|
|
- // Amplify Shader Editor - Visual Shader Editing Tool
- // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
-
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEditor;
- using UnityEditorInternal;
-
- namespace AmplifyShaderEditor
- {
-
- public enum CustomExpressionMode
- {
- Create,
- Call
- }
-
- [Serializable]
- public class CustomExpressionInputItem
- {
- public PrecisionType Precision;
- public VariableQualifiers Qualifier;
- public WirePortDataType Type;
- public string CustomType;
- public bool FoldoutFlag;
- public string FoldoutLabel;
-
- public CustomExpressionInputItem( PrecisionType precision, VariableQualifiers qualifier, string customType, bool foldoutFlag, string foldoutLabel )
- {
- Precision = precision;
- Qualifier = qualifier;
- CustomType = customType;
- FoldoutFlag = foldoutFlag;
- FoldoutLabel = foldoutLabel;
- }
- }
-
- [Serializable]
- public class CustomExpressionDependency
- {
- public int DependencyArrayIdx;
- public int DependencyNodeId;
- public CustomExpressionDependency() { DependencyArrayIdx = DependencyNodeId = -1; }
- public CustomExpressionDependency( string id ) { DependencyNodeId = Convert.ToInt32( id ); DependencyArrayIdx = -1; }
- public void Reset()
- {
- DependencyArrayIdx = -1;
- DependencyNodeId = -1;
- }
- }
-
- [Serializable]
- [NodeAttributes( "Custom Expression", "Miscellaneous", "Creates a custom expression or function if <b>return</b> is detected in the written code." )]
- public sealed class CustomExpressionNode : ParentNode
- {
- private const float AddRemoveButtonLayoutWidth = 15;
- private const float LineAdjust = 1.15f;
- private const float IdentationAdjust = 5f;
- private const string CustomExpressionInfo = "Creates a custom expression or function according to how code is written on text area.\n\n" +
- " - If a return function is detected on Code text area then a function will be created.\n" +
- "Also in function mode a ; is expected on the end of each instruction line.\n\n" +
- "- If no return function is detected then an expression will be generated and used directly on the vertex/frag body.\n" +
- "On Expression mode a ; is not required on the end of an instruction line.";
- private const char LineFeedSeparator = '$';
-
- private const string ReturnHelper = "return";
- private const double MaxTimestamp = 1;
- private const string DefaultExpressionNameStr = "My Custom Expression";
- private const string DefaultInputNameStr = "In";
- private const string CodeTitleStr = "Code";
- private const string OutputTypeStr = "Output Type";
- private const string CustomTypeStr = " ";
- private const string InputsStr = "Inputs";
- private const string InputNameStr = "Name";
- private const string InputTypeStr = "Type";
- private const string InputValueStr = "Value";
- private const string InputQualifierStr = "Qualifier";
- private const string ExpressionNameLabelStr = "Name";
- private const string FunctionCallModeStr = "Mode";
- private const string GenerateUniqueNameStr = "Set Unique";
- private const string AutoRegisterStr = "Auto-Register";
- private const string DependenciesStr = "Dependencies";
-
- private readonly string[] AvailableWireTypesStr =
- {
- "int",
- "float",
- "float2",
- "float3",
- "float4",
- "float3x3",
- "float4x4",
- "sampler1D",
- "sampler2D",
- "sampler3D",
- "samplerCUBE",
- "custom"};
-
- private readonly string[] AvailableOutputWireTypesStr =
- {
- "int",
- "float",
- "float2",
- "float3",
- "float4",
- "float3x3",
- "float4x4",
- "void",
- };
-
- private readonly string[] QualifiersStr =
- {
- "In",
- "Out",
- "InOut"
- };
-
- private readonly WirePortDataType[] AvailableWireTypes =
- {
- WirePortDataType.INT,
- WirePortDataType.FLOAT,
- WirePortDataType.FLOAT2,
- WirePortDataType.FLOAT3,
- WirePortDataType.FLOAT4,
- WirePortDataType.FLOAT3x3,
- WirePortDataType.FLOAT4x4,
- WirePortDataType.SAMPLER1D,
- WirePortDataType.SAMPLER2D,
- WirePortDataType.SAMPLER3D,
- WirePortDataType.SAMPLERCUBE,
- WirePortDataType.OBJECT
- };
-
- private readonly WirePortDataType[] AvailableOutputWireTypes =
- {
- WirePortDataType.INT,
- WirePortDataType.FLOAT,
- WirePortDataType.FLOAT2,
- WirePortDataType.FLOAT3,
- WirePortDataType.FLOAT4,
- WirePortDataType.FLOAT3x3,
- WirePortDataType.FLOAT4x4,
- WirePortDataType.OBJECT,
- };
-
-
- private readonly Dictionary<WirePortDataType, int> WireToIdx = new Dictionary<WirePortDataType, int>
- {
- { WirePortDataType.INT, 0},
- { WirePortDataType.FLOAT, 1},
- { WirePortDataType.FLOAT2, 2},
- { WirePortDataType.FLOAT3, 3},
- { WirePortDataType.FLOAT4, 4},
- { WirePortDataType.FLOAT3x3, 5},
- { WirePortDataType.FLOAT4x4, 6},
- { WirePortDataType.SAMPLER1D, 7},
- { WirePortDataType.SAMPLER2D, 8},
- { WirePortDataType.SAMPLER3D, 9},
- { WirePortDataType.SAMPLERCUBE, 10},
- { WirePortDataType.OBJECT, 11}
- };
-
- [SerializeField]
- private string m_customExpressionName = DefaultExpressionNameStr;
-
- [SerializeField]
- private List<CustomExpressionInputItem> m_items = new List<CustomExpressionInputItem>();
-
- [SerializeField]
- private string m_code = " ";
-
- [SerializeField]
- private int m_outputTypeIdx = 1;
-
- [SerializeField]
- private bool m_visibleInputsFoldout = true;
-
- [SerializeField]
- private CustomExpressionMode m_mode = CustomExpressionMode.Create;
-
- [SerializeField]
- private bool m_voidMode = false;
-
- [SerializeField]
- private bool m_autoRegisterMode = false;
-
- [SerializeField]
- private bool m_functionMode = false;
-
- [SerializeField]
- private int m_firstAvailablePort = 0;
-
- [SerializeField]
- private string m_uniqueName;
-
- [SerializeField]
- private bool m_generateUniqueName = true;
-
- [SerializeField]
- private bool m_dependenciesFoldout = false;
-
- [SerializeField]
- private List<CustomExpressionDependency> m_dependencies = new List<CustomExpressionDependency>();
-
- private int m_markedToDelete = -1;
- private const float ButtonLayoutWidth = 15;
-
- private bool m_repopulateNameDictionary = true;
- private Dictionary<string, int> m_usedNames = new Dictionary<string, int>();
-
- private double m_lastTimeNameModified = 0;
- private bool m_nameModified = false;
-
- private double m_lastTimeCodeModified = 0;
- private bool m_codeModified = false;
-
- //Title editing
- private bool m_isEditing;
- private bool m_stopEditing;
- private bool m_startEditing;
- private double m_clickTime;
- private double m_doubleClickTime = 0.3;
- private Rect m_titleClickArea;
-
- //Item Reordable List
- private ReordableAction m_actionType = ReordableAction.None;
- private int m_actionIndex = 0;
- private int m_lastIndex = 0;
-
- private ReorderableList m_itemReordableList = null;
- private ReorderableList m_dependenciesReordableList = null;
-
- protected override void CommonInit( int uniqueId )
- {
- base.CommonInit( uniqueId );
- AddInputPort( WirePortDataType.FLOAT, false, "In0" );
- m_items.Add( new CustomExpressionInputItem( PrecisionType.Float, VariableQualifiers.In, string.Empty, true, string.Empty/*"[0]"*/ ) );
- AddOutputPort( WirePortDataType.FLOAT, "Out" );
- m_textLabelWidth = 97;
- }
-
- protected override void OnUniqueIDAssigned()
- {
- base.OnUniqueIDAssigned();
-
- if( m_mode == CustomExpressionMode.Create )
- m_containerGraph.CustomExpressionOnFunctionMode.AddNode( this );
-
- SetTitleText( m_customExpressionName );
-
- if( m_nodeAttribs != null )
- m_uniqueName = m_nodeAttribs.Name + OutputId;
- else
- m_uniqueName = "CustomExpression" + OutputId;
- }
-
- public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
- {
- base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode );
- CheckPortConnection( portId );
- }
-
- public override void OnConnectedOutputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
- {
- base.OnConnectedOutputNodeChanges( portId, otherNodeId, otherPortId, name, type );
- CheckPortConnection( portId );
- }
-
- void CheckPortConnection( int portId )
- {
- if( portId == 0 && ( m_mode == CustomExpressionMode.Call || m_voidMode ) )
- {
- m_inputPorts[ 0 ].MatchPortToConnection();
- m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false );
- }
- }
-
- public override void OnNodeLogicUpdate( DrawInfo drawInfo )
- {
- base.OnNodeLogicUpdate( drawInfo );
- if( m_nameModified )
- {
- if( ( EditorApplication.timeSinceStartup - m_lastTimeNameModified ) > MaxTimestamp )
- {
- m_nameModified = false;
- m_repopulateNameDictionary = true;
- }
- }
-
- if( m_repopulateNameDictionary )
- {
- m_repopulateNameDictionary = false;
- m_usedNames.Clear();
- for( int i = 0; i < m_inputPorts.Count; i++ )
- {
- m_usedNames.Add( m_inputPorts[ i ].Name, i );
- }
- }
-
- if( m_codeModified )
- {
- if( ( EditorApplication.timeSinceStartup - m_lastTimeCodeModified ) > MaxTimestamp )
- {
- m_codeModified = false;
- bool functionMode = m_code.Contains( ReturnHelper );
- if( functionMode != m_functionMode )
- {
- m_functionMode = functionMode;
- CheckCallMode();
- }
- }
- }
- }
-
- bool CheckCallMode()
- {
- if( m_functionMode && m_mode == CustomExpressionMode.Call )
- {
- Mode = CustomExpressionMode.Create;
- m_outputTypeIdx = ( AvailableOutputWireTypesStr.Length - 1 );
- m_outputPorts[ 0 ].ChangeType( AvailableOutputWireTypes[ m_outputTypeIdx ], false );
- m_voidMode = true;
- return true;
- }
- return false;
- }
-
- public override void Draw( DrawInfo drawInfo )
- {
- base.Draw( drawInfo );
- if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 )
- {
- if( !m_isEditing && ( ( !ContainerGraph.ParentWindow.MouseInteracted && drawInfo.CurrentEventType == EventType.MouseDown && m_titleClickArea.Contains( drawInfo.MousePosition ) ) ) )
- {
- if( ( EditorApplication.timeSinceStartup - m_clickTime ) < m_doubleClickTime )
- m_startEditing = true;
- else
- GUI.FocusControl( null );
- m_clickTime = EditorApplication.timeSinceStartup;
- }
- else if( m_isEditing && ( ( drawInfo.CurrentEventType == EventType.MouseDown && !m_titleClickArea.Contains( drawInfo.MousePosition ) ) || !EditorGUIUtility.editingTextField ) )
- {
- m_stopEditing = true;
- }
-
- if( m_isEditing || m_startEditing )
- {
- EditorGUI.BeginChangeCheck();
- GUI.SetNextControlName( m_uniqueName );
- m_customExpressionName = EditorGUITextField( m_titleClickArea, string.Empty, m_customExpressionName, UIUtils.GetCustomStyle( CustomStyle.NodeTitle ) );
- if( EditorGUI.EndChangeCheck() )
- {
- SetTimedUpdate( 2 );
- SetTitleText( m_customExpressionName );
- m_sizeIsDirty = true;
- m_isDirty = true;
- }
-
- if( m_startEditing )
- EditorGUI.FocusTextInControl( m_uniqueName );
- }
-
- if( drawInfo.CurrentEventType == EventType.Repaint )
- {
- if( m_startEditing )
- {
- m_startEditing = false;
- m_isEditing = true;
- }
-
- if( m_stopEditing )
- {
- m_stopEditing = false;
- m_isEditing = false;
- GUI.FocusControl( null );
- }
- }
- }
- }
-
- public override void OnNodeLayout( DrawInfo drawInfo )
- {
- base.OnNodeLayout( drawInfo );
- m_titleClickArea = m_titlePos;
- m_titleClickArea.height = Constants.NODE_HEADER_HEIGHT;
- }
-
- public override void OnNodeRepaint( DrawInfo drawInfo )
- {
- base.OnNodeRepaint( drawInfo );
- if( !m_isVisible )
- return;
-
- // Fixed Title ( only renders when not editing )
- if( !m_isEditing && !m_startEditing && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 )
- {
- GUI.Label( m_titleClickArea, m_content, UIUtils.GetCustomStyle( CustomStyle.NodeTitle ) );
- }
- }
-
- public string GetFirstAvailableName()
- {
- string name = string.Empty;
- for( int i = 0; i < m_inputPorts.Count + 1; i++ )
- {
- name = DefaultInputNameStr + i;
- if( !m_usedNames.ContainsKey( name ) )
- {
- return name;
- }
- }
- Debug.LogWarning( "Could not find valid name" );
- return string.Empty;
- }
-
- public override void DrawProperties()
- {
- base.DrawProperties();
- NodeUtils.DrawPropertyGroup( ref m_propertiesFoldout, Constants.ParameterLabelStr, DrawBaseProperties );
- //NodeUtils.DrawPropertyGroup( ref m_visibleInputsFoldout, InputsStr, DrawInputs, DrawAddRemoveInputs );
- NodeUtils.DrawPropertyGroup( ref m_visibleInputsFoldout, InputsStr, DrawReordableInputs, DrawItemsAddRemoveInputs );
-
- EditorGUILayout.HelpBox( CustomExpressionInfo, MessageType.Info );
- }
-
- string WrapCodeInFunction( bool isTemplate, string functionName, bool expressionMode )
- {
- //Hack to be used util indent is properly used
- int currIndent = UIUtils.ShaderIndentLevel;
- UIUtils.ShaderIndentLevel = isTemplate ? 0 : 1;
-
- if( !isTemplate ) UIUtils.ShaderIndentLevel++;
-
- //string functionName = UIUtils.RemoveInvalidCharacters( m_customExpressionName );
- string returnType = ( m_mode == CustomExpressionMode.Call || m_voidMode ) ? "void" : UIUtils.PrecisionWirePortToCgType( m_currentPrecisionType, m_outputPorts[ 0 ].DataType );
- if( expressionMode )
- returnType = "inline " + returnType;
-
- string functionBody = UIUtils.ShaderIndentTabs + returnType + " " + functionName + "( ";
- int count = m_inputPorts.Count - m_firstAvailablePort;
- for( int i = 0; i < count; i++ )
- {
- int portIdx = i + m_firstAvailablePort;
- string qualifier = m_items[ i ].Qualifier == VariableQualifiers.In ? string.Empty : UIUtils.QualifierToCg( m_items[ i ].Qualifier ) + " ";
- PrecisionType precision = ( (int)m_items[ i ].Precision > (int)m_currentPrecisionType ) ? m_items[ i ].Precision : m_currentPrecisionType;
- string dataType = ( m_inputPorts[ portIdx ].DataType == WirePortDataType.OBJECT ) ? m_items[ i ].CustomType : UIUtils.PrecisionWirePortToCgType( precision, m_inputPorts[ portIdx ].DataType );
- functionBody += qualifier + dataType + " " + m_inputPorts[ portIdx ].Name;
- if( i < ( count - 1 ) )
- {
- functionBody += " , ";
- }
- }
- functionBody += " )\n" + UIUtils.ShaderIndentTabs + "{\n";
- UIUtils.ShaderIndentLevel++;
- {
- if( expressionMode )
- functionBody += UIUtils.ShaderIndentTabs + "return ";
-
- string[] codeLines = m_code.Split( IOUtils.LINE_TERMINATOR );
- for( int i = 0; i < codeLines.Length; i++ )
- {
- if( codeLines[ i ].Length > 0 )
- {
- functionBody += ( ( i == 0 && expressionMode ) ? string.Empty : UIUtils.ShaderIndentTabs ) + codeLines[ i ] + ( ( ( i == codeLines.Length - 1 ) && expressionMode ) ? string.Empty : "\n" );
- }
- }
- if( expressionMode )
- functionBody += ";\n";
- }
- UIUtils.ShaderIndentLevel--;
-
- functionBody += UIUtils.ShaderIndentTabs + "}\n";
- UIUtils.ShaderIndentLevel = currIndent;
- return functionBody;
- }
-
- void DrawBaseProperties()
- {
- EditorGUI.BeginChangeCheck();
- m_customExpressionName = EditorGUILayoutTextField( ExpressionNameLabelStr, m_customExpressionName );
- if( EditorGUI.EndChangeCheck() )
- {
- SetTimedUpdate( 2 );
- SetTitleText( m_customExpressionName );
- }
-
- EditorGUI.BeginChangeCheck();
- Mode = (CustomExpressionMode)EditorGUILayoutEnumPopup( FunctionCallModeStr, m_mode );
- if( EditorGUI.EndChangeCheck() )
- {
- if( CheckCallMode() )
- UIUtils.ShowMessage( "Call Mode cannot have return over is code.\nFalling back to Create Mode" );
- SetupCallMode();
- RecalculateInOutOutputPorts();
- }
-
- EditorGUILayout.LabelField( CodeTitleStr );
- EditorGUI.BeginChangeCheck();
- {
- m_code = EditorGUILayoutTextArea( m_code, UIUtils.MainSkin.textArea );
- }
- if( EditorGUI.EndChangeCheck() )
- {
- m_codeModified = true;
- m_lastTimeCodeModified = EditorApplication.timeSinceStartup;
- }
-
- if( m_mode == CustomExpressionMode.Create )
- {
- DrawPrecisionProperty();
-
- bool guiEnabled = GUI.enabled;
-
- GUI.enabled = !AutoRegisterMode;
- m_generateUniqueName = EditorGUILayoutToggle( GenerateUniqueNameStr, m_generateUniqueName ) && !AutoRegisterMode;
-
- GUI.enabled = !m_generateUniqueName;
- AutoRegisterMode = EditorGUILayoutToggle( AutoRegisterStr, AutoRegisterMode ) && !m_generateUniqueName;
-
- GUI.enabled = guiEnabled;
-
- EditorGUI.BeginChangeCheck();
- m_outputTypeIdx = EditorGUILayoutPopup( OutputTypeStr, m_outputTypeIdx, AvailableOutputWireTypesStr );
- if( EditorGUI.EndChangeCheck() )
- {
- bool oldVoidValue = m_voidMode;
- UpdateVoidMode();
- if( oldVoidValue != m_voidMode )
- {
- SetupCallMode();
- RecalculateInOutOutputPorts();
- }
- else
- {
- m_outputPorts[ 0 ].ChangeType( AvailableOutputWireTypes[ m_outputTypeIdx ], false );
- }
- }
- }
- NodeUtils.DrawNestedPropertyGroup( ref m_dependenciesFoldout, "Dependencies", DrawDependencies, DrawDependenciesAddRemoveInputs );
- }
-
- void UpdateVoidMode()
- {
- m_voidMode = ( m_outputTypeIdx == ( AvailableOutputWireTypesStr.Length - 1 ) );
- }
-
- void SetupCallMode()
- {
- if( m_mode == CustomExpressionMode.Call || m_voidMode )
- {
- if( m_firstAvailablePort != 1 )
- {
- m_firstAvailablePort = 1;
- AddInputPortAt( 0, WirePortDataType.FLOAT, false, DefaultInputNameStr );
- m_outputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT, false );
- }
- }
- else
- {
- if( m_firstAvailablePort != 0 )
- {
- m_firstAvailablePort = 0;
- if( m_inputPorts[ 0 ].IsConnected )
- {
- m_containerGraph.DeleteConnection( true, UniqueId, m_inputPorts[ 0 ].PortId, false, true );
- }
- DeleteInputPortByArrayIdx( 0 );
- m_outputPorts[ 0 ].ChangeType( AvailableOutputWireTypes[ m_outputTypeIdx ], false );
- }
- }
- }
-
- void DrawItemsAddRemoveInputs()
- {
- if( m_inputPorts.Count == m_firstAvailablePort )
- m_visibleInputsFoldout = false;
-
- // Add new port
- if( GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ButtonLayoutWidth ) ) )
- {
- AddPortAt( m_inputPorts.Count );
- m_visibleInputsFoldout = true;
- EditorGUI.FocusTextInControl( null );
- }
-
- //Remove port
- if( GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ButtonLayoutWidth ) ) )
- {
- RemovePortAt( m_inputPorts.Count - 1 );
- EditorGUI.FocusTextInControl( null );
- }
- }
-
- void DrawDependenciesAddRemoveInputs()
- {
- // Add new port
- if( GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ButtonLayoutWidth ) ) )
- {
- m_dependencies.Add( new CustomExpressionDependency() );
- EditorGUI.FocusTextInControl( null );
- }
-
- //Remove port
- if( GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ButtonLayoutWidth ) ) )
- {
- m_dependencies.RemoveAt( m_dependencies.Count - 1 );
- }
- }
-
- void DrawDependencies()
- {
- if( m_dependenciesReordableList == null )
- {
- m_dependenciesReordableList = new ReorderableList( m_dependencies, typeof( CustomExpressionDependency ), true, false, false, false )
- {
- headerHeight = 0,
- footerHeight = 0,
- showDefaultBackground = false,
- drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) =>
- {
- if( m_dependencies[ index ] != null )
- {
- rect.xMin -= 1;
-
- Rect popupPos = new Rect( rect.x, rect.y, rect.width - 2 * Constants.PlusMinusButtonLayoutWidth, EditorGUIUtility.singleLineHeight );
- Rect buttonPlusPos = new Rect( rect.x + rect.width - 2 * Constants.PlusMinusButtonLayoutWidth, rect.y - 2, Constants.PlusMinusButtonLayoutWidth, Constants.PlusMinusButtonLayoutWidth );
- Rect buttonMinusPos = new Rect( rect.x + rect.width - Constants.PlusMinusButtonLayoutWidth, rect.y - 2, Constants.PlusMinusButtonLayoutWidth, Constants.PlusMinusButtonLayoutWidth );
- EditorGUI.BeginChangeCheck();
- m_dependencies[ index ].DependencyArrayIdx = EditorGUIPopup( popupPos, string.Empty, m_dependencies[ index ].DependencyArrayIdx, m_containerGraph.CustomExpressionOnFunctionMode.NodesArr );
- if( EditorGUI.EndChangeCheck() )
- {
- m_dependencies[ index ].DependencyNodeId = m_containerGraph.CustomExpressionOnFunctionMode.GetNode( m_dependencies[ index ].DependencyArrayIdx ).UniqueId;
- if( m_dependencies[ index ].DependencyNodeId == UniqueId )
- {
- m_dependencies[ index ].Reset();
- }
- }
-
- if( GUI.Button( buttonPlusPos, string.Empty, UIUtils.PlusStyle ) )
- {
- m_actionType = ReordableAction.Add;
- m_actionIndex = index;
- }
-
- if( GUI.Button( buttonMinusPos, string.Empty, UIUtils.MinusStyle ) )
- {
- m_actionType = ReordableAction.Remove;
- m_actionIndex = index;
- }
- }
- }
- };
- }
-
- if( m_dependenciesReordableList != null )
- {
- EditorGUILayout.Space();
- if( m_dependencies.Count == 0 )
- {
- EditorGUILayout.HelpBox( "Your list is Empty!\nUse the plus button to add one.", MessageType.Info );
- }
- else
- {
- m_dependenciesReordableList.DoLayoutList();
- }
- EditorGUILayout.Space();
- }
-
- if( m_actionType != ReordableAction.None )
- {
- switch( m_actionType )
- {
- case ReordableAction.Add:
- m_dependencies.Insert( m_actionIndex + 1, new CustomExpressionDependency() );
- break;
- case ReordableAction.Remove:
- m_dependencies.RemoveAt( m_actionIndex );
- break;
- }
- m_isDirty = true;
- m_actionType = ReordableAction.None;
- EditorGUI.FocusTextInControl( null );
- }
- }
-
- void DrawReordableInputs()
- {
- if( m_itemReordableList == null )
- {
- m_itemReordableList = new ReorderableList( m_items, typeof( CustomExpressionInputItem ), true, false, false, false )
- {
- headerHeight = 0,
- footerHeight = 0,
- showDefaultBackground = false,
- elementHeightCallback = ( int index ) =>
- {
- float lineHeight = EditorGUIUtility.singleLineHeight * LineAdjust;
- if( m_items[ index ].FoldoutFlag )
- {
- float size = 7 * lineHeight;
-
- if( m_inputPorts[ m_firstAvailablePort + index ].DataType == WirePortDataType.OBJECT )
- size += lineHeight;
-
- if( !m_inputPorts[ m_firstAvailablePort + index ].IsConnected )
- {
- switch( m_inputPorts[ m_firstAvailablePort + index ].DataType )
- {
- case WirePortDataType.INT:
- case WirePortDataType.FLOAT:
- size += 0;// lineHeight;
- break;
- case WirePortDataType.FLOAT2:
- case WirePortDataType.FLOAT3:
- case WirePortDataType.FLOAT4:
- size += lineHeight;//2 * lineHeight;
- break;
- case WirePortDataType.FLOAT3x3:
- size += 5 * lineHeight;//6 * lineHeight;
- break;
- case WirePortDataType.FLOAT4x4:
- size += 6 * lineHeight;//8 * lineHeight;
- break;
-
- }
- }
-
- return size;
- }
- else
- {
- return lineHeight;
- }
- },
-
- onReorderCallback = ( ReorderableList list ) =>
- {
- int realLastIndex = m_firstAvailablePort + m_lastIndex;
- int realCurrIndex = m_firstAvailablePort + list.index;
- SwapInputPorts( realLastIndex, realCurrIndex );
- },
- onSelectCallback = ( ReorderableList list ) =>
- {
- m_lastIndex = list.index;
- },
- drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) =>
- {
- if( m_items[ index ] != null )
- {
- float lineHeight = EditorGUIUtility.singleLineHeight;
- float lineSpacing = lineHeight * LineAdjust;
-
- rect.x -= IdentationAdjust;
- rect.height = lineHeight;
- int portIdx = index + m_firstAvailablePort;
- Rect foldoutRect = rect;
- if( !m_items[ index ].FoldoutFlag )
- {
- foldoutRect.width -= 2 * AddRemoveButtonLayoutWidth;
- }
- m_items[ index ].FoldoutFlag = EditorGUIFoldout( foldoutRect, m_items[ index ].FoldoutFlag, /*m_items[ index ].FoldoutLabel + " - " +*/ m_inputPorts[ portIdx ].Name );
- if( m_items[ index ].FoldoutFlag )
- {
- rect.x += IdentationAdjust;
-
- //Qualifier
- rect.y += lineSpacing;
- VariableQualifiers newQualifier = (VariableQualifiers)EditorGUIPopup( rect, InputQualifierStr, (int)m_items[ index ].Qualifier, QualifiersStr );
- if( newQualifier != m_items[ index ].Qualifier )
- {
- VariableQualifiers oldQualifier = m_items[ index ].Qualifier;
- m_items[ index ].Qualifier = newQualifier;
- if( newQualifier == VariableQualifiers.In )
- {
- RemoveOutputPort( CreateOutputId( m_inputPorts[ portIdx ].PortId ), false );
- }
- else if( oldQualifier == VariableQualifiers.In )
- {
- AddOutputPort( m_inputPorts[ portIdx ].DataType, m_inputPorts[ portIdx ].Name, CreateOutputId( m_inputPorts[ portIdx ].PortId ) );
- }
- m_inputPorts[ portIdx ].Visible = newQualifier != VariableQualifiers.Out;
- m_sizeIsDirty = true;
- RecalculateInOutOutputPorts();
- }
-
- // Precision
- rect.y += lineSpacing;
- m_items[ index ].Precision = (PrecisionType)EditorGUIPopup(rect, PrecisionContent.text, (int)m_items[ index ].Precision, PrecisionLabels );
- // Type
- rect.y += lineSpacing;
- int typeIdx = WireToIdx[ m_inputPorts[ portIdx ].DataType ];
- EditorGUI.BeginChangeCheck();
- {
- typeIdx = EditorGUIPopup( rect, InputTypeStr, typeIdx, AvailableWireTypesStr );
- }
-
- if( EditorGUI.EndChangeCheck() )
- {
- m_inputPorts[ portIdx ].ChangeType( AvailableWireTypes[ typeIdx ], false );
- if( m_items[ index ].Qualifier != VariableQualifiers.In )
- {
- OutputPort currOutPort = GetOutputPortByUniqueId( CreateOutputId( m_inputPorts[ portIdx ].PortId ) );
- currOutPort.ChangeType( AvailableWireTypes[ typeIdx ], false );
- }
- }
-
- if( AvailableWireTypes[ typeIdx ] == WirePortDataType.OBJECT )
- {
- rect.y += lineSpacing;
- m_items[ index ].CustomType = EditorGUITextField( rect, CustomTypeStr, m_items[ index ].CustomType );
- }
-
- //Name
- rect.y += lineSpacing;
- EditorGUI.BeginChangeCheck();
- {
- m_inputPorts[ portIdx ].Name = EditorGUITextField( rect, InputNameStr, m_inputPorts[ portIdx ].Name );
- }
- if( EditorGUI.EndChangeCheck() )
- {
- m_nameModified = true;
- m_lastTimeNameModified = EditorApplication.timeSinceStartup;
- m_inputPorts[ portIdx ].Name = UIUtils.RemoveInvalidCharacters( m_inputPorts[ portIdx ].Name );
- if( string.IsNullOrEmpty( m_inputPorts[ portIdx ].Name ) )
- {
- m_inputPorts[ portIdx ].Name = DefaultInputNameStr + index;
- }
-
- if( m_items[ index ].Qualifier != VariableQualifiers.In )
- {
- OutputPort currOutPort = GetOutputPortByUniqueId( CreateOutputId( m_inputPorts[ portIdx ].PortId ) );
- currOutPort.Name = m_inputPorts[ portIdx ].Name;
- }
- }
-
- // Port Data
- if( !m_inputPorts[ portIdx ].IsConnected )
- {
- rect.y += lineSpacing;
- m_inputPorts[ portIdx ].ShowInternalData( rect, this, true, InputValueStr );
- }
-
- //Buttons
- rect.x += rect.width - 2 * AddRemoveButtonLayoutWidth;
- rect.y += lineSpacing;
- if( !m_inputPorts[ m_firstAvailablePort + index ].IsConnected )
- {
- switch( m_inputPorts[ m_firstAvailablePort + index ].DataType )
- {
- case WirePortDataType.INT:
- case WirePortDataType.FLOAT:
- rect.y += 0;// lineSpacing;
- break;
- case WirePortDataType.FLOAT2:
- case WirePortDataType.FLOAT3:
- case WirePortDataType.FLOAT4:
- rect.y += lineSpacing;//2 * lineSpacing;
- break;
- case WirePortDataType.FLOAT3x3:
- rect.y += 5 * lineSpacing;//6 * lineSpacing;
- break;
- case WirePortDataType.FLOAT4x4:
- rect.y += 6 * lineSpacing;//8 * lineSpacing;
- break;
-
- }
- }
- rect.width = AddRemoveButtonLayoutWidth;
- if( GUI.Button( rect, string.Empty, UIUtils.PlusStyle ) )
- {
- m_actionType = ReordableAction.Add;
- m_actionIndex = index;
- }
- rect.x += AddRemoveButtonLayoutWidth;
- if( GUI.Button( rect, string.Empty, UIUtils.MinusStyle ) )
- {
- m_actionType = ReordableAction.Remove;
- m_actionIndex = index;
- }
-
- }
- else
- {
- //Buttons
- rect.x += IdentationAdjust + rect.width - 2 * AddRemoveButtonLayoutWidth;
- rect.width = AddRemoveButtonLayoutWidth;
- if( GUI.Button( rect, string.Empty, UIUtils.PlusStyle ) )
- {
- m_actionType = ReordableAction.Add;
- m_actionIndex = index;
- }
- rect.x += AddRemoveButtonLayoutWidth;
- if( GUI.Button( rect, string.Empty, UIUtils.MinusStyle ) )
- {
- m_actionType = ReordableAction.Remove;
- m_actionIndex = index;
- }
- }
- }
- }
- };
- }
-
- ///////////////////////////////////
- if( m_itemReordableList != null )
- {
- EditorGUILayout.Space();
- if( m_items.Count == 0 )
- {
- EditorGUILayout.HelpBox( "Your list is Empty!\nUse the plus button to add one.", MessageType.Info );
- }
- else
- {
- m_itemReordableList.DoLayoutList();
- }
- EditorGUILayout.Space();
- }
-
- if( m_actionType != ReordableAction.None )
- {
- switch( m_actionType )
- {
- case ReordableAction.Add:
- AddPortAt( m_firstAvailablePort + m_actionIndex + 1 );
- break;
- case ReordableAction.Remove:
- RemovePortAt( m_firstAvailablePort + m_actionIndex );
- break;
- }
- m_isDirty = true;
- m_actionType = ReordableAction.None;
- EditorGUI.FocusTextInControl( null );
- }
- }
-
-
- void DrawInputs()
- {
- int count = m_inputPorts.Count - m_firstAvailablePort;
- for( int i = 0; i < count; i++ )
- {
- int portIdx = i + m_firstAvailablePort;
- m_items[ i ].FoldoutFlag = EditorGUILayoutFoldout( m_items[ i ].FoldoutFlag, /*m_items[ i ].FoldoutLabel + " - " +*/ m_inputPorts[ portIdx ].Name );
-
- if( m_items[ i ].FoldoutFlag )
- {
- EditorGUI.indentLevel += 1;
-
- //Qualifier
- VariableQualifiers newQualifier = (VariableQualifiers)EditorGUILayoutPopup( InputQualifierStr, (int)m_items[ i ].Qualifier, QualifiersStr );
- if( newQualifier != m_items[ i ].Qualifier )
- {
- VariableQualifiers oldQualifier = m_items[ i ].Qualifier;
- m_items[ i ].Qualifier = newQualifier;
- if( newQualifier == VariableQualifiers.In )
- {
- RemoveOutputPort( CreateOutputId( m_inputPorts[ portIdx ].PortId ), false );
- }
- else if( oldQualifier == VariableQualifiers.In )
- {
- AddOutputPort( m_inputPorts[ portIdx ].DataType, m_inputPorts[ portIdx ].Name, CreateOutputId( m_inputPorts[ portIdx ].PortId ) );
- }
- RecalculateInOutOutputPorts();
- }
-
- // Type
- int typeIdx = WireToIdx[ m_inputPorts[ portIdx ].DataType ];
- EditorGUI.BeginChangeCheck();
- {
- typeIdx = EditorGUILayoutPopup( InputTypeStr, typeIdx, AvailableWireTypesStr );
- }
-
- if( EditorGUI.EndChangeCheck() )
- {
- m_inputPorts[ portIdx ].ChangeType( AvailableWireTypes[ typeIdx ], false );
- if( m_items[ i ].Qualifier != VariableQualifiers.In )
- {
- OutputPort currOutPort = GetOutputPortByUniqueId( CreateOutputId( m_inputPorts[ portIdx ].PortId ) );
- currOutPort.ChangeType( AvailableWireTypes[ typeIdx ], false );
- }
- }
-
- if( AvailableWireTypes[ typeIdx ] == WirePortDataType.OBJECT )
- {
- EditorGUI.indentLevel += 1;
- m_items[ i ].CustomType = EditorGUILayoutTextField( CustomTypeStr, m_items[ i ].CustomType );
- EditorGUI.indentLevel -= 1;
- }
-
- //Name
- EditorGUI.BeginChangeCheck();
- {
- m_inputPorts[ portIdx ].Name = EditorGUILayoutTextField( InputNameStr, m_inputPorts[ portIdx ].Name );
- }
- if( EditorGUI.EndChangeCheck() )
- {
- m_nameModified = true;
- m_lastTimeNameModified = EditorApplication.timeSinceStartup;
- m_inputPorts[ portIdx ].Name = UIUtils.RemoveInvalidCharacters( m_inputPorts[ portIdx ].Name );
- if( string.IsNullOrEmpty( m_inputPorts[ portIdx ].Name ) )
- {
- m_inputPorts[ portIdx ].Name = DefaultInputNameStr + i;
- }
- if( m_items[ i ].Qualifier != VariableQualifiers.In )
- {
- OutputPort currOutPort = GetOutputPortByUniqueId( CreateOutputId( m_inputPorts[ portIdx ].PortId ) );
- currOutPort.Name = m_inputPorts[ portIdx ].Name;
- }
- }
-
- // Port Data
- if( !m_inputPorts[ portIdx ].IsConnected )
- {
- m_inputPorts[ portIdx ].ShowInternalData( this, true, InputValueStr );
- }
-
- EditorGUILayout.BeginHorizontal();
- {
- GUILayout.Label( " " );
- // Add new port
- if( GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ButtonLayoutWidth ) ) )
- {
- AddPortAt( portIdx );
- EditorGUI.FocusTextInControl( null );
- }
-
- //Remove port
- if( GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ButtonLayoutWidth ) ) )
- {
- m_markedToDelete = portIdx;
- }
- }
- EditorGUILayout.EndHorizontal();
-
- EditorGUI.indentLevel -= 1;
- }
- }
-
- if( m_markedToDelete > -1 )
- {
- RemovePortAt( m_markedToDelete );
- m_markedToDelete = -1;
- EditorGUI.FocusTextInControl( null );
- }
- }
-
- void RecalculateInOutOutputPorts()
- {
- m_outputPorts.Sort( ( x, y ) => x.PortId.CompareTo( y.PortId ) );
-
- m_outputPortsDict.Clear();
- int count = m_inputPorts.Count - m_firstAvailablePort;
- int outputId = 1;
- for( int i = 0; i < count; i++ )
- {
- int idx = i + m_firstAvailablePort;
- if( m_items[ i ].Qualifier != VariableQualifiers.In )
- {
- m_outputPorts[ outputId ].ChangeProperties( m_inputPorts[ idx ].Name, m_inputPorts[ idx ].DataType, false );
- m_outputPorts[ outputId ].ChangePortId( CreateOutputId( m_inputPorts[ idx ].PortId ) );
- outputId++;
- }
- }
-
- int outCount = m_outputPorts.Count;
- for( int i = 0; i < outCount; i++ )
- {
- m_outputPortsDict.Add( m_outputPorts[ i ].PortId, m_outputPorts[ i ] );
- }
- }
-
- void AddPortAt( int idx )
- {
- AddInputPortAt( idx, WirePortDataType.FLOAT, false, GetFirstAvailableName() );
- m_items.Insert( idx - m_firstAvailablePort, new CustomExpressionInputItem( PrecisionType.Float, VariableQualifiers.In, string.Empty, true, string.Empty/* "[" + idx + "]"*/ ) );
- m_repopulateNameDictionary = true;
- }
-
- void RemovePortAt( int idx )
- {
- if( m_inputPorts.Count > m_firstAvailablePort )
- {
- bool recalculateOutputs = false;
- int varIdx = idx - m_firstAvailablePort;
- if( m_items[ varIdx ].Qualifier != VariableQualifiers.In )
- {
- RemoveOutputPort( CreateOutputId( m_inputPorts[ idx ].PortId ), false );
- recalculateOutputs = true;
- }
-
- DeleteInputPortByArrayIdx( idx );
- m_items.RemoveAt( varIdx );
-
- m_repopulateNameDictionary = true;
- if( recalculateOutputs )
- RecalculateInOutOutputPorts();
- }
- }
-
- public override void OnAfterDeserialize()
- {
- base.OnAfterDeserialize();
- m_repopulateNameDictionary = true;
- }
-
- public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
- {
- if( string.IsNullOrEmpty( m_code ) )
- {
- UIUtils.ShowMessage( "Custom Expression need to have code associated", MessageSeverity.Warning );
- return "0";
- }
-
- m_code = m_code.Replace( "\r\n", "\n" );
-
- bool codeContainsReturn = m_code.Contains( ReturnHelper );
- if( !codeContainsReturn && outputId != 0 && m_mode == CustomExpressionMode.Create && !m_voidMode )
- {
- UIUtils.ShowMessage( "Attempting to get value from inexisting inout/out variable", MessageSeverity.Warning );
- return "0";
- }
-
- int dependenciesCount = m_dependencies.Count;
- Dictionary<int, CustomExpressionNode> examinedNodes = new Dictionary<int, CustomExpressionNode>();
- for( int i = 0; i < dependenciesCount; i++ )
- {
- CustomExpressionNode node = m_containerGraph.GetNode( m_dependencies[ i ].DependencyNodeId ) as CustomExpressionNode;
- if( node != null )
- {
- node.CheckDependencies( ref dataCollector, ref examinedNodes );
- }
- }
- examinedNodes.Clear();
- examinedNodes = null;
-
-
- OutputPort outputPort = GetOutputPortByUniqueId( outputId );
- if( outputPort.IsLocalValue( dataCollector.PortCategory ) )
- return outputPort.LocalValue( dataCollector.PortCategory );
-
- string expressionName = UIUtils.RemoveInvalidCharacters( m_customExpressionName );
- string localVarName = "local" + expressionName;
-
- if( m_generateUniqueName )
- {
- expressionName += OutputId;
- }
- localVarName += OutputId;
-
- int count = m_inputPorts.Count;
- if( count > 0 )
- {
- if( m_mode == CustomExpressionMode.Call || m_voidMode )
- {
- string mainData = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
- RegisterLocalVariable( 0, string.Format( Constants.CodeWrapper, mainData ), ref dataCollector, localVarName );
- }
-
- if( codeContainsReturn )
- {
- string function = WrapCodeInFunction( dataCollector.IsTemplate, expressionName, false );
- string functionCall = expressionName + "( ";
- for( int i = m_firstAvailablePort; i < count; i++ )
- {
- string inputPortLocalVar = m_inputPorts[ i ].Name + OutputId;
- string result = m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector );
- dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, m_inputPorts[ i ].DataType, inputPortLocalVar, result );
- int idx = i - m_firstAvailablePort;
- if( m_items[ idx ].Qualifier != VariableQualifiers.In )
- {
- OutputPort currOutputPort = GetOutputPortByUniqueId( CreateOutputId( m_inputPorts[ i ].PortId ) );
- currOutputPort.SetLocalValue( inputPortLocalVar, dataCollector.PortCategory );
- }
- functionCall += inputPortLocalVar;
- if( i < ( count - 1 ) )
- {
- functionCall += " , ";
- }
- }
- functionCall += " )";
-
- if( m_mode == CustomExpressionMode.Call || m_voidMode )
- {
- dataCollector.AddLocalVariable( 0, functionCall + ";", true );
- }
- else
- {
- RegisterLocalVariable( 0, functionCall, ref dataCollector, localVarName );
- }
-
- dataCollector.AddFunction( expressionName, function );
- }
- else
- {
- string localCode = m_code;
- if( m_mode == CustomExpressionMode.Call || m_voidMode )
- {
- for( int i = m_firstAvailablePort; i < count; i++ )
- {
- string inputPortLocalVar = m_inputPorts[ i ].Name + OutputId;
- localCode = localCode.Replace( m_inputPorts[ i ].Name, inputPortLocalVar );
-
- if( m_inputPorts[ i ].IsConnected )
- {
- string result = m_inputPorts[ i ].GenerateShaderForOutput( ref dataCollector, m_inputPorts[ i ].DataType, true, true );
- dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, m_inputPorts[ i ].DataType, inputPortLocalVar, result );
- }
- else
- {
- dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, m_inputPorts[ i ].DataType, inputPortLocalVar, m_inputPorts[ i ].WrappedInternalData );
- }
- int idx = i - m_firstAvailablePort;
- if( m_items[ idx ].Qualifier != VariableQualifiers.In )
- {
- OutputPort currOutputPort = GetOutputPortByUniqueId( CreateOutputId( m_inputPorts[ i ].PortId ) );
- currOutputPort.SetLocalValue( inputPortLocalVar, dataCollector.PortCategory );
- }
- }
- string[] codeLines = localCode.Split( '\n' );
- for( int codeIdx = 0; codeIdx < codeLines.Length; codeIdx++ )
- {
- dataCollector.AddLocalVariable( 0, codeLines[ codeIdx ], true );
- }
- }
- else
- {
- string function = WrapCodeInFunction( dataCollector.IsTemplate, expressionName, true );
-
- string functionCall = expressionName + "( ";
- for( int i = m_firstAvailablePort; i < count; i++ )
- {
- string inputPortLocalVar = m_inputPorts[ i ].Name + OutputId;
- string result = m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector );
- dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, m_inputPorts[ i ].DataType, inputPortLocalVar, result );
- int idx = i - m_firstAvailablePort;
- if( m_items[ idx ].Qualifier != VariableQualifiers.In )
- {
- OutputPort currOutputPort = GetOutputPortByUniqueId( CreateOutputId( m_inputPorts[ i ].PortId ) );
- currOutputPort.SetLocalValue( inputPortLocalVar, dataCollector.PortCategory );
- }
- functionCall += inputPortLocalVar;
- if( i < ( count - 1 ) )
- {
- functionCall += " , ";
- }
- }
- functionCall += " )";
- RegisterLocalVariable( 0, functionCall, ref dataCollector, localVarName );
- dataCollector.AddFunction( expressionName, function );
- }
- }
-
- return outputPort.LocalValue( dataCollector.PortCategory );
- }
- else
- {
- if( m_code.Contains( ReturnHelper ) )
- {
- string function = WrapCodeInFunction( dataCollector.IsTemplate, expressionName, false );
- dataCollector.AddFunction( expressionName, function );
- string functionCall = expressionName + "()";
- RegisterLocalVariable( 0, functionCall, ref dataCollector, localVarName );
- }
- else
- {
- RegisterLocalVariable( 0, string.Format( Constants.CodeWrapper, m_code ), ref dataCollector, localVarName );
- }
-
- return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
- }
- }
-
- int CreateOutputId( int inputId )
- {
- return ( inputId + 1 );
- }
-
- int CreateInputId( int outputId )
- {
- return outputId - 1;
- }
-
- void UpdateOutputPorts()
- {
- int count = m_inputPorts.Count - m_firstAvailablePort;
- for( int i = 0; i < count; i++ )
- {
- if( m_items[ i ].Qualifier != VariableQualifiers.In )
- {
- int portIdx = i + m_firstAvailablePort;
- AddOutputPort( m_inputPorts[ portIdx ].DataType, m_inputPorts[ portIdx ].Name, CreateOutputId( m_inputPorts[ portIdx ].PortId ) );
- }
- }
- }
-
- public override void ReadFromString( ref string[] nodeParams )
- {
- // This node is, by default, created with one input port
- base.ReadFromString( ref nodeParams );
- m_code = GetCurrentParam( ref nodeParams );
- m_code = m_code.Replace( LineFeedSeparator, '\n' );
- m_code = m_code.Replace( Constants.SemiColonSeparator, ';' );
- m_outputTypeIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
- if( m_outputTypeIdx >= AvailableWireTypes.Length )
- {
- UIUtils.ShowMessage( "Sampler types were removed as a valid output custom expression type" );
- m_outputTypeIdx = 1;
- }
- UpdateVoidMode();
- m_outputPorts[ 0 ].ChangeType( AvailableWireTypes[ m_outputTypeIdx ], false );
-
- if( UIUtils.CurrentShaderVersion() > 12001 )
- {
- bool mode = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
- m_mode = mode ? CustomExpressionMode.Call : CustomExpressionMode.Create;
- if( m_mode == CustomExpressionMode.Call || m_voidMode )
- {
- m_firstAvailablePort = 1;
- AddInputPortAt( 0, WirePortDataType.FLOAT, false, DefaultInputNameStr );
- }
- }
-
- if( m_mode == CustomExpressionMode.Call )
- m_containerGraph.CustomExpressionOnFunctionMode.RemoveNode( this );
-
- int count = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
- if( count == 0 )
- {
- DeleteInputPortByArrayIdx( 0 );
- m_items.Clear();
- }
- else
- {
- for( int i = 0; i < count; i++ )
- {
- bool foldoutValue = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
- string name = GetCurrentParam( ref nodeParams );
- WirePortDataType type = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), GetCurrentParam( ref nodeParams ) );
- string internalData = GetCurrentParam( ref nodeParams );
- VariableQualifiers qualifier = VariableQualifiers.In;
- if( UIUtils.CurrentShaderVersion() > 12001 )
- {
- qualifier = (VariableQualifiers)Enum.Parse( typeof( VariableQualifiers ), GetCurrentParam( ref nodeParams ) );
- }
- string customType = string.Empty;
- if( UIUtils.CurrentShaderVersion() > 15311 )
- {
- customType = GetCurrentParam( ref nodeParams );
- }
- PrecisionType precision = PrecisionType.Float;
- if( UIUtils.CurrentShaderVersion() > 15607 )
- {
- precision = (PrecisionType)Enum.Parse( typeof( PrecisionType ), GetCurrentParam( ref nodeParams ));
- }
-
- int portIdx = i + m_firstAvailablePort;
- if( i == 0 )
- {
- m_inputPorts[ portIdx ].ChangeProperties( name, type, false );
- m_inputPorts[ portIdx ].Visible = qualifier != VariableQualifiers.Out;
- m_items[ 0 ].Qualifier = qualifier;
- m_items[ 0 ].FoldoutFlag = foldoutValue;
- m_items[ 0 ].CustomType = customType;
- m_items[ 0 ].Precision = precision;
- }
- else
- {
- m_items.Add( new CustomExpressionInputItem( precision, qualifier, customType, foldoutValue, string.Empty/*"[" + i + "]"*/ ) );
- AddInputPort( type, false, name );
- m_inputPorts[ m_inputPorts.Count -1 ].Visible = qualifier != VariableQualifiers.Out;
- }
- m_inputPorts[ i ].InternalData = internalData;
- }
- }
-
- if( UIUtils.CurrentShaderVersion() > 7205 )
- {
- m_customExpressionName = GetCurrentParam( ref nodeParams );
- SetTitleText( m_customExpressionName );
- }
-
- if( UIUtils.CurrentShaderVersion() > 14401 )
- {
- m_generateUniqueName = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
- }
-
- if( UIUtils.CurrentShaderVersion() > 15102 )
- {
- m_autoRegisterMode = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
- }
-
- if( UIUtils.CurrentShaderVersion() > 15403 )
- {
- int dependencyCount = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
- for( int i = 0; i < dependencyCount; i++ )
- {
- m_dependencies.Add( new CustomExpressionDependency( GetCurrentParam( ref nodeParams ) ) );
- }
- }
-
- if( m_mode == CustomExpressionMode.Create )
- {
- m_containerGraph.CustomExpressionOnFunctionMode.AddNode( this );
- }
- UpdateOutputPorts();
-
- m_repopulateNameDictionary = true;
- m_functionMode = m_code.Contains( ReturnHelper );
- CheckCallMode();
-
- }
-
- public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
- {
- base.WriteToString( ref nodeInfo, ref connectionsInfo );
-
- m_code = m_code.Replace( "\r\n", "\n" );
-
- string parsedCode = m_code.Replace( '\n', LineFeedSeparator );
- parsedCode = parsedCode.Replace( ';', Constants.SemiColonSeparator );
-
- IOUtils.AddFieldValueToString( ref nodeInfo, parsedCode );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_outputTypeIdx );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_mode == CustomExpressionMode.Call );
-
- int count = m_inputPorts.Count - m_firstAvailablePort;
- IOUtils.AddFieldValueToString( ref nodeInfo, count );
- for( int i = 0; i < count; i++ )
- {
- int portIdx = m_firstAvailablePort + i;
- IOUtils.AddFieldValueToString( ref nodeInfo, m_items[ i ].FoldoutFlag );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts[ portIdx ].Name );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts[ portIdx ].DataType );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts[ portIdx ].InternalData );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_items[ i ].Qualifier );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_items[ i ].CustomType );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_items[ i ].Precision );
- }
- IOUtils.AddFieldValueToString( ref nodeInfo, m_customExpressionName );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_generateUniqueName );
- IOUtils.AddFieldValueToString( ref nodeInfo, m_autoRegisterMode );
- count = m_dependencies.Count;
- IOUtils.AddFieldValueToString( ref nodeInfo, count );
- for( int i = 0; i < count; i++ )
- {
- IOUtils.AddFieldValueToString( ref nodeInfo, m_dependencies[ i ].DependencyNodeId );
- }
- }
-
- public override void Destroy()
- {
- base.Destroy();
- if( m_mode == CustomExpressionMode.Create )
- {
- m_containerGraph.CustomExpressionOnFunctionMode.RemoveNode( this );
- }
- m_items.Clear();
- m_items = null;
- m_dependencies.Clear();
- m_dependencies = null;
- m_itemReordableList = null;
- }
-
- public void CheckDependencies( ref MasterNodeDataCollector dataCollector, ref Dictionary<int, CustomExpressionNode> examinedNodes )
- {
- if( !examinedNodes.ContainsKey( UniqueId ) && m_mode == CustomExpressionMode.Create && !m_generateUniqueName )
- {
- int dependencyCount = m_dependencies.Count;
- for( int d = 0; d < dependencyCount; d++ )
- {
- if( !examinedNodes.ContainsKey( m_dependencies[ d ].DependencyNodeId ) )
- {
- CustomExpressionNode dNode = m_containerGraph.GetNode( m_dependencies[ d ].DependencyNodeId ) as CustomExpressionNode;
- if( dNode != null )
- {
- dNode.CheckDependencies( ref dataCollector, ref examinedNodes );
- }
- }
- }
- dataCollector.AddFunction( ExpressionName, EncapsulatedCode( dataCollector.IsTemplate ) );
- examinedNodes.Add( UniqueId, this );
- }
- }
-
- public string EncapsulatedCode( bool isTemplate )
- {
- string functionName = UIUtils.RemoveInvalidCharacters( m_customExpressionName );
- if( m_generateUniqueName )
- {
- functionName += OutputId;
- }
- return WrapCodeInFunction( isTemplate, functionName, false );
- }
-
- public CustomExpressionMode Mode
- {
- get { return m_mode; }
- set
- {
- if( m_mode != value )
- {
- m_mode = value;
- if( m_mode == CustomExpressionMode.Call )
- {
- AutoRegisterMode = false;
- m_generateUniqueName = false;
- m_containerGraph.CustomExpressionOnFunctionMode.RemoveNode( this );
- }
- else
- {
- m_containerGraph.CustomExpressionOnFunctionMode.AddNode( this );
- }
- }
- }
- }
-
- public string ExpressionName
- {
- get
- {
- string expressionName = UIUtils.RemoveInvalidCharacters( m_customExpressionName );
-
- if( m_generateUniqueName )
- {
- expressionName += OutputId;
- }
- return expressionName;
- }
- }
- public override string DataToArray { get { return m_customExpressionName; } }
- public bool AutoRegisterMode
- {
- get { return m_autoRegisterMode; }
- set
- {
- if( value != m_autoRegisterMode )
- {
- m_autoRegisterMode = value;
- }
- }
- }
-
- public override void RefreshExternalReferences()
- {
- base.RefreshExternalReferences();
- int portCount = m_inputPorts.Count;
- for( int i = 0; i < portCount; i++ )
- {
- if( m_inputPorts[ i ].DataType == WirePortDataType.COLOR )
- {
- m_inputPorts[ i ].ChangeType( WirePortDataType.FLOAT4, false ); ;
- }
- }
-
- int dependencyCount = m_dependencies.Count;
- for( int i = 0; i < dependencyCount; i++ )
- {
- m_dependencies[ i ].DependencyArrayIdx = m_containerGraph.CustomExpressionOnFunctionMode.GetNodeRegisterIdx( m_dependencies[ i ].DependencyNodeId );
- }
- }
-
- public override void FireTimedUpdate()
- {
- m_containerGraph.CustomExpressionOnFunctionMode.UpdateDataOnNode( UniqueId, m_customExpressionName );
- }
-
- public List<CustomExpressionDependency> Dependencies { get { return m_dependencies; } }
- }
- }
|