diff options
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc')
49 files changed, 6635 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/AppendNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/AppendNode.cs new file mode 100644 index 00000000..6318614b --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/AppendNode.cs @@ -0,0 +1,254 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "[Old]Append", "Vector Operators", "Append channels to create a new component",null,KeyCode.V,true,true,"Append",typeof(DynamicAppendNode))] + public sealed class AppendNode : ParentNode + { + private const string OutputTypeStr = "Output type"; + + [SerializeField] + private WirePortDataType m_selectedOutputType = WirePortDataType.FLOAT4; + + [SerializeField] + private int m_selectedOutputTypeInt = 2; + + [SerializeField] + private float[] m_defaultValues = { 0, 0, 0, 0 }; + private string[] m_defaultValuesStr = { "[0]", "[1]", "[2]", "[3]" }; + + private readonly string[] m_outputValueTypes ={ "Vector2", + "Vector3", + "Vector4", + "Color"}; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, "[0]" ); + AddInputPort( WirePortDataType.FLOAT, false, "[1]" ); + AddInputPort( WirePortDataType.FLOAT, false, "[2]" ); + AddInputPort( WirePortDataType.FLOAT, false, "[3]" ); + AddOutputPort( m_selectedOutputType, Constants.EmptyPortValue ); + m_textLabelWidth = 90; + m_autoWrapProperties = true; + m_previewShaderGUID = "d80ac81aabf643848a4eaa76f2f88d65"; + } + + 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; + } + } + } + + 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; + } + + UpdatePorts(); + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUILayout.BeginVertical(); + + EditorGUI.BeginChangeCheck(); + m_selectedOutputTypeInt = EditorGUILayoutPopup( OutputTypeStr, m_selectedOutputTypeInt, m_outputValueTypes ); + if ( EditorGUI.EndChangeCheck() ) + { + SetupPorts(); + } + + int count = 0; + switch ( m_selectedOutputType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + { + count = 4; + } + break; + case WirePortDataType.FLOAT3: + { + count = 3; + } + break; + case WirePortDataType.FLOAT2: + { + count = 2; + } + break; + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT: + case WirePortDataType.INT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + { } + break; + } + + for ( int i = 0; i < count; i++ ) + { + if ( !m_inputPorts[ i ].IsConnected ) + m_defaultValues[ i ] = EditorGUILayoutFloatField( m_defaultValuesStr[ i ], m_defaultValues[ i ] ); + } + + EditorGUILayout.EndVertical(); + } + void UpdatePorts() + { + m_sizeIsDirty = true; + ChangeOutputType( m_selectedOutputType, false ); + switch ( m_selectedOutputType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.OBJECT: + case WirePortDataType.COLOR: + { + m_inputPorts[ 0 ].Visible = true; + m_inputPorts[ 1 ].Visible = true; + m_inputPorts[ 2 ].Visible = true; + m_inputPorts[ 3 ].Visible = true; + } + break; + case WirePortDataType.FLOAT3: + { + m_inputPorts[ 0 ].Visible = true; + m_inputPorts[ 1 ].Visible = true; + m_inputPorts[ 2 ].Visible = true; + m_inputPorts[ 3 ].Visible = false; + if ( m_inputPorts[ 3 ].IsConnected ) + UIUtils.DeleteConnection( true, UniqueId, 3, false, true ); + } + break; + case WirePortDataType.FLOAT2: + { + m_inputPorts[ 0 ].Visible = true; + m_inputPorts[ 1 ].Visible = true; + m_inputPorts[ 2 ].Visible = false; + if ( m_inputPorts[ 2 ].IsConnected ) + UIUtils.DeleteConnection( true, UniqueId, 2, false, true ); + + m_inputPorts[ 3 ].Visible = false; + if ( m_inputPorts[ 3 ].IsConnected ) + UIUtils.DeleteConnection( true, UniqueId, 3, false, true ); + } + break; + case WirePortDataType.FLOAT: + case WirePortDataType.INT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + { } + break; + } + } + 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 value = string.Empty; + switch ( m_selectedOutputType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.OBJECT: + case WirePortDataType.COLOR: + { + value = "float4( "; + for ( int i = 0; i < 4; i++ ) + { + value += m_inputPorts[ i ].IsConnected ? InputPorts[ i ].GenerateShaderForOutput( ref dataCollector, WirePortDataType.FLOAT, ignoreLocalVar, true ) : m_defaultValues[ i ].ToString(); + if ( i != 3 ) + value += " , "; + } + value += " )"; + } + break; + case WirePortDataType.FLOAT3: + { + value = "float3( "; + for ( int i = 0; i < 3; i++ ) + { + value += m_inputPorts[ i ].IsConnected ? InputPorts[ i ].GenerateShaderForOutput( ref dataCollector, WirePortDataType.FLOAT, ignoreLocalVar, true ) : m_defaultValues[ i ].ToString(); + if ( i != 2 ) + value += " , "; + } + value += " )"; + } + break; + case WirePortDataType.FLOAT2: + { + value = "float2( "; + for ( int i = 0; i < 2; i++ ) + { + value += m_inputPorts[ i ].IsConnected ? InputPorts[ i ].GenerateShaderForOutput( ref dataCollector, WirePortDataType.FLOAT, ignoreLocalVar, true ) : m_defaultValues[ i ].ToString(); + if ( i != 1 ) + value += " , "; + } + value += " )"; + } + break; + case WirePortDataType.FLOAT: + case WirePortDataType.INT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + { } + break; + } + + RegisterLocalVariable( 0, value, 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; + } + for ( int i = 0; i < m_defaultValues.Length; i++ ) + { + m_defaultValues[ i ] = Convert.ToSingle( GetCurrentParam( ref nodeParams ) ); + } + UpdatePorts(); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedOutputType ); + for ( int i = 0; i < m_defaultValues.Length; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_defaultValues[ i ] ); + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/AppendNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/AppendNode.cs.meta new file mode 100644 index 00000000..bd513529 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/AppendNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 688412c534df41444ad49759fa2b6a62 +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/BreakToComponentsNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/BreakToComponentsNode.cs new file mode 100644 index 00000000..340ae384 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/BreakToComponentsNode.cs @@ -0,0 +1,273 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Break To Components", "Vector Operators", "Breaks the input data into its individual components", null, KeyCode.B, tags: "split" )] + public sealed class BreakToComponentsNode : ParentNode + { + private WirePortDataType m_currentType = WirePortDataType.FLOAT; + private readonly string[] ColorPortNames = { "R", "G", "B", "A" }; + private readonly string[] VectorPortNames = { "X", "Y", "Z", "W" }; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue ); + for( int i = 0; i < 16; i++ ) + { + AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + m_outputPorts[ i ].IndexPreviewOffset = 1; + if( i != 0 ) + { + m_outputPorts[ i ].Visible = false; + } + } + m_previewShaderGUID = "5f58f74a202ba804daddec838b75207d"; + } + + public override void RenderNodePreview() + { + //Runs at least one time + if( !m_initialized ) + { + // nodes with no preview don't update at all + PreviewIsDirty = false; + return; + } + + if( !PreviewIsDirty ) + return; + + SetPreviewInputs(); + + int count = m_outputPorts.Count; + for( int i = 0; i < count; i++ ) + { + RenderTexture temp = RenderTexture.active; + RenderTexture.active = m_outputPorts[ i ].OutputPreviewTexture; + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, Mathf.Min( i, 3 ) ); + RenderTexture.active = temp; + } + + PreviewIsDirty = m_continuousPreviewRefresh; + } + + public override RenderTexture PreviewTexture + { + get + { + return m_inputPorts[ 0 ].InputPreviewTexture( ContainerGraph ); + } + } + + void UpdateOutputs( WirePortDataType newType ) + { + //this only happens when on initial load + if( newType == WirePortDataType.OBJECT ) + return; + + m_currentType = newType; + switch( newType ) + { + case WirePortDataType.OBJECT: + { + m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.OBJECT, false ); + m_outputPorts[ 0 ].Visible = true; + for( int i = 1; i < m_outputPorts.Count; i++ ) + { + m_outputPorts[ i ].Visible = false; + } + } + break; + case WirePortDataType.FLOAT: + { + m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.FLOAT, false ); + m_outputPorts[ 0 ].Visible = true; + for( int i = 1; i < m_outputPorts.Count; i++ ) + { + m_outputPorts[ i ].Visible = false; + } + } + break; + case WirePortDataType.FLOAT2: + { + for( int i = 0; i < 2; i++ ) + { + m_outputPorts[ i ].ChangeProperties( VectorPortNames[ i ], WirePortDataType.FLOAT, false ); + m_outputPorts[ i ].Visible = true; + } + for( int i = 2; i < m_outputPorts.Count; i++ ) + { + m_outputPorts[ i ].Visible = false; + } + } + break; + case WirePortDataType.FLOAT3: + { + for( int i = 0; i < 3; i++ ) + { + m_outputPorts[ i ].ChangeProperties( VectorPortNames[ i ], WirePortDataType.FLOAT, false ); + m_outputPorts[ i ].Visible = true; + } + for( int i = 3; i < m_outputPorts.Count; i++ ) + { + m_outputPorts[ i ].Visible = false; + } + } + break; + case WirePortDataType.FLOAT4: + { + for( int i = 0; i < 4; i++ ) + { + m_outputPorts[ i ].ChangeProperties( VectorPortNames[ i ], WirePortDataType.FLOAT, false ); + m_outputPorts[ i ].Visible = true; + } + for( int i = 4; i < m_outputPorts.Count; i++ ) + { + m_outputPorts[ i ].Visible = false; + } + } + break; + case WirePortDataType.FLOAT3x3: + { + for( int i = 0; i < 9; i++ ) + { + m_outputPorts[ i ].ChangeProperties( "[" + (int)( i / 3 ) + "][" + i % 3 + "]", WirePortDataType.FLOAT, false ); + m_outputPorts[ i ].Visible = true; + } + for( int i = 9; i < m_outputPorts.Count; i++ ) + { + m_outputPorts[ i ].Visible = false; + } + } + break; + case WirePortDataType.FLOAT4x4: + { + for( int i = 0; i < 16; i++ ) + { + m_outputPorts[ i ].ChangeProperties( "[" + (int)( i / 4 ) + "][" + i % 4 + "]", WirePortDataType.FLOAT, false ); + m_outputPorts[ i ].Visible = true; + } + } + break; + case WirePortDataType.COLOR: + { + for( int i = 0; i < 4; i++ ) + { + m_outputPorts[ i ].ChangeProperties( ColorPortNames[ i ], WirePortDataType.FLOAT, false ); + m_outputPorts[ i ].Visible = true; + } + for( int i = 4; i < m_outputPorts.Count; i++ ) + { + m_outputPorts[ i ].Visible = false; + } + } + break; + case WirePortDataType.INT: + { + m_outputPorts[ 0 ].Visible = true; + m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.INT, false ); + for( int i = 1; i < m_outputPorts.Count; i++ ) + { + m_outputPorts[ i ].Visible = false; + } + } + break; + } + m_sizeIsDirty = true; + } + + public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type ); + m_inputPorts[ 0 ].MatchPortToConnection(); + UpdateOutputs( m_inputPorts[ 0 ].DataType ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_inputPorts[ 0 ].MatchPortToConnection(); + UpdateOutputs( m_inputPorts[ 0 ].DataType ); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentType ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + UpdateOutputs( (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), GetCurrentParam( ref nodeParams ) ) ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + { + return ReturnByType( m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ), outputId ); + } + + string value = string.Empty; + value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + + int channelsUsed = 0; + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + if( m_outputPorts[ i ].IsConnected ) + channelsUsed++; + } + string varName = "break" + OutputId; + if( channelsUsed > 1 ) + { + //RegisterLocalVariable( 0, value, ref dataCollector, varName ); + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ 0 ].DataType, varName, value ); + m_outputPorts[ 0 ].SetLocalValue( varName, dataCollector.PortCategory ); + + + value = varName; + } + + return ReturnByType( value, outputId ); + } + + private string ReturnByType( string value, int outputId ) + { + switch( m_inputPorts[ 0 ].DataType ) + { + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT: + case WirePortDataType.INT: + { + return value; + } + case WirePortDataType.FLOAT2: + case WirePortDataType.FLOAT3: + case WirePortDataType.FLOAT4: + { + return GetOutputVectorItem( 0, outputId + 1, value ); + } + case WirePortDataType.COLOR: + { + return GetOutputColorItem( 0, outputId + 1, value ); + } + case WirePortDataType.FLOAT3x3: + { + return value + "[ " + ( (int)( outputId / 3 ) ) + " ][ " + ( outputId % 3 ) + " ]"; + } + case WirePortDataType.FLOAT4x4: + { + return value + "[ " + ( (int)( outputId / 4 ) ) + " ][ " + ( outputId % 4 ) + " ]"; + } + } + return value; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/BreakToComponentsNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/BreakToComponentsNode.cs.meta new file mode 100644 index 00000000..34381d11 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/BreakToComponentsNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a74e2c0a9306c0048bfcc733cb7d154d +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/CustomExpressionNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/CustomExpressionNode.cs new file mode 100644 index 00000000..4c792b7f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/CustomExpressionNode.cs @@ -0,0 +1,1625 @@ +// 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; +using System.Text.RegularExpressions; + +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 IsVariable; + public bool FoldoutFlag; + public string FoldoutLabel; + + public CustomExpressionInputItem( PrecisionType precision, VariableQualifiers qualifier, string customType, bool isVariable, bool foldoutFlag, string foldoutLabel ) + { + Precision = precision; + Qualifier = qualifier; + CustomType = customType; + FoldoutFlag = foldoutFlag; + FoldoutLabel = foldoutLabel; + IsVariable = isVariable; + } + } + + [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 IsVariableStr = "Is Variable"; + 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 const string VarRegexReplacer = @"\b{0}\b"; + private readonly string[] PrecisionLabelsExtraLocal = { "Float", "Half", "Inherit Local" }; + + 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 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.Inherit, VariableQualifiers.In, string.Empty, false, true, string.Empty/*"[0]"*/ ) ); + AddOutputPort( WirePortDataType.FLOAT, "Out" ); + m_textLabelWidth = 97; + m_customPrecision = true; + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + + if( m_mode == CustomExpressionMode.Create ) + UIUtils.CurrentWindow.OutsideGraph.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_sizeIsDirty = true; + 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_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, 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( 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 = m_items[ i ].Precision; + if( precision == PrecisionType.Inherit ) + precision = 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( UniqueId, "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, UIUtils.CurrentWindow.OutsideGraph.CustomExpressionOnFunctionMode.NodesArr ); + if( EditorGUI.EndChangeCheck() ) + { + m_dependencies[ index ].DependencyNodeId = UIUtils.CurrentWindow.OutsideGraph.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; + + // Take Is Variable toggle into account + if( m_mode == CustomExpressionMode.Call ) + size += 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; + + InputPort portA = m_inputPorts[ realLastIndex ]; + int originalOutputPortId = CreateOutputId( portA.PortId ); + + SwapInputPorts( realLastIndex, realCurrIndex ); + + if( m_outputPorts.Count > 1 ) + { + if( list.index > m_lastIndex ) + { + for( int i = m_lastIndex; i <= list.index; i++ ) + { + if( m_items[ i ].Qualifier != VariableQualifiers.In ) + { + int portIdx = i + m_firstAvailablePort; + int oldOutputPortId; + if( i < list.index ) + { + int oldinputPortId = m_inputPorts[ portIdx ].PortId + 1; + oldOutputPortId = CreateOutputId( oldinputPortId ); + } + else + { + oldOutputPortId = originalOutputPortId; + } + + m_outputPortsDict[ oldOutputPortId ].ChangePortId( CreateOutputId( m_inputPorts[ portIdx ].PortId ) ); + } + } + } + else + { + for( int i = list.index; i <= m_lastIndex; i++ ) + { + if( m_items[ i ].Qualifier != VariableQualifiers.In ) + { + int portIdx = i + m_firstAvailablePort; + int oldOutputPortId; + if( i > list.index ) + { + int oldinputPortId = m_inputPorts[ portIdx ].PortId - 1; + oldOutputPortId = CreateOutputId( oldinputPortId ); + } + else + { + oldOutputPortId = originalOutputPortId; + } + + m_outputPortsDict[ oldOutputPortId ].ChangePortId( CreateOutputId( m_inputPorts[ portIdx ].PortId ) ); + } + } + } + } + + + m_outputPorts.Sort( ( A, B ) => + { + return A.PortId.CompareTo( B.PortId ); + } ); + + m_outputPortsDict.Clear(); + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + m_outputPortsDict.Add( m_outputPorts[ i ].PortId, m_outputPorts[ i ] ); + } + + }, + 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 ) + { + int outputId = CreateOutputId( m_inputPorts[ portIdx ].PortId ); + AddOutputPort( m_inputPorts[ portIdx ].DataType, m_inputPorts[ portIdx ].Name, outputId ); + } + 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, PrecisionLabelsExtraLocal ); + // 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( typeIdx == 5 || typeIdx == 6 ) + { + m_inputPorts[ portIdx ].Matrix4x4InternalData = Matrix4x4.identity; + } + + 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; + } + } + + if( m_mode == CustomExpressionMode.Call ) + { + //Is Unique + rect.y += lineSpacing; + m_items[ index ].IsVariable = EditorGUIToggle( rect, IsVariableStr, m_items[ index ].IsVariable ); + } + // 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 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.Inherit, VariableQualifiers.In, string.Empty, false, true, string.Empty/* "[" + idx + "]"*/ ) ); + m_repopulateNameDictionary = true; + RecalculateInOutOutputPorts(); + } + + void RemovePortAt( int idx ) + { + if( m_inputPorts.Count > m_firstAvailablePort ) + { + int varIdx = idx - m_firstAvailablePort; + if( m_items[ varIdx ].Qualifier != VariableQualifiers.In ) + { + int id = CreateOutputId( m_inputPorts[ idx ].PortId ); + RemoveOutputPort( id, false ); + } + + DeleteInputPortByArrayIdx( idx ); + m_items.RemoveAt( varIdx ); + + m_repopulateNameDictionary = true; + + 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( UniqueId, "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 = UIUtils.CurrentWindow.OutsideGraph.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; + int idx = i - m_firstAvailablePort; + if( m_inputPorts[ i ].DataType != WirePortDataType.OBJECT ) + { + string result = m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector ); + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ i ].DataType, inputPortLocalVar, result ); + } + else + { + string result =( m_inputPorts[ i ].IsConnected )? m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector) : m_inputPorts[ i ].InternalData.ToString(); + string inputLocalVar = string.Format( Constants.CustomTypeLocalValueDecWithoutIdent, m_items[ idx ].CustomType, inputPortLocalVar, result ); + dataCollector.AddLocalVariable( UniqueId, inputLocalVar ); + } + + 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++ ) + { + int idx = i - m_firstAvailablePort; + if( !m_items[ idx ].IsVariable || + m_items[ idx ].Qualifier != VariableQualifiers.In || + !m_inputPorts[ i ].IsConnected + ) + { + string inputPortLocalVar = m_inputPorts[ i ].Name + OutputId; + string nameToReplaceRegex = string.Format( VarRegexReplacer, m_inputPorts[ i ].Name ); + localCode = Regex.Replace( localCode, nameToReplaceRegex, inputPortLocalVar, RegexOptions.Multiline ); + //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 ); + if( m_inputPorts[ i ].DataType == WirePortDataType.OBJECT ) + { + dataCollector.AddLocalVariable( UniqueId, m_items[ idx ].CustomType + " " + inputPortLocalVar, result + ";" ); + } + else + { + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ i ].DataType, inputPortLocalVar, result ); + } + } + else + { + if( m_inputPorts[ i ].DataType == WirePortDataType.OBJECT ) + { + dataCollector.AddLocalVariable( UniqueId, m_items[ idx ].CustomType + " " + inputPortLocalVar, m_inputPorts[ i ].WrappedInternalData + ";" ); + } + else + { + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ i ].DataType, inputPortLocalVar, m_inputPorts[ i ].WrappedInternalData ); + } + } + + if( m_items[ idx ].Qualifier != VariableQualifiers.In ) + { + OutputPort currOutputPort = GetOutputPortByUniqueId( CreateOutputId( m_inputPorts[ i ].PortId ) ); + currOutputPort.SetLocalValue( inputPortLocalVar, dataCollector.PortCategory ); + } + } + else + { + // Not Unique + string result = m_inputPorts[ i ].GenerateShaderForOutput( ref dataCollector, m_inputPorts[ i ].DataType, true, true ); + string nameToReplaceRegex = string.Format( VarRegexReplacer, m_inputPorts[ i ].Name ); + localCode = Regex.Replace( localCode, nameToReplaceRegex, result, RegexOptions.Multiline ); + //localCode = localCode.Replace( m_inputPorts[ i ].Name, result ); + } + } + 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; + int idx = i - m_firstAvailablePort; + if( m_inputPorts[ i ].DataType != WirePortDataType.OBJECT ) + { + string result = m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector ); + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ i ].DataType, inputPortLocalVar, result ); + } + else + { + string result = ( m_inputPorts[ i ].IsConnected ) ? m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector ) : m_inputPorts[ i ].InternalData.ToString(); + string inputLocalVar = string.Format( Constants.CustomTypeLocalValueDecWithoutIdent, m_items[ idx ].CustomType, inputPortLocalVar, result ); + dataCollector.AddLocalVariable( UniqueId, inputLocalVar ); + } + + 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; + int outputPortId = CreateOutputId( m_inputPorts[ portIdx ].PortId ); + AddOutputPort( m_inputPorts[ portIdx ].DataType, m_inputPorts[ portIdx ].Name, outputPortId ); + } + } + } + + 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( UniqueId, "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 ) + UIUtils.CurrentWindow.OutsideGraph.CustomExpressionOnFunctionMode.RemoveNode( this ); + + int count = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + if( count == 0 ) + { + DeleteInputPortByArrayIdx( m_firstAvailablePort ); + 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 ) ); + } + bool isVariable = false; + if( UIUtils.CurrentShaderVersion() > 16600 ) + { + isVariable = Convert.ToBoolean( 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; + m_items[ 0 ].IsVariable = isVariable; + } + else + { + m_items.Add( new CustomExpressionInputItem( precision, qualifier, customType, isVariable, 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 ) + { + UIUtils.CurrentWindow.OutsideGraph.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_items[ i ].IsVariable ); + } + 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 ) + { + UIUtils.CurrentWindow.OutsideGraph.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 = UIUtils.CurrentWindow.OutsideGraph.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; + UIUtils.CurrentWindow.OutsideGraph.CustomExpressionOnFunctionMode.RemoveNode( this ); + } + else + { + UIUtils.CurrentWindow.OutsideGraph.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 = UIUtils.CurrentWindow.OutsideGraph.CustomExpressionOnFunctionMode.GetNodeRegisterIdx( m_dependencies[ i ].DependencyNodeId ); + } + //Fixing bug where user could set main output port as OBJECT + if( m_outputPorts[ 0 ].DataType == WirePortDataType.OBJECT && ( m_voidMode || m_mode == CustomExpressionMode.Call ) ) + { + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + } + + public override void FireTimedUpdate() + { + UIUtils.CurrentWindow.OutsideGraph.CustomExpressionOnFunctionMode.UpdateDataOnNode( UniqueId, m_customExpressionName ); + } + + public List<CustomExpressionDependency> Dependencies { get { return m_dependencies; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/CustomExpressionNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/CustomExpressionNode.cs.meta new file mode 100644 index 00000000..bf377187 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/CustomExpressionNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f2507a764c07082458e350211d671334 +timeCreated: 1481126960 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: 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 ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs.meta new file mode 100644 index 00000000..c442e367 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bc524cd13743b6f49a2e331767646448 +timeCreated: 1500632879 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/FresnelNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/FresnelNode.cs new file mode 100644 index 00000000..7cb2a329 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/FresnelNode.cs @@ -0,0 +1,393 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +// http://kylehalladay.com/blog/tutorial/2014/02/18/Fresnel-Shaders-From-The-Ground-Up.html +// http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter07.html + +using System; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Fresnel", "Surface Data", "Simple Fresnel effect" )] + public sealed class FresnelNode : ParentNode + { + private const string FresnedFinalVar = "fresnelNode"; + + [SerializeField] + private ViewSpace m_normalSpace = ViewSpace.Tangent; + + enum FresnelType + { + Standard = 0, + Schlick, + SchlickIOR, + } + + enum NormalType + { + WorldNormal = 0, + TangentNormal, + HalfVector, + } + + enum ViewType + { + ViewDir = 0, + LightDir, + } + + [SerializeField] + private FresnelType m_fresnelType = FresnelType.Standard; + + [SerializeField] + private NormalType m_normalType = NormalType.WorldNormal; + + [SerializeField] + private ViewType m_viewType = ViewType.ViewDir; + + [SerializeField] + private bool m_normalizeVectors = false; + + [SerializeField] + private bool m_safePower = false; + + private InputPort m_normalVecPort; + private InputPort m_viewVecPort; + private InputPort m_biasPort; + private InputPort m_scalePort; + private InputPort m_powerPort; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT3, false, "World Normal", -1, MasterNodePortCategory.Fragment, 0 ); + AddInputPort( WirePortDataType.FLOAT3, false, "View Dir", -1, MasterNodePortCategory.Fragment, 4 ); + AddInputPort( WirePortDataType.FLOAT, false, "Bias", -1, MasterNodePortCategory.Fragment, 1 ); + AddInputPort( WirePortDataType.FLOAT, false, "Scale", -1, MasterNodePortCategory.Fragment, 2 ); + AddInputPort( WirePortDataType.FLOAT, false, "Power", -1, MasterNodePortCategory.Fragment, 3 ); + AddOutputPort( WirePortDataType.FLOAT, "Out" ); + + m_normalVecPort = m_inputPorts[ 0 ]; + m_viewVecPort = m_inputPorts[ 1 ]; + m_biasPort = m_inputPorts[ 2 ]; + m_scalePort = m_inputPorts[ 3 ]; + m_powerPort = m_inputPorts[ 4 ]; + + m_biasPort.AutoDrawInternalData = true; + m_scalePort.AutoDrawInternalData = true; + m_powerPort.AutoDrawInternalData = true; + m_autoWrapProperties = true; + m_drawPreviewAsSphere = true; + m_normalVecPort.Vector3InternalData = Vector3.forward; + m_scalePort.FloatInternalData = 1; + m_powerPort.FloatInternalData = 5; + m_previewShaderGUID = "240145eb70cf79f428015012559f4e7d"; + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + + //m_mate + PreviewMaterial.SetInt( "_FresnelType", (int)m_fresnelType ); + + if( m_normalType == NormalType.TangentNormal && m_normalVecPort.IsConnected ) + m_previewMaterialPassId = 2; + else if( (m_normalType == NormalType.WorldNormal || m_normalType == NormalType.HalfVector ) && m_normalVecPort.IsConnected && !m_viewVecPort.IsConnected ) + m_previewMaterialPassId = 1; + else if( m_normalType == NormalType.HalfVector && !m_normalVecPort.IsConnected && !m_viewVecPort.IsConnected ) + m_previewMaterialPassId = 3; + else if( m_normalVecPort.IsConnected && m_viewVecPort.IsConnected ) + m_previewMaterialPassId = 4; + else if( !m_normalVecPort.IsConnected && !m_viewVecPort.IsConnected && m_viewType == ViewType.LightDir ) + m_previewMaterialPassId = 5; + else if( !m_normalVecPort.IsConnected && m_viewVecPort.IsConnected && m_normalType == NormalType.HalfVector ) + m_previewMaterialPassId = 7; + else if( !m_normalVecPort.IsConnected && m_viewVecPort.IsConnected ) + m_previewMaterialPassId = 6; + else + m_previewMaterialPassId = 0; + } + + public override void DrawProperties() + { + base.DrawProperties(); + + EditorGUI.BeginChangeCheck(); + m_fresnelType = (FresnelType)EditorGUILayoutEnumPopup( "Type", m_fresnelType ); + m_normalType = (NormalType)EditorGUILayoutEnumPopup( "Normal Vector", m_normalType ); + m_viewType = (ViewType)EditorGUILayoutEnumPopup( "View Vector", m_viewType ); + if( EditorGUI.EndChangeCheck() ) + { + UpdatePort(); + } + + if( !m_biasPort.IsConnected && m_biasPort.Visible ) + m_biasPort.FloatInternalData = EditorGUILayoutFloatField( m_biasPort.Name, m_biasPort.FloatInternalData ); + if( !m_scalePort.IsConnected && m_scalePort.Visible ) + m_scalePort.FloatInternalData = EditorGUILayoutFloatField( m_scalePort.Name, m_scalePort.FloatInternalData ); + if( !m_powerPort.IsConnected && m_powerPort.Visible ) + m_powerPort.FloatInternalData = EditorGUILayoutFloatField( m_powerPort.Name, m_powerPort.FloatInternalData ); + + m_normalizeVectors = EditorGUILayoutToggle( "Normalize Vectors", m_normalizeVectors ); + m_safePower = EditorGUILayoutToggle( PowerNode.SafePowerLabel, m_safePower ); + } + + private void UpdatePort() + { + switch( m_normalType ) + { + default: + case NormalType.WorldNormal: + m_normalVecPort.Name = "World Normal"; + break; + case NormalType.TangentNormal: + m_normalVecPort.Name = "Normal"; + break; + case NormalType.HalfVector: + m_normalVecPort.Name = "Half Vector"; + break; + } + + switch( m_viewType ) + { + default: + case ViewType.ViewDir: + m_viewVecPort.Name = "View Dir"; + break; + case ViewType.LightDir: + m_viewVecPort.Name = "Light Dir"; + break; + } + + switch( m_fresnelType ) + { + default: + case FresnelType.Standard: + m_biasPort.Visible = true; + m_biasPort.Name = "Bias"; + m_scalePort.Name = "Scale"; + m_scalePort.Visible = true; + m_powerPort.Visible = true; + break; + case FresnelType.Schlick: + m_biasPort.Visible = true; + m_biasPort.Name = "F0"; + m_scalePort.Visible = false; + m_powerPort.Visible = false; + break; + case FresnelType.SchlickIOR: + m_biasPort.Visible = false; + m_scalePort.Name = "IOR"; + m_scalePort.Visible = true; + m_powerPort.Visible = false; + break; + } + + m_sizeIsDirty = true; + } + + 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 ); + + if( dataCollector.IsFragmentCategory ) + dataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_POS ); + + string viewdir = string.Empty; + if( m_viewType == ViewType.ViewDir ) + { + if( m_viewVecPort.IsConnected ) + viewdir = m_viewVecPort.GeneratePortInstructions( ref dataCollector ); + else + viewdir = GeneratorUtils.GenerateViewDirection( ref dataCollector, UniqueId, ViewSpace.World ); + } + else + { + if( m_viewVecPort.IsConnected ) + viewdir = m_viewVecPort.GeneratePortInstructions( ref dataCollector ); + else + viewdir = GeneratorUtils.GenerateWorldLightDirection( ref dataCollector, UniqueId, CurrentPrecisionType ); + } + + string normal = string.Empty; + if( m_normalType == NormalType.WorldNormal || m_normalType == NormalType.TangentNormal ) + { + if( m_normalVecPort.IsConnected ) + { + normal = m_normalVecPort.GeneratePortInstructions( ref dataCollector ); + + if( dataCollector.IsFragmentCategory ) + { + dataCollector.AddToInput( UniqueId, SurfaceInputs.INTERNALDATA, addSemiColon: false ); + + if( m_normalType == NormalType.TangentNormal ) + { + if( dataCollector.IsTemplate ) + { + normal = dataCollector.TemplateDataCollectorInstance.GetWorldNormal( UniqueId, CurrentPrecisionType, normal, OutputId ); + } + else + { + normal = GeneratorUtils.GenerateWorldNormal( ref dataCollector, UniqueId, CurrentPrecisionType, normal, OutputId ); + dataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_NORMAL, CurrentPrecisionType ); + dataCollector.ForceNormal = true; + } + } + else + { + if( m_normalizeVectors ) + normal = string.Format( "normalize( {0} )", normal ); + } + } + else + { + if( m_normalType == NormalType.TangentNormal ) + { + string wtMatrix = GeneratorUtils.GenerateWorldToTangentMatrix( ref dataCollector, UniqueId, CurrentPrecisionType ); + normal = "mul( " + normal + "," + wtMatrix + " )"; + } + } + } + else + { + if( dataCollector.IsFragmentCategory ) + { + dataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_NORMAL, CurrentPrecisionType ); + if( dataCollector.DirtyNormal ) + dataCollector.AddToInput( UniqueId, SurfaceInputs.INTERNALDATA, addSemiColon: false ); + } + + if( dataCollector.IsTemplate ) + normal = dataCollector.TemplateDataCollectorInstance.GetWorldNormal( CurrentPrecisionType, normalize: ( dataCollector.DirtyNormal && m_normalizeVectors ) ); + else + normal = GeneratorUtils.GenerateWorldNormal( ref dataCollector, UniqueId, ( dataCollector.DirtyNormal && m_normalizeVectors ) ); + + if( dataCollector.DirtyNormal ) + { + dataCollector.ForceNormal = true; + } + } + } + else + { + // generate HV + if( !m_normalVecPort.IsConnected ) + { + string halfView = GeneratorUtils.GenerateViewDirection( ref dataCollector, UniqueId, ViewSpace.World ); + string halfLight = GeneratorUtils.GenerateWorldLightDirection( ref dataCollector, UniqueId, CurrentPrecisionType ); + normal = "halfVector" + OutputId; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT3, normal, "normalize( " + halfView + " + " + halfLight + " )" ); + } + else + { + normal = m_normalVecPort.GeneratePortInstructions( ref dataCollector ); + if( m_normalizeVectors ) + normal = string.Format( "normalize( {0} )", normal ); + } + } + + string bias = m_biasPort.GeneratePortInstructions( ref dataCollector ); + string scale = m_scalePort.GeneratePortInstructions( ref dataCollector ); + string power = m_powerPort.GeneratePortInstructions( ref dataCollector ); + + string fresnelNDotVLocalValue = "dot( " + normal + ", " + viewdir + " )"; + string fresnelNDotVLocalVar = "fresnelNdotV" + OutputId; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, fresnelNDotVLocalVar, fresnelNDotVLocalValue ); + + string fresnelFinalVar = FresnedFinalVar + OutputId; + + string result = string.Empty; + switch( m_fresnelType ) + { + default: + case FresnelType.Standard: + { + string powOp = m_safePower? string.Format( "pow( max( 1.0 - {0} , 0.0001 ), {1} )", fresnelNDotVLocalVar, power ): + string.Format( "pow( 1.0 - {0}, {1} )", fresnelNDotVLocalVar, power ); + result = string.Format( "( {0} + {1} * {2} )", bias, scale, powOp ); + } + break; + case FresnelType.Schlick: + { + string f0VarName = "f0" + OutputId; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, f0VarName, bias ); + string powOp = m_safePower? string.Format( "pow( max( 1.0 - {0} , 0.0001 ), 5 )", fresnelNDotVLocalVar ) : + string.Format( "pow( 1.0 - {0}, 5 )", fresnelNDotVLocalVar ); + result = string.Format( "( {0} + ( 1.0 - {0} ) * {1} )", f0VarName, powOp ); + } + break; + case FresnelType.SchlickIOR: + { + string iorVarName = "ior" + OutputId; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT, iorVarName, scale ); + string iorPowOp = m_safePower? string.Format( "pow( max( ( 1 - {0} ) / ( 1 + {0} ) , 0.0001 ), 2 )", iorVarName ): + string.Format( "pow( ( 1 - {0} ) / ( 1 + {0} ), 2 )", iorVarName ); + + dataCollector.AddLocalVariable( UniqueId, iorVarName +" = "+ iorPowOp + ";"); + + string fresnelPowOp = m_safePower? string.Format( "pow( max( 1.0 - {0} , 0.0001 ), 5 )", fresnelNDotVLocalVar ): + string.Format( "pow( 1.0 - {0}, 5 )", fresnelNDotVLocalVar ); + result = string.Format( "( {0} + ( 1.0 - {0} ) * {1} )", iorVarName, fresnelPowOp ); + } + break; + } + + RegisterLocalVariable( 0, result, ref dataCollector, fresnelFinalVar ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + + public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + { + base.PropagateNodeData( nodeData, ref dataCollector ); + if( m_normalType == NormalType.TangentNormal && m_normalVecPort.IsConnected ) + dataCollector.DirtyNormal = true; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + + if( UIUtils.CurrentShaderVersion() > 15305 ) + { + m_fresnelType = (FresnelType)Enum.Parse( typeof( FresnelType ), GetCurrentParam( ref nodeParams ) ); + m_normalType = (NormalType)Enum.Parse( typeof( NormalType ), GetCurrentParam( ref nodeParams ) ); + m_viewType = (ViewType)Enum.Parse( typeof( ViewType ), GetCurrentParam( ref nodeParams ) ); + m_normalizeVectors = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > 17502 ) + m_safePower = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + } + else + { + if( UIUtils.CurrentShaderVersion() >= 13202 ) + { + m_normalSpace = (ViewSpace)Enum.Parse( typeof( ViewSpace ), GetCurrentParam( ref nodeParams ) ); + } + else + { + m_normalSpace = ViewSpace.World; + } + + if( m_normalSpace == ViewSpace.World ) + m_normalType = NormalType.WorldNormal; + else + m_normalType = NormalType.TangentNormal; + } + UpdatePort(); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + + IOUtils.AddFieldValueToString( ref nodeInfo, m_fresnelType ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_normalType ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_viewType ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_normalizeVectors ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_safePower ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/FresnelNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/FresnelNode.cs.meta new file mode 100644 index 00000000..54876f82 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/FresnelNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 91955bc593b0dc14d90b10cb3eb25355 +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/GetLocalVarNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/GetLocalVarNode.cs new file mode 100644 index 00000000..7a5b54f2 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/GetLocalVarNode.cs @@ -0,0 +1,430 @@ +// 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] + [NodeAttributes( "Get Local Var", "Miscellaneous", "Use a registered local variable", null, KeyCode.G )] + public class GetLocalVarNode : ParentNode + { + [SerializeField] + private int m_referenceId = -1; + + [SerializeField] + private float m_referenceWidth = -1; + + [SerializeField] + private int m_nodeId = -1; + + [SerializeField] + private RegisterLocalVarNode m_currentSelected = null; + + [SerializeField] + private string m_registerLocalVarName = string.Empty; + + private int m_cachedPropertyId = -1; + + private string m_previousLabel = string.Empty; + + private bool m_refSelect = false; + private int m_prevReferenceId = -1; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddOutputPort( WirePortDataType.OBJECT, Constants.EmptyPortValue ); + + // This is needed for infinite loop detection + AddInputPort( WirePortDataType.OBJECT, false, Constants.EmptyPortValue ); + m_inputPorts[ 0 ].Visible = false; + + m_outputPorts[ 0 ].Locked = true; + m_textLabelWidth = 80; + m_autoWrapProperties = true; + m_hasLeftDropdown = true; + m_previewShaderGUID = "f21a6e44c7d7b8543afacd19751d24c6"; + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + + if( UniqueId > -1 ) + m_containerGraph.LocalVarNodes.OnReorderEventComplete += OnReorderEventComplete; + } + + private void OnReorderEventComplete() + { + if( m_currentSelected != null ) + { + m_referenceId = m_containerGraph.LocalVarNodes.GetNodeRegisterIdx( m_currentSelected.UniqueId ); + } + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + + if( m_currentSelected != null ) + { + if( m_drawPreviewAsSphere != m_currentSelected.SpherePreview ) + { + m_drawPreviewAsSphere = m_currentSelected.SpherePreview; + OnNodeChange(); + } + //CheckSpherePreview(); + + if( m_cachedPropertyId == -1 ) + m_cachedPropertyId = Shader.PropertyToID( "_A" ); + + PreviewMaterial.SetTexture( m_cachedPropertyId, m_currentSelected.OutputPorts[ 0 ].OutputPreviewTexture ); + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUILayout.BeginHorizontal(); + EditorGUI.BeginChangeCheck(); + m_referenceId = EditorGUILayoutPopup( Constants.AvailableReferenceStr, m_referenceId, UIUtils.LocalVarNodeArr() ); + if( EditorGUI.EndChangeCheck() ) + { + UpdateFromSelected(); + } + + if( GUILayout.Button( "\u25C4", "minibutton", GUILayout.Width( 17 ) ) && m_currentSelected ) + { + UIUtils.FocusOnNode( m_currentSelected, 0, false ); + } + EditorGUILayout.EndHorizontal(); + //EditorGUILayout.LabelField( ConnStatus.ToString() + " " + m_activeConnections ); + } + + public override void Destroy() + { + base.Destroy(); + CurrentSelected = null; + if( UniqueId > -1 ) + m_containerGraph.LocalVarNodes.OnReorderEventComplete -= OnReorderEventComplete; + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + if( m_dropdownEditing ) + { + EditorGUI.BeginChangeCheck(); + m_referenceId = EditorGUIPopup( m_dropdownRect, m_referenceId, UIUtils.LocalVarNodeArr(), UIUtils.PropertyPopUp ); + if( EditorGUI.EndChangeCheck() ) + { + UpdateFromSelected(); + DropdownEditing = false; + } + } + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + UpdateLocalVar(); + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if( m_isVisible && m_refSelect && !m_selected ) + { + GUI.color = Constants.SpecialGetLocalVarSelectionColor; + GUI.Label( m_globalPosition, string.Empty, UIUtils.GetCustomStyle( CustomStyle.NodeWindowOn ) ); + GUI.color = m_colorBuffer; + } + } + + void CheckForLoops() + { + if( CurrentSelected != null && UIUtils.DetectNodeLoopsFrom( CurrentSelected, new Dictionary<int, int>() ) ) + { + CurrentSelected = UIUtils.GetLocalVarNode( m_prevReferenceId ); + if( CurrentSelected == null || UIUtils.DetectNodeLoopsFrom( CurrentSelected, new Dictionary<int, int>() ) ) + { + m_referenceId = -1; + m_prevReferenceId = -1; + CurrentSelected = null; + m_outputPorts[ 0 ].Locked = true; + SetAdditonalTitleText( "" ); + UIUtils.ShowMessage( "Infinite Loop detected, disabled selection" ); + } + else + { + m_referenceId = m_prevReferenceId; + UIUtils.ShowMessage( "Infinite Loop detected, reverted to previous selection" ); + } + } + } + + void UpdateFromSelected() + { + CurrentSelected = UIUtils.GetLocalVarNode( m_referenceId ); + CheckForLoops(); + + if( m_currentSelected != null ) + { + m_nodeId = m_currentSelected.UniqueId; + m_outputPorts[ 0 ].Locked = false; + m_outputPorts[ 0 ].ChangeType( m_currentSelected.OutputPorts[ 0 ].DataType, false ); + m_drawPreviewAsSphere = m_currentSelected.SpherePreview; + CheckSpherePreview(); + + m_previousLabel = m_currentSelected.DataToArray; + SetAdditonalTitleText( string.Format( Constants.SubTitleVarNameFormatStr, m_currentSelected.DataToArray ) ); + m_referenceWidth = m_currentSelected.Position.width; + } + + m_sizeIsDirty = true; + m_isDirty = true; + m_prevReferenceId = m_referenceId; + } + + void UpdateLocalVar() + { + m_refSelect = false; + if( m_referenceId > -1 ) + { + ParentNode newNode = UIUtils.GetLocalVarNode( m_referenceId ); + if( newNode != null ) + { + if( newNode.UniqueId != m_nodeId ) + { + CurrentSelected = null; + int count = UIUtils.LocalVarNodeAmount(); + for( int i = 0; i < count; i++ ) + { + ParentNode node = UIUtils.GetLocalVarNode( i ); + if( node.UniqueId == m_nodeId ) + { + CurrentSelected = node as RegisterLocalVarNode; + m_referenceId = i; + break; + } + } + } + } + + if( m_currentSelected != null ) + { + if( m_currentSelected.OutputPorts[ 0 ].DataType != m_outputPorts[ 0 ].DataType ) + { + m_outputPorts[ 0 ].Locked = false; + m_outputPorts[ 0 ].ChangeType( m_currentSelected.OutputPorts[ 0 ].DataType, false ); + } + + if( !m_previousLabel.Equals( m_currentSelected.DataToArray ) ) + { + m_previousLabel = m_currentSelected.DataToArray; + SetAdditonalTitleText( string.Format( Constants.SubTitleVarNameFormatStr, m_currentSelected.DataToArray ) ); + } + + if( m_referenceWidth != m_currentSelected.Position.width ) + { + m_referenceWidth = m_currentSelected.Position.width; + m_sizeIsDirty = true; + } + + if( m_currentSelected.Selected ) + m_refSelect = true; + } + else + { + ResetReference(); + } + } + } + + public void ResetReference() + { + m_outputPorts[ 0 ].Locked = true; + m_currentSelected = null; + m_inputPorts[ 0 ].DummyClear(); + m_nodeId = -1; + m_referenceId = -1; + m_referenceWidth = -1; + SetAdditonalTitleText( string.Empty ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_currentSelected != null ) + { + return m_currentSelected.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + } + else + { + UIUtils.ShowMessage( UniqueId, "Get Local Var node without reference. Attempting to access inexistant local variable.", MessageSeverity.Error ); + + return m_outputPorts[ 0 ].ErrorValue; + } + } + + + //public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + //{ + // base.PropagateNodeData( nodeData, ref dataCollector ); + // if( m_currentSelected != null ) + // { + // m_currentSelected.PropagateNodeData( nodeData, ref dataCollector ); + // } + //} + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + if( UIUtils.CurrentShaderVersion() > 15 ) + { + m_nodeId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_outputPorts[ 0 ].Locked = ( m_nodeId < 0 ); + if( UIUtils.CurrentShaderVersion() > 15500 ) + { + m_registerLocalVarName = GetCurrentParam( ref nodeParams ); + } + } + else + { + m_referenceId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_outputPorts[ 0 ].Locked = ( m_referenceId < 0 ); + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + if( m_currentSelected != null ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentSelected.UniqueId ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentSelected.DataToArray ); + } + else + { + IOUtils.AddFieldValueToString( ref nodeInfo, -1 ); + IOUtils.AddFieldValueToString( ref nodeInfo, string.Empty ); + } + + } + + public override void OnNodeDoubleClicked( Vector2 currentMousePos2D ) + { + if( m_currentSelected != null ) + { + UIUtils.FocusOnNode( m_currentSelected, 0, true ); + } + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + if( UIUtils.CurrentShaderVersion() > 15 ) + { + CurrentSelected = UIUtils.GetNode( m_nodeId ) as RegisterLocalVarNode; + m_referenceId = UIUtils.GetLocalVarNodeRegisterId( m_nodeId ); + if( CurrentSelected == null && UIUtils.CurrentShaderVersion() > 15500 && !string.IsNullOrEmpty( m_registerLocalVarName ) ) + { + CurrentSelected = m_containerGraph.LocalVarNodes.GetNodeByDataToArray( m_registerLocalVarName ); + if( CurrentSelected != null ) + { + m_nodeId = CurrentSelected.UniqueId; + m_referenceId = UIUtils.GetLocalVarNodeRegisterId( m_nodeId ); + } + } + } + else + { + CurrentSelected = UIUtils.GetLocalVarNode( m_referenceId ); + if( m_currentSelected != null ) + { + m_nodeId = m_currentSelected.UniqueId; + } + } + + CheckForLoops(); + + if( m_currentSelected != null ) + { + m_outputPorts[ 0 ].Locked = false; + m_outputPorts[ 0 ].ChangeType( m_currentSelected.OutputPorts[ 0 ].DataType, false ); + } + else + { + m_outputPorts[ 0 ].Locked = true; + } + } + + public override void ActivateNode( int signalGenNodeId, int signalGenPortId, System.Type signalGenNodeType ) + { + base.ActivateNode( signalGenNodeId, signalGenPortId, signalGenNodeType ); + if( m_activeConnections == 1 ) + { + if( m_currentSelected != null ) + { + m_currentSelected.ActivateNode( signalGenNodeId, signalGenPortId, signalGenNodeType ); + } + } + } + + public override void DeactivateNode( int deactivatedPort, bool forceComplete ) + { + forceComplete = forceComplete || ( m_activeConnections == 1 ); + base.DeactivateNode( deactivatedPort, forceComplete ); + if( forceComplete && m_currentSelected != null ) + { + m_currentSelected.DeactivateNode( deactivatedPort, false ); + } + } + + public override void OnNodeSelected( bool value ) + { + base.OnNodeSelected( value ); + if( m_currentSelected != null ) + { + m_currentSelected.CheckReferenceSelection(); + } + } + + public RegisterLocalVarNode CurrentSelected + { + get { return m_currentSelected; } + set + { + // This is needed for infinite loop detection + if( m_inputPorts != null ) + m_inputPorts[ 0 ].DummyClear(); + + if( m_currentSelected != null ) + { + m_currentSelected.UnregisterGetLocalVar( this ); + + //if( m_currentSelected != value ) + m_currentSelected.DeactivateNode( 0, false ); + } + + if( value != null ) + { + value.RegisterGetLocalVar( this ); + if( IsConnected && value != m_currentSelected ) + value.ActivateNode( UniqueId, 0, m_activeType ); + + // This is needed for infinite loop detection + m_inputPorts[ 0 ].DummyAdd( value.UniqueId, 0 ); ; + } + + m_currentSelected = value; + + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/GetLocalVarNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/GetLocalVarNode.cs.meta new file mode 100644 index 00000000..9b80adde --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/GetLocalVarNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: efce529ed3c74854b9d0cece836991c3 +timeCreated: 1481126960 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LayeredBlendNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LayeredBlendNode.cs new file mode 100644 index 00000000..21589b00 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LayeredBlendNode.cs @@ -0,0 +1,61 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using System; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Layered Blend", "Miscellaneous", "Mix all channels through interpolation factors", null, KeyCode.None, true )] + public sealed class LayeredBlendNode : WeightedAvgNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + m_inputPorts[ 1 ].Name = "Layer Base"; + AddInputPort( WirePortDataType.FLOAT, false, string.Empty ); + for ( int i = 2; i < m_inputPorts.Count; i++ ) + { + m_inputPorts[ i ].Name = AmountsStr[ i - 2 ]; + } + m_inputData = new string[ 6 ]; + m_minimumSize = 2; + UpdateConnection( 0 ); + m_previewShaderGUID = "48faca2f6506fc44c97adb1e2b79c37d"; + } + + 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 ); + + GetInputData( ref dataCollector, ignoreLocalvar ); + + string result = string.Empty; + string localVarName = "layeredBlendVar" + OutputId; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ 0 ].DataType, localVarName, m_inputData[ 0 ] ); + + if ( m_activeCount == 1 ) + { + result = m_inputData[ 0 ]; + } + else if ( m_activeCount == 2 ) + { + result += "lerp( " + m_inputData[ 1 ] + "," + m_inputData[ 2 ] + " , " + localVarName + " )"; + } + else + { + result = m_inputData[ 1 ]; + for ( int i = 1; i < m_activeCount; i++ ) + { + result = "lerp( " + result + " , " + m_inputData[ i + 1 ] + " , " + localVarName + Constants.VectorSuffixes[ i - 1 ] + " )"; + } + } + result = UIUtils.AddBrackets( result ); + RegisterLocalVariable( 0, result, ref dataCollector, "layeredBlend" + OutputId ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LayeredBlendNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LayeredBlendNode.cs.meta new file mode 100644 index 00000000..bcfcd292 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LayeredBlendNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 90801da82a0b4f74cae2f9387bd5ad92 +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LinearDepthNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LinearDepthNode.cs new file mode 100644 index 00000000..0193bbc9 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LinearDepthNode.cs @@ -0,0 +1,97 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Linear Depth", "Miscellaneous", "Converts depth values given on logarithmic space to linear" )] + public sealed class LinearDepthNode : ParentNode + { + private readonly string[] LinearModeLabels = { "Eye Space", "0-1 Space" }; + + private const string LinearEyeFuncFormat = "LinearEyeDepth({0})"; + private const string Linear01FuncFormat = "Linear01Depth({0})"; + private const string LinerValName = "depthToLinear"; + private const string ViewSpaceLabel = "View Space"; + + private UpperLeftWidgetHelper m_upperLeftWidget = new UpperLeftWidgetHelper(); + + [SerializeField] + private int m_currentOption = 0; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue ); + AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + m_autoWrapProperties = true; + m_hasLeftDropdown = true; + m_previewShaderGUID = "2b0785cc8b854974ab4e45419072705a"; + UpdateFromOption(); + } + + public override void Destroy() + { + base.Destroy(); + m_upperLeftWidget = null; + } + + void UpdateFromOption() + { + m_previewMaterialPassId = m_currentOption; + SetAdditonalTitleText( string.Format( Constants.SubTitleSpaceFormatStr, LinearModeLabels[ m_currentOption ] ) ); + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + EditorGUI.BeginChangeCheck(); + m_currentOption = m_upperLeftWidget.DrawWidget( this, m_currentOption, LinearModeLabels ); + if( EditorGUI.EndChangeCheck() ) + { + UpdateFromOption(); + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUI.BeginChangeCheck(); + m_currentOption = EditorGUILayoutPopup( ViewSpaceLabel, m_currentOption, LinearModeLabels ); + if( EditorGUI.EndChangeCheck() ) + { + SetAdditonalTitleText( string.Format( Constants.SubTitleSpaceFormatStr, LinearModeLabels[ m_currentOption ] ) ); + } + } + + 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 ); + + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + + string value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + value = string.Format( (( m_currentOption == 0 ) ? LinearEyeFuncFormat : Linear01FuncFormat), value ); + RegisterLocalVariable( 0, value, ref dataCollector, LinerValName + OutputId ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentOption ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + int.TryParse( GetCurrentParam( ref nodeParams ), out m_currentOption ); + UpdateFromOption(); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LinearDepthNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LinearDepthNode.cs.meta new file mode 100644 index 00000000..490856d4 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LinearDepthNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8b8af65130c9ed64f95976ec67ac1adf +timeCreated: 1546438982 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/MatrixFromVectors.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/MatrixFromVectors.cs new file mode 100644 index 00000000..af6325bc --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/MatrixFromVectors.cs @@ -0,0 +1,215 @@ +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Matrix From Vectors", "Matrix Operators", "Matrix From Vectors" )] + public sealed class MatrixFromVectors : ParentNode + { + private const string RowFromVector = "Input to Row"; + [SerializeField] + private WirePortDataType m_selectedOutputType = WirePortDataType.FLOAT3x3; + + [SerializeField] + private int m_selectedOutputTypeInt = 0; + + [SerializeField] + private Vector3[] m_defaultValuesV3 = { Vector3.zero, Vector3.zero, Vector3.zero }; + + [SerializeField] + private Vector4[] m_defaultValuesV4 = { Vector4.zero, Vector4.zero, Vector4.zero, Vector4.zero }; + + [SerializeField] + private bool m_rowsFromVector = true; + + private string[] m_defaultValuesStr = { "[0]", "[1]", "[2]", "[3]" }; + + private readonly string[] _outputValueTypes ={ "Matrix3X3", + "Matrix4X4"}; + + private UpperLeftWidgetHelper m_upperLeftWidget = new UpperLeftWidgetHelper(); + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT4, false, "[0]" ); + AddInputPort( WirePortDataType.FLOAT4, false, "[1]" ); + AddInputPort( WirePortDataType.FLOAT4, false, "[2]" ); + AddInputPort( WirePortDataType.FLOAT4, false, "[3]" ); + AddOutputPort( m_selectedOutputType, Constants.EmptyPortValue ); + m_textLabelWidth = 90; + m_autoWrapProperties = true; + m_hasLeftDropdown = true; + UpdatePorts(); + } + + public override void AfterCommonInit() + { + base.AfterCommonInit(); + if( PaddingTitleLeft == 0 ) + { + PaddingTitleLeft = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin; + if( PaddingTitleRight == 0 ) + PaddingTitleRight = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin; + } + } + + public override void Destroy() + { + base.Destroy(); + m_upperLeftWidget = null; + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + EditorGUI.BeginChangeCheck(); + m_selectedOutputTypeInt = m_upperLeftWidget.DrawWidget( this, m_selectedOutputTypeInt, _outputValueTypes ); + if( EditorGUI.EndChangeCheck() ) + { + switch( m_selectedOutputTypeInt ) + { + case 0: m_selectedOutputType = WirePortDataType.FLOAT3x3; break; + case 1: m_selectedOutputType = WirePortDataType.FLOAT4x4; break; + } + + UpdatePorts(); + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + + EditorGUI.BeginChangeCheck(); + m_selectedOutputTypeInt = EditorGUILayoutPopup( "Output type", m_selectedOutputTypeInt, _outputValueTypes ); + if( EditorGUI.EndChangeCheck() ) + { + switch( m_selectedOutputTypeInt ) + { + case 0: m_selectedOutputType = WirePortDataType.FLOAT3x3; break; + case 1: m_selectedOutputType = WirePortDataType.FLOAT4x4; break; + } + + UpdatePorts(); + } + + int count = 0; + switch( m_selectedOutputType ) + { + case WirePortDataType.FLOAT3x3: + count = 3; + for( int i = 0; i < count; i++ ) + { + if( !m_inputPorts[ i ].IsConnected ) + m_defaultValuesV3[ i ] = EditorGUILayoutVector3Field( m_defaultValuesStr[ i ], m_defaultValuesV3[ i ] ); + } + break; + case WirePortDataType.FLOAT4x4: + count = 4; + for( int i = 0; i < count; i++ ) + { + if( !m_inputPorts[ i ].IsConnected ) + m_defaultValuesV4[ i ] = EditorGUILayoutVector4Field( m_defaultValuesStr[ i ], m_defaultValuesV4[ i ] ); + } + break; + } + m_rowsFromVector = EditorGUILayoutToggle( RowFromVector, m_rowsFromVector ); + } + + void UpdatePorts() + { + m_sizeIsDirty = true; + ChangeOutputType( m_selectedOutputType, false ); + switch( m_selectedOutputType ) + { + case WirePortDataType.FLOAT3x3: + m_inputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ 1 ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ 2 ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ 3 ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ 3 ].Visible = false; + break; + case WirePortDataType.FLOAT4x4: + m_inputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT4, false ); + m_inputPorts[ 1 ].ChangeType( WirePortDataType.FLOAT4, false ); + m_inputPorts[ 2 ].ChangeType( WirePortDataType.FLOAT4, false ); + m_inputPorts[ 3 ].ChangeType( WirePortDataType.FLOAT4, false ); + m_inputPorts[ 3 ].Visible = true; + break; + } + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + string result = ""; + switch( m_selectedOutputType ) + { + case WirePortDataType.FLOAT3x3: + if( m_rowsFromVector ) + { + result = "float3x3(" + m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ) + ", " + + m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ) + ", " + + m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ) + ")"; + } + else + { + string vec0 = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string vec1 = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ); + string vec2 = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + result = string.Format( "float3x3({0}.x,{1}.x,{2}.x,{0}.y,{1}.y,{2}.y,{0}.z,{1}.z,{2}.z )", vec0, vec1, vec2 ); + } + break; + case WirePortDataType.FLOAT4x4: + if( m_rowsFromVector ) + { + result = "float4x4(" + m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ) + ", " + + m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ) + ", " + + m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ) + ", " + + m_inputPorts[ 3 ].GeneratePortInstructions( ref dataCollector ) + ")"; + } + else + { + string vec0 = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string vec1 = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ); + string vec2 = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + string vec3 = m_inputPorts[ 3 ].GeneratePortInstructions( ref dataCollector ); + result = string.Format( "float4x4( {0}.x,{1}.x,{2}.x,{3}.x,{0}.y,{1}.y,{2}.y,{3}.y,{0}.z,{1}.z,{2}.z,{3}.z,{0}.w,{1}.w,{2}.w,{3}.w )", vec0, vec1, vec2, vec3 ); + } + break; + } + + return result; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_selectedOutputType = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > 15310 ) + { + m_rowsFromVector = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + } + switch( m_selectedOutputType ) + { + case WirePortDataType.FLOAT3x3: + m_selectedOutputTypeInt = 0; + break; + case WirePortDataType.FLOAT4x4: + m_selectedOutputTypeInt = 1; + break; + } + UpdatePorts(); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedOutputType ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_rowsFromVector ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/MatrixFromVectors.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/MatrixFromVectors.cs.meta new file mode 100644 index 00000000..25231848 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/MatrixFromVectors.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a313774cf0e4d1e4289d7395e8e49067 +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/PosFromTransformMatrix.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/PosFromTransformMatrix.cs new file mode 100644 index 00000000..41a14788 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/PosFromTransformMatrix.cs @@ -0,0 +1,34 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Position From Transform", "Matrix Operators", "Gets the position vector from a transformation matrix" )] + public sealed class PosFromTransformMatrix : ParentNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT4x4, true, Constants.EmptyPortValue ); + AddOutputPort( WirePortDataType.FLOAT4, "XYZW" ); + AddOutputPort( WirePortDataType.FLOAT, "X" ); + AddOutputPort( WirePortDataType.FLOAT, "Y" ); + AddOutputPort( WirePortDataType.FLOAT, "Z" ); + AddOutputPort( WirePortDataType.FLOAT, "W" ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + + string value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string result = string.Format( "float4( {0},{1},{2},{3})", value + "[3][0]", value + "[3][1]", value + "[3][2]", value + "[3][3]" ); + RegisterLocalVariable( 0, result, ref dataCollector, "matrixToPos" + OutputId ); + + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/PosFromTransformMatrix.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/PosFromTransformMatrix.cs.meta new file mode 100644 index 00000000..568be07a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/PosFromTransformMatrix.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7c7321a370f1f1b499d4655cc25f457b +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RegisterLocalVarNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RegisterLocalVarNode.cs new file mode 100644 index 00000000..15bf0313 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RegisterLocalVarNode.cs @@ -0,0 +1,346 @@ +// 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] + [NodeAttributes( "Register Local Var", "Miscellaneous", "Forces a local variable to be written with the given name. Can then be fetched at any place with a <b>Get Local Var</b> node.", null, KeyCode.R )] + public sealed class RegisterLocalVarNode : ParentNode + { + private const double MaxEditingTimestamp = 1; + + private const string LocalDefaultNameStr = "myVarName"; + private const string LocalVarNameStr = "Var Name"; + private const string OrderIndexStr = "Order Index"; + private const string AutoOrderIndexStr = "Auto Order"; + private const string ReferencesStr = "References"; + + private const string GetLocalVarLabel = "( {0} ) Get Local Var"; + private string m_oldName = string.Empty; + private bool m_reRegisterName = false; + private int m_autoOrderIndex = int.MaxValue; + private bool m_forceUpdate = true; + private bool m_refSelect = false; + + private bool m_referencesVisible = false; + + [SerializeField] + private string m_variableName = LocalDefaultNameStr; + + [SerializeField] + private int m_orderIndex = -1; + + [SerializeField] + private bool m_autoIndexActive = true; + + [SerializeField] + private List<GetLocalVarNode> m_registeredGetLocalVars = new List<GetLocalVarNode>(); + + [NonSerialized] + private double m_editingTimestamp; + + [NonSerialized] + private bool m_editingTimestampFlag; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue ); + AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + m_textLabelWidth = 85; + m_customPrecision = true; + + if( m_containerGraph != null ) + m_variableName += m_containerGraph.LocalVarNodes.NodesList.Count; + + m_oldName = m_variableName; + UpdateTitle(); + m_previewShaderGUID = "5aaa1d3ea9e1fa64781647e035a82334"; + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + m_containerGraph.LocalVarNodes.AddNode( this ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + + public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + + void UpdateTitle() + { + SetAdditonalTitleText( string.Format( Constants.SubTitleVarNameFormatStr, m_variableName ) ); + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + if( m_editingTimestampFlag && ( EditorApplication.timeSinceStartup - m_editingTimestamp ) > MaxEditingTimestamp ) + { + m_editingTimestampFlag = false; + CheckAndChangeName(); + } + } + + void DrawMainProperties() + { + EditorGUI.BeginChangeCheck(); + m_variableName = EditorGUILayoutTextField( LocalVarNameStr, m_variableName ); + if( EditorGUI.EndChangeCheck() ) + { + m_editingTimestampFlag = true; + m_editingTimestamp = EditorApplication.timeSinceStartup; + //CheckAndChangeName(); + } + + DrawPrecisionProperty(); + } + + public override void AfterDuplication() + { + base.AfterDuplication(); + CheckAndChangeName(); + } + + void CheckAndChangeName() + { + m_variableName = UIUtils.RemoveInvalidCharacters( m_variableName ); + if( string.IsNullOrEmpty( m_variableName ) ) + { + m_variableName = LocalDefaultNameStr + OutputId; + } + bool isNumericName = UIUtils.IsNumericName( m_variableName ); + bool isLocalVarNameAvailable = m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.IsLocalvariableNameAvailable( m_variableName ); + if( !isNumericName && isLocalVarNameAvailable ) + { + m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.ReleaseLocalVariableName( UniqueId, m_oldName ); + m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.RegisterLocalVariableName( UniqueId, m_variableName ); + m_oldName = m_variableName; + m_containerGraph.LocalVarNodes.UpdateDataOnNode( UniqueId, m_variableName ); + UpdateTitle(); + m_forceUpdate = true; + } + else + { + if( isNumericName ) + { + UIUtils.ShowMessage( UniqueId, string.Format( "Local variable name '{0}' cannot start or be numerical values. Reverting back to '{1}'.", m_variableName, m_oldName ), MessageSeverity.Warning ); + } + else if( !isLocalVarNameAvailable ) + { + UIUtils.ShowMessage( UniqueId, string.Format( "Local variable name '{0}' already being used. Reverting back to '{1}'.", m_variableName, m_oldName ), MessageSeverity.Warning ); + } + + m_variableName = m_oldName; + m_containerGraph.LocalVarNodes.UpdateDataOnNode( UniqueId, m_variableName ); + } + } + + void DrawReferences() + { + int count = m_registeredGetLocalVars.Count; + if( m_registeredGetLocalVars.Count > 0 ) + { + for( int i = 0; i < count; i++ ) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField( string.Format( GetLocalVarLabel, m_registeredGetLocalVars[ i ].UniqueId ) ); + if( GUILayout.Button( "\u25BA", "minibutton", GUILayout.Width( 17 ) ) ) + { + m_containerGraph.ParentWindow.FocusOnNode( m_registeredGetLocalVars[ i ], 0, false ); + } + EditorGUILayout.EndHorizontal(); + } + + if( GUILayout.Button( "Back" ) ) + { + m_containerGraph.ParentWindow.FocusOnNode( this, 0, false ); + } + } + else + { + EditorGUILayout.HelpBox( "This node is not being referenced by any Get Local Var.", MessageType.Info ); + } + } + + public override void DrawProperties() + { + NodeUtils.DrawPropertyGroup( ref m_propertiesFoldout, Constants.ParameterLabelStr, DrawMainProperties ); + NodeUtils.DrawPropertyGroup( ref m_referencesVisible, ReferencesStr, DrawReferences ); + //EditorGUILayout.LabelField(ConnStatus.ToString()+" "+m_activeConnections); + } + + public override void OnEnable() + { + base.OnEnable(); + m_reRegisterName = true; + } + + public void CheckReferenceSelection() + { + m_refSelect = false; + int count = m_registeredGetLocalVars.Count; + for( int i = 0; i < count; i++ ) + { + if( m_registeredGetLocalVars[ i ].Selected ) + m_refSelect = true; + } + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + if( m_isVisible && m_refSelect && !m_selected ) + { + GUI.color = Constants.SpecialRegisterLocalVarSelectionColor; + GUI.Label( m_globalPosition, string.Empty, UIUtils.GetCustomStyle( CustomStyle.NodeWindowOn ) ); + GUI.color = m_colorBuffer; + } + } + + public override void Draw( DrawInfo drawInfo ) + { + + base.Draw( drawInfo ); + if( m_reRegisterName ) + { + m_reRegisterName = false; + m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.RegisterLocalVariableName( UniqueId, m_variableName ); + } + + if( m_forceUpdate ) + { + m_forceUpdate = false; + UpdateTitle(); + } + } + + 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 = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + if( m_inputPorts[ 0 ].DataType == WirePortDataType.OBJECT ) + m_outputPorts[ 0 ].SetLocalValue( result, dataCollector.PortCategory ); + else + RegisterLocalVariable( 0, result, ref dataCollector, m_variableName + OutputId ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_variableName = GetCurrentParam( ref nodeParams ); + m_oldName = m_variableName; + if( UIUtils.CurrentShaderVersion() > 14 ) + m_orderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + + if( UIUtils.CurrentShaderVersion() > 3106 ) + { + m_autoIndexActive = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + } + else + { + m_autoIndexActive = false; + } + if( !m_isNodeBeingCopied ) + { + m_containerGraph.LocalVarNodes.UpdateDataOnNode( UniqueId, m_variableName ); + m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.ReleaseLocalVariableName( UniqueId, m_oldName ); + m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.RegisterLocalVariableName( UniqueId, m_variableName ); + } + m_forceUpdate = true; + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_variableName ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_orderIndex ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autoIndexActive ); + } + + public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + { + if( m_autoOrderIndex < nodeData.OrderIndex ) + { + nodeData.OrderIndex = m_autoOrderIndex - 1; + } + else + { + m_autoOrderIndex = nodeData.OrderIndex; + nodeData.OrderIndex -= 1; + } + + base.PropagateNodeData( nodeData, ref dataCollector ); + } + + public override void ResetNodeData() + { + base.ResetNodeData(); + m_autoOrderIndex = int.MaxValue; + } + + public void RegisterGetLocalVar( GetLocalVarNode node ) + { + if( !m_registeredGetLocalVars.Contains( node ) ) + { + m_registeredGetLocalVars.Add( node ); + CheckReferenceSelection(); + } + } + + public void UnregisterGetLocalVar( GetLocalVarNode node ) + { + if( m_registeredGetLocalVars.Contains( node ) ) + { + m_registeredGetLocalVars.Remove( node ); + CheckReferenceSelection(); + } + } + + public override void Destroy() + { + base.Destroy(); + m_containerGraph.LocalVarNodes.RemoveNode( this ); + m_containerGraph.ParentWindow.DuplicatePrevBufferInstance.ReleaseLocalVariableName( UniqueId, m_variableName ); + + int count = m_registeredGetLocalVars.Count; + for( int i = 0; i < count; i++ ) + { + //GetLocalVarNode node = m_containerGraph.GetNode( m_registeredGetLocalVars[ i ] ) as GetLocalVarNode; + if( m_registeredGetLocalVars[ i ] != null ) + m_registeredGetLocalVars[ i ].ResetReference(); + } + m_registeredGetLocalVars.Clear(); + m_registeredGetLocalVars = null; + + m_containerGraph.LocalVarNodes.RemoveNode( this ); + } + + public override void ActivateNode( int signalGenNodeId, int signalGenPortId, Type signalGenNodeType ) + { + base.ActivateNode( signalGenNodeId, signalGenPortId, signalGenNodeType ); + } + public override string DataToArray { get { return m_variableName; } } + public List<GetLocalVarNode> NodeReferences { get { return m_registeredGetLocalVars; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RegisterLocalVarNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RegisterLocalVarNode.cs.meta new file mode 100644 index 00000000..9cda9e54 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RegisterLocalVarNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ebd1a3b3014ccdd40b8fa805b4281c6f +timeCreated: 1481126960 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RelayNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RelayNode.cs new file mode 100644 index 00000000..ab6df692 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RelayNode.cs @@ -0,0 +1,38 @@ +using System; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Relay", "Miscellaneous", "Relay" )] + public sealed class RelayNode : ParentNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.OBJECT, false, Constants.EmptyPortValue ); + AddOutputPort( WirePortDataType.OBJECT, Constants.EmptyPortValue ); + m_previewShaderGUID = "74e4d859fbdb2c0468de3612145f4929"; + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + + public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + return m_inputPorts[ 0 ].GenerateShaderForOutput( ref dataCollector, m_inputPorts[ 0 ].DataType, ignoreLocalvar ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RelayNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RelayNode.cs.meta new file mode 100644 index 00000000..378c2048 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RelayNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ef679ba7cdeda594aa3e5c02b25e66df +timeCreated: 1481126960 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RotateAboutAxisNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RotateAboutAxisNode.cs new file mode 100644 index 00000000..b9b0a6c2 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RotateAboutAxisNode.cs @@ -0,0 +1,95 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Rotate About Axis", "Vector Operators", "Rotates a vector around a normalized axis" )] + public class RotateAboutAxisNode : ParentNode + { + private const string FunctionHeader = "float3 RotateAroundAxis( float3 center, float3 original, float3 u, float angle )"; + private const string FunctionCall = "RotateAroundAxis( {0}, {1}, {2}, {3} )"; + private readonly string[] FunctionBody = + { + "float3 RotateAroundAxis( float3 center, float3 original, float3 u, float angle )\n", + "{\n", + "\toriginal -= center;\n", + "\tfloat C = cos( angle );\n", + "\tfloat S = sin( angle );\n", + "\tfloat t = 1 - C;\n", + "\tfloat m00 = t * u.x * u.x + C;\n", + "\tfloat m01 = t * u.x * u.y - S * u.z;\n", + "\tfloat m02 = t * u.x * u.z + S * u.y;\n", + "\tfloat m10 = t * u.x * u.y + S * u.z;\n", + "\tfloat m11 = t * u.y * u.y + C;\n", + "\tfloat m12 = t * u.y * u.z - S * u.x;\n", + "\tfloat m20 = t * u.x * u.z - S * u.y;\n", + "\tfloat m21 = t * u.y * u.z + S * u.x;\n", + "\tfloat m22 = t * u.z * u.z + C;\n", + "\tfloat3x3 finalMatrix = float3x3( m00, m01, m02, m10, m11, m12, m20, m21, m22 );\n", + "\treturn mul( finalMatrix, original ) + center;\n", + "}\n" + }; + + private const string NormalizeAxisLabel = "Rotation Axis"; + private const string NonNormalizeAxisLabel = "Normalized Rotation Axis"; + private const string NormalizeAxisStr = "Normalize Axis"; + + [UnityEngine.SerializeField] + private bool m_normalizeAxis = false; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT3, false, m_normalizeAxis? NormalizeAxisLabel: NonNormalizeAxisLabel ); + AddInputPort( WirePortDataType.FLOAT, false, "Rotation Angle" ); + AddInputPort( WirePortDataType.FLOAT3, false, "Pivot Point" ); + AddInputPort( WirePortDataType.FLOAT3, false, "Position" ); + AddOutputPort( WirePortDataType.FLOAT3, Constants.EmptyPortValue ); + m_useInternalPortData = true; + m_autoWrapProperties = true; + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUI.BeginChangeCheck(); + m_normalizeAxis = EditorGUILayoutToggle( NormalizeAxisStr, m_normalizeAxis ); + if( EditorGUI.EndChangeCheck() ) + { + m_inputPorts[ 0 ].Name = (m_normalizeAxis ? NormalizeAxisLabel : NonNormalizeAxisLabel); + } + } + + 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 normalizeRotAxis = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + if( m_normalizeAxis ) + { + normalizeRotAxis = string.Format( "normalize( {0} )", normalizeRotAxis ); + } + string rotationAngle = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ); + string pivotPoint = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + string position = m_inputPorts[ 3 ].GeneratePortInstructions( ref dataCollector ); + dataCollector.AddFunction( FunctionHeader, FunctionBody, false ); + RegisterLocalVariable( 0, string.Format( FunctionCall, pivotPoint, position, normalizeRotAxis, rotationAngle ), ref dataCollector, "rotatedValue" + OutputId ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_normalizeAxis = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_normalizeAxis ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RotateAboutAxisNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RotateAboutAxisNode.cs.meta new file mode 100644 index 00000000..f5af5b8d --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RotateAboutAxisNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6190b6c1a4cd29b48bfd36ff9b2ea773 +timeCreated: 1513184612 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SummedBlendNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SummedBlendNode.cs new file mode 100644 index 00000000..735bcd9a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SummedBlendNode.cs @@ -0,0 +1,56 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Summed Blend", "Miscellaneous", "Mix all channels through weighted sum", null, KeyCode.None, true )] + public sealed class SummedBlendNode : WeightedAvgNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + m_inputData = new string[ 6 ]; + m_previewShaderGUID = "eda18b96e13f78b49bbdaa4da3fead19"; + } + + 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 ); + + GetInputData( ref dataCollector, ignoreLocalvar ); + + string result = string.Empty; + string localVarName = "weightedBlendVar" + OutputId; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ 0 ].DataType, localVarName, m_inputData[ 0 ] ); + + if ( m_activeCount == 0 ) + { + result = m_inputData[ 0 ]; + } + else if ( m_activeCount == 1 ) + { + result += localVarName + "*" + m_inputData[ 1 ]; + } + else + { + for ( int i = 0; i < m_activeCount; i++ ) + { + result += localVarName + Constants.VectorSuffixes[ i ] + "*" + m_inputData[ i + 1 ]; + if ( i != ( m_activeCount - 1 ) ) + { + result += " + "; + } + } + } + + result = UIUtils.AddBrackets( result ); + RegisterLocalVariable( 0, result, ref dataCollector, "weightedBlend" + OutputId ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SummedBlendNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SummedBlendNode.cs.meta new file mode 100644 index 00000000..102a6f19 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SummedBlendNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: da71cf021d98a7f468319e56eaefe6f1 +timeCreated: 1484229430 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwitchNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwitchNode.cs new file mode 100644 index 00000000..ae3d4107 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwitchNode.cs @@ -0,0 +1,230 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Debug Switch", "Logical Operators", "Hard Switch between any of its input ports" )] + public class SwitchNode : ParentNode + { + private const string Info = "This is a Debug node which only generates the source for the selected port. This means that no properties are generated for other ports and information might be lost."; + private const string InputPortName = "In "; + + private const string CurrSelectedStr = "Current"; + private const string MaxAmountStr = "Max Amount"; + private const int MaxAllowedAmount = 8; + + [SerializeField] + private string[] m_availableInputsLabels = { "In 0", "In 1" }; + + [SerializeField] + private int[] m_availableInputsValues = { 0, 1 }; + + [SerializeField] + private int m_currentSelectedInput = 0; + + [SerializeField] + private int m_maxAmountInputs = 2; + + private int m_cachedPropertyId = -1; + + private GUIContent m_popContent; + + private Rect m_varRect; + private Rect m_imgRect; + private bool m_editing; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + AddInputPort( WirePortDataType.FLOAT, false, InputPortName + i ); + m_inputPorts[ i ].Visible = ( i < 2 ); + } + AddOutputPort( WirePortDataType.FLOAT, " " ); + + m_popContent = new GUIContent(); + m_popContent.image = UIUtils.PopupIcon; + + m_insideSize.Set( 50, 25 ); + m_textLabelWidth = 100; + m_autoWrapProperties = false; + m_previewShaderGUID = "a58e46feaa5e3d14383bfeac24d008bc"; + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + + if( m_cachedPropertyId == -1 ) + m_cachedPropertyId = Shader.PropertyToID( "_Current" ); + + PreviewMaterial.SetInt( m_cachedPropertyId, m_currentSelectedInput ); + } + + public override void OnConnectedOutputNodeChanges( int inputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + m_inputPorts[ inputPortId ].MatchPortToConnection(); + if( inputPortId == m_currentSelectedInput ) + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ inputPortId ].DataType, false ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_inputPorts[ portId ].MatchPortToConnection(); + if( portId == m_currentSelectedInput ) + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ portId ].DataType, false ); + } + + public void UpdateLabels() + { + m_availableInputsLabels = new string[ m_maxAmountInputs ]; + m_availableInputsValues = new int[ m_maxAmountInputs ]; + + for( int i = 0; i < m_maxAmountInputs; i++ ) + { + m_availableInputsLabels[ i ] = InputPortName + i; + m_availableInputsValues[ i ] = i; + } + } + + //void UpdateOutput() + //{ + // m_outputPorts[ 0 ].ChangeProperties( m_inputPorts[ m_currentSelectedInput ].Name, m_inputPorts[ m_currentSelectedInput ].DataType, false ); + // m_sizeIsDirty = true; + //} + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + base.OnNodeLayout( drawInfo ); + + m_varRect = m_remainingBox; + m_varRect.width = 50 * drawInfo.InvertedZoom; + m_varRect.height = 16 * drawInfo.InvertedZoom; + m_varRect.x = m_remainingBox.xMax - m_varRect.width; + //m_varRect.x += m_remainingBox.width * 0.5f - m_varRect.width * 0.5f; + m_varRect.y += 1 * drawInfo.InvertedZoom; + + m_imgRect = m_varRect; + m_imgRect.x = m_varRect.xMax - 16 * drawInfo.InvertedZoom; + m_imgRect.width = 16 * drawInfo.InvertedZoom; + m_imgRect.height = m_imgRect.width; + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + base.DrawGUIControls( drawInfo ); + + if( drawInfo.CurrentEventType != EventType.MouseDown ) + return; + + if( m_varRect.Contains( drawInfo.MousePosition ) ) + { + m_editing = true; + } + else if( m_editing ) + { + m_editing = false; + } + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + if( m_editing ) + { + EditorGUI.BeginChangeCheck(); + m_currentSelectedInput = EditorGUIIntPopup( m_varRect, m_currentSelectedInput, m_availableInputsLabels, m_availableInputsValues, UIUtils.GraphDropDown ); + if( EditorGUI.EndChangeCheck() ) + { + PreviewIsDirty = true; + m_editing = false; + } + } + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if( !m_isVisible ) + return; + + if( !m_editing && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 ) + { + GUI.Label( m_varRect, m_availableInputsLabels[ m_currentSelectedInput ], UIUtils.GraphDropDown ); + GUI.Label( m_imgRect, m_popContent, UIUtils.GraphButtonIcon ); + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + NodeUtils.DrawPropertyGroup( ref m_propertiesFoldout, Constants.ParameterLabelStr, DrawDebugOptions ); + + EditorGUILayout.HelpBox( Info, MessageType.Warning ); + } + + void DrawDebugOptions() + { + EditorGUI.BeginChangeCheck(); + m_maxAmountInputs = EditorGUILayoutIntSlider( MaxAmountStr, m_maxAmountInputs, 2, MaxAllowedAmount ); + if( EditorGUI.EndChangeCheck() ) + { + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs ); + } + + if( m_currentSelectedInput >= m_maxAmountInputs ) + { + m_currentSelectedInput = m_maxAmountInputs - 1; + } + + UpdateLabels(); + m_sizeIsDirty = true; + } + + m_currentSelectedInput = EditorGUILayoutIntPopup( CurrSelectedStr, m_currentSelectedInput, m_availableInputsLabels, m_availableInputsValues ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + return m_inputPorts[ m_currentSelectedInput ].GeneratePortInstructions( ref dataCollector ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_currentSelectedInput = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_maxAmountInputs = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs ); + } + + if( m_currentSelectedInput >= m_maxAmountInputs ) + { + m_currentSelectedInput = m_maxAmountInputs - 1; + } + + UpdateLabels(); + m_sizeIsDirty = true; + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentSelectedInput ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_maxAmountInputs ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwitchNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwitchNode.cs.meta new file mode 100644 index 00000000..246aa75c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwitchNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ad88ed9f1b6010a4bb17685dec17a585 +timeCreated: 1483956795 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwizzleNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwizzleNode.cs new file mode 100644 index 00000000..ec839517 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwizzleNode.cs @@ -0,0 +1,441 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +// +// Custom Node Swizzle +// Donated by Tobias Pott - @ Tobias Pott +// www.tobiaspott.de + +using System; +using UnityEditor; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Swizzle", "Vector Operators", "Swizzle components of vector types", null, KeyCode.Z, true, false, null, null, "Tobias Pott - @TobiasPott" )] + public sealed class SwizzleNode : SingleInputOp + { + + private const string OutputTypeStr = "Output type"; + + [SerializeField] + private WirePortDataType m_selectedOutputType = WirePortDataType.FLOAT4; + + [SerializeField] + private int m_selectedOutputTypeInt = 3; + + [SerializeField] + private int[] m_selectedOutputSwizzleTypes = new int[] { 0, 1, 2, 3 }; + + [SerializeField] + private int m_maskId; + + [SerializeField] + private Vector4 m_maskValue = Vector4.one; + + private readonly string[] SwizzleVectorChannels = { "x", "y", "z", "w" }; + private readonly string[] SwizzleColorChannels = { "r", "g", "b", "a" }; + private readonly string[] SwizzleChannelLabels = { "Channel 0", "Channel 1", "Channel 2", "Channel 3" }; + + private readonly string[] m_outputValueTypes ={ "Float", + "Vector 2", + "Vector 3", + "Vector 4"}; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + m_inputPorts[ 0 ].CreatePortRestrictions( WirePortDataType.FLOAT, + WirePortDataType.FLOAT2, + WirePortDataType.FLOAT3, + WirePortDataType.FLOAT4, + WirePortDataType.COLOR, + WirePortDataType.INT ); + + + m_inputPorts[ 0 ].DataType = WirePortDataType.FLOAT4; + m_outputPorts[ 0 ].DataType = m_selectedOutputType; + m_textLabelWidth = 90; + m_autoWrapProperties = true; + m_autoUpdateOutputPort = false; + m_hasLeftDropdown = true; + m_previewShaderGUID = "d20531704ce28b14bafb296f291f6608"; + SetAdditonalTitleText( "Value( XYZW )" ); + CalculatePreviewData(); + } + + public override void OnEnable() + { + base.OnEnable(); + m_maskId = Shader.PropertyToID( "_Mask" ); + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + PreviewMaterial.SetVector( m_maskId, m_maskValue ); + } + + 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; + } + + int inputMaxChannelId = 0; + switch( m_inputPorts[ 0 ].DataType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + inputMaxChannelId = 3; + break; + case WirePortDataType.FLOAT3: + inputMaxChannelId = 2; + break; + case WirePortDataType.FLOAT2: + inputMaxChannelId = 1; + break; + case WirePortDataType.INT: + case WirePortDataType.FLOAT: + inputMaxChannelId = 0; + break; + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + break; + } + + m_previewMaterialPassId = -1; + float passValue = 0; + for( int i = 3; i > -1; i-- ) + { + int currentSwizzle = Mathf.Min( inputMaxChannelId, m_selectedOutputSwizzleTypes[ i ] ); + if( currentSwizzle > 0 ) + { + passValue += Mathf.Pow( 4, 3 - i ) * currentSwizzle; + } + } + + m_previewMaterialPassId = (int)passValue; + + if( m_previewMaterialPassId == -1 ) + { + m_previewMaterialPassId = 0; + if( DebugConsoleWindow.DeveloperMode ) + { + UIUtils.ShowMessage( UniqueId, "Could not find pass ID for swizzle", MessageSeverity.Error ); + } + } + } + + public override void AfterCommonInit() + { + base.AfterCommonInit(); + + if ( PaddingTitleLeft == 0 ) + { + PaddingTitleLeft = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin; + if ( PaddingTitleRight == 0 ) + PaddingTitleRight = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin; + } + } + + public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type ); + UpdatePorts(); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + UpdatePorts(); + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + UpdatePorts(); + } + + 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() ) + { + switch ( m_selectedOutputTypeInt ) + { + case 0: m_selectedOutputType = WirePortDataType.FLOAT; break; + case 1: m_selectedOutputType = WirePortDataType.FLOAT2; break; + case 2: m_selectedOutputType = WirePortDataType.FLOAT3; break; + case 3: m_selectedOutputType = WirePortDataType.FLOAT4; break; + } + + UpdatePorts(); + DropdownEditing = false; + } + } + } + + public override void DrawProperties() + { + + EditorGUILayout.BeginVertical(); + EditorGUI.BeginChangeCheck(); + m_selectedOutputTypeInt = EditorGUILayoutPopup( OutputTypeStr, m_selectedOutputTypeInt, m_outputValueTypes ); + if ( EditorGUI.EndChangeCheck() ) + { + switch ( m_selectedOutputTypeInt ) + { + case 0: m_selectedOutputType = WirePortDataType.FLOAT; break; + case 1: m_selectedOutputType = WirePortDataType.FLOAT2; break; + case 2: m_selectedOutputType = WirePortDataType.FLOAT3; break; + case 3: m_selectedOutputType = WirePortDataType.FLOAT4; break; + } + + UpdatePorts(); + } + EditorGUILayout.EndVertical(); + + // Draw base properties + base.DrawProperties(); + + EditorGUILayout.BeginVertical(); + + int count = 0; + + switch ( m_selectedOutputType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + count = 4; + break; + case WirePortDataType.FLOAT3: + count = 3; + break; + case WirePortDataType.FLOAT2: + count = 2; + break; + case WirePortDataType.INT: + case WirePortDataType.FLOAT: + count = 1; + break; + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + break; + } + + EditorGUI.BeginChangeCheck(); + if ( m_inputPorts[ 0 ].DataType == WirePortDataType.COLOR ) + { + for ( int i = 0; i < count; i++ ) + { + m_selectedOutputSwizzleTypes[ i ] = EditorGUILayoutPopup( SwizzleChannelLabels[ i ], m_selectedOutputSwizzleTypes[ i ], SwizzleColorChannels ); + } + } + else + { + for ( int i = 0; i < count; i++ ) + { + m_selectedOutputSwizzleTypes[ i ] = EditorGUILayoutPopup( SwizzleChannelLabels[ i ], m_selectedOutputSwizzleTypes[ i ], SwizzleVectorChannels ); + } + } + if ( EditorGUI.EndChangeCheck() ) + { + UpdatePorts(); + } + + EditorGUILayout.EndVertical(); + + } + + void UpdatePorts() + { + ChangeOutputType( m_selectedOutputType, false ); + + int count = 0; + switch ( m_selectedOutputType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + count = 4; + break; + case WirePortDataType.FLOAT3: + count = 3; + break; + case WirePortDataType.FLOAT2: + count = 2; + break; + case WirePortDataType.INT: + case WirePortDataType.FLOAT: + count = 1; + break; + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + break; + } + + int inputMaxChannelId = 0; + switch ( m_inputPorts[ 0 ].DataType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + inputMaxChannelId = 3; + break; + case WirePortDataType.FLOAT3: + inputMaxChannelId = 2; + break; + case WirePortDataType.FLOAT2: + inputMaxChannelId = 1; + break; + case WirePortDataType.INT: + case WirePortDataType.FLOAT: + inputMaxChannelId = 0; + break; + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + break; + } + + //for ( int i = 0; i < count; i++ ) + //{ + //m_selectedOutputSwizzleTypes[ i ] = Mathf.Clamp( m_selectedOutputSwizzleTypes[ i ], 0, inputMaxChannelId ); + //} + + // Update Title + string additionalText = string.Empty; + for ( int i = 0; i < count; i++ ) + { + int currentSwizzle = Mathf.Min( inputMaxChannelId, m_selectedOutputSwizzleTypes[ i ] ); + additionalText += GetSwizzleComponentForChannel( currentSwizzle ).ToUpper(); + } + + if ( additionalText.Length > 0 ) + SetAdditonalTitleText( "Value( " + additionalText + " )" ); + else + SetAdditonalTitleText( string.Empty ); + + CalculatePreviewData(); + m_sizeIsDirty = true; + } + + public string GetSwizzleComponentForChannel( int channel ) + { + if ( m_inputPorts[ 0 ].DataType == WirePortDataType.COLOR ) + { + return SwizzleColorChannels[ channel ]; + } + else + { + return SwizzleVectorChannels[ channel ]; + } + } + + 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 value = string.Format( "({0}).", m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ) ); + + int inputMaxChannelId = 0; + switch( m_inputPorts[ 0 ].DataType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + inputMaxChannelId = 3; + break; + case WirePortDataType.FLOAT3: + inputMaxChannelId = 2; + break; + case WirePortDataType.FLOAT2: + inputMaxChannelId = 1; + break; + case WirePortDataType.INT: + case WirePortDataType.FLOAT: + inputMaxChannelId = 0; + break; + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + break; + } + + int count = 0; + switch ( m_selectedOutputType ) + { + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + count = 4; + break; + case WirePortDataType.FLOAT3: + count = 3; + break; + case WirePortDataType.FLOAT2: + count = 2; + break; + case WirePortDataType.INT: + case WirePortDataType.FLOAT: + count = 1; + break; + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + break; + } + + for ( int i = 0; i < count; i++ ) + { + int currentSwizzle = Mathf.Min( inputMaxChannelId, m_selectedOutputSwizzleTypes[ i ] ); + value += GetSwizzleComponentForChannel( currentSwizzle ); + } + + return CreateOutputLocalVariable( 0, value, ref dataCollector ); + } + + 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.FLOAT: m_selectedOutputTypeInt = 0; break; + case WirePortDataType.FLOAT2: m_selectedOutputTypeInt = 1; break; + case WirePortDataType.FLOAT3: m_selectedOutputTypeInt = 2; break; + case WirePortDataType.COLOR: + case WirePortDataType.FLOAT4: m_selectedOutputTypeInt = 3; break; + } + for ( int i = 0; i < m_selectedOutputSwizzleTypes.Length; i++ ) + { + m_selectedOutputSwizzleTypes[ i ] = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + UpdatePorts(); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedOutputType ); + for ( int i = 0; i < m_selectedOutputSwizzleTypes.Length; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedOutputSwizzleTypes[ i ] ); + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwizzleNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwizzleNode.cs.meta new file mode 100644 index 00000000..5049f92b --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwizzleNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3bb41488b4b3e034d838c73c2eb471f5 +timeCreated: 1481126955 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/ToggleSwitchNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/ToggleSwitchNode.cs new file mode 100644 index 00000000..baa91b53 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/ToggleSwitchNode.cs @@ -0,0 +1,285 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using UnityEditor; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Toggle Switch", "Logical Operators", "Switch between any of its input ports" )] + public class ToggleSwitchNode : PropertyNode + { + private const string InputPortName = "In "; + private const string CurrSelectedStr = "Toggle Value"; + //private const string LerpOp = "lerp({0},{1},{2})"; + private const string LerpOp = "(( {2} )?( {1} ):( {0} ))"; + + [SerializeField] + private string[] AvailableInputsLabels = { "In 0", "In 1" }; + + [SerializeField] + private int[] AvailableInputsValues = { 0, 1 }; + + [SerializeField] + private int m_currentSelectedInput = 0; + + [SerializeField] + private WirePortDataType m_mainDataType = WirePortDataType.FLOAT; + + private int m_cachedPropertyId = -1; + + private GUIContent m_popContent; + + private Rect m_varRect; + private Rect m_imgRect; + private bool m_editing; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( m_mainDataType, false, InputPortName + "0" ); + AddInputPort( m_mainDataType, false, InputPortName + "1" ); + + AddOutputPort( m_mainDataType, " " ); + m_insideSize.Set( 80, 25 ); + m_currentParameterType = PropertyType.Property; + m_customPrefix = "Toggle Switch"; + + m_popContent = new GUIContent(); + m_popContent.image = UIUtils.PopupIcon; + + m_availableAttribs.Clear(); + //Need to maintain this because of retrocompatibility reasons + m_availableAttribs.Add( new PropertyAttributes( "Toggle", "[Toggle]" ) ); + + m_drawAttributes = false; + m_freeType = false; + m_useVarSubtitle = true; + m_useInternalPortData = true; + m_previewShaderGUID = "beeb138daeb592a4887454f81dba2b3f"; + + m_allowPropertyDuplicates = true; + m_showAutoRegisterUI = false; + + m_srpBatcherCompatible = true; + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + UIUtils.RegisterPropertyNode( this ); + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + + if ( m_cachedPropertyId == -1 ) + m_cachedPropertyId = Shader.PropertyToID( "_Current" ); + + PreviewMaterial.SetInt( m_cachedPropertyId, m_currentSelectedInput ); + } + + public override void OnConnectedOutputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( portId, otherNodeId, otherPortId, name, type ); + UpdateConnection(); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + UpdateConnection(); + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + UpdateConnection(); + } + + void UpdateConnection() + { + WirePortDataType type1 = WirePortDataType.FLOAT; + if( m_inputPorts[ 0 ].IsConnected ) + type1 = m_inputPorts[ 0 ].GetOutputConnection( 0 ).DataType; + + WirePortDataType type2 = WirePortDataType.FLOAT; + if( m_inputPorts[ 1 ].IsConnected ) + type2 = m_inputPorts[ 1 ].GetOutputConnection( 0 ).DataType; + + m_mainDataType = UIUtils.GetPriority( type1 ) > UIUtils.GetPriority( type2 ) ? type1 : type2; + + m_inputPorts[ 0 ].ChangeType( m_mainDataType, false ); + m_inputPorts[ 1 ].ChangeType( m_mainDataType, false ); + + + //m_outputPorts[ 0 ].ChangeProperties( m_out, m_mainDataType, false ); + m_outputPorts[ 0 ].ChangeType( m_mainDataType, false ); + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + base.OnNodeLayout( drawInfo ); + + m_varRect = m_remainingBox; + m_varRect.width = 50 * drawInfo.InvertedZoom; + m_varRect.height = 16 * drawInfo.InvertedZoom; + m_varRect.x = m_remainingBox.xMax - m_varRect.width; + m_varRect.y += 1 * drawInfo.InvertedZoom; + + m_imgRect = m_varRect; + m_imgRect.x = m_varRect.xMax - 16 * drawInfo.InvertedZoom; + m_imgRect.width = 16 * drawInfo.InvertedZoom; + m_imgRect.height = m_imgRect.width; + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + base.DrawGUIControls( drawInfo ); + + if ( drawInfo.CurrentEventType != EventType.MouseDown ) + return; + + if ( m_varRect.Contains( drawInfo.MousePosition ) ) + { + m_editing = true; + } + else if ( m_editing ) + { + m_editing = false; + } + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + if( m_editing ) + { + EditorGUI.BeginChangeCheck(); + m_currentSelectedInput = EditorGUIIntPopup( m_varRect, m_currentSelectedInput, AvailableInputsLabels, AvailableInputsValues, UIUtils.SwitchNodePopUp ); + if ( EditorGUI.EndChangeCheck() ) + { + PreviewIsDirty = true; + UpdateConnection(); + m_requireMaterialUpdate = true; + m_editing = false; + } + } + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if ( !m_isVisible ) + return; + + if ( !m_editing && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 ) + { + GUI.Label( m_varRect, AvailableInputsLabels[ m_currentSelectedInput ], UIUtils.GraphDropDown ); + GUI.Label( m_imgRect, m_popContent, UIUtils.GraphButtonIcon ); + } + } + + public override void DrawMainPropertyBlock() + { + base.DrawMainPropertyBlock(); + EditorGUILayout.Separator(); + EditorGUI.BeginChangeCheck(); + m_currentSelectedInput = EditorGUILayoutIntPopup( CurrSelectedStr, m_currentSelectedInput, AvailableInputsLabels, AvailableInputsValues ); + if ( EditorGUI.EndChangeCheck() ) + { + UpdateConnection(); + m_requireMaterialUpdate = true; + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + NodeUtils.DrawPropertyGroup( ref m_visibleCustomAttrFoldout, CustomAttrStr, DrawCustomAttributes, DrawCustomAttrAddRemoveButtons ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + m_precisionString = UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, m_outputPorts[ 0 ].DataType ); + + string resultA = m_inputPorts[ 0 ].GenerateShaderForOutput( ref dataCollector, m_mainDataType, ignoreLocalvar, true ); + string resultB = m_inputPorts[ 1 ].GenerateShaderForOutput( ref dataCollector, m_mainDataType, ignoreLocalvar, true ); + return string.Format( LerpOp, resultA, resultB, m_propertyName ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_currentSelectedInput = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentSelectedInput ); + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + m_selectedAttribs.Clear(); + UpdateConnection(); + } + public override string GetPropertyValue() + { + return PropertyAttributes + "[Toggle]" + m_propertyName + "(\"" + m_propertyInspectorName + "\", Float) = " + m_currentSelectedInput; + } + + public override string GetUniformValue() + { + int index = m_containerGraph.IsSRP ? 1 : 0; + return string.Format( Constants.UniformDec[ index ], UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, WirePortDataType.FLOAT ), m_propertyName ); + } + + public override bool GetUniformData( out string dataType, out string dataName, ref bool fullValue ) + { + dataType = UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, WirePortDataType.FLOAT ); + dataName = m_propertyName; + return true; + } + + public override void UpdateMaterial( Material mat ) + { + base.UpdateMaterial( mat ); + if ( UIUtils.IsProperty( m_currentParameterType ) && !InsideShaderFunction ) + { + mat.SetFloat( m_propertyName, ( float ) m_currentSelectedInput ); + } + } + + public override void SetMaterialMode( Material mat , bool fetchMaterialValues ) + { + base.SetMaterialMode( mat , fetchMaterialValues ); + if ( fetchMaterialValues && m_materialMode && UIUtils.IsProperty( m_currentParameterType ) && mat.HasProperty( m_propertyName ) ) + { + m_currentSelectedInput = ( int ) mat.GetFloat( m_propertyName ); + } + } + + public override void ForceUpdateFromMaterial( Material material ) + { + if( UIUtils.IsProperty( m_currentParameterType ) && material.HasProperty( m_propertyName ) ) + { + m_currentSelectedInput = (int)material.GetFloat( m_propertyName ); + PreviewIsDirty = true; + } + } + + public override string GetPropertyValStr() + { + return PropertyName; //return m_currentSelectedInput.ToString(); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/ToggleSwitchNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/ToggleSwitchNode.cs.meta new file mode 100644 index 00000000..54b20752 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/ToggleSwitchNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c7f6ffd9a8c958e449321777764784de +timeCreated: 1484213504 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation.meta new file mode 100644 index 00000000..3dcf03fc --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2505ed67ae6a9d647a25755a065e350e +folderAsset: yes +timeCreated: 1488205900 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ObjectToWorldTransfNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ObjectToWorldTransfNode.cs new file mode 100644 index 00000000..48de5fbe --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ObjectToWorldTransfNode.cs @@ -0,0 +1,30 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +namespace AmplifyShaderEditor +{ + [System.Serializable] + [NodeAttributes( "Object To World", "Object Transform", "Transforms input to World Space" )] + public sealed class ObjectToWorldTransfNode : ParentTransfNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + m_matrixName = "unity_ObjectToWorld"; + m_matrixHDName = "GetObjectToWorldMatrix()"; + m_matrixLWName = "GetObjectToWorldMatrix()"; + m_previewShaderGUID = "a4044ee165813654486d0cecd0de478c"; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + string result = base.GenerateShaderForOutput( 0, ref dataCollector, ignoreLocalvar ); + if( dataCollector.IsTemplate && dataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD && !string.IsNullOrEmpty( m_matrixHDName ) ) + { + dataCollector.AddLocalVariable( UniqueId, string.Format( "{0}.xyz", result ), string.Format( "GetAbsolutePositionWS(({0}).xyz);", result ) ); + } + + return GetOutputVectorItem( 0, outputId, result ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ObjectToWorldTransfNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ObjectToWorldTransfNode.cs.meta new file mode 100644 index 00000000..40b45c87 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ObjectToWorldTransfNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 545417ad304cea84b9f625a3b6ad4e56 +timeCreated: 1488205951 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ParentTransfNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ParentTransfNode.cs new file mode 100644 index 00000000..5781e115 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ParentTransfNode.cs @@ -0,0 +1,53 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +namespace AmplifyShaderEditor +{ + [System.Serializable] + public class ParentTransfNode : ParentNode + { + protected string m_matrixName; + protected string m_matrixHDName; + protected string m_matrixLWName; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT4, false, string.Empty ); + AddOutputVectorPorts( WirePortDataType.FLOAT4, "XYZW" ); + m_useInternalPortData = true; + m_inputPorts[ 0 ].Vector4InternalData = new UnityEngine.Vector4( 0, 0, 0, 1 ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if ( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + + string value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string matrixName = string.Empty; + if( dataCollector.IsTemplate ) + { + if( dataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD && !string.IsNullOrEmpty( m_matrixHDName ) ) + { + matrixName = m_matrixHDName; + } + else if( dataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.Lightweight && !string.IsNullOrEmpty( m_matrixLWName ) ) + { + matrixName = m_matrixLWName; + } + else + { + matrixName = m_matrixName; + } + } + else + { + matrixName = m_matrixName; + } + + RegisterLocalVariable( 0, string.Format( "mul({0},{1})", matrixName, value ),ref dataCollector,"transform"+ OutputId ); + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ParentTransfNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ParentTransfNode.cs.meta new file mode 100644 index 00000000..5a714ba2 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ParentTransfNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 11f04432b7f1ffb43b584adb226614c6 +timeCreated: 1488206086 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/WorldToObjectTransfNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/WorldToObjectTransfNode.cs new file mode 100644 index 00000000..ccc57813 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/WorldToObjectTransfNode.cs @@ -0,0 +1,54 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +namespace AmplifyShaderEditor +{ + [System.Serializable] + [NodeAttributes( "World To Object", "Object Transform", "Transforms input to Object Space" )] + public sealed class WorldToObjectTransfNode : ParentTransfNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + m_matrixName = "unity_WorldToObject"; + m_matrixHDName = "GetWorldToObjectMatrix()"; + m_matrixLWName = "GetWorldToObjectMatrix()"; + m_previewShaderGUID = "79a5efd1e3309f54d8ba3e7fdf5e459b"; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + + string value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string matrixName = string.Empty; + if( dataCollector.IsTemplate ) + { + if( dataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD && !string.IsNullOrEmpty( m_matrixHDName ) ) + { + string varName = "localWorldVar" + OutputId; + dataCollector.AddLocalVariable( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT4, varName, value ); + dataCollector.AddLocalVariable( UniqueId, string.Format( "({0}).xyz", varName ), string.Format( "GetCameraRelativePositionWS(({0}).xyz);", varName ) ); + value = varName; + matrixName = m_matrixHDName; + } + else if( dataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.Lightweight && !string.IsNullOrEmpty( m_matrixLWName ) ) + { + matrixName = m_matrixLWName; + } + else + { + matrixName = m_matrixName; + } + } + else + { + matrixName = m_matrixName; + } + + RegisterLocalVariable( 0, string.Format( "mul({0},{1})", matrixName, value ), ref dataCollector, "transform" + OutputId ); + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/WorldToObjectTransfNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/WorldToObjectTransfNode.cs.meta new file mode 100644 index 00000000..8ad85ca4 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/WorldToObjectTransfNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8a25ccf8973bfae46ae3df2823f58229 +timeCreated: 1488205986 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/VectorFromMatrixNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/VectorFromMatrixNode.cs new file mode 100644 index 00000000..1095df44 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/VectorFromMatrixNode.cs @@ -0,0 +1,131 @@ +using System; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + public enum eVectorFromMatrixMode + { + Row, + Column + } + + [Serializable] + [NodeAttributes( "Vector From Matrix", "Matrix Operators", "Retrieve vector data from a matrix" )] + public sealed class VectorFromMatrixNode : ParentNode + { + private const string IndexStr = "Index"; + private const string ModeStr = "Mode"; + + [SerializeField] + private eVectorFromMatrixMode m_mode = eVectorFromMatrixMode.Row; + + [SerializeField] + private int m_index = 0; + + [SerializeField] + private int m_maxIndex = 3; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT4x4, false, Constants.EmptyPortValue ); + m_inputPorts[ 0 ].CreatePortRestrictions( WirePortDataType.FLOAT3x3, WirePortDataType.FLOAT4x4 ); + AddOutputVectorPorts( WirePortDataType.FLOAT4, "XYZW" ); + m_useInternalPortData = true; + m_autoWrapProperties = true; + } + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + UpdatePorts(); + } + + public override void OnConnectedOutputNodeChanges( int inputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( inputPortId, otherNodeId, otherPortId, name, type ); + UpdatePorts(); + } + + void UpdatePorts() + { + m_inputPorts[ 0 ].MatchPortToConnection(); + + if ( m_inputPorts[ 0 ].DataType == WirePortDataType.FLOAT3x3 ) + { + m_outputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT3, false ); + m_outputPorts[ 0 ].Name = "XYZ"; + m_maxIndex = 2; + m_outputPorts[ 4 ].Visible = false; + } + else + { + m_outputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT4, false ); + m_outputPorts[ 0 ].Name = "XYZW"; + m_maxIndex = 3; + m_outputPorts[ 4 ].Visible = true; + } + m_sizeIsDirty = true; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + string value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + if ( m_inputPorts[ 0 ].DataType != WirePortDataType.FLOAT4x4 && + m_inputPorts[ 0 ].DataType != WirePortDataType.FLOAT3x3 ) + { + value = UIUtils.CastPortType( ref dataCollector, CurrentPrecisionType, new NodeCastInfo( UniqueId, outputId ), value, m_inputPorts[ 0 ].DataType, WirePortDataType.FLOAT4x4, value ); + } + if ( m_mode == eVectorFromMatrixMode.Row ) + { + value += "[" + m_index + "]"; + } + else + { + string formatStr = value + "[{0}]" + "[" + m_index + "]"; + int count = 4; + if ( m_inputPorts[ 0 ].DataType != WirePortDataType.FLOAT3x3 ) + { + value = "float4( "; + } + else + { + count = 3; + value = "float3( "; + } + + for ( int i = 0; i < count; i++ ) + { + value += string.Format( formatStr, i ); + if ( i != ( count - 1 ) ) + { + value += ","; + } + } + value += " )"; + } + return GetOutputVectorItem( 0, outputId, value ); + } + + public override void DrawProperties() + { + m_mode = (eVectorFromMatrixMode)EditorGUILayoutEnumPopup( ModeStr, m_mode ); + m_index = EditorGUILayoutIntSlider( IndexStr, m_index, 0, m_maxIndex ); + base.DrawProperties(); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_mode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_index ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_mode = ( eVectorFromMatrixMode ) Enum.Parse( typeof( eVectorFromMatrixMode ), GetCurrentParam( ref nodeParams ) ); + m_index = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/VectorFromMatrixNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/VectorFromMatrixNode.cs.meta new file mode 100644 index 00000000..c2e6a9f5 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/VectorFromMatrixNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 31c07015a5f2aa44297aa7cfb80ffdd5 +timeCreated: 1481126954 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedAvgNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedAvgNode.cs new file mode 100644 index 00000000..2ef31bf2 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedAvgNode.cs @@ -0,0 +1,180 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using System; +using UnityEditor; +namespace AmplifyShaderEditor +{ + [Serializable] + + public class WeightedAvgNode : ParentNode + { + protected string[] AmountsStr = { "Layer 1", "Layer 2", "Layer 3", "Layer 4" }; + + [SerializeField] + protected int m_minimumSize = 1; + + [SerializeField] + protected WirePortDataType m_mainDataType = WirePortDataType.FLOAT; + + [SerializeField] + protected string[] m_inputData; + [SerializeField] + protected int m_activeCount = 0; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, "Weights" ); + AddInputPort( WirePortDataType.FLOAT, false, AmountsStr[ 0 ] ); + AddInputPort( WirePortDataType.FLOAT, false, AmountsStr[ 1 ] ); + AddInputPort( WirePortDataType.FLOAT, false, AmountsStr[ 2 ] ); + AddInputPort( WirePortDataType.FLOAT, false, AmountsStr[ 3 ] ); + AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + m_inputPorts[ i ].AddPortForbiddenTypes( WirePortDataType.FLOAT3x3, + WirePortDataType.FLOAT4x4, + WirePortDataType.SAMPLER1D, + WirePortDataType.SAMPLER2D, + WirePortDataType.SAMPLER3D, + WirePortDataType.SAMPLERCUBE ); + } + UpdateConnection( 0 ); + m_useInternalPortData = true; + } + + public override void OnConnectedOutputNodeChanges( int inputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( inputPortId, otherNodeId, otherPortId, name, type ); + UpdateConnection( inputPortId ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + UpdateConnection( portId ); + } + + void UpdateInputPorts( int activePorts ) + { + int idx = 1; + for ( ; idx < m_minimumSize + activePorts; idx++ ) + { + m_inputPorts[ idx ].Visible = true; + } + + m_activeCount = idx - 1; + + for ( ; idx < m_inputPorts.Count; idx++ ) + { + m_inputPorts[ idx ].Visible = false; + } + } + + protected void UpdateConnection( int portId ) + { + if ( portId == 0 ) + { + if( m_inputPorts[ portId ].IsConnected ) + m_inputPorts[ portId ].MatchPortToConnection(); + + switch ( m_inputPorts[ 0 ].DataType ) + { + case WirePortDataType.INT: + case WirePortDataType.FLOAT: + { + UpdateInputPorts( 1 ); + m_previewMaterialPassId = 0; + } + break; + case WirePortDataType.FLOAT2: + { + UpdateInputPorts( 2 ); + m_previewMaterialPassId = 1; + } + break; + case WirePortDataType.FLOAT3: + { + UpdateInputPorts( 3 ); + m_previewMaterialPassId = 2; + } + break; + case WirePortDataType.COLOR: + case WirePortDataType.FLOAT4: + { + UpdateInputPorts( 4 ); + m_previewMaterialPassId = 3; + } + break; + case WirePortDataType.OBJECT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + { + for ( int i = 1; i < m_inputPorts.Count; i++ ) + { + m_inputPorts[ i ].Visible = false; + } + m_activeCount = 0; + } + break; + } + } + //else + //{ + // SetMainOutputType(); + //} + + SetMainOutputType(); + m_sizeIsDirty = true; + } + + protected void SetMainOutputType() + { + m_mainDataType = WirePortDataType.OBJECT; + int count = m_inputPorts.Count; + for ( int i = 1; i < count; i++ ) + { + if ( m_inputPorts[ i ].Visible ) + { + WirePortDataType portType = m_inputPorts[ i ].IsConnected ? m_inputPorts[ i ].ConnectionType() : WirePortDataType.FLOAT; + if ( m_mainDataType != portType && + UIUtils.GetPriority( portType ) > UIUtils.GetPriority( m_mainDataType ) ) + { + m_mainDataType = portType; + } + } + } + + for( int i = 1; i < count; i++ ) + { + if( m_inputPorts[ i ].Visible ) + { + m_inputPorts[ i ].ChangeType( m_mainDataType, false ); + } + } + + m_outputPorts[ 0 ].ChangeType( m_mainDataType, false ); + } + + protected void GetInputData( ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + m_inputData[ 0 ] = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + for ( int i = 1; i < m_inputPorts.Count; i++ ) + { + if ( m_inputPorts[ i ].Visible ) + { + m_inputData[ i ] = m_inputPorts[ i ].GeneratePortInstructions( ref dataCollector ); + } + } + } + + public override void ReadInputDataFromString( ref string[] nodeParams ) + { + base.ReadInputDataFromString( ref nodeParams ); + UpdateConnection( 0 ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedAvgNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedAvgNode.cs.meta new file mode 100644 index 00000000..1faefae2 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedAvgNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 35c70c67524c86049a25b7ebd0de6ae3 +timeCreated: 1481126954 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedBlendNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedBlendNode.cs new file mode 100644 index 00000000..dc5fc1b0 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedBlendNode.cs @@ -0,0 +1,58 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using System; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Weighted Blend", "Miscellaneous", "Mix all channels through weighted average sum", null, KeyCode.None, true )] + public sealed class WeightedBlendNode : WeightedAvgNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + m_inputData = new string[ 6 ]; + m_previewShaderGUID = "6076cbeaa41ebb14c85ff81b58df7d88"; + } + + 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 ); + + GetInputData( ref dataCollector, ignoreLocalvar ); + + string result = string.Empty; + string avgSum = string.Empty; + + string localVarName = "weightedBlendVar" + OutputId; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_inputPorts[ 0 ].DataType, localVarName, m_inputData[ 0 ] ); + + if ( m_activeCount < 2 ) + { + return CreateOutputLocalVariable( 0, m_inputData[ 1 ], ref dataCollector ); + } + else + { + for ( int i = 0; i < m_activeCount; i++ ) + { + result += localVarName + Constants.VectorSuffixes[ i ] + "*" + m_inputData[ i + 1 ]; + avgSum += localVarName + Constants.VectorSuffixes[ i ]; + if ( i != ( m_activeCount - 1 ) ) + { + result += " + "; + avgSum += " + "; + } + } + } + + result = UIUtils.AddBrackets( result ) + "/" + UIUtils.AddBrackets( avgSum ); + result = UIUtils.AddBrackets( result ); + RegisterLocalVariable( 0, result, ref dataCollector, "weightedAvg" + OutputId ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedBlendNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedBlendNode.cs.meta new file mode 100644 index 00000000..744bfd0c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedBlendNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b91b2aefbfad5b444b25320e9ed53cac +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WireNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WireNode.cs new file mode 100644 index 00000000..4bcc5005 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WireNode.cs @@ -0,0 +1,484 @@ +using System; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Wire Node", "Miscellaneous", "Wire Node", null, KeyCode.None, false )] + public sealed class WireNode : ParentNode + { + private bool m_markedToDelete = false; + + [SerializeField] + private WirePortDataType m_visualDataType = WirePortDataType.FLOAT; + + bool m_forceVisualDataUpdate = false; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.OBJECT, false, string.Empty ); + AddOutputPort( WirePortDataType.OBJECT, Constants.EmptyPortValue ); + m_tooltipText = string.Empty; + m_drawPreview = false; + m_drawPreviewExpander = false; + m_canExpand = false; + m_previewShaderGUID = "fa1e3e404e6b3c243b5527b82739d682"; + } + + public WirePortDataType GetLastInputDataTypeRecursively() + { + if( m_outputPorts[ 0 ].ExternalReferences.Count > 0 ) + { + WireNode rightWire = m_outputPorts[ 0 ].GetInputNode( 0 ) as WireNode; + if( rightWire != null ) + return rightWire.GetLastInputDataTypeRecursively(); + else + { + return m_outputPorts[ 0 ].GetInputConnection( 0 ).DataType; + } + } + + if( m_containerGraph.ParentWindow.WireReferenceUtils.OutputPortReference.IsValid ) + return m_containerGraph.ParentWindow.WireReferenceUtils.OutputPortReference.DataType; + else + return m_visualDataType; + } + + public override WirePortDataType GetInputPortVisualDataTypeByArrayIdx( int portArrayIdx ) + { + return m_visualDataType; + } + + public override WirePortDataType GetOutputPortVisualDataTypeById( int portId ) + { + return m_visualDataType; + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + + m_forceVisualDataUpdate = true; + } + + public override void OnOutputPortConnected( int portId, int otherNodeId, int otherPortId ) + { + base.OnOutputPortConnected( portId, otherNodeId, otherPortId ); + + if( m_outputPorts[ portId ].ConnectionCount > 1 ) + { + for( int i = 0; i < m_outputPorts[ portId ].ExternalReferences.Count; i++ ) + { + if( m_outputPorts[ portId ].ExternalReferences[ i ].PortId != otherPortId ) + { + UIUtils.DeleteConnection( true, m_outputPorts[ portId ].ExternalReferences[ i ].NodeId, m_outputPorts[ portId ].ExternalReferences[ i ].PortId, false, true ); + } + } + } + + m_inputPorts[ 0 ].NotifyExternalRefencesOnChange(); + m_forceVisualDataUpdate = true; + } + + public override void OnConnectedInputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedInputNodeChanges( portId, otherNodeId, otherPortId, name, type ); + + m_inputPorts[ 0 ].NotifyExternalRefencesOnChange(); + m_forceVisualDataUpdate = true; + } + + public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + + m_forceVisualDataUpdate = true; + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + TestIfValid(); + + m_forceVisualDataUpdate = true; + m_outputPorts[ 0 ].NotifyExternalRefencesOnChange(); + } + + public override void OnOutputPortDisconnected( int portId ) + { + base.OnOutputPortDisconnected( portId ); + TestIfValid(); + + m_forceVisualDataUpdate = true; + m_inputPorts[ 0 ].NotifyExternalRefencesOnChange(); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + return m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + } + + public override void DrawProperties() + { + if( m_markedToDelete ) + return; + + base.DrawProperties(); + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + if( m_firstDraw ) + { + m_firstDraw = false; + AfterCommonInit(); + OnNodeChange(); + } + + if( m_forceVisualDataUpdate ) + { + m_forceVisualDataUpdate = false; + m_visualDataType = GetLastInputDataTypeRecursively(); + } + + if( m_repopulateDictionaries ) + { + m_repopulateDictionaries = false; + + m_inputPortsDict.Clear(); + int inputCount = m_inputPorts.Count; + for( int i = 0; i < inputCount; i++ ) + { + m_inputPortsDict.Add( m_inputPorts[ i ].PortId, m_inputPorts[ i ] ); + } + + m_outputPortsDict.Clear(); + int outputCount = m_outputPorts.Count; + for( int i = 0; i < outputCount; i++ ) + { + m_outputPortsDict.Add( m_outputPorts[ i ].PortId, m_outputPorts[ i ] ); + } + } + + if( m_sizeIsDirty ) + { + m_sizeIsDirty = false; + m_extraSize.Set( 20f, 20f ); + m_position.width = m_extraSize.x + UIUtils.PortsSize.x; + m_position.height = m_extraSize.y + UIUtils.PortsSize.y; + + Vec2Position -= Position.size * 0.5f; + if( OnNodeChangeSizeEvent != null ) + { + OnNodeChangeSizeEvent( this ); + } + + ChangeSizeFinished(); + //ChangeSize(); + } + + CalculatePositionAndVisibility( drawInfo ); + + // Input Ports + { + m_currInputPortPos = m_globalPosition; + m_currInputPortPos.width = drawInfo.InvertedZoom * UIUtils.PortsSize.x; + m_currInputPortPos.height = drawInfo.InvertedZoom * UIUtils.PortsSize.y; + m_currInputPortPos.position = m_globalPosition.center - m_currInputPortPos.size * 0.5f; + int inputCount = m_inputPorts.Count; + + for( int i = 0; i < inputCount; i++ ) + { + if( m_inputPorts[ i ].Visible ) + { + // Button + m_inputPorts[ i ].Position = m_currInputPortPos; + + if( !m_inputPorts[ i ].Locked ) + { + float overflow = 2; + float scaledOverflow = 3 * drawInfo.InvertedZoom; + m_auxRect = m_currInputPortPos; + m_auxRect.yMin -= scaledOverflow + overflow; + m_auxRect.yMax += scaledOverflow + overflow; + m_auxRect.xMin -= Constants.PORT_INITIAL_X * drawInfo.InvertedZoom + scaledOverflow + overflow; + m_auxRect.xMax += m_inputPorts[ i ].LabelSize.x + Constants.PORT_TO_LABEL_SPACE_X * drawInfo.InvertedZoom + scaledOverflow + overflow; + m_inputPorts[ i ].ActivePortArea = m_auxRect; + } + m_currInputPortPos.y += drawInfo.InvertedZoom * ( m_fontHeight + Constants.INPUT_PORT_DELTA_Y ); + } + } + } + + // Output Ports + { + m_currOutputPortPos = m_globalPosition; + m_currOutputPortPos.width = drawInfo.InvertedZoom * UIUtils.PortsSize.x; + m_currOutputPortPos.height = drawInfo.InvertedZoom * UIUtils.PortsSize.y; + m_currOutputPortPos.position = m_globalPosition.center - m_currOutputPortPos.size * 0.5f; + //m_currOutputPortPos.x += ( m_globalPosition.width - drawInfo.InvertedZoom * ( Constants.PORT_INITIAL_X + m_anchorAdjust ) ); + //m_currOutputPortPos.y += drawInfo.InvertedZoom * Constants.PORT_INITIAL_Y;// + m_extraHeaderHeight * drawInfo.InvertedZoom; + int outputCount = m_outputPorts.Count; + + for( int i = 0; i < outputCount; i++ ) + { + if( m_outputPorts[ i ].Visible ) + { + //Button + m_outputPorts[ i ].Position = m_currOutputPortPos; + + if( !m_outputPorts[ i ].Locked ) + { + float overflow = 2; + float scaledOverflow = 3 * drawInfo.InvertedZoom; + m_auxRect = m_currOutputPortPos; + m_auxRect.yMin -= scaledOverflow + overflow; + m_auxRect.yMax += scaledOverflow + overflow; + m_auxRect.xMin -= m_outputPorts[ i ].LabelSize.x + Constants.PORT_TO_LABEL_SPACE_X * drawInfo.InvertedZoom + scaledOverflow + overflow; + m_auxRect.xMax += Constants.PORT_INITIAL_X * drawInfo.InvertedZoom + scaledOverflow + overflow; + m_outputPorts[ i ].ActivePortArea = m_auxRect; + } + m_currOutputPortPos.y += drawInfo.InvertedZoom * ( m_fontHeight + Constants.INPUT_PORT_DELTA_Y ); + } + } + } + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + //base.OnRepaint( drawInfo ); + //return; + if( !m_isVisible ) + return; + + m_colorBuffer = GUI.color; + + // Output Ports + int outputCount = m_outputPorts.Count; + for( int i = 0; i < outputCount; i++ ) + { + if( m_outputPorts[ i ].Visible ) + { + // Output Port Icon + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 ) + { + if( m_outputPorts[ i ].Locked ) + GUI.color = Constants.LockedPortColor; + else if( ContainerGraph.ParentWindow.Options.ColoredPorts ) + GUI.color = UIUtils.GetColorForDataType( m_visualDataType, false, false ); + else + GUI.color = m_outputPorts[ i ].HasCustomColor ? m_outputPorts[ i ].CustomColor : UIUtils.GetColorForDataType( m_visualDataType, true, false ); + + GUIStyle style = m_outputPorts[ i ].IsConnected ? UIUtils.GetCustomStyle( CustomStyle.PortFullIcon ) : UIUtils.GetCustomStyle( CustomStyle.PortEmptyIcon ); + GUI.Label( m_outputPorts[ i ].Position, string.Empty, style ); + + GUI.color = m_colorBuffer; + } + + // Output Port Label + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 ) + { + if( m_outputPorts[ i ].Locked ) + { + GUI.color = Constants.PortLockedTextColor; + GUI.Label( m_outputPorts[ i ].LabelPosition, m_outputPorts[ i ].Name, UIUtils.OutputPortLabel ); + GUI.color = m_colorBuffer; + } + else + { + GUI.Label( m_outputPorts[ i ].LabelPosition, m_outputPorts[ i ].Name, UIUtils.OutputPortLabel ); + } + } + } + } + + // Selection Box + if( m_selected ) + { + Rect selectionBox = m_globalPosition; + selectionBox.size = Vector2.one * 16 * drawInfo.InvertedZoom + Vector2.one * 4; + selectionBox.center = m_globalPosition.center; + GUI.DrawTexture( selectionBox, UIUtils.WireNodeSelection ); + GUI.color = m_colorBuffer; + } + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + //base.DrawGUIControls( drawInfo ); + } + + public override void Draw( DrawInfo drawInfo ) + { + if( m_markedToDelete ) + return; + + if( drawInfo.CurrentEventType == EventType.Repaint ) + OnNodeRepaint( drawInfo ); + //base.Draw( drawInfo ); + + if( drawInfo.CurrentEventType == EventType.Repaint ) + TestIfValid(); + } + + bool TestIfValid() + { + if( !Alive ) + return false; + + bool result = true; + if( !m_inputPorts[ 0 ].IsConnected ) + { + if( !m_containerGraph.ParentWindow.WireReferenceUtils.InputPortReference.IsValid || m_containerGraph.ParentWindow.WireReferenceUtils.InputPortReference.IsValid && m_containerGraph.ParentWindow.WireReferenceUtils.InputPortReference.NodeId != UniqueId ) + { + ContainerGraph.MarkWireNodeSequence( this, true ); + result = false; + } + } + + if( !m_outputPorts[ 0 ].IsConnected ) + { + if( !m_containerGraph.ParentWindow.WireReferenceUtils.OutputPortReference.IsValid || m_containerGraph.ParentWindow.WireReferenceUtils.OutputPortReference.IsValid && m_containerGraph.ParentWindow.WireReferenceUtils.OutputPortReference.NodeId != UniqueId ) + { + ContainerGraph.MarkWireNodeSequence( this, false ); + result = false; + } + } + return result; + } + + public Vector3 TangentDirection + { + get + { + ParentNode otherInputNode = null; + ParentNode otherOutputNode = null; + + //defaults to itself so it can still calculate tangents + WirePort otherInputPort = m_outputPorts[ 0 ]; + WirePort otherOutputPort = m_inputPorts[ 0 ]; + + if( m_outputPorts[ 0 ].ConnectionCount > 0 ) + { + otherInputNode = m_containerGraph.GetNode( m_outputPorts[ 0 ].ExternalReferences[ 0 ].NodeId ); + otherInputPort = otherInputNode.GetInputPortByUniqueId( m_outputPorts[ 0 ].ExternalReferences[ 0 ].PortId ); + } + + if( m_inputPorts[ 0 ].ConnectionCount > 0 ) + { + otherOutputNode = m_containerGraph.GetNode( m_inputPorts[ 0 ].ExternalReferences[ 0 ].NodeId ); + otherOutputPort = otherOutputNode.GetOutputPortByUniqueId( m_inputPorts[ 0 ].ExternalReferences[ 0 ].PortId ); + } + + //TODO: it still generates crooked lines if wire nodes get too close to non-wire nodes (the fix would be to calculate the non-wire nodes magnitude properly) + float mag = Constants.HORIZONTAL_TANGENT_SIZE * ContainerGraph.ParentWindow.CameraDrawInfo.InvertedZoom; + + Vector2 outPos; + if( otherOutputNode != null && otherOutputNode.GetType() != typeof( WireNode ) ) + outPos = otherOutputPort.Position.position + Vector2.right * mag * 0.66f; + else + outPos = otherOutputPort.Position.position; + + Vector2 inPos; + if( otherInputNode != null && otherInputNode.GetType() != typeof( WireNode ) ) + inPos = otherInputPort.Position.position - Vector2.right * mag * 0.66f; + else + inPos = otherInputPort.Position.position; + + Vector2 tangent = ( outPos - inPos ).normalized; + return new Vector3( tangent.x, tangent.y ); + } + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + + m_extraSize.Set( 20f, 20f ); + m_position.width = m_extraSize.x + UIUtils.PortsSize.x; + m_position.height = m_extraSize.y + UIUtils.PortsSize.y; + + Vec2Position += Position.size * 0.5f; + } + + public override void OnAfterDeserialize() + { + base.OnAfterDeserialize(); + m_sizeIsDirty = false; + } + + public WireReference FindNewValidInputNode( WireNode current ) + { + if( current.InputPorts[ 0 ].IsConnected ) + { + ParentNode node = m_containerGraph.GetNode( current.InputPorts[ 0 ].ExternalReferences[ 0 ].NodeId ); + if( node != null ) + { + WireNode wireNode = node as WireNode; + if( wireNode != null && wireNode.MarkToDelete ) + { + return FindNewValidInputNode( wireNode ); + } + else + { + return current.InputPorts[ 0 ].ExternalReferences[ 0 ]; + } + } + } + return null; + } + + public WireReference FindNewValidOutputNode( WireNode current ) + { + if( current.OutputPorts[ 0 ].IsConnected ) + { + ParentNode node = m_containerGraph.GetNode( current.OutputPorts[ 0 ].ExternalReferences[ 0 ].NodeId ); + + if( node != null ) + { + WireNode wireNode = node as WireNode; + if( wireNode != null && wireNode.MarkToDelete ) + { + return FindNewValidOutputNode( wireNode ); + } + else + { + return current.OutputPorts[ 0 ].ExternalReferences[ 0 ]; + } + } + } + return null; + } + + public override void Rewire() + { + //if ( m_inputPorts[ 0 ].ExternalReferences != null && m_inputPorts[ 0 ].ExternalReferences.Count > 0 ) + //{ + //WireReference backPort = m_inputPorts[ 0 ].ExternalReferences[ 0 ]; + //for ( int i = 0; i < m_outputPorts[ 0 ].ExternalReferences.Count; i++ ) + //{ + // UIUtils.CurrentWindow.ConnectInputToOutput( m_outputPorts[ 0 ].ExternalReferences[ i ].NodeId, m_outputPorts[ 0 ].ExternalReferences[ i ].PortId, backPort.NodeId, backPort.PortId ); + //} + //} + MarkToDelete = true; + WireReference outputReference = FindNewValidInputNode( this ); + WireReference inputReference = FindNewValidOutputNode( this ); + if( outputReference != null && inputReference != null ) + { + ContainerGraph.ParentWindow.ConnectInputToOutput( inputReference.NodeId, inputReference.PortId, outputReference.NodeId, outputReference.PortId ); + } + } + + public bool MarkToDelete + { + get { return m_markedToDelete; } + set { m_markedToDelete = value; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WireNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WireNode.cs.meta new file mode 100644 index 00000000..ab597cb9 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WireNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7a566d6bf220cd74b8385a91f690b683 +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |