Roman 5b28c9a977 Squashed commit of the following:
commit bb3be793ca5db3df43679f2d6c34c75f768047a1
Author: SAIPO <grasste0403@hotmail.com>
Date:   Wed Dec 22 07:46:07 2021 +0800

    修改佛教Boss关卡和伊斯兰Boss关卡的粒子特效

commit 1987a63954402be8894f9cc9805545432afefa18
Author: SAIPO <grasste0403@hotmail.com>
Date:   Tue Dec 21 20:55:05 2021 +0800

    任务:编写shader,完善数据库类
    1.完善了PlayerInfo类,用以数据库功能
     1) 编写GetSqlData()函数,使用多线程获取用户信息,使用前请先设置公关变量name。
     2) 编写CreateUser(string username)函数,在用户表内创建一个用户。
     3) 编写hasName(string _searchName)函数,判断是否存在这个用户。
     4) 编写GetBoardInfo(int WorldId)函数,获取指定世界的留言板链表。
     5) 编写GetDeadInfo(int WorldId)函数,获取指定世界的死亡信息链表。
     6) 编写CreateDead(int WorldId, Vector2 postion)函数,创建一条死亡信息。
     7) 编写CreateBoard(int WorldId, Vector2 postion,string text)函数,创建一条留言信息。
     8) 编写UpdatePlayerInfo()函数,将类里储存的信息上传到数据库。

    2.实装相关Shader
     1)完善以撒关卡的屏幕后特效,使其可以在发怒场景发出红色辉光。
     2)完善以撒鬼魂的粒子,并且颜色和发怒与否关联。
     3)实装以撒关卡的窗户辉光效果。
     4)实装伊斯兰Boss关卡炸弹弹反的粒子特效。
     5)实装伊斯兰Boss关卡的尘土特效(需要重做)
     6)实装佛教Boss关卡的敲钟声波特效。
     7)实装佛教Boss关卡的钟声受击灰尘(需要重做)

    3.目前发现的bug
     1)当人物恰好调到角落里会卡动画。
     2)伊斯兰Boss关卡,特洛伊木马吐出的炸弹落到特效小怪上会闪退。

commit c06b842382051bc260d9f509491c683a41ca2a4c
Author: SAIPO <grasste0403@hotmail.com>
Date:   Tue Dec 21 14:08:06 2021 +0800

    Squashed commit of the following:

    commit e7dcdec1d9913e283f42d42f72f1030f0c8b6fda
    Author: Roman <1325980292@qq.com>
    Date:   Tue Dec 21 00:45:50 2021 +0800

        任务:搭建前置关卡,编写演出逻辑

        1.流程化游戏
        (1.制作转移器,内含字典,根据玩家的静态属性“阶段”来决定到转移点后将会移动到哪一个场景
        (2.制作转场器,水平方向从左到右

        下班

    commit 74f926815ec8d00fa051192eb3b978ff4b3c01a6
    Author: Roman <1325980292@qq.com>
    Date:   Mon Dec 20 23:33:14 2021 +0800

        任务:搭建前置关卡,编写演出逻辑

        1.编写基督前置关卡
        (1.放置平台、怪物和男童
        (2.修改男童类,外加OnSaveEvent,OnSave时若有事件则触发该Event
        (3.编写开幕演出,与yi前置类似
        (4.编写男童解救演出
        ((1.触发Fungus对话
        ((2.对话结束后,开启通往上层的门

        2.搭建村场景
        (1.放置平台和元素
        (2.为可动元素制作动画

        3.为玩家添加static属性,进度。0:刚开,1进村,2通佛,3通伊,4.通基

        4.制作死亡重开功能
        (1.当玩家生命值降到0及以下,触发死亡事件
        (2.死亡后reload当前场景,并设记录员,关闭某些事件和演出不再执行

        *优化和修复
        (1.尝试制作击中卡肉效果,目前打击感太弱。也可以尝试粒子效果

        *至此,全部前置关卡搭建完毕,村场景搭建完毕。
        *明天可以完成流程化,接下来就是填充剧情、UI、死亡标记和留言板等系统了

        下班

    commit f257b40d10373a13380e9c395fe94d6559a82a0f
    Author: Roman <1325980292@qq.com>
    Date:   Sun Dec 19 23:57:44 2021 +0800

        任务:搭建前置关卡,编写演出逻辑

        1.编写佛教前置关开场演出
        (*.休整地形,使得左边多出一块地面,方便演出正常运作
        (*.项目后期再通过逻辑触发该演出,目前先用调试方式触发演出
        (1.关闭空气墙
        (2.修改玩家inputDir使玩家从屏幕外冲进到屏幕内部
        (3.等待一段时间
        (4.此时玩家应该走到某个合适的位置,停止玩家的inputDir
        (5.等待一小段时间给玩家反应
        (6.修改相机offset,使其对准对话的两个小怪
        (7.等待一小段时间给玩家反应
        (8.触发Fungus对话
        (9.Fungus对话结束后,返回标记命令演出Main继续执行
        *.修改NormalEnemy,添加标识isInFoStage,在Update中判断,若是,使该怪物水平方向上追踪玩家,可以参考爱欲品的Seek
        (10.修改左边小怪的isInFoStage
        (11.开启右边小怪的Path动画,表现其慌忙逃跑
        (12.Invoke一个延时,等右边小怪逃出视野后删除它
        (13.触发善后和结束事件
        (14.重写善后事件,重新开启空气墙

        2.搭建伊斯兰前置关卡

        3.创建伊斯兰前置关卡演出
        (1.关闭空气墙
        (2.修改玩家inputDir使玩家从屏幕外冲进到屏幕内部
        (3.等待一段时间
        (4.此时玩家应该走到某个合适的位置,停止玩家的inputDir
        (5.等待一小段时间给玩家反应
        (6.触发善后与结束事件

        4.创建玩家隔间触发事件
        (1.是进入式触发器对象
        (2.触发时Call隔间演出

        5.编写隔间演出逻辑
        (1.表现关门
        (2.左右晃一下镜头,中心移动到左右门处,表示门被关闭
        (3.镜头回到玩家处,同时压缩相机可移动范围更窄
        (4.打开隔间墙壁的空气墙
        (5.设置EndEvent为伊斯兰事件

        6.编写召唤伊斯兰事件
        (1.摘自木马的召唤攻击,稍作修改
        (2.当召唤的伊斯兰全部挂了,触发隔间结束事件

        7.编写隔间结束事件
        (1.表现开门
        (2.关闭隔间的空气墙
        (3.重设相机移动范围

        8.搭建基督前置关卡

        *.至此,第一关、第二关前置关卡的逻辑基本开发完毕

        *.明天能做完所有前置关,顺便应该能搭完村场景,后天可以开始搭建新系统,目前还差留言、死亡标记等系统等待编写

        下班

    commit cd22966ad7637a84c0f08c3a716d5ec549699749
    Author: Roman <1325980292@qq.com>
    Date:   Sun Dec 19 14:12:05 2021 +0800

        Squashed commit of the following:

        commit 26aff356971bdc2c2a6a3bd444eeb50c4bf7ec14
        Author: SAIPO <grasste0403@hotmail.com>
        Date:   Sun Dec 19 02:20:44 2021 +0800

            导入近期制作的一些Shader
            1.合并分支
            2.完成了人物描边的流动shader制作,并且可以对Bloom屏幕后处理产生反应。
            3.完成了基督教boss关卡,彩色窗户辉光的shader制作,可以对Bloom产生反应。
            4.完成了伊斯兰教弹反的炸弹拖尾粒子shader的制作。
            5.完成了火焰粒子shader的制作(可以用在基督教的以撒鬼魂上)。
            6.完成了灰尘粒子像素化的shader制作。
            7.完成了边缘扭曲的shader制作,可以用在一些树木上,让画面产生动感。

            明天制作敲钟的声波Shader

    # Conflicts:
    #	UserSettings/EditorUserSettings.asset

commit 26aff356971bdc2c2a6a3bd444eeb50c4bf7ec14
Author: SAIPO <grasste0403@hotmail.com>
Date:   Sun Dec 19 02:20:44 2021 +0800

    导入近期制作的一些Shader
    1.合并分支
    2.完成了人物描边的流动shader制作,并且可以对Bloom屏幕后处理产生反应。
    3.完成了基督教boss关卡,彩色窗户辉光的shader制作,可以对Bloom产生反应。
    4.完成了伊斯兰教弹反的炸弹拖尾粒子shader的制作。
    5.完成了火焰粒子shader的制作(可以用在基督教的以撒鬼魂上)。
    6.完成了灰尘粒子像素化的shader制作。
    7.完成了边缘扭曲的shader制作,可以用在一些树木上,让画面产生动感。

    明天制作敲钟的声波Shader

# Conflicts:
#	Assets/Scenes/TeLuoYiStageTest.unity
#	Assets/Shader/火焰粒子shader/particle.shadergraph
#	Assets/Shader/灰尘粒子用shader/Pixel_My.shader
#	Assets/Shader/灰尘粒子用shader/Unlit_Pixel_My 1.mat
#	Assets/Shader/灰尘粒子用shader/Unlit_Pixel_My 2.mat
#	Assets/Shader/灰尘粒子用shader/Unlit_Pixel_My.mat
#	Logs/ApiUpdaterCheck.txt
#	UserSettings/EditorUserSettings.asset
2021-12-22 10:01:30 +08:00

4061 lines
119 KiB
C#

// Amplify Shader Editor - Visual Shader Editing Tool
// Copyright (c) Amplify Creations, Lda <info@amplify.pt>
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
namespace AmplifyShaderEditor
{
[Serializable]
public class ParentGraph : ScriptableObject, ISerializationCallbackReceiver
{
private const int MasterNodeLODIncrement = 100;
private const int MaxLodAmount = 9;
public enum NodeLOD
{
LOD0,
LOD1,
LOD2,
LOD3,
LOD4,
LOD5
}
[SerializeField]
private bool m_samplingThroughMacros = false;
private NodeLOD m_lodLevel = NodeLOD.LOD0;
private GUIStyle nodeStyleOff;
private GUIStyle nodeStyleOn;
private GUIStyle nodeTitle;
private GUIStyle commentaryBackground;
public delegate void LODMasterNodesAdded( int lod );
public event LODMasterNodesAdded OnLODMasterNodesAddedEvent;
public delegate void EmptyGraphDetected( ParentGraph graph );
public event EmptyGraphDetected OnEmptyGraphDetectedEvt;
public delegate void NodeEvent( ParentNode node );
public event NodeEvent OnNodeEvent = null;
public event NodeEvent OnNodeRemovedEvent;
public delegate void DuplicateEvent();
public event DuplicateEvent OnDuplicateEvent;
public event MasterNode.OnMaterialUpdated OnMaterialUpdatedEvent;
public event MasterNode.OnMaterialUpdated OnShaderUpdatedEvent;
private bool m_afterDeserializeFlag = true;
private bool m_lateOptionsRefresh = false;
private bool m_foundDuplicates = false;
//[SerializeField]
private AmplifyShaderEditorWindow m_parentWindow = null;
[SerializeField]
private int m_validNodeId;
[SerializeField]
private List<ParentNode> m_nodes = new List<ParentNode>();
// Sampler Nodes registry
[SerializeField]
private UsageListSamplerNodes m_samplerNodes = new UsageListSamplerNodes();
[SerializeField]
private UsageListFloatIntNodes m_floatNodes = new UsageListFloatIntNodes();
[SerializeField]
private UsageListTexturePropertyNodes m_texturePropertyNodes = new UsageListTexturePropertyNodes();
[SerializeField]
private UsageListTextureArrayNodes m_textureArrayNodes = new UsageListTextureArrayNodes();
[SerializeField]
private UsageListPropertyNodes m_propertyNodes = new UsageListPropertyNodes();
[SerializeField]
private UsageListPropertyNodes m_rawPropertyNodes = new UsageListPropertyNodes();
[SerializeField]
private UsageListScreenColorNodes m_screenColorNodes = new UsageListScreenColorNodes();
[SerializeField]
private UsageListRegisterLocalVarNodes m_localVarNodes = new UsageListRegisterLocalVarNodes();
[SerializeField]
private UsageListGlobalArrayNodes m_globalArrayNodes = new UsageListGlobalArrayNodes();
[SerializeField]
private UsageListFunctionInputNodes m_functionInputNodes = new UsageListFunctionInputNodes();
[SerializeField]
private UsageListFunctionNodes m_functionNodes = new UsageListFunctionNodes();
[SerializeField]
private UsageListFunctionOutputNodes m_functionOutputNodes = new UsageListFunctionOutputNodes();
[SerializeField]
private UsageListFunctionSwitchNodes m_functionSwitchNodes = new UsageListFunctionSwitchNodes();
[SerializeField]
private UsageListFunctionSwitchCopyNodes m_functionSwitchCopyNodes = new UsageListFunctionSwitchCopyNodes();
[SerializeField]
private UsageListTemplateMultiPassMasterNodes m_multiPassMasterNodes = new UsageListTemplateMultiPassMasterNodes();
[SerializeField]
private List<UsageListTemplateMultiPassMasterNodes> m_lodMultiPassMasterNodes;
[SerializeField]
private UsageListCustomExpressionsOnFunctionMode m_customExpressionsOnFunctionMode = new UsageListCustomExpressionsOnFunctionMode();
[SerializeField]
private UsageListStaticSwitchNodes m_staticSwitchNodes = new UsageListStaticSwitchNodes();
[SerializeField]
private int m_masterNodeId = Constants.INVALID_NODE_ID;
[SerializeField]
private bool m_isDirty;
[SerializeField]
private bool m_saveIsDirty = false;
[SerializeField]
private int m_nodeClicked;
[SerializeField]
private int m_loadedShaderVersion;
[SerializeField]
private int m_instancePropertyCount = 0;
[SerializeField]
private int m_virtualTextureCount = 0;
[SerializeField]
private int m_graphId = 0;
[SerializeField]
private PrecisionType m_currentPrecision = PrecisionType.Float;
[SerializeField]
private NodeAvailability m_currentCanvasMode = NodeAvailability.SurfaceShader;
[SerializeField]
private TemplateSRPType m_currentSRPType = TemplateSRPType.BuiltIn;
//private List<ParentNode> m_visibleNodes = new List<ParentNode>();
private List<ParentNode> m_nodePreviewList = new List<ParentNode>();
private Dictionary<int, ParentNode> m_nodesDict = new Dictionary<int, ParentNode>();
[NonSerialized]
private List<ParentNode> m_selectedNodes = new List<ParentNode>();
[NonSerialized]
private List<ParentNode> m_markedForDeletion = new List<ParentNode>();
[SerializeField]
private List<WireReference> m_highlightedWires = new List<WireReference>();
private System.Type m_masterNodeDefaultType;
[SerializeField]
private List<PropertyNode> m_internalTemplateNodesList = new List<PropertyNode>();
private Dictionary<int, PropertyNode> m_internalTemplateNodesDict = new Dictionary<int, PropertyNode>();
private NodeGrid m_nodeGrid;
private bool m_markedToDeSelect = false;
private int m_markToSelect = -1;
private bool m_markToReOrder = false;
private bool m_hasUnConnectedNodes = false;
private bool m_checkSelectedWireHighlights = false;
// Bezier info
[SerializeField]
private List<WireBezierReference> m_bezierReferences;
private const int MaxBezierReferences = 50;
private int m_wireBezierCount = 0;
protected int m_normalDependentCount = 0;
private bool m_forceCategoryRefresh = false;
[SerializeField]
private bool m_forceRepositionCheck = false;
private bool m_isLoading = false;
private bool m_isDuplicating = false;
private bool m_changedLightingModel = false;
public void ResetEvents()
{
OnNodeEvent = null;
OnMaterialUpdatedEvent = null;
OnShaderUpdatedEvent = null;
OnEmptyGraphDetectedEvt = null;
OnNodeRemovedEvent = null;
}
public void Init()
{
Undo.undoRedoPerformed += OnUndoRedoCallback;
m_normalDependentCount = 0;
m_nodes = new List<ParentNode>();
m_samplerNodes = new UsageListSamplerNodes();
m_samplerNodes.ContainerGraph = this;
m_samplerNodes.ReorderOnChange = true;
m_floatNodes = new UsageListFloatIntNodes();
m_floatNodes.ContainerGraph = this;
m_texturePropertyNodes = new UsageListTexturePropertyNodes();
m_texturePropertyNodes.ContainerGraph = this;
m_textureArrayNodes = new UsageListTextureArrayNodes();
m_textureArrayNodes.ContainerGraph = this;
m_textureArrayNodes.ReorderOnChange = true;
m_propertyNodes = new UsageListPropertyNodes();
m_propertyNodes.ContainerGraph = this;
m_rawPropertyNodes = new UsageListPropertyNodes();
m_rawPropertyNodes.ContainerGraph = this;
m_customExpressionsOnFunctionMode = new UsageListCustomExpressionsOnFunctionMode();
m_customExpressionsOnFunctionMode.ContainerGraph = this;
m_staticSwitchNodes = new UsageListStaticSwitchNodes();
m_staticSwitchNodes.ContainerGraph = this;
m_staticSwitchNodes.ReorderOnChange = true;
m_screenColorNodes = new UsageListScreenColorNodes();
m_screenColorNodes.ContainerGraph = this;
m_screenColorNodes.ReorderOnChange = true;
m_localVarNodes = new UsageListRegisterLocalVarNodes();
m_localVarNodes.ContainerGraph = this;
m_localVarNodes.ReorderOnChange = true;
m_globalArrayNodes = new UsageListGlobalArrayNodes();
m_globalArrayNodes.ContainerGraph = this;
m_functionInputNodes = new UsageListFunctionInputNodes();
m_functionInputNodes.ContainerGraph = this;
m_functionNodes = new UsageListFunctionNodes();
m_functionNodes.ContainerGraph = this;
m_functionOutputNodes = new UsageListFunctionOutputNodes();
m_functionOutputNodes.ContainerGraph = this;
m_functionSwitchNodes = new UsageListFunctionSwitchNodes();
m_functionSwitchNodes.ContainerGraph = this;
m_functionSwitchCopyNodes = new UsageListFunctionSwitchCopyNodes();
m_functionSwitchCopyNodes.ContainerGraph = this;
m_multiPassMasterNodes = new UsageListTemplateMultiPassMasterNodes();
m_multiPassMasterNodes.ContainerGraph = this;
m_lodMultiPassMasterNodes = new List<UsageListTemplateMultiPassMasterNodes>( MaxLodAmount );
for( int i = 0; i < MaxLodAmount; i++ )
{
m_lodMultiPassMasterNodes.Add( new UsageListTemplateMultiPassMasterNodes() );
}
m_selectedNodes = new List<ParentNode>();
m_markedForDeletion = new List<ParentNode>();
m_highlightedWires = new List<WireReference>();
m_validNodeId = 0;
IsDirty = false;
SaveIsDirty = false;
m_masterNodeDefaultType = typeof( StandardSurfaceOutputNode );
m_bezierReferences = new List<WireBezierReference>( MaxBezierReferences );
for( int i = 0; i < MaxBezierReferences; i++ )
{
m_bezierReferences.Add( new WireBezierReference() );
}
}
public void ActivatePreviews( bool value )
{
int count = m_nodes.Count;
if( value )
{
for( int i = 0 ; i < count ; i++ )
{
m_nodes[ i ].PreviewIsDirty = true;
}
}
else
{
//for( int i = 0 ; i < count ; i++ )
//{
// m_nodes[ i ].DisablePreview();
//}
}
}
private void OnUndoRedoCallback()
{
DeSelectAll();
}
private void OnEnable()
{
hideFlags = HideFlags.HideAndDontSave;
m_nodeGrid = new NodeGrid();
m_internalTemplateNodesDict = new Dictionary<int, PropertyNode>();
m_nodesDict = new Dictionary<int, ParentNode>();
nodeStyleOff = UIUtils.GetCustomStyle( CustomStyle.NodeWindowOff );
nodeStyleOn = UIUtils.GetCustomStyle( CustomStyle.NodeWindowOn );
nodeTitle = UIUtils.GetCustomStyle( CustomStyle.NodeHeader );
commentaryBackground = UIUtils.GetCustomStyle( CustomStyle.CommentaryBackground );
}
public void UpdateRegisters()
{
m_samplerNodes.UpdateNodeArr();
m_propertyNodes.UpdateNodeArr();
m_rawPropertyNodes.UpdateNodeArr();
m_customExpressionsOnFunctionMode.UpdateNodeArr();
m_staticSwitchNodes.UpdateNodeArr();
m_functionInputNodes.UpdateNodeArr();
m_functionNodes.UpdateNodeArr();
m_functionOutputNodes.UpdateNodeArr();
m_functionSwitchNodes.UpdateNodeArr();
m_functionSwitchCopyNodes.UpdateNodeArr();
m_multiPassMasterNodes.UpdateNodeArr();
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
m_lodMultiPassMasterNodes[ i ].UpdateNodeArr();
}
m_texturePropertyNodes.UpdateNodeArr();
m_textureArrayNodes.UpdateNodeArr();
m_screenColorNodes.UpdateNodeArr();
m_localVarNodes.UpdateNodeArr();
m_globalArrayNodes.UpdateNodeArr();
}
public int GetValidId()
{
return m_validNodeId++;
}
void UpdateIdFromNode( ParentNode node )
{
if( node.UniqueId >= m_validNodeId )
{
m_validNodeId = node.UniqueId + 1;
}
}
public void ResetNodeConnStatus()
{
for( int i = 0; i < m_nodes.Count; i++ )
{
if( m_nodes[ i ].ConnStatus == NodeConnectionStatus.Connected )
{
m_nodes[ i ].ConnStatus = NodeConnectionStatus.Not_Connected;
}
}
}
public void CleanUnusedNodes()
{
List<ParentNode> unusedNodes = new List<ParentNode>();
for( int i = 0; i < m_nodes.Count; i++ )
{
if( m_nodes[ i ].ConnStatus == NodeConnectionStatus.Not_Connected )
{
unusedNodes.Add( m_nodes[ i ] );
}
}
for( int i = 0; i < unusedNodes.Count; i++ )
{
DestroyNode( unusedNodes[ i ] );
}
unusedNodes.Clear();
unusedNodes = null;
IsDirty = true;
}
// Destroy all nodes excluding Master Node
public void ClearGraph()
{
List<ParentNode> list = new List<ParentNode>();
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ].UniqueId != m_masterNodeId )
{
list.Add( m_nodes[ i ] );
}
}
while( list.Count > 0 )
{
DestroyNode( list[ 0 ] );
list.RemoveAt( 0 );
}
}
public void CleanNodes()
{
for( int i = 0; i < m_nodes.Count; i++ )
{
if( m_nodes[ i ] != null )
{
Undo.ClearUndo( m_nodes[ i ] );
m_nodes[ i ].Destroy();
GameObject.DestroyImmediate( m_nodes[ i ] );
}
}
ClearInternalTemplateNodes();
m_masterNodeId = Constants.INVALID_NODE_ID;
m_validNodeId = 0;
m_instancePropertyCount = 0;
m_virtualTextureCount = 0;
m_nodesDict.Clear();
m_nodes.Clear();
m_samplerNodes.Clear();
m_propertyNodes.Clear();
m_rawPropertyNodes.Clear();
m_customExpressionsOnFunctionMode.Clear();
m_staticSwitchNodes.Clear();
m_functionInputNodes.Clear();
m_functionNodes.Clear();
m_functionOutputNodes.Clear();
m_functionSwitchNodes.Clear();
m_functionSwitchCopyNodes.Clear();
m_multiPassMasterNodes.Clear();
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
m_lodMultiPassMasterNodes[ i ].Clear();
}
m_texturePropertyNodes.Clear();
m_textureArrayNodes.Clear();
m_screenColorNodes.Clear();
m_localVarNodes.Clear();
m_globalArrayNodes.Clear();
m_selectedNodes.Clear();
m_markedForDeletion.Clear();
}
public void ResetHighlightedWires()
{
for( int i = 0; i < m_highlightedWires.Count; i++ )
{
m_highlightedWires[ i ].WireStatus = WireStatus.Default;
}
m_highlightedWires.Clear();
}
public void HighlightWiresStartingNode( ParentNode node )
{
for( int outputIdx = 0; outputIdx < node.OutputPorts.Count; outputIdx++ )
{
for( int extIdx = 0; extIdx < node.OutputPorts[ outputIdx ].ExternalReferences.Count; extIdx++ )
{
WireReference wireRef = node.OutputPorts[ outputIdx ].ExternalReferences[ extIdx ];
ParentNode nextNode = GetNode( wireRef.NodeId );
if( nextNode && nextNode.ConnStatus == NodeConnectionStatus.Connected )
{
InputPort port = nextNode.GetInputPortByUniqueId( wireRef.PortId );
if( port.ExternalReferences.Count == 0 || port.ExternalReferences[ 0 ].WireStatus == WireStatus.Highlighted )
{
// if even one wire is already highlighted then this tells us that this node was already been analysed
return;
}
port.ExternalReferences[ 0 ].WireStatus = WireStatus.Highlighted;
m_highlightedWires.Add( port.ExternalReferences[ 0 ] );
HighlightWiresStartingNode( nextNode );
}
}
}
RegisterLocalVarNode regNode = node as RegisterLocalVarNode;
if( (object)regNode != null )
{
int count = regNode.NodeReferences.Count;
for( int i = 0; i < count; i++ )
{
HighlightWiresStartingNode( regNode.NodeReferences[ i ] );
}
}
}
void PropagateHighlightDeselection( ParentNode node, int portId = -1 )
{
if( portId > -1 )
{
InputPort port = node.GetInputPortByUniqueId( portId );
port.ExternalReferences[ 0 ].WireStatus = WireStatus.Default;
}
if( node.Selected )
return;
for( int i = 0; i < node.InputPorts.Count; i++ )
{
if( node.InputPorts[ i ].ExternalReferences.Count > 0 && node.InputPorts[ i ].ExternalReferences[ 0 ].WireStatus == WireStatus.Highlighted )
{
// even though node is deselected, it receives wire highlight from a previous one
return;
}
}
for( int outputIdx = 0; outputIdx < node.OutputPorts.Count; outputIdx++ )
{
for( int extIdx = 0; extIdx < node.OutputPorts[ outputIdx ].ExternalReferences.Count; extIdx++ )
{
WireReference wireRef = node.OutputPorts[ outputIdx ].ExternalReferences[ extIdx ];
ParentNode nextNode = GetNode( wireRef.NodeId );
PropagateHighlightDeselection( nextNode, wireRef.PortId );
}
}
RegisterLocalVarNode regNode = node as RegisterLocalVarNode;
if( (object)regNode != null )
{
int count = regNode.NodeReferences.Count;
for( int i = 0; i < count; i++ )
{
PropagateHighlightDeselection( regNode.NodeReferences[ i ], -1 );
}
}
}
public void ResetNodesData()
{
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
m_nodes[ i ].ResetNodeData();
}
}
public void FullCleanUndoStack()
{
Undo.ClearUndo( this );
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ] != null )
{
Undo.ClearUndo( m_nodes[ i ] );
}
}
}
public void FullRegisterOnUndoStack()
{
Undo.RegisterCompleteObjectUndo( this, Constants.UndoRegisterFullGrapId );
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ] != null )
{
Undo.RegisterCompleteObjectUndo( m_nodes[ i ], Constants.UndoRegisterFullGrapId );
}
}
}
public void CheckPropertiesAutoRegister( ref MasterNodeDataCollector dataCollector )
{
List<PropertyNode> propertyNodesList = m_rawPropertyNodes.NodesList;
int propertyCount = propertyNodesList.Count;
for( int i = 0; i < propertyCount; i++ )
{
propertyNodesList[ i ].CheckIfAutoRegister( ref dataCollector );
}
propertyNodesList = null;
List<GlobalArrayNode> globalArrayNodeList = m_globalArrayNodes.NodesList;
int globalArrayCount = globalArrayNodeList.Count;
for( int i = 0; i < globalArrayCount; i++ )
{
globalArrayNodeList[ i ].CheckIfAutoRegister( ref dataCollector );
}
globalArrayNodeList = null;
//List<PropertyNode> propertyNodesList = m_propertyNodes.NodesList;
//int propertyCount = propertyNodesList.Count;
//for( int i = 0; i < propertyCount; i++ )
//{
// propertyNodesList[ i ].CheckIfAutoRegister( ref dataCollector );
//}
//propertyNodesList = null;
//List<ScreenColorNode> screenColorNodes = m_screenColorNodes.NodesList;
//int screenColorNodesCount = screenColorNodes.Count;
//for( int i = 0; i < screenColorNodesCount; i++ )
//{
// screenColorNodes[ i ].CheckIfAutoRegister( ref dataCollector );
//}
//screenColorNodes = null;
}
public void SoftDestroy()
{
OnNodeRemovedEvent = null;
m_masterNodeId = Constants.INVALID_NODE_ID;
m_validNodeId = 0;
m_nodeGrid.Destroy();
//m_nodeGrid = null;
ClearInternalTemplateNodes();
for( int i = 0; i < m_nodes.Count; i++ )
{
if( m_nodes[ i ] != null )
{
m_nodes[ i ].Destroy();
GameObject.DestroyImmediate( m_nodes[ i ] );
}
}
m_instancePropertyCount = 0;
m_nodes.Clear();
//m_nodes = null;
m_nodesDict.Clear();
//m_nodesDict = null;
m_samplerNodes.Clear();
//m_samplerNodes = null;
m_propertyNodes.Clear();
m_rawPropertyNodes.Clear();
//m_propertyNodes = null;
m_customExpressionsOnFunctionMode.Clear();
m_staticSwitchNodes.Clear();
m_functionInputNodes.Clear();
//m_functionInputNodes = null;
m_functionNodes.Clear();
//m_functionNodes = null;
m_functionOutputNodes.Clear();
//m_functionOutputNodes = null;
m_functionSwitchNodes.Clear();
//m_functionSwitchNodes = null;
m_functionSwitchCopyNodes.Clear();
//m_functionSwitchCopyNodes = null;
m_texturePropertyNodes.Clear();
//m_texturePropertyNodes = null;
m_textureArrayNodes.Clear();
//m_textureArrayNodes = null;
m_screenColorNodes.Clear();
//m_screenColorNodes = null;
m_localVarNodes.Clear();
//m_localVarNodes = null;
m_globalArrayNodes.Clear();
m_selectedNodes.Clear();
//m_selectedNodes = null;
m_markedForDeletion.Clear();
//m_markedForDeletion = null;
m_nodePreviewList.Clear();
//m_nodePreviewList = null;
IsDirty = true;
OnNodeEvent = null;
OnDuplicateEvent = null;
//m_currentShaderFunction = null;
OnMaterialUpdatedEvent = null;
OnShaderUpdatedEvent = null;
OnEmptyGraphDetectedEvt = null;
nodeStyleOff = null;
nodeStyleOn = null;
nodeTitle = null;
commentaryBackground = null;
OnLODMasterNodesAddedEvent = null;
}
public void Destroy()
{
Undo.undoRedoPerformed -= OnUndoRedoCallback;
for( int i = 0; i < m_nodes.Count; i++ )
{
if( m_nodes[ i ] != null )
{
Undo.ClearUndo( m_nodes[ i ] );
m_nodes[ i ].Destroy();
GameObject.DestroyImmediate( m_nodes[ i ] );
}
}
//Must be before m_propertyNodes.Destroy();
ClearInternalTemplateNodes();
m_internalTemplateNodesDict = null;
m_internalTemplateNodesList = null;
OnNodeRemovedEvent = null;
m_masterNodeId = Constants.INVALID_NODE_ID;
m_validNodeId = 0;
m_instancePropertyCount = 0;
m_nodeGrid.Destroy();
m_nodeGrid = null;
m_nodes.Clear();
m_nodes = null;
m_samplerNodes.Destroy();
m_samplerNodes = null;
m_propertyNodes.Destroy();
m_propertyNodes = null;
m_rawPropertyNodes.Destroy();
m_rawPropertyNodes = null;
m_customExpressionsOnFunctionMode.Destroy();
m_customExpressionsOnFunctionMode = null;
m_staticSwitchNodes.Destroy();
m_staticSwitchNodes = null;
m_functionInputNodes.Destroy();
m_functionInputNodes = null;
m_functionNodes.Destroy();
m_functionNodes = null;
m_functionOutputNodes.Destroy();
m_functionOutputNodes = null;
m_functionSwitchNodes.Destroy();
m_functionSwitchNodes = null;
m_functionSwitchCopyNodes.Destroy();
m_functionSwitchCopyNodes = null;
m_multiPassMasterNodes.Destroy();
m_multiPassMasterNodes = null;
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
m_lodMultiPassMasterNodes[ i ].Destroy();
m_lodMultiPassMasterNodes[ i ] = null;
}
m_lodMultiPassMasterNodes.Clear();
m_lodMultiPassMasterNodes = null;
m_texturePropertyNodes.Destroy();
m_texturePropertyNodes = null;
m_textureArrayNodes.Destroy();
m_textureArrayNodes = null;
m_screenColorNodes.Destroy();
m_screenColorNodes = null;
m_localVarNodes.Destroy();
m_localVarNodes = null;
m_globalArrayNodes.Destroy();
m_globalArrayNodes = null;
m_selectedNodes.Clear();
m_selectedNodes = null;
m_markedForDeletion.Clear();
m_markedForDeletion = null;
m_nodesDict.Clear();
m_nodesDict = null;
m_nodePreviewList.Clear();
m_nodePreviewList = null;
IsDirty = true;
OnNodeEvent = null;
OnDuplicateEvent = null;
//m_currentShaderFunction = null;
OnMaterialUpdatedEvent = null;
OnShaderUpdatedEvent = null;
OnEmptyGraphDetectedEvt = null;
nodeStyleOff = null;
nodeStyleOn = null;
nodeTitle = null;
commentaryBackground = null;
OnLODMasterNodesAddedEvent = null;
}
void OnNodeChangeSizeEvent( ParentNode node )
{
m_nodeGrid.RemoveNodeFromGrid( node, true );
m_nodeGrid.AddNodeToGrid( node );
}
public void OnNodeFinishMoving( ParentNode node, bool testOnlySelected, InteractionMode interactionMode )
{
if( OnNodeEvent != null )
{
OnNodeEvent( node );
SaveIsDirty = true;
}
m_nodeGrid.RemoveNodeFromGrid( node, true );
m_nodeGrid.AddNodeToGrid( node );
//if( testOnlySelected )
//{
// for( int i = m_visibleNodes.Count - 1; i > -1; i-- )
// {
// if( node.UniqueId != m_visibleNodes[ i ].UniqueId )
// {
// switch( interactionMode )
// {
// case InteractionMode.Target:
// {
// node.OnNodeInteraction( m_visibleNodes[ i ] );
// }
// break;
// case InteractionMode.Other:
// {
// m_visibleNodes[ i ].OnNodeInteraction( node );
// }
// break;
// case InteractionMode.Both:
// {
// node.OnNodeInteraction( m_visibleNodes[ i ] );
// m_visibleNodes[ i ].OnNodeInteraction( node );
// }
// break;
// }
// }
// }
//}
//else
{
for( int i = m_nodes.Count - 1; i > -1; i-- )
{
if( node.UniqueId != m_nodes[ i ].UniqueId )
{
switch( interactionMode )
{
case InteractionMode.Target:
{
node.OnNodeInteraction( m_nodes[ i ] );
}
break;
case InteractionMode.Other:
{
m_nodes[ i ].OnNodeInteraction( node );
}
break;
case InteractionMode.Both:
{
node.OnNodeInteraction( m_nodes[ i ] );
m_nodes[ i ].OnNodeInteraction( node );
}
break;
}
}
}
}
}
public void OnNodeReOrderEvent( ParentNode node, int index )
{
if( node.Depth < index )
{
Debug.LogWarning( "Reorder canceled: This is a specific method for when reordering needs to be done and a its original index is higher than the new one" );
}
else
{
m_nodes.Remove( node );
m_nodes.Insert( index, node );
m_markToReOrder = true;
}
}
public void AddNode( ParentNode node, bool updateId = false, bool addLast = true, bool registerUndo = true, bool fetchMaterialValues = true )
{
if( registerUndo )
{
UIUtils.MarkUndoAction();
Undo.RegisterCompleteObjectUndo( ParentWindow, Constants.UndoCreateNodeId );
Undo.RegisterCompleteObjectUndo( this, Constants.UndoCreateNodeId );
Undo.RegisterCreatedObjectUndo( node, Constants.UndoCreateNodeId );
}
if( OnNodeEvent != null )
{
OnNodeEvent( node );
}
if( updateId )
{
node.UniqueId = GetValidId();
}
else
{
UpdateIdFromNode( node );
}
if( addLast )
{
m_nodes.Add( node );
node.Depth = m_nodes.Count;
}
else
{
m_nodes.Insert( 0, node );
node.Depth = 0;
}
if( m_nodesDict.ContainsKey( node.UniqueId ) )
{
//m_nodesDict[ node.UniqueId ] = node;
m_foundDuplicates = true;
}
else
{
m_nodesDict.Add( node.UniqueId, node );
node.SetMaterialMode( CurrentMaterial, fetchMaterialValues );
}
m_nodeGrid.AddNodeToGrid( node );
node.OnNodeChangeSizeEvent += OnNodeChangeSizeEvent;
node.OnNodeReOrderEvent += OnNodeReOrderEvent;
IsDirty = true;
}
public void CheckForDuplicates()
{
if( m_foundDuplicates )
{
Debug.LogWarning( "Found duplicates:" );
m_foundDuplicates = false;
m_nodesDict.Clear();
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodesDict.ContainsKey( m_nodes[ i ].UniqueId ) )
{
m_nodes[ i ].UniqueId = GetValidId();
m_nodesDict.Add( m_nodes[ i ].UniqueId, m_nodes[ i ] );
Debug.LogWarning( "Assigning new ID to " + m_nodes[ i ].TypeName );
}
else
{
m_nodesDict.Add( m_nodes[ i ].UniqueId, m_nodes[ i ] );
}
}
}
}
public ParentNode GetClickedNode()
{
if( m_nodeClicked < 0 )
return null;
return GetNode( m_nodeClicked );
}
public PropertyNode GetInternalTemplateNode( int nodeId )
{
if( m_internalTemplateNodesDict.Count != m_internalTemplateNodesList.Count )
{
m_internalTemplateNodesDict.Clear();
int count = m_internalTemplateNodesList.Count;
for( int i = 0; i < m_internalTemplateNodesList.Count; i++ )
{
if( m_internalTemplateNodesList[ i ] != null )
m_internalTemplateNodesDict.Add( m_internalTemplateNodesList[ i ].UniqueId, m_internalTemplateNodesList[ i ] );
}
}
if( m_internalTemplateNodesDict.ContainsKey( nodeId ) )
return m_internalTemplateNodesDict[ nodeId ];
return null;
}
public PropertyNode GetInternalTemplateNode( string propertyName )
{
return m_internalTemplateNodesList.Find( ( x ) => x.PropertyName.Equals( propertyName ) );
}
public void AddInternalTemplateNode( TemplateShaderPropertyData data )
{
PropertyNode propertyNode = null;
switch( data.PropertyDataType )
{
case WirePortDataType.FLOAT:
propertyNode = CreateInstance<RangedFloatNode>(); break;
case WirePortDataType.FLOAT4:
propertyNode = CreateInstance<Vector4Node>();
break;
case WirePortDataType.COLOR:
propertyNode = CreateInstance<ColorNode>();
break;
case WirePortDataType.INT:
propertyNode = CreateInstance<IntNode>(); break;
case WirePortDataType.SAMPLER1D:
case WirePortDataType.SAMPLER2D:
case WirePortDataType.SAMPLER3D:
case WirePortDataType.SAMPLERCUBE:
case WirePortDataType.SAMPLER2DARRAY:
propertyNode = CreateInstance<SamplerNode>();
break;
default: return;
}
propertyNode.PropertyNameFromTemplate( data );
// Create a negative unique Id to separate it from
// the regular ids on the main nodes list
// Its begins at -2 since -1 is used to detect invalid values
int uniqueId = -( m_internalTemplateNodesList.Count + 2 );
propertyNode.SetBaseUniqueId( uniqueId );
//Register into Float/Int Nodes list to be available inline
// Unique Id must be already set at this point to properly
// create array
if( data.PropertyDataType == WirePortDataType.FLOAT ||
data.PropertyDataType == WirePortDataType.INT )
m_floatNodes.AddNode( propertyNode );
m_internalTemplateNodesList.Add( propertyNode );
m_internalTemplateNodesDict.Add( uniqueId, propertyNode );
}
public void ClearInternalTemplateNodes()
{
if( m_internalTemplateNodesList != null )
{
int count = m_internalTemplateNodesList.Count;
for( int i = 0; i < count; i++ )
{
m_internalTemplateNodesList[ i ].Destroy();
GameObject.DestroyImmediate( m_internalTemplateNodesList[ i ] );
}
m_internalTemplateNodesList.Clear();
m_internalTemplateNodesDict.Clear();
}
}
public ParentNode GetNode( int nodeId )
{
if( m_nodesDict.Count != m_nodes.Count )
{
m_nodesDict.Clear();
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ] != null && !m_nodesDict.ContainsKey( m_nodes[ i ].UniqueId ) )
m_nodesDict.Add( m_nodes[ i ].UniqueId, m_nodes[ i ] );
}
}
if( m_nodesDict.ContainsKey( nodeId ) )
return m_nodesDict[ nodeId ];
return null;
}
public void ForceReOrder()
{
m_nodes.Sort( ( x, y ) => x.Depth.CompareTo( y.Depth ) );
}
public bool Draw( DrawInfo drawInfo )
{
MasterNode masterNode = GetNode( m_masterNodeId ) as MasterNode;
if( m_forceCategoryRefresh && masterNode != null )
{
masterNode.RefreshAvailableCategories();
m_forceCategoryRefresh = false;
}
SaveIsDirty = false;
if( m_afterDeserializeFlag )
{
// this is now done after logic update... templates needs it this way
//m_afterDeserializeFlag = false;
CleanCorruptedNodes();
if( m_nodes.Count == 0 )
{
//TODO: remove this temp from here
NodeAvailability cachedCanvas = CurrentCanvasMode;
ParentWindow.CreateNewGraph( "Empty" );
CurrentCanvasMode = cachedCanvas;
if( OnEmptyGraphDetectedEvt != null )
{
OnEmptyGraphDetectedEvt( this );
SaveIsDirty = false;
}
else
{
SaveIsDirty = true;
}
}
//for( int i = 0; i < m_nodes.Count; i++ )
//{
// m_nodes[ i ].SetContainerGraph( this );
//}
}
if( drawInfo.CurrentEventType == EventType.Repaint )
{
if( m_markedToDeSelect )
DeSelectAll();
if( m_markToSelect > -1 )
{
AddToSelectedNodes( GetNode( m_markToSelect ) );
m_markToSelect = -1;
}
if( m_markToReOrder )
{
m_markToReOrder = false;
int nodesCount = m_nodes.Count;
for( int i = 0; i < nodesCount; i++ )
{
m_nodes[ i ].Depth = i;
}
}
}
if( drawInfo.CurrentEventType == EventType.Repaint )
{
// Resizing Nods per LOD level
NodeLOD newLevel = NodeLOD.LOD0;
float referenceValue;
if( drawInfo.InvertedZoom > 0.5f )
{
newLevel = NodeLOD.LOD0;
referenceValue = 4;
}
else if( drawInfo.InvertedZoom > 0.25f )
{
newLevel = NodeLOD.LOD1;
referenceValue = 2;
}
else if( drawInfo.InvertedZoom > 0.15f )
{
newLevel = NodeLOD.LOD2;
referenceValue = 1;
}
else if( drawInfo.InvertedZoom > 0.1f )
{
newLevel = NodeLOD.LOD3;
referenceValue = 0;
}
else if( drawInfo.InvertedZoom > 0.07f )
{
newLevel = NodeLOD.LOD4;
referenceValue = 0;
}
else
{
newLevel = NodeLOD.LOD5;
referenceValue = 0;
}
// Just a sanity check
nodeStyleOff = UIUtils.GetCustomStyle( CustomStyle.NodeWindowOff );
nodeStyleOn = UIUtils.GetCustomStyle( CustomStyle.NodeWindowOn );//= UIUtils.GetCustomStyle( CustomStyle.NodeWindowOn );
nodeTitle = UIUtils.GetCustomStyle( CustomStyle.NodeHeader );
commentaryBackground = UIUtils.GetCustomStyle( CustomStyle.CommentaryBackground );
if( newLevel != m_lodLevel || ( UIUtils.MainSkin != null && UIUtils.MainSkin.textField.border.left != referenceValue ) )
{
m_lodLevel = newLevel;
switch( m_lodLevel )
{
default:
case NodeLOD.LOD0:
{
UIUtils.MainSkin.textField.border = UIUtils.RectOffsetFour;
nodeStyleOff.border = UIUtils.RectOffsetSix;
UIUtils.NodeWindowOffSquare.border = UIUtils.RectOffsetFour;
nodeStyleOn.border = UIUtils.RectOffsetSix;
UIUtils.NodeWindowOnSquare.border = UIUtils.RectOffsetSix;
nodeTitle.border.left = 6;
nodeTitle.border.right = 6;
nodeTitle.border.top = 6;
nodeTitle.border.bottom = 4;
UIUtils.NodeHeaderSquare.border = UIUtils.RectOffsetFour;
commentaryBackground.border = UIUtils.RectOffsetSix;
}
break;
case NodeLOD.LOD1:
{
UIUtils.MainSkin.textField.border = UIUtils.RectOffsetTwo;
nodeStyleOff.border = UIUtils.RectOffsetFive;
UIUtils.NodeWindowOffSquare.border = UIUtils.RectOffsetFive;
nodeStyleOn.border = UIUtils.RectOffsetFive;
UIUtils.NodeWindowOnSquare.border = UIUtils.RectOffsetFour;
nodeTitle.border.left = 5;
nodeTitle.border.right = 5;
nodeTitle.border.top = 5;
nodeTitle.border.bottom = 2;
UIUtils.NodeHeaderSquare.border = UIUtils.RectOffsetThree;
commentaryBackground.border = UIUtils.RectOffsetFive;
}
break;
case NodeLOD.LOD2:
{
UIUtils.MainSkin.textField.border = UIUtils.RectOffsetOne;
nodeStyleOff.border.left = 2;
nodeStyleOff.border.right = 2;
nodeStyleOff.border.top = 2;
nodeStyleOff.border.bottom = 3;
UIUtils.NodeWindowOffSquare.border = UIUtils.RectOffsetThree;
nodeStyleOn.border.left = 4;
nodeStyleOn.border.right = 4;
nodeStyleOn.border.top = 4;
nodeStyleOn.border.bottom = 3;
UIUtils.NodeWindowOnSquare.border = UIUtils.RectOffsetThree;
nodeTitle.border = UIUtils.RectOffsetTwo;
UIUtils.NodeHeaderSquare.border = UIUtils.RectOffsetTwo;
commentaryBackground.border.left = 2;
commentaryBackground.border.right = 2;
commentaryBackground.border.top = 2;
commentaryBackground.border.bottom = 3;
}
break;
case NodeLOD.LOD3:
case NodeLOD.LOD4:
case NodeLOD.LOD5:
{
UIUtils.MainSkin.textField.border = UIUtils.RectOffsetZero;
nodeStyleOff.border.left = 1;
nodeStyleOff.border.right = 1;
nodeStyleOff.border.top = 1;
nodeStyleOff.border.bottom = 2;
UIUtils.NodeWindowOffSquare.border = UIUtils.RectOffsetTwo;
nodeStyleOn.border = UIUtils.RectOffsetTwo;
UIUtils.NodeWindowOnSquare.border = UIUtils.RectOffsetTwo;
nodeTitle.border = UIUtils.RectOffsetOne;
UIUtils.NodeHeaderSquare.border = UIUtils.RectOffsetOne;
commentaryBackground.border.left = 1;
commentaryBackground.border.right = 1;
commentaryBackground.border.top = 1;
commentaryBackground.border.bottom = 2;
}
break;
}
}
}
//m_visibleNodes.Clear();
//int nullCount = 0;
m_hasUnConnectedNodes = false;
bool repaint = false;
Material currentMaterial = masterNode != null ? masterNode.CurrentMaterial : null;
EditorGUI.BeginChangeCheck();
bool repaintMaterialInspector = false;
int nodeCount = m_nodes.Count;
for( int i = 0; i < nodeCount; i++ )
{
m_nodes[ i ].OnNodeLogicUpdate( drawInfo );
}
if( m_afterDeserializeFlag || m_lateOptionsRefresh )
{
m_afterDeserializeFlag = false;
m_lateOptionsRefresh = false;
if( CurrentCanvasMode == NodeAvailability.TemplateShader )
{
RefreshLinkedMasterNodes( true );
OnRefreshLinkedPortsComplete();
//If clipboard has cached nodes then a master node replacement will take place
//We need to re-cache master nodes to ensure applied options are correctly cached
//As first cache happens before that
if( m_parentWindow.ClipboardInstance.HasCachedMasterNodes )
{
m_parentWindow.ClipboardInstance.AddMultiPassNodesToClipboard( MultiPassMasterNodes.NodesList,true,-1 );
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
if( m_lodMultiPassMasterNodes[ i ].Count > 0 )
m_parentWindow.ClipboardInstance.AddMultiPassNodesToClipboard( m_lodMultiPassMasterNodes[ i ].NodesList, false, i );
}
}
//RepositionTemplateNodes( CurrentMasterNode );
}
}
if( m_forceRepositionCheck )
{
RepositionTemplateNodes( CurrentMasterNode );
}
//for( int i = 0; i < m_functionNodes.NodesList.Count; i++ )
//{
// m_functionNodes.NodesList[ i ].LogicGraph();
//}
//for( int i = 0; i < UIUtils.FunctionSwitchCopyList().Count; i++ )
//{
// UIUtils.FunctionSwitchCopyList()[ i ].CheckReference();
//}
// Dont use nodeCount variable because node count can change in this loop???
nodeCount = m_nodes.Count;
ParentNode node = null;
for( int i = 0; i < nodeCount; i++ )
{
node = m_nodes[ i ];
if( !node.IsOnGrid )
{
m_nodeGrid.AddNodeToGrid( node );
}
node.MovingInFrame = false;
if( drawInfo.CurrentEventType == EventType.Repaint )
node.OnNodeLayout( drawInfo );
m_hasUnConnectedNodes = m_hasUnConnectedNodes ||
( node.ConnStatus != NodeConnectionStatus.Connected && node.ConnStatus != NodeConnectionStatus.Island );
if( node.RequireMaterialUpdate && currentMaterial != null )
{
node.UpdateMaterial( currentMaterial );
repaintMaterialInspector = true;
}
//if( node.IsVisible )
// m_visibleNodes.Add( node );
IsDirty = ( m_isDirty || node.IsDirty );
SaveIsDirty = ( m_saveIsDirty || node.SaveIsDirty );
}
// Handles GUI controls
nodeCount = m_nodes.Count;
for( int i = nodeCount - 1; i >= 0; i-- )
//for ( int i = 0; i < nodeCount; i++ )
{
node = m_nodes[ i ];
bool restoreMouse = false;
if( drawInfo.CurrentEventType == EventType.MouseDown && m_nodeClicked > -1 && node.UniqueId != m_nodeClicked )
{
restoreMouse = true;
drawInfo.CurrentEventType = EventType.Ignore;
}
node.DrawGUIControls( drawInfo );
if( restoreMouse )
{
drawInfo.CurrentEventType = EventType.MouseDown;
}
}
// Draw connection wires
if( drawInfo.CurrentEventType == EventType.Repaint )
DrawWires( ParentWindow.WireTexture, drawInfo, ParentWindow.WindowContextPallete.IsActive, ParentWindow.WindowContextPallete.CurrentPosition );
// Master Draw
nodeCount = m_nodes.Count;
for( int i = 0; i < nodeCount; i++ )
{
node = m_nodes[ i ];
bool restoreMouse = false;
if( drawInfo.CurrentEventType == EventType.MouseDown && m_nodeClicked > -1 && node.UniqueId != m_nodeClicked )
{
restoreMouse = true;
drawInfo.CurrentEventType = EventType.Ignore;
}
node.Draw( drawInfo );
if( restoreMouse )
{
drawInfo.CurrentEventType = EventType.MouseDown;
}
}
// Draw Tooltip
if( drawInfo.CurrentEventType == EventType.Repaint || drawInfo.CurrentEventType == EventType.MouseDown )
{
nodeCount = m_nodes.Count;
for( int i = nodeCount - 1; i >= 0; i-- )
{
node = m_nodes[ i ];
if( node.IsVisible && !node.IsMoving )
{
bool showing = node.ShowTooltip( drawInfo );
if( showing )
break;
}
}
}
if( repaintMaterialInspector )
{
if( ASEMaterialInspector.Instance != null )
{
ASEMaterialInspector.Instance.Repaint();
}
}
if( m_checkSelectedWireHighlights )
{
m_checkSelectedWireHighlights = false;
ResetHighlightedWires();
for( int i = 0; i < m_selectedNodes.Count; i++ )
{
HighlightWiresStartingNode( m_selectedNodes[ i ] );
}
}
if( EditorGUI.EndChangeCheck() )
{
SaveIsDirty = true;
repaint = true;
}
if( drawInfo.CurrentEventType == EventType.Repaint )
{
// Revert LOD changes to LOD0 (only if it's different)
if( UIUtils.MainSkin.textField.border.left != 4 )
{
UIUtils.MainSkin.textField.border = UIUtils.RectOffsetFour;
nodeStyleOff.border = UIUtils.RectOffsetSix;
UIUtils.NodeWindowOffSquare.border = UIUtils.RectOffsetFour;
nodeStyleOn.border = UIUtils.RectOffsetSix;
UIUtils.NodeWindowOnSquare.border = UIUtils.RectOffsetSix;
nodeTitle.border.left = 6;
nodeTitle.border.right = 6;
nodeTitle.border.top = 6;
nodeTitle.border.bottom = 4;
UIUtils.NodeHeaderSquare.border = UIUtils.RectOffsetFour;
commentaryBackground.border = UIUtils.RectOffsetSix;
}
}
//if ( nullCount == m_nodes.Count )
// m_nodes.Clear();
ChangedLightingModel = false;
return repaint;
}
public bool UpdateMarkForDeletion()
{
if( m_markedForDeletion.Count != 0 )
{
DeleteMarkedForDeletionNodes();
return true;
}
return false;
}
public void DrawWires( Texture2D wireTex, DrawInfo drawInfo, bool contextPaletteActive, Vector3 contextPalettePos )
{
//Handles.BeginGUI();
//Debug.Log(GUI.depth);
// Draw connected node wires
m_wireBezierCount = 0;
for( int nodeIdx = 0; nodeIdx < m_nodes.Count; nodeIdx++ )
{
ParentNode node = m_nodes[ nodeIdx ];
if( (object)node == null )
return;
for( int inputPortIdx = 0; inputPortIdx < node.InputPorts.Count; inputPortIdx++ )
{
InputPort inputPort = node.InputPorts[ inputPortIdx ];
if( inputPort.ExternalReferences.Count > 0 && inputPort.Visible )
{
bool cleanInvalidConnections = false;
for( int wireIdx = 0; wireIdx < inputPort.ExternalReferences.Count; wireIdx++ )
{
WireReference reference = inputPort.ExternalReferences[ wireIdx ];
if( reference.NodeId != -1 && reference.PortId != -1 )
{
ParentNode outputNode = GetNode( reference.NodeId );
if( outputNode != null )
{
OutputPort outputPort = outputNode.GetOutputPortByUniqueId( reference.PortId );
Vector3 endPos = new Vector3( inputPort.Position.x, inputPort.Position.y );
Vector3 startPos = new Vector3( outputPort.Position.x, outputPort.Position.y );
float x = ( startPos.x < endPos.x ) ? startPos.x : endPos.x;
float y = ( startPos.y < endPos.y ) ? startPos.y : endPos.y;
float width = Mathf.Abs( startPos.x - endPos.x ) + outputPort.Position.width;
float height = Mathf.Abs( startPos.y - endPos.y ) + outputPort.Position.height;
Rect portsBoundingBox = new Rect( x, y, width, height );
bool isVisible = node.IsVisible || outputNode.IsVisible;
if( !isVisible )
{
isVisible = drawInfo.TransformedCameraArea.Overlaps( portsBoundingBox );
}
if( isVisible )
{
Rect bezierBB = DrawBezier( drawInfo.InvertedZoom, startPos, endPos, inputPort.DataType, outputPort.DataType, node.GetInputPortVisualDataTypeByArrayIdx( inputPortIdx ), outputNode.GetOutputPortVisualDataTypeById( reference.PortId ), reference.WireStatus, wireTex, node, outputNode );
bezierBB.x -= Constants.OUTSIDE_WIRE_MARGIN;
bezierBB.y -= Constants.OUTSIDE_WIRE_MARGIN;
bezierBB.width += Constants.OUTSIDE_WIRE_MARGIN * 2;
bezierBB.height += Constants.OUTSIDE_WIRE_MARGIN * 2;
if( m_wireBezierCount < m_bezierReferences.Count )
{
m_bezierReferences[ m_wireBezierCount ].UpdateInfo( ref bezierBB, inputPort.NodeId, inputPort.PortId, outputPort.NodeId, outputPort.PortId );
}
else
{
m_bezierReferences.Add( new WireBezierReference( ref bezierBB, inputPort.NodeId, inputPort.PortId, outputPort.NodeId, outputPort.PortId ) );
}
m_wireBezierCount++;
}
}
else
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowMessage( "Detected Invalid connection from node " + node.UniqueId + " port " + inputPortIdx + " to Node " + reference.NodeId + " port " + reference.PortId, MessageSeverity.Error );
cleanInvalidConnections = true;
inputPort.ExternalReferences[ wireIdx ].Invalidate();
}
}
}
if( cleanInvalidConnections )
{
inputPort.RemoveInvalidConnections();
}
}
}
}
//Draw selected wire
if( m_parentWindow.WireReferenceUtils.ValidReferences() )
{
if( m_parentWindow.WireReferenceUtils.InputPortReference.IsValid )
{
InputPort inputPort = GetNode( m_parentWindow.WireReferenceUtils.InputPortReference.NodeId ).GetInputPortByUniqueId( m_parentWindow.WireReferenceUtils.InputPortReference.PortId );
Vector3 endPos = Vector3.zero;
if( m_parentWindow.WireReferenceUtils.SnapEnabled )
{
Vector2 pos = ( m_parentWindow.WireReferenceUtils.SnapPosition + drawInfo.CameraOffset ) * drawInfo.InvertedZoom;
endPos = new Vector3( pos.x, pos.y ) + UIUtils.ScaledPortsDelta;
}
else
{
endPos = contextPaletteActive ? contextPalettePos : new Vector3( Event.current.mousePosition.x, Event.current.mousePosition.y );
}
Vector3 startPos = new Vector3( inputPort.Position.x, inputPort.Position.y );
DrawBezier( drawInfo.InvertedZoom, endPos, startPos, inputPort.DataType, inputPort.DataType, inputPort.DataType, inputPort.DataType, WireStatus.Default, wireTex );
}
if( m_parentWindow.WireReferenceUtils.OutputPortReference.IsValid )
{
OutputPort outputPort = GetNode( m_parentWindow.WireReferenceUtils.OutputPortReference.NodeId ).GetOutputPortByUniqueId( m_parentWindow.WireReferenceUtils.OutputPortReference.PortId );
Vector3 endPos = Vector3.zero;
if( m_parentWindow.WireReferenceUtils.SnapEnabled )
{
Vector2 pos = ( m_parentWindow.WireReferenceUtils.SnapPosition + drawInfo.CameraOffset ) * drawInfo.InvertedZoom;
endPos = new Vector3( pos.x, pos.y ) + UIUtils.ScaledPortsDelta;
}
else
{
endPos = contextPaletteActive ? contextPalettePos : new Vector3( Event.current.mousePosition.x, Event.current.mousePosition.y );
}
Vector3 startPos = new Vector3( outputPort.Position.x, outputPort.Position.y );
DrawBezier( drawInfo.InvertedZoom, startPos, endPos, outputPort.DataType, outputPort.DataType, outputPort.DataType, outputPort.DataType, WireStatus.Default, wireTex );
}
}
//Handles.EndGUI();
}
Rect DrawBezier( float invertedZoom, Vector3 startPos, Vector3 endPos, WirePortDataType inputDataType, WirePortDataType outputDataType, WirePortDataType inputVisualDataType, WirePortDataType outputVisualDataType, WireStatus wireStatus, Texture2D wireTex, ParentNode inputNode = null, ParentNode outputNode = null )
{
startPos += UIUtils.ScaledPortsDelta;
endPos += UIUtils.ScaledPortsDelta;
// Calculate the 4 points for bezier taking into account wire nodes and their automatic tangents
float mag = ( endPos - startPos ).magnitude;
float resizedMag = Mathf.Min( mag * 0.66f, Constants.HORIZONTAL_TANGENT_SIZE * invertedZoom );
Vector3 startTangent = new Vector3( startPos.x + resizedMag, startPos.y );
Vector3 endTangent = new Vector3( endPos.x - resizedMag, endPos.y );
if( (object)inputNode != null && inputNode.GetType() == typeof( WireNode ) )
endTangent = endPos + ( ( inputNode as WireNode ).TangentDirection ) * mag * 0.33f;
if( (object)outputNode != null && outputNode.GetType() == typeof( WireNode ) )
startTangent = startPos - ( ( outputNode as WireNode ).TangentDirection ) * mag * 0.33f;
///////////////Draw tangents
//Rect box1 = new Rect( new Vector2( startTangent.x, startTangent.y ), new Vector2( 10, 10 ) );
//box1.x -= box1.width * 0.5f;
//box1.y -= box1.height * 0.5f;
//GUI.Label( box1, string.Empty, UIUtils.Box );
//Rect box2 = new Rect( new Vector2( endTangent.x, endTangent.y ), new Vector2( 10, 10 ) );
//box2.x -= box2.width * 0.5f;
//box2.y -= box2.height * 0.5f;
//GUI.Label( box2, string.Empty, UIUtils.Box );
//m_auxRect.Set( 0, 0, UIUtils.CurrentWindow.position.width, UIUtils.CurrentWindow.position.height );
//GLDraw.BeginGroup( m_auxRect );
int ty = 1;
float wireThickness = 0;
if( ParentWindow.Options.MultiLinePorts )
{
GLDraw.MultiLine = true;
Shader.SetGlobalFloat( "_InvertedZoom", invertedZoom );
WirePortDataType smallest = ( (int)outputDataType < (int)inputDataType ? outputDataType : inputDataType );
smallest = ( (int)smallest < (int)outputVisualDataType ? smallest : outputVisualDataType );
smallest = ( (int)smallest < (int)inputVisualDataType ? smallest : inputVisualDataType );
switch( smallest )
{
case WirePortDataType.FLOAT2: ty = 2; break;
case WirePortDataType.FLOAT3: ty = 3; break;
case WirePortDataType.FLOAT4:
case WirePortDataType.COLOR:
{
ty = 4;
}
break;
default: ty = 1; break;
}
wireThickness = Mathf.Lerp( Constants.WIRE_WIDTH * ( ty * invertedZoom * -0.05f + 0.15f ), Constants.WIRE_WIDTH * ( ty * invertedZoom * 0.175f + 0.3f ), invertedZoom + 0.4f );
}
else
{
GLDraw.MultiLine = false;
wireThickness = Mathf.Lerp( Constants.WIRE_WIDTH * ( invertedZoom * -0.05f + 0.15f ), Constants.WIRE_WIDTH * ( invertedZoom * 0.175f + 0.3f ), invertedZoom + 0.4f );
}
Rect boundBox = new Rect();
int segments = 11;
if( LodLevel <= ParentGraph.NodeLOD.LOD4 )
segments = Mathf.Clamp( Mathf.FloorToInt( mag * 0.2f * invertedZoom ), 11, 35 );
else
segments = (int)( invertedZoom * 14.28f * 11 );
if( ParentWindow.Options.ColoredPorts && wireStatus != WireStatus.Highlighted )
boundBox = GLDraw.DrawBezier( startPos, startTangent, endPos, endTangent, UIUtils.GetColorForDataType( outputVisualDataType, false, false ), UIUtils.GetColorForDataType( inputVisualDataType, false, false ), wireThickness, segments, ty );
else
boundBox = GLDraw.DrawBezier( startPos, startTangent, endPos, endTangent, UIUtils.GetColorFromWireStatus( wireStatus ), wireThickness, segments, ty );
//GLDraw.EndGroup();
//GUI.Box( m_auxRect, string.Empty, UIUtils.CurrentWindow.CustomStylesInstance.Box );
//GUI.Box( boundBox, string.Empty, UIUtils.CurrentWindow.CustomStylesInstance.Box );
//if ( UIUtils.CurrentWindow.Options.ColoredPorts && wireStatus != WireStatus.Highlighted )
// Handles.DrawBezier( startPos, endPos, startTangent, endTangent, UIUtils.GetColorForDataType( outputDataType, false, false ), wireTex, wiresTickness );
//else
// Handles.DrawBezier( startPos, endPos, startTangent, endTangent, UIUtils.GetColorFromWireStatus( wireStatus ), wireTex, wiresTickness );
//Handles.DrawLine( startPos, startTangent );
//Handles.DrawLine( endPos, endTangent );
float extraBound = 30 * invertedZoom;
boundBox.xMin -= extraBound;
boundBox.xMax += extraBound;
boundBox.yMin -= extraBound;
boundBox.yMax += extraBound;
return boundBox;
}
public void DrawBezierBoundingBox()
{
for( int i = 0; i < m_wireBezierCount; i++ )
{
m_bezierReferences[ i ].DebugDraw();
}
}
public WireBezierReference GetWireBezierInPos( Vector2 position )
{
for( int i = 0; i < m_wireBezierCount; i++ )
{
if( m_bezierReferences[ i ].Contains( position ) )
return m_bezierReferences[ i ];
}
return null;
}
public List<WireBezierReference> GetWireBezierListInPos( Vector2 position )
{
List<WireBezierReference> list = new List<WireBezierReference>();
for( int i = 0; i < m_wireBezierCount; i++ )
{
if( m_bezierReferences[ i ].Contains( position ) )
list.Add( m_bezierReferences[ i ] );
}
return list;
}
public void MoveSelectedNodes( Vector2 delta, bool snap = false )
{
//bool validMovement = delta.magnitude > 0.001f;
//if ( validMovement )
//{
// Undo.RegisterCompleteObjectUndo( ParentWindow, Constants.UndoMoveNodesId );
// for ( int i = 0; i < m_selectedNodes.Count; i++ )
// {
// if ( !m_selectedNodes[ i ].MovingInFrame )
// {
// Undo.RecordObject( m_selectedNodes[ i ], Constants.UndoMoveNodesId );
// m_selectedNodes[ i ].Move( delta, snap );
// }
// }
// IsDirty = true;
//}
bool performUndo = delta.magnitude > 0.01f;
if( performUndo )
{
Undo.RegisterCompleteObjectUndo( ParentWindow, Constants.UndoMoveNodesId );
Undo.RegisterCompleteObjectUndo( this, Constants.UndoMoveNodesId );
}
for( int i = 0; i < m_selectedNodes.Count; i++ )
{
if( !m_selectedNodes[ i ].MovingInFrame )
{
if( performUndo )
m_selectedNodes[ i ].RecordObject( Constants.UndoMoveNodesId );
m_selectedNodes[ i ].Move( delta, snap );
}
}
IsDirty = true;
}
public void SetConnection( int InNodeId, int InPortId, int OutNodeId, int OutPortId )
{
ParentNode inNode = GetNode( InNodeId );
ParentNode outNode = GetNode( OutNodeId );
InputPort inputPort = null;
OutputPort outputPort = null;
if( inNode != null && outNode != null )
{
inputPort = inNode.GetInputPortByUniqueId( InPortId );
outputPort = outNode.GetOutputPortByUniqueId( OutPortId );
if( inputPort != null && outputPort != null )
{
if( inputPort.IsConnectedTo( OutNodeId, OutPortId ) || outputPort.IsConnectedTo( InNodeId, InPortId ) )
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowMessage( "Node/Port already connected " + InNodeId, MessageSeverity.Error );
return;
}
if( !inputPort.CheckValidType( outputPort.DataType ) )
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowIncompatiblePortMessage( true, inNode, inputPort, outNode, outputPort );
return;
}
if( !outputPort.CheckValidType( inputPort.DataType ) )
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowIncompatiblePortMessage( false, outNode, outputPort, inNode, inputPort );
return;
}
if( !inputPort.Available || !outputPort.Available )
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowMessage( "Ports not available to connection", MessageSeverity.Warning );
return;
}
if( inputPort.ConnectTo( OutNodeId, OutPortId, outputPort.DataType, false ) )
{
inNode.OnInputPortConnected( InPortId, OutNodeId, OutPortId );
}
if( outputPort.ConnectTo( InNodeId, InPortId, inputPort.DataType, inputPort.TypeLocked ) )
{
outNode.OnOutputPortConnected( OutPortId, InNodeId, InPortId );
}
}
else if( (object)inputPort == null )
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowMessage( "Input Port " + InPortId + " doesn't exist on node " + InNodeId, MessageSeverity.Error );
}
else
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowMessage( "Output Port " + OutPortId + " doesn't exist on node " + OutNodeId, MessageSeverity.Error );
}
}
else if( (object)inNode == null )
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowMessage( "Input node " + InNodeId + " doesn't exist", MessageSeverity.Error );
}
else
{
if( DebugConsoleWindow.DeveloperMode )
UIUtils.ShowMessage( "Output node " + OutNodeId + " doesn't exist", MessageSeverity.Error );
}
}
public void CreateConnection( int inNodeId, int inPortId, int outNodeId, int outPortId, bool registerUndo = true )
{
ParentNode outputNode = GetNode( outNodeId );
if( outputNode != null )
{
OutputPort outputPort = outputNode.GetOutputPortByUniqueId( outPortId );
if( outputPort != null )
{
ParentNode inputNode = GetNode( inNodeId );
InputPort inputPort = inputNode.GetInputPortByUniqueId( inPortId );
if( !inputPort.CheckValidType( outputPort.DataType ) )
{
UIUtils.ShowIncompatiblePortMessage( true, inputNode, inputPort, outputNode, outputPort );
return;
}
if( !outputPort.CheckValidType( inputPort.DataType ) )
{
UIUtils.ShowIncompatiblePortMessage( false, outputNode, outputPort, inputNode, inputPort );
return;
}
inputPort.DummyAdd( outputPort.NodeId, outputPort.PortId );
outputPort.DummyAdd( inNodeId, inPortId );
if( UIUtils.DetectNodeLoopsFrom( inputNode, new Dictionary<int, int>() ) )
{
inputPort.DummyRemove();
outputPort.DummyRemove();
m_parentWindow.WireReferenceUtils.InvalidateReferences();
UIUtils.ShowMessage( "Infinite Loop detected" );
Event.current.Use();
return;
}
inputPort.DummyRemove();
outputPort.DummyRemove();
if( inputPort.IsConnected )
{
DeleteConnection( true, inNodeId, inPortId, true, false, registerUndo );
}
//link output to input
if( outputPort.ConnectTo( inNodeId, inPortId, inputPort.DataType, inputPort.TypeLocked ) )
outputNode.OnOutputPortConnected( outputPort.PortId, inNodeId, inPortId );
//link input to output
if( inputPort.ConnectTo( outputPort.NodeId, outputPort.PortId, outputPort.DataType, inputPort.TypeLocked ) )
inputNode.OnInputPortConnected( inPortId, outputNode.UniqueId, outputPort.PortId );
MarkWireHighlights();
}
SaveIsDirty = true;
//ParentWindow.ShaderIsModified = true;
}
}
public void DeleteInvalidConnections()
{
int count = m_nodes.Count;
for( int nodeIdx = 0; nodeIdx < count; nodeIdx++ )
{
{
int inputCount = m_nodes[ nodeIdx ].InputPorts.Count;
for( int inputIdx = 0; inputIdx < inputCount; inputIdx++ )
{
if( !m_nodes[ nodeIdx ].InputPorts[ inputIdx ].Visible &&
m_nodes[ nodeIdx ].InputPorts[ inputIdx ].IsConnected &&
!m_nodes[ nodeIdx ].InputPorts[ inputIdx ].IsDummy )
{
DeleteConnection( true, m_nodes[ nodeIdx ].UniqueId, m_nodes[ nodeIdx ].InputPorts[ inputIdx ].PortId, true, true );
}
}
}
{
int outputCount = m_nodes[ nodeIdx ].OutputPorts.Count;
for( int outputIdx = 0; outputIdx < outputCount; outputIdx++ )
{
if( !m_nodes[ nodeIdx ].OutputPorts[ outputIdx ].Visible && m_nodes[ nodeIdx ].OutputPorts[ outputIdx ].IsConnected )
{
DeleteConnection( false, m_nodes[ nodeIdx ].UniqueId, m_nodes[ nodeIdx ].OutputPorts[ outputIdx ].PortId, true, true );
}
}
}
}
}
public void DeleteAllConnectionFromNode( int nodeId, bool registerOnLog, bool propagateCallback, bool registerUndo )
{
ParentNode node = GetNode( nodeId );
if( (object)node == null )
return;
DeleteAllConnectionFromNode( node, registerOnLog, propagateCallback, registerUndo );
}
public void DeleteAllConnectionFromNode( ParentNode node, bool registerOnLog, bool propagateCallback, bool registerUndo )
{
for( int i = 0; i < node.InputPorts.Count; i++ )
{
if( node.InputPorts[ i ].IsConnected )
DeleteConnection( true, node.UniqueId, node.InputPorts[ i ].PortId, registerOnLog, propagateCallback, registerUndo );
}
for( int i = 0; i < node.OutputPorts.Count; i++ )
{
if( node.OutputPorts[ i ].IsConnected )
DeleteConnection( false, node.UniqueId, node.OutputPorts[ i ].PortId, registerOnLog, propagateCallback, registerUndo );
}
}
public void DeleteConnection( bool isInput, int nodeId, int portId, bool registerOnLog, bool propagateCallback, bool registerUndo = true )
{
ParentNode node = GetNode( nodeId );
if( (object)node == null )
return;
if( registerUndo )
{
UIUtils.MarkUndoAction();
Undo.RegisterCompleteObjectUndo( ParentWindow, Constants.UndoDeleteConnectionId );
Undo.RegisterCompleteObjectUndo( this, Constants.UndoDeleteConnectionId );
node.RecordObject( Constants.UndoDeleteConnectionId );
}
if( isInput )
{
InputPort inputPort = node.GetInputPortByUniqueId( portId );
if( inputPort != null && inputPort.IsConnected )
{
if( node.ConnStatus == NodeConnectionStatus.Connected )
{
node.DeactivateInputPortNode( portId, false );
//inputPort.GetOutputNode().DeactivateNode( portId, false );
m_checkSelectedWireHighlights = true;
}
for( int i = 0; i < inputPort.ExternalReferences.Count; i++ )
{
WireReference inputReference = inputPort.ExternalReferences[ i ];
ParentNode outputNode = GetNode( inputReference.NodeId );
if( registerUndo )
outputNode.RecordObject( Constants.UndoDeleteConnectionId );
outputNode.GetOutputPortByUniqueId( inputReference.PortId ).InvalidateConnection( inputPort.NodeId, inputPort.PortId );
if( propagateCallback )
outputNode.OnOutputPortDisconnected( inputReference.PortId );
}
inputPort.InvalidateAllConnections();
if( propagateCallback )
node.OnInputPortDisconnected( portId );
}
}
else
{
OutputPort outputPort = node.GetOutputPortByUniqueId( portId );
if( outputPort != null && outputPort.IsConnected )
{
if( propagateCallback )
node.OnOutputPortDisconnected( portId );
for( int i = 0; i < outputPort.ExternalReferences.Count; i++ )
{
WireReference outputReference = outputPort.ExternalReferences[ i ];
ParentNode inputNode = GetNode( outputReference.NodeId );
if( registerUndo )
inputNode.RecordObject( Constants.UndoDeleteConnectionId );
if( inputNode.ConnStatus == NodeConnectionStatus.Connected )
{
node.DeactivateNode( portId, false );
m_checkSelectedWireHighlights = true;
}
inputNode.GetInputPortByUniqueId( outputReference.PortId ).InvalidateConnection( outputPort.NodeId, outputPort.PortId );
if( propagateCallback )
{
// Removing WireNodes fires this after the rewiring ( and the OnInputPortConnected callback ) which causes incorrect behaviors
// If is connected is true then we're on that case so we don't fire the OnInputPortDisconnected
if( !inputNode.GetInputPortByUniqueId( outputReference.PortId ).IsConnected )
inputNode.OnInputPortDisconnected( outputReference.PortId );
}
}
outputPort.InvalidateAllConnections();
}
}
IsDirty = true;
SaveIsDirty = true;
}
//public void DeleteSelectedNodes()
//{
// bool invalidateMasterNode = false;
// int count = m_selectedNodes.Count;
// for( int nodeIdx = 0; nodeIdx < count; nodeIdx++ )
// {
// ParentNode node = m_selectedNodes[ nodeIdx ];
// if( node.UniqueId == m_masterNodeId )
// {
// invalidateMasterNode = true;
// }
// else
// {
// DestroyNode( node );
// }
// }
// if( invalidateMasterNode )
// {
// CurrentOutputNode.Selected = false;
// }
// //Clear all references
// m_selectedNodes.Clear();
// IsDirty = true;
//}
public void DeleteNodesOnArray( ref ParentNode[] nodeArray )
{
bool invalidateMasterNode = false;
for( int nodeIdx = 0; nodeIdx < nodeArray.Length; nodeIdx++ )
{
ParentNode node = nodeArray[ nodeIdx ];
if( node.UniqueId == m_masterNodeId )
{
FunctionOutput fout = node as FunctionOutput;
if( fout != null )
{
for( int i = 0; i < m_nodes.Count; i++ )
{
FunctionOutput secondfout = m_nodes[ i ] as FunctionOutput;
if( secondfout != null && secondfout != fout )
{
secondfout.Function = fout.Function;
AssignMasterNode( secondfout, false );
DeselectNode( fout );
DestroyNode( fout );
break;
}
}
}
invalidateMasterNode = true;
}
else
{
DeselectNode( node );
DestroyNode( node );
}
nodeArray[ nodeIdx ] = null;
}
if( invalidateMasterNode && CurrentMasterNode != null )
{
CurrentMasterNode.Selected = false;
}
//Clear all references
nodeArray = null;
IsDirty = true;
}
public void MarkWireNodeSequence( WireNode node, bool isInput )
{
if( node == null )
{
return;
}
if( m_markedForDeletion.Contains( node ) )
return;
m_markedForDeletion.Add( node );
if( isInput && node.InputPorts[ 0 ].IsConnected )
{
MarkWireNodeSequence( GetNode( node.InputPorts[ 0 ].ExternalReferences[ 0 ].NodeId ) as WireNode, isInput );
}
else if( !isInput && node.OutputPorts[ 0 ].IsConnected )
{
MarkWireNodeSequence( GetNode( node.OutputPorts[ 0 ].ExternalReferences[ 0 ].NodeId ) as WireNode, isInput );
}
}
public void UndoableDeleteSelectedNodes( List<ParentNode> nodeList )
{
if( nodeList.Count == 0 )
return;
List<ParentNode> validNode = new List<ParentNode>();
for( int i = 0; i < nodeList.Count; i++ )
{
if( nodeList[ i ] != null && nodeList[ i ].UniqueId != m_masterNodeId )
{
validNode.Add( nodeList[ i ] );
}
}
UIUtils.ClearUndoHelper();
ParentNode[] selectedNodes = new ParentNode[ validNode.Count ];
for( int i = 0; i < selectedNodes.Length; i++ )
{
if( validNode[ i ] != null )
{
selectedNodes[ i ] = validNode[ i ];
UIUtils.CheckUndoNode( selectedNodes[ i ] );
}
}
//Check nodes connected to deleted nodes to preserve connections on undo
List<ParentNode> extraNodes = new List<ParentNode>();
for( int selectedNodeIdx = 0; selectedNodeIdx < selectedNodes.Length; selectedNodeIdx++ )
{
// Check inputs
if( selectedNodes[ selectedNodeIdx ] != null )
{
int inputIdxCount = selectedNodes[ selectedNodeIdx ].InputPorts.Count;
if( inputIdxCount > 0 )
{
for( int inputIdx = 0; inputIdx < inputIdxCount; inputIdx++ )
{
if( selectedNodes[ selectedNodeIdx ].InputPorts[ inputIdx ].IsConnected )
{
int nodeIdx = selectedNodes[ selectedNodeIdx ].InputPorts[ inputIdx ].ExternalReferences[ 0 ].NodeId;
if( nodeIdx > -1 )
{
ParentNode node = GetNode( nodeIdx );
if( node != null && UIUtils.CheckUndoNode( node ) )
{
extraNodes.Add( node );
}
}
}
}
}
}
// Check outputs
if( selectedNodes[ selectedNodeIdx ] != null )
{
int outputIdxCount = selectedNodes[ selectedNodeIdx ].OutputPorts.Count;
if( outputIdxCount > 0 )
{
for( int outputIdx = 0; outputIdx < outputIdxCount; outputIdx++ )
{
int inputIdxCount = selectedNodes[ selectedNodeIdx ].OutputPorts[ outputIdx ].ExternalReferences.Count;
if( inputIdxCount > 0 )
{
for( int inputIdx = 0; inputIdx < inputIdxCount; inputIdx++ )
{
int nodeIdx = selectedNodes[ selectedNodeIdx ].OutputPorts[ outputIdx ].ExternalReferences[ inputIdx ].NodeId;
if( nodeIdx > -1 )
{
ParentNode node = GetNode( nodeIdx );
if( UIUtils.CheckUndoNode( node ) )
{
extraNodes.Add( node );
}
}
}
}
}
}
}
}
UIUtils.ClearUndoHelper();
//Record deleted nodes
UIUtils.MarkUndoAction();
Undo.RegisterCompleteObjectUndo( ParentWindow, Constants.UndoDeleteNodeId );
Undo.RegisterCompleteObjectUndo( this, Constants.UndoDeleteNodeId );
Undo.RecordObjects( selectedNodes, Constants.UndoDeleteNodeId );
Undo.RecordObjects( extraNodes.ToArray(), Constants.UndoDeleteNodeId );
//Record deleting connections
for( int i = 0; i < selectedNodes.Length; i++ )
{
CurrentOutputNode.Selected = false;
selectedNodes[ i ].Alive = false;
DeleteAllConnectionFromNode( selectedNodes[ i ], false, true, true );
}
//Delete
DeleteNodesOnArray( ref selectedNodes );
extraNodes.Clear();
extraNodes = null;
EditorUtility.SetDirty( ParentWindow );
ParentWindow.ForceRepaint();
}
public void DeleteMarkedForDeletionNodes()
{
UndoableDeleteSelectedNodes( m_markedForDeletion );
m_markedForDeletion.Clear();
IsDirty = true;
//bool invalidateMasterNode = false;
//int count = m_markedForDeletion.Count;
//for ( int nodeIdx = 0; nodeIdx < count; nodeIdx++ )
//{
// ParentNode node = m_markedForDeletion[ nodeIdx ];
// if ( node.UniqueId == m_masterNodeId )
// {
// invalidateMasterNode = true;
// }
// else
// {
// if ( node.Selected )
// {
// m_selectedNodes.Remove( node );
// node.Selected = false;
// }
// DestroyNode( node );
// }
//}
//if ( invalidateMasterNode )
//{
// CurrentMasterNode.Selected = false;
//}
////Clear all references
//m_markedForDeletion.Clear();
//IsDirty = true;
}
public void DestroyNode( int nodeId )
{
ParentNode node = GetNode( nodeId );
DestroyNode( node );
}
public void DestroyNode( ParentNode node, bool registerUndo = true, bool destroyMasterNode = false )
{
if( node == null )
{
UIUtils.ShowMessage( "Attempting to destroying a inexistant node ", MessageSeverity.Warning );
return;
}
if( node.ConnStatus == NodeConnectionStatus.Connected && !m_checkSelectedWireHighlights )
{
ResetHighlightedWires();
m_checkSelectedWireHighlights = true;
}
//TODO: check better placement of this code (reconnects wires from wire nodes)
//if ( node.GetType() == typeof( WireNode ) )
//{
// if ( node.InputPorts[ 0 ].ExternalReferences != null && node.InputPorts[ 0 ].ExternalReferences.Count > 0 )
// {
// WireReference backPort = node.InputPorts[ 0 ].ExternalReferences[ 0 ];
// for ( int i = 0; i < node.OutputPorts[ 0 ].ExternalReferences.Count; i++ )
// {
// UIUtils.CurrentWindow.ConnectInputToOutput( node.OutputPorts[ 0 ].ExternalReferences[ i ].NodeId, node.OutputPorts[ 0 ].ExternalReferences[ i ].PortId, backPort.NodeId, backPort.PortId );
// }
// }
//}
if( destroyMasterNode || ( node.UniqueId != m_masterNodeId && !( node is TemplateMultiPassMasterNode )/*!m_multiPassMasterNodes.HasNode( node.UniqueId )*/ ) )
{
m_nodeGrid.RemoveNodeFromGrid( node, false );
//Send Deactivation signal if active
if( node.ConnStatus == NodeConnectionStatus.Connected )
{
node.DeactivateNode( -1, true );
}
//Invalidate references
//Invalidate input references
for( int inputPortIdx = 0; inputPortIdx < node.InputPorts.Count; inputPortIdx++ )
{
InputPort inputPort = node.InputPorts[ inputPortIdx ];
if( inputPort.IsConnected )
{
for( int wireIdx = 0; wireIdx < inputPort.ExternalReferences.Count; wireIdx++ )
{
WireReference inputReference = inputPort.ExternalReferences[ wireIdx ];
ParentNode outputNode = GetNode( inputReference.NodeId );
outputNode.GetOutputPortByUniqueId( inputReference.PortId ).InvalidateConnection( inputPort.NodeId, inputPort.PortId );
outputNode.OnOutputPortDisconnected( inputReference.PortId );
}
inputPort.InvalidateAllConnections();
}
}
//Invalidate output reference
for( int outputPortIdx = 0; outputPortIdx < node.OutputPorts.Count; outputPortIdx++ )
{
OutputPort outputPort = node.OutputPorts[ outputPortIdx ];
if( outputPort.IsConnected )
{
for( int wireIdx = 0; wireIdx < outputPort.ExternalReferences.Count; wireIdx++ )
{
WireReference outputReference = outputPort.ExternalReferences[ wireIdx ];
ParentNode outnode = GetNode( outputReference.NodeId );
if( outnode != null )
{
outnode.GetInputPortByUniqueId( outputReference.PortId ).InvalidateConnection( outputPort.NodeId, outputPort.PortId );
outnode.OnInputPortDisconnected( outputReference.PortId );
}
}
outputPort.InvalidateAllConnections();
}
}
//Remove node from main list
//Undo.RecordObject( node, "Destroying node " + ( node.Attributes != null? node.Attributes.Name: node.GetType().ToString() ) );
if( registerUndo )
{
UIUtils.MarkUndoAction();
Undo.RegisterCompleteObjectUndo( ParentWindow, Constants.UndoDeleteNodeId );
Undo.RegisterCompleteObjectUndo( this, Constants.UndoDeleteNodeId );
node.RecordObjectOnDestroy( Constants.UndoDeleteNodeId );
}
if( OnNodeRemovedEvent != null )
OnNodeRemovedEvent( node );
m_nodes.Remove( node );
m_nodesDict.Remove( node.UniqueId );
node.Destroy();
if( registerUndo )
Undo.DestroyObjectImmediate( node );
else
DestroyImmediate( node );
IsDirty = true;
m_markToReOrder = true;
}
//else if( node.UniqueId == m_masterNodeId && node.GetType() == typeof(FunctionOutput) )
//{
// Debug.Log( "Attempting to destroy a output node" );
// DeselectNode( node );
// UIUtils.ShowMessage( "Attempting to destroy a output node" );
//}
else
{
TemplateMultiPassMasterNode templateMasterNode = node as TemplateMultiPassMasterNode;
if( templateMasterNode != null && templateMasterNode.InvalidNode )
{
DestroyNode( node, false, true );
return;
}
DeselectNode( node );
UIUtils.ShowMessage( "Attempting to destroy a master node" );
}
}
void AddToSelectedNodes( ParentNode node )
{
node.Selected = true;
m_selectedNodes.Add( node );
node.OnNodeStoppedMovingEvent += OnNodeFinishMoving;
if( node.ConnStatus == NodeConnectionStatus.Connected )
{
HighlightWiresStartingNode( node );
}
}
void RemoveFromSelectedNodes( ParentNode node )
{
node.Selected = false;
m_selectedNodes.Remove( node );
node.OnNodeStoppedMovingEvent -= OnNodeFinishMoving;
}
public void SelectNode( ParentNode node, bool append, bool reorder )
{
if( node == null )
return;
if( append )
{
if( !m_selectedNodes.Contains( node ) )
{
AddToSelectedNodes( node );
}
}
else
{
DeSelectAll();
AddToSelectedNodes( node );
}
if( reorder && !node.ReorderLocked )
{
m_nodes.Remove( node );
m_nodes.Add( node );
m_markToReOrder = true;
}
}
public void MultipleSelection( Rect selectionArea, bool appendSelection = true )
{
if( !appendSelection )
{
for( int i = 0; i < m_nodes.Count; i++ )
{
if( selectionArea.Overlaps( m_nodes[ i ].Position, true ) )
{
RemoveFromSelectedNodes( m_nodes[ i ] );
}
}
m_markedToDeSelect = false;
ResetHighlightedWires();
}
else
{
for( int i = 0; i < m_nodes.Count; i++ )
{
if( !m_nodes[ i ].Selected && selectionArea.Overlaps( m_nodes[ i ].Position, true ) )
{
AddToSelectedNodes( m_nodes[ i ] );
}
}
}
// reorder nodes and highlight them
for( int i = 0; i < m_selectedNodes.Count; i++ )
{
if( !m_selectedNodes[ i ].ReorderLocked )
{
m_nodes.Remove( m_selectedNodes[ i ] );
m_nodes.Add( m_selectedNodes[ i ] );
m_markToReOrder = true;
if( m_selectedNodes[ i ].ConnStatus == NodeConnectionStatus.Connected )
{
HighlightWiresStartingNode( m_selectedNodes[ i ] );
}
}
}
}
public void SelectAll()
{
for( int i = 0; i < m_nodes.Count; i++ )
{
if( !m_nodes[ i ].Selected )
AddToSelectedNodes( m_nodes[ i ] );
}
}
public void SelectMasterNode()
{
if( m_masterNodeId != Constants.INVALID_NODE_ID )
{
SelectNode( CurrentMasterNode, false, false );
}
}
public void SelectOutputNode()
{
if( m_masterNodeId != Constants.INVALID_NODE_ID )
{
SelectNode( CurrentOutputNode, false, false );
}
}
public void DeselectNode( int nodeId )
{
ParentNode node = GetNode( nodeId );
if( node )
{
m_selectedNodes.Remove( node );
node.Selected = false;
}
}
public void DeselectNode( ParentNode node )
{
m_selectedNodes.Remove( node );
node.Selected = false;
PropagateHighlightDeselection( node );
}
public void DeSelectAll()
{
m_markedToDeSelect = false;
for( int i = 0; i < m_selectedNodes.Count; i++ )
{
m_selectedNodes[ i ].Selected = false;
m_selectedNodes[ i ].OnNodeStoppedMovingEvent -= OnNodeFinishMoving;
}
m_selectedNodes.Clear();
ResetHighlightedWires();
}
public void AssignMasterNode()
{
if( m_selectedNodes.Count == 1 )
{
OutputNode newOutputNode = m_selectedNodes[ 0 ] as OutputNode;
MasterNode newMasterNode = newOutputNode as MasterNode;
if( newOutputNode != null )
{
if( m_masterNodeId != Constants.INVALID_NODE_ID && m_masterNodeId != newOutputNode.UniqueId )
{
OutputNode oldOutputNode = GetNode( m_masterNodeId ) as OutputNode;
MasterNode oldMasterNode = oldOutputNode as MasterNode;
if( oldOutputNode != null )
{
oldOutputNode.IsMainOutputNode = false;
if( oldMasterNode != null )
{
oldMasterNode.ClearUpdateEvents();
}
}
}
m_masterNodeId = newOutputNode.UniqueId;
newOutputNode.IsMainOutputNode = true;
if( newMasterNode != null )
{
newMasterNode.OnMaterialUpdatedEvent += OnMaterialUpdatedEvent;
newMasterNode.OnShaderUpdatedEvent += OnShaderUpdatedEvent;
}
}
}
IsDirty = true;
}
public void AssignMasterNode( OutputNode node, bool onlyUpdateGraphId )
{
AssignMasterNode( node.UniqueId, onlyUpdateGraphId );
MasterNode masterNode = node as MasterNode;
if( masterNode != null )
{
masterNode.OnMaterialUpdatedEvent += OnMaterialUpdatedEvent;
masterNode.OnShaderUpdatedEvent += OnShaderUpdatedEvent;
}
}
public void AssignMasterNode( int nodeId, bool onlyUpdateGraphId )
{
if( nodeId < 0 || m_masterNodeId == nodeId )
return;
if( m_masterNodeId > Constants.INVALID_NODE_ID )
{
OutputNode oldOutputNode = ( GetNode( nodeId ) as OutputNode );
MasterNode oldMasterNode = oldOutputNode as MasterNode;
if( oldOutputNode != null )
{
oldOutputNode.IsMainOutputNode = false;
if( oldMasterNode != null )
{
oldMasterNode.ClearUpdateEvents();
}
}
}
if( onlyUpdateGraphId )
{
m_masterNodeId = nodeId;
}
else
{
OutputNode outputNode = ( GetNode( nodeId ) as OutputNode );
if( outputNode != null )
{
outputNode.IsMainOutputNode = true;
m_masterNodeId = nodeId;
}
}
IsDirty = true;
}
public void RefreshOnUndo()
{
if( m_nodes != null )
{
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ] != null )
{
m_nodes[ i ].RefreshOnUndo();
}
}
}
}
public void DrawGrid( DrawInfo drawInfo )
{
m_nodeGrid.DrawGrid( drawInfo );
}
public float MaxNodeDist
{
get { return m_nodeGrid.MaxNodeDist; }
}
public List<ParentNode> GetNodesInGrid( Vector2 transformedMousePos )
{
return m_nodeGrid.GetNodesOn( transformedMousePos );
}
public void FireMasterNode( Shader selectedShader )
{
( GetNode( m_masterNodeId ) as MasterNode ).Execute( selectedShader );
}
public Shader FireMasterNode( string pathname, bool isFullPath )
{
return ( GetNode( m_masterNodeId ) as MasterNode ).Execute( pathname, isFullPath );
}
private void ForceSignalPropagationOnMasterNodeInternal( UsageListTemplateMultiPassMasterNodes masterNodes )
{
int mpCount = masterNodes.Count;
for( int i = 0; i < mpCount; i++ )
{
masterNodes.NodesList[ i ].GenerateSignalPropagation();
}
}
public void ForceSignalPropagationOnMasterNode()
{
if( m_multiPassMasterNodes.Count > 0 )
{
ForceSignalPropagationOnMasterNodeInternal( m_multiPassMasterNodes );
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
ForceSignalPropagationOnMasterNodeInternal( m_lodMultiPassMasterNodes[ i ] );
}
}
else if( CurrentOutputNode != null )
CurrentOutputNode.GenerateSignalPropagation();
List<FunctionOutput> allOutputs = m_functionOutputNodes.NodesList;
for( int i = 0; i < allOutputs.Count; i++ )
{
allOutputs[ i ].GenerateSignalPropagation();
}
//List<RegisterLocalVarNode> localVarNodes = m_localVarNodes.NodesList;
//int count = localVarNodes.Count;
//for( int i = 0; i < count; i++ )
//{
// localVarNodes[ i ].GenerateSignalPropagation();
//}
}
public void UpdateShaderOnMasterNode( Shader newShader )
{
MasterNode mainMasterNode = ( GetNode( m_masterNodeId ) as MasterNode );
if( mainMasterNode == null )
{
Debug.LogError( "No Master Node was detected. Aborting update!" );
return;
}
mainMasterNode.UpdateFromShader( newShader );
if( HasLODs )
{
int passIdx = ( (TemplateMultiPassMasterNode)mainMasterNode ).PassIdx;
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
if( m_lodMultiPassMasterNodes.Count != 0 && m_lodMultiPassMasterNodes[ i ].NodesList.Count > 0 )
{
if( m_lodMultiPassMasterNodes[ i ].NodesList[ passIdx ] != null )
{
m_lodMultiPassMasterNodes[ i ].NodesList[ passIdx ].UpdateFromShader( newShader );
}
else
{
Debug.LogError( "Null master node detected. Aborting update!" );
return;
}
}
else break;
}
}
}
public void CopyValuesFromMaterial( Material material )
{
Material currMaterial = CurrentMaterial;
if( currMaterial == material )
{
for( int i = 0; i < m_nodes.Count; i++ )
{
m_nodes[ i ].ForceUpdateFromMaterial( material );
}
}
}
public void UpdateMaterialOnMasterNode( Material material )
{
MasterNode mainMasterNode = ( GetNode( m_masterNodeId ) as MasterNode );
mainMasterNode.UpdateMasterNodeMaterial( material );
if( HasLODs )
{
int passIdx = ( (TemplateMultiPassMasterNode)mainMasterNode ).PassIdx;
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
if( m_lodMultiPassMasterNodes.Count != 0 && m_lodMultiPassMasterNodes[ i ].NodesList.Count > 0 )
{
m_lodMultiPassMasterNodes[ i ].NodesList[ passIdx ].UpdateMasterNodeMaterial( material );
}
else break;
}
}
}
public void UpdateMaterialOnPropertyNodes( Material material )
{
int propertyCount = m_propertyNodes.Count;
for(int i = 0;i< propertyCount;i++ )
{
m_propertyNodes.NodesList[i].UpdateMaterial( material );
}
}
public void SetMaterialModeOnGraph( Material mat, bool fetchMaterialValues = true )
{
for( int i = 0; i < m_nodes.Count; i++ )
{
m_nodes[ i ].SetMaterialMode( mat, fetchMaterialValues );
}
}
public ParentNode CheckNodeAt( Vector3 pos, bool checkForRMBIgnore = false )
{
ParentNode selectedNode = null;
// this is checked on the inverse order to give priority to nodes that are drawn on top ( last on the list )
for( int i = m_nodes.Count - 1; i > -1; i-- )
{
if( m_nodes[ i ].Contains( pos ) )
{
if( checkForRMBIgnore )
{
if( !m_nodes[ i ].RMBIgnore )
{
selectedNode = m_nodes[ i ];
break;
}
}
else
{
selectedNode = m_nodes[ i ];
break;
}
}
}
return selectedNode;
}
public void ResetNodesLocalVariables()
{
for( int i = 0; i < m_nodes.Count; i++ )
{
m_nodes[ i ].Reset();
m_nodes[ i ].ResetOutputLocals();
FunctionNode fnode = m_nodes[ i ] as FunctionNode;
if( fnode != null )
{
if( fnode.Function != null )
fnode.FunctionGraph.ResetNodesLocalVariables();
}
}
}
public void ResetNodesLocalVariablesIfNot( MasterNodePortCategory category )
{
for( int i = 0; i < m_nodes.Count; i++ )
{
m_nodes[ i ].Reset();
m_nodes[ i ].ResetOutputLocalsIfNot( category );
FunctionNode fnode = m_nodes[ i ] as FunctionNode;
if( fnode != null )
{
if( fnode.Function != null )
fnode.FunctionGraph.ResetNodesLocalVariablesIfNot( category );
}
}
}
public void ResetNodesLocalVariables( ParentNode node )
{
if( node is GetLocalVarNode )
{
GetLocalVarNode localVarNode = node as GetLocalVarNode;
if( localVarNode.CurrentSelected != null )
{
node = localVarNode.CurrentSelected;
}
}
node.Reset();
node.ResetOutputLocals();
int count = node.InputPorts.Count;
for( int i = 0; i < count; i++ )
{
if( node.InputPorts[ i ].IsConnected )
{
ResetNodesLocalVariables( m_nodesDict[ node.InputPorts[ i ].GetConnection().NodeId ] );
}
}
}
public void ResetNodesLocalVariablesIfNot( ParentNode node, MasterNodePortCategory category )
{
if( node is GetLocalVarNode )
{
GetLocalVarNode localVarNode = node as GetLocalVarNode;
if( localVarNode.CurrentSelected != null )
{
node = localVarNode.CurrentSelected;
}
}
node.Reset();
node.ResetOutputLocalsIfNot( category );
int count = node.InputPorts.Count;
for( int i = 0; i < count; i++ )
{
if( node.InputPorts[ i ].IsConnected )
{
ResetNodesLocalVariablesIfNot( m_nodesDict[ node.InputPorts[ i ].GetConnection().NodeId ], category );
}
}
}
public override string ToString()
{
string dump = ( "Parent Graph \n" );
for( int i = 0; i < m_nodes.Count; i++ )
{
dump += ( m_nodes[ i ] + "\n" );
}
return dump;
}
public void OrderNodesByGraphDepth()
{
if( CurrentMasterNode != null )
{
//CurrentMasterNode.SetupNodeCategories();
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ].ConnStatus == NodeConnectionStatus.Island )
{
m_nodes[ i ].CalculateCustomGraphDepth();
}
}
}
else
{
//TODO: remove this dynamic list
List<OutputNode> allOutputs = new List<OutputNode>();
for( int i = 0; i < AllNodes.Count; i++ )
{
OutputNode temp = AllNodes[ i ] as OutputNode;
if( temp != null )
allOutputs.Add( temp );
}
for( int j = 0; j < allOutputs.Count; j++ )
{
allOutputs[ j ].SetupNodeCategories();
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ].ConnStatus == NodeConnectionStatus.Island )
{
m_nodes[ i ].CalculateCustomGraphDepth();
}
}
}
}
m_nodes.Sort( ( x, y ) => { return y.GraphDepth.CompareTo( x.GraphDepth ); } );
}
public void WriteToString( ref string nodesInfo, ref string connectionsInfo )
{
for( int i = 0; i < m_nodes.Count; i++ )
{
m_nodes[ i ].FullWriteToString( ref nodesInfo, ref connectionsInfo );
IOUtils.AddLineTerminator( ref nodesInfo );
}
}
public void Reset()
{
SaveIsDirty = false;
IsDirty = false;
}
public void OnBeforeSerialize()
{
//DeSelectAll();
}
public void OnAfterDeserialize()
{
m_afterDeserializeFlag = true;
}
public void CleanCorruptedNodes()
{
for( int i = 0; i < m_nodes.Count; i++ )
{
if( (object)m_nodes[ i ] == null )
{
m_nodes.RemoveAt( i );
CleanCorruptedNodes();
}
}
}
public void OnDuplicateEventWrapper()
{
if( OnDuplicateEvent != null )
{
AmplifyShaderEditorWindow temp = UIUtils.CurrentWindow;
UIUtils.CurrentWindow = ParentWindow;
OnDuplicateEvent();
UIUtils.CurrentWindow = temp;
}
}
public ParentNode CreateNode( AmplifyShaderFunction shaderFunction, bool registerUndo, int nodeId = -1, bool addLast = true )
{
FunctionNode newNode = ScriptableObject.CreateInstance<FunctionNode>();
if( newNode )
{
newNode.ContainerGraph = this;
newNode.CommonInit( shaderFunction, nodeId );
newNode.UniqueId = nodeId;
AddNode( newNode, nodeId < 0, addLast, registerUndo );
}
return newNode;
}
public ParentNode CreateNode( AmplifyShaderFunction shaderFunction, bool registerUndo, Vector2 pos, int nodeId = -1, bool addLast = true )
{
ParentNode newNode = CreateNode( shaderFunction, registerUndo, nodeId, addLast );
if( newNode )
{
newNode.Vec2Position = pos;
}
return newNode;
}
public TemplateMultiPassMasterNode CreateMultipassMasterNode( int lodId, bool registerUndo, int nodeId = -1, bool addLast = true )
{
TemplateMultiPassMasterNode newNode = ScriptableObject.CreateInstance<TemplateMultiPassMasterNode>();
if( newNode )
{
newNode.LODIndex = lodId;
newNode.ContainerGraph = this;
if( newNode.IsStubNode )
{
TemplateMultiPassMasterNode stubNode = newNode.ExecuteStubCode() as TemplateMultiPassMasterNode;
ScriptableObject.DestroyImmediate( newNode, true );
newNode = stubNode;
}
else
{
newNode.UniqueId = nodeId;
AddNode( newNode, nodeId < 0, addLast, registerUndo );
}
}
return newNode;
}
public ParentNode CreateNode( System.Type type, bool registerUndo, int nodeId = -1, bool addLast = true )
{
ParentNode newNode = ScriptableObject.CreateInstance( type ) as ParentNode;
if( newNode )
{
newNode.ContainerGraph = this;
if( newNode.IsStubNode )
{
ParentNode stubNode = newNode.ExecuteStubCode();
ScriptableObject.DestroyImmediate( newNode, true );
newNode = stubNode;
}
else
{
newNode.UniqueId = nodeId;
AddNode( newNode, nodeId < 0, addLast, registerUndo );
}
}
return newNode;
}
public ParentNode CreateNode( System.Type type, bool registerUndo, Vector2 pos, int nodeId = -1, bool addLast = true )
{
ParentNode newNode = CreateNode( type, registerUndo, nodeId, addLast );
if( newNode )
{
newNode.Vec2Position = pos;
}
return newNode;
}
public void FireMasterNodeReplacedEvent()
{
MasterNode masterNode = CurrentMasterNode;
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ].UniqueId != m_masterNodeId )
{
m_nodes[ i ].OnMasterNodeReplaced( masterNode );
}
}
}
//Used over shader functions to propagate signal into their graphs
public void FireMasterNodeReplacedEvent( MasterNode masterNode )
{
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
if( m_nodes[ i ].UniqueId != masterNode.UniqueId )
{
m_nodes[ i ].OnMasterNodeReplaced( masterNode );
}
}
}
public void CrossCheckTemplateNodes( TemplateDataParent templateData , List<TemplateMultiPassMasterNode> mpNodesList , int lodId )
{
/*Paulo*/
DeSelectAll();
TemplateMultiPassMasterNode newMasterNode = null;
Dictionary<string, TemplateReplaceHelper> nodesDict = new Dictionary<string, TemplateReplaceHelper>();
int mpNodeCount = mpNodesList.Count;
for( int i = 0; i < mpNodeCount; i++ )
{
string masterNodeId = mpNodesList[ i ].InvalidNode ? mpNodesList[ i ].OriginalPassName + "ASEInvalidMasterNode" + i : mpNodesList[ i ].OriginalPassName;
nodesDict.Add( masterNodeId, new TemplateReplaceHelper( mpNodesList[ i ] ) );
}
TemplateMultiPassMasterNode currMasterNode = GetNode( m_masterNodeId ) as TemplateMultiPassMasterNode;
TemplateMultiPass multipassData = templateData as TemplateMultiPass;
m_currentSRPType = multipassData.SubShaders[ 0 ].Modules.SRPType;
bool sortTemplatesNodes = false;
Vector2 currentPosition = currMasterNode.Vec2Position;
for( int subShaderIdx = 0; subShaderIdx < multipassData.SubShaders.Count; subShaderIdx++ )
{
for( int passIdx = 0; passIdx < multipassData.SubShaders[ subShaderIdx ].Passes.Count; passIdx++ )
{
string currPassName = multipassData.SubShaders[ subShaderIdx ].Passes[ passIdx ].PassNameContainer.Data;
if( nodesDict.ContainsKey( currPassName ) )
{
bool wasMainNode = nodesDict[ currPassName ].MasterNode.IsMainOutputNode;
currentPosition.y += nodesDict[ currPassName ].MasterNode.Position.height + 10;
nodesDict[ currPassName ].Used = true;
nodesDict[ currPassName ].MasterNode.SetTemplate( multipassData, false, false, subShaderIdx, passIdx, SetTemplateSource.NewShader );
if( wasMainNode && !nodesDict[ currPassName ].MasterNode.IsMainOutputNode )
{
nodesDict[ currPassName ].MasterNode.ReleaseResources();
}
else if( !wasMainNode && nodesDict[ currPassName ].MasterNode.IsMainOutputNode )
{
newMasterNode = nodesDict[ currPassName ].MasterNode;
}
}
else
{
sortTemplatesNodes = true;
TemplateMultiPassMasterNode masterNode = CreateMultipassMasterNode( lodId, false );
if( multipassData.SubShaders[ subShaderIdx ].Passes[ passIdx ].IsMainPass )
{
newMasterNode = masterNode;
currMasterNode.ReleaseResources();
}
masterNode.Vec2Position = currentPosition;
masterNode.SetTemplate( multipassData, true, true, subShaderIdx, passIdx, SetTemplateSource.NewShader );
//currentPosition.y += masterNode.HeightEstimate + 10;
}
}
}
foreach( KeyValuePair<string, TemplateReplaceHelper> kvp in nodesDict )
{
if( !kvp.Value.Used )
DestroyNode( kvp.Value.MasterNode, false, true );
}
nodesDict.Clear();
if( newMasterNode != null )
{
if( lodId == -1 )
{
m_masterNodeId = newMasterNode.UniqueId;
}
newMasterNode.OnMaterialUpdatedEvent += OnMaterialUpdatedEvent;
newMasterNode.OnShaderUpdatedEvent += OnShaderUpdatedEvent;
newMasterNode.IsMainOutputNode = true;
}
if( sortTemplatesNodes )
{
mpNodesList.Sort( ( x, y ) => ( x.PassIdx.CompareTo( y.PassIdx ) ) );
}
}
public void OnRefreshLinkedPortsComplete()
{
OnRefreshLinkedPortsCompleteInternal( m_multiPassMasterNodes );
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
OnRefreshLinkedPortsCompleteInternal( m_lodMultiPassMasterNodes[ i ] );
}
}
private void OnRefreshLinkedPortsCompleteInternal( UsageListTemplateMultiPassMasterNodes masterNodes )
{
int mpCount = masterNodes.Count;
for( int i = 0; i < mpCount; i++ )
{
masterNodes.NodesList[ i ].OnRefreshLinkedPortsComplete();
}
}
public void RefreshLinkedMasterNodes( bool optionsUpdate = false )
{
if( DebugConsoleWindow.DeveloperMode )
Debug.Log( "Refresh linked master nodes" );
RefreshLinkedMasterNodesInternal( m_multiPassMasterNodes, optionsUpdate );
for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
{
RefreshLinkedMasterNodesInternal( m_lodMultiPassMasterNodes[i], optionsUpdate );
}
}
private void RefreshLinkedMasterNodesInternal( UsageListTemplateMultiPassMasterNodes masterNodes, bool optionsUpdate )
{
int mpCount = masterNodes.Count;
if( mpCount > 1 )
{
Dictionary<string, List<InputPort>> registeredLinks = new Dictionary<string, List<InputPort>>();
for( int i = 0; i < mpCount; i++ )
{
CheckLinkedPorts( ref registeredLinks, masterNodes.NodesList[ mpCount - 1 - i ] );
}
foreach( KeyValuePair<string, List<InputPort>> kvp in registeredLinks )
{
int linkCount = kvp.Value.Count;
if( linkCount == 1 )
{
kvp.Value[ 0 ].Visible = true;
}
else
{
kvp.Value[ 0 ].Visible = true;
for( int i = 1; i < linkCount; i++ )
{
kvp.Value[ i ].SetExternalLink( kvp.Value[ 0 ].NodeId, kvp.Value[ 0 ].PortId );
kvp.Value[ i ].Visible = false;
}
}
kvp.Value.Clear();
}
registeredLinks.Clear();
registeredLinks = null;
}
masterNodes.NodesList.Sort( ( x, y ) => ( x.SubShaderIdx * 1000 + x.PassIdx ).CompareTo( y.SubShaderIdx * 1000 + y.PassIdx ) );
masterNodes.UpdateNodeArr();
m_parentWindow.TemplatesManagerInstance.ResetOptionsSetupData();
for( int i = 0; i < mpCount; i++ )
{
int visiblePorts = 0;
for( int j = 0; j < masterNodes.NodesList[ i ].InputPorts.Count; j++ )
{
if( masterNodes.NodesList[ i ].InputPorts[ j ].Visible )
{
visiblePorts++;
}
}
if( masterNodes.NodesList[ i ].VisiblePorts != visiblePorts )
{
masterNodes.NodesList[ i ].VisiblePorts = visiblePorts;
ForceRepositionCheck = true;
}
masterNodes.NodesList[ i ].Docking = visiblePorts <= 0;
if( optionsUpdate )
{
masterNodes.NodesList[ i ].ForceOptionsRefresh();
}
}
}
void CheckLinkedPorts( ref Dictionary<string, List<InputPort>> registeredLinks, TemplateMultiPassMasterNode masterNode )
{
if( masterNode.HasLinkPorts )
{
int inputCount = masterNode.InputPorts.Count;
for( int i = 0; i < inputCount; i++ )
{
if( !string.IsNullOrEmpty( masterNode.InputPorts[ i ].ExternalLinkId ) )
{
string linkId = masterNode.InputPorts[ i ].ExternalLinkId;
if( !registeredLinks.ContainsKey( masterNode.InputPorts[ i ].ExternalLinkId ) )
{
registeredLinks.Add( linkId, new List<InputPort>() );
}
if( masterNode.IsMainOutputNode )
{
registeredLinks[ linkId ].Insert( 0, masterNode.InputPorts[ i ] );
}
else
{
registeredLinks[ linkId ].Add( masterNode.InputPorts[ i ] );
}
}
else
{
masterNode.InputPorts[ i ].Visible = true;
}
}
}
else
{
int inputCount = masterNode.InputPorts.Count;
for( int i = 0; i < inputCount; i++ )
{
masterNode.InputPorts[ i ].Visible = true;
}
}
}
public MasterNode ReplaceMasterNode( AvailableShaderTypes newType, bool writeDefaultData = false, TemplateDataParent templateData = null )
{
DeSelectAll();
ResetNodeConnStatus();
MasterNode newMasterNode = null;
List<TemplateMultiPassMasterNode> nodesToDelete = null;
int mpNodeCount = m_multiPassMasterNodes.NodesList.Count;
if( mpNodeCount > 0 )
{
nodesToDelete = new List<TemplateMultiPassMasterNode>();
for( int i = 0; i < mpNodeCount; i++ )
{
if( m_multiPassMasterNodes.NodesList[ i ].UniqueId != m_masterNodeId )
{
nodesToDelete.Add( m_multiPassMasterNodes.NodesList[ i ] );
}
}
for( int lod = 0; lod < m_lodMultiPassMasterNodes.Count; lod++ )
{
int lodNodeCount = m_lodMultiPassMasterNodes[ lod ].Count;
for( int i = 0; i < lodNodeCount; i++ )
{
nodesToDelete.Add( m_lodMultiPassMasterNodes[ lod ].NodesList[ i ] );
}
}
}
MasterNode currMasterNode = GetNode( m_masterNodeId ) as MasterNode;
if( currMasterNode != null )
{
currMasterNode.ReleaseResources();
}
bool refreshLinkedMasterNodes = false;
switch( newType )
{
default:
case AvailableShaderTypes.SurfaceShader:
{
CurrentCanvasMode = NodeAvailability.SurfaceShader;
m_currentSRPType = TemplateSRPType.BuiltIn;
newMasterNode = CreateNode( typeof( StandardSurfaceOutputNode ), false ) as MasterNode;
}
break;
case AvailableShaderTypes.Template:
{
CurrentCanvasMode = NodeAvailability.TemplateShader;
if( templateData.TemplateType == TemplateDataType.LegacySinglePass )
{
newMasterNode = CreateNode( typeof( TemplateMasterNode ), false ) as MasterNode;
( newMasterNode as TemplateMasterNode ).SetTemplate( templateData as TemplateData, writeDefaultData, false );
m_currentSRPType = TemplateSRPType.BuiltIn;
}
else
{
/*Paulo*/
TemplateMultiPass multipassData = templateData as TemplateMultiPass;
m_currentSRPType = multipassData.SubShaders[ 0 ].Modules.SRPType;
Vector2 currentPosition = currMasterNode.Vec2Position;
for( int subShaderIdx = 0; subShaderIdx < multipassData.SubShaders.Count; subShaderIdx++ )
{
for( int passIdx = 0; passIdx < multipassData.SubShaders[ subShaderIdx ].Passes.Count; passIdx++ )
{
TemplateMultiPassMasterNode masterNode = CreateNode( typeof( TemplateMultiPassMasterNode ), false ) as TemplateMultiPassMasterNode;
if( multipassData.SubShaders[ subShaderIdx ].Passes[ passIdx ].IsMainPass )
{
newMasterNode = masterNode;
ParentWindow.IsShaderFunctionWindow = false;
CurrentCanvasMode = NodeAvailability.TemplateShader;
}
masterNode.Vec2Position = currentPosition;
masterNode.SetTemplate( multipassData, true, true, subShaderIdx, passIdx, SetTemplateSource.NewShader );
//currentPosition.y += masterNode.HeightEstimate + 10;
}
}
refreshLinkedMasterNodes = true;
//RefreshLinkedMasterNodes();
}
}
break;
}
if( currMasterNode != null )
{
newMasterNode.CopyFrom( currMasterNode );
m_masterNodeId = -1;
DestroyNode( currMasterNode, false, true );
}
if( nodesToDelete != null )
{
for( int i = 0; i < nodesToDelete.Count; i++ )
{
DestroyNode( nodesToDelete[ i ], false, true );
}
nodesToDelete.Clear();
}
m_masterNodeId = newMasterNode.UniqueId;
if( refreshLinkedMasterNodes )
RefreshLinkedMasterNodes( true );
newMasterNode.OnMaterialUpdatedEvent += OnMaterialUpdatedEvent;
newMasterNode.OnShaderUpdatedEvent += OnShaderUpdatedEvent;
newMasterNode.IsMainOutputNode = true;
OnRefreshLinkedPortsComplete();
FullCleanUndoStack();
return newMasterNode;
}
private void RepositionTemplateNodes( MasterNode newMasterNode )
{
m_forceRepositionCheck = false;
int dockedElementsBefore = 0;
int dockedElementsAfter = 0;
int masterIndex = 0;
bool foundMaster = false;
for( int i = 0; i < MultiPassMasterNodes.Count; i++ )
{
if( MultiPassMasterNodes.NodesList[ i ].UniqueId == m_masterNodeId )
{
foundMaster = true;
masterIndex = i;
}
if( !MultiPassMasterNodes.NodesList[ i ].IsInvisible && MultiPassMasterNodes.NodesList[ i ].Docking )
{
if( foundMaster )
dockedElementsAfter++;
else
dockedElementsBefore++;
}
}
if( dockedElementsBefore > 0 )
{
newMasterNode.UseSquareNodeTitle = true;
}
for( int i = masterIndex - 1; i >= 0; i-- )
{
float forwardTracking = 0;
for( int j = i + 1; j <= masterIndex; j++ )
{
if( !MultiPassMasterNodes.NodesList[ i ].IsInvisible && !MultiPassMasterNodes.NodesList[ j ].Docking )
{
forwardTracking += MultiPassMasterNodes.NodesList[ j ].HeightEstimate + 10;
}
}
MasterNode node = MultiPassMasterNodes.NodesList[ i ];
node.Vec2Position = new Vector2( node.Vec2Position.x, newMasterNode.Position.y - forwardTracking - 33 * ( dockedElementsBefore ) );
}
for( int i = masterIndex + 1; i < MultiPassMasterNodes.Count; i++ )
{
if( MultiPassMasterNodes.NodesList[ i ].UniqueId == newMasterNode.UniqueId || MultiPassMasterNodes.NodesList[ i ].Docking )
continue;
float backTracking = 0;
for( int j = i - 1; j >= masterIndex; j-- )
{
if( !MultiPassMasterNodes.NodesList[ i ].IsInvisible && !MultiPassMasterNodes.NodesList[ j ].Docking )
{
backTracking += MultiPassMasterNodes.NodesList[ j ].HeightEstimate + 10;
}
}
MasterNode node = MultiPassMasterNodes.NodesList[ i ];
node.Vec2Position = new Vector2( node.Vec2Position.x, newMasterNode.Position.y + backTracking + 33 * ( dockedElementsAfter ) );
}
}
public void CreateNewEmpty( string name )
{
CleanNodes();
if( m_masterNodeDefaultType == null )
m_masterNodeDefaultType = typeof( StandardSurfaceOutputNode );
MasterNode newMasterNode = CreateNode( m_masterNodeDefaultType, false ) as MasterNode;
newMasterNode.SetName( name );
m_masterNodeId = newMasterNode.UniqueId;
ParentWindow.IsShaderFunctionWindow = false;
CurrentCanvasMode = NodeAvailability.SurfaceShader;
newMasterNode.OnMaterialUpdatedEvent += OnMaterialUpdatedEvent;
newMasterNode.OnShaderUpdatedEvent += OnShaderUpdatedEvent;
newMasterNode.IsMainOutputNode = true;
LoadedShaderVersion = VersionInfo.FullNumber;
}
public void CreateNewEmptyTemplate( string templateGUID )
{
CleanNodes();
TemplateDataParent templateData = m_parentWindow.TemplatesManagerInstance.GetTemplate( templateGUID );
if( templateData.TemplateType == TemplateDataType.LegacySinglePass )
{
TemplateMasterNode newMasterNode = CreateNode( typeof( TemplateMasterNode ), false ) as TemplateMasterNode;
m_masterNodeId = newMasterNode.UniqueId;
ParentWindow.IsShaderFunctionWindow = false;
CurrentCanvasMode = NodeAvailability.TemplateShader;
m_currentSRPType = TemplateSRPType.BuiltIn;
newMasterNode.OnMaterialUpdatedEvent += OnMaterialUpdatedEvent;
newMasterNode.OnShaderUpdatedEvent += OnShaderUpdatedEvent;
newMasterNode.IsMainOutputNode = true;
newMasterNode.SetTemplate( templateData as TemplateData, true, true );
}
else
{
/*Paulo*/
TemplateMultiPass multipassData = templateData as TemplateMultiPass;
m_currentSRPType = multipassData.SubShaders[ 0 ].Modules.SRPType;
Vector2 currentPosition = Vector2.zero;
for( int subShaderIdx = 0; subShaderIdx < multipassData.SubShaders.Count; subShaderIdx++ )
{
for( int passIdx = 0; passIdx < multipassData.SubShaders[ subShaderIdx ].Passes.Count; passIdx++ )
{
TemplateMultiPassMasterNode newMasterNode = CreateNode( typeof( TemplateMultiPassMasterNode ), false ) as TemplateMultiPassMasterNode;
if( multipassData.SubShaders[ subShaderIdx ].Passes[ passIdx ].IsMainPass )
{
m_masterNodeId = newMasterNode.UniqueId;
ParentWindow.IsShaderFunctionWindow = false;
CurrentCanvasMode = NodeAvailability.TemplateShader;
newMasterNode.OnMaterialUpdatedEvent += OnMaterialUpdatedEvent;
newMasterNode.OnShaderUpdatedEvent += OnShaderUpdatedEvent;
newMasterNode.IsMainOutputNode = true;
}
newMasterNode.Vec2Position = currentPosition;
newMasterNode.SetTemplate( multipassData, true, true, subShaderIdx, passIdx, SetTemplateSource.NewShader );
//currentPosition.y += newMasterNode.HeightEstimate + 10;
}
}
RefreshLinkedMasterNodes( false );
OnRefreshLinkedPortsComplete();
}
LoadedShaderVersion = VersionInfo.FullNumber;
}
public void CreateNewEmptyFunction( AmplifyShaderFunction shaderFunction )
{
CleanNodes();
FunctionOutput newOutputNode = CreateNode( typeof( FunctionOutput ), false ) as FunctionOutput;
m_masterNodeId = newOutputNode.UniqueId;
ParentWindow.IsShaderFunctionWindow = true;
CurrentCanvasMode = NodeAvailability.ShaderFunction;
newOutputNode.IsMainOutputNode = true;
}
public void ForceCategoryRefresh() { m_forceCategoryRefresh = true; }
public void RefreshExternalReferences()
{
int count = m_nodes.Count;
for( int i = 0; i < count; i++ )
{
m_nodes[ i ].RefreshExternalReferences();
}
}
public Vector2 SelectedNodesCentroid
{
get
{
if( m_selectedNodes.Count == 0 )
return Vector2.zero;
Vector2 pos = new Vector2( 0, 0 );
for( int i = 0; i < m_selectedNodes.Count; i++ )
{
pos += m_selectedNodes[ i ].Vec2Position;
}
pos /= m_selectedNodes.Count;
return pos;
}
}
public void AddVirtualTextureCount()
{
m_virtualTextureCount += 1;
}
public void RemoveVirtualTextureCount()
{
m_virtualTextureCount -= 1;
if( m_virtualTextureCount < 0 )
{
Debug.LogWarning( "Invalid virtual texture count" );
}
}
public bool HasVirtualTexture { get { return m_virtualTextureCount > 0; } }
public void AddInstancePropertyCount()
{
m_instancePropertyCount += 1;
// Debug.Log( "AddInstancePropertyCount "+this.GetInstanceID() + " " + m_instancePropertyCount );
}
public void RemoveInstancePropertyCount()
{
m_instancePropertyCount -= 1;
// Debug.Log( "RemoveInstancePropertyCount " + this.GetInstanceID() + " " + m_instancePropertyCount );
if( m_instancePropertyCount < 0 )
{
Debug.LogWarning( "Invalid property instance count" );
}
}
public int InstancePropertyCount { get { return m_instancePropertyCount; } set { m_instancePropertyCount = value; } }
public bool IsInstancedShader { get { return m_instancePropertyCount > 0; } }
public void AddNormalDependentCount() { m_normalDependentCount += 1; }
public void RemoveNormalDependentCount()
{
m_normalDependentCount -= 1;
if( m_normalDependentCount < 0 )
{
Debug.LogWarning( "Invalid normal dependentCount count" );
}
}
public void SetModeFromMasterNode()
{
MasterNode masterNode = CurrentMasterNode;
if( masterNode != null )
{
switch( masterNode.CurrentMasterNodeCategory )
{
default:
case AvailableShaderTypes.SurfaceShader:
{
if( masterNode is StandardSurfaceOutputNode )
CurrentCanvasMode = ParentWindow.CurrentNodeAvailability;
else
CurrentCanvasMode = NodeAvailability.SurfaceShader;
}
break;
case AvailableShaderTypes.Template:
{
CurrentCanvasMode = NodeAvailability.TemplateShader;
}
break;
}
}
else
{
CurrentCanvasMode = NodeAvailability.SurfaceShader;
}
}
public void MarkToDelete( ParentNode node )
{
m_markedForDeletion.Add( node );
}
public bool IsMasterNode( ParentNode node )
{
return ( node.UniqueId == m_masterNodeId ) ||
m_multiPassMasterNodes.HasNode( node.UniqueId );
}
public TemplateMultiPassMasterNode GetMainMasterNodeOfLOD( int lod )
{
if( lod == -1 )
return CurrentMasterNode as TemplateMultiPassMasterNode;
return m_lodMultiPassMasterNodes[ lod ].NodesList.Find( x => x.IsMainOutputNode );
}
public TemplateMultiPassMasterNode GetMasterNodeOfPass( string passName, int lod )
{
if( lod == -1 )
return m_multiPassMasterNodes.NodesList.Find( x => x.PassName.Equals( passName ) );
return m_lodMultiPassMasterNodes[lod].NodesList.Find( x => x.PassName.Equals( passName ) );
}
public void ForceMultiPassMasterNodesRefresh()
{
int mainOutputId = 0;
int count = m_multiPassMasterNodes.Count;
for( int i = 0; i < count; i++ )
{
m_multiPassMasterNodes.NodesList[ i ].ForceTemplateRefresh();
if( m_multiPassMasterNodes.NodesList[ i ].IsMainOutputNode )
mainOutputId = i;
}
int lodCount = m_lodMultiPassMasterNodes.Count;
for( int i = 0; i < lodCount; i++ )
{
if( m_lodMultiPassMasterNodes[ i ] != null )
{
count = m_lodMultiPassMasterNodes[ i ].Count;
for( int j = 0; j < count; j++ )
{
m_lodMultiPassMasterNodes[ i ].NodesList[ j ].ForceTemplateRefresh();
}
}
}
m_multiPassMasterNodes.NodesList[ mainOutputId ].CheckTemplateChanges();
}
public void SetLateOptionsRefresh()
{
m_lateOptionsRefresh = true;
}
public void CreateLodMasterNodes( TemplateMultiPass templateMultiPass,int index, Vector2 initialPosition )
{
for( int lod = 0; lod < m_lodMultiPassMasterNodes.Count; lod++ )
{
if( m_lodMultiPassMasterNodes[ lod ].Count == 0 )
{
TemplateMultiPassMasterNode reference = CurrentMasterNode as TemplateMultiPassMasterNode;
int shaderLod = -1;
if( lod == 0 )
{
shaderLod = reference.ShaderLOD - MasterNodeLODIncrement;
}
else
{
//index == -2 is when user clicks on +/- buttons over the foldout UI
if( index == -2 )
{
shaderLod = m_lodMultiPassMasterNodes[ lod - 1 ].NodesList[ reference.PassIdx ].ShaderLOD - MasterNodeLODIncrement;
}
//index == -1 is when user clicks on + button over the main lod master node
else if( index == -1 )
{
int mainShaderLOD = m_lodMultiPassMasterNodes[ 0 ].NodesList[ reference.PassIdx ].ShaderLOD;
shaderLod = ( reference.ShaderLOD + mainShaderLOD )/2;
}
else
{
if( m_lodMultiPassMasterNodes[ index ].Count > 0 )
{
if( m_lodMultiPassMasterNodes[ index + 1 ].Count > 0 )
{
shaderLod = (m_lodMultiPassMasterNodes[ index ].NodesList[ reference.PassIdx ].ShaderLOD +
m_lodMultiPassMasterNodes[ index + 1 ].NodesList[ reference.PassIdx ].ShaderLOD )/2;
}
else
{
shaderLod = m_lodMultiPassMasterNodes[ index ].NodesList[ reference.PassIdx ].ShaderLOD - MasterNodeLODIncrement;
}
}
}
}
int nodeId = 0;
TemplateMultiPassMasterNode mainMasterNode = null;
for( int subShaderIdx = 0; subShaderIdx < templateMultiPass.SubShaders.Count; subShaderIdx++ )
{
for( int passIdx = 0; passIdx < templateMultiPass.SubShaders[ subShaderIdx ].Passes.Count; passIdx++ )
{
TemplateMultiPassMasterNode masterNode = ScriptableObject.CreateInstance( typeof( TemplateMultiPassMasterNode ) ) as TemplateMultiPassMasterNode;
masterNode.LODIndex = lod;
masterNode.ContainerGraph = this;
masterNode.Vec2Position = initialPosition;
AddNode( masterNode, true );
masterNode.SetTemplate( templateMultiPass, true, true, subShaderIdx, passIdx, SetTemplateSource.NewShader );
masterNode.CopyOptionsFrom( m_multiPassMasterNodes.NodesList[ nodeId++ ] );
if( masterNode.IsMainOutputNode || ( subShaderIdx == 0 && passIdx == 0 ) )
{
masterNode.SetShaderLODValueAndLabel( shaderLod );
mainMasterNode = masterNode;
}
}
}
mainMasterNode.ForceOptionsRefresh();
SortLODMasterNodes();
if( OnLODMasterNodesAddedEvent != null )
{
OnLODMasterNodesAddedEvent( lod );
}
TemplateMultiPassMasterNode lodMainMasterNode = CurrentMasterNode as TemplateMultiPassMasterNode;
lodMainMasterNode.SetShaderLODValueAndLabel( lodMainMasterNode.ShaderLOD );
return;
}
}
}
public void DestroyLodMasterNodes( int index )
{
if( index < 0 )
{
for( int lod = m_lodMultiPassMasterNodes.Count - 1; lod >= 0; lod-- )
{
if( m_lodMultiPassMasterNodes[ lod ].Count > 0 )
{
while( m_lodMultiPassMasterNodes[ lod ].Count > 0 )
{
DestroyNode( m_lodMultiPassMasterNodes[ lod ].NodesList[ 0 ], false, true );
}
break;
}
}
}
else
{
while( m_lodMultiPassMasterNodes[ index ].Count > 0 )
{
DestroyNode( m_lodMultiPassMasterNodes[ index ].NodesList[ 0 ], false, true );
}
}
SortLODMasterNodes();
TemplateMultiPassMasterNode lodMainMasterNode = CurrentMasterNode as TemplateMultiPassMasterNode;
lodMainMasterNode.SetShaderLODValueAndLabel( lodMainMasterNode.ShaderLOD );
}
public void SortLODMasterNodes()
{
int idx = (CurrentMasterNode as TemplateMultiPassMasterNode).PassIdx;
m_lodMultiPassMasterNodes.Sort( ( x, y ) =>
{
if( x.Count > 0 )
{
if( y.Count > 0 )
{
return -x.NodesList[ idx ].ShaderLOD.CompareTo( y.NodesList[ idx ].ShaderLOD );
}
else
{
return -1;
}
}
else
{
if( y.Count > 0 )
{
return 1;
}
}
return 0;
});
for( int lodIdx = 0; lodIdx < m_lodMultiPassMasterNodes.Count; lodIdx++ )
{
for( int nodeIdx = 0; nodeIdx < m_lodMultiPassMasterNodes[ lodIdx ].Count; nodeIdx++ )
{
m_lodMultiPassMasterNodes[ lodIdx ].NodesList[ nodeIdx ].LODIndex = lodIdx;
}
}
}
public List<TemplateMultiPassMasterNode> GetMultiPassMasterNodes( int lod )
{
if( lod == -1 )
return m_multiPassMasterNodes.NodesList;
return m_lodMultiPassMasterNodes[ lod ].NodesList;
}
public bool IsNormalDependent { get { return m_normalDependentCount > 0; } }
public void MarkToDeselect() { m_markedToDeSelect = true; }
public void MarkToSelect( int nodeId ) { m_markToSelect = nodeId; }
public void MarkWireHighlights() { m_checkSelectedWireHighlights = true; }
public List<ParentNode> SelectedNodes { get { return m_selectedNodes; } }
public List<ParentNode> MarkedForDeletionNodes { get { return m_markedForDeletion; } }
public int CurrentMasterNodeId { get { return m_masterNodeId; } set { m_masterNodeId = value; } }
public Shader CurrentShader
{
get
{
MasterNode masterNode = GetNode( m_masterNodeId ) as MasterNode;
if( masterNode != null )
return masterNode.CurrentShader;
return null;
}
}
public Material CurrentMaterial
{
get
{
MasterNode masterNode = GetNode( m_masterNodeId ) as MasterNode;
if( masterNode != null )
return masterNode.CurrentMaterial;
return null;
}
}
public NodeAvailability CurrentCanvasMode { get { return m_currentCanvasMode; } set { m_currentCanvasMode = value; ParentWindow.LateRefreshAvailableNodes(); } }
public OutputNode CurrentOutputNode { get { return GetNode( m_masterNodeId ) as OutputNode; } }
public FunctionOutput CurrentFunctionOutput { get { return GetNode( m_masterNodeId ) as FunctionOutput; } }
public MasterNode CurrentMasterNode { get { return GetNode( m_masterNodeId ) as MasterNode; } }
public StandardSurfaceOutputNode CurrentStandardSurface { get { return GetNode( m_masterNodeId ) as StandardSurfaceOutputNode; } }
public List<ParentNode> AllNodes { get { return m_nodes; } }
public int NodeCount { get { return m_nodes.Count; } }
//public List<ParentNode> VisibleNodes { get { return m_visibleNodes; } }
public int NodeClicked
{
set { m_nodeClicked = value; }
get { return m_nodeClicked; }
}
public bool IsDirty
{
set { m_isDirty = value && UIUtils.DirtyMask; }
get
{
bool value = m_isDirty;
m_isDirty = false;
return value;
}
}
public bool SaveIsDirty
{
set { m_saveIsDirty = value && UIUtils.DirtyMask; }
get { return m_saveIsDirty; }
}
public int LoadedShaderVersion
{
get { return m_loadedShaderVersion; }
set { m_loadedShaderVersion = value; }
}
public AmplifyShaderFunction CurrentShaderFunction
{
get { if( CurrentFunctionOutput != null ) return CurrentFunctionOutput.Function; else return null; }
set { if( CurrentFunctionOutput != null ) CurrentFunctionOutput.Function = value; }
}
public bool HasUnConnectedNodes { get { return m_hasUnConnectedNodes; } }
public UsageListSamplerNodes SamplerNodes { get { return m_samplerNodes; } }
public UsageListFloatIntNodes FloatIntNodes { get { return m_floatNodes; } }
public UsageListTexturePropertyNodes TexturePropertyNodes { get { return m_texturePropertyNodes; } }
public UsageListTextureArrayNodes TextureArrayNodes { get { return m_textureArrayNodes; } }
public UsageListPropertyNodes PropertyNodes { get { return m_propertyNodes; } }
public UsageListPropertyNodes RawPropertyNodes { get { return m_rawPropertyNodes; } }
public UsageListCustomExpressionsOnFunctionMode CustomExpressionOnFunctionMode { get { return m_customExpressionsOnFunctionMode; } }
public UsageListStaticSwitchNodes StaticSwitchNodes { get { return m_staticSwitchNodes; } }
public UsageListScreenColorNodes ScreenColorNodes { get { return m_screenColorNodes; } }
public UsageListRegisterLocalVarNodes LocalVarNodes { get { return m_localVarNodes; } }
public UsageListGlobalArrayNodes GlobalArrayNodes { get { return m_globalArrayNodes; } }
public UsageListFunctionInputNodes FunctionInputNodes { get { return m_functionInputNodes; } }
public UsageListFunctionNodes FunctionNodes { get { return m_functionNodes; } }
public UsageListFunctionOutputNodes FunctionOutputNodes { get { return m_functionOutputNodes; } }
public UsageListFunctionSwitchNodes FunctionSwitchNodes { get { return m_functionSwitchNodes; } }
public UsageListFunctionSwitchCopyNodes FunctionSwitchCopyNodes { get { return m_functionSwitchCopyNodes; } }
public UsageListTemplateMultiPassMasterNodes MultiPassMasterNodes { get { return m_multiPassMasterNodes; } set { m_multiPassMasterNodes = value; } }
public List<UsageListTemplateMultiPassMasterNodes> LodMultiPassMasternodes { get { return m_lodMultiPassMasterNodes; } }
public PrecisionType CurrentPrecision
{
get { return m_currentPrecision; }
set { m_currentPrecision = value; }
}
public NodeLOD LodLevel
{
get { return m_lodLevel; }
}
public List<ParentNode> NodePreviewList { get { return m_nodePreviewList; } set { m_nodePreviewList = value; } }
public void SetGraphId( int id )
{
m_graphId = id;
}
public int GraphId
{
get { return m_graphId; }
}
public AmplifyShaderEditorWindow ParentWindow
{
get { return m_parentWindow; }
set { m_parentWindow = value; }
}
public bool ChangedLightingModel
{
get { return m_changedLightingModel; }
set { m_changedLightingModel = value; }
}
public bool ForceRepositionCheck
{
get { return m_forceRepositionCheck; }
set { m_forceRepositionCheck = value; }
}
public bool IsLoading { get { return m_isLoading; } set { m_isLoading = value; } }
public bool IsDuplicating { get { return m_isDuplicating; } set { m_isDuplicating = value; } }
public TemplateSRPType CurrentSRPType { get { return m_currentSRPType; }set { m_currentSRPType = value; } }
public bool IsSRP { get { return m_currentSRPType == TemplateSRPType.Lightweight || m_currentSRPType == TemplateSRPType.HD; } }
public bool IsHDRP { get { return m_currentSRPType == TemplateSRPType.HD; } }
public bool IsLWRP { get { return m_currentSRPType == TemplateSRPType.Lightweight; } }
public bool IsStandardSurface { get { return GetNode( m_masterNodeId ) is StandardSurfaceOutputNode; } }
public bool SamplingMacros {
get { return m_samplingThroughMacros; }
set { m_samplingThroughMacros = value; }
}
public bool HasLODs { get { return m_lodMultiPassMasterNodes[ 0 ].Count > 0; } }
//public bool HasLodMultiPassNodes
//{
// get
// {
// for( int i = 0; i < m_lodMultiPassMasterNodes.Count; i++ )
// {
// if( m_lodMultiPassMasterNodes[ i ].Count > 0 )
// return true;
// }
// return false;
// }
//}
}
}