|
@@ -11,20 +11,15 @@ import { GlobalState } from './globalState';
|
|
|
import { GenericNodeFactory } from './components/diagram/generic/genericNodeFactory';
|
|
|
import { GenericNodeModel } from './components/diagram/generic/genericNodeModel';
|
|
|
import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
|
|
|
-import { NodeMaterialConnectionPoint, NodeMaterialConnectionPointCompatibilityStates } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
|
|
|
+import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
|
|
|
import { NodeListComponent } from './components/nodeList/nodeListComponent';
|
|
|
import { PropertyTabComponent } from './components/propertyTab/propertyTabComponent';
|
|
|
import { Portal } from './portal';
|
|
|
import { TextureNodeFactory } from './components/diagram/texture/textureNodeFactory';
|
|
|
import { DefaultNodeModel } from './components/diagram/defaultNodeModel';
|
|
|
-import { TextureNodeModel } from './components/diagram/texture/textureNodeModel';
|
|
|
import { DefaultPortModel } from './components/diagram/port/defaultPortModel';
|
|
|
import { InputNodeFactory } from './components/diagram/input/inputNodeFactory';
|
|
|
-import { InputNodeModel } from './components/diagram/input/inputNodeModel';
|
|
|
-import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/textureBlock';
|
|
|
import { LogComponent, LogEntry } from './components/log/logComponent';
|
|
|
-import { LightBlock } from 'babylonjs/Materials/Node/Blocks/Dual/lightBlock';
|
|
|
-import { LightNodeModel } from './components/diagram/light/lightNodeModel';
|
|
|
import { LightNodeFactory } from './components/diagram/light/lightNodeFactory';
|
|
|
import { DataStorage } from './dataStorage';
|
|
|
import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes';
|
|
@@ -34,30 +29,18 @@ import { MessageDialogComponent } from './sharedComponents/messageDialog';
|
|
|
import { BlockTools } from './blockTools';
|
|
|
import { AdvancedLinkFactory } from './components/diagram/link/advancedLinkFactory';
|
|
|
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';
|
|
|
import { PreviewManager } from './components/preview/previewManager';
|
|
|
import { INodeLocationInfo } from './nodeLocationInfo';
|
|
|
import { PreviewMeshControlComponent } from './components/preview/previewMeshControlComponent';
|
|
|
import { TrigonometryNodeFactory } from './components/diagram/trigonometry/trigonometryNodeFactory';
|
|
|
-import { TrigonometryBlock } from 'babylonjs/Materials/Node/Blocks/trigonometryBlock';
|
|
|
-import { TrigonometryNodeModel } from './components/diagram/trigonometry/trigonometryNodeModel';
|
|
|
-import { AdvancedLinkModel } from './components/diagram/link/advancedLinkModel';
|
|
|
import { ClampNodeFactory } from './components/diagram/clamp/clampNodeFactory';
|
|
|
-import { ClampNodeModel } from './components/diagram/clamp/clampNodeModel';
|
|
|
-import { ClampBlock } from 'babylonjs/Materials/Node/Blocks/clampBlock';
|
|
|
import { LightInformationNodeFactory } from './components/diagram/lightInformation/lightInformationNodeFactory';
|
|
|
-import { LightInformationNodeModel } from './components/diagram/lightInformation/lightInformationNodeModel';
|
|
|
-import { LightInformationBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/lightInformationBlock';
|
|
|
import { PreviewAreaComponent } from './components/preview/previewAreaComponent';
|
|
|
-import { GradientBlock } from 'babylonjs/Materials/Node/Blocks/gradientBlock';
|
|
|
-import { GradientNodeModel } from './components/diagram/gradient/gradientNodeModel';
|
|
|
import { GradientNodeFactory } from './components/diagram/gradient/gradientNodeFactory';
|
|
|
-import { ReflectionTextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock';
|
|
|
import { ReflectionTextureNodeFactory } from './components/diagram/reflectionTexture/reflectionTextureNodeFactory';
|
|
|
-import { ReflectionTextureNodeModel } from './components/diagram/reflectionTexture/reflectionTextureNodeModel';
|
|
|
import { SerializationTools } from './serializationTools';
|
|
|
+import { GraphCanvasComponent } from './diagram/graphCanvas';
|
|
|
+import { GraphNode } from './diagram/graphNode';
|
|
|
|
|
|
require("storm-react-diagrams/dist/style.min.css");
|
|
|
require("./main.scss");
|
|
@@ -75,6 +58,7 @@ export class NodeCreationOptions {
|
|
|
|
|
|
export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
private readonly NodeWidth = 100;
|
|
|
+ private _graphCanvas: GraphCanvasComponent;
|
|
|
private _engine: DiagramEngine;
|
|
|
private _model: DiagramModel;
|
|
|
|
|
@@ -84,7 +68,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
private _leftWidth = DataStorage.ReadNumber("LeftWidth", 200);
|
|
|
private _rightWidth = DataStorage.ReadNumber("RightWidth", 300);
|
|
|
|
|
|
- private _nodes = new Array<DefaultNodeModel>();
|
|
|
+ private _nodes = new Array<GraphNode>();
|
|
|
private _blocks = new Array<NodeMaterialBlock>();
|
|
|
|
|
|
private _previewManager: PreviewManager;
|
|
@@ -114,52 +98,19 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
this.props.globalState.nodeMaterial!.attachedBlocks.push(options.nodeMaterialBlock);
|
|
|
}
|
|
|
|
|
|
- // Create new node in the graph
|
|
|
- var newNode: DefaultNodeModel;
|
|
|
-
|
|
|
- if (options.nodeMaterialBlock instanceof TextureBlock) {
|
|
|
- newNode = new TextureNodeModel();
|
|
|
- } else if (options.nodeMaterialBlock instanceof ReflectionTextureBlock) {
|
|
|
- newNode = new ReflectionTextureNodeModel();
|
|
|
- } else if (options.nodeMaterialBlock instanceof LightBlock) {
|
|
|
- newNode = new LightNodeModel();
|
|
|
- } else if (options.nodeMaterialBlock instanceof InputBlock) {
|
|
|
- newNode = new InputNodeModel();
|
|
|
- } else if (options.nodeMaterialBlock instanceof TrigonometryBlock) {
|
|
|
- newNode = new TrigonometryNodeModel();
|
|
|
- } else if (options.nodeMaterialBlock instanceof RemapBlock) {
|
|
|
- newNode = new RemapNodeModel();
|
|
|
- } else if (options.nodeMaterialBlock instanceof ClampBlock) {
|
|
|
- newNode = new ClampNodeModel();
|
|
|
- } else if (options.nodeMaterialBlock instanceof LightInformationBlock) {
|
|
|
- newNode = new LightInformationNodeModel();
|
|
|
- } else if (options.nodeMaterialBlock instanceof GradientBlock) {
|
|
|
- newNode = new GradientNodeModel();
|
|
|
- } else {
|
|
|
- newNode = new GenericNodeModel();
|
|
|
- }
|
|
|
-
|
|
|
if (options.nodeMaterialBlock.isFinalMerger) {
|
|
|
this.props.globalState.nodeMaterial!.addOutputNode(options.nodeMaterialBlock);
|
|
|
}
|
|
|
|
|
|
- this._nodes.push(newNode);
|
|
|
- this._model.addAll(newNode);
|
|
|
-
|
|
|
- if (options.nodeMaterialBlock) {
|
|
|
- newNode.prepare(options, this._nodes, this._model, this);
|
|
|
- }
|
|
|
-
|
|
|
- return newNode;
|
|
|
+ // Graph
|
|
|
+ return this._graphCanvas.appendBlock(options.nodeMaterialBlock);
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
+ return this.createNodeFromObject({ type: type, nodeMaterialBlock: newInputBlock })
|
|
|
}
|
|
|
|
|
|
onWidgetKeyUp(evt: any) {
|
|
@@ -177,6 +128,9 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
|
|
|
componentDidMount() {
|
|
|
if (this.props.globalState.hostDocument) {
|
|
|
+ this._graphCanvas = (this.refs["graphCanvas"] as GraphCanvasComponent);
|
|
|
+
|
|
|
+
|
|
|
var widget = (this.refs["test"] as DiagramWidget);
|
|
|
widget.setState({ document: this.props.globalState.hostDocument })
|
|
|
this._onWidgetKeyUpPointer = this.onWidgetKeyUp.bind(this)
|
|
@@ -213,6 +167,8 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
if (navigator.userAgent.indexOf("Mobile") !== -1) {
|
|
|
((this.props.globalState.hostDocument || document).querySelector(".blocker") as HTMLElement).style.visibility = "visible";
|
|
|
}
|
|
|
+
|
|
|
+ this.build(true);
|
|
|
}
|
|
|
|
|
|
componentWillUnmount() {
|
|
@@ -268,9 +224,9 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
this.reOrganize();
|
|
|
});
|
|
|
|
|
|
- this.props.globalState.onGetNodeFromBlock = (block) => {
|
|
|
- return this._nodes.filter(n => n.block === block)[0];
|
|
|
- }
|
|
|
+ // this.props.globalState.onGetNodeFromBlock = (block) => {
|
|
|
+ // return this._nodes.filter(n => n.block === block)[0];
|
|
|
+ // }
|
|
|
|
|
|
this.props.globalState.hostDocument!.addEventListener("keydown", evt => {
|
|
|
this._altKeyIsPressed = evt.altKey;
|
|
@@ -329,33 +285,18 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
y = currentY;
|
|
|
}
|
|
|
|
|
|
- newNode.setPosition(x, y);
|
|
|
+ newNode.x = x;
|
|
|
+ newNode.y = y;
|
|
|
}
|
|
|
|
|
|
this._engine.repaintCanvas();
|
|
|
}
|
|
|
|
|
|
}, false);
|
|
|
-
|
|
|
- this.build(true);
|
|
|
}
|
|
|
|
|
|
- zoomToFit(retry = 0) {
|
|
|
- const xFactor = this._engine.canvas.clientWidth / this._engine.canvas.scrollWidth;
|
|
|
- const yFactor = this._engine.canvas.clientHeight / this._engine.canvas.scrollHeight;
|
|
|
- const zoomFactor = xFactor < yFactor ? xFactor : yFactor;
|
|
|
-
|
|
|
- if (zoomFactor === 1) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- this._engine.diagramModel.setZoomLevel(this._engine.diagramModel.getZoomLevel() * zoomFactor);
|
|
|
- this._engine.diagramModel.setOffset(0, 0);
|
|
|
- this._engine.repaintCanvas();
|
|
|
- retry++;
|
|
|
- if (retry < 4) {
|
|
|
- setTimeout(() => this.zoomToFit(retry), 1);
|
|
|
- }
|
|
|
+ zoomToFit() {
|
|
|
+ this._graphCanvas.zoomToFit();
|
|
|
}
|
|
|
|
|
|
buildMaterial() {
|
|
@@ -397,152 +338,153 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
this._model = new DiagramModel();
|
|
|
this._nodes = [];
|
|
|
this._blocks = [];
|
|
|
+ this._graphCanvas.reset();
|
|
|
|
|
|
// Listen to events
|
|
|
- this._model.addListener({
|
|
|
- nodesUpdated: (e) => {
|
|
|
- if (!e.isCreated) {
|
|
|
- // Block is deleted
|
|
|
- let targetBlock = (e.node as GenericNodeModel).block;
|
|
|
-
|
|
|
- if (targetBlock) {
|
|
|
- let attachedBlockIndex = this.props.globalState.nodeMaterial!.attachedBlocks.indexOf(targetBlock);
|
|
|
- if (attachedBlockIndex > -1) {
|
|
|
- this.props.globalState.nodeMaterial!.attachedBlocks.splice(attachedBlockIndex, 1);
|
|
|
- }
|
|
|
-
|
|
|
- if (targetBlock.isFinalMerger) {
|
|
|
- this.props.globalState.nodeMaterial!.removeOutputNode(targetBlock);
|
|
|
- }
|
|
|
- let blockIndex = this._blocks.indexOf(targetBlock);
|
|
|
-
|
|
|
- if (blockIndex > -1) {
|
|
|
- this._blocks.splice(blockIndex, 1);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
|
|
|
- } else {
|
|
|
-
|
|
|
- }
|
|
|
- },
|
|
|
- linksUpdated: (e) => {
|
|
|
- if (!e.isCreated) {
|
|
|
- // Link is deleted
|
|
|
- this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
|
|
|
- let sourcePort = e.link.sourcePort as DefaultPortModel;
|
|
|
-
|
|
|
- var link = DefaultPortModel.SortInputOutput(sourcePort, e.link.targetPort as DefaultPortModel);
|
|
|
- if (link) {
|
|
|
- if (link.input.connection && link.output.connection) {
|
|
|
- if (link.input.connection.connectedPoint) {
|
|
|
- // Disconnect standard nodes
|
|
|
- link.output.connection.disconnectFrom(link.input.connection);
|
|
|
- link.input.syncWithNodeMaterialConnectionPoint(link.input.connection);
|
|
|
- link.output.syncWithNodeMaterialConnectionPoint(link.output.connection);
|
|
|
+ // this._model.addListener({
|
|
|
+ // nodesUpdated: (e) => {
|
|
|
+ // if (!e.isCreated) {
|
|
|
+ // // Block is deleted
|
|
|
+ // let targetBlock = (e.node as GenericNodeModel).block;
|
|
|
+
|
|
|
+ // if (targetBlock) {
|
|
|
+ // let attachedBlockIndex = this.props.globalState.nodeMaterial!.attachedBlocks.indexOf(targetBlock);
|
|
|
+ // if (attachedBlockIndex > -1) {
|
|
|
+ // this.props.globalState.nodeMaterial!.attachedBlocks.splice(attachedBlockIndex, 1);
|
|
|
+ // }
|
|
|
+
|
|
|
+ // if (targetBlock.isFinalMerger) {
|
|
|
+ // this.props.globalState.nodeMaterial!.removeOutputNode(targetBlock);
|
|
|
+ // }
|
|
|
+ // let blockIndex = this._blocks.indexOf(targetBlock);
|
|
|
+
|
|
|
+ // if (blockIndex > -1) {
|
|
|
+ // this._blocks.splice(blockIndex, 1);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ // this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
|
|
|
+ // } else {
|
|
|
+
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ // linksUpdated: (e) => {
|
|
|
+ // if (!e.isCreated) {
|
|
|
+ // // Link is deleted
|
|
|
+ // this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
|
|
|
+ // let sourcePort = e.link.sourcePort as DefaultPortModel;
|
|
|
+
|
|
|
+ // var link = DefaultPortModel.SortInputOutput(sourcePort, e.link.targetPort as DefaultPortModel);
|
|
|
+ // if (link) {
|
|
|
+ // if (link.input.connection && link.output.connection) {
|
|
|
+ // if (link.input.connection.connectedPoint) {
|
|
|
+ // // Disconnect standard nodes
|
|
|
+ // link.output.connection.disconnectFrom(link.input.connection);
|
|
|
+ // link.input.syncWithNodeMaterialConnectionPoint(link.input.connection);
|
|
|
+ // link.output.syncWithNodeMaterialConnectionPoint(link.output.connection);
|
|
|
|
|
|
- this.props.globalState.onRebuildRequiredObservable.notifyObservers();
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (!e.link.targetPort && e.link.sourcePort && (e.link.sourcePort as DefaultPortModel).position === "input" && !(e.link.sourcePort as DefaultPortModel).connection!.isConnected) {
|
|
|
- // Drag from input port, we are going to build an input for it
|
|
|
- let input = e.link.sourcePort as DefaultPortModel;
|
|
|
-
|
|
|
- if (input.connection!.type == NodeMaterialBlockConnectionPointTypes.AutoDetect) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- let nodeModel = this.addValueNode(BlockTools.GetStringFromConnectionNodeType(input.connection!.type));
|
|
|
- let link = nodeModel.ports.output.link(input);
|
|
|
-
|
|
|
- nodeModel.x = e.link.points[1].x - this.NodeWidth;
|
|
|
- nodeModel.y = e.link.points[1].y;
|
|
|
-
|
|
|
- setTimeout(() => {
|
|
|
- this._model.addLink(link);
|
|
|
- input.syncWithNodeMaterialConnectionPoint(input.connection!);
|
|
|
- nodeModel.ports.output.syncWithNodeMaterialConnectionPoint(nodeModel.ports.output.connection!);
|
|
|
+ // this.props.globalState.onRebuildRequiredObservable.notifyObservers();
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // if (!e.link.targetPort && e.link.sourcePort && (e.link.sourcePort as DefaultPortModel).position === "input" && !(e.link.sourcePort as DefaultPortModel).connection!.isConnected) {
|
|
|
+ // // Drag from input port, we are going to build an input for it
|
|
|
+ // let input = e.link.sourcePort as DefaultPortModel;
|
|
|
+
|
|
|
+ // if (input.connection!.type == NodeMaterialBlockConnectionPointTypes.AutoDetect) {
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // let nodeModel = this.addValueNode(BlockTools.GetStringFromConnectionNodeType(input.connection!.type));
|
|
|
+ // let link = nodeModel.ports.output.link(input);
|
|
|
+
|
|
|
+ // nodeModel.x = e.link.points[1].x - this.NodeWidth;
|
|
|
+ // nodeModel.y = e.link.points[1].y;
|
|
|
+
|
|
|
+ // setTimeout(() => {
|
|
|
+ // this._model.addLink(link);
|
|
|
+ // input.syncWithNodeMaterialConnectionPoint(input.connection!);
|
|
|
+ // nodeModel.ports.output.syncWithNodeMaterialConnectionPoint(nodeModel.ports.output.connection!);
|
|
|
|
|
|
- let isFragmentOutput = (input.parent as DefaultNodeModel).block!.getClassName() === "FragmentOutputBlock";
|
|
|
+ // let isFragmentOutput = (input.parent as DefaultNodeModel).block!.getClassName() === "FragmentOutputBlock";
|
|
|
|
|
|
- if (isFragmentOutput) {
|
|
|
- this.applyFragmentOutputConstraints(input);
|
|
|
- }
|
|
|
+ // if (isFragmentOutput) {
|
|
|
+ // this.applyFragmentOutputConstraints(input);
|
|
|
+ // }
|
|
|
|
|
|
- this.forceUpdate();
|
|
|
- }, 1);
|
|
|
+ // this.forceUpdate();
|
|
|
+ // }, 1);
|
|
|
|
|
|
- nodeModel.ports.output.connection!.connectTo(input.connection!);
|
|
|
- this.props.globalState.onRebuildRequiredObservable.notifyObservers();
|
|
|
- }
|
|
|
- }
|
|
|
- this.forceUpdate();
|
|
|
- return;
|
|
|
- } else {
|
|
|
- e.link.addListener({
|
|
|
- sourcePortChanged: () => {
|
|
|
- },
|
|
|
- targetPortChanged: (evt) => {
|
|
|
- // Link is created with a target port
|
|
|
- var link = DefaultPortModel.SortInputOutput(e.link.sourcePort as DefaultPortModel, e.link.targetPort as DefaultPortModel);
|
|
|
+ // nodeModel.ports.output.connection!.connectTo(input.connection!);
|
|
|
+ // this.props.globalState.onRebuildRequiredObservable.notifyObservers();
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // this.forceUpdate();
|
|
|
+ // return;
|
|
|
+ // } else {
|
|
|
+ // e.link.addListener({
|
|
|
+ // sourcePortChanged: () => {
|
|
|
+ // },
|
|
|
+ // targetPortChanged: (evt) => {
|
|
|
+ // // Link is created with a target port
|
|
|
+ // var link = DefaultPortModel.SortInputOutput(e.link.sourcePort as DefaultPortModel, e.link.targetPort as DefaultPortModel);
|
|
|
|
|
|
- if (link) {
|
|
|
- if (link.output.connection && link.input.connection) {
|
|
|
- let currentBlock = link.input.connection.ownerBlock;
|
|
|
- let isFragmentOutput = currentBlock.getClassName() === "FragmentOutputBlock";
|
|
|
+ // if (link) {
|
|
|
+ // if (link.output.connection && link.input.connection) {
|
|
|
+ // let currentBlock = link.input.connection.ownerBlock;
|
|
|
+ // let isFragmentOutput = currentBlock.getClassName() === "FragmentOutputBlock";
|
|
|
|
|
|
- // Disconnect previous connection
|
|
|
- for (var key in link.input.links) {
|
|
|
- let other = link.input.links[key];
|
|
|
- let sourcePortConnection = (other.getSourcePort() as DefaultPortModel).connection;
|
|
|
- let targetPortConnection = (other.getTargetPort() as DefaultPortModel).connection;
|
|
|
+ // // Disconnect previous connection
|
|
|
+ // for (var key in link.input.links) {
|
|
|
+ // let other = link.input.links[key];
|
|
|
+ // let sourcePortConnection = (other.getSourcePort() as DefaultPortModel).connection;
|
|
|
+ // let targetPortConnection = (other.getTargetPort() as DefaultPortModel).connection;
|
|
|
|
|
|
- if (
|
|
|
- sourcePortConnection !== (link.output as DefaultPortModel).connection &&
|
|
|
- targetPortConnection !== (link.output as DefaultPortModel).connection
|
|
|
- ) {
|
|
|
- other.remove();
|
|
|
- }
|
|
|
- }
|
|
|
+ // if (
|
|
|
+ // sourcePortConnection !== (link.output as DefaultPortModel).connection &&
|
|
|
+ // targetPortConnection !== (link.output as DefaultPortModel).connection
|
|
|
+ // ) {
|
|
|
+ // other.remove();
|
|
|
+ // }
|
|
|
+ // }
|
|
|
|
|
|
- let compatibilityState = link.output.connection.checkCompatibilityState(link.input.connection);
|
|
|
- if (compatibilityState === NodeMaterialConnectionPointCompatibilityStates.Compatible) {
|
|
|
- if (isFragmentOutput) {
|
|
|
- this.applyFragmentOutputConstraints(link.input);
|
|
|
- }
|
|
|
+ // let compatibilityState = link.output.connection.checkCompatibilityState(link.input.connection);
|
|
|
+ // if (compatibilityState === NodeMaterialConnectionPointCompatibilityStates.Compatible) {
|
|
|
+ // if (isFragmentOutput) {
|
|
|
+ // this.applyFragmentOutputConstraints(link.input);
|
|
|
+ // }
|
|
|
|
|
|
- link.output.connection.connectTo(link.input.connection);
|
|
|
- } else {
|
|
|
- (evt.entity as AdvancedLinkModel).remove();
|
|
|
-
|
|
|
- let message = "";
|
|
|
-
|
|
|
- switch (compatibilityState) {
|
|
|
- case NodeMaterialConnectionPointCompatibilityStates.TypeIncompatible:
|
|
|
- message = "Cannot connect two different connection types";
|
|
|
- break;
|
|
|
- case NodeMaterialConnectionPointCompatibilityStates.TargetIncompatible:
|
|
|
- message = "Source block can only work in fragment shader whereas destination block is currently aimed for the vertex shader";
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- this.props.globalState.onErrorMessageDialogRequiredObservable.notifyObservers(message);
|
|
|
- }
|
|
|
+ // link.output.connection.connectTo(link.input.connection);
|
|
|
+ // } else {
|
|
|
+ // (evt.entity as AdvancedLinkModel).remove();
|
|
|
+
|
|
|
+ // let message = "";
|
|
|
+
|
|
|
+ // switch (compatibilityState) {
|
|
|
+ // case NodeMaterialConnectionPointCompatibilityStates.TypeIncompatible:
|
|
|
+ // message = "Cannot connect two different connection types";
|
|
|
+ // break;
|
|
|
+ // case NodeMaterialConnectionPointCompatibilityStates.TargetIncompatible:
|
|
|
+ // message = "Source block can only work in fragment shader whereas destination block is currently aimed for the vertex shader";
|
|
|
+ // break;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // this.props.globalState.onErrorMessageDialogRequiredObservable.notifyObservers(message);
|
|
|
+ // }
|
|
|
|
|
|
- this.forceUpdate();
|
|
|
- }
|
|
|
- if (this.props.globalState.nodeMaterial) {
|
|
|
- this.buildMaterial();
|
|
|
- }
|
|
|
- } else {
|
|
|
- e.link.remove();
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
+ // this.forceUpdate();
|
|
|
+ // }
|
|
|
+ // if (this.props.globalState.nodeMaterial) {
|
|
|
+ // this.buildMaterial();
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // e.link.remove();
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // });
|
|
|
|
|
|
// Load graph of nodes from the material
|
|
|
if (this.props.globalState.nodeMaterial) {
|
|
@@ -575,26 +517,17 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
|
|
|
reOrganize(locations: Nullable<INodeLocationInfo[]> = null) {
|
|
|
if (!locations) {
|
|
|
- let nodes = GraphHelper.DistributeGraph(this._model);
|
|
|
- nodes.forEach(node => {
|
|
|
- for (var nodeName in this._model.nodes) {
|
|
|
- let modelNode = this._model.nodes[nodeName];
|
|
|
-
|
|
|
- if (modelNode.id === node.id) {
|
|
|
- modelNode.setPosition(node.x - node.width / 2, node.y - node.height / 2);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
+ this._graphCanvas.distributeGraph();
|
|
|
} else {
|
|
|
- for (var location of locations) {
|
|
|
- for (var node of this._nodes) {
|
|
|
- if (node.block && node.block.uniqueId === location.blockId) {
|
|
|
- node.setPosition(location.x, location.y);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ // TO DO
|
|
|
+ // for (var location of locations) {
|
|
|
+ // for (var node of this._nodes) {
|
|
|
+ // if (node.block && node.block.uniqueId === location.blockId) {
|
|
|
+ // node.setPosition(location.x, location.y);
|
|
|
+ // break;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
}
|
|
|
|
|
|
this._engine.repaintCanvas();
|
|
@@ -641,64 +574,70 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
|
|
|
emitNewBlock(event: React.DragEvent<HTMLDivElement>) {
|
|
|
var data = event.dataTransfer.getData("babylonjs-material-node") as string;
|
|
|
- let nodeModel: Nullable<DefaultNodeModel> = null;
|
|
|
+ let newNode: GraphNode;
|
|
|
|
|
|
if (data.indexOf("Block") === -1) {
|
|
|
- nodeModel = this.addValueNode(data);
|
|
|
+ newNode = this.addValueNode(data);
|
|
|
} else {
|
|
|
- let block = BlockTools.GetBlockFromString(data, this.props.globalState.nodeMaterial.getScene(), this.props.globalState.nodeMaterial);
|
|
|
+ let block = BlockTools.GetBlockFromString(data, this.props.globalState.nodeMaterial.getScene(), this.props.globalState.nodeMaterial)!;
|
|
|
|
|
|
- if (block) {
|
|
|
- if (block.isUnique) {
|
|
|
- const className = block.getClassName();
|
|
|
- for (var other of this._blocks) {
|
|
|
- if (other !== block && other.getClassName() === className) {
|
|
|
- this.props.globalState.onErrorMessageDialogRequiredObservable.notifyObservers(`You can only have one ${className} per graph`);
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (block.isUnique) {
|
|
|
+ const className = block.getClassName();
|
|
|
+ for (var other of this._blocks) {
|
|
|
+ if (other !== block && other.getClassName() === className) {
|
|
|
+ this.props.globalState.onErrorMessageDialogRequiredObservable.notifyObservers(`You can only have one ${className} per graph`);
|
|
|
+ return;
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- this._toAdd = [];
|
|
|
- block.autoConfigure(this.props.globalState.nodeMaterial);
|
|
|
- nodeModel = this.createNodeFromObject({ nodeMaterialBlock: block });
|
|
|
- }
|
|
|
+ this._toAdd = [];
|
|
|
+ block.autoConfigure(this.props.globalState.nodeMaterial);
|
|
|
+ newNode = this.createNodeFromObject({ nodeMaterialBlock: block });
|
|
|
};
|
|
|
|
|
|
- if (nodeModel) {
|
|
|
- const zoomLevel = this._engine.diagramModel.getZoomLevel() / 100.0;
|
|
|
+ let x = (event.clientX - event.currentTarget.offsetLeft - this._graphCanvas.x - this.NodeWidth) / this._graphCanvas.zoom;
|
|
|
+ let y = (event.clientY - event.currentTarget.offsetTop - this._graphCanvas.y - 20) / this._graphCanvas.zoom;
|
|
|
+
|
|
|
+ newNode.x = x;
|
|
|
+ newNode.y = y;
|
|
|
+
|
|
|
+ this.props.globalState.onSelectionChangedObservable.notifyObservers(newNode);
|
|
|
|
|
|
- let x = (event.clientX - event.currentTarget.offsetLeft - this._engine.diagramModel.getOffsetX() - this.NodeWidth) / zoomLevel;
|
|
|
- let y = (event.clientY - event.currentTarget.offsetTop - this._engine.diagramModel.getOffsetY() - 20) / zoomLevel;
|
|
|
- nodeModel.setPosition(x, y);
|
|
|
+ // if (nodeModel) {
|
|
|
+ // const zoomLevel = this._engine.diagramModel.getZoomLevel() / 100.0;
|
|
|
+
|
|
|
+ // let x = (event.clientX - event.currentTarget.offsetLeft - this._engine.diagramModel.getOffsetX() - this.NodeWidth) / zoomLevel;
|
|
|
+ // let y = (event.clientY - event.currentTarget.offsetTop - this._engine.diagramModel.getOffsetY() - 20) / zoomLevel;
|
|
|
+ // nodeModel.setPosition(x, y);
|
|
|
|
|
|
- let block = nodeModel!.block;
|
|
|
+ // let block = nodeModel!.block;
|
|
|
|
|
|
- x -= this.NodeWidth + 150;
|
|
|
+ // x -= this.NodeWidth + 150;
|
|
|
|
|
|
- block!._inputs.forEach((connection) => {
|
|
|
- if (connection.connectedPoint) {
|
|
|
- var existingNodes = this._nodes.filter((n) => { return n.block === (connection as any)._connectedPoint._ownerBlock });
|
|
|
- let connectedNode = existingNodes[0];
|
|
|
+ // block!._inputs.forEach((connection) => {
|
|
|
+ // if (connection.connectedPoint) {
|
|
|
+ // var existingNodes = this._nodes.filter((n) => { return n.block === (connection as any)._connectedPoint._ownerBlock });
|
|
|
+ // let connectedNode = existingNodes[0];
|
|
|
|
|
|
- if (connectedNode.x === 0 && connectedNode.y === 0) {
|
|
|
- connectedNode.setPosition(x, y);
|
|
|
- y += 80;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
+ // if (connectedNode.x === 0 && connectedNode.y === 0) {
|
|
|
+ // connectedNode.setPosition(x, y);
|
|
|
+ // y += 80;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // });
|
|
|
|
|
|
- this._engine.repaintCanvas();
|
|
|
+ // this._engine.repaintCanvas();
|
|
|
|
|
|
- setTimeout(() => {
|
|
|
- this._model.addAll(...this._toAdd!);
|
|
|
- this._toAdd = null;
|
|
|
- this._model.clearSelection();
|
|
|
- nodeModel!.setSelected(true);
|
|
|
+ // setTimeout(() => {
|
|
|
+ // this._model.addAll(...this._toAdd!);
|
|
|
+ // this._toAdd = null;
|
|
|
+ // this._model.clearSelection();
|
|
|
+ // nodeModel!.setSelected(true);
|
|
|
|
|
|
- this._engine.repaintCanvas();
|
|
|
- }, 150);
|
|
|
- }
|
|
|
+ // this._engine.repaintCanvas();
|
|
|
+ // }, 150);
|
|
|
+ // }
|
|
|
|
|
|
this.forceUpdate();
|
|
|
}
|
|
@@ -744,6 +683,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
|
|
|
inverseZoom={true}
|
|
|
diagramEngine={this._engine}
|
|
|
maxNumberPointsPerLink={0} />
|
|
|
+ <GraphCanvasComponent ref={"graphCanvas"} globalState={this.props.globalState}/>
|
|
|
</div>
|
|
|
|
|
|
<div id="rightGrab"
|