A game about forced loneliness, made by TACStudios
at master 145 lines 5.3 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using UnityEditor.Graphing; 5using UnityEditor.ShaderGraph.Drawing.Slots; 6using UnityEditor.ShaderGraph.Internal; 7using UnityEngine; 8 9using UnityEngine.UIElements; 10 11namespace UnityEditor.ShaderGraph 12{ 13 [Serializable] 14 class DynamicVectorMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4> 15 { 16 [SerializeField] 17 private Vector4 m_Value; 18 19 [SerializeField] 20 private Vector4 m_DefaultValue = Vector4.zero; 21 22 static readonly string[] k_Labels = { "X", "Y", "Z", "W" }; 23 24 private ConcreteSlotValueType m_ConcreteValueType = ConcreteSlotValueType.Vector1; 25 26 public DynamicVectorMaterialSlot() 27 { 28 } 29 30 public DynamicVectorMaterialSlot( 31 int slotId, 32 string displayName, 33 string shaderOutputName, 34 SlotType slotType, 35 Vector4 value, 36 ShaderStageCapability stageCapability = ShaderStageCapability.All, 37 bool hidden = false) 38 : base(slotId, displayName, shaderOutputName, slotType, stageCapability, hidden) 39 { 40 m_Value = value; 41 } 42 43 public Vector4 defaultValue { get { return m_DefaultValue; } } 44 45 public Vector4 value 46 { 47 get { return m_Value; } 48 set { m_Value = value; } 49 } 50 51 public override bool isDefaultValue => value.Equals(defaultValue); 52 53 public override VisualElement InstantiateControl() 54 { 55 var labels = k_Labels.Take(concreteValueType.GetChannelCount()).ToArray(); 56 return new MultiFloatSlotControlView(owner, labels, () => value, (newValue) => value = newValue); 57 } 58 59 public override SlotValueType valueType { get { return SlotValueType.DynamicVector; } } 60 61 public override ConcreteSlotValueType concreteValueType 62 { 63 get { return m_ConcreteValueType; } 64 } 65 66 public void SetConcreteType(ConcreteSlotValueType valueType) 67 { 68 m_ConcreteValueType = valueType; 69 } 70 71 public override void GetPreviewProperties(List<PreviewProperty> properties, string name) 72 { 73 var propType = concreteValueType.ToPropertyType(); 74 var pp = new PreviewProperty(propType) { name = name }; 75 if (propType == PropertyType.Float) 76 pp.floatValue = value.x; 77 else 78 pp.vector4Value = new Vector4(value.x, value.y, value.z, value.w); 79 properties.Add(pp); 80 } 81 82 protected override string ConcreteSlotValueAsVariable() 83 { 84 var channelCount = SlotValueHelper.GetChannelCount(concreteValueType); 85 string values = NodeUtils.FloatToShaderValue(value.x); 86 if (channelCount == 1) 87 return string.Format("$precision({0})", values); 88 for (var i = 1; i < channelCount; i++) 89 values += ", " + NodeUtils.FloatToShaderValue(value[i]); 90 return string.Format("$precision{0}({1})", channelCount, values); 91 } 92 93 public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode) 94 { 95 if (!generationMode.IsPreview()) 96 return; 97 98 var matOwner = owner as AbstractMaterialNode; 99 if (matOwner == null) 100 throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode))); 101 102 AbstractShaderProperty property; 103 switch (concreteValueType) 104 { 105 case ConcreteSlotValueType.Vector4: 106 property = new Vector4ShaderProperty(); 107 break; 108 case ConcreteSlotValueType.Vector3: 109 property = new Vector3ShaderProperty(); 110 break; 111 case ConcreteSlotValueType.Vector2: 112 property = new Vector2ShaderProperty(); 113 break; 114 case ConcreteSlotValueType.Vector1: 115 property = new Vector1ShaderProperty(); 116 break; 117 default: 118 // This shouldn't happen due to edge validation. The generated shader will 119 // have errors. 120 Debug.LogError($"Invalid value type {concreteValueType} passed to Vector Slot {displayName}. Value will be ignored, please plug in an edge with a vector type."); 121 return; 122 } 123 124 property.overrideReferenceName = matOwner.GetVariableNameForSlot(id); 125 property.generatePropertyBlock = false; 126 properties.AddShaderProperty(property); 127 } 128 129 public override void CopyValuesFrom(MaterialSlot foundSlot) 130 { 131 var slot = foundSlot as DynamicVectorMaterialSlot; 132 if (slot != null) 133 value = slot.value; 134 } 135 136 public override void CopyDefaultValue(MaterialSlot other) 137 { 138 base.CopyDefaultValue(other); 139 if (other is IMaterialSlotHasValue<Vector4> ms) 140 { 141 m_DefaultValue = ms.defaultValue; 142 } 143 } 144 } 145}