TemplateInterpData.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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 UnityEngine;
  6. namespace AmplifyShaderEditor
  7. {
  8. [Serializable]
  9. public class TemplateInterpElement
  10. {
  11. public TemplateSemantics Semantic;
  12. public bool[] AvailableChannels = { true, true, true, true };
  13. public bool IsFull = false;
  14. public int Usage = 0;
  15. public string Name;
  16. //https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-struct
  17. public bool NoInterpolation;
  18. public bool Sample;
  19. public TemplateInterpElement( TemplateInterpElement other )
  20. {
  21. Semantic = other.Semantic;
  22. for ( int i = 0; i < AvailableChannels.Length; i++ )
  23. {
  24. AvailableChannels[ i ] = other.AvailableChannels[ i ];
  25. }
  26. IsFull = other.IsFull;
  27. Usage = other.Usage;
  28. Name = other.Name;
  29. NoInterpolation = other.NoInterpolation;
  30. Sample = other.Sample;
  31. }
  32. public TemplateInterpElement( TemplateSemantics semantic )
  33. {
  34. Semantic = semantic;
  35. int semanticId = TemplateHelperFunctions.SemanticToInt[ Semantic ];
  36. Name = ( semanticId == 0 ) ? TemplateHelperFunctions.BaseInterpolatorName : TemplateHelperFunctions.BaseInterpolatorName + semanticId.ToString();
  37. }
  38. public void SetAvailableChannelsFromString( string channels )
  39. {
  40. for ( int i = 0; i < AvailableChannels.Length; i++ )
  41. {
  42. AvailableChannels[ i ] = false;
  43. }
  44. Usage = AvailableChannels.Length;
  45. for ( int i = 0; i < channels.Length; i++ )
  46. {
  47. switch ( channels[ i ] )
  48. {
  49. case 'x': if ( !AvailableChannels[ 0 ] ) { AvailableChannels[ 0 ] = true; Usage--; } break;
  50. case 'y': if ( !AvailableChannels[ 1 ] ) { AvailableChannels[ 1 ] = true; Usage--; } break;
  51. case 'z': if ( !AvailableChannels[ 2 ] ) { AvailableChannels[ 2 ] = true; Usage--; } break;
  52. case 'w': if ( !AvailableChannels[ 3 ] ) { AvailableChannels[ 3 ] = true; Usage--; } break;
  53. }
  54. }
  55. }
  56. public TemplateVertexData RequestChannels( WirePortDataType type, bool isColor, string customName = null )
  57. {
  58. if ( IsFull )
  59. return null;
  60. int channelsRequired = TemplateHelperFunctions.DataTypeChannelUsage[ type ];
  61. if ( channelsRequired == 0 )
  62. return null;
  63. int firstChannel = -1;
  64. for ( int i = 0; i < AvailableChannels.Length; i++ )
  65. {
  66. if ( AvailableChannels[ i ] )
  67. {
  68. if ( firstChannel < 0 )
  69. {
  70. firstChannel = i;
  71. }
  72. channelsRequired -= 1;
  73. if ( channelsRequired == 0 )
  74. break;
  75. }
  76. }
  77. //did not found enough channels to fill request
  78. if ( channelsRequired > 0 )
  79. return null;
  80. if( Usage == 0 && customName != null )
  81. {
  82. Name = customName;
  83. }
  84. Usage += 1;
  85. TemplateVertexData data = null;
  86. if ( type == WirePortDataType.COLOR || type == WirePortDataType.FLOAT4 )
  87. {
  88. // Automatically lock all channels
  89. for ( int i = firstChannel; i < ( firstChannel + channelsRequired ); i++ )
  90. {
  91. AvailableChannels[ i ] = false;
  92. }
  93. IsFull = true;
  94. data = new TemplateVertexData( Semantic, type, Name );
  95. }
  96. else
  97. {
  98. string[] swizzleArray = ( isColor ) ? TemplateHelperFunctions.ColorSwizzle : TemplateHelperFunctions.VectorSwizzle;
  99. string channels = ".";
  100. int count = firstChannel + TemplateHelperFunctions.DataTypeChannelUsage[ type ];
  101. for ( int i = firstChannel; i < count; i++ )
  102. {
  103. AvailableChannels[ i ] = false;
  104. channels += swizzleArray[ i ];
  105. if ( i == ( AvailableChannels.Length - 1 ) )
  106. {
  107. IsFull = true;
  108. }
  109. }
  110. data = new TemplateVertexData( Semantic, type, Name, channels );
  111. }
  112. return data;
  113. }
  114. }
  115. [Serializable]
  116. public class TemplateInterpData
  117. {
  118. [SerializeField]
  119. private string m_interpDataId = string.Empty;
  120. [SerializeField]
  121. private int m_interpDataStartIdx = -1;
  122. [SerializeField]
  123. private bool m_dynamicMax = false;
  124. public List<TemplateInterpElement> AvailableInterpolators = new List<TemplateInterpElement>();
  125. public List<TemplateVertexData> Interpolators = new List<TemplateVertexData>();
  126. public List<TemplateVertexData> RawInterpolators = new List<TemplateVertexData>();
  127. public TemplateInterpData() { }
  128. public bool HasRawInterpolatorOfName( string name )
  129. {
  130. return RawInterpolators.Exists( ( x ) => x.VarName.Equals( name ));
  131. }
  132. public TemplateInterpData( TemplateInterpData other )
  133. {
  134. m_dynamicMax = other.DynamicMax;
  135. foreach ( TemplateInterpElement data in other.AvailableInterpolators )
  136. {
  137. AvailableInterpolators.Add( new TemplateInterpElement( data ) );
  138. }
  139. for ( int i = 0; i < other.Interpolators.Count; i++ )
  140. {
  141. Interpolators.Add( new TemplateVertexData( other.Interpolators[ i ] ) );
  142. }
  143. for( int i = 0; i < other.RawInterpolators.Count; i++ )
  144. {
  145. RawInterpolators.Add( new TemplateVertexData( other.RawInterpolators[ i ] ) );
  146. }
  147. }
  148. public void RecalculateAvailableInterpolators( int newMax )
  149. {
  150. if( m_dynamicMax )
  151. {
  152. if( !TemplateHelperFunctions.IntToSemantic.ContainsKey( ( newMax - 1 ) ) )
  153. {
  154. Debug.LogWarning( "Attempting to add inexisting available interpolators" );
  155. return;
  156. }
  157. if( AvailableInterpolators.Count > 0 )
  158. {
  159. int currMax = 1 + TemplateHelperFunctions.SemanticToInt[ AvailableInterpolators[ AvailableInterpolators.Count - 1 ].Semantic ];
  160. if( newMax > currMax )
  161. {
  162. int count = newMax - currMax;
  163. for( int i = 0; i < count; i++ )
  164. {
  165. AvailableInterpolators.Add( new TemplateInterpElement( TemplateHelperFunctions.IntToSemantic[ currMax + i ] ));
  166. }
  167. }
  168. else if( newMax < currMax )
  169. {
  170. int min = TemplateHelperFunctions.SemanticToInt[ AvailableInterpolators[ 0 ].Semantic ];
  171. if( newMax > min )
  172. {
  173. int count = currMax - newMax;
  174. for( int i = 0; i < count; i++ )
  175. {
  176. AvailableInterpolators.RemoveAt( AvailableInterpolators.Count - 1 );
  177. }
  178. }
  179. }
  180. }
  181. }
  182. }
  183. public void ReplaceNameOnInterpolator( TemplateSemantics semantic, string newName )
  184. {
  185. for ( int i = 0; i < AvailableInterpolators.Count; i++ )
  186. {
  187. if ( AvailableInterpolators[ i ].Semantic == semantic )
  188. {
  189. AvailableInterpolators[ i ].Name = newName;
  190. break;
  191. }
  192. }
  193. }
  194. public void Destroy()
  195. {
  196. AvailableInterpolators.Clear();
  197. AvailableInterpolators = null;
  198. Interpolators.Clear();
  199. Interpolators = null;
  200. RawInterpolators.Clear();
  201. RawInterpolators = null;
  202. }
  203. public string InterpDataId { get { return m_interpDataId; } set { m_interpDataId = value; } }
  204. public int InterpDataStartIdx { get { return m_interpDataStartIdx; } set { m_interpDataStartIdx = value; } }
  205. public bool DynamicMax { get { return m_dynamicMax; } set { m_dynamicMax = value; } }
  206. }
  207. }