소스 검색

Associated with #6012

David Catuhe 6 년 전
부모
커밋
83c90ed215

+ 1 - 1
nodeEditor/src/components/propertyTab/propertyTabComponent.tsx

@@ -80,7 +80,7 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                     <LineContainerComponent title="FILE">                        
                         <FileButtonLineComponent label="Load" onClick={(file) => this.load(file)} accept=".json" />
                         <ButtonLineComponent label="Save" onClick={() => {
-                            let json = JSON.stringify(this.props.globalState.nodeMaterial!.serialize());
+                            let json = JSON.stringify(this.props.globalState.nodeMaterial!.serialize(), undefined, 2);
                             StringTools.DownloadAsFile(json, "nodeMaterial.json");
                         }} />
                         <ButtonLineComponent label="Export shaders" onClick={() => {

+ 12 - 79
nodeEditor/src/graphEditor.tsx

@@ -6,7 +6,6 @@ import {
 } from "storm-react-diagrams";
 
 import * as React from "react";
-import * as dagre from "dagre";
 import { GlobalState } from './globalState';
 
 import { GenericNodeFactory } from './components/diagram/generic/genericNodeFactory';
@@ -37,25 +36,12 @@ import { AdvancedLinkFactory } from './components/diagram/link/advancedLinkFacto
 import { RemapNodeFactory } from './components/diagram/remap/remapNodeFactory';
 import { RemapNodeModel } from './components/diagram/remap/remapNodeModel';
 import { RemapBlock } from 'babylonjs/Materials/Node/Blocks/remapBlock';
+import { GraphHelper } from './graphHelper';
 
 require("storm-react-diagrams/dist/style.min.css");
 require("./main.scss");
 require("./components/diagram/diagram.scss");
 
-/*
-Graph Editor Overview
-
-Storm React setup:
-GenericNodeModel - Represents the nodes in the graph and can be any node type (eg. texture, vector2, etc)
-GenericNodeWidget - Renders the node model in the graph 
-GenericPortModel - Represents the input/output of a node (contained within each GenericNodeModel)
-
-Generating/modifying the graph:
-Generating node graph - the createNodeFromObject method is used to recursively create the graph
-Modifications to the graph - The listener in the constructor of GraphEditor listens for port changes and updates the node material based on changes
-Saving the graph/generating code - Not yet done
-*/
-
 interface IGraphEditorProps {
     globalState: GlobalState;
 }
@@ -126,6 +112,15 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
 
         return newNode;
     }
+    
+    addValueNode(type: string) {
+        let nodeType: NodeMaterialBlockConnectionPointTypes = BlockTools.GetConnectionNodeTypeFromString(type);
+
+        let newInputBlock = new InputBlock(type, undefined, nodeType);
+        var localNode = this.createNodeFromObject({ type: type, nodeMaterialBlock: newInputBlock })
+
+        return localNode;
+    }
 
     componentDidMount() {
         if (this.props.globalState.hostDocument) {
@@ -202,59 +197,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         }
     }
 
-    distributeGraph() {
-        let nodes = this.mapElements();
-        let edges = this.mapEdges();
-        let graph = new dagre.graphlib.Graph();
-        graph.setGraph({});
-        graph.setDefaultEdgeLabel(() => ({}));
-        graph.graph().rankdir = "LR";
-        //add elements to dagre graph
-        nodes.forEach(node => {
-            graph.setNode(node.id, node.metadata);
-        });
-        edges.forEach(edge => {
-            if (edge.from && edge.to) {
-                graph.setEdge(edge.from.id, edge.to.id);
-            }
-        });
-        //auto-distribute
-        dagre.layout(graph);
-        return graph.nodes().map(node => graph.node(node));
-    }
-
-    mapElements() {
-        let output = [];
-
-        // dagre compatible format
-        for (var nodeName in this._model.nodes) {
-            let node = this._model.nodes[nodeName];
-            let size = {
-                width: node.width | 200,
-                height: node.height | 100
-            };
-            output.push({ id: node.id, metadata: { ...size, id: node.id } });
-        }
-
-        return output;
-    }
-
-    mapEdges() {
-        // returns links which connects nodes
-        // we check are there both from and to nodes in the model. Sometimes links can be detached
-        let output = [];
-
-        for (var linkName in this._model.links) {
-            let link = this._model.links[linkName];
-
-            output.push({
-                from: link.sourcePort!.parent,
-                to: link.targetPort!.parent
-            });
-        }
-
-        return output;
-    }
+ 
 
     buildMaterial() {
         if (!this.props.globalState.nodeMaterial) {
@@ -412,7 +355,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
     }
 
     reOrganize() {
-        let nodes = this.distributeGraph();
+        let nodes = GraphHelper.DistributeGraph(this._model);
         nodes.forEach(node => {
             for (var nodeName in this._model.nodes) {
                 let modelNode = this._model.nodes[nodeName];
@@ -426,15 +369,6 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         this.forceUpdate();
     }
 
-    addValueNode(type: string) {
-        let nodeType: NodeMaterialBlockConnectionPointTypes = BlockTools.GetConnectionNodeTypeFromString(type);
-
-        let newInputBlock = new InputBlock(type, undefined, nodeType);
-        var localNode = this.createNodeFromObject({ type: type, nodeMaterialBlock: newInputBlock })
-
-        return localNode;
-    }
-
     onPointerDown(evt: React.PointerEvent<HTMLDivElement>) {
         this._startX = evt.clientX;
         this._moveInProgress = true;
@@ -447,7 +381,6 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
     }
 
     resizeColumns(evt: React.PointerEvent<HTMLDivElement>, forLeft = true) {
-
         if (!this._moveInProgress) {
             return;
         }

+ 59 - 0
nodeEditor/src/graphHelper.ts

@@ -0,0 +1,59 @@
+
+import * as dagre from "dagre";
+import { DiagramModel } from 'storm-react-diagrams/dist/@types/src/models/DiagramModel';
+
+export class GraphHelper {
+    public static DistributeGraph(model: DiagramModel) {
+        let nodes = this._MapElements(model);
+        let edges = this._MapEdges(model);
+        let graph = new dagre.graphlib.Graph();
+        graph.setGraph({});
+        graph.setDefaultEdgeLabel(() => ({}));
+        graph.graph().rankdir = "LR";
+        //add elements to dagre graph
+        nodes.forEach(node => {
+            graph.setNode(node.id, node.metadata);
+        });
+        edges.forEach(edge => {
+            if (edge.from && edge.to) {
+                graph.setEdge(edge.from.id, edge.to.id);
+            }
+        });
+        //auto-distribute
+        dagre.layout(graph);
+        return graph.nodes().map(node => graph.node(node));
+    }
+
+    private static _MapElements(model: DiagramModel) {
+        let output = [];
+
+        // dagre compatible format
+        for (var nodeName in model.nodes) {
+            let node = model.nodes[nodeName];
+            let size = {
+                width: node.width | 200,
+                height: node.height | 100
+            };
+            output.push({ id: node.id, metadata: { ...size, id: node.id } });
+        }
+
+        return output;
+    }
+
+    private static _MapEdges(model: DiagramModel) {
+        // returns links which connects nodes
+        // we check are there both from and to nodes in the model. Sometimes links can be detached
+        let output = [];
+
+        for (var linkName in model.links) {
+            let link = model.links[linkName];
+
+            output.push({
+                from: link.sourcePort!.parent,
+                to: link.targetPort!.parent
+            });
+        }
+
+        return output;
+    }
+}

+ 4 - 1
src/Materials/Node/nodeMaterial.ts

@@ -922,7 +922,10 @@ export class NodeMaterial extends PushMaterial {
 
         for (var outputNode of this._fragmentOutputNodes) {
             this._gatherBlocks(outputNode, blocks);
-            serializationObject.outputNodes.push(outputNode.uniqueId);
+
+            if (serializationObject.outputNodes.indexOf(outputNode.uniqueId) === -1) {
+                serializationObject.outputNodes.push(outputNode.uniqueId);
+            }
         }
 
         // Blocks