private void OnFragmentTreeItemDrag(object sender, ItemDragEventArgs e) { if (e != null) { if (e.Item is Aga.Controls.Tree.TreeNodeAdv[]) { var array = (Aga.Controls.Tree.TreeNodeAdv[])e.Item; foreach (var a in array) { if (a.Tag is TreeViewArchiveModel.ShaderFragmentItem) { var item = (TreeViewArchiveModel.ShaderFragmentItem)a.Tag; var archiveName = item.ArchiveName; if (archiveName != null && archiveName.Length > 0) { var fn = ShaderFragmentArchive.Archive.GetFunction(archiveName); if (fn != null) { this.DoDragDrop(ShaderFragmentNodeCreator.CreateNode(fn, archiveName, graphControl, _document), DragDropEffects.Copy); } } } else if (a.Tag is TreeViewArchiveModel.ParameterStructItem) { var item = (TreeViewArchiveModel.ParameterStructItem)a.Tag; var archiveName = item.ArchiveName; if (archiveName != null && archiveName.Length > 0) { var fn = ShaderFragmentArchive.Archive.GetParameterStruct(archiveName); if (fn != null) { this.DoDragDrop(ShaderFragmentNodeCreator.CreateParameterNode(fn, archiveName, ShaderFragmentArchive.Parameter.SourceType.Material), DragDropEffects.Copy); } } } } } } }
// // Convert from the "ViewModel" to the "Model" // // We don't maintain the ShaderPatcherLayer.NodeGraph representation // permanently... But we need this for serialization and shader // generation operations // // So, let's just build it from the graph control object. // public static ShaderPatcherLayer.NodeGraph ToShaderPatcherLayer(HyperGraph.GraphControl graphControl) { ShaderPatcherLayer.NodeGraph nodeGraph = new ShaderPatcherLayer.NodeGraph(); Dictionary <Node, int> nodeToVisualNodeId = new Dictionary <Node, int>(); foreach (Node n in graphControl.Nodes) { if (n.Tag is ShaderFragmentNodeTag) { ShaderFragmentNodeTag nTag = (ShaderFragmentNodeTag)n.Tag; ShaderPatcherLayer.Node resultNode = new ShaderPatcherLayer.Node(); resultNode.FragmentArchiveName = nTag.ArchiveName; resultNode.NodeId = nTag.Id; if (n.Tag is ShaderParameterNodeTag) { // This is a hack... But there should be a drop down list that // can tell us the type of this parameter struct box. foreach (var i in n.Items) { if (i is HyperGraph.Items.NodeDropDownItem) { var dropDown = (HyperGraph.Items.NodeDropDownItem)i; var stringForm = dropDown.Items[dropDown.SelectedIndex]; var parameterSource = ShaderFragmentNodeCreator.AsSourceType(stringForm); resultNode.NodeType = AsNodeType(parameterSource); } } } else { resultNode.NodeType = ShaderPatcherLayer.Node.Type.Procedure; } { if (nodeToVisualNodeId.ContainsKey(n)) { resultNode.VisualNodeId = nodeToVisualNodeId[n]; } else { resultNode.VisualNodeId = nodeGraph.VisualNodes.Count(); nodeToVisualNodeId.Add(n, resultNode.VisualNodeId); var visualNode = new ShaderPatcherLayer.VisualNode(); visualNode.Location = n.Location; if (n.Collapsed) { visualNode.State = ShaderPatcherLayer.VisualNode.StateType.Collapsed; } else { visualNode.State = ShaderPatcherLayer.VisualNode.StateType.Normal; } nodeGraph.VisualNodes.Add(visualNode); } } nodeGraph.Nodes.Add(resultNode); foreach (NodeConnection connection in n.Connections) { if (connection.From == null) { // this is a direct constant connection. It connects the value either to a constant value, or some named variable if (connection.To != null) { Node destination = connection.To.Node; if (destination.Tag is ShaderFragmentNodeTag) { ShaderFragmentNodeTag dTag = (ShaderFragmentNodeTag)destination.Tag; ShaderPatcherLayer.NodeConstantConnection resultConnection = new ShaderPatcherLayer.NodeConstantConnection(); resultConnection.Value = connection.Name; resultConnection.OutputNodeID = dTag.Id; if (connection.To.Item is ShaderFragmentNodeItem) { ShaderFragmentNodeItem destinationItem = (ShaderFragmentNodeItem)connection.To.Item; resultConnection.OutputParameterName = destinationItem.Name; } nodeGraph.NodeConstantConnections.Add(resultConnection); } } } else if (connection.From.Node == n) { // This is an output to the next node Node destination = connection.To.Node; if (destination.Tag is ShaderFragmentNodeTag) { ShaderFragmentNodeTag dTag = (ShaderFragmentNodeTag)destination.Tag; ShaderPatcherLayer.NodeConnection resultConnection = new ShaderPatcherLayer.NodeConnection(); resultConnection.InputNodeID = nTag.Id; resultConnection.OutputNodeID = dTag.Id; if (connection.To.Item is ShaderFragmentNodeItem) { ShaderFragmentNodeItem destinationItem = (ShaderFragmentNodeItem)connection.To.Item; resultConnection.OutputParameterName = destinationItem.Name; resultConnection.OutputType = TypeFromNodeItem(destinationItem); } if (connection.From.Item is ShaderFragmentNodeItem) { ShaderFragmentNodeItem sourceItem = (ShaderFragmentNodeItem)connection.From.Item; resultConnection.InputParameterName = sourceItem.Name; resultConnection.InputType = TypeFromNodeItem(sourceItem); } nodeGraph.NodeConnections.Add(resultConnection); } } } } } return(nodeGraph); }
public static bool FillInMaterialParameters(ShaderDiagram.Document document, HyperGraph.GraphControl graphControl) { // // Look for new or removed material parameters // and update the material parameters dictionary // Dictionary <String, String> newMaterialParameters = new Dictionary <String, String>(); foreach (Node n in graphControl.Nodes) { if (n.Tag is ShaderParameterNodeTag && n.Items.Count() > 0) { // look for a drop down list element -- this will tell us the type ShaderFragmentArchive.Parameter.SourceType type = ShaderFragmentArchive.Parameter.SourceType.System; foreach (var i in n.Items) { if (i is HyperGraph.Items.NodeDropDownItem) { var dropDown = (HyperGraph.Items.NodeDropDownItem)i; var stringForm = dropDown.Items[dropDown.SelectedIndex]; type = ShaderFragmentNodeCreator.AsSourceType(stringForm); break; } } if (type == ShaderFragmentArchive.Parameter.SourceType.Material) { foreach (var i in n.Items) { if (i is ShaderFragmentNodeItem) { ShaderFragmentNodeItem item = (ShaderFragmentNodeItem)i; if (item.Output != null) { if (!newMaterialParameters.ContainsKey(item.ArchiveName)) { var param = ShaderFragmentArchive.Archive.GetParameter(item.ArchiveName); if (param != null) { newMaterialParameters.Add(item.ArchiveName, param.Type); } else { newMaterialParameters.Add(item.ArchiveName, "<<unknown>>"); } } } } } } } } bool didSomething = false; List <String> entriesToRemove = new List <String>(); foreach (String s in document.PreviewMaterialState.Keys) { if (!newMaterialParameters.ContainsKey(s)) { entriesToRemove.Add(s); } } foreach (String s in entriesToRemove) { document.PreviewMaterialState.Remove(s); // does this invalidate the iteration? didSomething = true; } foreach (KeyValuePair <String, String> s in newMaterialParameters) { if (!document.PreviewMaterialState.ContainsKey(s.Key)) { var parameter = ShaderFragmentArchive.Archive.GetParameter(s.Key); System.Object def = null; if (parameter != null && parameter.Default != null && parameter.Default.Length > 0) { def = ShaderPatcherLayer.TypeRules.CreateFromString(parameter.Default, parameter.Type); } var parameterName = s.Key; if (parameter != null) { parameterName = parameter.Name; } if (def != null) { document.PreviewMaterialState.Add(parameterName, def); } else { document.PreviewMaterialState.Add(parameterName, ShaderPatcherLayer.TypeRules.CreateDefaultObject(s.Value)); } didSomething = true; } } return(didSomething); }
public static void AddToHyperGraph(ShaderPatcherLayer.NodeGraph nodeGraph, HyperGraph.GraphControl graphControl, ShaderDiagram.Document doc) { // // Convert from the "ShaderPatcherLayer" representation back to // our graph control nodes. // // This is required for robust serialisation. We can't easily // serialise in and out the graph control objects directly, because // it risks problems if the rendering code or shader fragment objects // change. That is, it's not very version-robust. // // It's better to serialise a slightly higher level representation // that just contains the node names and connections. That way, we // can adapt to changes in the tool and data. // { // --------< Basic Nodes >-------- var newNodes = new Dictionary <int, Node>(); var nodeIdToControlNode = new Dictionary <UInt64, Node>(); foreach (var n in nodeGraph.Nodes) { if (!newNodes.ContainsKey(n.VisualNodeId)) { if (n.NodeType == ShaderPatcherLayer.Node.Type.Procedure) { var fn = ShaderFragmentArchive.Archive.GetFunction(n.FragmentArchiveName); if (fn != null) { var visualNode = nodeGraph.VisualNodes[n.VisualNodeId]; var newNode = ShaderFragmentNodeCreator.CreateNode(fn, n.FragmentArchiveName, graphControl, doc); newNode.Location = visualNode.Location; newNode.Collapsed = visualNode.State == ShaderPatcherLayer.VisualNode.StateType.Collapsed; newNodes[n.VisualNodeId] = newNode; nodeIdToControlNode[n.NodeId] = newNode; } } else { var ps = ShaderFragmentArchive.Archive.GetParameterStruct(n.FragmentArchiveName); if (ps != null) { var visualNode = nodeGraph.VisualNodes[n.VisualNodeId]; var newNode = ShaderFragmentNodeCreator.CreateParameterNode(ps, n.FragmentArchiveName, AsSourceType(n.NodeType)); newNode.Location = visualNode.Location; newNode.Collapsed = visualNode.State == ShaderPatcherLayer.VisualNode.StateType.Collapsed; newNodes[n.VisualNodeId] = newNode; nodeIdToControlNode[n.NodeId] = newNode; } } } } graphControl.AddNodes(newNodes.Values); // --------< Node Connections >-------- foreach (var c in nodeGraph.NodeConnections) { if (nodeIdToControlNode.ContainsKey(c.InputNodeID) && nodeIdToControlNode.ContainsKey(c.OutputNodeID)) { var inputItem = FindOrCreateNodeItem(nodeIdToControlNode[c.InputNodeID], (item) => (item.Output != null && item.Output.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.InputParameterName)), () => new ShaderFragmentNodeItem("return", c.InputType, null, false, true)); var outputItem = FindOrCreateNodeItem(nodeIdToControlNode[c.OutputNodeID], (item) => (item.Input != null && item.Input.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.OutputParameterName)), () => new ShaderFragmentNodeItem(c.OutputParameterName, c.OutputType, null, true, false)); graphControl.Connect(inputItem.Output, outputItem.Input); } } // --------< Node Constant Connections >-------- foreach (var c in nodeGraph.NodeConstantConnections) { if (nodeIdToControlNode.ContainsKey(c.OutputNodeID)) { var node = nodeIdToControlNode[c.OutputNodeID]; var outputItem = FindOrCreateNodeItem(node, (item) => (item.Input != null && item.Input.Enabled && item is ShaderFragmentNodeItem && ((ShaderFragmentNodeItem)item).Name.Equals(c.OutputParameterName)), () => new ShaderFragmentNodeItem(c.OutputParameterName, "float", null, true, false)); var connection = new NodeConnection(); connection.To = outputItem.Input; connection.Name = c.Value; node.AddConnection(connection); } } } }