Tim Cooper
9 年前
当前提交
cf6628c6
共有 38 个文件被更改,包括 978 次插入 和 45 次删除
-
8UnityProject/Assets/UnityShaderEditor/Editor/Source/AbstractMaterialGraph.cs
-
3UnityProject/Assets/UnityShaderEditor/Editor/Source/AssetCallbacks/CreateShaderGraph.cs
-
4UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs
-
8UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs
-
9UnityProject/Assets/UnityShaderEditor/Editor/Source/Editors/MaterialGraphEditor.cs
-
22UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraph.cs
-
2UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbstractMaterialNode.cs
-
4UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaterialSlot.cs
-
3UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs
-
3UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs
-
4UnityProject/Assets/UnityShaderEditor/Editor/Source/PixelGraph.cs
-
28UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/SerializationHelper.cs
-
5UnityProject/Assets/UnityShaderEditor/Editor/Testing/ShaderGeneration/ShaderGenerationTest.cs
-
25UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphAsset.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphAsset.cs.meta
-
9UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph.meta
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/SerializationHelper.cs.meta
-
9UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests.meta
-
30UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/Edge.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/Edge.cs.meta
-
9UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/GUIModificationType.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/GUIModificationType.cs.meta
-
102UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs
-
8UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs.meta
-
156UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs.meta
-
233UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs.meta
-
68UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs.meta
-
44UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs.meta
-
11UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/TitleAttribute.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/TitleAttribute.cs.meta
-
96UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs.meta
|
|||
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(); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 74a2b0e5e69571d4184bcdd77764b3b3 |
|||
timeCreated: 1464081042 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: a15baf967ea110641b4e31c092c2ed95 |
|||
folderAsset: yes |
|||
timeCreated: 1464081041 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: f6657676e9fd9cd4bbcb26b0771df3ac |
|||
timeCreated: 1464079585 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 7f85ac5340a5dff468e347347435cf68 |
|||
folderAsset: yes |
|||
timeCreated: 1464096294 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; } |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6b610a05c25f54d4c90f7ebf82696481 |
|||
timeCreated: 1463576280 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
namespace UnityEditor.MaterialGraph |
|||
{ |
|||
public enum GUIModificationType |
|||
{ |
|||
None, |
|||
Repaint, |
|||
ModelChanged |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c1bef593b05291f46b4bfd7a7192b881 |
|||
timeCreated: 1464079584 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 992a8f404953a8248b943cb6fb0b2c79 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
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); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 212c20183bfb8be42a77c212a54af19e |
|||
timeCreated: 1464079584 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: a9ce774f3d69dc241aff311e95b8ad19 |
|||
timeCreated: 1464081042 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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 |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 751467780a86a1044a8037840649efd0 |
|||
timeCreated: 1464081042 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: a178e14960be0e944b4652535f2d12e4 |
|||
timeCreated: 1463576280 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 9cd071f2d3ab1ba4ea2d9cc7a8b7a5d0 |
|||
timeCreated: 1464081042 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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()); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 28928f8f53abca94fbfaabf4d2c440af |
|||
timeCreated: 1464096294 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue