You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

297 lines
10 KiB

// Amplify Shader Editor - Visual Shader Editing Tool
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
using UnityEngine;
using System;
//using System.Collections.Generic;
//using UnityEditor;
namespace AmplifyShaderEditor
{
[Serializable]
[NodeAttributes( "If", "Logical Operators", "Conditional comparison between A with B." )]
public sealed class ConditionalIfNode : ParentNode
{
private const string UseUnityBranchesStr = "Dynamic Branching";
private const string UnityBranchStr = "UNITY_BRANCH ";
private readonly string[] IfOps = { "if( {0} > {1} )",
"if( {0} == {1} )",
"if( {0} < {1} )",
"if( {0} >= {1} )",
"if( {0} <= {1} )",
"if( {0} != {1} )" };
//private WirePortDataType m_inputMainDataType = WirePortDataType.FLOAT;
private WirePortDataType m_outputMainDataType = WirePortDataType.FLOAT;
private string[] m_results = { string.Empty, string.Empty, string.Empty };
[SerializeField]
private bool m_useUnityBranch = false;
protected override void CommonInit( int uniqueId )
{
base.CommonInit( uniqueId );
AddInputPort( WirePortDataType.FLOAT, false, "A" );
AddInputPort( WirePortDataType.FLOAT, false, "B" );
m_inputPorts[ 0 ].AddPortRestrictions( WirePortDataType.FLOAT, WirePortDataType.INT );
m_inputPorts[ 1 ].AddPortRestrictions( WirePortDataType.FLOAT, WirePortDataType.INT );
AddInputPort( WirePortDataType.FLOAT, false, "A > B" );
AddInputPort( WirePortDataType.FLOAT, false, "A == B" );
AddInputPort( WirePortDataType.FLOAT, false, "A < B" );
AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
m_inputPorts[ 0 ].AutoDrawInternalData = true;
m_inputPorts[ 1 ].AutoDrawInternalData = true;
m_textLabelWidth = 131;
//m_useInternalPortData = true;
m_autoWrapProperties = true;
m_previewShaderGUID = "f6fb4d46bddf29e45a8a3ddfed75d0c0";
}
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 );
}
public override void DrawProperties()
{
base.DrawProperties();
if( !m_inputPorts[ 0 ].IsConnected )
m_inputPorts[ 0 ].FloatInternalData = EditorGUILayoutFloatField( m_inputPorts[ 0 ].Name, m_inputPorts[ 0 ].FloatInternalData );
if( !m_inputPorts[ 1 ].IsConnected )
m_inputPorts[ 1 ].FloatInternalData = EditorGUILayoutFloatField( m_inputPorts[ 1 ].Name, m_inputPorts[ 1 ].FloatInternalData );
m_useUnityBranch = EditorGUILayoutToggle( UseUnityBranchesStr, m_useUnityBranch );
}
public override void OnInputPortDisconnected( int portId )
{
base.OnInputPortDisconnected( portId );
UpdateConnection( portId );
}
//void TestMainInputDataType()
//{
// WirePortDataType newType = WirePortDataType.FLOAT;
// if ( m_inputPorts[ 0 ].IsConnected && UIUtils.GetPriority( m_inputPorts[ 0 ].DataType ) > UIUtils.GetPriority( newType ) )
// {
// newType = m_inputPorts[ 0 ].DataType;
// }
// if ( m_inputPorts[ 1 ].IsConnected && ( UIUtils.GetPriority( m_inputPorts[ 1 ].DataType ) > UIUtils.GetPriority( newType ) ) )
// {
// newType = m_inputPorts[ 1 ].DataType;
// }
// m_inputMainDataType = newType;
//}
void TestMainOutputDataType()
{
WirePortDataType newType = WirePortDataType.FLOAT;
for( int i = 2; i < 5; i++ )
{
if( m_inputPorts[ i ].IsConnected && ( UIUtils.GetPriority( m_inputPorts[ i ].DataType ) > UIUtils.GetPriority( newType ) ) )
{
newType = m_inputPorts[ i ].DataType;
}
}
if( newType != m_outputMainDataType )
{
m_outputMainDataType = newType;
}
m_outputPorts[ 0 ].ChangeType( m_outputMainDataType, false );
}
public void UpdateConnection( int portId )
{
m_inputPorts[ portId ].MatchPortToConnection();
switch( portId )
{
//case 0:
//case 1:
//{
// TestMainInputDataType();
//}
//break;
case 2:
case 3:
case 4:
{
TestMainOutputDataType();
}
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 AValue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector);
string BValue = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
m_results[ 0 ] = m_inputPorts[ 2 ].GenerateShaderForOutput( ref dataCollector, m_outputMainDataType, ignoreLocalvar, true );
m_results[ 1 ] = m_inputPorts[ 3 ].GenerateShaderForOutput( ref dataCollector, m_outputMainDataType, ignoreLocalvar, true );
m_results[ 2 ] = m_inputPorts[ 4 ].GenerateShaderForOutput( ref dataCollector, m_outputMainDataType, ignoreLocalvar, true );
string localVarName = "ifLocalVar" + OutputId;
string localVarDec = string.Format( "{0} {1} = 0;", UIUtils.FinalPrecisionWirePortToCgType( m_currentPrecisionType, m_outputPorts[ 0 ].DataType ), localVarName );
bool lequal = false;
bool greater = false;
bool lesser = false;
bool gequal = false;
bool equal = false;
bool nequal = false;
bool welse = false;
bool midCon = false;
if( m_inputPorts[ 2 ].IsConnected )
{
greater = true;
}
if( m_inputPorts[ 4 ].IsConnected )
{
lesser = true;
}
if( greater && m_inputPorts[ 2 ].GetOutputConnection() == m_inputPorts[ 3 ].GetOutputConnection() )
{
gequal = true;
}
if( lesser && m_inputPorts[ 4 ].GetOutputConnection() == m_inputPorts[ 3 ].GetOutputConnection() )
{
lequal = true;
}
if( m_inputPorts[ 2 ].GetOutputConnection() == m_inputPorts[ 4 ].GetOutputConnection() )
{
if( m_inputPorts[ 3 ].IsConnected )
equal = true;
else if( m_inputPorts[ 2 ].IsConnected )
nequal = true;
}
if( m_inputPorts[ 3 ].IsConnected )
{
midCon = true;
if( greater && lesser )
welse = true;
}
dataCollector.AddLocalVariable( UniqueId, localVarDec, true );
if ( m_useUnityBranch && !( lequal && gequal ) && !( !greater && !midCon && !lesser ) )
dataCollector.AddLocalVariable( UniqueId, UnityBranchStr, true );
if( lequal && gequal ) // all equal
{
dataCollector.AddLocalVariable( UniqueId, string.Format( "{0} = {1};", localVarName, m_results[ 1 ] ), true );
}
else if( !lequal && gequal ) // greater or equal
{
dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 3 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
if( welse )
{
dataCollector.AddLocalVariable( UniqueId, "else", true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 2 ] ), true );
}
}
else if( lequal && !gequal )// lesser or equal
{
dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 4 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 2 ] ), true );
if( welse )
{
dataCollector.AddLocalVariable( UniqueId, "else", true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
}
}
else if( nequal )// not equal
{
dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 5 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
}
else if( equal )// equal
{
dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 1 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 1 ] ), true );
if( welse )
{
dataCollector.AddLocalVariable( UniqueId, "else", true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
}
}
else if( lesser && !midCon && !greater ) // lesser
{
dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 2 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 2 ] ), true );
}
else if( greater && !midCon && !lesser ) // greater
{
dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 0 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
}
else if( !greater && !midCon && !lesser ) // none
{
//dataCollector.AddLocalVariable( UniqueId, localVarDec );
}
else // all different
{
bool ifStarted = false;
if( greater )
{
dataCollector.AddLocalVariable( UniqueId, string.Format( IfOps[ 0 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 0 ] ), true );
ifStarted = true;
}
if( midCon )
{
dataCollector.AddLocalVariable( UniqueId, ( ifStarted ? "else " : string.Empty ) +string.Format( IfOps[ 1 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 1 ] ), true );
ifStarted = true;
}
if( lesser )
{
dataCollector.AddLocalVariable( UniqueId, "else " + string.Format( IfOps[ 2 ], AValue, BValue ), true );
dataCollector.AddLocalVariable( UniqueId, string.Format( "\t{0} = {1};", localVarName, m_results[ 2 ] ), true );
}
}
m_outputPorts[ 0 ].SetLocalValue( localVarName, dataCollector.PortCategory );
return localVarName;
}
public override void ReadFromString( ref string[] nodeParams )
{
base.ReadFromString( ref nodeParams );
if( UIUtils.CurrentShaderVersion() > 4103 )
{
m_useUnityBranch = 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_useUnityBranch );
}
}
}