浏览代码

#29 Propagate `requiresTime` in `MaterialGraphPresenter.UpdateData` rather than computing it on-the-fly (+ rename a bunch of variables in said method to match new conventions)

/main
Peter Bay Bastian 7 年前
当前提交
a3cbf332
共有 2 个文件被更改,包括 101 次插入65 次删除
  1. 153
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs
  2. 13
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialNodePresenter.cs

153
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs


using UnityEditor.Experimental.UIElements.GraphView;
using UnityEditor.Graphing.Util;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Graphing;
namespace UnityEditor.MaterialGraph.Drawing

{
HashSet<INode> m_TimeDependentNodes = new HashSet<INode>();
protected GraphTypeMapper typeMapper { get; set; }
public IGraphAsset graphAsset { get; private set; }

void UpdateData()
{
// Find all nodes currently being drawn which are no longer in the graph (i.e. deleted)
var deletedElements = m_Elements
var deletedElementPresenters = m_Elements
var deletedEdges = m_Elements.OfType<GraphEdgePresenter>()
var deletedEdgePresenters = m_Elements.OfType<GraphEdgePresenter>()
foreach (var edgeData in deletedEdges)
foreach (var edgePresenter in deletedEdgePresenters)
edgeData.output.Disconnect(edgeData);
edgeData.input.Disconnect(edgeData);
edgePresenter.output.Disconnect(edgePresenter);
edgePresenter.input.Disconnect(edgePresenter);
var fromNodeGuid = edgePresenter.edge.outputSlot.nodeGuid;
var fromNodePresenter = m_Elements.OfType<MaterialNodePresenter>().FirstOrDefault(nd => nd.node.guid == fromNodeGuid);
var toNodeGuid = edgePresenter.edge.inputSlot.nodeGuid;
var toNodePresenter = m_Elements.OfType<MaterialNodePresenter>().FirstOrDefault(nd => nd.node.guid == toNodeGuid);
var toNodeGuid = edgeData.edge.inputSlot.nodeGuid;
var toNode = m_Elements.OfType<MaterialNodePresenter>().FirstOrDefault(nd => nd.node.guid == toNodeGuid);
if (toNode != null)
{
if (toNodePresenter != null)
OnNodeChanged(toNode.node, ModificationScope.Graph);
}
OnNodeChanged(toNodePresenter.node, ModificationScope.Graph);
deletedElements.Add(edgeData);
deletedElementPresenters.Add(edgePresenter);
foreach (var deletedElement in deletedElements)
foreach (var elementPresenter in deletedElementPresenters)
m_Elements.Remove(deletedElement);
m_Elements.Remove(elementPresenter);
var addedNodes = new List<MaterialNodePresenter>();
var addedNodePresenters = new List<MaterialNodePresenter>();
// Find all new nodes and mark for addition
foreach (var node in graphAsset.graph.GetNodes<INode>())

continue;
var nodeData = (MaterialNodePresenter)typeMapper.Create(node);
var nodePresenter = (MaterialNodePresenter)typeMapper.Create(node);
nodeData.Initialize(node);
addedNodes.Add(nodeData);
nodePresenter.Initialize(node);
addedNodePresenters.Add(nodePresenter);
var drawableEdges = new List<GraphEdgePresenter>();
foreach (var addedNode in addedNodes)
var edgePresenters = new List<GraphEdgePresenter>();
foreach (var addedNodePresenter in addedNodePresenters)
var baseNode = addedNode.node;
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
var addedNode = addedNodePresenter.node;
foreach (var slot in addedNode.GetOutputSlots<ISlot>())
var sourceAnchors = addedNode.outputAnchors.OfType<GraphAnchorPresenter>();
var sourceAnchors = addedNodePresenter.outputAnchors.OfType<GraphAnchorPresenter>();
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.id));
var edges = addedNode.owner.GetEdges(new SlotReference(addedNode.guid, slot.id));
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toNode = addedNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var targetNode = addedNodes.FirstOrDefault(x => x.node == toNode);
var targetNode = addedNodePresenters.FirstOrDefault(x => x.node == toNode);
var edgeData = CreateInstance<GraphEdgePresenter>();
edgeData.Initialize(edge);
edgeData.output = sourceAnchor;
edgeData.output.Connect(edgeData);
edgeData.input = targetAnchor;
edgeData.input.Connect(edgeData);
drawableEdges.Add(edgeData);
var edgePresenter = CreateInstance<GraphEdgePresenter>();
edgePresenter.Initialize(edge);
edgePresenter.output = sourceAnchor;
edgePresenter.output.Connect(edgePresenter);
edgePresenter.input = targetAnchor;
edgePresenter.input.Connect(edgePresenter);
edgePresenters.Add(edgePresenter);
m_Elements.AddRange(addedNodes.OfType<GraphElementPresenter>());
m_Elements.AddRange(addedNodePresenters.OfType<GraphElementPresenter>());
if (!m_Elements.OfType<GraphEdgePresenter>().Any(ed => ed.edge == edge))
{
var fromNode = graphAsset.graph.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var fromSlot = fromNode.FindOutputSlot<ISlot>(edge.outputSlot.slotId);
var sourceNode = m_Elements.OfType<MaterialNodePresenter>().FirstOrDefault(x => x.node == fromNode);
var sourceAnchors = sourceNode.outputAnchors.OfType<GraphAnchorPresenter>();
var sourceAnchor = sourceAnchors.FirstOrDefault(x => x.slot == fromSlot);
if (m_Elements.OfType<GraphEdgePresenter>().Any(ed => ed.edge == edge))
continue;
var toNode = graphAsset.graph.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = m_Elements.OfType<MaterialNodePresenter>().FirstOrDefault(x => x.node == toNode);
var targetAnchors = targetNode.inputAnchors.OfType<GraphAnchorPresenter>();
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == toSlot);
var sourceNode = graphAsset.graph.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var sourceSlot = sourceNode.FindOutputSlot<ISlot>(edge.outputSlot.slotId);
var sourceNodePresenter = m_Elements.OfType<MaterialNodePresenter>().FirstOrDefault(x => x.node == sourceNode);
var sourceAnchorPresenters = sourceNodePresenter.outputAnchors.OfType<GraphAnchorPresenter>();
var sourceAnchorPresenter = sourceAnchorPresenters.FirstOrDefault(x => x.slot == sourceSlot);
OnNodeChanged(targetNode.node, ModificationScope.Graph);
var targetNode = graphAsset.graph.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var targetSlot = targetNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNodePresenter = m_Elements.OfType<MaterialNodePresenter>().FirstOrDefault(x => x.node == targetNode);
var targetAnchors = targetNodePresenter.inputAnchors.OfType<GraphAnchorPresenter>();
var targetAnchor = targetAnchors.FirstOrDefault(x => x.slot == targetSlot);
var edgeData = CreateInstance<GraphEdgePresenter>();
edgeData.Initialize(edge);
edgeData.output = sourceAnchor;
edgeData.output.Connect(edgeData);
edgeData.input = targetAnchor;
edgeData.input.Connect(edgeData);
drawableEdges.Add(edgeData);
OnNodeChanged(targetNodePresenter.node, ModificationScope.Graph);
var edgePresenter = CreateInstance<GraphEdgePresenter>();
edgePresenter.Initialize(edge);
edgePresenter.output = sourceAnchorPresenter;
edgePresenter.output.Connect(edgePresenter);
edgePresenter.input = targetAnchor;
edgePresenter.input.Connect(edgePresenter);
edgePresenters.Add(edgePresenter);
}
m_Elements.AddRange(edgePresenters.OfType<GraphElementPresenter>());
// Calculate which nodes require updates each frame (i.e. are time-dependent).
// Let the node set contain all the nodes that are directly time-dependent.
m_TimeDependentNodes.Clear();
foreach (var node in graphAsset.graph.GetNodes<INode>().Where(x => x is IRequiresTime))
m_TimeDependentNodes.Add(node);
// The wavefront contains time-dependent nodes from which we wish to propagate time-dependency into the
// nodes that it feeds into.
var wavefront = new Stack<INode>(m_TimeDependentNodes);
while (wavefront.Count > 0)
{
var node = wavefront.Pop();
// Loop through all nodes that the node feeds into.
foreach (var slot in node.GetOutputSlots<ISlot>())
{
foreach (var edge in node.owner.GetEdges(slot.slotReference))
{
var inputNode = node.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
if (!m_TimeDependentNodes.Contains(inputNode))
{
// If the node is not in the set of time-dependent nodes, add it.
m_TimeDependentNodes.Add(inputNode);
// Also add it to the wavefront, such that we can process the nodes that it feeds into.
wavefront.Push(inputNode);
}
}
m_Elements.AddRange(drawableEdges.OfType<GraphElementPresenter>());
// Update presenters `requiresTime` based on the hash set values.
foreach (var nodePresenter in m_Elements.OfType<MaterialNodePresenter>())
nodePresenter.requiresTime = m_TimeDependentNodes.Contains(nodePresenter.node);
}
public virtual void Initialize(IGraphAsset graphAsset, MaterialGraphEditWindow container)

13
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialNodePresenter.cs


[SerializeField]
int m_Version;
[SerializeField]
bool m_RequiresTime;
get
{
using (var childrenNodes = ListPool<INode>.GetDisposable())
{
NodeUtils.DepthFirstCollectNodesFromNode(childrenNodes.value, node);
return childrenNodes.value.OfType<IRequiresTime>().Any();
}
}
get { return m_RequiresTime; }
set { m_RequiresTime = value; }
}
public override bool expanded

正在加载...
取消
保存