summaryrefslogtreecommitdiff
path: root/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc')
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/AppendNode.cs254
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/AppendNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/BreakToComponentsNode.cs273
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/BreakToComponentsNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/CustomExpressionNode.cs1625
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/CustomExpressionNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs475
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/DynamicAppendNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/FresnelNode.cs393
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/FresnelNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/GetLocalVarNode.cs430
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/GetLocalVarNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LayeredBlendNode.cs61
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LayeredBlendNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LinearDepthNode.cs97
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/LinearDepthNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/MatrixFromVectors.cs215
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/MatrixFromVectors.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/PosFromTransformMatrix.cs34
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/PosFromTransformMatrix.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RegisterLocalVarNode.cs346
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RegisterLocalVarNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RelayNode.cs38
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RelayNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RotateAboutAxisNode.cs95
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/RotateAboutAxisNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SummedBlendNode.cs56
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SummedBlendNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwitchNode.cs230
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwitchNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwizzleNode.cs441
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/SwizzleNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/ToggleSwitchNode.cs285
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/ToggleSwitchNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation.meta9
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ObjectToWorldTransfNode.cs30
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ObjectToWorldTransfNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ParentTransfNode.cs53
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/ParentTransfNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/WorldToObjectTransfNode.cs54
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/Transformation/WorldToObjectTransfNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/VectorFromMatrixNode.cs131
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/VectorFromMatrixNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedAvgNode.cs180
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedAvgNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedBlendNode.cs58
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WeightedBlendNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WireNode.cs484
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Misc/WireNode.cs.meta12
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: