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

3664 lines
114 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using System.Collections.Generic;
  5. using UnityEditor;
  6. using UnityEngine;
  7. namespace AmplifyShaderEditor
  8. {
  9. public enum PreviewLocation
  10. {
  11. Auto,
  12. TopCenter,
  13. BottomCenter,
  14. Left,
  15. Right
  16. }
  17. public enum NodeMessageType
  18. {
  19. Error,
  20. Warning,
  21. Info
  22. }
  23. [Serializable]
  24. public class ParentNode : UndoParentNode, ISerializationCallbackReceiver
  25. {
  26. protected readonly string[] PrecisionLabels = { "Float", "Half" };
  27. private const double NodeClickTime = 0.2;
  28. protected GUIContent PrecisionContent = new GUIContent( "Precision", "Changes the precision of internal calculations, using lower types saves some performance\nDefault: Float" );
  29. private const int MoveCountBuffer = 3;// When testing for stopped movement we need to take Layout and Repaint into account for them not to interfere with tests
  30. private const float MinInsideBoxWidth = 20;
  31. private const float MinInsideBoxHeight = 10;
  32. private const string WikiLinkStr = "online reference";
  33. public delegate void OnNodeEvent( ParentNode node, bool testOnlySelected, InteractionMode interactionMode );
  34. public delegate void OnNodeGenericEvent( ParentNode node );
  35. public delegate void OnNodeReOrder( ParentNode node, int index );
  36. public delegate void DrawPropertySection();
  37. public delegate void OnSRPAction( int outputId, ref MasterNodeDataCollector dataCollector );
  38. [SerializeField]
  39. protected PrecisionType m_currentPrecisionType = PrecisionType.Float;
  40. [SerializeField]
  41. protected InteractionMode m_defaultInteractionMode = InteractionMode.Other;
  42. public event OnNodeEvent OnNodeStoppedMovingEvent;
  43. public OnNodeGenericEvent OnNodeChangeSizeEvent;
  44. public OnNodeGenericEvent OnNodeDestroyedEvent;
  45. public event OnNodeReOrder OnNodeReOrderEvent;
  46. public OnSRPAction OnLightweightAction;
  47. public OnSRPAction OnHDAction;
  48. [SerializeField]
  49. private int m_uniqueId;
  50. [SerializeField]
  51. protected Rect m_position;
  52. [SerializeField]
  53. protected Rect m_unpreviewedPosition;
  54. [SerializeField]
  55. protected GUIContent m_content;
  56. [SerializeField]
  57. protected GUIContent m_additionalContent;
  58. [SerializeField]
  59. protected bool m_initialized;
  60. [SerializeField]
  61. protected NodeConnectionStatus m_connStatus;
  62. protected bool m_selfPowered = false;
  63. [SerializeField]
  64. protected int m_activeConnections;
  65. [SerializeField]
  66. protected System.Type m_activeType;
  67. [SerializeField]
  68. protected int m_activePort;
  69. [SerializeField]
  70. protected int m_activeNode;
  71. protected NodeRestrictions m_restrictions;
  72. [SerializeField]
  73. protected Color m_statusColor;
  74. [SerializeField]
  75. protected Rect m_propertyDrawPos;
  76. // Ports
  77. [SerializeField]
  78. protected List<InputPort> m_inputPorts = new List<InputPort>();
  79. protected Dictionary<int, InputPort> m_inputPortsDict = new Dictionary<int, InputPort>();
  80. [SerializeField]
  81. protected List<OutputPort> m_outputPorts = new List<OutputPort>();
  82. protected Dictionary<int, OutputPort> m_outputPortsDict = new Dictionary<int, OutputPort>();
  83. [SerializeField]
  84. protected Rect m_globalPosition;
  85. [SerializeField]
  86. protected Rect m_headerPosition;
  87. //private Vector2 m_tooltipOffset;
  88. [SerializeField]
  89. protected bool m_sizeIsDirty = false;
  90. [SerializeField]
  91. protected Vector2 m_extraSize;
  92. [SerializeField]
  93. protected Vector2 m_insideSize;
  94. [SerializeField]
  95. protected float m_fontHeight;
  96. // Editor State save on Play Button
  97. [SerializeField]
  98. protected bool m_isDirty;
  99. [SerializeField]
  100. private int m_isMoving = 0;
  101. [SerializeField]
  102. private Rect m_lastPosition;
  103. // Live Shader Gen
  104. [SerializeField]
  105. private bool m_saveIsDirty;
  106. [SerializeField]
  107. protected bool m_requireMaterialUpdate = false;
  108. [SerializeField]
  109. protected int m_commentaryParent = -1;
  110. [SerializeField]
  111. protected int m_depth = -1;
  112. [SerializeField]
  113. protected bool m_materialMode = false;
  114. [SerializeField]
  115. protected bool m_showPreview = false;
  116. [SerializeField]
  117. protected int m_previewMaterialPassId = -1;
  118. protected bool m_useSquareNodeTitle = false;
  119. // Error Box Messages
  120. private Rect m_errorBox;
  121. private bool m_previousErrorMessage = false;
  122. protected bool m_showErrorMessage = false;
  123. protected NodeMessageType m_errorMessageTypeIsError = NodeMessageType.Error;
  124. protected string m_errorMessageTooltip = string.Empty;
  125. private GUIContent m_errorIcon = new GUIContent();
  126. private GUIContent m_errorMessage = new GUIContent();
  127. private GUIStyle m_errorCurrentStyle;
  128. private const string ErrorTitle = "ERROR";
  129. private const string WarningTitle = "WARNING";
  130. private const string InfoTitle = "INFO";
  131. // Drawing Node
  132. protected PreviewLocation m_selectedLocation = PreviewLocation.Auto;
  133. private int m_extraHeaderHeight = 0;
  134. protected bool m_isVisible;
  135. protected bool m_selected = false;
  136. protected bool m_rmbIgnore;
  137. protected GUIContent m_sizeContentAux;
  138. protected uint m_currentReadParamIdx = 1;
  139. protected bool m_reorderLocked = false;
  140. protected Rect m_cachedPos;
  141. protected Vector2 m_accumDelta = Vector2.zero;
  142. private bool m_isOnGrid = false;
  143. protected bool m_useInternalPortData = false;
  144. protected bool m_autoDrawInternalPortData = true;
  145. protected DrawOrder m_drawOrder = DrawOrder.Default;
  146. protected bool m_movingInFrame = false;
  147. protected float m_anchorAdjust = -1;
  148. protected Color m_headerColor;
  149. [SerializeField] // needs to be serialized because of Undo
  150. protected Color m_headerColorModifier = Color.white;
  151. protected bool m_infiniteLoopDetected = false;
  152. protected int m_textLabelWidth = -1;
  153. private bool m_linkVisibility = false;
  154. [SerializeField]
  155. protected bool m_hasTooltipLink = true;
  156. protected int m_category = 0;
  157. protected double m_lastTimeSelected;
  158. private double m_tooltipTimestamp;
  159. protected string m_tooltipText;
  160. protected Rect m_unscaledRemainingBox;
  161. protected Rect m_remainingBox;
  162. private int m_visibleInputs = 0;
  163. private int m_visibleOutputs = 0;
  164. private double m_doubleClickTimestamp;
  165. private const double DoubleClickTime = 0.25;
  166. protected bool m_canExpand = true;
  167. protected bool m_firstDraw = true;
  168. protected int m_matrixId = -1;
  169. private float m_paddingTitleLeft = 0;
  170. private float m_paddingTitleRight = 0;
  171. // Preview Fields
  172. private Material m_previewMaterial = null;
  173. private Shader m_previewShader = null;
  174. protected string m_previewShaderGUID = string.Empty;
  175. protected float m_marginPreviewLeft = 0;
  176. protected bool m_globalShowPreview = false;
  177. protected Rect m_unscaledPreviewRect;
  178. protected Rect m_previewRect;
  179. protected bool m_drawPreviewMaskButtons = true;
  180. private int m_channelNumber = 0;
  181. protected bool m_firstPreviewDraw = true;
  182. [SerializeField]
  183. protected bool m_drawPreview = true;
  184. protected bool m_drawPreviewExpander = true;
  185. private bool m_spherePreview = false;
  186. protected bool m_drawPreviewAsSphere = false;
  187. protected bool m_forceDrawPreviewAsPlane = false;
  188. private int m_cachedMainTexId = -1;
  189. private int m_cachedMaskTexId = -1;
  190. private int m_cachedPortsId = -1;
  191. private int m_cachedPortId = -1;
  192. private int m_cachedDrawSphereId = -1;
  193. private int m_cachedInvertedZoomId = -1;
  194. //private int m_cachedIsLinearId = -1;
  195. private bool[] m_previewChannels = { true, true, true, false };
  196. // Others
  197. protected bool m_hasSubtitle = false;
  198. protected bool m_showSubtitle = true;
  199. protected bool m_hasLeftDropdown = false;
  200. protected bool m_autoWrapProperties = false;
  201. protected bool m_internalDataFoldout = true;
  202. protected bool m_propertiesFoldout = true;
  203. protected bool m_repopulateDictionaries = true;
  204. protected Vector2 m_lastInputBottomRight = Vector2.zero;
  205. protected Vector2 m_lastOutputBottomLeft = Vector2.zero;
  206. private Vector4 m_portMask = Vector4.zero;
  207. private Vector2 m_auxVector2 = Vector4.zero;
  208. protected Rect m_auxRect;
  209. protected PreviewLocation m_autoLocation;
  210. protected Rect m_titlePos;
  211. protected Rect m_addTitlePos;
  212. protected Rect m_expandRect;
  213. protected Rect m_dropdownRect;
  214. protected Rect m_currInputPortPos;
  215. protected Rect m_currOutputPortPos;
  216. protected Color m_colorBuffer;
  217. [SerializeField]
  218. protected bool m_docking = false;
  219. [SerializeField]
  220. protected int m_visiblePorts = 0;
  221. protected int m_graphDepth = 0;
  222. protected int m_oldInputCount = -1;
  223. protected bool m_dropdownEditing = false;
  224. protected bool m_isNodeBeingCopied = false;
  225. protected string m_previousTitle = string.Empty;
  226. protected string m_previousAdditonalTitle = string.Empty;
  227. private bool m_alive = true;
  228. private double m_timedUpdateInitialValue;
  229. private double m_timedUpdateInterval;
  230. private bool m_fireTimedUpdateRequest = false;
  231. public ParentNode()
  232. {
  233. m_position = new Rect( 0, 0, 0, 0 );
  234. m_content = new GUIContent( GUIContent.none );
  235. m_additionalContent = new GUIContent( GUIContent.none );
  236. CommonInit( -1 );
  237. }
  238. public ParentNode( int uniqueId, float x, float y, float width, float height )
  239. {
  240. m_position = new Rect( x, y, width, height );
  241. m_content = new GUIContent( GUIContent.none );
  242. m_additionalContent = new GUIContent( GUIContent.none );
  243. CommonInit( uniqueId );
  244. }
  245. public virtual void OnEnable()
  246. {
  247. hideFlags = HideFlags.HideAndDontSave;
  248. if( m_nodeAttribs != null )
  249. {
  250. if( UIUtils.HasColorCategory( m_nodeAttribs.Category ) )
  251. {
  252. m_headerColor = UIUtils.GetColorFromCategory( m_nodeAttribs.Category );
  253. }
  254. else
  255. {
  256. if( !string.IsNullOrEmpty( m_nodeAttribs.CustomCategoryColor ) )
  257. {
  258. m_headerColor = UIUtils.AddColorCategory( m_nodeAttribs.Category, m_nodeAttribs.CustomCategoryColor );
  259. }
  260. }
  261. }
  262. m_tooltipTimestamp = Time.realtimeSinceStartup;
  263. hideFlags = HideFlags.DontSave;
  264. }
  265. protected virtual void CommonInit( int uniqueId )
  266. {
  267. m_uniqueId = uniqueId;
  268. m_isOnGrid = false;
  269. ConnStatus = NodeConnectionStatus.Not_Connected;
  270. m_inputPorts = new List<InputPort>();
  271. m_inputPortsDict = new Dictionary<int, InputPort>();
  272. m_outputPorts = new List<OutputPort>();
  273. m_outputPortsDict = new Dictionary<int, OutputPort>();
  274. System.Reflection.MemberInfo info = this.GetType();
  275. m_nodeAttribs = info.GetCustomAttributes( true )[ 0 ] as NodeAttributes;
  276. if( m_nodeAttribs != null )
  277. {
  278. m_content.text = m_nodeAttribs.Name;
  279. //m_content.tooltip = m_nodeAttribs.Description;
  280. m_tooltipText = m_nodeAttribs.Description;
  281. m_selected = false;
  282. }
  283. m_sizeContentAux = new GUIContent();
  284. m_extraSize = new Vector2( 0, 0 );
  285. m_insideSize = new Vector2( 0, 0 );
  286. m_sizeIsDirty = true;
  287. m_initialized = true;
  288. m_restrictions = new NodeRestrictions();
  289. m_propertyDrawPos = new Rect();
  290. }
  291. public virtual void AfterCommonInit()
  292. {
  293. if( PreviewShader && !HasPreviewShader )
  294. {
  295. m_drawPreview = false;
  296. m_drawPreviewExpander = false;
  297. m_canExpand = false;
  298. }
  299. if( m_drawPreviewExpander || m_hasLeftDropdown )
  300. {
  301. m_paddingTitleRight += Constants.PreviewExpanderWidth + Constants.IconsLeftRightMargin;
  302. m_paddingTitleLeft = Constants.PreviewExpanderWidth + Constants.IconsLeftRightMargin;
  303. }
  304. }
  305. public virtual void Destroy()
  306. {
  307. m_alive = false;
  308. if( OnNodeDestroyedEvent != null )
  309. {
  310. OnNodeDestroyedEvent( this );
  311. OnNodeDestroyedEvent = null;
  312. }
  313. OnLightweightAction = null;
  314. OnHDAction = null;
  315. OnNodeStoppedMovingEvent = null;
  316. OnNodeChangeSizeEvent = null;
  317. OnNodeReOrderEvent = null;
  318. if( m_restrictions != null )
  319. m_restrictions.Destroy();
  320. m_restrictions = null;
  321. if( m_inputPorts != null )
  322. {
  323. int inputCount = m_inputPorts.Count;
  324. for( int i = 0; i < inputCount; i++ )
  325. {
  326. m_inputPorts[ i ].Destroy();
  327. }
  328. m_inputPorts.Clear();
  329. m_inputPorts = null;
  330. }
  331. if( m_outputPorts != null )
  332. {
  333. int outputCount = m_outputPorts.Count;
  334. for( int i = 0; i < outputCount; i++ )
  335. {
  336. m_outputPorts[ i ].Destroy();
  337. }
  338. m_outputPorts.Clear();
  339. m_outputPorts = null;
  340. }
  341. if( m_inputPortsDict != null )
  342. m_inputPortsDict.Clear();
  343. m_inputPortsDict = null;
  344. if( m_outputPortsDict != null )
  345. m_outputPortsDict.Clear();
  346. m_outputPortsDict = null;
  347. if( m_previewMaterial != null )
  348. DestroyImmediate( m_previewMaterial );
  349. m_previewMaterial = null;
  350. m_previewShader = null;
  351. //m_containerGraph = null;
  352. }
  353. public virtual void Move( Vector2 delta )
  354. {
  355. if( m_docking )
  356. return;
  357. Move( delta, false );
  358. }
  359. public virtual void Move( Vector2 delta, bool snap )
  360. {
  361. if( m_docking )
  362. return;
  363. if( m_isMoving == 0 )
  364. {
  365. m_cachedPos = m_position;
  366. m_accumDelta = Vector2.zero;
  367. }
  368. m_isMoving = MoveCountBuffer;
  369. m_accumDelta += delta;
  370. if( snap )
  371. {
  372. m_position.x = Mathf.Round( ( m_cachedPos.x + m_accumDelta.x ) / 16 ) * 16;
  373. m_position.y = Mathf.Round( ( m_cachedPos.y + m_accumDelta.y ) / 16 ) * 16;
  374. }
  375. else
  376. {
  377. m_position.x += delta.x;
  378. m_position.y += delta.y;
  379. }
  380. //if(Event.current.type == EventType.Layout)
  381. m_movingInFrame = true;
  382. }
  383. public virtual void UpdateMaterial( Material mat )
  384. {
  385. m_requireMaterialUpdate = false;
  386. }
  387. public virtual void SetMaterialMode( Material mat, bool fetchMaterialValues )
  388. {
  389. m_materialMode = ( mat != null );
  390. }
  391. public virtual bool UpdateShaderDefaults( ref Shader shader, ref TextureDefaultsDataColector defaultCol ) { return false; }
  392. public virtual void ForceUpdateFromMaterial( Material material ) { }
  393. public void SetSaveIsDirty()
  394. {
  395. if( m_connStatus == NodeConnectionStatus.Connected )
  396. {
  397. SaveIsDirty = true;
  398. }
  399. }
  400. public void ActivateNodeReordering( int index )
  401. {
  402. if( OnNodeReOrderEvent != null )
  403. OnNodeReOrderEvent( this, index );
  404. }
  405. void RecalculateInputPortIdx()
  406. {
  407. m_inputPortsDict.Clear();
  408. int count = m_inputPorts.Count;
  409. for( int i = 0; i < count; i++ )
  410. {
  411. if( m_inputPorts[ i ].IsConnected )
  412. {
  413. int nodeId = m_inputPorts[ i ].ExternalReferences[ 0 ].NodeId;
  414. int portId = m_inputPorts[ i ].ExternalReferences[ 0 ].PortId;
  415. ParentNode node = UIUtils.GetNode( nodeId );
  416. if( node != null )
  417. {
  418. OutputPort outputPort = node.GetOutputPortByUniqueId( portId );
  419. int outputCount = outputPort.ExternalReferences.Count;
  420. for( int j = 0; j < outputCount; j++ )
  421. {
  422. if( outputPort.ExternalReferences[ j ].NodeId == m_uniqueId &&
  423. outputPort.ExternalReferences[ j ].PortId == m_inputPorts[ i ].PortId )
  424. {
  425. outputPort.ExternalReferences[ j ].PortId = i;
  426. }
  427. }
  428. }
  429. }
  430. m_inputPorts[ i ].PortId = i;
  431. m_inputPortsDict.Add( i, m_inputPorts[ i ] );
  432. }
  433. }
  434. public void SwapInputPorts( int fromIdx, int toIdx )
  435. {
  436. InputPort port = m_inputPorts[ fromIdx ];
  437. //if( toIdx > fromIdx )
  438. // toIdx--;
  439. m_inputPorts.Remove( port );
  440. m_inputPorts.Insert( toIdx, port );
  441. RecalculateInputPortIdx();
  442. SetSaveIsDirty();
  443. }
  444. public void RemoveInputPort( int idx )
  445. {
  446. if( idx < m_inputPorts.Count )
  447. {
  448. m_inputPortsDict.Remove( m_inputPorts[ idx ].PortId );
  449. m_inputPorts.RemoveAt( idx );
  450. SetSaveIsDirty();
  451. m_sizeIsDirty = true;
  452. }
  453. }
  454. public void RemoveOutputPort( string name )
  455. {
  456. int count = m_outputPorts.Count;
  457. for( int i = 0; i < count; i++ )
  458. {
  459. if( m_outputPorts[ i ].Name.Equals( name ) )
  460. {
  461. if( m_outputPorts[ i ].IsConnected )
  462. {
  463. m_containerGraph.DeleteConnection( false, m_uniqueId, m_outputPorts[ i ].PortId, false, true );
  464. m_outputPortsDict.Remove( m_outputPorts[ i ].PortId );
  465. m_outputPorts.RemoveAt( i );
  466. SetSaveIsDirty();
  467. m_sizeIsDirty = true;
  468. }
  469. }
  470. }
  471. }
  472. public void RemoveOutputPort( int idx, bool isArrayIndex = true )
  473. {
  474. if( isArrayIndex )
  475. {
  476. // idx represents a position on the output port array
  477. if( idx < m_outputPorts.Count )
  478. {
  479. if( m_outputPorts[ idx ].IsConnected )
  480. {
  481. m_containerGraph.DeleteConnection( false, m_uniqueId, m_outputPorts[ idx ].PortId, false, true );
  482. }
  483. m_outputPortsDict.Remove( m_outputPorts[ idx ].PortId );
  484. m_outputPorts.RemoveAt( idx );
  485. SetSaveIsDirty();
  486. m_sizeIsDirty = true;
  487. }
  488. }
  489. else
  490. {
  491. // idx represents a port unique id
  492. int count = m_outputPorts.Count;
  493. int arrIdx = -1;
  494. for( int i = 0; i < count; i++ )
  495. {
  496. if( m_outputPorts[ i ].PortId == idx )
  497. {
  498. arrIdx = i;
  499. break;
  500. }
  501. }
  502. if( arrIdx >= 0 )
  503. {
  504. if( m_outputPorts[ arrIdx ].IsConnected )
  505. {
  506. m_containerGraph.DeleteConnection( false, m_uniqueId, idx, false, true );
  507. }
  508. m_outputPortsDict.Remove( idx );
  509. m_outputPorts.RemoveAt( arrIdx );
  510. SetSaveIsDirty();
  511. m_sizeIsDirty = true;
  512. }
  513. }
  514. }
  515. // Manually add Ports
  516. public InputPort AddInputPort( WirePortDataType type, bool typeLocked, string name, int orderId = -1, MasterNodePortCategory category = MasterNodePortCategory.Fragment, int uniquePortId = -1 )
  517. {
  518. InputPort port = new InputPort( m_uniqueId, ( uniquePortId < 0 ? m_inputPorts.Count : uniquePortId ), type, name, typeLocked, ( orderId >= 0 ? orderId : m_inputPorts.Count ), category );
  519. m_inputPorts.Add( port );
  520. m_inputPortsDict.Add( port.PortId, port );
  521. SetSaveIsDirty();
  522. m_sizeIsDirty = true;
  523. return port;
  524. }
  525. public InputPort AddInputPort( WirePortDataType type, bool typeLocked, string name, string dataName, int orderId = -1, MasterNodePortCategory category = MasterNodePortCategory.Fragment, int uniquePortId = -1 )
  526. {
  527. InputPort port = new InputPort( m_uniqueId, ( uniquePortId < 0 ? m_inputPorts.Count : uniquePortId ), type, name, dataName, typeLocked, ( orderId >= 0 ? orderId : m_inputPorts.Count ), category );
  528. m_inputPorts.Add( port );
  529. m_inputPortsDict.Add( port.PortId, port );
  530. SetSaveIsDirty();
  531. m_sizeIsDirty = true;
  532. return port;
  533. }
  534. public InputPort AddInputPortAt( int idx, WirePortDataType type, bool typeLocked, string name, int orderId = -1, MasterNodePortCategory category = MasterNodePortCategory.Fragment, int uniquePortId = -1 )
  535. {
  536. InputPort port = new InputPort( m_uniqueId, ( uniquePortId < 0 ? m_inputPorts.Count : uniquePortId ), type, name, typeLocked, ( orderId >= 0 ? orderId : m_inputPorts.Count ), category );
  537. m_inputPorts.Insert( idx, port );
  538. m_inputPortsDict.Add( port.PortId, port );
  539. SetSaveIsDirty();
  540. m_sizeIsDirty = true;
  541. RecalculateInputPortIdx();
  542. return port;
  543. }
  544. public void AddOutputPort( WirePortDataType type, string name, int uniquePortId = -1 )
  545. {
  546. m_outputPorts.Add( new OutputPort( m_uniqueId, ( uniquePortId < 0 ? m_outputPorts.Count : uniquePortId ), type, name ) );
  547. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  548. SetSaveIsDirty();
  549. m_sizeIsDirty = true;
  550. }
  551. public void AddOutputPortAt( int idx, WirePortDataType type, string name, int uniquePortId = -1 )
  552. {
  553. OutputPort port = new OutputPort( m_uniqueId, ( uniquePortId < 0 ? m_outputPorts.Count : uniquePortId ), type, name );
  554. m_outputPorts.Insert( idx, port );
  555. m_outputPortsDict.Add( port.PortId, port );
  556. SetSaveIsDirty();
  557. m_sizeIsDirty = true;
  558. }
  559. public void AddOutputVectorPorts( WirePortDataType type, string name )
  560. {
  561. m_sizeIsDirty = true;
  562. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, type, name ) );
  563. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  564. switch( type )
  565. {
  566. case WirePortDataType.FLOAT2:
  567. {
  568. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "X" ) );
  569. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  570. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "Y" ) );
  571. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  572. }
  573. break;
  574. case WirePortDataType.FLOAT3:
  575. {
  576. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "X" ) );
  577. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  578. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "Y" ) );
  579. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  580. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "Z" ) );
  581. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  582. }
  583. break;
  584. case WirePortDataType.FLOAT4:
  585. {
  586. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "X" ) );
  587. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  588. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "Y" ) );
  589. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  590. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "Z" ) );
  591. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  592. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "W" ) );
  593. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  594. }
  595. break;
  596. }
  597. SetSaveIsDirty();
  598. }
  599. public string GetOutputVectorItem( int vectorPortId, int currentPortId, string result )
  600. {
  601. if( m_outputPorts[ 0 ].DataType == WirePortDataType.COLOR )
  602. {
  603. switch( currentPortId - vectorPortId )
  604. {
  605. case 1: result += ".r"; break;
  606. case 2: result += ".g"; break;
  607. case 3: result += ".b"; break;
  608. case 4: result += ".a"; break;
  609. }
  610. }
  611. else
  612. {
  613. switch( currentPortId - vectorPortId )
  614. {
  615. case 1: result += ".x"; break;
  616. case 2: result += ".y"; break;
  617. case 3: result += ".z"; break;
  618. case 4: result += ".w"; break;
  619. }
  620. }
  621. return result;
  622. }
  623. public void AddOutputColorPorts( string name, bool addAlpha = true )
  624. {
  625. m_sizeIsDirty = true;
  626. //Main port
  627. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, addAlpha ? WirePortDataType.COLOR : WirePortDataType.FLOAT3, name ) );
  628. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  629. //Color components port
  630. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "R" ) );
  631. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  632. m_outputPorts[ m_outputPorts.Count - 1 ].CustomColor = Color.red;
  633. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "G" ) );
  634. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  635. m_outputPorts[ m_outputPorts.Count - 1 ].CustomColor = Color.green;
  636. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "B" ) );
  637. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  638. m_outputPorts[ m_outputPorts.Count - 1 ].CustomColor = Color.blue;
  639. if( addAlpha )
  640. {
  641. m_outputPorts.Add( new OutputPort( m_uniqueId, m_outputPorts.Count, WirePortDataType.FLOAT, "A" ) );
  642. m_outputPortsDict.Add( m_outputPorts[ m_outputPorts.Count - 1 ].PortId, m_outputPorts[ m_outputPorts.Count - 1 ] );
  643. m_outputPorts[ m_outputPorts.Count - 1 ].CustomColor = Color.white;
  644. }
  645. }
  646. public void ConvertFromVectorToColorPorts()
  647. {
  648. m_outputPorts[ 0 ].ChangeType( WirePortDataType.COLOR, false );
  649. m_outputPorts[ 1 ].Name = "R";
  650. m_outputPorts[ 1 ].CustomColor = Color.red;
  651. m_outputPorts[ 2 ].Name = "G";
  652. m_outputPorts[ 2 ].CustomColor = Color.green;
  653. m_outputPorts[ 3 ].Name = "B";
  654. m_outputPorts[ 3 ].CustomColor = Color.blue;
  655. m_outputPorts[ 4 ].Name = "A";
  656. m_outputPorts[ 4 ].CustomColor = Color.white;
  657. }
  658. public string GetOutputColorItem( int vectorPortId, int currentPortId, string result )
  659. {
  660. switch( currentPortId - vectorPortId )
  661. {
  662. case 1: result += ".r"; break;
  663. case 2: result += ".g"; break;
  664. case 3: result += ".b"; break;
  665. case 4: result += ".a"; break;
  666. }
  667. return result;
  668. }
  669. public void ChangeOutputType( WirePortDataType type, bool invalidateConnections )
  670. {
  671. int outputCount = m_outputPorts.Count;
  672. for( int i = 0; i < outputCount; i++ )
  673. {
  674. m_outputPorts[ i ].ChangeType( type, invalidateConnections );
  675. }
  676. }
  677. public void ChangeInputType( WirePortDataType type, bool invalidateConnections )
  678. {
  679. int inputCount = m_inputPorts.Count;
  680. for( int i = 0; i < inputCount; i++ )
  681. {
  682. m_inputPorts[ i ].ChangeType( type, invalidateConnections );
  683. }
  684. }
  685. public void ChangeOutputProperties( int outputID, string newName, WirePortDataType newType, bool invalidateConnections = true )
  686. {
  687. if( outputID < m_outputPorts.Count )
  688. {
  689. m_outputPorts[ outputID ].ChangeProperties( newName, newType, invalidateConnections );
  690. IsDirty = true;
  691. m_sizeIsDirty = true;
  692. SetSaveIsDirty();
  693. }
  694. }
  695. public void ChangeOutputName( int outputArrayIdx, string newName )
  696. {
  697. if( outputArrayIdx < m_outputPorts.Count )
  698. {
  699. m_outputPorts[ outputArrayIdx ].Name = newName;
  700. IsDirty = true;
  701. m_sizeIsDirty = true;
  702. }
  703. }
  704. public InputPort CheckInputPortAt( Vector3 pos )
  705. {
  706. int count = m_inputPorts.Count;
  707. for( int i = 0; i < count; i++ )
  708. {
  709. if( m_inputPorts[ i ].InsideActiveArea( pos ) )
  710. return m_inputPorts[ i ];
  711. }
  712. return null;
  713. }
  714. public InputPort GetFirstInputPortOfType( WirePortDataType dataType, bool countObjectTypeAsValid )
  715. {
  716. int count = m_inputPorts.Count;
  717. for( int i = 0; i < count; i++ )
  718. {
  719. if( ( m_inputPorts[ i ].CheckValidType( dataType ) ) || ( countObjectTypeAsValid && m_inputPorts[ i ].DataType == WirePortDataType.OBJECT ) )
  720. return m_inputPorts[ i ];
  721. }
  722. return null;
  723. }
  724. public OutputPort CheckOutputPortAt( Vector3 pos )
  725. {
  726. int count = m_outputPorts.Count;
  727. for( int i = 0; i < count; i++ )
  728. {
  729. if( m_outputPorts[ i ].InsideActiveArea( pos ) )
  730. return m_outputPorts[ i ];
  731. }
  732. return null;
  733. }
  734. public OutputPort GetFirstOutputPortOfType( WirePortDataType dataType, bool checkForCasts )
  735. {
  736. int count = m_outputPorts.Count;
  737. for( int i = 0; i < count; i++ )
  738. {
  739. if( ( m_outputPorts[ i ].CheckValidType( dataType ) ) || ( checkForCasts && UIUtils.CanCast( dataType, m_outputPorts[ i ].DataType ) ) )
  740. return m_outputPorts[ i ];
  741. }
  742. return null;
  743. }
  744. virtual protected void ChangeSizeFinished() { m_firstPreviewDraw = true; /*MarkForPreviewUpdate();*/ }
  745. protected void ChangeSize()
  746. {
  747. m_cachedPos = m_position;
  748. //UIUtils.ResetMainSkin();
  749. Vector2 inSize = Vector2.zero;
  750. int inputCount = 0;
  751. int inputSize = m_inputPorts.Count;
  752. for( int i = 0; i < inputSize; i++ )
  753. {
  754. if( m_inputPorts[ i ].Visible )
  755. {
  756. if( m_inputPorts[ i ].DirtyLabelSize || m_inputPorts[ i ].LabelSize == Vector2.zero )
  757. {
  758. m_inputPorts[ i ].DirtyLabelSize = false;
  759. m_sizeContentAux.text = m_inputPorts[ i ].Name;
  760. m_inputPorts[ i ].UnscaledLabelSize = UIUtils.UnZoomedInputPortStyle.CalcSize( m_sizeContentAux );
  761. }
  762. inSize.x = Mathf.Max( inSize.x, m_inputPorts[ i ].UnscaledLabelSize.x );
  763. inSize.y = Mathf.Max( inSize.y, m_inputPorts[ i ].UnscaledLabelSize.y );
  764. inputCount += 1;
  765. }
  766. }
  767. if( inSize.x > 0 )
  768. inSize.x += UIUtils.PortsSize.x + Constants.PORT_TO_LABEL_SPACE_X * 2;
  769. inSize.x += m_marginPreviewLeft;
  770. inSize.y = Mathf.Max( inSize.y, UIUtils.PortsSize.y );
  771. Vector2 outSize = Vector2.zero;
  772. int outputCount = 0;
  773. int outputSize = m_outputPorts.Count;
  774. for( int i = 0; i < outputSize; i++ )
  775. {
  776. if( m_outputPorts[ i ].Visible )
  777. {
  778. if( m_outputPorts[ i ].DirtyLabelSize || m_outputPorts[ i ].LabelSize == Vector2.zero )
  779. {
  780. m_outputPorts[ i ].DirtyLabelSize = false;
  781. m_sizeContentAux.text = m_outputPorts[ i ].Name;
  782. m_outputPorts[ i ].UnscaledLabelSize = UIUtils.UnZoomedOutputPortPortStyle.CalcSize( m_sizeContentAux );
  783. }
  784. outSize.x = Mathf.Max( outSize.x, m_outputPorts[ i ].UnscaledLabelSize.x );
  785. outSize.y = Mathf.Max( outSize.y, m_outputPorts[ i ].UnscaledLabelSize.y );
  786. outputCount += 1;
  787. }
  788. }
  789. if( outSize.x > 0 )
  790. outSize.x += UIUtils.PortsSize.x + Constants.PORT_TO_LABEL_SPACE_X * 2;
  791. outSize.y = Mathf.Max( outSize.y, UIUtils.PortsSize.y );
  792. if( m_additionalContent.text.Length > 0 )
  793. {
  794. m_extraHeaderHeight = (int)Constants.NODE_HEADER_EXTRA_HEIGHT;
  795. m_hasSubtitle = true && m_showSubtitle;
  796. }
  797. else
  798. {
  799. m_extraHeaderHeight = 0;
  800. m_hasSubtitle = false;
  801. }
  802. float headerWidth = Mathf.Max( UIUtils.UnZoomedNodeTitleStyle.CalcSize( m_content ).x + m_paddingTitleLeft + m_paddingTitleRight, UIUtils.UnZoomedPropertyValuesTitleStyle.CalcSize( m_additionalContent ).x + m_paddingTitleLeft + m_paddingTitleRight );
  803. m_position.width = Mathf.Max( headerWidth, Mathf.Max( MinInsideBoxWidth, m_insideSize.x ) + inSize.x + outSize.x ) + Constants.NODE_HEADER_LEFTRIGHT_MARGIN * 2;
  804. //m_position.width += m_extraSize.x;
  805. m_fontHeight = Mathf.Max( inSize.y, outSize.y );
  806. m_position.height = Mathf.Max( inputCount, outputCount ) * ( m_fontHeight + Constants.INPUT_PORT_DELTA_Y );// + Constants.INPUT_PORT_DELTA_Y;
  807. m_position.height = Mathf.Max( m_position.height, Mathf.Max( MinInsideBoxHeight, m_insideSize.y ) );
  808. m_position.height += UIUtils.HeaderMaxHeight + m_extraHeaderHeight + Constants.INPUT_PORT_DELTA_Y;// + m_extraSize.y;
  809. if( m_showErrorMessage )
  810. m_position.height += 24;
  811. m_unpreviewedPosition = m_position;
  812. //UIUtils.CurrentWindow.CameraDrawInfo.InvertedZoom = cachedZoom;
  813. if( OnNodeChangeSizeEvent != null )
  814. {
  815. OnNodeChangeSizeEvent( this );
  816. }
  817. ChangeSizeFinished();
  818. }
  819. public virtual void Reset() { }
  820. public virtual void OnOutputPortConnected( int portId, int otherNodeId, int otherPortId ) { }
  821. public virtual void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
  822. {
  823. InputPort port = GetInputPortByUniqueId( portId );
  824. if( activateNode && m_connStatus == NodeConnectionStatus.Connected )
  825. {
  826. port.GetOutputNode().ActivateNode( m_activeNode, m_activePort, m_activeType );
  827. }
  828. OnNodeChange();
  829. SetSaveIsDirty();
  830. }
  831. public virtual void OnInputPortDisconnected( int portId ) { OnNodeChange(); }
  832. public virtual void OnOutputPortDisconnected( int portId ) { }
  833. public virtual void OnNodeChange()
  834. {
  835. CheckSpherePreview();
  836. int count = m_outputPorts.Count;
  837. for( int i = 0; i < count; i++ )
  838. {
  839. if( m_outputPorts[ i ].IsConnected )
  840. {
  841. for( int f = 0; f < m_outputPorts[ i ].ExternalReferences.Count; f++ )
  842. {
  843. m_outputPorts[ i ].GetInputNode( f ).OnNodeChange();
  844. }
  845. }
  846. }
  847. }
  848. public virtual void ActivateNode( int signalGenNodeId, int signalGenPortId, System.Type signalGenNodeType )
  849. {
  850. if( m_selfPowered )
  851. return;
  852. ConnStatus = m_restrictions.GetRestiction( signalGenNodeType, signalGenPortId ) ? NodeConnectionStatus.Error : NodeConnectionStatus.Connected;
  853. m_activeConnections += 1;
  854. if( m_activeConnections == 1 )
  855. {
  856. m_activeType = signalGenNodeType;
  857. m_activeNode = signalGenNodeId;
  858. m_activePort = signalGenPortId;
  859. for( int i = 0; i < m_inputPorts.Count; i++ )
  860. {
  861. if( m_inputPorts[ i ].IsConnected )
  862. {
  863. m_inputPorts[ i ].GetOutputNode().ActivateNode( signalGenNodeId, signalGenPortId, signalGenNodeType );
  864. }
  865. }
  866. }
  867. // saveisdirty might be needed, gonna leave this here for now
  868. // SetSaveIsDirty();
  869. }
  870. public virtual void DeactivateInputPortNode( int deactivatedPort, bool forceComplete )
  871. {
  872. GetInputPortByUniqueId( deactivatedPort ).GetOutputNode().DeactivateNode( deactivatedPort, false );
  873. }
  874. public virtual void DeactivateNode( int deactivatedPort, bool forceComplete )
  875. {
  876. if( m_selfPowered )
  877. return;
  878. // saveisdirty might be needed, gonna leave this here for now
  879. // SetSaveIsDirty();
  880. m_activeConnections -= 1;
  881. if( forceComplete || m_activeConnections <= 0 )
  882. {
  883. m_activeConnections = 0;
  884. ConnStatus = NodeConnectionStatus.Not_Connected;
  885. for( int i = 0; i < m_inputPorts.Count; i++ )
  886. {
  887. if( m_inputPorts[ i ].IsConnected )
  888. {
  889. ParentNode node = m_inputPorts[ i ].GetOutputNode();
  890. if( node != null )
  891. node.DeactivateNode( deactivatedPort == -1 ? m_inputPorts[ i ].PortId : deactivatedPort, false );
  892. }
  893. }
  894. }
  895. }
  896. public Rect GlobalToLocalPosition( DrawInfo drawInfo )
  897. {
  898. float width = m_globalPosition.width / drawInfo.InvertedZoom;
  899. float height = m_globalPosition.height / drawInfo.InvertedZoom;
  900. float x = m_globalPosition.x / drawInfo.InvertedZoom - drawInfo.CameraOffset.x;
  901. float y = m_globalPosition.y / drawInfo.InvertedZoom - drawInfo.CameraOffset.y;
  902. return new Rect( x, y, width, height );
  903. }
  904. protected void CalculatePositionAndVisibility( DrawInfo drawInfo )
  905. {
  906. //m_movingInFrame = false;
  907. m_globalPosition = m_position;
  908. m_globalPosition.x = drawInfo.InvertedZoom * ( m_globalPosition.x + drawInfo.CameraOffset.x );
  909. m_globalPosition.y = drawInfo.InvertedZoom * ( m_globalPosition.y + drawInfo.CameraOffset.y );
  910. m_globalPosition.width *= drawInfo.InvertedZoom;
  911. m_globalPosition.height *= drawInfo.InvertedZoom;
  912. m_isVisible = ( m_globalPosition.x + m_globalPosition.width > 0 ) &&
  913. ( m_globalPosition.x < drawInfo.CameraArea.width ) &&
  914. ( m_globalPosition.y + m_globalPosition.height > 0 ) &&
  915. ( m_globalPosition.y < drawInfo.CameraArea.height );
  916. if( m_isMoving > 0 && drawInfo.CurrentEventType != EventType.MouseDrag )
  917. {
  918. float deltaX = Mathf.Abs( m_lastPosition.x - m_position.x );
  919. float deltaY = Mathf.Abs( m_lastPosition.y - m_position.y );
  920. if( deltaX < 0.01f && deltaY < 0.01f )
  921. {
  922. m_isMoving -= 1;
  923. if( m_isMoving == 0 )
  924. {
  925. OnSelfStoppedMovingEvent();
  926. }
  927. }
  928. else
  929. {
  930. m_isMoving = MoveCountBuffer;
  931. }
  932. m_lastPosition = m_position;
  933. }
  934. }
  935. public void FireStoppedMovingEvent( bool testOnlySelected, InteractionMode interactionMode )
  936. {
  937. if( OnNodeStoppedMovingEvent != null )
  938. OnNodeStoppedMovingEvent( this, testOnlySelected, interactionMode );
  939. }
  940. public virtual void OnSelfStoppedMovingEvent()
  941. {
  942. FireStoppedMovingEvent( true, m_defaultInteractionMode );
  943. }
  944. protected void DrawPrecisionProperty()
  945. {
  946. //m_currentPrecisionType = (PrecisionType)EditorGUILayoutEnumPopup( PrecisionContante, m_currentPrecisionType );
  947. m_currentPrecisionType = (PrecisionType)EditorGUILayoutPopup( PrecisionContent.text, (int)m_currentPrecisionType, PrecisionLabels );
  948. }
  949. public virtual void DrawTitle( Rect titlePos )
  950. {
  951. if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 )
  952. {
  953. GUI.Label( titlePos, m_content, UIUtils.GetCustomStyle( CustomStyle.NodeTitle ) );
  954. }
  955. }
  956. public virtual void DrawPreview( DrawInfo drawInfo, Rect rect )
  957. {
  958. //if ( !m_drawPreview )
  959. // return;
  960. if( m_cachedDrawSphereId == -1 )
  961. m_cachedDrawSphereId = Shader.PropertyToID( "_DrawSphere" );
  962. if( m_cachedInvertedZoomId == -1 )
  963. m_cachedInvertedZoomId = Shader.PropertyToID( "_InvertedZoom" );
  964. m_channelNumber = 0;
  965. Vector4 mask = Vector4.one;
  966. if( m_outputPorts.Count > 0 )
  967. {
  968. switch( m_outputPorts[ 0 ].DataType )
  969. {
  970. case WirePortDataType.FLOAT:
  971. m_channelNumber = 1;
  972. mask.Set( 1, 1, 1, 0 );
  973. break;
  974. case WirePortDataType.FLOAT2:
  975. m_channelNumber = 2;
  976. mask.Set( m_previewChannels[ 0 ] ? 1 : 0, m_previewChannels[ 1 ] ? 1 : 0, 1, 0 );
  977. break;
  978. case WirePortDataType.COLOR:
  979. case WirePortDataType.FLOAT4:
  980. case WirePortDataType.SAMPLER1D:
  981. case WirePortDataType.SAMPLER2D:
  982. case WirePortDataType.SAMPLER3D:
  983. case WirePortDataType.SAMPLERCUBE:
  984. m_channelNumber = 4;
  985. mask.Set( m_previewChannels[ 0 ] ? 1 : 0, m_previewChannels[ 1 ] ? 1 : 0, m_previewChannels[ 2 ] ? 1 : 0, m_previewChannels[ 3 ] ? 1 : 0 );
  986. break;
  987. default:
  988. m_channelNumber = 3;
  989. mask.Set( m_previewChannels[ 0 ] ? 1 : 0, m_previewChannels[ 1 ] ? 1 : 0, m_previewChannels[ 2 ] ? 1 : 0, 0 );
  990. break;
  991. }
  992. }
  993. UIUtils.LinearMaterial.SetFloat( m_cachedDrawSphereId, ( SpherePreview ? 1 : 0 ) );
  994. UIUtils.LinearMaterial.SetFloat( m_cachedInvertedZoomId, drawInfo.InvertedZoom );
  995. UIUtils.LinearMaterial.SetVector( "_Mask", mask );
  996. bool cached = GL.sRGBWrite;
  997. GL.sRGBWrite = true;
  998. //EditorGUI.DrawPreviewTexture( rect, PreviewTexture, UIUtils.LinearMaterial );
  999. int pass = 0;
  1000. if( SpherePreview )
  1001. {
  1002. if( mask.w == 1 )
  1003. pass = 3;
  1004. else
  1005. pass = 1;
  1006. }
  1007. else if( mask.w == 1 )
  1008. pass = 2;
  1009. Graphics.DrawTexture( rect, PreviewTexture, UIUtils.LinearMaterial, pass );
  1010. GL.sRGBWrite = cached;
  1011. //Preview buttons
  1012. if( m_drawPreviewMaskButtons )
  1013. DrawPreviewMaskButtonsRepaint( drawInfo, rect );
  1014. }
  1015. protected void DrawPreviewMaskButtonsLayout( DrawInfo drawInfo, Rect rect )
  1016. {
  1017. if( rect.Contains( drawInfo.MousePosition ) && m_channelNumber > 1 && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 )
  1018. {
  1019. Rect buttonRect = rect;
  1020. buttonRect.height = 14 * drawInfo.InvertedZoom;
  1021. buttonRect.y = rect.yMax - buttonRect.height;
  1022. buttonRect.width = 14 * drawInfo.InvertedZoom;
  1023. if( m_channelNumber == 2 )
  1024. {
  1025. m_previewChannels[ 0 ] = GUI.Toggle( buttonRect, m_previewChannels[ 0 ], string.Empty, GUIStyle.none );
  1026. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1027. m_previewChannels[ 1 ] = GUI.Toggle( buttonRect, m_previewChannels[ 1 ], string.Empty, GUIStyle.none );
  1028. }
  1029. else if( m_channelNumber == 3 )
  1030. {
  1031. m_previewChannels[ 0 ] = GUI.Toggle( buttonRect, m_previewChannels[ 0 ], string.Empty, GUIStyle.none );
  1032. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1033. m_previewChannels[ 1 ] = GUI.Toggle( buttonRect, m_previewChannels[ 1 ], string.Empty, GUIStyle.none );
  1034. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1035. m_previewChannels[ 2 ] = GUI.Toggle( buttonRect, m_previewChannels[ 2 ], string.Empty, GUIStyle.none );
  1036. }
  1037. else if( m_channelNumber == 4 )
  1038. {
  1039. m_previewChannels[ 0 ] = GUI.Toggle( buttonRect, m_previewChannels[ 0 ], string.Empty, GUIStyle.none );
  1040. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1041. m_previewChannels[ 1 ] = GUI.Toggle( buttonRect, m_previewChannels[ 1 ], string.Empty, GUIStyle.none );
  1042. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1043. m_previewChannels[ 2 ] = GUI.Toggle( buttonRect, m_previewChannels[ 2 ], string.Empty, GUIStyle.none );
  1044. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1045. m_previewChannels[ 3 ] = GUI.Toggle( buttonRect, m_previewChannels[ 3 ], string.Empty, GUIStyle.none );
  1046. }
  1047. }
  1048. }
  1049. protected void DrawPreviewMaskButtonsRepaint( DrawInfo drawInfo, Rect rect )
  1050. {
  1051. if( drawInfo.CurrentEventType == EventType.Repaint && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 && rect.Contains( drawInfo.MousePosition ) && m_channelNumber > 1 )
  1052. {
  1053. Rect buttonRect = rect;
  1054. buttonRect.height = 14 * drawInfo.InvertedZoom;
  1055. buttonRect.y = rect.yMax - buttonRect.height;
  1056. buttonRect.width = 14 * drawInfo.InvertedZoom;
  1057. if( m_channelNumber == 2 )
  1058. {
  1059. UIUtils.MiniButtonTopMid.Draw( buttonRect, "R", false, false, m_previewChannels[ 0 ], false );
  1060. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1061. UIUtils.MiniButtonTopRight.Draw( buttonRect, "G", false, false, m_previewChannels[ 1 ], false );
  1062. }
  1063. else if( m_channelNumber == 3 )
  1064. {
  1065. UIUtils.MiniButtonTopMid.Draw( buttonRect, "R", false, false, m_previewChannels[ 0 ], false );
  1066. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1067. UIUtils.MiniButtonTopMid.Draw( buttonRect, "G", false, false, m_previewChannels[ 1 ], false );
  1068. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1069. UIUtils.MiniButtonTopRight.Draw( buttonRect, "B", false, false, m_previewChannels[ 2 ], false );
  1070. }
  1071. else if( m_channelNumber == 4 )
  1072. {
  1073. UIUtils.MiniButtonTopMid.Draw( buttonRect, "R", false, false, m_previewChannels[ 0 ], false );
  1074. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1075. UIUtils.MiniButtonTopMid.Draw( buttonRect, "G", false, false, m_previewChannels[ 1 ], false );
  1076. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1077. UIUtils.MiniButtonTopMid.Draw( buttonRect, "B", false, false, m_previewChannels[ 2 ], false );
  1078. buttonRect.x += 14 * drawInfo.InvertedZoom;
  1079. UIUtils.MiniButtonTopRight.Draw( buttonRect, "A", false, false, m_previewChannels[ 3 ], false );
  1080. }
  1081. }
  1082. }
  1083. public void SetTimedUpdate( double timerInterval )
  1084. {
  1085. m_timedUpdateInitialValue = EditorApplication.timeSinceStartup;
  1086. m_timedUpdateInterval = timerInterval;
  1087. m_fireTimedUpdateRequest = true;
  1088. }
  1089. public virtual void FireTimedUpdate() { }
  1090. /// <summary>
  1091. ///
  1092. /// </summary>
  1093. /// <param name="drawInfo"></param>
  1094. public virtual void OnNodeLogicUpdate( DrawInfo drawInfo )
  1095. {
  1096. if( m_fireTimedUpdateRequest && ( EditorApplication.timeSinceStartup - m_timedUpdateInitialValue ) > m_timedUpdateInterval )
  1097. {
  1098. m_fireTimedUpdateRequest = false;
  1099. FireTimedUpdate();
  1100. }
  1101. if( m_repopulateDictionaries )
  1102. {
  1103. m_repopulateDictionaries = false;
  1104. m_inputPortsDict.Clear();
  1105. int inputCount = m_inputPorts.Count;
  1106. for( int i = 0; i < inputCount; i++ )
  1107. {
  1108. m_inputPortsDict.Add( m_inputPorts[ i ].PortId, m_inputPorts[ i ] );
  1109. }
  1110. m_outputPortsDict.Clear();
  1111. int outputCount = m_outputPorts.Count;
  1112. for( int i = 0; i < outputCount; i++ )
  1113. {
  1114. m_outputPortsDict.Add( m_outputPorts[ i ].PortId, m_outputPorts[ i ] );
  1115. }
  1116. }
  1117. }
  1118. /// <summary>
  1119. /// This method should only be called to calculate layouts of elements to be draw later, only runs once per frame and before wires are drawn
  1120. /// </summary>
  1121. /// <param name="drawInfo"></param>
  1122. public virtual void OnNodeLayout( DrawInfo drawInfo )
  1123. {
  1124. if( ContainerGraph.ChangedLightingModel )
  1125. {
  1126. m_sizeIsDirty = true;
  1127. m_firstPreviewDraw = true;
  1128. }
  1129. if( m_firstDraw )
  1130. {
  1131. m_firstDraw = false;
  1132. AfterCommonInit();
  1133. OnNodeChange();
  1134. }
  1135. if( m_previousErrorMessage != m_showErrorMessage )
  1136. {
  1137. m_sizeIsDirty = true;
  1138. }
  1139. if( m_sizeIsDirty )
  1140. {
  1141. m_sizeIsDirty = false;
  1142. ChangeSize();
  1143. }
  1144. CalculatePositionAndVisibility( drawInfo );
  1145. m_unscaledRemainingBox = m_position;
  1146. m_remainingBox = m_globalPosition;
  1147. m_lastInputBottomRight = m_position.position;
  1148. m_lastOutputBottomLeft = m_position.position;
  1149. m_lastOutputBottomLeft.x += m_position.width;
  1150. m_visibleInputs = 0;
  1151. m_visibleOutputs = 0;
  1152. if( m_hasSubtitle )
  1153. m_extraHeaderHeight = (int)Constants.NODE_HEADER_EXTRA_HEIGHT;
  1154. else
  1155. m_extraHeaderHeight = 0;
  1156. m_lastInputBottomRight.y += UIUtils.HeaderMaxHeight + m_extraHeaderHeight;
  1157. m_lastOutputBottomLeft.y += UIUtils.HeaderMaxHeight + m_extraHeaderHeight;
  1158. m_unscaledRemainingBox.y += UIUtils.HeaderMaxHeight + m_extraHeaderHeight;
  1159. if( m_isVisible )
  1160. {
  1161. // Header
  1162. m_headerPosition = m_globalPosition;
  1163. m_headerPosition.height = UIUtils.CurrentHeaderHeight + m_extraHeaderHeight * drawInfo.InvertedZoom;
  1164. // Title
  1165. m_titlePos = m_globalPosition;
  1166. m_titlePos.height = m_headerPosition.height;
  1167. if( m_hasSubtitle )
  1168. m_titlePos.yMin += ( 4 * drawInfo.InvertedZoom );
  1169. else
  1170. m_titlePos.yMin += ( 7 * drawInfo.InvertedZoom );
  1171. m_titlePos.width -= ( m_paddingTitleLeft + m_paddingTitleRight ) * drawInfo.InvertedZoom;
  1172. m_titlePos.x += m_paddingTitleLeft * drawInfo.InvertedZoom;
  1173. // Additional Title
  1174. if( m_hasSubtitle )
  1175. {
  1176. m_addTitlePos = m_titlePos;
  1177. m_addTitlePos.y = m_globalPosition.y;
  1178. m_addTitlePos.yMin += ( 19 * drawInfo.InvertedZoom );
  1179. }
  1180. // Left Dropdown
  1181. if( m_hasLeftDropdown && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 )
  1182. {
  1183. m_dropdownRect = m_headerPosition;
  1184. m_dropdownRect.width = Constants.NodeButtonSizeX * drawInfo.InvertedZoom;
  1185. m_dropdownRect.x = m_globalPosition.x + ( Constants.IconsLeftRightMargin + 1 ) * drawInfo.InvertedZoom;
  1186. m_dropdownRect.height = Constants.NodeButtonSizeY * drawInfo.InvertedZoom;
  1187. m_dropdownRect.y = m_globalPosition.y + m_headerPosition.height * 0.5f - 14 * drawInfo.InvertedZoom * 0.5f;
  1188. }
  1189. // Expander
  1190. if( m_drawPreviewExpander && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 )
  1191. {
  1192. m_expandRect = m_globalPosition;
  1193. m_expandRect.width = Constants.PreviewExpanderWidth * drawInfo.InvertedZoom;
  1194. m_expandRect.x = m_globalPosition.x + m_globalPosition.width - ( Constants.IconsLeftRightMargin + Constants.PreviewExpanderWidth ) * drawInfo.InvertedZoom; //titlePos.x + titlePos.width;
  1195. m_expandRect.height = Constants.PreviewExpanderHeight * drawInfo.InvertedZoom;
  1196. m_expandRect.y = m_globalPosition.y + m_headerPosition.height * 0.5f - Constants.PreviewExpanderHeight * drawInfo.InvertedZoom * 0.5f;
  1197. }
  1198. }
  1199. if( m_anchorAdjust < 0 )
  1200. {
  1201. m_anchorAdjust = UIUtils.GetCustomStyle( CustomStyle.PortEmptyIcon ).normal.background.width;
  1202. }
  1203. m_unscaledRemainingBox.y += Constants.INPUT_PORT_DELTA_Y;
  1204. m_lastOutputBottomLeft.y += Constants.INPUT_PORT_DELTA_Y;
  1205. m_lastInputBottomRight.y += Constants.INPUT_PORT_DELTA_Y;
  1206. // Input Ports
  1207. {
  1208. m_currInputPortPos = m_globalPosition;
  1209. m_currInputPortPos.width = drawInfo.InvertedZoom * UIUtils.PortsSize.x;
  1210. m_currInputPortPos.height = drawInfo.InvertedZoom * UIUtils.PortsSize.y;
  1211. m_currInputPortPos.x += drawInfo.InvertedZoom * Constants.PORT_INITIAL_X;
  1212. m_currInputPortPos.y += drawInfo.InvertedZoom * Constants.PORT_INITIAL_Y + m_extraHeaderHeight * drawInfo.InvertedZoom;
  1213. int inputCount = m_inputPorts.Count;
  1214. float initialX = m_lastInputBottomRight.x;
  1215. for( int i = 0; i < inputCount; i++ )
  1216. {
  1217. if( m_inputPorts[ i ].Visible )
  1218. {
  1219. m_visibleInputs++;
  1220. // Button
  1221. m_inputPorts[ i ].Position = m_currInputPortPos;
  1222. // Label
  1223. m_inputPorts[ i ].LabelPosition = m_currInputPortPos;
  1224. float deltaX = 1f * drawInfo.InvertedZoom * ( UIUtils.PortsSize.x + Constants.PORT_TO_LABEL_SPACE_X );
  1225. m_auxRect = m_inputPorts[ i ].LabelPosition;
  1226. m_auxRect.x += deltaX;
  1227. m_inputPorts[ i ].LabelPosition = m_auxRect;
  1228. //if( m_inputPorts[ i ].DirtyLabelSize || m_inputPorts[ i ].LabelSize == Vector2.zero )
  1229. //{
  1230. // m_inputPorts[ i ].DirtyLabelSize = false;
  1231. // m_sizeContentAux.text = m_inputPorts[ i ].Name;
  1232. // m_inputPorts[ i ].UnscaledLabelSize = UIUtils.UnZoomedInputPortStyle.CalcSize( m_sizeContentAux );
  1233. //}
  1234. m_inputPorts[ i ].LabelSize = m_inputPorts[ i ].UnscaledLabelSize * drawInfo.InvertedZoom;
  1235. m_lastInputBottomRight.x = Mathf.Max( m_lastInputBottomRight.x, initialX + m_inputPorts[ i ].UnscaledLabelSize.x + Constants.PORT_INITIAL_X + Constants.PORT_TO_LABEL_SPACE_X + UIUtils.PortsSize.x );
  1236. if( !m_inputPorts[ i ].Locked )
  1237. {
  1238. float overflow = 2;
  1239. float scaledOverflow = 4 * drawInfo.InvertedZoom;
  1240. m_auxRect = m_currInputPortPos;
  1241. m_auxRect.yMin -= scaledOverflow + overflow;
  1242. m_auxRect.yMax += scaledOverflow + overflow;
  1243. m_auxRect.xMin -= Constants.PORT_INITIAL_X * drawInfo.InvertedZoom + scaledOverflow + overflow;
  1244. if( m_containerGraph.ParentWindow.WireReferenceUtils.OutputPortReference.IsValid )
  1245. m_auxRect.xMax += m_inputPorts[ i ].LabelSize.x + Constants.PORT_TO_LABEL_SPACE_X * drawInfo.InvertedZoom + scaledOverflow + overflow;
  1246. else
  1247. m_auxRect.xMax += Constants.PORT_TO_LABEL_SPACE_X * drawInfo.InvertedZoom + scaledOverflow + overflow;
  1248. m_inputPorts[ i ].ActivePortArea = m_auxRect;
  1249. }
  1250. m_currInputPortPos.y += drawInfo.InvertedZoom * ( m_fontHeight + Constants.INPUT_PORT_DELTA_Y );
  1251. //GUI.Label( m_inputPorts[ i ].ActivePortArea, string.Empty, UIUtils.Box );
  1252. }
  1253. }
  1254. if( m_visibleInputs > 0 )
  1255. m_lastInputBottomRight.y += m_fontHeight * m_visibleInputs + Constants.INPUT_PORT_DELTA_Y * ( m_visibleInputs - 1 );
  1256. }
  1257. // Output Ports
  1258. {
  1259. m_currOutputPortPos = m_globalPosition;
  1260. m_currOutputPortPos.width = drawInfo.InvertedZoom * UIUtils.PortsSize.x;
  1261. m_currOutputPortPos.height = drawInfo.InvertedZoom * UIUtils.PortsSize.y;
  1262. m_currOutputPortPos.x += ( m_globalPosition.width - drawInfo.InvertedZoom * ( Constants.PORT_INITIAL_X + m_anchorAdjust ) );
  1263. m_currOutputPortPos.y += drawInfo.InvertedZoom * Constants.PORT_INITIAL_Y + m_extraHeaderHeight * drawInfo.InvertedZoom;
  1264. int outputCount = m_outputPorts.Count;
  1265. float initialX = m_lastOutputBottomLeft.x;
  1266. for( int i = 0; i < outputCount; i++ )
  1267. {
  1268. if( m_outputPorts[ i ].Visible )
  1269. {
  1270. m_visibleOutputs++;
  1271. //Button
  1272. m_outputPorts[ i ].Position = m_currOutputPortPos;
  1273. // Label
  1274. m_outputPorts[ i ].LabelPosition = m_currOutputPortPos;
  1275. float deltaX = 1f * drawInfo.InvertedZoom * ( UIUtils.PortsSize.x + Constants.PORT_TO_LABEL_SPACE_X );
  1276. m_auxRect = m_outputPorts[ i ].LabelPosition;
  1277. m_auxRect.x -= deltaX;
  1278. m_outputPorts[ i ].LabelPosition = m_auxRect;
  1279. m_outputPorts[ i ].LabelSize = m_outputPorts[ i ].UnscaledLabelSize * drawInfo.InvertedZoom;
  1280. m_lastOutputBottomLeft.x = Mathf.Min( m_lastOutputBottomLeft.x, initialX - m_outputPorts[ i ].UnscaledLabelSize.x - Constants.PORT_INITIAL_X - Constants.PORT_TO_LABEL_SPACE_X - UIUtils.PortsSize.x );
  1281. if( !m_outputPorts[ i ].Locked )
  1282. {
  1283. float overflow = 2;
  1284. float scaledOverflow = 4 * drawInfo.InvertedZoom;
  1285. m_auxRect = m_currOutputPortPos;
  1286. m_auxRect.yMin -= scaledOverflow + overflow;
  1287. m_auxRect.yMax += scaledOverflow + overflow;
  1288. if( m_containerGraph.ParentWindow.WireReferenceUtils.InputPortReference.IsValid )
  1289. m_auxRect.xMin -= m_outputPorts[ i ].LabelSize.x + Constants.PORT_TO_LABEL_SPACE_X * drawInfo.InvertedZoom + scaledOverflow + overflow;
  1290. else
  1291. m_auxRect.xMin -= Constants.PORT_TO_LABEL_SPACE_X * drawInfo.InvertedZoom + scaledOverflow + overflow;
  1292. m_auxRect.xMax += Constants.PORT_INITIAL_X * drawInfo.InvertedZoom + scaledOverflow + overflow;
  1293. m_outputPorts[ i ].ActivePortArea = m_auxRect;
  1294. }
  1295. m_currOutputPortPos.y += drawInfo.InvertedZoom * ( m_fontHeight + Constants.INPUT_PORT_DELTA_Y );
  1296. //GUI.Label( m_outputPorts[ i ].ActivePortArea, string.Empty, UIUtils.Box );
  1297. }
  1298. }
  1299. if( m_visibleOutputs > 0 )
  1300. m_lastOutputBottomLeft.y += m_fontHeight * m_visibleOutputs + Constants.INPUT_PORT_DELTA_Y * ( m_visibleOutputs - 1 );
  1301. }
  1302. m_lastInputBottomRight.x += m_marginPreviewLeft;
  1303. //Vector2 scaledLastOutputBottomLeft = ( m_lastOutputBottomLeft + drawInfo.CameraOffset ) * drawInfo.InvertedZoom;
  1304. //GUI.Label( new Rect( scaledLastOutputBottomLeft, Vector2.one * 2 ), string.Empty, UIUtils.CurrentWindow.CustomStylesInstance.Box );
  1305. m_unscaledRemainingBox.xMin = m_lastInputBottomRight.x;
  1306. //m_unscaledRemainingBox.yMin = m_lastInputBottomRight.y;
  1307. m_unscaledRemainingBox.xMax = m_lastOutputBottomLeft.x;
  1308. m_unscaledRemainingBox.yMax = Mathf.Max( m_lastOutputBottomLeft.y, m_lastInputBottomRight.y );
  1309. m_remainingBox.position = ( m_unscaledRemainingBox.position + drawInfo.CameraOffset ) * drawInfo.InvertedZoom;
  1310. m_remainingBox.size = m_unscaledRemainingBox.size * drawInfo.InvertedZoom;
  1311. //GUI.Label( m_remainingBox, string.Empty, UIUtils.Box );
  1312. if( m_visibleInputs == 0 )
  1313. {
  1314. m_remainingBox.x += Constants.PORT_INITIAL_X * drawInfo.InvertedZoom;
  1315. m_remainingBox.width -= Constants.PORT_INITIAL_X * drawInfo.InvertedZoom;
  1316. }
  1317. if( m_visibleOutputs == 0 )
  1318. {
  1319. m_remainingBox.width -= Constants.PORT_INITIAL_X * drawInfo.InvertedZoom;
  1320. }
  1321. if( ContainerGraph.ParentWindow.GlobalPreview != m_globalShowPreview )
  1322. {
  1323. m_globalShowPreview = ContainerGraph.ParentWindow.GlobalPreview;
  1324. m_sizeIsDirty = true;
  1325. }
  1326. // Generate Proper Preview Rect
  1327. float marginAround = 10;
  1328. float scaledMarginAround = marginAround * drawInfo.InvertedZoom;
  1329. float previewSize = 128;
  1330. PreviewLocation m_autoLocation = m_selectedLocation;
  1331. if( m_selectedLocation == PreviewLocation.Auto )
  1332. {
  1333. if( m_visibleOutputs > m_visibleInputs )
  1334. {
  1335. m_autoLocation = PreviewLocation.Left;
  1336. }
  1337. else if( m_visibleOutputs < m_visibleInputs )
  1338. {
  1339. m_autoLocation = PreviewLocation.Right;
  1340. }
  1341. else if( m_unscaledRemainingBox.width > previewSize )
  1342. {
  1343. m_autoLocation = PreviewLocation.TopCenter;
  1344. }
  1345. else
  1346. {
  1347. m_autoLocation = PreviewLocation.BottomCenter;
  1348. }
  1349. }
  1350. if( m_canExpand && ( m_showPreview || m_globalShowPreview ) )
  1351. {
  1352. if( m_autoLocation == PreviewLocation.TopCenter )
  1353. {
  1354. m_unscaledPreviewRect.y = m_unscaledRemainingBox.y;
  1355. m_unscaledPreviewRect.x = m_unscaledRemainingBox.center.x - 0.5f * ( previewSize + 2 * marginAround );
  1356. }
  1357. else if( m_autoLocation == PreviewLocation.BottomCenter )
  1358. {
  1359. m_unscaledPreviewRect.y = Mathf.Max( m_lastOutputBottomLeft.y, m_lastInputBottomRight.y );
  1360. m_unscaledPreviewRect.x = m_position.x + 0.5f * m_position.width - 0.5f * ( previewSize + 2 * marginAround );
  1361. }
  1362. else if( m_autoLocation == PreviewLocation.Left )
  1363. {
  1364. m_unscaledPreviewRect.y = m_lastInputBottomRight.y;
  1365. m_unscaledPreviewRect.x = m_position.x;
  1366. }
  1367. else if( m_autoLocation == PreviewLocation.Right )
  1368. {
  1369. m_unscaledPreviewRect.y = m_lastOutputBottomLeft.y;
  1370. m_unscaledPreviewRect.x = m_lastInputBottomRight.x;
  1371. }
  1372. if( m_autoLocation == PreviewLocation.BottomCenter )
  1373. m_unscaledPreviewRect.height = previewSize + 2 * marginAround;
  1374. else if( m_autoLocation == PreviewLocation.TopCenter )
  1375. m_unscaledPreviewRect.height = previewSize + marginAround;
  1376. else
  1377. m_unscaledPreviewRect.height = previewSize + ( m_visibleInputs > 0 && m_visibleOutputs > 0 ? 2 * marginAround : marginAround );
  1378. m_unscaledPreviewRect.width = previewSize + 2 * marginAround;
  1379. m_previewRect = m_unscaledPreviewRect;
  1380. m_previewRect.position = ( m_previewRect.position + drawInfo.CameraOffset ) * drawInfo.InvertedZoom;
  1381. m_auxVector2.Set( previewSize * drawInfo.InvertedZoom, previewSize * drawInfo.InvertedZoom );
  1382. m_previewRect.size = m_auxVector2;
  1383. if( m_autoLocation == PreviewLocation.BottomCenter )
  1384. {
  1385. m_auxVector2.Set( m_previewRect.position.x + scaledMarginAround, m_previewRect.position.y + scaledMarginAround );
  1386. m_previewRect.position = m_auxVector2;
  1387. }
  1388. else if( m_autoLocation == PreviewLocation.TopCenter )
  1389. {
  1390. m_auxVector2.Set( m_previewRect.position.x + scaledMarginAround, m_previewRect.position.y );
  1391. m_previewRect.position = m_auxVector2;
  1392. }
  1393. else
  1394. {
  1395. m_previewRect.position += new Vector2( scaledMarginAround, ( m_visibleInputs > 0 && m_visibleOutputs > 0 ? scaledMarginAround : 0 ) );
  1396. }
  1397. }
  1398. // Adjust node rect after preview
  1399. if( m_firstPreviewDraw )
  1400. {
  1401. m_firstPreviewDraw = false;
  1402. if( m_canExpand && ( m_showPreview || m_globalShowPreview ) )
  1403. {
  1404. if( m_autoLocation == PreviewLocation.TopCenter )
  1405. {
  1406. float fillWidth = m_unscaledRemainingBox.width - m_unscaledPreviewRect.width;
  1407. m_extraSize.x = Mathf.Max( -fillWidth, 0 );
  1408. float fillHeight = m_position.yMax - m_unscaledPreviewRect.yMax;
  1409. m_extraSize.y = Mathf.Max( -fillHeight, 0 );
  1410. }
  1411. if( m_autoLocation == PreviewLocation.BottomCenter )
  1412. {
  1413. float fillWidth = m_position.width - m_unscaledPreviewRect.width;
  1414. m_extraSize.x = Mathf.Max( -fillWidth, 0 );
  1415. float fillHeight = m_position.yMax - m_unscaledPreviewRect.yMax;
  1416. m_extraSize.y = Mathf.Max( -fillHeight, 0 );
  1417. }
  1418. else if( m_autoLocation == PreviewLocation.Left )
  1419. {
  1420. float fillWidth = m_lastOutputBottomLeft.x - m_unscaledPreviewRect.xMax;
  1421. m_extraSize.x = Mathf.Max( -fillWidth, 0 );
  1422. float fillHeight = m_position.yMax - m_unscaledPreviewRect.yMax;
  1423. m_extraSize.y = Mathf.Max( -fillHeight, 0 );
  1424. }
  1425. else if( m_autoLocation == PreviewLocation.Right )
  1426. {
  1427. float fillWidth = m_position.xMax - m_unscaledPreviewRect.xMax;
  1428. m_extraSize.x = Mathf.Max( -fillWidth, 0 );
  1429. float fillHeight = m_position.yMax - m_unscaledPreviewRect.yMax;
  1430. m_extraSize.y = Mathf.Max( -fillHeight, 0 );
  1431. }
  1432. if( m_showErrorMessage )
  1433. m_extraSize.y += 24;
  1434. }
  1435. else if( m_canExpand )
  1436. {
  1437. m_extraSize.y = 0;
  1438. m_extraSize.x = 0;
  1439. }
  1440. m_position.width = m_unpreviewedPosition.width + m_extraSize.x;
  1441. m_position.height = m_unpreviewedPosition.height + m_extraSize.y;
  1442. }
  1443. if( m_showErrorMessage )
  1444. {
  1445. m_errorBox = m_globalPosition;
  1446. m_errorBox.y = ( m_globalPosition.yMax - 28 * drawInfo.InvertedZoom ) + 3 * drawInfo.InvertedZoom;
  1447. m_errorBox.height = 25 * drawInfo.InvertedZoom;
  1448. }
  1449. m_previousErrorMessage = m_showErrorMessage;
  1450. }
  1451. /// <summary>
  1452. /// This method should only be called to draw elements, runs once per frame and after wires are drawn
  1453. /// </summary>
  1454. /// <param name="drawInfo"></param>
  1455. public virtual void OnNodeRepaint( DrawInfo drawInfo )
  1456. {
  1457. if( !m_isVisible )
  1458. return;
  1459. m_colorBuffer = GUI.color;
  1460. // Background
  1461. GUI.color = m_infiniteLoopDetected ? Constants.InfiniteLoopColor : Constants.NodeBodyColor;
  1462. if( m_useSquareNodeTitle || ContainerGraph.LodLevel >= ParentGraph.NodeLOD.LOD2 )
  1463. GUI.Label( m_globalPosition, string.Empty, UIUtils.NodeWindowOffSquare );
  1464. else
  1465. GUI.Label( m_globalPosition, string.Empty, UIUtils.GetCustomStyle( CustomStyle.NodeWindowOff ) );
  1466. // Header
  1467. //GUI
  1468. GUI.color = m_headerColor * m_headerColorModifier;
  1469. if( m_useSquareNodeTitle || ContainerGraph.LodLevel >= ParentGraph.NodeLOD.LOD2 )
  1470. GUI.Label( m_headerPosition, string.Empty, UIUtils.NodeHeaderSquare );
  1471. else
  1472. GUI.Label( m_headerPosition, string.Empty, UIUtils.GetCustomStyle( CustomStyle.NodeHeader ) );
  1473. GUI.color = m_colorBuffer;
  1474. // Title
  1475. DrawTitle( m_titlePos );
  1476. // Additional Tile
  1477. if( m_hasSubtitle && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 )
  1478. GUI.Label( m_addTitlePos, m_additionalContent, UIUtils.GetCustomStyle( CustomStyle.PropertyValuesTitle ) );
  1479. // Dropdown
  1480. if( m_hasLeftDropdown && !m_dropdownEditing && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 )
  1481. GUI.Label( m_dropdownRect, string.Empty, UIUtils.PropertyPopUp );
  1482. // Expander
  1483. if( m_drawPreviewExpander && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 )
  1484. GUI.Label( m_expandRect, string.Empty, ( m_showPreview ? UIUtils.PreviewCollapser : UIUtils.PreviewExpander ) );
  1485. // Input Ports
  1486. int inputCount = m_inputPorts.Count;
  1487. for( int i = 0; i < inputCount; i++ )
  1488. {
  1489. if( m_inputPorts[ i ].Visible )
  1490. {
  1491. // Input Port Icon
  1492. if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 )
  1493. {
  1494. if( m_inputPorts[ i ].Locked )
  1495. GUI.color = Constants.LockedPortColor;
  1496. else if( ContainerGraph.ParentWindow.Options.ColoredPorts )
  1497. GUI.color = UIUtils.GetColorForDataType( m_inputPorts[ i ].DataType, false, true );
  1498. else
  1499. GUI.color = m_inputPorts[ i ].HasCustomColor ? m_inputPorts[ i ].CustomColor : UIUtils.GetColorForDataType( m_inputPorts[ i ].DataType, true, true );
  1500. GUIStyle style = m_inputPorts[ i ].IsConnected ? UIUtils.GetCustomStyle( CustomStyle.PortFullIcon ) : UIUtils.GetCustomStyle( CustomStyle.PortEmptyIcon );
  1501. GUI.Label( m_inputPorts[ i ].Position, string.Empty, style );
  1502. GUI.color = m_colorBuffer;
  1503. }
  1504. // Input Port Label
  1505. if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 )
  1506. {
  1507. if( m_inputPorts[ i ].Locked )
  1508. {
  1509. GUI.color = Constants.PortLockedTextColor;
  1510. GUI.Label( m_inputPorts[ i ].LabelPosition, m_inputPorts[ i ].Name, UIUtils.InputPortLabel );
  1511. GUI.color = m_colorBuffer;
  1512. }
  1513. else
  1514. {
  1515. if( m_containerGraph.ParentWindow.GlobalShowInternalData && !m_inputPorts[ i ].IsConnected && UIUtils.InternalDataOnPort.fontSize > 1f && ( m_inputPorts[ i ].AutoDrawInternalData || ( m_autoDrawInternalPortData && m_useInternalPortData ) ) && m_inputPorts[ i ].DisplayInternalData.Length > 4 )
  1516. {
  1517. GUI.color = Constants.NodeBodyColor/* * new Color( 1f, 1f, 1f, 0.75f )*/;
  1518. Rect internalBox = m_inputPorts[ i ].LabelPosition;
  1519. m_sizeContentAux.text = m_inputPorts[ i ].DisplayInternalData;
  1520. Vector2 portText = UIUtils.InternalDataOnPort.CalcSize( m_sizeContentAux );
  1521. internalBox.width = portText.x;
  1522. internalBox.height = portText.y;
  1523. internalBox.y = m_inputPorts[ i ].LabelPosition.center.y - internalBox.height * 0.5f;
  1524. internalBox.x = GlobalPosition.x - internalBox.width - 4 * drawInfo.InvertedZoom - 1;
  1525. Rect backBox = new Rect( internalBox );
  1526. backBox.xMin -= 4 * drawInfo.InvertedZoom;
  1527. backBox.xMax += 4 * drawInfo.InvertedZoom;
  1528. backBox.yMin -= 2 * drawInfo.InvertedZoom;
  1529. backBox.yMax += 2 * drawInfo.InvertedZoom;
  1530. GUI.Label( backBox, string.Empty, UIUtils.InternalDataBackground );
  1531. GUI.color *= new Color( 1f, 1f, 1f, 0.5f );
  1532. GUI.Label( internalBox, m_sizeContentAux, UIUtils.InternalDataOnPort );
  1533. GUI.color = m_colorBuffer;
  1534. }
  1535. GUI.Label( m_inputPorts[ i ].LabelPosition, m_inputPorts[ i ].Name, UIUtils.InputPortLabel );
  1536. }
  1537. }
  1538. }
  1539. }
  1540. // Output Ports
  1541. int outputCount = m_outputPorts.Count;
  1542. for( int i = 0; i < outputCount; i++ )
  1543. {
  1544. if( m_outputPorts[ i ].Visible )
  1545. {
  1546. // Output Port Icon
  1547. if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD4 )
  1548. {
  1549. if( m_outputPorts[ i ].Locked )
  1550. GUI.color = Constants.LockedPortColor;
  1551. else if( ContainerGraph.ParentWindow.Options.ColoredPorts )
  1552. GUI.color = UIUtils.GetColorForDataType( m_outputPorts[ i ].DataType, false, false );
  1553. else
  1554. GUI.color = m_outputPorts[ i ].HasCustomColor ? m_outputPorts[ i ].CustomColor : UIUtils.GetColorForDataType( m_outputPorts[ i ].DataType, true, false );
  1555. GUIStyle style = m_outputPorts[ i ].IsConnected ? UIUtils.GetCustomStyle( CustomStyle.PortFullIcon ) : UIUtils.GetCustomStyle( CustomStyle.PortEmptyIcon );
  1556. GUI.Label( m_outputPorts[ i ].Position, string.Empty, style );
  1557. GUI.color = m_colorBuffer;
  1558. }
  1559. // Output Port Label
  1560. if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 )
  1561. {
  1562. if( m_outputPorts[ i ].Locked )
  1563. {
  1564. GUI.color = Constants.PortLockedTextColor;
  1565. GUI.Label( m_outputPorts[ i ].LabelPosition, m_outputPorts[ i ].Name, UIUtils.OutputPortLabel );
  1566. GUI.color = m_colorBuffer;
  1567. }
  1568. else
  1569. {
  1570. GUI.Label( m_outputPorts[ i ].LabelPosition, m_outputPorts[ i ].Name, UIUtils.OutputPortLabel );
  1571. }
  1572. }
  1573. }
  1574. }
  1575. // Preview
  1576. if( ( m_showPreview || m_globalShowPreview ) && m_drawPreview )
  1577. DrawPreview( drawInfo, m_previewRect );
  1578. // Error and Warning bottom message
  1579. if( m_showErrorMessage )
  1580. {
  1581. GUI.color = new Color( 0.0f, 0.0f, 0.0f, 0.5f );
  1582. GUI.Label( m_errorBox, string.Empty, UIUtils.Separator );
  1583. GUI.color = m_colorBuffer;
  1584. switch( m_errorMessageTypeIsError )
  1585. {
  1586. default:
  1587. case NodeMessageType.Error:
  1588. {
  1589. m_errorMessage.text = ErrorTitle;
  1590. m_errorIcon.image = UIUtils.SmallErrorIcon;
  1591. m_errorCurrentStyle = UIUtils.BoldErrorStyle;
  1592. }
  1593. break;
  1594. case NodeMessageType.Warning:
  1595. {
  1596. m_errorMessage.text = WarningTitle;
  1597. m_errorIcon.image = UIUtils.SmallWarningIcon;
  1598. m_errorCurrentStyle = UIUtils.BoldWarningStyle;
  1599. }
  1600. break;
  1601. case NodeMessageType.Info:
  1602. {
  1603. m_errorMessage.text = InfoTitle;
  1604. m_errorIcon.image = UIUtils.SmallInfoIcon;
  1605. m_errorCurrentStyle = UIUtils.BoldInfoStyle;
  1606. }
  1607. break;
  1608. }
  1609. Rect textBox = m_errorBox;
  1610. textBox.y += 1 * drawInfo.InvertedZoom;
  1611. textBox.height = 24 * drawInfo.InvertedZoom;
  1612. float textWidth = m_errorCurrentStyle.CalcSize( m_errorMessage ).x;
  1613. GUI.Label( textBox, m_errorMessage, m_errorCurrentStyle );
  1614. textBox.x -= textWidth * 0.5f + 12 * drawInfo.InvertedZoom;
  1615. GUI.Label( textBox, m_errorIcon, m_errorCurrentStyle );
  1616. textBox.x += textWidth + 24 * drawInfo.InvertedZoom;
  1617. GUI.Label( textBox, m_errorIcon, m_errorCurrentStyle );
  1618. }
  1619. // Selection Box
  1620. if( m_selected )
  1621. {
  1622. GUI.color = Constants.NodeSelectedColor;
  1623. if( m_useSquareNodeTitle || ContainerGraph.LodLevel >= ParentGraph.NodeLOD.LOD2 )
  1624. GUI.Label( m_globalPosition, string.Empty, UIUtils.NodeWindowOnSquare );
  1625. else
  1626. GUI.Label( m_globalPosition, string.Empty, UIUtils.GetCustomStyle( CustomStyle.NodeWindowOn ) );
  1627. GUI.color = m_colorBuffer;
  1628. }
  1629. // Debug Visualizers
  1630. //GUI.Label( m_remainingBox, string.Empty, UIUtils.Box );
  1631. }
  1632. public bool DropdownEditing { get { return m_dropdownEditing; } set { m_dropdownEditing = value; } }
  1633. /// <summary>
  1634. /// Handles gui controls, runs before node layout
  1635. /// </summary>
  1636. /// <param name="drawInfo"></param>
  1637. public virtual void DrawGUIControls( DrawInfo drawInfo )
  1638. {
  1639. if( !m_initialized )
  1640. return;
  1641. if( !m_isVisible )
  1642. return;
  1643. if( drawInfo.CurrentEventType == EventType.MouseDown && drawInfo.LeftMouseButtonPressed )
  1644. {
  1645. if( m_expandRect.Contains( drawInfo.MousePosition ) )
  1646. {
  1647. m_showPreview = !m_showPreview;
  1648. m_sizeIsDirty = true;
  1649. ContainerGraph.ParentWindow.MouseInteracted = true;
  1650. }
  1651. if( m_hasLeftDropdown && m_dropdownRect.Contains( drawInfo.MousePosition ) )
  1652. {
  1653. m_dropdownEditing = true;
  1654. }
  1655. else if( m_dropdownEditing )
  1656. {
  1657. m_dropdownEditing = false;
  1658. }
  1659. }
  1660. DrawGuiPorts( drawInfo );
  1661. }
  1662. //public static bool MyRepeatButton( DrawInfo drawInfo, Rect position, string text, GUIStyle style )
  1663. //{
  1664. // if(/* drawInfo.CurrentEventType == EventType.MouseDown &&*/ position.Contains( drawInfo.MousePosition ) )
  1665. // {
  1666. // UIUtils.CurrentWindow.MouseInteracted = true;
  1667. // return true;
  1668. // }
  1669. // return false;
  1670. //}
  1671. public void DrawGuiPorts( DrawInfo drawInfo )
  1672. {
  1673. if( !m_initialized )
  1674. return;
  1675. if( !m_isVisible )
  1676. return;
  1677. if( drawInfo.CurrentEventType == EventType.MouseDown )
  1678. {
  1679. int inputCount = m_inputPorts.Count;
  1680. int outputCount = m_outputPorts.Count;
  1681. for( int i = 0; i < inputCount; i++ )
  1682. {
  1683. if( m_inputPorts[ i ].Visible && !m_inputPorts[ i ].Locked && m_isVisible && m_inputPorts[ i ].ActivePortArea.Contains( drawInfo.MousePosition ) && drawInfo.LeftMouseButtonPressed )
  1684. {
  1685. UIUtils.CurrentWindow.MouseInteracted = true;
  1686. m_inputPorts[ i ].Click();
  1687. // need to put the mouse button on a hot state so it will detect the Mouse Up event correctly on the Editor Window
  1688. int controlID = GUIUtility.GetControlID( FocusType.Passive );
  1689. //int controlID = GUIUtility.GetControlID( "repeatButton".GetHashCode(), FocusType.Passive, m_inputPorts[ i ].ActivePortArea );
  1690. GUIUtility.hotControl = controlID;
  1691. bool saveReference = true;
  1692. if( m_inputPorts[ i ].IsConnected )
  1693. {
  1694. double doubleTapTime = EditorApplication.timeSinceStartup;
  1695. bool doubleTap = ( doubleTapTime - m_doubleClickTimestamp ) < DoubleClickTime;
  1696. m_doubleClickTimestamp = doubleTapTime;
  1697. if( doubleTap )
  1698. {
  1699. m_containerGraph.DeleteConnection( true, UniqueId, m_inputPorts[ i ].PortId, true, true );
  1700. Event.current.Use();
  1701. }
  1702. else
  1703. //if ( AppyModifierToPort( _inputPorts[ i ], true ) )
  1704. //{
  1705. //saveReference = false;
  1706. //}
  1707. if( !ApplyModifierToPort( m_inputPorts[ i ], true ) )
  1708. {
  1709. UIUtils.ShowContextOnPick = false;
  1710. PickInput( m_inputPorts[ i ] );
  1711. }
  1712. saveReference = false;
  1713. }
  1714. if( saveReference && !m_containerGraph.ParentWindow.WireReferenceUtils.InputPortReference.IsValid )
  1715. //if ( !modifierApplied && !UIUtils.InputPortReference.IsValid )
  1716. {
  1717. m_containerGraph.ParentWindow.WireReferenceUtils.SetInputReference( m_uniqueId, m_inputPorts[ i ].PortId, m_inputPorts[ i ].DataType, m_inputPorts[ i ].TypeLocked );
  1718. }
  1719. IsDirty = true;
  1720. inputCount = m_inputPorts.Count;
  1721. }
  1722. }
  1723. for( int i = 0; i < outputCount; i++ )
  1724. {
  1725. if( m_outputPorts[ i ].Visible && m_outputPorts[ i ].ActivePortArea.Contains( drawInfo.MousePosition ) && drawInfo.LeftMouseButtonPressed )
  1726. {
  1727. UIUtils.CurrentWindow.MouseInteracted = true;
  1728. m_outputPorts[ i ].Click();
  1729. // need to put the mouse button on a hot state so it will detect the Mouse Up event correctly on the Editor Window
  1730. int controlID = GUIUtility.GetControlID( FocusType.Passive );
  1731. //int controlID = GUIUtility.GetControlID( "aseRepeatButton".GetHashCode(), FocusType.Passive, m_outputPorts[ i ].ActivePortArea );
  1732. GUIUtility.hotControl = controlID;
  1733. bool saveReference = true;
  1734. if( m_outputPorts[ i ].IsConnected )
  1735. {
  1736. if( ApplyModifierToPort( m_outputPorts[ i ], false ) )
  1737. {
  1738. saveReference = false;
  1739. }
  1740. }
  1741. if( saveReference && !m_containerGraph.ParentWindow.WireReferenceUtils.OutputPortReference.IsValid )
  1742. {
  1743. m_containerGraph.ParentWindow.WireReferenceUtils.SetOutputReference( m_uniqueId, m_outputPorts[ i ].PortId, m_outputPorts[ i ].DataType, false );
  1744. }
  1745. IsDirty = true;
  1746. outputCount = m_outputPorts.Count;
  1747. }
  1748. }
  1749. }
  1750. //Preview buttons
  1751. if( m_drawPreviewMaskButtons && ( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp ) )
  1752. DrawPreviewMaskButtonsLayout( drawInfo, m_previewRect );
  1753. }
  1754. /// <summary>
  1755. /// Can be used to draw an entire node, runs after wires
  1756. /// </summary>
  1757. /// <param name="drawInfo"></param>
  1758. public virtual void Draw( DrawInfo drawInfo )
  1759. {
  1760. if( !m_initialized )
  1761. return;
  1762. if( drawInfo.CurrentEventType == EventType.Repaint )
  1763. OnNodeRepaint( drawInfo );
  1764. }
  1765. public virtual void SetPreviewInputs()
  1766. {
  1767. if( !HasPreviewShader || !m_initialized )
  1768. return;
  1769. int count = m_inputPorts.Count;
  1770. for( int i = 0; i < count; i++ )
  1771. {
  1772. if( m_inputPorts[ i ].IsConnected && m_inputPorts[ i ].InputNodeHasPreview() )
  1773. {
  1774. m_inputPorts[ i ].SetPreviewInputTexture();
  1775. }
  1776. else
  1777. {
  1778. m_inputPorts[ i ].SetPreviewInputValue();
  1779. }
  1780. }
  1781. }
  1782. public virtual void AfterPreviewRefresh() { }
  1783. public bool SafeDraw( DrawInfo drawInfo )
  1784. {
  1785. EditorGUI.BeginChangeCheck();
  1786. Draw( drawInfo );
  1787. if( EditorGUI.EndChangeCheck() )
  1788. {
  1789. SaveIsDirty = true;
  1790. return true;
  1791. }
  1792. return false;
  1793. }
  1794. public bool ShowTooltip( DrawInfo drawInfo )
  1795. {
  1796. if( string.IsNullOrEmpty( m_tooltipText ) )
  1797. return false;
  1798. if( m_globalPosition.Contains( drawInfo.MousePosition ) || m_linkVisibility )
  1799. {
  1800. if( m_tooltipTimestamp + 0.6f < Time.realtimeSinceStartup || m_linkVisibility )
  1801. {
  1802. bool errorTooltip = false;
  1803. if( m_showErrorMessage && m_errorBox.Contains( drawInfo.MousePosition ) && !string.IsNullOrEmpty( m_errorMessageTooltip ) )
  1804. errorTooltip = true;
  1805. Rect globalTooltipPos = m_globalPosition;
  1806. GUIContent temp = new GUIContent( errorTooltip ? m_errorMessageTooltip : m_tooltipText );
  1807. UIUtils.TooltipBox.wordWrap = false;
  1808. Vector2 optimal = UIUtils.TooltipBox.CalcSize( temp );
  1809. if( optimal.x > 300f )
  1810. {
  1811. UIUtils.TooltipBox.wordWrap = true;
  1812. optimal.x = 300f;
  1813. optimal.y = UIUtils.TooltipBox.CalcHeight( temp, 300f );
  1814. }
  1815. globalTooltipPos.width = Mathf.Max( 120, optimal.x );
  1816. globalTooltipPos.height = optimal.y;
  1817. globalTooltipPos.center = m_globalPosition.center;
  1818. if( !errorTooltip && m_hasTooltipLink )
  1819. globalTooltipPos.height += 16;
  1820. if( errorTooltip )
  1821. globalTooltipPos.y = 10 + m_globalPosition.yMax;
  1822. else
  1823. globalTooltipPos.y = m_globalPosition.yMin - 10 - globalTooltipPos.height;
  1824. if ( globalTooltipPos.x < 10 )
  1825. globalTooltipPos.x = 10;
  1826. if( globalTooltipPos.x + globalTooltipPos.width > Screen.width - 10 )
  1827. globalTooltipPos.x = Screen.width - globalTooltipPos.width - 10;
  1828. //UNCOMMENT this for auto adjust tooltip to the top window box
  1829. //if( globalTooltipPos.y < 40 )
  1830. // globalTooltipPos.y = 40;
  1831. if( errorTooltip && globalTooltipPos.y + globalTooltipPos.height > Screen.height - 32 )
  1832. globalTooltipPos.y = Screen.height - 32 - globalTooltipPos.height;
  1833. GUI.Label( globalTooltipPos, temp, UIUtils.TooltipBox );
  1834. if( !errorTooltip && m_hasTooltipLink )
  1835. {
  1836. Rect link = globalTooltipPos;
  1837. link.y = globalTooltipPos.yMax - 16;
  1838. link.height = 16;
  1839. link.width = 86;
  1840. link.x = globalTooltipPos.center.x - 43;
  1841. Rect hover = globalTooltipPos;
  1842. hover.yMax += 15;// m_globalPosition.yMax;
  1843. m_linkVisibility = hover.Contains( drawInfo.MousePosition );
  1844. if( link.Contains( drawInfo.MousePosition ) )
  1845. {
  1846. if( drawInfo.CurrentEventType == EventType.MouseDown )
  1847. {
  1848. if( m_tooltipTimestamp + 1.25f < Time.realtimeSinceStartup )
  1849. {
  1850. Application.OpenURL( Attributes.NodeUrl );
  1851. }
  1852. }
  1853. else
  1854. {
  1855. UIUtils.MainSkin.customStyles[ 52 ].Draw( link, WikiLinkStr, true, false, false, false );
  1856. }
  1857. }
  1858. else
  1859. {
  1860. GUI.Label( link, WikiLinkStr, UIUtils.MainSkin.customStyles[ 52 ] );
  1861. }
  1862. }
  1863. return true;
  1864. }
  1865. }
  1866. else
  1867. {
  1868. if( !m_linkVisibility )
  1869. m_tooltipTimestamp = Time.realtimeSinceStartup;
  1870. }
  1871. return false;
  1872. }
  1873. public virtual bool SafeDrawProperties()
  1874. {
  1875. EditorGUI.BeginChangeCheck();
  1876. PreDrawProperties();
  1877. if( m_autoWrapProperties )
  1878. {
  1879. NodeUtils.DrawPropertyGroup( ref m_propertiesFoldout, Constants.ParameterLabelStr, DrawProperties );
  1880. }
  1881. else
  1882. {
  1883. DrawProperties();
  1884. }
  1885. if( EditorGUI.EndChangeCheck() )
  1886. {
  1887. //UIUtils.RecordObject(this);
  1888. //MarkForPreviewUpdate();
  1889. return true;
  1890. }
  1891. return false;
  1892. }
  1893. public void PreDrawProperties()
  1894. {
  1895. if( m_useInternalPortData && m_autoDrawInternalPortData )
  1896. {
  1897. DrawInternalDataGroup();
  1898. }
  1899. }
  1900. virtual public void DrawProperties() { }
  1901. protected void DrawInternalDataGroup()
  1902. {
  1903. bool drawInternalDataUI = false;
  1904. int inputCount = m_inputPorts.Count;
  1905. if( inputCount > 0 )
  1906. {
  1907. for( int i = 0; i < inputCount; i++ )
  1908. {
  1909. if( m_inputPorts[ i ].Available && m_inputPorts[ i ].ValidInternalData && !m_inputPorts[ i ].IsConnected /*&& ( m_inputPorts[ i ].AutoDrawInternalData || ( m_autoDrawInternalPortData && m_useInternalPortData ) )*/ /*&& m_inputPorts[ i ].AutoDrawInternalData*/ )
  1910. {
  1911. drawInternalDataUI = true;
  1912. break;
  1913. }
  1914. }
  1915. }
  1916. if( drawInternalDataUI )
  1917. NodeUtils.DrawPropertyGroup( ref m_internalDataFoldout, Constants.InternalDataLabelStr, () =>
  1918. {
  1919. for( int i = 0; i < m_inputPorts.Count; i++ )
  1920. {
  1921. if( m_inputPorts[ i ].ValidInternalData && !m_inputPorts[ i ].IsConnected && m_inputPorts[ i ].Visible /*&& m_inputPorts[ i ].AutoDrawInternalData*/ )
  1922. {
  1923. m_inputPorts[ i ].ShowInternalData( this );
  1924. }
  1925. }
  1926. } );
  1927. }
  1928. protected void PickInput( InputPort port )
  1929. {
  1930. WireReference connection = port.GetConnection( 0 );
  1931. OutputPort from = port.GetOutputConnection( 0 );
  1932. m_containerGraph.ParentWindow.WireReferenceUtils.OutputPortReference.SetReference( from.NodeId, from.PortId, from.DataType, connection.TypeLocked );
  1933. m_containerGraph.DeleteConnection( true, UniqueId, port.PortId, true, true );
  1934. //TODO: check if not necessary
  1935. Event.current.Use();
  1936. IsDirty = true;
  1937. SetSaveIsDirty();
  1938. }
  1939. protected bool ApplyModifierToPort( WirePort port, bool isInput )
  1940. {
  1941. bool modifierApplied = false;
  1942. switch( Event.current.modifiers )
  1943. {
  1944. case EventModifiers.Alt:
  1945. {
  1946. m_containerGraph.DeleteConnection( isInput, UniqueId, port.PortId, true, true );
  1947. modifierApplied = true;
  1948. m_containerGraph.ParentWindow.InvalidateAlt();
  1949. }
  1950. break;
  1951. case EventModifiers.Control:
  1952. {
  1953. //WireReference connection = port.GetConnection( 0 );
  1954. //if ( isInput )
  1955. //{
  1956. // UIUtils.OutputPortReference.SetReference( connection.NodeId, connection.PortId, connection.DataType, connection.TypeLocked );
  1957. //}
  1958. //else
  1959. //{
  1960. // UIUtils.InputPortReference.SetReference( connection.NodeId, connection.PortId, connection.DataType, connection.TypeLocked );
  1961. //}
  1962. //UIUtils.DeleteConnection( isInput, UniqueId, port.PortId, true );
  1963. //modifierApplied = true;
  1964. if( !isInput )
  1965. {
  1966. WireReference connection = port.GetConnection( 0 );
  1967. m_containerGraph.ParentWindow.WireReferenceUtils.InputPortReference.SetReference( connection.NodeId, connection.PortId, connection.DataType, connection.TypeLocked );
  1968. m_containerGraph.DeleteConnection( isInput, UniqueId, port.PortId, true, true );
  1969. modifierApplied = true;
  1970. }
  1971. }
  1972. break;
  1973. }
  1974. if( isInput )
  1975. m_containerGraph.ParentWindow.WireReferenceUtils.SwitchPortReference.SetReference( port.NodeId, port.PortId, port.DataType, false ); //always save last connection
  1976. else
  1977. m_containerGraph.ParentWindow.WireReferenceUtils.SwitchPortReference.SetReference( -1, -1, WirePortDataType.OBJECT, false ); //invalidate connection
  1978. if( modifierApplied )
  1979. {
  1980. Event.current.Use();
  1981. IsDirty = true;
  1982. SetSaveIsDirty();
  1983. }
  1984. return modifierApplied;
  1985. }
  1986. public void DeleteAllInputConnections( bool alsoDeletePorts , bool inhibitWireNodeAutoDel = false )
  1987. {
  1988. int count = m_inputPorts.Count;
  1989. for( int i = 0; i < count; i++ )
  1990. {
  1991. if( m_inputPorts[ i ].IsConnected )
  1992. {
  1993. ParentNode connNode = null;
  1994. if( inhibitWireNodeAutoDel )
  1995. {
  1996. connNode = m_inputPorts[ i ].GetOutputNode();
  1997. connNode.Alive = false;
  1998. }
  1999. m_containerGraph.DeleteConnection( true, UniqueId, m_inputPorts[ i ].PortId, false, true );
  2000. if( inhibitWireNodeAutoDel )
  2001. {
  2002. connNode.Alive = true;
  2003. }
  2004. }
  2005. }
  2006. if( alsoDeletePorts )
  2007. {
  2008. m_inputPorts.Clear();
  2009. m_inputPortsDict.Clear();
  2010. }
  2011. SetSaveIsDirty();
  2012. }
  2013. public void DeleteAllOutputConnections( bool alsoDeletePorts )
  2014. {
  2015. int count = m_outputPorts.Count;
  2016. for( int i = 0; i < count; i++ )
  2017. {
  2018. if( m_outputPorts[ i ].IsConnected )
  2019. m_containerGraph.DeleteConnection( false, UniqueId, m_outputPorts[ i ].PortId, false, true );
  2020. }
  2021. if( alsoDeletePorts )
  2022. {
  2023. m_outputPorts.Clear();
  2024. m_outputPortsDict.Clear();
  2025. }
  2026. SetSaveIsDirty();
  2027. }
  2028. public void DeleteInputPortByArrayIdx( int arrayIdx )
  2029. {
  2030. if( arrayIdx >= m_inputPorts.Count )
  2031. return;
  2032. m_containerGraph.DeleteConnection( true, UniqueId, m_inputPorts[ arrayIdx ].PortId, false, true );
  2033. m_inputPortsDict.Remove( m_inputPorts[ arrayIdx ].PortId );
  2034. m_inputPorts.RemoveAt( arrayIdx );
  2035. m_sizeIsDirty = true;
  2036. SetSaveIsDirty();
  2037. RecalculateInputPortIdx();
  2038. }
  2039. public void DeleteOutputPortByArrayIdx( int portIdx )
  2040. {
  2041. if( portIdx >= m_outputPorts.Count )
  2042. return;
  2043. m_containerGraph.DeleteConnection( false, UniqueId, m_outputPorts[ portIdx ].PortId, false, true );
  2044. m_outputPortsDict.Remove( m_outputPorts[ portIdx ].PortId );
  2045. m_outputPorts.RemoveAt( portIdx );
  2046. m_sizeIsDirty = true;
  2047. }
  2048. public InputPort GetInputPortByArrayId( int id )
  2049. {
  2050. if( id < m_inputPorts.Count )
  2051. return m_inputPorts[ id ];
  2052. return null;
  2053. }
  2054. public OutputPort GetOutputPortByArrayId( int id )
  2055. {
  2056. if( id < m_outputPorts.Count )
  2057. return m_outputPorts[ id ];
  2058. return null;
  2059. }
  2060. public InputPort GetInputPortByUniqueId( int id )
  2061. {
  2062. if( m_inputPortsDict.ContainsKey( id ) )
  2063. return m_inputPortsDict[ id ];
  2064. if( m_inputPortsDict.Count != m_inputPorts.Count )
  2065. m_repopulateDictionaries = true;
  2066. int inputCount = m_inputPorts.Count;
  2067. for( int i = 0; i < inputCount; i++ )
  2068. {
  2069. if( m_inputPorts[ i ].PortId == id )
  2070. {
  2071. return m_inputPorts[ i ];
  2072. }
  2073. }
  2074. return null;
  2075. }
  2076. public OutputPort GetOutputPortByUniqueId( int id )
  2077. {
  2078. if( m_outputPortsDict.ContainsKey( id ) )
  2079. return m_outputPortsDict[ id ];
  2080. if( m_outputPortsDict.Count != m_outputPorts.Count )
  2081. m_repopulateDictionaries = true;
  2082. int outputCount = m_outputPorts.Count;
  2083. for( int i = 0; i < outputCount; i++ )
  2084. {
  2085. if( m_outputPorts[ i ].PortId == id )
  2086. return m_outputPorts[ i ];
  2087. }
  2088. return null;
  2089. }
  2090. public virtual void AfterDuplication(){}
  2091. public override string ToString()
  2092. {
  2093. string dump = "";
  2094. dump += ( "Type: " + GetType() );
  2095. dump += ( " Unique Id: " + UniqueId + "\n" );
  2096. dump += ( " Inputs: \n" );
  2097. int inputCount = m_inputPorts.Count;
  2098. int outputCount = m_outputPorts.Count;
  2099. for( int inputIdx = 0; inputIdx < inputCount; inputIdx++ )
  2100. {
  2101. dump += ( m_inputPorts[ inputIdx ] + "\n" );
  2102. }
  2103. dump += ( "Outputs: \n" );
  2104. for( int outputIdx = 0; outputIdx < outputCount; outputIdx++ )
  2105. {
  2106. dump += ( m_outputPorts[ outputIdx ] + "\n" );
  2107. }
  2108. return dump;
  2109. }
  2110. public string GetValueFromOutputStr( int outputId, WirePortDataType inputPortType, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  2111. {
  2112. if( ignoreLocalvar )
  2113. {
  2114. return GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar );
  2115. }
  2116. OutputPort outPort = GetOutputPortByUniqueId( outputId );
  2117. if( outPort.IsLocalValue( dataCollector.PortCategory ) )
  2118. {
  2119. if( outPort.DataType != WirePortDataType.OBJECT && outPort.DataType != inputPortType )
  2120. {
  2121. return UIUtils.CastPortType( ref dataCollector, m_currentPrecisionType, new NodeCastInfo( m_uniqueId, outputId ), null, outPort.DataType, inputPortType, outPort.LocalValue( dataCollector.PortCategory ) );
  2122. }
  2123. else
  2124. {
  2125. return outPort.LocalValue( dataCollector.PortCategory );
  2126. }
  2127. }
  2128. string result = GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar );
  2129. result = CreateOutputLocalVariable( outputId, result, ref dataCollector );
  2130. if( outPort.DataType != WirePortDataType.OBJECT && outPort.DataType != inputPortType )
  2131. {
  2132. result = UIUtils.CastPortType( ref dataCollector, m_currentPrecisionType, new NodeCastInfo( m_uniqueId, outputId ), null, outPort.DataType, inputPortType, result );
  2133. }
  2134. return result;
  2135. }
  2136. public virtual string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  2137. {
  2138. if( dataCollector.IsSRP )
  2139. {
  2140. switch( dataCollector.CurrentSRPType )
  2141. {
  2142. case TemplateSRPType.HD: if(OnHDAction!=null) OnHDAction( outputId, ref dataCollector ); break;
  2143. case TemplateSRPType.Lightweight:if(OnLightweightAction != null) OnLightweightAction( outputId, ref dataCollector ); break;
  2144. }
  2145. }
  2146. return string.Empty;
  2147. }
  2148. public string GenerateValueInVertex( ref MasterNodeDataCollector dataCollector, WirePortDataType dataType, string dataValue, string dataName, bool createInterpolator )
  2149. {
  2150. if( !dataCollector.IsFragmentCategory )
  2151. return dataValue;
  2152. //TEMPLATES
  2153. if( dataCollector.IsTemplate )
  2154. {
  2155. if( createInterpolator && dataCollector.TemplateDataCollectorInstance.HasCustomInterpolatedData( dataName ) )
  2156. return dataName;
  2157. MasterNodePortCategory category = dataCollector.PortCategory;
  2158. dataCollector.PortCategory = MasterNodePortCategory.Vertex;
  2159. dataCollector.PortCategory = category;
  2160. if( createInterpolator )
  2161. {
  2162. dataCollector.TemplateDataCollectorInstance.RegisterCustomInterpolatedData( dataName, dataType, m_currentPrecisionType, dataValue );
  2163. }
  2164. else
  2165. {
  2166. dataCollector.AddToVertexLocalVariables( -1, m_currentPrecisionType, dataType, dataName, dataValue );
  2167. }
  2168. return dataName;
  2169. }
  2170. //SURFACE
  2171. {
  2172. if( dataCollector.TesselationActive )
  2173. {
  2174. UIUtils.ShowMessage( "Unable to use Vertex to Frag when Tessellation is active" );
  2175. return m_outputPorts[ 0 ].ErrorValue;
  2176. }
  2177. if( createInterpolator )
  2178. dataCollector.AddToInput( UniqueId, dataName, dataType, m_currentPrecisionType );
  2179. MasterNodePortCategory portCategory = dataCollector.PortCategory;
  2180. dataCollector.PortCategory = MasterNodePortCategory.Vertex;
  2181. if( createInterpolator )
  2182. {
  2183. dataCollector.AddLocalVariable( UniqueId, Constants.VertexShaderOutputStr + "." + dataName, dataValue + ";" );
  2184. }
  2185. else
  2186. {
  2187. dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, dataType, dataName, dataValue );
  2188. }
  2189. dataCollector.PortCategory = portCategory;
  2190. return createInterpolator ? Constants.InputVarStr + "." + dataName : dataName;
  2191. }
  2192. }
  2193. public string GenerateInputInVertex( ref MasterNodeDataCollector dataCollector, int inputPortUniqueId, string varName, bool createInterpolator )
  2194. {
  2195. InputPort inputPort = GetInputPortByUniqueId( inputPortUniqueId );
  2196. if( !dataCollector.IsFragmentCategory)
  2197. return inputPort.GeneratePortInstructions( ref dataCollector );
  2198. //TEMPLATES
  2199. if( dataCollector.IsTemplate )
  2200. {
  2201. if( createInterpolator && dataCollector.TemplateDataCollectorInstance.HasCustomInterpolatedData( varName ) )
  2202. return varName;
  2203. MasterNodePortCategory category = dataCollector.PortCategory;
  2204. dataCollector.PortCategory = MasterNodePortCategory.Vertex;
  2205. //bool dirtyVertexVarsBefore = dataCollector.DirtyVertexVariables;
  2206. //ContainerGraph.ResetNodesLocalVariablesIfNot( this, MasterNodePortCategory.Vertex );
  2207. string data = inputPort.GeneratePortInstructions( ref dataCollector );
  2208. dataCollector.PortCategory = category;
  2209. //if( !dirtyVertexVarsBefore && dataCollector.DirtyVertexVariables )
  2210. //{
  2211. // dataCollector.AddVertexInstruction( dataCollector.VertexLocalVariablesFromList, UniqueId, false );
  2212. // dataCollector.ClearVertexLocalVariables();
  2213. // ContainerGraph.ResetNodesLocalVariablesIfNot( this, MasterNodePortCategory.Vertex );
  2214. //}
  2215. //ContainerGraph.ResetNodesLocalVariablesIfNot( this, MasterNodePortCategory.Fragment );
  2216. if( createInterpolator )
  2217. {
  2218. dataCollector.TemplateDataCollectorInstance.RegisterCustomInterpolatedData( varName, inputPort.DataType, m_currentPrecisionType, data );
  2219. }
  2220. else
  2221. {
  2222. dataCollector.AddToVertexLocalVariables( -1, m_currentPrecisionType, inputPort.DataType, varName, data );
  2223. }
  2224. return varName;
  2225. }
  2226. //SURFACE
  2227. {
  2228. if( dataCollector.TesselationActive )
  2229. {
  2230. UIUtils.ShowMessage( "Unable to use Vertex to Frag when Tessellation is active" );
  2231. return m_outputPorts[ 0 ].ErrorValue;
  2232. }
  2233. if( createInterpolator )
  2234. dataCollector.AddToInput( UniqueId, varName, inputPort.DataType, m_currentPrecisionType );
  2235. MasterNodePortCategory portCategory = dataCollector.PortCategory;
  2236. dataCollector.PortCategory = MasterNodePortCategory.Vertex;
  2237. //bool dirtyVertexVarsBefore = dataCollector.DirtyVertexVariables;
  2238. //ContainerGraph.ResetNodesLocalVariablesIfNot( this, MasterNodePortCategory.Vertex );
  2239. string vertexVarValue = inputPort.GeneratePortInstructions( ref dataCollector );
  2240. if( createInterpolator )
  2241. {
  2242. dataCollector.AddLocalVariable( UniqueId, Constants.VertexShaderOutputStr + "." + varName, vertexVarValue + ";" );
  2243. }
  2244. else
  2245. {
  2246. dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, inputPort.DataType, varName, vertexVarValue );
  2247. }
  2248. dataCollector.PortCategory = portCategory;
  2249. //if( !dirtyVertexVarsBefore && dataCollector.DirtyVertexVariables )
  2250. //{
  2251. // dataCollector.AddVertexInstruction( dataCollector.VertexLocalVariables, UniqueId, false );
  2252. // dataCollector.ClearVertexLocalVariables();
  2253. // ContainerGraph.ResetNodesLocalVariablesIfNot( this, MasterNodePortCategory.Vertex );
  2254. //}
  2255. //ContainerGraph.ResetNodesLocalVariablesIfNot( this, MasterNodePortCategory.Fragment );
  2256. return createInterpolator ? Constants.InputVarStr + "." + varName : varName;
  2257. }
  2258. }
  2259. protected virtual void OnUniqueIDAssigned() { }
  2260. public string CreateOutputLocalVariable( int outputArrayId, string value, ref MasterNodeDataCollector dataCollector )
  2261. {
  2262. OutputPort port = GetOutputPortByUniqueId( outputArrayId );
  2263. if( port.IsLocalValue( dataCollector.PortCategory ) )
  2264. return port.LocalValue( dataCollector.PortCategory );
  2265. if( port.ConnectionCount > 1 )
  2266. {
  2267. RegisterLocalVariable( outputArrayId, value, ref dataCollector );
  2268. return port.LocalValue( dataCollector.PortCategory );
  2269. }
  2270. else
  2271. {
  2272. // revisit later (break to components case)
  2273. port.SetLocalValue( value, dataCollector.PortCategory );
  2274. }
  2275. return value;
  2276. }
  2277. public void RegisterLocalVariable( int outputArrayId, string value, ref MasterNodeDataCollector dataCollector, string customName = null )
  2278. {
  2279. OutputPort port = GetOutputPortByUniqueId( outputArrayId );
  2280. if( (int)port.DataType >= (int)( 1 << 10 ) ) //10 is the flag start of sampler types
  2281. {
  2282. port.SetLocalValue( value, dataCollector.PortCategory );
  2283. return;
  2284. }
  2285. bool vertexMode = dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation;
  2286. string localVar = port.ConfigOutputLocalValue( m_currentPrecisionType, value, customName, dataCollector.PortCategory );
  2287. if( vertexMode )
  2288. {
  2289. dataCollector.AddToVertexLocalVariables( m_uniqueId, localVar );
  2290. }
  2291. else
  2292. {
  2293. dataCollector.AddToLocalVariables( m_uniqueId, localVar );
  2294. }
  2295. }
  2296. public void InvalidateConnections()
  2297. {
  2298. int inputCount = m_inputPorts.Count;
  2299. int outputCount = m_outputPorts.Count;
  2300. for( int i = 0; i < inputCount; i++ )
  2301. {
  2302. m_inputPorts[ i ].InvalidateAllConnections();
  2303. }
  2304. for( int i = 0; i < outputCount; i++ )
  2305. {
  2306. m_outputPorts[ i ].InvalidateAllConnections();
  2307. }
  2308. }
  2309. public virtual bool OnClick( Vector2 currentMousePos2D )
  2310. {
  2311. bool singleClick = true;
  2312. if( ( EditorApplication.timeSinceStartup - m_lastTimeSelected ) < NodeClickTime )
  2313. {
  2314. OnNodeDoubleClicked( currentMousePos2D );
  2315. singleClick = false;
  2316. }
  2317. m_lastTimeSelected = EditorApplication.timeSinceStartup;
  2318. return singleClick;
  2319. }
  2320. public virtual void OnNodeDoubleClicked( Vector2 currentMousePos2D )
  2321. {
  2322. ContainerGraph.ParentWindow.ParametersWindow.IsMaximized = !ContainerGraph.ParentWindow.ParametersWindow.IsMaximized;
  2323. }
  2324. public virtual void OnNodeSelected( bool value )
  2325. {
  2326. if( !value )
  2327. {
  2328. if( m_inputPorts != null )
  2329. {
  2330. int count = m_inputPorts.Count;
  2331. for( int i = 0; i < count; i++ )
  2332. {
  2333. m_inputPorts[ i ].ResetEditing();
  2334. }
  2335. }
  2336. if( m_outputPorts != null )
  2337. {
  2338. int count = m_outputPorts.Count;
  2339. for( int i = 0; i < count; i++ )
  2340. {
  2341. m_outputPorts[ i ].ResetEditing();
  2342. }
  2343. }
  2344. }
  2345. }
  2346. public void ResetOutputLocals()
  2347. {
  2348. int outputCount = m_outputPorts.Count;
  2349. for( int i = 0; i < outputCount; i++ )
  2350. {
  2351. m_outputPorts[ i ].ResetLocalValue();
  2352. }
  2353. }
  2354. public void ResetOutputLocalsIfNot( MasterNodePortCategory category )
  2355. {
  2356. int outputCount = m_outputPorts.Count;
  2357. for( int i = 0; i < outputCount; i++ )
  2358. {
  2359. //if( !m_outputPorts[ i ].IsLocalOnCategory( category ) )
  2360. // m_outputPorts[ i ].ResetLocalValue();
  2361. m_outputPorts[ i ].ResetLocalValueIfNot( category );
  2362. }
  2363. }
  2364. public virtual void Rewire() { }
  2365. //public virtual List<int> NodeReferences { get { return null; } }
  2366. public int UniqueId
  2367. {
  2368. get { return m_uniqueId; }
  2369. set
  2370. {
  2371. m_uniqueId = value;
  2372. int inputCount = m_inputPorts.Count;
  2373. int outputCount = m_outputPorts.Count;
  2374. for( int inputIdx = 0; inputIdx < inputCount; inputIdx++ )
  2375. {
  2376. m_inputPorts[ inputIdx ].NodeId = value;
  2377. }
  2378. for( int outputIdx = 0; outputIdx < outputCount; outputIdx++ )
  2379. {
  2380. m_outputPorts[ outputIdx ].NodeId = value;
  2381. }
  2382. OnUniqueIDAssigned();
  2383. }
  2384. }
  2385. public void SetBaseUniqueId( int uniqueId )
  2386. {
  2387. m_uniqueId = uniqueId;
  2388. }
  2389. public string OutputId
  2390. {
  2391. get
  2392. {
  2393. if( ContainerGraph.GraphId > 0 )
  2394. return UniqueId + "_g" + ContainerGraph.GraphId;
  2395. else
  2396. return UniqueId.ToString();
  2397. }
  2398. }
  2399. public virtual Rect Position { get { return m_position; } }
  2400. public Rect TruePosition { get { return m_position; } }
  2401. public Vector2 CenterPosition { get { return new Vector2( m_position.x + m_position.width * 0.5f, m_position.y + m_position.height * 0.5f ); ; } }
  2402. public Rect GlobalPosition { get { return m_globalPosition; } }
  2403. public Vector2 Corner { get { return new Vector2( m_position.x + m_position.width, m_position.y + m_position.height ); } }
  2404. public Vector2 Vec2Position
  2405. {
  2406. get { return new Vector2( m_position.x, m_position.y ); }
  2407. set
  2408. {
  2409. m_position.x = value.x;
  2410. m_position.y = value.y;
  2411. }
  2412. }
  2413. public Vector3 Vec3Position
  2414. {
  2415. get { return new Vector3( m_position.x, m_position.y, 0f ); }
  2416. set
  2417. {
  2418. m_position.x = value.x;
  2419. m_position.y = value.y;
  2420. }
  2421. }
  2422. public bool Selected
  2423. {
  2424. get { return m_selected; }
  2425. set
  2426. {
  2427. m_infiniteLoopDetected = false;
  2428. m_selected = value;
  2429. OnNodeSelected( value );
  2430. }
  2431. }
  2432. public List<InputPort> InputPorts { get { return m_inputPorts; } }
  2433. public List<OutputPort> OutputPorts
  2434. {
  2435. get { return m_outputPorts; }
  2436. }
  2437. public bool IsConnected { get { return m_connStatus == NodeConnectionStatus.Connected; } }
  2438. public NodeConnectionStatus ConnStatus
  2439. {
  2440. get { return m_connStatus; }
  2441. set
  2442. {
  2443. if( m_selfPowered )
  2444. {
  2445. m_connStatus = NodeConnectionStatus.Connected;
  2446. }
  2447. else
  2448. {
  2449. m_connStatus = value;
  2450. }
  2451. switch( m_connStatus )
  2452. {
  2453. case NodeConnectionStatus.Island:
  2454. case NodeConnectionStatus.Not_Connected: m_statusColor = Constants.NodeDefaultColor; break;
  2455. case NodeConnectionStatus.Connected: m_statusColor = Constants.NodeConnectedColor; break;
  2456. case NodeConnectionStatus.Error: m_statusColor = Constants.NodeErrorColor; break;
  2457. }
  2458. }
  2459. }
  2460. public bool SelfPowered
  2461. {
  2462. set
  2463. {
  2464. m_selfPowered = value;
  2465. if( value )
  2466. {
  2467. ConnStatus = NodeConnectionStatus.Connected;
  2468. }
  2469. }
  2470. }
  2471. // This is also called when recording on Undo
  2472. public virtual void OnBeforeSerialize() { }
  2473. public virtual void OnAfterDeserialize()
  2474. {
  2475. m_selected = false;
  2476. m_isOnGrid = false;
  2477. for( int i = 0; i < m_inputPorts.Count; i++ )
  2478. {
  2479. m_inputPorts[ i ].ResetWireReferenceStatus();
  2480. }
  2481. m_repopulateDictionaries = true;
  2482. m_sizeIsDirty = true;
  2483. if( m_currentPrecisionType == PrecisionType.Fixed )
  2484. {
  2485. m_currentPrecisionType = PrecisionType.Half;
  2486. }
  2487. }
  2488. public virtual void ReadFromDeprecated( ref string[] nodeParams, Type oldType = null ) { }
  2489. //Inherited classes must call this base method in order to setup id and position
  2490. public virtual void ReadFromString( ref string[] nodeParams )
  2491. {
  2492. ParentReadFromString( ref nodeParams );
  2493. }
  2494. public void ParentReadFromString( ref string[] nodeParams )
  2495. {
  2496. m_currentReadParamIdx = IOUtils.NodeTypeId + 1;
  2497. UniqueId = Convert.ToInt32( nodeParams[ m_currentReadParamIdx++ ] );
  2498. string[] posCoordinates = nodeParams[ m_currentReadParamIdx++ ].Split( IOUtils.VECTOR_SEPARATOR );
  2499. m_position.x = Convert.ToSingle( posCoordinates[ 0 ] );
  2500. m_position.y = Convert.ToSingle( posCoordinates[ 1 ] );
  2501. if( UIUtils.CurrentShaderVersion() > 22 )
  2502. {
  2503. m_currentPrecisionType = (PrecisionType)Enum.Parse( typeof( PrecisionType ), GetCurrentParam( ref nodeParams ) );
  2504. if( m_currentPrecisionType == PrecisionType.Fixed )
  2505. m_currentPrecisionType = PrecisionType.Half;
  2506. }
  2507. if( UIUtils.CurrentShaderVersion() > 5004 )
  2508. m_showPreview = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
  2509. }
  2510. //should be called after ReadFromString
  2511. public virtual void ReadInputDataFromString( ref string[] nodeParams )
  2512. {
  2513. int count = 0;
  2514. if( UIUtils.CurrentShaderVersion() > 7003 )
  2515. {
  2516. try
  2517. {
  2518. count = Convert.ToInt32( nodeParams[ m_currentReadParamIdx++ ] );
  2519. }
  2520. catch( Exception e )
  2521. {
  2522. Debug.LogException( e );
  2523. }
  2524. }
  2525. else
  2526. {
  2527. count = ( m_oldInputCount < 0 ) ? m_inputPorts.Count : m_oldInputCount;
  2528. }
  2529. for( int i = 0; i < count && i < nodeParams.Length && m_currentReadParamIdx < nodeParams.Length; i++ )
  2530. {
  2531. if( UIUtils.CurrentShaderVersion() < 5003 )
  2532. {
  2533. int newId = VersionConvertInputPortId( i );
  2534. if( UIUtils.CurrentShaderVersion() > 23 )
  2535. {
  2536. m_inputPorts[ newId ].DataType = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), nodeParams[ m_currentReadParamIdx++ ] );
  2537. }
  2538. m_inputPorts[ newId ].InternalData = nodeParams[ m_currentReadParamIdx++ ];
  2539. if( m_inputPorts[ newId ].IsEditable && UIUtils.CurrentShaderVersion() >= 3100 && m_currentReadParamIdx < nodeParams.Length )
  2540. {
  2541. m_inputPorts[ newId ].Name = nodeParams[ m_currentReadParamIdx++ ];
  2542. }
  2543. m_inputPorts[ newId ].UpdatePreviewInternalData();
  2544. }
  2545. else
  2546. {
  2547. string portIdStr = nodeParams[ m_currentReadParamIdx++ ];
  2548. int portId = -1;
  2549. try
  2550. {
  2551. portId = Convert.ToInt32( portIdStr );
  2552. }
  2553. catch( Exception e )
  2554. {
  2555. Debug.LogException( e );
  2556. }
  2557. WirePortDataType DataType = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), nodeParams[ m_currentReadParamIdx++ ] );
  2558. string InternalData = nodeParams[ m_currentReadParamIdx++ ];
  2559. bool isEditable = Convert.ToBoolean( nodeParams[ m_currentReadParamIdx++ ] );
  2560. string Name = string.Empty;
  2561. if( isEditable && m_currentReadParamIdx < nodeParams.Length )
  2562. {
  2563. Name = nodeParams[ m_currentReadParamIdx++ ];
  2564. }
  2565. InputPort inputPort = GetInputPortByUniqueId( portId );
  2566. if( inputPort != null )
  2567. {
  2568. if( UIUtils.IsValidType( DataType ) )
  2569. inputPort.DataType = DataType;
  2570. inputPort.InternalData = InternalData;
  2571. if( !string.IsNullOrEmpty( Name ) )
  2572. {
  2573. inputPort.Name = Name;
  2574. }
  2575. inputPort.UpdatePreviewInternalData();
  2576. }
  2577. }
  2578. }
  2579. }
  2580. public virtual void ReadOutputDataFromString( ref string[] nodeParams )
  2581. {
  2582. int count = 0;
  2583. if( UIUtils.CurrentShaderVersion() > 7003 )
  2584. {
  2585. count = Convert.ToInt32( nodeParams[ m_currentReadParamIdx++ ] );
  2586. }
  2587. else
  2588. {
  2589. count = m_outputPorts.Count;
  2590. }
  2591. for( int i = 0; i < count && i < nodeParams.Length && m_currentReadParamIdx < nodeParams.Length; i++ )
  2592. {
  2593. try
  2594. {
  2595. WirePortDataType dataType = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), nodeParams[ m_currentReadParamIdx++ ] );
  2596. int portId = -1;
  2597. if( UIUtils.CurrentShaderVersion() > 13903 )
  2598. {
  2599. portId = Convert.ToInt32( nodeParams[ m_currentReadParamIdx++ ] ); ;
  2600. }
  2601. else
  2602. {
  2603. portId = i;
  2604. }
  2605. OutputPort port = GetOutputPortByUniqueId( portId );
  2606. if( port != null && UIUtils.IsValidType( dataType ) )
  2607. {
  2608. port.DataType = dataType;
  2609. }
  2610. }
  2611. catch( Exception e )
  2612. {
  2613. Debug.LogException( e );
  2614. }
  2615. }
  2616. }
  2617. public virtual void ReadAdditionalClipboardData( ref string[] nodeParams ) { }
  2618. protected string GetCurrentParam( ref string[] nodeParams )
  2619. {
  2620. if( m_currentReadParamIdx < nodeParams.Length )
  2621. {
  2622. return nodeParams[ m_currentReadParamIdx++ ];
  2623. }
  2624. UIUtils.ShowMessage( "Invalid params number in node " + m_uniqueId + " of type " + GetType(), MessageSeverity.Error );
  2625. return string.Empty;
  2626. }
  2627. protected string GetCurrentParam( int index, ref string[] nodeParams )
  2628. {
  2629. if( m_currentReadParamIdx < nodeParams.Length )
  2630. {
  2631. return nodeParams[ index ];
  2632. }
  2633. UIUtils.ShowMessage( "Invalid params number in node " + m_uniqueId + " of type " + GetType(), MessageSeverity.Error );
  2634. return string.Empty;
  2635. }
  2636. public virtual void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  2637. {
  2638. IOUtils.AddTypeToString( ref nodeInfo, IOUtils.NodeParam );
  2639. IOUtils.AddFieldValueToString( ref nodeInfo, GetType() );
  2640. IOUtils.AddFieldValueToString( ref nodeInfo, m_uniqueId );
  2641. IOUtils.AddFieldValueToString( ref nodeInfo, ( m_position.x.ToString() + IOUtils.VECTOR_SEPARATOR + m_position.y.ToString() ) );
  2642. IOUtils.AddFieldValueToString( ref nodeInfo, m_currentPrecisionType );
  2643. IOUtils.AddFieldValueToString( ref nodeInfo, m_showPreview );
  2644. for( int i = 0; i < m_inputPorts.Count; i++ )
  2645. {
  2646. m_inputPorts[ i ].WriteToString( ref connectionsInfo );
  2647. }
  2648. }
  2649. public virtual void WriteInputDataToString( ref string nodeInfo )
  2650. {
  2651. IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts.Count );
  2652. for( int i = 0; i < m_inputPorts.Count; i++ )
  2653. {
  2654. IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts[ i ].PortId );
  2655. IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts[ i ].DataType );
  2656. IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts[ i ].InternalData );
  2657. IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts[ i ].IsEditable );
  2658. if( m_inputPorts[ i ].IsEditable )
  2659. {
  2660. IOUtils.AddFieldValueToString( ref nodeInfo, m_inputPorts[ i ].Name );
  2661. }
  2662. }
  2663. }
  2664. public void WriteOutputDataToString( ref string nodeInfo )
  2665. {
  2666. IOUtils.AddFieldValueToString( ref nodeInfo, m_outputPorts.Count );
  2667. for( int i = 0; i < m_outputPorts.Count; i++ )
  2668. {
  2669. IOUtils.AddFieldValueToString( ref nodeInfo, m_outputPorts[ i ].DataType );
  2670. IOUtils.AddFieldValueToString( ref nodeInfo, m_outputPorts[ i ].PortId );
  2671. }
  2672. }
  2673. public virtual void WriteAdditionalClipboardData( ref string nodeInfo ) { }
  2674. public virtual string GetIncludes() { return string.Empty; }
  2675. public virtual void OnObjectDropped( UnityEngine.Object obj ) { }
  2676. public virtual void SetupFromCastObject( UnityEngine.Object obj ) { }
  2677. public virtual bool OnNodeInteraction( ParentNode node ) { return false; }
  2678. public virtual void OnConnectedOutputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) { }
  2679. public virtual void OnConnectedInputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) { }
  2680. public Rect CachedPos { get { return m_cachedPos; } }
  2681. public bool IsOnGrid
  2682. {
  2683. set { m_isOnGrid = value; }
  2684. get { return m_isOnGrid; }
  2685. }
  2686. public uint CurrentReadParamIdx
  2687. {
  2688. get { return m_currentReadParamIdx++; }
  2689. set { m_currentReadParamIdx = value; }
  2690. }
  2691. public Dictionary<string, InputPort> InputPortsDict
  2692. {
  2693. get
  2694. {
  2695. Dictionary<string, InputPort> dict = new Dictionary<string, InputPort>();
  2696. for( int i = 0; i < m_inputPorts.Count; i++ )
  2697. {
  2698. dict.Add( m_inputPorts[ i ].Name, m_inputPorts[ i ] );
  2699. }
  2700. return dict;
  2701. }
  2702. }
  2703. public bool IsDirty
  2704. {
  2705. set { m_isDirty = value && UIUtils.DirtyMask; }
  2706. get
  2707. {
  2708. bool value = m_isDirty;
  2709. m_isDirty = false;
  2710. return value;
  2711. }
  2712. }
  2713. public virtual void ResetNodeData()
  2714. {
  2715. m_category = 0;
  2716. m_graphDepth = 0;
  2717. }
  2718. public virtual void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector )
  2719. {
  2720. UIUtils.SetCategoryInBitArray( ref m_category, nodeData.Category );
  2721. nodeData.GraphDepth += 1;
  2722. if( nodeData.GraphDepth > m_graphDepth )
  2723. {
  2724. m_graphDepth = nodeData.GraphDepth;
  2725. }
  2726. int count = m_inputPorts.Count;
  2727. for( int i = 0; i < count; i++ )
  2728. {
  2729. if( m_inputPorts[ i ].IsConnected )
  2730. {
  2731. m_inputPorts[ i ].GetOutputNode().PropagateNodeData( nodeData, ref dataCollector );
  2732. }
  2733. }
  2734. }
  2735. public void SetTitleTextOnCallback( string compareTitle, Action<ParentNode, string> callback )
  2736. {
  2737. if( !m_previousTitle.Equals( compareTitle ) )
  2738. {
  2739. m_previousTitle = compareTitle;
  2740. m_sizeIsDirty = true;
  2741. callback( this, compareTitle );
  2742. }
  2743. }
  2744. public void SetAdditonalTitleTextOnCallback( string compareTitle, Action<ParentNode, string> callback )
  2745. {
  2746. if( !m_previousAdditonalTitle.Equals( compareTitle ) )
  2747. {
  2748. m_previousAdditonalTitle = compareTitle;
  2749. m_sizeIsDirty = true;
  2750. callback( this, compareTitle );
  2751. }
  2752. }
  2753. public virtual void SetClippedTitle( string newText, int maxSize = 170, string endString = "..." )
  2754. {
  2755. m_content.text = GenerateClippedTitle( newText,maxSize,endString );
  2756. m_sizeIsDirty = true;
  2757. }
  2758. public virtual void SetClippedAdditionalTitle( string newText, int maxSize = 170, string endString = "..." )
  2759. {
  2760. m_additionalContent.text = GenerateClippedTitle( newText, maxSize, endString );
  2761. m_sizeIsDirty = true;
  2762. }
  2763. public void SetTitleText( string newText )
  2764. {
  2765. if( !newText.Equals( m_content.text ) )
  2766. {
  2767. m_content.text = newText;
  2768. m_sizeIsDirty = true;
  2769. }
  2770. }
  2771. public void SetAdditonalTitleText( string newText )
  2772. {
  2773. if( !newText.Equals( m_additionalContent.text ) )
  2774. {
  2775. m_additionalContent.text = newText;
  2776. m_sizeIsDirty = true;
  2777. }
  2778. }
  2779. public string GenerateErrorValue( int outputIdx = 0 )
  2780. {
  2781. switch( m_outputPorts[ outputIdx ].DataType )
  2782. {
  2783. case WirePortDataType.FLOAT2:
  2784. {
  2785. return "(0).xx";
  2786. }
  2787. case WirePortDataType.FLOAT3:
  2788. {
  2789. return "(0).xxx";
  2790. }
  2791. case WirePortDataType.FLOAT4:
  2792. case WirePortDataType.COLOR:
  2793. {
  2794. return "(0).xxxx";
  2795. }
  2796. }
  2797. return "0";
  2798. }
  2799. //Methods created to take into account new ports added on nodes newer versions
  2800. //This way we can convert connections from previous versions to newer ones and not brake shader graph
  2801. public virtual int VersionConvertInputPortId( int portId ) { return portId; }
  2802. public virtual int VersionConvertOutputPortId( int portId ) { return portId; }
  2803. public virtual string DataToArray { get { return string.Empty; } }
  2804. public bool SaveIsDirty
  2805. {
  2806. set { m_saveIsDirty = value && UIUtils.DirtyMask; }
  2807. get
  2808. {
  2809. bool value = m_saveIsDirty;
  2810. m_saveIsDirty = false;
  2811. return value;
  2812. }
  2813. }
  2814. public GUIContent TitleContent { get { return m_content; } }
  2815. public GUIContent AdditonalTitleContent { get { return m_additionalContent; } }
  2816. public bool IsVisible { get { return m_isVisible; } }
  2817. public NodeAttributes Attributes { get { return m_nodeAttribs; } }
  2818. public bool ReorderLocked { get { return m_reorderLocked; } }
  2819. public bool RequireMaterialUpdate { get { return m_requireMaterialUpdate; } }
  2820. public bool RMBIgnore { get { return m_rmbIgnore; } }
  2821. public float TextLabelWidth { get { return m_textLabelWidth; } }
  2822. public bool IsMoving { get { return m_isMoving > 0; } }
  2823. public bool MovingInFrame { get { return m_movingInFrame; } set { m_movingInFrame = value; } }
  2824. public bool SizeIsDirty { get { return m_sizeIsDirty; } }
  2825. public int Category { get { return m_category; } }
  2826. public int CommentaryParent
  2827. {
  2828. get { return m_commentaryParent; }
  2829. set { m_commentaryParent = value; }
  2830. }
  2831. public int Depth
  2832. {
  2833. get { return m_depth; }
  2834. set { m_depth = value; }
  2835. }
  2836. public int MatrixId
  2837. {
  2838. get { return m_matrixId; }
  2839. set { m_matrixId = value; }
  2840. }
  2841. public float PaddingTitleRight
  2842. {
  2843. get { return m_paddingTitleRight; }
  2844. set { m_paddingTitleRight += value; }
  2845. }
  2846. public float PaddingTitleLeft
  2847. {
  2848. get { return m_paddingTitleLeft; }
  2849. set { m_paddingTitleLeft += value; }
  2850. }
  2851. public int CachedPortsId
  2852. {
  2853. get
  2854. {
  2855. return m_cachedPortsId;
  2856. }
  2857. }
  2858. public virtual void RenderNodePreview()
  2859. {
  2860. //Runs at least one time
  2861. if( !HasPreviewShader || !m_initialized )
  2862. return;
  2863. SetPreviewInputs();
  2864. if( m_cachedMainTexId == -1 )
  2865. m_cachedMainTexId = Shader.PropertyToID( "_MainTex" );
  2866. if( m_cachedMaskTexId == -1 )
  2867. m_cachedMaskTexId = Shader.PropertyToID( "_MaskTex" );
  2868. if( m_cachedPortsId == -1 )
  2869. m_cachedPortsId = Shader.PropertyToID( "_Ports" );
  2870. if( m_cachedPortId == -1 )
  2871. m_cachedPortId = Shader.PropertyToID( "_Port" );
  2872. int count = m_outputPorts.Count;
  2873. for( int i = 0; i < count; i++ )
  2874. {
  2875. if( i == 0 )
  2876. {
  2877. RenderTexture temp = RenderTexture.active;
  2878. RenderTexture beforeMask = RenderTexture.GetTemporary( 128, 128, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear );
  2879. RenderTexture.active = beforeMask;
  2880. Graphics.Blit( null, beforeMask, PreviewMaterial, m_previewMaterialPassId );
  2881. m_portMask.Set( 0, 0, 0, 0 );
  2882. switch( m_outputPorts[ i ].DataType )
  2883. {
  2884. case WirePortDataType.INT:
  2885. case WirePortDataType.FLOAT:
  2886. m_portMask.Set( 1, 1, 1, 1 );
  2887. break;
  2888. case WirePortDataType.FLOAT2:
  2889. m_portMask.Set( 1, 1, 0, 0 );
  2890. break;
  2891. case WirePortDataType.FLOAT3:
  2892. m_portMask.Set( 1, 1, 1, 0 );
  2893. break;
  2894. case WirePortDataType.COLOR:
  2895. case WirePortDataType.FLOAT4:
  2896. m_portMask.Set( 1, 1, 1, 1 );
  2897. break;
  2898. default:
  2899. m_portMask.Set( 1, 1, 1, 1 );
  2900. break;
  2901. }
  2902. if( m_outputPorts[ i ].DataType == WirePortDataType.FLOAT3x3 || m_outputPorts[ i ].DataType == WirePortDataType.FLOAT4x4 )
  2903. {
  2904. m_outputPorts[ i ].MaskingMaterial.SetTexture( m_cachedMainTexId, EditorGUIUtility.whiteTexture );
  2905. }
  2906. else
  2907. {
  2908. m_outputPorts[ i ].MaskingMaterial.SetTexture( m_cachedMainTexId, beforeMask );
  2909. }
  2910. m_outputPorts[ i ].MaskingMaterial.SetVector( m_cachedPortsId, m_portMask );
  2911. RenderTexture.active = m_outputPorts[ i ].OutputPreviewTexture;
  2912. Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, m_outputPorts[ i ].MaskingMaterial, 0 );
  2913. RenderTexture.ReleaseTemporary( beforeMask );
  2914. RenderTexture.active = temp;
  2915. }
  2916. else
  2917. {
  2918. RenderTexture temp = RenderTexture.active;
  2919. m_outputPorts[ i ].MaskingMaterial.SetTexture( m_cachedMaskTexId, PreviewTexture );
  2920. m_outputPorts[ i ].MaskingMaterial.SetFloat( m_cachedPortId, i );
  2921. RenderTexture.active = m_outputPorts[ i ].OutputPreviewTexture;
  2922. Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, m_outputPorts[ i ].MaskingMaterial, 1 );
  2923. RenderTexture.active = temp;
  2924. }
  2925. }
  2926. }
  2927. protected void ShowTab( NodeMessageType type, string tooltip )
  2928. {
  2929. m_showErrorMessage = true;
  2930. m_errorMessageTypeIsError = type;
  2931. m_errorMessageTooltip = tooltip;
  2932. }
  2933. protected void ShowTab()
  2934. {
  2935. m_showErrorMessage = true;
  2936. }
  2937. protected void HideTab()
  2938. {
  2939. m_showErrorMessage = false;
  2940. }
  2941. public virtual RenderTexture PreviewTexture
  2942. {
  2943. get
  2944. {
  2945. if( m_outputPorts.Count > 0 )
  2946. return m_outputPorts[ 0 ].OutputPreviewTexture;
  2947. else
  2948. return null;
  2949. }
  2950. }
  2951. public void FullWriteToString( ref string nodesInfo, ref string connectionsInfo )
  2952. {
  2953. WriteToString( ref nodesInfo, ref connectionsInfo );
  2954. WriteInputDataToString( ref nodesInfo );
  2955. WriteOutputDataToString( ref nodesInfo );
  2956. }
  2957. public void ClipboardFullWriteToString( ref string nodesInfo, ref string connectionsInfo )
  2958. {
  2959. FullWriteToString( ref nodesInfo, ref connectionsInfo );
  2960. WriteAdditionalClipboardData( ref nodesInfo );
  2961. }
  2962. public void FullReadFromString( ref string[] parameters )
  2963. {
  2964. try
  2965. {
  2966. ReadFromString( ref parameters );
  2967. ReadInputDataFromString( ref parameters );
  2968. ReadOutputDataFromString( ref parameters );
  2969. }
  2970. catch( Exception e )
  2971. {
  2972. Debug.LogException( e );
  2973. }
  2974. }
  2975. public void ClipboardFullReadFromString( ref string[] parameters )
  2976. {
  2977. try
  2978. {
  2979. FullReadFromString( ref parameters );
  2980. ReadAdditionalClipboardData( ref parameters );
  2981. }
  2982. catch( Exception e )
  2983. {
  2984. Debug.LogException( e );
  2985. }
  2986. }
  2987. public string GenerateClippedTitle( string original , int maxSize = 170, string endString = "..." )
  2988. {
  2989. if( UIUtils.UnZoomedNodeTitleStyle == null )
  2990. return original;
  2991. GUIContent content = new GUIContent( original );
  2992. string finalTitle = string.Empty;
  2993. bool addEllipsis = false;
  2994. for( int i = 1; i <= original.Length; i++ )
  2995. {
  2996. content.text = original.Substring( 0, i );
  2997. Vector2 titleSize = UIUtils.UnZoomedNodeTitleStyle.CalcSize( content );
  2998. if( titleSize.x > maxSize )
  2999. {
  3000. addEllipsis = true;
  3001. break;
  3002. }
  3003. else
  3004. {
  3005. finalTitle = content.text;
  3006. }
  3007. }
  3008. if( addEllipsis )
  3009. finalTitle += endString;
  3010. return finalTitle;
  3011. }
  3012. public virtual void RefreshOnUndo() { }
  3013. public virtual void CalculateCustomGraphDepth() { }
  3014. public int GraphDepth { get { return m_graphDepth; } }
  3015. public PrecisionType CurrentPrecisionType { get { return m_currentPrecisionType; } }
  3016. public Material PreviewMaterial
  3017. {
  3018. get
  3019. {
  3020. if( m_previewMaterial == null )
  3021. {
  3022. m_previewMaterial = new Material( PreviewShader );
  3023. }
  3024. return m_previewMaterial;
  3025. }
  3026. }
  3027. public Shader PreviewShader
  3028. {
  3029. get
  3030. {
  3031. if( m_previewShader == null )
  3032. {
  3033. m_previewShader = AssetDatabase.LoadAssetAtPath<Shader>( AssetDatabase.GUIDToAssetPath( m_previewShaderGUID ) );
  3034. }
  3035. if( m_previewShader == null )
  3036. {
  3037. m_previewShader = AssetDatabase.LoadAssetAtPath<Shader>( AssetDatabase.GUIDToAssetPath( "d9ca47581ac157145bff6f72ac5dd73e" ) ); //ranged float guid
  3038. }
  3039. if( m_previewShader == null )
  3040. m_previewShader = Shader.Find( "Unlit/Colored Transparent" );
  3041. return m_previewShader;
  3042. }
  3043. }
  3044. public bool HasPreviewShader
  3045. {
  3046. get { return !string.IsNullOrEmpty( m_previewShaderGUID ); }
  3047. }
  3048. public void CheckSpherePreview()
  3049. {
  3050. bool oneIsSphere = false;
  3051. if( m_drawPreviewAsSphere )
  3052. oneIsSphere = true;
  3053. int count = m_inputPorts.Count;
  3054. for( int i = 0; i < count; i++ )
  3055. {
  3056. ParentNode node = m_inputPorts[ i ].GetOutputNode( 0 );
  3057. if( node != null && node.SpherePreview )
  3058. oneIsSphere = true;
  3059. }
  3060. if( m_forceDrawPreviewAsPlane )
  3061. oneIsSphere = false;
  3062. SpherePreview = oneIsSphere;
  3063. }
  3064. public bool SpherePreview
  3065. {
  3066. get { return m_spherePreview; }
  3067. set { m_spherePreview = value; }
  3068. }
  3069. public bool ShowPreview
  3070. {
  3071. get { return m_showPreview; }
  3072. set { m_showPreview = value; }
  3073. }
  3074. public int VisiblePorts
  3075. {
  3076. get { return m_visiblePorts; }
  3077. set { m_visiblePorts = value; }
  3078. }
  3079. public bool Docking
  3080. {
  3081. get { return m_docking; }
  3082. set { m_docking = value; }
  3083. }
  3084. public bool UseSquareNodeTitle
  3085. {
  3086. get { return m_useSquareNodeTitle; }
  3087. set { m_useSquareNodeTitle = value; }
  3088. }
  3089. public bool InsideShaderFunction
  3090. {
  3091. get { return ContainerGraph != ContainerGraph.ParentWindow.CurrentGraph; }
  3092. }
  3093. public virtual void SetContainerGraph( ParentGraph newgraph )
  3094. {
  3095. m_containerGraph = newgraph;
  3096. }
  3097. public virtual void OnMasterNodeReplaced( MasterNode newMasterNode ) { }
  3098. public virtual void RefreshExternalReferences() { }
  3099. public Rect DropdownRect { get { return m_dropdownRect; } }
  3100. public virtual bool Contains( Vector2 pos ) { return m_globalPosition.Contains( pos ); }
  3101. public virtual bool Contains( Vector3 pos ) { return m_globalPosition.Contains( pos ); }
  3102. public bool IsNodeBeingCopied { get { return m_isNodeBeingCopied; } set { m_isNodeBeingCopied = value; } }
  3103. public virtual WirePortDataType GetInputPortVisualDataTypeByArrayIdx( int portArrayIdx )
  3104. {
  3105. return m_inputPorts[ portArrayIdx ].DataType;
  3106. }
  3107. public virtual WirePortDataType GetOutputPortVisualDataTypeById( int portId )
  3108. {
  3109. return GetOutputPortByUniqueId( portId ).DataType;
  3110. }
  3111. public virtual float HeightEstimate
  3112. {
  3113. get
  3114. {
  3115. float heightEstimate = 0;
  3116. heightEstimate = 32 + Constants.INPUT_PORT_DELTA_Y;
  3117. for( int i = 0; i < InputPorts.Count; i++ )
  3118. {
  3119. if( InputPorts[ i ].Visible )
  3120. heightEstimate += 18 + Constants.INPUT_PORT_DELTA_Y;
  3121. }
  3122. return heightEstimate;
  3123. // Magic number 18 represents m_fontHeight that might not be set yet
  3124. //return Constants.NODE_HEADER_EXTRA_HEIGHT + Mathf.Max( 18 + m_inputPorts.Count, m_outputPorts.Count ) * Constants.INPUT_PORT_DELTA_Y;
  3125. }
  3126. }
  3127. public bool Alive { get { return m_alive;} set { m_alive = value; } }
  3128. public string TypeName { get { if( m_nodeAttribs != null ) return m_nodeAttribs.Name;return GetType().ToString(); } }
  3129. }
  3130. }