浏览代码

[material graph]Fix serialization issues + start adding unit tests

/main
Tim Cooper 8 年前
当前提交
cf6628c6
共有 38 个文件被更改,包括 978 次插入45 次删除
  1. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/AbstractMaterialGraph.cs
  2. 3
      UnityProject/Assets/UnityShaderEditor/Editor/Source/AssetCallbacks/CreateShaderGraph.cs
  3. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs
  4. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs
  5. 9
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Editors/MaterialGraphEditor.cs
  6. 22
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraph.cs
  7. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbstractMaterialNode.cs
  8. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaterialSlot.cs
  9. 3
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs
  10. 3
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs
  11. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/PixelGraph.cs
  12. 28
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/SerializationHelper.cs
  13. 5
      UnityProject/Assets/UnityShaderEditor/Editor/Testing/ShaderGeneration/ShaderGenerationTest.cs
  14. 25
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphAsset.cs
  15. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphAsset.cs.meta
  16. 9
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph.meta
  17. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/SerializationHelper.cs.meta
  18. 9
      UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests.meta
  19. 30
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/Edge.cs
  20. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/Edge.cs.meta
  21. 9
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/GUIModificationType.cs
  22. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/GUIModificationType.cs.meta
  23. 102
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs
  24. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs.meta
  25. 156
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs
  26. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs.meta
  27. 233
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs
  28. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs.meta
  29. 68
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs
  30. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs.meta
  31. 44
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs
  32. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs.meta
  33. 11
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/TitleAttribute.cs
  34. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/TitleAttribute.cs.meta
  35. 96
      UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs
  36. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs.meta

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/AbstractMaterialGraph.cs


[Serializable]
public abstract class AbstractMaterialGraph : SerializableGraph
{
[NonSerialized]
[NonSerialized]
private MaterialGraph m_Owner;
protected AbstractMaterialGraph(MaterialGraph owner)

public MaterialGraph owner
{
get { return m_Owner; }
get { return m_Owner; }
set { m_Owner = value; }
public override void AddNode(SerializableNode node)
{
if (node is AbstractMaterialNode)

3
UnityProject/Assets/UnityShaderEditor/Editor/Source/AssetCallbacks/CreateShaderGraph.cs


public override void Action(int instanceId, string pathName, string resourceFile)
{
var graph = CreateInstance<MaterialGraph>();
var graph = CreateInstance<MaterialGraphAsset>();
graph.PostCreate();
}
}
}

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs


translation = node.position.min;
scale = new Vector2(width, width);
m_Node = node;
m_Node = node;
m_Node.onNeedsRepaint += Invalidate;
m_Node.onNeedsRepaint += Invalidate;
const float yStart = 10.0f;
var vector3 = new Vector3(5.0f, yStart, 0.0f);

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs


if (Selection.activeObject == null || !EditorUtility.IsPersistent(Selection.activeObject))
return;
if (Selection.activeObject is MaterialGraph)
if (Selection.activeObject is MaterialGraphAsset)
var selection = Selection.activeObject as MaterialGraph;
if (selection != m_MaterialGraph)
var selection = Selection.activeObject as MaterialGraphAsset;
if (selection.graph != m_MaterialGraph)
m_MaterialGraph = selection;
m_MaterialGraph = selection.graph;
}
}

9
UnityProject/Assets/UnityShaderEditor/Editor/Source/Editors/MaterialGraphEditor.cs


namespace UnityEditor.MaterialGraph
{
[CustomEditor(typeof (MaterialGraph), true)]
[CustomEditor(typeof (MaterialGraphAsset), true)]
internal class MaterialGraphEditor : Editor
{
private PreviewRenderUtility m_PreviewUtility;

private void DoRenderPreview()
{
var materialGraph = target as MaterialGraph;
var materialGraph = target as MaterialGraphAsset;
Material mat = materialGraph.GetMaterial();
m_PreviewUtility.m_Camera.transform.position = -Vector3.forward * 5;
m_PreviewUtility.m_Camera.transform.rotation = Quaternion.identity;
m_PreviewUtility.m_Light[0].intensity = 1.0f;

m_PreviewUtility.m_Camera.transform.position = Quaternion.Inverse(rot) * m_PreviewUtility.m_Camera.transform.position;
m_PreviewUtility.m_Camera.transform.LookAt(Vector3.zero);
rot = Quaternion.identity;
m_PreviewUtility.DrawMesh(mesh, Vector3.zero, rot, mat, 0);
m_PreviewUtility.DrawMesh(mesh, Vector3.zero, rot, materialGraph.GetMaterial(), 0);
bool oldFog = RenderSettings.fog;
Unsupported.SetRenderSettingsUseFogNoDirty(false);

22
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraph.cs


namespace UnityEditor.MaterialGraph
{
public class MaterialGraph : ScriptableObject, ISerializationCallbackReceiver
[Serializable]
public class MaterialGraph : ISerializationCallbackReceiver
[NonSerialized]
private Material m_Material;
[SerializeField]
private MaterialOptions m_MaterialOptions = new MaterialOptions();

private MaterialGraph()
[SerializeField]
private string m_Name;
public string name
{
get { return m_Name; }
set { m_Name = value; }
}
public MaterialGraph()
{
m_PixelGraph = new PixelGraph(this);
}

shaderImporter.SetNonModifiableTextures(textureNames.ToArray(), textures.ToArray());
shaderImporter.SaveAndReimport();
}
public void PostCreate()
{
m_PixelGraph.AddNode(new PixelShaderNode(m_PixelGraph));
}
}
}

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbstractMaterialNode.cs


private bool m_HasError;
[SerializeField]
private string m_LastShader;
private string m_LastShader;
[NonSerialized]
private Material m_PreviewMaterial;

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaterialSlot.cs


m_CurrentValue = defaultValue;
}
internal MaterialSlot (AbstractMaterialNode owner) : base (owner)
public MaterialSlot (AbstractMaterialNode owner) : base (owner)
{ }
public Vector4 defaultValue

}
public SlotValueType valueType
{
{
get { return m_ValueType; }
set { m_ValueType = value; }
}

3
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs


{
[SerializeField]
public string m_LightFunctionClassName;
private string lightFunctionClassName
{
get { return m_LightFunctionClassName; }

public override bool canDeleteNode { get { return false; } }
private static List<BaseLightFunction> GetLightFunctions()
{
if (s_LightFunctions == null)

3
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs


m_Value = EditorGUI.Vector4Field(new Rect(drawArea.x, drawArea.y, drawArea.width, EditorGUIUtility.singleLineHeight), "Value", m_Value);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(materialGraphOwner.owner);
//TODO:tidy this shit.
//EditorUtility.SetDirty(materialGraphOwner.owner);
return GUIModificationType.Repaint;
}
return GUIModificationType.None;

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/PixelGraph.cs


return m_PixelMasterNode;
}
}
[NonSerialized]
private List<SerializableNode> m_ActiveNodes = new List<SerializableNode>();

return m_ActiveNodes.OfType<AbstractMaterialNode>();
}
}
public MaterialGraph owner { get; set; }
public void GenerateSurfaceShader(
ShaderGenerator shaderBody,
ShaderGenerator inputStruct,

28
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/SerializationHelper.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace UnityEditor.MaterialGraph

return result;
}
public static List<T> Deserialize<T>(List<JSONSerializedElement> list, object[] constructorArgs)
public static List<T> Deserialize<T>(List<JSONSerializedElement> list, object[] constructorArgs) where T : class
Type[] types = constructorArgs.Select(x => x.GetType()).ToArray();
foreach (var element in list)
foreach (var element in list)
{
if (string.IsNullOrEmpty(element.typeName) || string.IsNullOrEmpty(element.JSONnodeData))
continue;

T instance;
try
{
var constructorInfo = type.GetConstructor(types);
instance = (T) constructorInfo.Invoke(constructorArgs);
{
instance = Activator.CreateInstance(type, constructorArgs) as T;
catch
catch (Exception e)
Debug.LogWarningFormat("Could not construct instance of: {0} as there is no single argument constuctor that takes a AbstractMaterialGraph", type);
Debug.LogWarningFormat("Could not construct instance of: {0} - {1}", type, e);
JsonUtility.FromJsonOverwrite(element.JSONnodeData, instance);
result.Add(instance);
if (instance != null)
{
JsonUtility.FromJsonOverwrite(element.JSONnodeData, instance);
result.Add(instance);
}
return result;
return result;
}
}

5
UnityProject/Assets/UnityShaderEditor/Editor/Testing/ShaderGeneration/ShaderGenerationTest.cs


foreach (var file in filePaths.Where(x => x.Extension == ".ShaderGraph"))
{
var graph = AssetDatabase.LoadAssetAtPath<MaterialGraph>(filePath);
var graph = AssetDatabase.LoadAssetAtPath<MaterialGraphAsset>(filePath);
if (graph == null)
continue;

string shader = ShaderGenerator.GenerateSurfaceShader(graph, graph.name, false, out buff);
string shader = ShaderGenerator.GenerateSurfaceShader(graph.graph, graph.name, false, out buff);
// find the 'reference' shader
var dumpFileLocation = string.Format("{0}.{1}", file, "dump");

25
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphAsset.cs


using UnityEngine;
namespace UnityEditor.MaterialGraph
{
public class MaterialGraphAsset : ScriptableObject
{
[SerializeField]
private MaterialGraph m_MaterialGraph;
public MaterialGraph graph
{
get { return m_MaterialGraph; }
}
public Material GetMaterial()
{
return null;
}
public void PostCreate()
{
m_MaterialGraph.PostCreate();
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphAsset.cs.meta


fileFormatVersion: 2
guid: 74a2b0e5e69571d4184bcdd77764b3b3
timeCreated: 1464081042
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph.meta


fileFormatVersion: 2
guid: a15baf967ea110641b4e31c092c2ed95
folderAsset: yes
timeCreated: 1464081041
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/SerializationHelper.cs.meta


fileFormatVersion: 2
guid: f6657676e9fd9cd4bbcb26b0771df3ac
timeCreated: 1464079585
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests.meta


fileFormatVersion: 2
guid: 7f85ac5340a5dff468e347347435cf68
folderAsset: yes
timeCreated: 1464096294
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

30
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/Edge.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class Edge
{
[SerializeField]
private SlotReference m_OutputSlot;
[SerializeField]
private SlotReference m_InputSlot;
public Edge(SlotReference outputSlot, SlotReference inputSlot)
{
m_OutputSlot = outputSlot;
m_InputSlot = inputSlot;
}
public SlotReference outputSlot
{
get { return m_OutputSlot; }
}
public SlotReference inputSlot
{
get { return m_InputSlot; }
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/Edge.cs.meta


fileFormatVersion: 2
guid: 6b610a05c25f54d4c90f7ebf82696481
timeCreated: 1463576280
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/GUIModificationType.cs


namespace UnityEditor.MaterialGraph
{
public enum GUIModificationType
{
None,
Repaint,
ModelChanged
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/GUIModificationType.cs.meta


fileFormatVersion: 2
guid: c1bef593b05291f46b4bfd7a7192b881
timeCreated: 1464079584
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

102
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs


using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
internal class NodeUtils
{
// GetSlotsThatOutputToNodeRecurse returns a list of output slots on from node that
// manage to connect to toNode... they may go via some other nodes to reach there.
// This is done by working backwards from the toNode to the fromNode as graph is one directional
public static List<SerializableSlot> GetSlotsThatOutputToNodeRecurse(SerializableNode fromNode, SerializableNode toNode)
{
var foundUsedOutputSlots = new List<SerializableSlot>();
RecurseNodesToFindValidOutputSlots(fromNode, toNode, foundUsedOutputSlots);
return foundUsedOutputSlots;
}
public static void RecurseNodesToFindValidOutputSlots(SerializableNode fromNode, SerializableNode currentNode, ICollection<SerializableSlot> foundUsedOutputSlots)
{
if (fromNode == null || currentNode == null)
{
Debug.LogError("Recursing to find valid inputs on NULL node");
return;
}
var validSlots = ListPool<SerializableSlot>.Get();
validSlots.AddRange(currentNode.inputSlots);
for (int index = 0; index < validSlots.Count; index++)
{
var inputSlot = validSlots[index];
var edges = currentNode.owner.GetEdges(inputSlot);
foreach (var edge in edges)
{
var outputNode = currentNode.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var outputSlot = outputNode.FindOutputSlot(edge.outputSlot.slotName);
if (outputNode == fromNode && !foundUsedOutputSlots.Contains(outputSlot))
foundUsedOutputSlots.Add(outputSlot);
else
RecurseNodesToFindValidOutputSlots(fromNode, outputNode, foundUsedOutputSlots);
}
}
ListPool<SerializableSlot>.Release(validSlots);
}
public static void CollectChildNodesByExecutionOrder(List<SerializableNode> nodeList, SerializableNode node, SerializableSlot slotToUse)
{
if (node == null)
return;
if (nodeList.Contains(node))
return;
var validSlots = ListPool<SerializableSlot>.Get();
validSlots.AddRange(node.inputSlots);
if (slotToUse != null && !validSlots.Contains(slotToUse))
{
ListPool<SerializableSlot>.Release(validSlots);
return;
}
if (slotToUse != null)
{
validSlots.Clear();
validSlots.Add(slotToUse);
}
for (int index = 0; index < validSlots.Count; index++)
{
var slot = validSlots[index];
var edges = node.owner.GetEdges(slot);
foreach (var edge in edges)
{
var outputNode = node.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);
CollectChildNodesByExecutionOrder(nodeList, outputNode, null);
}
}
nodeList.Add(node);
ListPool<SerializableSlot>.Release(validSlots);
}
public static void CollectDependentNodes(List<SerializableNode> nodeList, SerializableNode node)
{
if (node == null)
return;
if (nodeList.Contains(node))
return;
foreach (var slot in node.outputSlots)
{
foreach (var edge in node.owner.GetEdges(slot))
{
var inputNode = node.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
CollectDependentNodes(nodeList, inputNode);
}
}
nodeList.Add(node);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs.meta


fileFormatVersion: 2
guid: 992a8f404953a8248b943cb6fb0b2c79
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

156
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class SerializableGraph : ISerializationCallbackReceiver
{
[SerializeField]
private List<Edge> m_Edges = new List<Edge>();
[NonSerialized]
private List<SerializableNode> m_Nodes = new List<SerializableNode>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>();
public IEnumerable<SerializableNode> nodes
{
get { return m_Nodes; }
}
public IEnumerable<Edge> edges
{
get { return m_Edges; }
}
public virtual void AddNode(SerializableNode node)
{
m_Nodes.Add(node);
ValidateGraph();
}
public virtual void RemoveNode(SerializableNode node)
{
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node);
ValidateGraph();
}
private void RemoveNodeNoValidate(SerializableNode node)
{
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node);
}
public virtual Edge Connect(SerializableSlot fromSlot, SerializableSlot toSlot)
{
SerializableSlot outputSlot = null;
SerializableSlot inputSlot = null;
// output must connect to input
if (fromSlot.isOutputSlot)
outputSlot = fromSlot;
else if (fromSlot.isInputSlot)
inputSlot = fromSlot;
if (toSlot.isOutputSlot)
outputSlot = toSlot;
else if (toSlot.isInputSlot)
inputSlot = toSlot;
if (inputSlot == null || outputSlot == null)
return null;
var edges = GetEdges(inputSlot).ToList();
// remove any inputs that exits before adding
foreach (var edge in edges)
{
Debug.Log("Removing existing edge:" + edge);
// call base here as we DO NOT want to
// do expensive shader regeneration
RemoveEdge(edge);
}
var newEdge = new Edge(new SlotReference(outputSlot.owner.guid, outputSlot.name), new SlotReference(inputSlot.owner.guid, inputSlot.name));
m_Edges.Add(newEdge);
Debug.Log("Connected edge: " + newEdge);
ValidateGraph();
return newEdge;
}
public virtual void RemoveEdge(Edge e)
{
m_Edges.Remove(e);
ValidateGraph();
}
public void RemoveElements(IEnumerable<SerializableNode> nodes, IEnumerable<Edge> edges)
{
foreach (var edge in edges)
RemoveEdgeNoValidate(edge);
foreach (var serializableNode in nodes)
RemoveNodeNoValidate(serializableNode);
ValidateGraph();
}
private void RemoveEdgeNoValidate(Edge e)
{
m_Edges.Remove(e);
}
public SerializableNode GetNodeFromGuid(Guid guid)
{
return m_Nodes.FirstOrDefault(x => x.guid == guid);
}
public IEnumerable<Edge> GetEdges(SerializableSlot s)
{
return m_Edges.Where(x =>
(x.outputSlot.nodeGuid == s.owner.guid && x.outputSlot.slotName == s.name)
|| x.inputSlot.nodeGuid == s.owner.guid && x.inputSlot.slotName == s.name);
}
public virtual void OnBeforeSerialize()
{
m_SerializableNodes = SerializationHelper.Serialize(m_Nodes);
}
public virtual void OnAfterDeserialize()
{
m_Nodes = SerializationHelper.Deserialize<SerializableNode>(m_SerializableNodes, new object[] {this});
m_SerializableNodes = null;
ValidateGraph();
}
public virtual void ValidateGraph()
{
//First validate edges, remove any
//orphans. This can happen if a user
//manually modifies serialized data
//of if they delete a node in the inspector
//debug view.
var allNodeGUIDs = nodes.Select(x => x.guid).ToList();
foreach (var edge in edges.ToArray())
{
if (allNodeGUIDs.Contains(edge.inputSlot.nodeGuid) && allNodeGUIDs.Contains(edge.outputSlot.nodeGuid))
continue;
//orphaned edge
RemoveEdgeNoValidate(edge);
}
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs.meta


fileFormatVersion: 2
guid: 212c20183bfb8be42a77c212a54af19e
timeCreated: 1464079584
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

233
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class SerializableNode : ISerializationCallbackReceiver
{
public delegate void NeedsRepaint();
public NeedsRepaint onNeedsRepaint;
private const int kPreviewWidth = 64;
private const int kPreviewHeight = 64;
[NonSerialized]
private Guid m_Guid;
[SerializeField]
private string m_GuidSerialized;
[SerializeField]
private string m_Name;
[SerializeField]
private Rect m_Position;
[NonSerialized]
private List<SerializableSlot> m_Slots = new List<SerializableSlot>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableSlots = new List<SerializationHelper.JSONSerializedElement>();
public SerializableGraph owner { get; set; }
public Guid guid
{
get { return m_Guid; }
}
public string name
{
get { return m_Name; }
set { m_Name = value; }
}
public virtual bool canDeleteNode
{
get { return true; }
}
protected virtual int previewWidth
{
get { return kPreviewWidth; }
}
protected virtual int previewHeight
{
get { return kPreviewHeight; }
}
public Rect position
{
get { return m_Position; }
set { m_Position = value; }
}
public IEnumerable<SerializableSlot> inputSlots
{
get { return m_Slots.Where(x => x.isInputSlot); }
}
public IEnumerable<SerializableSlot> outputSlots
{
get { return m_Slots.Where(x => x.isOutputSlot); }
}
public IEnumerable<SerializableSlot> slots
{
get { return m_Slots; }
}
public SerializableNode(SerializableGraph theOwner)
{
owner = theOwner;
m_Guid = Guid.NewGuid();
}
public virtual void AddSlot(SerializableSlot slot)
{
if (slot == null)
return;
// new MaterialSlot, just add it, we cool
if (!m_Slots.Contains(slot))
{
m_Slots.Add(slot);
return;
}
// old Slot found
// update the default value, and the slotType!
var foundSlots = m_Slots.FindAll(x => x.name == slot.name);
// if we are in a bad state (> 1 slot with same name).
// or our types are differernt now
// reset the slot to the new value
if (foundSlots.Count > 1 || foundSlots[0].GetType() != slot.GetType())
{
Debug.LogWarningFormat("Node {0} has more than one MaterialSlot with the same name, removing.");
m_Slots.RemoveAll(x => x.name == slot.name);
m_Slots.Add(slot);
}
}
public void RemoveSlot(string name)
{
m_Slots.RemoveAll(x => x.name == name);
}
public void RemoveSlotsNameNotMatching(string[] slotNames)
{
var invalidSlots = m_Slots.Select(x => x.name).Except(slotNames);
foreach (var invalidSlot in invalidSlots.ToList())
{
Debug.LogFormat("Removing Invalid MaterialSlot: {0}", invalidSlot);
RemoveSlot(invalidSlot);
}
}
public SerializableSlot FindInputSlot(string name)
{
var slot = inputSlots.FirstOrDefault(x => x.name == name);
if (slot == null)
Debug.LogErrorFormat("Input Slot: {0} could be found on node {1}", name, this);
return slot;
}
public SerializableSlot FindOutputSlot(string name)
{
var slot = outputSlots.FirstOrDefault(x => x.name == name);
if (slot == null)
Debug.LogErrorFormat("Output Slot: {0} could be found on node {1}", name, this);
return slot;
}
// CollectDependentNodes looks at the current node and calculates
// which nodes further up the tree (parents) would be effected if this node was changed
// it also includes itself in this list
public IEnumerable<SerializableNode> CollectDependentNodes()
{
var nodeList = new List<SerializableNode>();
NodeUtils.CollectDependentNodes(nodeList, this);
return nodeList;
}
// CollectDependentNodes looks at the current node and calculates
// which child nodes it depends on for it's calculation.
// Results are returned depth first so by processing each node in
// order you can generate a valid code block.
public List<SerializableNode> CollectChildNodesByExecutionOrder(List<SerializableNode> nodeList, SerializableSlot slotToUse = null, bool includeSelf = true)
{
if (slotToUse != null && !m_Slots.Contains(slotToUse))
{
Debug.LogError("Attempting to collect nodes by execution order with an invalid MaterialSlot on: " + name);
return nodeList;
}
NodeUtils.CollectChildNodesByExecutionOrder(nodeList, this, slotToUse);
if (!includeSelf)
nodeList.Remove(this);
return nodeList;
}
public virtual float GetNodeUIHeight(float width)
{
return 0;
}
public virtual GUIModificationType NodeUI(Rect drawArea)
{
return GUIModificationType.None;
}
public virtual bool OnGUI()
{
GUILayout.Label("MaterialSlot Defaults", EditorStyles.boldLabel);
var modified = false;
foreach (var slot in inputSlots)
{
if (!owner.GetEdges(slot).Any())
modified |= DoSlotUI(this, slot);
}
return modified;
}
public static bool DoSlotUI(SerializableNode node, SerializableSlot slot)
{
GUILayout.BeginHorizontal( /*EditorStyles.inspectorBig*/);
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("MaterialSlot " + slot.name, EditorStyles.largeLabel);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUILayout.EndHorizontal();
return slot.OnGUI();
}
public virtual void OnBeforeSerialize()
{
m_GuidSerialized = m_Guid.ToString();
m_SerializableSlots = SerializationHelper.Serialize(m_Slots);
}
public virtual void OnAfterDeserialize()
{
if (!string.IsNullOrEmpty(m_GuidSerialized))
m_Guid = new Guid(m_GuidSerialized);
else
m_Guid = Guid.NewGuid();
m_Slots = SerializationHelper.Deserialize<SerializableSlot>(m_SerializableSlots, new object[] { this });
m_SerializableSlots = null;
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs.meta


fileFormatVersion: 2
guid: a9ce774f3d69dc241aff311e95b8ad19
timeCreated: 1464081042
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

68
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class SerializableSlot
{
private const string kNotInit = "Not Initilaized";
[SerializeField]
private string m_Name = kNotInit;
[SerializeField]
private string m_DisplayName = kNotInit;
[SerializeField]
private SlotType m_SlotType;
public SerializableNode owner { get; set; }
public string name
{
get { return m_Name; }
}
public string displayName
{
get { return m_DisplayName; }
}
public bool isInputSlot
{
get { return m_SlotType == SlotType.Input; }
}
public bool isOutputSlot
{
get { return m_SlotType == SlotType.Output; }
}
public SerializableSlot(SerializableNode theOwner, string name, string displayName, SlotType slotType)
{
owner = theOwner;
m_Name = name;
m_DisplayName = displayName;
m_SlotType = slotType;
}
// used via reflection / serialization after deserialize
// to reconstruct this slot.
protected SerializableSlot(SerializableNode theOwner)
{
owner = theOwner;
}
public virtual bool OnGUI()
{
return false;
}
}
public enum SlotType
{
Input,
Output
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs.meta


fileFormatVersion: 2
guid: 751467780a86a1044a8037840649efd0
timeCreated: 1464081042
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

44
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class SlotReference : ISerializationCallbackReceiver
{
[SerializeField]
private string m_SlotName;
[NonSerialized]
private Guid m_NodeGUID;
[SerializeField]
private string m_NodeGUIDSerialized;
public SlotReference(Guid nodeGuid, string slotName)
{
m_NodeGUID = nodeGuid;
m_SlotName = slotName;
}
public Guid nodeGuid
{
get { return m_NodeGUID; }
}
public string slotName
{
get { return m_SlotName; }
}
public void OnBeforeSerialize()
{
m_NodeGUIDSerialized = m_NodeGUID.ToString();
}
public void OnAfterDeserialize()
{
m_NodeGUID = new Guid(m_NodeGUIDSerialized);
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs.meta


fileFormatVersion: 2
guid: a178e14960be0e944b4652535f2d12e4
timeCreated: 1463576280
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

11
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/TitleAttribute.cs


using System;
namespace UnityEditor.MaterialGraph
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
public class TitleAttribute : Attribute
{
public string m_Title;
public TitleAttribute(string title) { m_Title = title; }
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/TitleAttribute.cs.meta


fileFormatVersion: 2
guid: 9cd071f2d3ab1ba4ea2d9cc7a8b7a5d0
timeCreated: 1464081042
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

96
UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs


using System.Linq;
using NUnit.Framework;
namespace UnityEditor.MaterialGraph.Tests
{
[TestFixture]
public class ScriptableGraphTests
{
[Test]
public void TestCreate()
{
var graph = new SerializableGraph();
Assert.AreEqual(0, graph.edges.Count());
Assert.AreEqual(0, graph.nodes.Count());
}
[Test]
public void TestAddNode()
{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.name = "Test Node";
graph.AddNode(node);
Assert.AreEqual(1, graph.nodes.Count());
Assert.AreEqual("Test Node", graph.nodes.FirstOrDefault().name);
}
[Test]
public void TestAddSlot()
{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.AddSlot(new SerializableSlot(node, "output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot(node, "input", "input", SlotType.Input));
node.name = "Test Node";
graph.AddNode(node);
Assert.AreEqual(1, graph.nodes.Count());
var found = graph.nodes.FirstOrDefault();
Assert.AreEqual(found.inputSlots.Count(), 1);
Assert.AreEqual(found.outputSlots.Count(), 1);
Assert.AreEqual(found.slots.Count(), 2);
}
[Test]
public void TestCanConnectAndTraverseTwoNodes()
{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot(outputNode, "output", "output", SlotType.Output);
outputNode.AddSlot(outputSlot);
graph.AddNode(outputNode);
var inputNode = new SerializableNode(graph);
var inputSlot = new SerializableSlot(inputNode, "input", "input", SlotType.Input);
inputNode.AddSlot(inputSlot);
graph.AddNode(inputNode);
Assert.AreEqual(2, graph.nodes.Count());
graph.Connect(outputNode.FindOutputSlot("output"), inputNode.FindInputSlot("input"));
Assert.AreEqual(1, graph.edges.Count());
var edge = graph.edges.FirstOrDefault();
var foundOutputNode = graph.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var foundOutputSlot = foundOutputNode.FindOutputSlot(edge.outputSlot.slotName);
Assert.AreEqual(foundOutputNode, outputNode);
Assert.AreEqual(foundOutputSlot, outputSlot);
var foundInputNode = graph.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var foundInputSlot = foundOutputNode.FindInputSlot(edge.inputSlot.slotName);
Assert.AreEqual(foundInputNode, inputNode);
Assert.AreEqual(foundInputSlot, outputSlot);
}
}
[TestFixture]
public class MaterialGraphTests
{
[Test]
public void TestCreateMaterialGraph()
{
MaterialGraph graph = new MaterialGraph();
Assert.IsNotNull(graph.currentGraph);
Assert.IsNotNull(graph.materialOptions);
graph.PostCreate();
Assert.AreEqual(1, graph.currentGraph.nodes.Count());
Assert.IsInstanceOf(typeof(PixelShaderNode), graph.currentGraph.nodes.FirstOrDefault());
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs.meta


fileFormatVersion: 2
guid: 28928f8f53abca94fbfaabf4d2c440af
timeCreated: 1464096294
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存