Assignment for RMIT Mixed Reality in 2020
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.

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