diff options
author | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
commit | b82da95b5181ac8bbae38efb13e950d5e88a4caa (patch) | |
tree | 48a6f3269276484bbc7cfc95f0651f40a2176aa1 /Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs | |
parent | 917e9e0b320775634dc2e710f7deac74fd0822f0 (diff) |
*移动amplify shader editor到third party目录
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs')
-rw-r--r-- | Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs | 1330 |
1 files changed, 1330 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs new file mode 100644 index 00000000..cc93bf0e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs @@ -0,0 +1,1330 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +using UnityEngine; +using UnityEditor; +using System; +using System.Collections.Generic; +#if !UNITY_2018_1_OR_NEWER +namespace AmplifyShaderEditor +{ + // Disabling Substance Deprecated warning +#pragma warning disable 0618 + [Serializable] + [NodeAttributes( "Substance Sample", "Textures", "Samples a procedural material", KeyCode.None, true, 0, int.MaxValue, typeof( SubstanceArchive ), typeof( ProceduralMaterial ) )] + public sealed class SubstanceSamplerNode : PropertyNode + { + private const string GlobalVarDecStr = "uniform sampler2D {0};"; + private const string PropertyDecStr = "{0}(\"{0}\", 2D) = \"white\""; + + private const string AutoNormalStr = "Auto-Normal"; + private const string SubstanceStr = "Substance"; + + private float TexturePreviewSizeX = 128; + private float TexturePreviewSizeY = 128; + + private float PickerPreviewWidthAdjust = 18; + + private bool m_editing; + + private CacheNodeConnections m_cacheNodeConnections; + + [SerializeField] + private int m_firstOutputConnected = 0; + + [SerializeField] + private ProceduralMaterial m_proceduralMaterial; + + [SerializeField] + private int m_textureCoordSet = 0; + + [SerializeField] + private ProceduralOutputType[] m_textureTypes; + + [SerializeField] + private bool m_autoNormal = true; + + private System.Type m_type; + + private Texture[] m_textures = new Texture[] { }; + + private List<int> m_outputConns = new List<int>(); + + private Rect m_previewArea; + + private Rect m_pickerArea; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ); + AddOutputPort( WirePortDataType.COLOR, Constants.EmptyPortValue ); + m_insideSize.Set( TexturePreviewSizeX + PickerPreviewWidthAdjust, TexturePreviewSizeY + 10 ); + m_type = typeof( ProceduralMaterial ); + m_currentParameterType = PropertyType.Property; + m_freeType = false; + m_freeName = false; + m_autoWrapProperties = true; + m_customPrefix = "Substance Sample "; + m_drawPrecisionUI = false; + m_showPreview = true; + m_drawPreviewExpander = false; + m_selectedLocation = PreviewLocation.TopCenter; + m_cacheNodeConnections = new CacheNodeConnections(); + m_previewShaderGUID = "6f322c1da33f1e744941aafcb0ad1a2d"; + m_showAutoRegisterUI = false; + } + + public override void RenderNodePreview() + { + //Runs at least one time + if( !m_initialized ) + { + // nodes with no preview don't update at all + PreviewIsDirty = false; + return; + } + + if( !PreviewIsDirty ) + return; + + SetPreviewInputs(); + + PreviewMaterial.SetInt( "_CustomUVs", m_inputPorts[ 0 ].IsConnected ? 1 : 0 ); + + if( m_proceduralMaterial == null ) + return; + + Texture[] texs = m_proceduralMaterial.GetGeneratedTextures(); + int count = m_outputPorts.Count; + for( int i = 0; i < count; i++ ) + { + RenderTexture temp = RenderTexture.active; + RenderTexture.active = m_outputPorts[ i ].OutputPreviewTexture; + + PreviewMaterial.SetTexture( "_GenTex", texs[ i ] ); + + if( m_autoNormal && m_textureTypes[ i ] == ProceduralOutputType.Normal ) + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, 1 ); + else + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, 0 ); + RenderTexture.active = temp; + } + + PreviewIsDirty = m_continuousPreviewRefresh; + } + + public override void OnOutputPortConnected( int portId, int otherNodeId, int otherPortId ) + { + base.OnOutputPortConnected( portId, otherNodeId, otherPortId ); + m_firstOutputConnected = -1; + } + + public override void OnOutputPortDisconnected( int portId ) + { + base.OnOutputPortDisconnected( portId ); + m_firstOutputConnected = -1; + } + + void CalculateFirstOutputConnected() + { + m_outputConns.Clear(); + int count = m_outputPorts.Count; + bool connectionsAvailable = false; + for( int i = 0; i < count; i++ ) + { + if( m_outputPorts[ i ].IsConnected ) + { + connectionsAvailable = true; + } + } + + for( int i = 0; i < count; i++ ) + { + if( connectionsAvailable ) + { + if( m_outputPorts[ i ].IsConnected ) + { + if( m_firstOutputConnected < 0 ) + m_firstOutputConnected = i; + + m_outputConns.Add( i ); + } + } + else + { + m_outputConns.Add( i ); + } + } + + if( m_firstOutputConnected < 0 ) + m_firstOutputConnected = 0; + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + base.OnNodeLayout( drawInfo ); + + m_previewArea = m_remainingBox; + m_previewArea.width = TexturePreviewSizeX * drawInfo.InvertedZoom; + m_previewArea.height = TexturePreviewSizeY * drawInfo.InvertedZoom; + m_previewArea.x += 0.5f * m_remainingBox.width - 0.5f * m_previewArea.width; + m_pickerArea = m_previewArea; + m_pickerArea.width = 40 * drawInfo.InvertedZoom; + m_pickerArea.x = m_previewArea.xMax - m_pickerArea.width - 2; + m_pickerArea.height = 14 * drawInfo.InvertedZoom; + m_pickerArea.y = m_previewArea.yMax - m_pickerArea.height - 2; + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + base.DrawGUIControls( drawInfo ); + + if( !( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp || drawInfo.CurrentEventType == EventType.ExecuteCommand || drawInfo.CurrentEventType == EventType.DragPerform ) ) + return; + + bool insideBox = m_previewArea.Contains( drawInfo.MousePosition ); + + if( insideBox ) + { + m_editing = true; + } + else if( m_editing && !insideBox && drawInfo.CurrentEventType != EventType.ExecuteCommand ) + { + GUI.FocusControl( null ); + m_editing = false; + } + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + if( m_editing ) + { + m_textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + if( GUI.Button( m_pickerArea, string.Empty, GUIStyle.none ) ) + { + int controlID = EditorGUIUtility.GetControlID( FocusType.Passive ); + EditorGUIUtility.ShowObjectPicker<ProceduralMaterial>( m_proceduralMaterial, false, "", controlID ); + } + + string commandName = Event.current.commandName; + UnityEngine.Object newValue = null; + if( commandName == "ObjectSelectorUpdated" ) + { + newValue = EditorGUIUtility.GetObjectPickerObject(); + if( newValue != (UnityEngine.Object)m_proceduralMaterial ) + { + PreviewIsDirty = true; + UndoRecordObject( "Changing value EditorGUIObjectField on node Substance Sample" ); + + m_proceduralMaterial = newValue != null ? (ProceduralMaterial)newValue : null; + m_textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + OnNewSubstanceSelected( m_textures ); + } + } + else if( commandName == "ObjectSelectorClosed" ) + { + newValue = EditorGUIUtility.GetObjectPickerObject(); + if( newValue != (UnityEngine.Object)m_proceduralMaterial ) + { + PreviewIsDirty = true; + UndoRecordObject( "Changing value EditorGUIObjectField on node Substance Sample" ); + + m_proceduralMaterial = newValue != null ? (ProceduralMaterial)newValue : null; + m_textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + OnNewSubstanceSelected( m_textures ); + } + m_editing = false; + } + + if( GUI.Button( m_previewArea, string.Empty, GUIStyle.none ) ) + { + if( m_proceduralMaterial != null ) + { + Selection.activeObject = m_proceduralMaterial; + EditorGUIUtility.PingObject( Selection.activeObject ); + } + m_editing = false; + } + } + + if( drawInfo.CurrentEventType == EventType.Repaint ) + { + if( !m_editing ) + m_textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + + if( m_textures != null ) + { + if( m_firstOutputConnected < 0 ) + { + CalculateFirstOutputConnected(); + } + else if( m_textures.Length != m_textureTypes.Length ) + { + OnNewSubstanceSelected( m_textures ); + } + + int texCount = m_outputConns.Count; + Rect individuals = m_previewArea; + individuals.height /= texCount; + + for( int i = 0; i < texCount; i++ ) + { + EditorGUI.DrawPreviewTexture( individuals, m_textures[ m_outputConns[ i ] ], null, ScaleMode.ScaleAndCrop ); + individuals.y += individuals.height; + } + } + else + { + GUI.Label( m_previewArea, string.Empty, UIUtils.ObjectFieldThumb ); + } + + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 ) + { + Rect smallButton = m_previewArea; + smallButton.height = 14 * drawInfo.InvertedZoom; + smallButton.y = m_previewArea.yMax - smallButton.height - 2; + smallButton.width = 40 * drawInfo.InvertedZoom; + smallButton.x = m_previewArea.xMax - smallButton.width - 2; + if( m_textures == null ) + { + GUI.Label( m_previewArea, "None (Procedural Material)", UIUtils.ObjectFieldThumbOverlay ); + } + GUI.Label( m_pickerArea, "Select", UIUtils.GetCustomStyle( CustomStyle.SamplerButton ) ); + } + + GUI.Label( m_previewArea, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) ); + } + } + + void OnNewSubstanceSelected( Texture[] textures ) + { + CacheCurrentSettings(); + ConfigPortsFromMaterial( true, textures ); + ConnectFromCache(); + m_requireMaterialUpdate = true; + CalculateFirstOutputConnected(); + ContainerGraph.ParentWindow.RequestRepaint(); + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUI.BeginChangeCheck(); + m_proceduralMaterial = EditorGUILayoutObjectField( SubstanceStr, m_proceduralMaterial, m_type, false ) as ProceduralMaterial; + if( EditorGUI.EndChangeCheck() ) + { + Texture[] textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + if( textures != null ) + { + OnNewSubstanceSelected( textures ); + } + } + + m_textureCoordSet = EditorGUILayoutIntPopup( Constants.AvailableUVSetsLabel, m_textureCoordSet, Constants.AvailableUVSetsStr, Constants.AvailableUVSets ); + EditorGUI.BeginChangeCheck(); + m_autoNormal = EditorGUILayoutToggle( AutoNormalStr, m_autoNormal ); + if( EditorGUI.EndChangeCheck() ) + { + for( int i = 0; i < m_textureTypes.Length; i++ ) + { + WirePortDataType portType = ( m_autoNormal && m_textureTypes[ i ] == ProceduralOutputType.Normal ) ? WirePortDataType.FLOAT3 : WirePortDataType.COLOR; + if( m_outputPorts[ i ].DataType != portType ) + { + m_outputPorts[ i ].ChangeType( portType, false ); + } + } + } + } + + private void CacheCurrentSettings() + { + m_cacheNodeConnections.Clear(); + for( int portId = 0; portId < m_outputPorts.Count; portId++ ) + { + if( m_outputPorts[ portId ].IsConnected ) + { + int connCount = m_outputPorts[ portId ].ConnectionCount; + for( int connIdx = 0; connIdx < connCount; connIdx++ ) + { + WireReference connection = m_outputPorts[ portId ].GetConnection( connIdx ); + m_cacheNodeConnections.Add( m_outputPorts[ portId ].Name, new NodeCache( connection.NodeId, connection.PortId ) ); + } + } + } + } + + private void ConnectFromCache() + { + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + List<NodeCache> connections = m_cacheNodeConnections.GetList( m_outputPorts[ i ].Name ); + if( connections != null ) + { + int count = connections.Count; + for( int connIdx = 0; connIdx < count; connIdx++ ) + { + UIUtils.SetConnection( connections[ connIdx ].TargetNodeId, connections[ connIdx ].TargetPortId, UniqueId, i ); + } + } + } + } + + + private void ConfigPortsFromMaterial( bool invalidateConnections = false, Texture[] newTextures = null ) + { + SetAdditonalTitleText( ( m_proceduralMaterial != null ) ? string.Format( Constants.PropertyValueLabel, m_proceduralMaterial.name ) : "Value( <None> )" ); + + Texture[] textures = newTextures != null ? newTextures : ( ( m_proceduralMaterial != null ) ? m_proceduralMaterial.GetGeneratedTextures() : null ); + if( textures != null ) + { + m_firstOutputConnected = -1; + string nameToRemove = m_proceduralMaterial.name + "_"; + m_textureTypes = new ProceduralOutputType[ textures.Length ]; + for( int i = 0; i < textures.Length; i++ ) + { + ProceduralTexture procTex = textures[ i ] as ProceduralTexture; + m_textureTypes[ i ] = procTex.GetProceduralOutputType(); + + WirePortDataType portType = ( m_autoNormal && m_textureTypes[ i ] == ProceduralOutputType.Normal ) ? WirePortDataType.FLOAT3 : WirePortDataType.COLOR; + string newName = textures[ i ].name.Replace( nameToRemove, string.Empty ); + char firstLetter = Char.ToUpper( newName[ 0 ] ); + newName = firstLetter.ToString() + newName.Substring( 1 ); + if( i < m_outputPorts.Count ) + { + m_outputPorts[ i ].ChangeProperties( newName, portType, false ); + if( invalidateConnections ) + { + m_outputPorts[ i ].FullDeleteConnections(); + } + } + else + { + AddOutputPort( portType, newName ); + } + } + + if( textures.Length < m_outputPorts.Count ) + { + int itemsToRemove = m_outputPorts.Count - textures.Length; + for( int i = 0; i < itemsToRemove; i++ ) + { + int idx = m_outputPorts.Count - 1; + if( m_outputPorts[ idx ].IsConnected ) + { + m_outputPorts[ idx ].ForceClearConnection(); + } + RemoveOutputPort( idx ); + } + } + } + else + { + int itemsToRemove = m_outputPorts.Count - 1; + m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.COLOR, false ); + m_outputPorts[ 0 ].ForceClearConnection(); + + for( int i = 0; i < itemsToRemove; i++ ) + { + int idx = m_outputPorts.Count - 1; + if( m_outputPorts[ idx ].IsConnected ) + { + m_outputPorts[ idx ].ForceClearConnection(); + } + RemoveOutputPort( idx ); + } + } + + m_sizeIsDirty = true; + m_isDirty = true; + } + + private void ConfigFromObject( UnityEngine.Object obj ) + { + ProceduralMaterial newMat = AssetDatabase.LoadAssetAtPath<ProceduralMaterial>( AssetDatabase.GetAssetPath( obj ) ); + if( newMat != null ) + { + m_proceduralMaterial = newMat; + ConfigPortsFromMaterial(); + } + } + + public override void OnObjectDropped( UnityEngine.Object obj ) + { + ConfigFromObject( obj ); + } + + public override void SetupFromCastObject( UnityEngine.Object obj ) + { + ConfigFromObject( obj ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_proceduralMaterial == null ) + { + return "(0).xxxx"; + } + + if( m_outputPorts[ outputId ].IsLocalValue( dataCollector.PortCategory ) ) + { + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + Texture[] textures = m_proceduralMaterial.GetGeneratedTextures(); + + string uvPropertyName = string.Empty; + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + if( m_outputPorts[ i ].HasConnectedNode ) + { + uvPropertyName = textures[ i ].name; + break; + } + } + + string name = textures[ outputId ].name + OutputId; + dataCollector.AddToUniforms( UniqueId, string.Format( GlobalVarDecStr, textures[ outputId ].name ) ); + dataCollector.AddToProperties( UniqueId, string.Format( PropertyDecStr, textures[ outputId ].name ) + "{}", -1 ); + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + string value = string.Format( "tex2D{0}({1}, {2})", ( isVertex ? "lod" : string.Empty ), textures[ outputId ].name, GetUVCoords( ref dataCollector, ignoreLocalvar, uvPropertyName ) ); + if( m_autoNormal && m_textureTypes[ outputId ] == ProceduralOutputType.Normal ) + { + value = string.Format( TemplateHelperFunctions.CreateUnpackNormalStr( dataCollector,false,"1.0"), value ); + } + + dataCollector.AddPropertyNode( this ); + RegisterLocalVariable( outputId, value, ref dataCollector, name ); + + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + public string GetUVCoords( ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar, string propertyName ) + { + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + if( m_inputPorts[ 0 ].IsConnected ) + { + return m_inputPorts[ 0 ].GenerateShaderForOutput( ref dataCollector, isVertex ? WirePortDataType.FLOAT4 : WirePortDataType.FLOAT2, ignoreLocalVar, true ); + } + else + { + string uvChannelName = IOUtils.GetUVChannelName( propertyName, m_textureCoordSet ); + + if( dataCollector.IsTemplate ) + { + string propertyHelperVar = propertyName + "_ST"; + dataCollector.AddToUniforms( UniqueId, "float4", propertyHelperVar, dataCollector.IsSRP ); + string uvName = string.Empty; + if( dataCollector.TemplateDataCollectorInstance.HasUV( m_textureCoordSet ) ) + { + uvName = dataCollector.TemplateDataCollectorInstance.GetUVName( m_textureCoordSet ); + } + else + { + uvName = dataCollector.TemplateDataCollectorInstance.RegisterUV( m_textureCoordSet ); + } + + uvChannelName = "uv" + propertyName; + if( isVertex ) + { + string value = string.Format( Constants.TilingOffsetFormat, uvName, propertyHelperVar + ".xy", propertyHelperVar + ".zw" ); + string lodLevel = "0"; + + value = "float4( " + value + ", 0 , " + lodLevel + " )"; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT4, uvChannelName, value ); + } + else + { + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT2, uvChannelName, string.Format( Constants.TilingOffsetFormat, uvName, propertyHelperVar + ".xy", propertyHelperVar + ".zw" ) ); + } + } + else + { + string vertexCoords = Constants.VertexShaderInputStr + ".texcoord"; + if( m_textureCoordSet > 0 ) + { + vertexCoords += m_textureCoordSet.ToString(); + } + + + string dummyPropUV = "_texcoord" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ); + string dummyUV = "uv" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ) + dummyPropUV; + + dataCollector.AddToUniforms( UniqueId, "uniform float4 " + propertyName + "_ST;" ); + dataCollector.AddToProperties( UniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 100 ); + dataCollector.AddToInput( UniqueId, dummyUV, WirePortDataType.FLOAT2 ); + + if( isVertex ) + { + dataCollector.AddToVertexLocalVariables( UniqueId, "float4 " + uvChannelName + " = float4(" + vertexCoords + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw, 0 ,0);" ); + return uvChannelName; + } + else + dataCollector.AddToLocalVariables( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvChannelName, Constants.InputVarStr + "." + dummyUV + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw" ); + + } + + return uvChannelName; + } + } + + public override void UpdateMaterial( Material mat ) + { + base.UpdateMaterial( mat ); + if( m_proceduralMaterial != null ) + { + Texture[] textures = m_proceduralMaterial.GetGeneratedTextures(); + for( int i = 0; i < textures.Length; i++ ) + { + if( mat.HasProperty( textures[ i ].name ) && !InsideShaderFunction ) + { + mat.SetTexture( textures[ i ].name, textures[ i ] ); + } + } + } + } + + public override bool UpdateShaderDefaults( ref Shader shader, ref TextureDefaultsDataColector defaultCol ) + { + if( m_proceduralMaterial != null ) + { + Texture[] textures = m_proceduralMaterial.GetGeneratedTextures(); + for( int i = 0; i < textures.Length; i++ ) + { + defaultCol.AddValue( textures[ i ].name, textures[ i ] ); + } + } + return true; + } + + public override void Destroy() + { + base.Destroy(); + m_textures = null; + m_proceduralMaterial = null; + m_cacheNodeConnections.Clear(); + m_cacheNodeConnections = null; + m_outputConns.Clear(); + m_outputConns = null; + } + + public override string GetPropertyValStr() + { + return m_proceduralMaterial ? m_proceduralMaterial.name : string.Empty; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + string guid = GetCurrentParam( ref nodeParams ); + m_textureCoordSet = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_autoNormal = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + if( guid.Length > 1 ) + { + m_proceduralMaterial = AssetDatabase.LoadAssetAtPath<ProceduralMaterial>( AssetDatabase.GUIDToAssetPath( guid ) ); + if( m_proceduralMaterial != null ) + { + ConfigPortsFromMaterial(); + } + else + { + UIUtils.ShowMessage( UniqueId, "Substance not found ", MessageSeverity.Error ); + } + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + string guid = ( m_proceduralMaterial != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_proceduralMaterial ) ) : "0"; + IOUtils.AddFieldValueToString( ref nodeInfo, guid ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_textureCoordSet ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autoNormal ); + } + + } +#pragma warning restore 0618 +} +#elif SUBSTANCE_PLUGIN_ENABLED + +using Substance.Game; + +namespace AmplifyShaderEditor +{ + public enum ASEProceduralOutputType + { + Color, + Normal, + } + // Disabling Substance Deprecated warning +#pragma warning disable 0618 + [Serializable] + [NodeAttributes( "Substance Sample", "Textures", "Samples a procedural material", KeyCode.None, true, 0, int.MaxValue, typeof( SubstanceGraph ), typeof( Substance.Game.Substance ) )] + public sealed class SubstanceSamplerNode : PropertyNode + { + private const string NormalMapCheck = "_normal"; + private const string GlobalVarDecStr = "uniform sampler2D {0};"; + private const string PropertyDecStr = "{0}(\"{1}\", 2D) = \"white\""; + + private const string AutoNormalStr = "Auto-Normal"; + private const string SubstanceStr = "Substance"; + + private float TexturePreviewSizeX = 128; + private float TexturePreviewSizeY = 128; + + private float PickerPreviewWidthAdjust = 18; + + private bool m_editing; + + private CacheNodeConnections m_cacheNodeConnections; + + [SerializeField] + private int m_firstOutputConnected = 0; + + [SerializeField] + private Substance.Game.SubstanceGraph m_substanceGraph; + [SerializeField] + private string m_substanceGUID = string.Empty; + + [SerializeField] + private int m_textureCoordSet = 0; + + [SerializeField] + private ASEProceduralOutputType[] m_textureTypes; + + [SerializeField] + private bool m_autoNormal = true; + + private System.Type m_type; + + private List<Texture2D> m_textures = new List<Texture2D>(); + + private List<int> m_outputConns = new List<int>(); + + private Rect m_previewArea; + + private Rect m_pickerArea; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ); + AddOutputPort( WirePortDataType.COLOR, Constants.EmptyPortValue ); + m_insideSize.Set( TexturePreviewSizeX + PickerPreviewWidthAdjust, TexturePreviewSizeY + 10 ); + m_type = typeof( Substance.Game.Substance ); + m_currentParameterType = PropertyType.Property; + m_freeType = false; + m_freeName = false; + m_autoWrapProperties = true; + m_customPrefix = "Substance Sample "; + m_drawPrecisionUI = false; + m_showPreview = true; + m_drawPreviewExpander = false; + m_selectedLocation = PreviewLocation.TopCenter; + m_cacheNodeConnections = new CacheNodeConnections(); + m_previewShaderGUID = "6f322c1da33f1e744941aafcb0ad1a2d"; + m_showAutoRegisterUI = false; + } + + public override void RenderNodePreview() + { + if( !m_initialized ) + return; + + SetPreviewInputs(); + PreviewMaterial.SetInt( "_CustomUVs", m_inputPorts[ 0 ].IsConnected ? 1 : 0 ); + + if( m_substanceGraph == null ) + return; + + List<Texture2D> texs = m_substanceGraph.generatedTextures; + int count = m_outputPorts.Count; + for( int i = 0; i < count; i++ ) + { + RenderTexture temp = RenderTexture.active; + RenderTexture.active = m_outputPorts[ i ].OutputPreviewTexture; + + PreviewMaterial.SetTexture( "_GenTex", texs[ i ] ); + + if( m_autoNormal && m_textureTypes[ i ] == ASEProceduralOutputType.Normal ) + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, 1 ); + else + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, 0 ); + RenderTexture.active = temp; + } + } + + public override void OnOutputPortConnected( int portId, int otherNodeId, int otherPortId ) + { + base.OnOutputPortConnected( portId, otherNodeId, otherPortId ); + m_firstOutputConnected = -1; + } + + public override void OnOutputPortDisconnected( int portId ) + { + base.OnOutputPortDisconnected( portId ); + m_firstOutputConnected = -1; + } + + void CalculateFirstOutputConnected() + { + m_outputConns.Clear(); + int count = m_outputPorts.Count; + bool connectionsAvailable = false; + for( int i = 0; i < count; i++ ) + { + if( m_outputPorts[ i ].IsConnected ) + { + connectionsAvailable = true; + } + } + + for( int i = 0; i < count; i++ ) + { + if( connectionsAvailable ) + { + if( m_outputPorts[ i ].IsConnected ) + { + if( m_firstOutputConnected < 0 ) + m_firstOutputConnected = i; + + m_outputConns.Add( i ); + } + } + else + { + m_outputConns.Add( i ); + } + } + + if( m_firstOutputConnected < 0 ) + m_firstOutputConnected = 0; + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + base.OnNodeLayout( drawInfo ); + + m_previewArea = m_remainingBox; + m_previewArea.width = TexturePreviewSizeX * drawInfo.InvertedZoom; + m_previewArea.height = TexturePreviewSizeY * drawInfo.InvertedZoom; + m_previewArea.x += 0.5f * m_remainingBox.width - 0.5f * m_previewArea.width; + m_pickerArea = m_previewArea; + m_pickerArea.width = 40 * drawInfo.InvertedZoom; + m_pickerArea.x = m_previewArea.xMax - m_pickerArea.width - 2; + m_pickerArea.height = 14 * drawInfo.InvertedZoom; + m_pickerArea.y = m_previewArea.yMax - m_pickerArea.height - 2; + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + base.DrawGUIControls( drawInfo ); + + if( !( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp || drawInfo.CurrentEventType == EventType.ExecuteCommand || drawInfo.CurrentEventType == EventType.DragPerform ) ) + return; + + bool insideBox = m_previewArea.Contains( drawInfo.MousePosition ); + + if( insideBox ) + { + m_editing = true; + } + else if( m_editing && !insideBox && drawInfo.CurrentEventType != EventType.ExecuteCommand ) + { + GUI.FocusControl( null ); + m_editing = false; + } + } + + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + if( m_editing ) + { + m_textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + if( GUI.Button( m_pickerArea, string.Empty, GUIStyle.none ) ) + { + int controlID = EditorGUIUtility.GetControlID( FocusType.Passive ); + EditorGUIUtility.ShowObjectPicker<SubstanceGraph>( m_substanceGraph, false, "", controlID ); + } + + string commandName = Event.current.commandName; + UnityEngine.Object newValue = null; + if( commandName == "ObjectSelectorUpdated" ) + { + newValue = EditorGUIUtility.GetObjectPickerObject(); + if( newValue != (UnityEngine.Object)m_substanceGraph ) + { + UndoRecordObject( "Changing value EditorGUIObjectField on node Substance Sample" ); + + SubstanceGraph = newValue != null ? (SubstanceGraph)newValue : null; + m_textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + OnNewSubstanceSelected( m_textures ); + } + } + else if( commandName == "ObjectSelectorClosed" ) + { + newValue = EditorGUIUtility.GetObjectPickerObject(); + if( newValue != (UnityEngine.Object)m_substanceGraph ) + { + UndoRecordObject( "Changing value EditorGUIObjectField on node Substance Sample" ); + + SubstanceGraph = newValue != null ? (SubstanceGraph)newValue : null; + m_textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + OnNewSubstanceSelected( m_textures ); + } + m_editing = false; + } + + if( GUI.Button( m_previewArea, string.Empty, GUIStyle.none ) ) + { + if( m_substanceGraph != null ) + { + Selection.activeObject = m_substanceGraph; + EditorGUIUtility.PingObject( Selection.activeObject ); + } + m_editing = false; + } + } + + if( drawInfo.CurrentEventType == EventType.Repaint ) + { + if( !m_editing ) + m_textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + + if( m_textures != null ) + { + if( m_firstOutputConnected < 0 ) + { + CalculateFirstOutputConnected(); + } + else if( m_textures.Count != m_textureTypes.Length ) + { + OnNewSubstanceSelected( m_textures ); + } + + int texCount = m_outputConns.Count; + Rect individuals = m_previewArea; + individuals.height /= texCount; + + for( int i = 0; i < texCount; i++ ) + { + EditorGUI.DrawPreviewTexture( individuals, m_textures[ m_outputConns[ i ] ], null, ScaleMode.ScaleAndCrop ); + individuals.y += individuals.height; + } + } + else + { + GUI.Label( m_previewArea, string.Empty, UIUtils.ObjectFieldThumb ); + } + + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 ) + { + Rect smallButton = m_previewArea; + smallButton.height = 14 * drawInfo.InvertedZoom; + smallButton.y = m_previewArea.yMax - smallButton.height - 2; + smallButton.width = 40 * drawInfo.InvertedZoom; + smallButton.x = m_previewArea.xMax - smallButton.width - 2; + if( m_textures == null ) + { + GUI.Label( m_previewArea, "None (Procedural Material)", UIUtils.ObjectFieldThumbOverlay ); + } + GUI.Label( m_pickerArea, "Select", UIUtils.GetCustomStyle( CustomStyle.SamplerButton ) ); + } + + GUI.Label( m_previewArea, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) ); + } + } + + void OnNewSubstanceSelected( List<Texture2D> textures ) + { + CacheCurrentSettings(); + ConfigPortsFromMaterial( true, textures ); + ConnectFromCache(); + m_requireMaterialUpdate = true; + CalculateFirstOutputConnected(); + ContainerGraph.ParentWindow.RequestRepaint(); + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUI.BeginChangeCheck(); + SubstanceGraph = EditorGUILayoutObjectField( SubstanceStr, m_substanceGraph, m_type, false ) as SubstanceGraph; + if( EditorGUI.EndChangeCheck() ) + { + List<Texture2D> textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + if( textures != null ) + { + OnNewSubstanceSelected( textures ); + } + } + + m_textureCoordSet = EditorGUILayoutIntPopup( Constants.AvailableUVSetsLabel, m_textureCoordSet, Constants.AvailableUVSetsStr, Constants.AvailableUVSets ); + EditorGUI.BeginChangeCheck(); + m_autoNormal = EditorGUILayoutToggle( AutoNormalStr, m_autoNormal ); + if( EditorGUI.EndChangeCheck() ) + { + for( int i = 0; i < m_textureTypes.Length; i++ ) + { + WirePortDataType portType = ( m_autoNormal && m_textureTypes[ i ] == ASEProceduralOutputType.Normal ) ? WirePortDataType.FLOAT3 : WirePortDataType.COLOR; + if( m_outputPorts[ i ].DataType != portType ) + { + m_outputPorts[ i ].ChangeType( portType, false ); + } + } + } + } + + private void CacheCurrentSettings() + { + m_cacheNodeConnections.Clear(); + for( int portId = 0; portId < m_outputPorts.Count; portId++ ) + { + if( m_outputPorts[ portId ].IsConnected ) + { + int connCount = m_outputPorts[ portId ].ConnectionCount; + for( int connIdx = 0; connIdx < connCount; connIdx++ ) + { + WireReference connection = m_outputPorts[ portId ].GetConnection( connIdx ); + m_cacheNodeConnections.Add( m_outputPorts[ portId ].Name, new NodeCache( connection.NodeId, connection.PortId ) ); + } + } + } + } + + private void ConnectFromCache() + { + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + List<NodeCache> connections = m_cacheNodeConnections.GetList( m_outputPorts[ i ].Name ); + if( connections != null ) + { + int count = connections.Count; + for( int connIdx = 0; connIdx < count; connIdx++ ) + { + UIUtils.SetConnection( connections[ connIdx ].TargetNodeId, connections[ connIdx ].TargetPortId, UniqueId, i ); + } + } + } + } + + + private void ConfigPortsFromMaterial( bool invalidateConnections = false, List<Texture2D> newTextures = null ) + { + SetAdditonalTitleText( ( m_substanceGraph != null ) ? string.Format( Constants.PropertyValueLabel, m_substanceGraph.name ) : "Value( <None> )" ); + + List<Texture2D> textures = newTextures != null ? newTextures : ( ( m_substanceGraph != null ) ? m_substanceGraph.generatedTextures : null ); + if( textures != null ) + { + m_firstOutputConnected = -1; + string nameToRemove = m_substanceGraph.graphLabel + "_"; + m_textureTypes = new ASEProceduralOutputType[ textures.Count ]; + for( int i = 0; i < textures.Count; i++ ) + { + //TODO: Replace for a more efficient test as soon as Laurent gives more infos + m_textureTypes[ i ] = textures[ i ].name.EndsWith( NormalMapCheck )?ASEProceduralOutputType.Normal:ASEProceduralOutputType.Color; + + WirePortDataType portType = ( m_autoNormal && m_textureTypes[ i ] == ASEProceduralOutputType.Normal ) ? WirePortDataType.FLOAT3 : WirePortDataType.COLOR; + string newName = textures[ i ].name.Replace( nameToRemove, string.Empty ); + char firstLetter = Char.ToUpper( newName[ 0 ] ); + newName = firstLetter.ToString() + newName.Substring( 1 ); + if( i < m_outputPorts.Count ) + { + m_outputPorts[ i ].ChangeProperties( newName, portType, false ); + if( invalidateConnections ) + { + m_outputPorts[ i ].FullDeleteConnections(); + } + } + else + { + AddOutputPort( portType, newName ); + } + } + + if( textures.Count < m_outputPorts.Count ) + { + int itemsToRemove = m_outputPorts.Count - textures.Count; + for( int i = 0; i < itemsToRemove; i++ ) + { + int idx = m_outputPorts.Count - 1; + if( m_outputPorts[ idx ].IsConnected ) + { + m_outputPorts[ idx ].ForceClearConnection(); + } + RemoveOutputPort( idx ); + } + } + } + else + { + int itemsToRemove = m_outputPorts.Count - 1; + m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.COLOR, false ); + m_outputPorts[ 0 ].ForceClearConnection(); + + for( int i = 0; i < itemsToRemove; i++ ) + { + int idx = m_outputPorts.Count - 1; + if( m_outputPorts[ idx ].IsConnected ) + { + m_outputPorts[ idx ].ForceClearConnection(); + } + RemoveOutputPort( idx ); + } + } + + m_sizeIsDirty = true; + m_isDirty = true; + } + + private void ConfigFromObject( UnityEngine.Object obj ) + { + SubstanceGraph newGraph = obj as SubstanceGraph;// AssetDatabase.LoadAssetAtPath<SubstanceGraph>( AssetDatabase.GetAssetPath( obj ) ); + if( newGraph != null ) + { + SubstanceGraph = newGraph; + ConfigPortsFromMaterial(); + } + + Substance.Game.Substance newSubstance = obj as Substance.Game.Substance;// AssetDatabase.LoadAssetAtPath<SubstanceGraph>( AssetDatabase.GetAssetPath( obj ) ); + if( newSubstance != null && newSubstance.graphs.Count > 0 ) + { + SubstanceGraph = newSubstance.graphs[0]; + ConfigPortsFromMaterial(); + } + + } + + public override void OnObjectDropped( UnityEngine.Object obj ) + { + ConfigFromObject( obj ); + } + + public override void SetupFromCastObject( UnityEngine.Object obj ) + { + ConfigFromObject( obj ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_substanceGraph == null ) + { + return "(0).xxxx"; + } + + if( m_outputPorts[ outputId ].IsLocalValue( dataCollector.PortCategory ) ) + { + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + List<Texture2D> textures = m_substanceGraph.generatedTextures; + + string uvPropertyName = string.Empty; + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + if( m_outputPorts[ i ].HasConnectedNode ) + { + uvPropertyName = UIUtils.GeneratePropertyName( textures[ i ].name , PropertyType.Property ); + break; + } + } + + string propertyName = UIUtils.GeneratePropertyName( textures[ outputId ].name, PropertyType.Property ); + string name = propertyName + OutputId; + dataCollector.AddToUniforms( UniqueId, string.Format( GlobalVarDecStr, propertyName ) ); + dataCollector.AddToProperties( UniqueId, string.Format( PropertyDecStr, propertyName, textures[ outputId ].name ) + "{}", -1 ); + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + string value = string.Format( "tex2D{0}({1}, {2})", ( isVertex ? "lod" : string.Empty ), propertyName, GetUVCoords( ref dataCollector, ignoreLocalvar, uvPropertyName ) ); + if( m_autoNormal && m_textureTypes[ outputId ] == ASEProceduralOutputType.Normal ) + { + value = string.Format( TemplateHelperFunctions.CreateUnpackNormalStr( dataCollector, false, "1.0" ), value ); + } + + dataCollector.AddPropertyNode( this ); + RegisterLocalVariable( outputId, value, ref dataCollector, name ); + + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + public string GetUVCoords( ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar, string propertyName ) + { + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + if( m_inputPorts[ 0 ].IsConnected ) + { + return m_inputPorts[ 0 ].GenerateShaderForOutput( ref dataCollector, isVertex ? WirePortDataType.FLOAT4 : WirePortDataType.FLOAT2, ignoreLocalVar, true ); + } + else + { + string uvChannelName = IOUtils.GetUVChannelName( propertyName, m_textureCoordSet ); + + if( dataCollector.IsTemplate ) + { + string propertyHelperVar = propertyName + "_ST"; + dataCollector.AddToUniforms( UniqueId, "float4", propertyHelperVar, dataCollector.IsSRP ); + string uvName = string.Empty; + if( dataCollector.TemplateDataCollectorInstance.HasUV( m_textureCoordSet ) ) + { + uvName = dataCollector.TemplateDataCollectorInstance.GetUVName( m_textureCoordSet ); + } + else + { + uvName = dataCollector.TemplateDataCollectorInstance.RegisterUV( m_textureCoordSet ); + } + + uvChannelName = "uv" + propertyName; + if( isVertex ) + { + string value = string.Format( Constants.TilingOffsetFormat, uvName, propertyHelperVar + ".xy", propertyHelperVar + ".zw" ); + string lodLevel = "0"; + + value = "float4( " + value + ", 0 , " + lodLevel + " )"; + dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, WirePortDataType.FLOAT4, uvChannelName, value ); + } + else + { + dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, WirePortDataType.FLOAT2, uvChannelName, string.Format( Constants.TilingOffsetFormat, uvName, propertyHelperVar + ".xy", propertyHelperVar + ".zw" ) ); + } + } + else + { + string vertexCoords = Constants.VertexShaderInputStr + ".texcoord"; + if( m_textureCoordSet > 0 ) + { + vertexCoords += m_textureCoordSet.ToString(); + } + + + string dummyPropUV = "_texcoord" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ); + string dummyUV = "uv" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ) + dummyPropUV; + + dataCollector.AddToUniforms( UniqueId, "uniform float4 " + propertyName + "_ST;" ); + dataCollector.AddToProperties( UniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 100 ); + dataCollector.AddToInput( UniqueId, dummyUV, WirePortDataType.FLOAT2 ); + + if( isVertex ) + { + dataCollector.AddToVertexLocalVariables( UniqueId, "float4 " + uvChannelName + " = float4(" + vertexCoords + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw, 0 ,0);" ); + return uvChannelName; + } + else + dataCollector.AddToLocalVariables( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvChannelName, Constants.InputVarStr + "." + dummyUV + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw" ); + + } + + return uvChannelName; + } + } + + public override void UpdateMaterial( Material mat ) + { + base.UpdateMaterial( mat ); + if( m_substanceGraph != null ) + { + List<Texture2D> textures = m_substanceGraph.generatedTextures; + for( int i = 0; i < textures.Count; i++ ) + { + string textureName = UIUtils.GeneratePropertyName( textures[ i ].name, PropertyType.Property ); + if( mat.HasProperty( textureName ) && !InsideShaderFunction ) + { + mat.SetTexture( textureName, textures[ i ] ); + } + } + } + } + + public override bool UpdateShaderDefaults( ref Shader shader, ref TextureDefaultsDataColector defaultCol ) + { + if( m_substanceGraph != null ) + { + List<Texture2D> textures = m_substanceGraph.generatedTextures; + for( int i = 0; i < textures.Count; i++ ) + { + defaultCol.AddValue( UIUtils.GeneratePropertyName( textures[ i ].name, PropertyType.Property ), textures[ i ] ); + } + } + return true; + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + if( m_substanceGraph == null && !string.IsNullOrEmpty( m_substanceGUID ) ) + { + SubstanceGraph = AssetDatabase.LoadAssetAtPath<SubstanceGraph>( AssetDatabase.GUIDToAssetPath( m_substanceGUID ) ); + if( m_substanceGraph == null ) + { + m_substanceGUID = string.Empty; + } + } + } + + public override void Destroy() + { + base.Destroy(); + m_textures = null; + m_substanceGraph = null; + m_substanceGUID = string.Empty; + m_cacheNodeConnections.Clear(); + m_cacheNodeConnections = null; + m_outputConns.Clear(); + m_outputConns = null; + } + + public override string GetPropertyValStr() + { + return m_substanceGraph ? m_substanceGraph.name : string.Empty; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + string guid = GetCurrentParam( ref nodeParams ); + m_textureCoordSet = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_autoNormal = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + if( guid.Length > 1 ) + { + SubstanceGraph = AssetDatabase.LoadAssetAtPath<SubstanceGraph>( AssetDatabase.GUIDToAssetPath( guid ) ); + if( m_substanceGraph != null ) + { + ConfigPortsFromMaterial(); + } + else + { + UIUtils.ShowMessage( "Substance not found ", MessageSeverity.Error ); + } + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + string guid = ( m_substanceGraph != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_substanceGraph ) ) : "0"; + IOUtils.AddFieldValueToString( ref nodeInfo, guid ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_textureCoordSet ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autoNormal ); + } + + public SubstanceGraph SubstanceGraph + { + set + { + m_substanceGraph = value; + if( value != null ) + { + m_substanceGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( value ) ); + } + else + { + m_substanceGUID = string.Empty; + } + } + get { return m_substanceGraph; } + } + } +#pragma warning restore 0618 +} +#endif |