A game about forced loneliness, made by TACStudios
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 DynamicValueMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
15 {
16 [SerializeField]
17 private Matrix4x4 m_Value;
18
19 [SerializeField]
20 private Matrix4x4 m_DefaultValue = Matrix4x4.identity;
21
22 static readonly string[] k_Labels = { "X", "Y", "Z", "W" };
23
24 private ConcreteSlotValueType m_ConcreteValueType = ConcreteSlotValueType.Vector4;
25
26 public DynamicValueMaterialSlot()
27 {
28 }
29
30 public DynamicValueMaterialSlot(
31 int slotId,
32 string displayName,
33 string shaderOutputName,
34 SlotType slotType,
35 Matrix4x4 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 Matrix4x4 defaultValue { get { return m_DefaultValue; } }
44
45 public Matrix4x4 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.GetRow(0), (newValue) =>
57 value = new Matrix4x4()
58 {
59 m00 = newValue.x,
60 m01 = newValue.y,
61 m02 = newValue.z,
62 m03 = newValue.w,
63 m10 = value.m10,
64 m11 = value.m11,
65 m12 = value.m12,
66 m13 = value.m13,
67 m20 = value.m20,
68 m21 = value.m21,
69 m22 = value.m22,
70 m23 = value.m23,
71 m30 = value.m30,
72 m31 = value.m31,
73 m32 = value.m32,
74 m33 = value.m33,
75 });
76 }
77
78 public override SlotValueType valueType { get { return SlotValueType.Dynamic; } }
79
80 public override ConcreteSlotValueType concreteValueType
81 {
82 get { return m_ConcreteValueType; }
83 }
84
85 public void SetConcreteType(ConcreteSlotValueType valueType)
86 {
87 m_ConcreteValueType = valueType;
88 }
89
90 public override void GetPreviewProperties(List<PreviewProperty> properties, string name)
91 {
92 var propType = concreteValueType.ToPropertyType();
93 var pp = new PreviewProperty(propType) { name = name };
94 if (propType == PropertyType.Float)
95 pp.floatValue = value.m00;
96 else
97 pp.vector4Value = new Vector4(value.m00, value.m01, value.m02, value.m03);
98 properties.Add(pp);
99 }
100
101 protected override string ConcreteSlotValueAsVariable()
102 {
103 var channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
104 string values = NodeUtils.FloatToShaderValue(value.m00);
105 if (channelCount == 1)
106 return values;
107 for (var i = 1; i < channelCount; i++)
108 values += ", " + NodeUtils.FloatToShaderValue(value.GetRow(0)[i]);
109 return string.Format("$precision{0}({1})", channelCount, values);
110 }
111
112 public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
113 {
114 if (!generationMode.IsPreview())
115 return;
116
117 var matOwner = owner as AbstractMaterialNode;
118 if (matOwner == null)
119 throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
120
121 AbstractShaderProperty property;
122 switch (concreteValueType)
123 {
124 case ConcreteSlotValueType.Vector4:
125 property = new Vector4ShaderProperty();
126 break;
127 case ConcreteSlotValueType.Vector3:
128 property = new Vector3ShaderProperty();
129 break;
130 case ConcreteSlotValueType.Vector2:
131 property = new Vector2ShaderProperty();
132 break;
133 case ConcreteSlotValueType.Vector1:
134 property = new Vector1ShaderProperty();
135 break;
136 case ConcreteSlotValueType.Matrix4:
137 property = new Matrix4ShaderProperty();
138 break;
139 case ConcreteSlotValueType.Matrix3:
140 property = new Matrix3ShaderProperty();
141 break;
142 case ConcreteSlotValueType.Matrix2:
143 property = new Matrix2ShaderProperty();
144 break;
145 default:
146 throw new ArgumentOutOfRangeException();
147 }
148
149 property.overrideReferenceName = matOwner.GetVariableNameForSlot(id);
150 property.generatePropertyBlock = false;
151 properties.AddShaderProperty(property);
152 }
153
154 public override void CopyValuesFrom(MaterialSlot foundSlot)
155 {
156 var slot = foundSlot as DynamicValueMaterialSlot;
157 if (slot != null)
158 value = slot.value;
159 }
160
161 public override void CopyDefaultValue(MaterialSlot other)
162 {
163 base.CopyDefaultValue(other);
164 if (other is IMaterialSlotHasValue<Matrix4x4> ms)
165 {
166 m_DefaultValue = ms.defaultValue;
167 }
168 }
169 }
170}