David Catuhe 5 years ago
parent
commit
23169a8975
60 changed files with 425 additions and 2219 deletions
  1. 0 23
      nodeEditor/src/components/diagram/clamp/clampNodeFactory.tsx
  2. 0 21
      nodeEditor/src/components/diagram/clamp/clampNodeModel.tsx
  3. 0 55
      nodeEditor/src/components/diagram/clamp/clampNodeWidget.tsx
  4. 0 69
      nodeEditor/src/components/diagram/defaultNodeModel.ts
  5. 0 319
      nodeEditor/src/components/diagram/diagram.scss
  6. 0 39
      nodeEditor/src/components/diagram/generic/genericNodeFactory.tsx
  7. 0 84
      nodeEditor/src/components/diagram/generic/genericNodeModel.tsx
  8. 0 60
      nodeEditor/src/components/diagram/generic/genericNodeWidget.tsx
  9. 0 23
      nodeEditor/src/components/diagram/gradient/gradientNodeFactory.tsx
  10. 0 21
      nodeEditor/src/components/diagram/gradient/gradientNodeModel.tsx
  11. 0 58
      nodeEditor/src/components/diagram/gradient/gradientNodeWidget.tsx
  12. 0 1
      nodeEditor/src/components/diagram/images/Matrix.svg
  13. 0 1
      nodeEditor/src/components/diagram/images/Vector1.svg
  14. 0 1
      nodeEditor/src/components/diagram/images/Vector2.svg
  15. 0 1
      nodeEditor/src/components/diagram/images/Vector3.svg
  16. 0 1
      nodeEditor/src/components/diagram/images/Vector4.svg
  17. 0 39
      nodeEditor/src/components/diagram/input/inputNodeFactory.tsx
  18. 0 24
      nodeEditor/src/components/diagram/input/inputNodeModel.tsx
  19. 0 141
      nodeEditor/src/components/diagram/input/inputNodeWidget.tsx
  20. 0 39
      nodeEditor/src/components/diagram/light/lightNodeFactory.tsx
  21. 0 43
      nodeEditor/src/components/diagram/light/lightNodeModel.tsx
  22. 0 47
      nodeEditor/src/components/diagram/light/lightNodeWidget.tsx
  23. 0 39
      nodeEditor/src/components/diagram/lightInformation/lightInformationNodeFactory.tsx
  24. 0 40
      nodeEditor/src/components/diagram/lightInformation/lightInformationNodeModel.tsx
  25. 0 47
      nodeEditor/src/components/diagram/lightInformation/lightInformationNodeWidget.tsx
  26. 0 32
      nodeEditor/src/components/diagram/link/advancedLinkFactory.tsx
  27. 0 7
      nodeEditor/src/components/diagram/link/advancedLinkModel.tsx
  28. 0 75
      nodeEditor/src/components/diagram/port/defaultPortModel.ts
  29. 0 39
      nodeEditor/src/components/diagram/port/defaultPortWidget.tsx
  30. 0 114
      nodeEditor/src/components/diagram/portHelper.tsx
  31. 0 39
      nodeEditor/src/components/diagram/reflectionTexture/reflectionTextureNodeFactory.tsx
  32. 0 43
      nodeEditor/src/components/diagram/reflectionTexture/reflectionTextureNodeModel.tsx
  33. 0 52
      nodeEditor/src/components/diagram/reflectionTexture/reflectionTextureNodeWidget.tsx
  34. 0 39
      nodeEditor/src/components/diagram/remap/remapNodeFactory.tsx
  35. 0 24
      nodeEditor/src/components/diagram/remap/remapNodeModel.tsx
  36. 0 86
      nodeEditor/src/components/diagram/remap/remapNodeWidget.tsx
  37. 0 39
      nodeEditor/src/components/diagram/texture/textureNodeFactory.tsx
  38. 0 43
      nodeEditor/src/components/diagram/texture/textureNodeModel.tsx
  39. 0 52
      nodeEditor/src/components/diagram/texture/textureNodeWidget.tsx
  40. 0 39
      nodeEditor/src/components/diagram/trigonometry/trigonometryNodeFactory.tsx
  41. 0 24
      nodeEditor/src/components/diagram/trigonometry/trigonometryNodeModel.tsx
  42. 0 54
      nodeEditor/src/components/diagram/trigonometry/trigonometryNodeWidget.tsx
  43. 28 0
      nodeEditor/src/diagram/display/clampDisplayManager.ts
  44. 1 1
      nodeEditor/src/diagram/previews/displayManager.ts
  45. 29 0
      nodeEditor/src/diagram/display/gradientDisplayManager.ts
  46. 1 1
      nodeEditor/src/diagram/previews/inputDisplayManager.ts
  47. 2 4
      nodeEditor/src/diagram/previews/outputDisplayManager.ts
  48. 49 0
      nodeEditor/src/diagram/display/remapDisplayManager.ts
  49. 46 0
      nodeEditor/src/diagram/display/textureDisplayManager.ts
  50. 28 0
      nodeEditor/src/diagram/display/trigonometryDisplayManager.ts
  51. 13 2
      nodeEditor/src/diagram/displayLedger.ts
  52. 49 0
      nodeEditor/src/diagram/graphCanvas.scss
  53. 4 0
      nodeEditor/src/diagram/graphCanvas.tsx
  54. 51 21
      nodeEditor/src/diagram/graphNode.ts
  55. 1 1
      nodeEditor/src/diagram/properties/gradientNodePropertyComponent.tsx
  56. 1 1
      nodeEditor/src/components/diagram/gradient/gradientStepComponent.tsx
  57. 8 1
      nodeEditor/src/diagram/properties/inputNodePropertyComponent.tsx
  58. 1 2
      nodeEditor/src/globalState.ts
  59. 87 129
      nodeEditor/src/graphEditor.tsx
  60. 26 19
      nodeEditor/src/sharedComponents/textureLineComponent.tsx

+ 0 - 23
nodeEditor/src/components/diagram/clamp/clampNodeFactory.tsx

@@ -1,23 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-import { ClampNodeWidget } from './clampNodeWidget';
-import { ClampNodeModel } from './clampNodeModel';
-
-export class ClampNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-    constructor(globalState: GlobalState) {
-        super("clamp");
-
-        this._globalState = globalState;
-    }
-
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: ClampNodeModel): JSX.Element {
-        return <ClampNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-    getNewInstance() {
-        return new ClampNodeModel();
-    }
-}

+ 0 - 21
nodeEditor/src/components/diagram/clamp/clampNodeModel.tsx

@@ -1,21 +0,0 @@
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { ClampBlock } from 'babylonjs/Materials/Node/Blocks/clampBlock';
-
-export class ClampNodeModel extends DefaultNodeModel {
-
-    public get clampBlock(): ClampBlock {
-        return this.block as ClampBlock;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("clamp");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-}

+ 0 - 55
nodeEditor/src/components/diagram/clamp/clampNodeWidget.tsx

@@ -1,55 +0,0 @@
-import * as React from "react";
-import { ClampNodeModel } from './clampNodeModel';
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { PortHelper } from '../portHelper';
-import { ClampBlock } from 'babylonjs/Materials/Node/Blocks/clampBlock';
-
-export interface ClampNodeWidgetProps {
-    node: Nullable<ClampNodeModel>;
-    globalState: GlobalState;
-}
-
-export class ClampNodeWidget extends React.Component<ClampNodeWidgetProps> {
-    constructor(props: ClampNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    renderValue(value: string) {
-        if (value) {
-            return (
-                <div className="value-text">
-                    {value}
-                </div>
-            )
-        }
-
-        return null;
-    }
-
-    render() {
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node, undefined, true);
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, true);
-        let clampBlock = this.props.node!.block! as ClampBlock;
-
-        return (
-            <div className={"diagramBlock clamp"}>
-                <div className="header">
-                    {clampBlock.name}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-                <div className="value">  
-                {
-                    `[${clampBlock.minimum}, ${clampBlock.maximum}]`
-                }                 
-                </div>
-            </div>
-        );
-    }
-}

+ 0 - 69
nodeEditor/src/components/diagram/defaultNodeModel.ts

@@ -1,69 +0,0 @@
-import { NodeModel, DiagramModel } from "storm-react-diagrams";
-import { Nullable } from 'babylonjs/types';
-import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
-import { GraphEditor, NodeCreationOptions } from '../../graphEditor';
-import { GlobalState } from '../../globalState';
-import { DefaultPortModel } from './port/defaultPortModel';
-
-/**
- * Generic node model which stores information about a node editor block
- */
-export class DefaultNodeModel extends NodeModel {
-	/**
-	 * The babylon block this node represents
-	 */
-    public block: Nullable<NodeMaterialBlock> = null;
-
-    public ports: { [s: string]: DefaultPortModel };
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor(key: string) {
-        super(key);
-    }
-
-    prepare(options: NodeCreationOptions, nodes: Array<DefaultNodeModel>, model: DiagramModel, graphEditor: GraphEditor) {
-        this.block = options.nodeMaterialBlock || null;
-
-        if (!options.nodeMaterialBlock) {
-            return;
-        }
-        // Create output ports
-        options.nodeMaterialBlock._outputs.forEach((connection: any) => {
-            var outputPort = new DefaultPortModel(connection.name, "output");
-            outputPort.syncWithNodeMaterialConnectionPoint(connection);
-            this.addPort(outputPort)
-        })
-
-        // Create input ports and nodes if they exist
-        options.nodeMaterialBlock._inputs.forEach((connection) => {
-
-            var inputPort = new DefaultPortModel(connection.name, "input");
-            inputPort.connection = connection;
-            this.addPort(inputPort)
-
-            if (connection.connectedPoint) {
-                // Block is not a leaf node, create node for the given block type
-              //  var connectedNode;
-                // var existingNodes = nodes.filter((n) => { return n.block === (connection as any)._connectedPoint._ownerBlock });
-                // if (existingNodes.length == 0) {
-                //     connectedNode = graphEditor.createNodeFromObject({ nodeMaterialBlock: connection.connectedPoint._ownerBlock });
-                // } else {
-                //     connectedNode = existingNodes[0];
-                // }
-
-                // let link = connectedNode.ports[connection.connectedPoint.name].link(inputPort);
-                // if (graphEditor._toAdd) {
-                //     graphEditor._toAdd.push(link);
-                // } else {
-                //     model.addAll(link);
-                // }
-            }
-        });
-    }
-
-    renderProperties(globalState: GlobalState): JSX.Element | null {
-        return null;
-    }
-}

+ 0 - 319
nodeEditor/src/components/diagram/diagram.scss

@@ -1,319 +0,0 @@
-.srd-node {
-    width: 200px;
-}
-
-.srd-node--selected {
-    .diagramBlock {
-        border-color: rgb(255, 255, 255) !important;
-    }
-}
-
-.srd-default-link--path-selected {
-    animation: 0s !important;
-    stroke: #ffffff !important;
-}
-      
-.srd-port {
-    grid-column: 1;
-    grid-row: 1;
-    background: #2796B2;
-    border-radius: 20px;
-    transform: scale(1);
-    width: 20px;
-    height: 20px;
-
-    &.connected {
-        background: #CAB422;
-    }
-
-    &:hover {
-        background: #DDDDDD !important;
-    }
-}
-
-.diagramBlock {
-    background: gray;
-    width: 100%;
-    border: 4px solid black;
-    border-radius: 12px;
-    display: grid;
-    grid-template-rows: 30px auto;
-    grid-template-columns: 50% 50%;    
-    color:white;
-
-    &.input {
-        background: #40866E;
-        color:white;
-
-        .value {
-            grid-row: 2;
-        }
-
-        .outputs {
-            transform: translateY(5px);
-        }
-
-        &.Float {
-            background: #cb9e27;
-        }
-
-        &.Vector2 {
-            background: #16bcb1;
-        }      
-        
-        &.Vector3 {
-            background: #b786cb;
-        }          
-
-        &.Color3 {
-            background: #b786cb;
-        }          
-
-        &.Vector4 {
-            background: #be5126;
-        }          
-
-        &.Color4 {
-            background: #be5126;
-        }          
-
-        &.Matrix {
-            background: #591990;
-        }
-    }
-
-    &.trigonometry {
-        background: rgb(64, 92, 134);
-        color:white;
-
-        .value {
-            grid-row: 2;
-        }
-    }
-
-     &.remap {
-        color:white;
-        background: #4086BB;
-
-        .value {
-            grid-row: 3;
-        }
-
-        .outputs, .inputs {
-            transform: translateY(5px);
-        }        
-    }
-
-    &.clamp {
-        color:white;
-        background: #4086BB;
-
-        .value {
-            grid-row: 2;
-        }
-
-        .outputs, .inputs {
-            transform: translateY(5px);
-        }        
-    }    
-
-    &.gradient {
-        .outputs, .inputs {
-            transform: translateY(5px);
-        }        
-        height: 70px;
-    }
-
-    &.attribute {
-        background: #40866E;
-    }
-
-    &.output {
-        background: rgb(106, 44, 131);
-        color:white;
-
-        .inputs { 
-            color:white;
-        }
-    }
-
-    .header {            
-        grid-row: 1;
-        grid-column: 1 / span 2;
-        border: 4px solid black;
-        border-top-right-radius: 7px;
-        border-top-left-radius: 7px;
-        font-size: 16px;
-        text-align: center;
-        margin-top: -1px;    
-        transform: scaleX(1.001);
-        
-        white-space: nowrap;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        background: black;
-        color: white;
-
-        &.constant {
-            border-color: #4E5C74;
-            background: #4E5C74 !important;
-        }
-
-        &.inspector {
-            border-color: #396437;
-            background: #396437 !important;
-        }
-    }
-
-    .value {
-        grid-row: 3;
-        grid-column: 1 / span 2;
-        height: 34px;
-        text-align: center;
-        font-size: 18px;
-        font-weight: bold;
-        margin: 0 10px;
-
-        .value-text {
-            white-space: nowrap;
-            text-overflow: ellipsis;
-            overflow: hidden;
-        }
-    }
-
-    .inputs {
-        grid-row: 2;
-        grid-column: 1;
-        padding-bottom: 8px;
-
-        .input-port {
-            display: grid;
-            grid-template-columns: 12px calc(100% - 12px);
-            grid-template-rows: 100%;
-
-            .input-port-plug {
-                grid-column: 1;
-                grid-row: 1;
-                display: grid;
-                align-content: center;
-                margin-left: -11px;
-                position: relative;
-
-                &:hover {           
-                    .input-port-connection {
-                        background: greenyellow !important;
-                    }
-                }
-
-                .input-port-type {
-                    width: 15px;
-                    pointer-events: none;
-                    grid-column: 1;
-                    grid-row: 1;
-                    display: grid;
-                    align-items: center;
-                    justify-items: center;     
-                    transform: scale(1);
-
-                    img {
-                        width: 20px;
-                    }
-                }
-            }
-
-            .input-port-label {
-                grid-column: 2;
-                grid-row: 1;         
-                margin-bottom: 4px;    
-                overflow: hidden;
-                white-space: nowrap;
-                text-overflow: ellipsis;   
-            }
-        }
-    }
-
-    .outputs {
-        grid-row: 2;
-        grid-column: 2;
-        padding-bottom: 8px;
-
-        .output-port {
-            display: grid;
-            grid-template-columns: calc(100% - 12px) 12px;
-            grid-template-rows: 100%;
-
-            .output-port-plug {
-                grid-column: 2;
-                grid-row: 1;
-                display: grid;
-                align-content: center;
-                position: relative;    
-                margin-left: 4px;
-
-                &:hover {           
-                    .output-port-connection {
-                        background: greenyellow !important;
-                    }
-                }
-
-                .output-port-type {
-                    pointer-events: none;
-                    grid-column: 1;
-                    grid-row: 1;
-                    display: grid;
-                    align-items: center;
-                    justify-items: center;
-                    transform: scale(1);
-
-                    img {
-                        width: 20px;
-                    }
-                }
-            }
-
-            .output-port-label {
-                text-align: right;
-                grid-column: 1;
-                grid-row: 1;                        
-                margin-bottom: 4px;   
-                overflow: hidden;
-                white-space: nowrap;
-                text-overflow: ellipsis;   
-            }
-        }
-    }
-
-    &.texture-block {
-        display: grid;
-        grid-template-rows: 30px auto 1fr;
-        grid-template-columns: calc(100% - 60px) 60px;
-        background: #323232;
-        color: white;
-
-        .inputs {
-            grid-column: 1;
-            grid-row: 2;
-        }
-
-        .outputs {
-            grid-column: 2;
-            grid-row: 2 / span 2;            
-        }
-
-        .textureLine {
-            height: 140px;
-            grid-column: 1;
-            grid-row: 3;     
-            overflow: hidden;
-            border-bottom-left-radius: 7px;
-            border: black 4px solid;
-            border-left: 0px;
-            border-bottom: 0px;
-
-            canvas {
-                width: 100%;
-                height: 100%;
-            }
-        }
-    }
-}

+ 0 - 39
nodeEditor/src/components/diagram/generic/genericNodeFactory.tsx

@@ -1,39 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import { GenericNodeWidget } from "./genericNodeWidget";
-import { GenericNodeModel } from "./genericNodeModel";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-
-/**
- * Node factory which creates editor nodes
- */
-export class GenericNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-	/**
-	 * Constructs a GenericNodeFactory
-	 */
-    constructor(globalState: GlobalState) {
-        super("generic");
-
-        this._globalState = globalState;
-    }
-
-	/**
-	 * Generates a node widget
-	 * @param diagramEngine diagram engine
-	 * @param node node to generate
-	 * @returns node widget jsx
-	 */
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: GenericNodeModel): JSX.Element {
-        return <GenericNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-	/**
-	 * Gets a new instance of a node model
-	 * @returns generic node model
-	 */
-    getNewInstance() {
-        return new GenericNodeModel();
-    }
-}

+ 0 - 84
nodeEditor/src/components/diagram/generic/genericNodeModel.tsx

@@ -1,84 +0,0 @@
-import * as React from "react";
-import { Nullable } from 'babylonjs/types';
-import { Vector2, Vector3, Vector4, Matrix } from 'babylonjs/Maths/math';
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { DiagramModel } from 'storm-react-diagrams/dist/@types/src/models/DiagramModel';
-import { GraphEditor, NodeCreationOptions } from '../../../graphEditor';
-import { GlobalState } from '../../../globalState';
-import { TextLineComponent } from '../../../sharedComponents/textLineComponent';
-import { LineContainerComponent } from '../../../sharedComponents/lineContainerComponent';
-import { TextInputLineComponent } from '../../../sharedComponents/textInputLineComponent';
-import { CheckBoxLineComponent } from '../../../sharedComponents/checkBoxLineComponent';
-import { TransformBlock } from 'babylonjs/Materials/Node/Blocks/transformBlock';
-
-/**
- * Generic node model which stores information about a node editor block
- */
-export class GenericNodeModel extends DefaultNodeModel {
-	/**
-	 * Vector2 for the node if it exists
-	 */
-    public vector2: Nullable<Vector2> = null;
-	/**
-	 * Vector3 for the node if it exists
-	 */
-    public vector3: Nullable<Vector3> = null;
-	/**
-	 * Vector4 for the node if it exists
-	 */
-    public vector4: Nullable<Vector4> = null;
-	/**
-	 * Matrix for the node if it exists
-	 */
-    public matrix: Nullable<Matrix> = null;
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("generic");
-    }
-
-    prepare(options: NodeCreationOptions, nodes: Array<DefaultNodeModel>, model: DiagramModel, graphEditor: GraphEditor) {
-        super.prepare(options, nodes, model, graphEditor);
-    }
-
-    renderProperties(globalState: GlobalState) {
-
-        return (
-            <div>
-            <LineContainerComponent title="GENERAL">
-                <TextInputLineComponent globalState={globalState} label="Name" propertyName="name" target={this.block!} onChange={() => globalState.onUpdateRequiredObservable.notifyObservers()} />
-                <TextLineComponent label="Type" value={this.block!.getClassName()} />
-            </LineContainerComponent>
-            {
-                this.block!.getClassName() === "TransformBlock" &&
-                <LineContainerComponent title="PROPERTIES">
-                    <CheckBoxLineComponent label="Transform as direction" onSelect={value => {
-                        let transformBlock = this.block as TransformBlock;
-                        if (value) {
-                            transformBlock.complementW = 0;
-                        } else {
-                            transformBlock.complementW = 1;
-                        }
-                        globalState.onRebuildRequiredObservable.notifyObservers();
-                    }} isSelected={() => (this.block as TransformBlock).complementW === 0} />
-                </LineContainerComponent>
-            }                    
-            {
-                this.block!.getClassName() === "PerturbNormalBlock" &&
-                <LineContainerComponent title="PROPERTIES">
-                    <CheckBoxLineComponent label="Invert X axis" target={this.block} propertyName="invertX" onValueChanged={() => globalState.onRebuildRequiredObservable.notifyObservers()} />
-                    <CheckBoxLineComponent label="Invert Y axis" target={this.block} propertyName="invertY" onValueChanged={() => globalState.onRebuildRequiredObservable.notifyObservers()}/>                    
-                </LineContainerComponent>
-            }
-            {
-                this.block!.getClassName() === "WorleyNoise3DBlock" &&
-                <LineContainerComponent title="PROPERTIES">
-                    <CheckBoxLineComponent label="Use Manhattan Distance" target={this.block} propertyName="manhattanDistance" onValueChanged={() => globalState.onRebuildRequiredObservable.notifyObservers()} />              
-                </LineContainerComponent>
-            }
-            </div>
-        );
-    }
-}

+ 0 - 60
nodeEditor/src/components/diagram/generic/genericNodeWidget.tsx

@@ -1,60 +0,0 @@
-import * as React from "react";
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { GenericNodeModel } from './genericNodeModel';
-import { PortHelper } from '../portHelper';
-
-/**
- * GenericNodeWidgetProps
- */
-export interface GenericNodeWidgetProps {
-    node: Nullable<GenericNodeModel>;
-    globalState: GlobalState;
-}
-
-/**
- * GenericNodeWidgetState
- */
-export interface GenericNodeWidgetState {
-
-}
-
-/**
- * Used to display a node block for the node editor
- */
-export class GenericNodeWidget extends React.Component<GenericNodeWidgetProps, GenericNodeWidgetState> {
-	/**
-	 * Creates a GenericNodeWidget
-	 * @param props 
-	 */
-    constructor(props: GenericNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    render() {
-        // Header label
-        var header = "";
-        if (this.props.node && this.props.node.block) {
-            header = this.props.node.block.name;
-        }
-
-        // Input/Output ports
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, false);
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node);
-
-        return (
-            <div className={"diagramBlock" + (outputPorts.length === 0 ? " output" : "")}>
-                <div className="header">
-                    {header}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-            </div>
-        );
-    }
-}

+ 0 - 23
nodeEditor/src/components/diagram/gradient/gradientNodeFactory.tsx

@@ -1,23 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-import { GradientNodeWidget } from './gradientNodeWidget';
-import { GradientNodeModel } from './gradientNodeModel';
-
-export class GradientNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-    constructor(globalState: GlobalState) {
-        super("gradient");
-
-        this._globalState = globalState;
-    }
-
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: GradientNodeModel): JSX.Element {
-        return <GradientNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-    getNewInstance() {
-        return new GradientNodeModel();
-    }
-}

+ 0 - 21
nodeEditor/src/components/diagram/gradient/gradientNodeModel.tsx

@@ -1,21 +0,0 @@
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { GradientBlock } from 'babylonjs/Materials/Node/Blocks/gradientBlock';
-
-export class GradientNodeModel extends DefaultNodeModel {
-
-    public get gradientBlock(): GradientBlock {
-        return this.block as GradientBlock;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("gradient");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-}

+ 0 - 58
nodeEditor/src/components/diagram/gradient/gradientNodeWidget.tsx

@@ -1,58 +0,0 @@
-import * as React from "react";
-import { GradientNodeModel } from './gradientNodeModel';
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { PortHelper } from '../portHelper';
-import { GradientBlock } from 'babylonjs/Materials/Node/Blocks/gradientBlock';
-
-export interface IGradientNodeWidgetProps {
-    node: Nullable<GradientNodeModel>;
-    globalState: GlobalState;
-}
-
-export class GradientNodeWidget extends React.Component<IGradientNodeWidgetProps> {
-    constructor(props: IGradientNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    renderValue(value: string) {
-        if (value) {
-            return (
-                <div className="value-text">
-                    {value}
-                </div>
-            )
-        }
-
-        return null;
-    }
-
-    render() {
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node, undefined, true);
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, true);
-        let gradientBlock = this.props.node!.block! as GradientBlock;
-
-        let gradients = gradientBlock.colorSteps.map(c => `rgb(${c.color.r * 255}, ${c.color.g * 255}, ${c.color.b * 255}) ${c.step * 100}%`);
-
-        let style = {
-            background: gradients.length ? `linear-gradient(90deg, ${gradients.join(", ")})` : 'black'
-        };
-
-        return (
-            <div className={"diagramBlock gradient"} style={style}>
-                <div className="header">
-                    {gradientBlock.name}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-                <div className="value">                
-                </div>
-            </div>
-        );
-    }
-}

File diff suppressed because it is too large
+ 0 - 1
nodeEditor/src/components/diagram/images/Matrix.svg


+ 0 - 1
nodeEditor/src/components/diagram/images/Vector1.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 21"><defs><style>.cls-1{fill:#fff;}</style></defs><title>Vector1</title><g id="Layer_5" data-name="Layer 5"><circle class="cls-1" cx="10.5" cy="10.5" r="7.5"/></g></svg>

+ 0 - 1
nodeEditor/src/components/diagram/images/Vector2.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 21"><defs><style>.cls-1{fill:#fff;}</style></defs><title>Vector2</title><g id="Layer_5" data-name="Layer 5"><path class="cls-1" d="M3,10.5a7.52,7.52,0,0,0,6.5,7.43V3.07A7.52,7.52,0,0,0,3,10.5Z"/><path class="cls-1" d="M11.5,3.07V17.93a7.5,7.5,0,0,0,0-14.86Z"/></g></svg>

+ 0 - 1
nodeEditor/src/components/diagram/images/Vector3.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 21"><defs><style>.cls-1{fill:#fff;}</style></defs><title>Vector3</title><g id="Layer_5" data-name="Layer 5"><path class="cls-1" d="M3.57,13.31,9.5,9.89V3A7.51,7.51,0,0,0,3,10.46,7.32,7.32,0,0,0,3.57,13.31Z"/><path class="cls-1" d="M16.43,15,10.5,11.62,4.57,15a7.48,7.48,0,0,0,11.86,0Z"/><path class="cls-1" d="M18,10.46A7.51,7.51,0,0,0,11.5,3V9.89l5.93,3.42A7.32,7.32,0,0,0,18,10.46Z"/></g></svg>

+ 0 - 1
nodeEditor/src/components/diagram/images/Vector4.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 21"><defs><style>.cls-1{fill:#fff;}</style></defs><title>Vector4</title><g id="Layer_5" data-name="Layer 5"><path class="cls-1" d="M11.5,11.5v6.43a7.51,7.51,0,0,0,6.43-6.43Z"/><path class="cls-1" d="M11.5,3.07V9.5h6.43A7.51,7.51,0,0,0,11.5,3.07Z"/><path class="cls-1" d="M9.5,17.93V11.5H3.07A7.51,7.51,0,0,0,9.5,17.93Z"/><path class="cls-1" d="M9.5,3.07A7.51,7.51,0,0,0,3.07,9.5H9.5Z"/></g></svg>

+ 0 - 39
nodeEditor/src/components/diagram/input/inputNodeFactory.tsx

@@ -1,39 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-import { InputNodeModel } from './inputNodeModel';
-import { InputNodeWidget } from './inputNodeWidget';
-
-/**
- * Node factory which creates editor nodes
- */
-export class InputNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-	/**
-	 * Constructs a GenericNodeFactory
-	 */
-    constructor(globalState: GlobalState) {
-        super("input");
-
-        this._globalState = globalState;
-    }
-
-	/**
-	 * Generates a node widget
-	 * @param diagramEngine diagram engine
-	 * @param node node to generate
-	 * @returns node widget jsx
-	 */
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: InputNodeModel): JSX.Element {
-        return <InputNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-	/**
-	 * Gets a new instance of a node model
-	 * @returns input node model
-	 */
-    getNewInstance() {
-        return new InputNodeModel();
-    }
-}

+ 0 - 24
nodeEditor/src/components/diagram/input/inputNodeModel.tsx

@@ -1,24 +0,0 @@
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
-
-/**
- * Generic node model which stores information about a node editor block
- */
-export class InputNodeModel extends DefaultNodeModel {
-
-    public get inputBlock(): InputBlock {
-        return this.block as InputBlock;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("input");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-}

+ 0 - 141
nodeEditor/src/components/diagram/input/inputNodeWidget.tsx

@@ -1,141 +0,0 @@
-import * as React from "react";
-import { InputNodeModel } from './inputNodeModel';
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { NodeMaterialSystemValues } from 'babylonjs/Materials/Node/Enums/nodeMaterialSystemValues';
-import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes';
-import { Color3, Vector2, Vector3, Vector4 } from 'babylonjs/Maths/math';
-import { StringTools } from '../../../stringTools';
-import { PortHelper } from '../portHelper';
-import { AnimatedInputBlockTypes } from 'babylonjs/Materials/Node/Blocks/Input/animatedInputBlockTypes';
-
-/**
- * GenericNodeWidgetProps
- */
-export interface IInputNodeWidgetProps {
-    node: Nullable<InputNodeModel>;
-    globalState: GlobalState;
-}
-
-/**
- * Used to display a node block for the node editor
- */
-export class InputNodeWidget extends React.Component<IInputNodeWidgetProps> {
-	/**
-	 * Creates a GenericNodeWidget
-	 * @param props 
-	 */
-    constructor(props: IInputNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    renderValue(value: string) {
-        if (value !== "") {
-            return (
-                <div className="value-text">
-                    {value}
-                </div>
-            )
-        }
-
-        return null;
-    }
-
-    render() {
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, true);
-
-        let inputBlock = this.props.node!.inputBlock;
-        let value = "";
-        let name = `${inputBlock.name} (${StringTools.GetBaseType(inputBlock.output.type)})`;
-        let color = "";
-
-        if (inputBlock) {
-            if (inputBlock.isAttribute) {
-                value = "mesh." + inputBlock.name;
-                name = StringTools.GetBaseType(inputBlock.output.type);
-            } else if (inputBlock.isSystemValue) {
-                switch (inputBlock.systemValue) {
-                    case NodeMaterialSystemValues.World:
-                        value = "World";
-                        break;
-                    case NodeMaterialSystemValues.WorldView:
-                        value = "World x View";
-                        break;
-                    case NodeMaterialSystemValues.WorldViewProjection:
-                        value = "World x View x Projection";
-                        break;
-                    case NodeMaterialSystemValues.View:
-                        value = "View";
-                        break;
-                    case NodeMaterialSystemValues.ViewProjection:
-                        value = "View x Projection";
-                        break;
-                    case NodeMaterialSystemValues.Projection:
-                        value = "Projection";
-                        break;
-                    case NodeMaterialSystemValues.CameraPosition:
-                        value = "Camera position";
-                        break;
-                    case NodeMaterialSystemValues.FogColor:
-                        value = "Fog color";
-                        break;
-                    case NodeMaterialSystemValues.DeltaTime:
-                        value = "Delta time";
-                        break;
-                }
-            } else {
-                if (!inputBlock || !inputBlock.isUniform) {
-                    return null;
-                }
-
-                switch (inputBlock.type) {
-                    case NodeMaterialBlockConnectionPointTypes.Float:
-                        if (inputBlock.animationType !== AnimatedInputBlockTypes.None) {
-                            value = AnimatedInputBlockTypes[inputBlock.animationType];
-                        } else {
-                            value = inputBlock.value.toFixed(2);
-                        }
-                        break;
-                    case NodeMaterialBlockConnectionPointTypes.Vector2:
-                        let vec2Value = inputBlock.value as Vector2
-                        value = `(${vec2Value.x.toFixed(2)}, ${vec2Value.y.toFixed(2)})`;
-                        break;
-                    case NodeMaterialBlockConnectionPointTypes.Vector3:
-                        let vec3Value = inputBlock.value as Vector3
-                        value = `(${vec3Value.x.toFixed(2)}, ${vec3Value.y.toFixed(2)}, ${vec3Value.z.toFixed(2)})`;
-                        break;
-                    case NodeMaterialBlockConnectionPointTypes.Vector4:
-                        let vec4Value = inputBlock.value as Vector4
-                        value = `(${vec4Value.x.toFixed(2)}, ${vec4Value.y.toFixed(2)}, ${vec4Value.z.toFixed(2)}, ${vec4Value.w.toFixed(2)})`;
-                        break;                        
-                    case NodeMaterialBlockConnectionPointTypes.Color3:
-                    case NodeMaterialBlockConnectionPointTypes.Color4: {
-                        color = (inputBlock.value as Color3).toHexString();
-                        break;
-                    }
-                }
-            }
-        } else {
-            name = "Not connected input";
-        }
-
-        return (
-            <div className={"diagramBlock input" + (inputBlock ? " " + NodeMaterialBlockConnectionPointTypes[inputBlock.type] : "")} style={{
-                background: color
-            }}>
-                <div className={"header" + (inputBlock && inputBlock.isConstant ? " constant" : "") + (inputBlock && inputBlock.visibleInInspector ? " inspector" : "")}>
-                    {name}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-                <div className="value">
-                    {
-                        this.renderValue(value)
-                    }
-                </div>
-            </div>
-        );
-    }
-}

+ 0 - 39
nodeEditor/src/components/diagram/light/lightNodeFactory.tsx

@@ -1,39 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import { LightNodeWidget } from "./lightNodeWidget";
-import { LightNodeModel } from "./lightNodeModel";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-
-/**
- * Node factory which creates editor nodes
- */
-export class LightNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-	/**
-	 * Constructs a LightNodeFactory
-	 */
-    constructor(globalState: GlobalState) {
-        super("light");
-
-        this._globalState = globalState;
-    }
-
-	/**
-	 * Generates a node widget
-	 * @param diagramEngine diagram engine
-	 * @param node node to generate
-	 * @returns node widget jsx
-	 */
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: LightNodeModel): JSX.Element {
-        return <LightNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-	/**
-	 * Gets a new instance of a node model
-	 * @returns light node model
-	 */
-    getNewInstance() {
-        return new LightNodeModel();
-    }
-}

+ 0 - 43
nodeEditor/src/components/diagram/light/lightNodeModel.tsx

@@ -1,43 +0,0 @@
-import { Nullable } from 'babylonjs/types';
-import { Light } from 'babylonjs/Lights/light';
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { NodeCreationOptions, GraphEditor } from '../../../graphEditor';
-import { DiagramModel } from 'storm-react-diagrams/dist/@types/src/models/DiagramModel';
-import { LightBlock } from 'babylonjs/Materials/Node/Blocks/Dual/lightBlock';
-
-/**
- * Light node model which stores information about a node editor block
- */
-export class LightNodeModel extends DefaultNodeModel {
-    private _block: LightBlock;
-
-	/**
-	 * Light for the node if it exists
-	 */
-    public get light(): Nullable<Light> {
-        return this._block.light;
-    }
-
-    public set light(value: Nullable<Light>) {
-        this._block.light = value;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("light");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-
-    prepare(options: NodeCreationOptions, nodes: Array<DefaultNodeModel>, model: DiagramModel, graphEditor: GraphEditor) {
-        this._block = options.nodeMaterialBlock as LightBlock;
-
-        super.prepare(options, nodes, model, graphEditor);
-    }
-
-}

+ 0 - 47
nodeEditor/src/components/diagram/light/lightNodeWidget.tsx

@@ -1,47 +0,0 @@
-import * as React from "react";
-import { LightNodeModel } from './lightNodeModel';
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { PortHelper } from '../portHelper';
-
-/**
- * GenericNodeWidgetProps
- */
-export interface ILightNodeWidgetProps {
-    node: Nullable<LightNodeModel>;
-    globalState: GlobalState;
-}
-
-/**
- * Used to display a node block for the node editor
- */
-export class LightNodeWidget extends React.Component<ILightNodeWidgetProps> {
-	/**
-	 * Creates a GenericNodeWidget
-	 * @param props 
-	 */
-    constructor(props: ILightNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    render() {
-        // Input/Output ports
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, false);
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node);
-
-        return (
-            <div className={"diagramBlock"}>
-                <div className="header">
-                    {this.props.node!.block!.name}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-            </div>
-        );
-    }
-}

+ 0 - 39
nodeEditor/src/components/diagram/lightInformation/lightInformationNodeFactory.tsx

@@ -1,39 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import { LightInformationNodeWidget } from "./lightInformationNodeWidget";
-import { LightInformationNodeModel } from "./lightInformationNodeModel";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-
-/**
- * Node factory which creates editor nodes
- */
-export class LightInformationNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-	/**
-	 * Constructs a LightNodeFactory
-	 */
-    constructor(globalState: GlobalState) {
-        super("light-information");
-
-        this._globalState = globalState;
-    }
-
-	/**
-	 * Generates a node widget
-	 * @param diagramEngine diagram engine
-	 * @param node node to generate
-	 * @returns node widget jsx
-	 */
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: LightInformationNodeModel): JSX.Element {
-        return <LightInformationNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-	/**
-	 * Gets a new instance of a node model
-	 * @returns light node model
-	 */
-    getNewInstance() {
-        return new LightInformationNodeModel();
-    }
-}

+ 0 - 40
nodeEditor/src/components/diagram/lightInformation/lightInformationNodeModel.tsx

@@ -1,40 +0,0 @@
-import { Nullable } from 'babylonjs/types';
-import { Light } from 'babylonjs/Lights/light';
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { NodeCreationOptions, GraphEditor } from '../../../graphEditor';
-import { DiagramModel } from 'storm-react-diagrams/dist/@types/src/models/DiagramModel';
-import { LightInformationBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/lightInformationBlock';
-
-export class LightInformationNodeModel extends DefaultNodeModel {
-    private _block: LightInformationBlock;
-
-	/**
-	 * Light for the node if it exists
-	 */
-    public get light(): Nullable<Light> {
-        return this._block.light;
-    }
-
-    public set light(value: Nullable<Light>) {
-        this._block.light = value;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("light-information");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-
-    prepare(options: NodeCreationOptions, nodes: Array<DefaultNodeModel>, model: DiagramModel, graphEditor: GraphEditor) {
-        this._block = options.nodeMaterialBlock as LightInformationBlock;
-
-        super.prepare(options, nodes, model, graphEditor);
-    }
-
-}

+ 0 - 47
nodeEditor/src/components/diagram/lightInformation/lightInformationNodeWidget.tsx

@@ -1,47 +0,0 @@
-import * as React from "react";
-import { LightInformationNodeModel } from './lightInformationNodeModel';
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { PortHelper } from '../portHelper';
-
-/**
- * GenericNodeWidgetProps
- */
-export interface ILightInformationNodeWidgetProps {
-    node: Nullable<LightInformationNodeModel>;
-    globalState: GlobalState;
-}
-
-/**
- * Used to display a node block for the node editor
- */
-export class LightInformationNodeWidget extends React.Component<ILightInformationNodeWidgetProps> {
-	/**
-	 * Creates a GenericNodeWidget
-	 * @param props 
-	 */
-    constructor(props: ILightInformationNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    render() {
-        // Input/Output ports
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, false);
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node);
-
-        return (
-            <div className={"diagramBlock"}>
-                <div className="header">
-                    {`${this.props.node!.block!.name} (${this.props.node!.light ? this.props.node!.light.name : "No light"})`}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-            </div>
-        );
-    }
-}

+ 0 - 32
nodeEditor/src/components/diagram/link/advancedLinkFactory.tsx

@@ -1,32 +0,0 @@
-import { DefaultLinkFactory, DefaultLinkWidget } from 'storm-react-diagrams';
-import * as React from 'react';
-import { DefaultPortModel } from '../port/defaultPortModel';
-import { AdvancedLinkModel } from './advancedLinkModel';
-import { BlockTools } from '../../../blockTools';
-
-export class AdvancedLinkFactory extends DefaultLinkFactory {
-	constructor() {
-		super();
-		this.type = "advanced";
-	}
-
-	getNewInstance(initialConfig?: any): AdvancedLinkModel {
-		return new AdvancedLinkModel();
-	}
-
-	generateLinkSegment(model: AdvancedLinkModel, widget: DefaultLinkWidget, selected: boolean, path: string) {
-        const portModel = (model.getTargetPort() || model.getSourcePort()) as DefaultPortModel;
-        const type = portModel.connection!.type;
-		let color = BlockTools.GetColorFromConnectionNodeType(type);
-		let width = 3;
-
-		return (
-			<path
-				className={selected ? widget.bem("--path-selected") : ""}
-				strokeWidth={width}
-				stroke={color}
-				d={path}
-			/>
-		);
-	}
-}

+ 0 - 7
nodeEditor/src/components/diagram/link/advancedLinkModel.tsx

@@ -1,7 +0,0 @@
-import { DefaultLinkModel } from 'storm-react-diagrams';
-
-export class AdvancedLinkModel extends DefaultLinkModel {
-	constructor() {
-		super("advanced");
-	}
-}

+ 0 - 75
nodeEditor/src/components/diagram/port/defaultPortModel.ts

@@ -1,75 +0,0 @@
-import { LinkModel, PortModel } from "storm-react-diagrams";
-import { Nullable } from 'babylonjs/types';
-import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { AdvancedLinkModel } from '../link/advancedLinkModel';
-
-/**
- * Port model
- */
-export class DefaultPortModel extends PortModel {
-	/**
-	 * If the port is input or output
-	 */
-    public position: string | "input" | "output";
-	/**
-	 * What the port is connected to
-	 */
-    public connection: Nullable<NodeMaterialConnectionPoint> = null;
-
-    public defaultValue: any;
-
-    static idCounter = 0;
-
-    constructor(name: string, type: string = "input") {
-        super(name, "generic");
-        this.position = type;
-        DefaultPortModel.idCounter++;
-    }
-
-    canLinkToPort(port: DefaultPortModel): boolean {
-        if (!this.connection || !port.connection) {
-            return true;
-        }
-
-        return this.connection.canConnectTo(port.connection);
-    }
-
-    syncWithNodeMaterialConnectionPoint(connection: NodeMaterialConnectionPoint) {
-        this.connection = connection;
-        this.name = connection.name;
-    }
-
-    getNodeModel() {
-        return this.parent as DefaultNodeModel
-    }
-
-    link(outPort: DefaultPortModel) {
-        var link = this.createLinkModel()
-        link.setSourcePort(this)
-        link.setTargetPort(outPort)
-        return link;
-    }
-
-    createLinkModel(): LinkModel {
-        return new AdvancedLinkModel();
-    }
-
-    static SortInputOutput(a: Nullable<DefaultPortModel>, b: Nullable<DefaultPortModel>) {
-        if (!a || !b) {
-            return null;
-        } else if (a.position == "output" && b.position == "input") {
-            return {
-                input: b,
-                output: a
-            }
-        } else if (b.position == "output" && a.position == "input") {
-            return {
-                input: a,
-                output: b
-            }
-        } else {
-            return null;
-        }
-    }
-}

+ 0 - 39
nodeEditor/src/components/diagram/port/defaultPortWidget.tsx

@@ -1,39 +0,0 @@
-import { BaseWidget, PortState, NodeModel, BaseWidgetProps } from 'storm-react-diagrams';
-import * as React from 'react';
-
-
-export interface IDefaultPortWidgetProps extends BaseWidgetProps {
-	name: string;
-	node: NodeModel;
-    style: any;
-}
-
-export class DefaultPortWidget extends BaseWidget<IDefaultPortWidgetProps, PortState> {
-    constructor(props: IDefaultPortWidgetProps) {
-		super("srd-port", props);
-		this.state = {
-			selected: false
-		};
-	}
-
-	getClassName() {
-		return "port " + super.getClassName() + (this.state.selected ? this.bem("--selected") : "");
-	}
-
-	render() {
-		return (
-			<div
-				style={this.props.style}
-				{...this.getProps()}
-				onMouseEnter={() => {
-					this.setState({ selected: true });
-				}}
-				onMouseLeave={() => {
-					this.setState({ selected: false });
-				}}
-				data-name={this.props.name}
-				data-nodeid={this.props.node.getID()}
-			/>
-		);
-	}
-}

File diff suppressed because it is too large
+ 0 - 114
nodeEditor/src/components/diagram/portHelper.tsx


+ 0 - 39
nodeEditor/src/components/diagram/reflectionTexture/reflectionTextureNodeFactory.tsx

@@ -1,39 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-import { ReflectionTextureNodeModel } from './reflectionTextureNodeModel';
-import { ReflectionTextureNodeWidget } from './reflectionTextureNodeWidget';
-
-/**
- * Node factory which creates editor nodes
- */
-export class ReflectionTextureNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-	/**
-	 * Constructs a TextureNodeFactory
-	 */
-    constructor(globalState: GlobalState) {
-        super("reflectiontexture");
-
-        this._globalState = globalState;
-    }
-
-	/**
-	 * Generates a node widget
-	 * @param diagramEngine diagram engine
-	 * @param node node to generate
-	 * @returns node widget jsx
-	 */
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: ReflectionTextureNodeModel): JSX.Element {
-        return <ReflectionTextureNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-	/**
-	 * Gets a new instance of a node model
-	 * @returns texture node model
-	 */
-    getNewInstance() {
-        return new ReflectionTextureNodeModel();
-    }
-}

+ 0 - 43
nodeEditor/src/components/diagram/reflectionTexture/reflectionTextureNodeModel.tsx

@@ -1,43 +0,0 @@
-import { Nullable } from 'babylonjs/types';
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { NodeCreationOptions, GraphEditor } from '../../../graphEditor';
-import { DiagramModel } from 'storm-react-diagrams/dist/@types/src/models/DiagramModel';
-import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture';
-import { ReflectionTextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock';
-
-/**
- * Texture node model which stores information about a node editor block
- */
-export class ReflectionTextureNodeModel extends DefaultNodeModel {
-    private _block: ReflectionTextureBlock;
-
-	/**
-	 * Texture for the node if it exists
-	 */
-    public get texture(): Nullable<BaseTexture> {
-        return this._block.texture;
-    }
-
-    public set texture(value: Nullable<BaseTexture>) {
-        this._block.texture = value;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("reflectiontexture");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-
-    prepare(options: NodeCreationOptions, nodes: Array<DefaultNodeModel>, model: DiagramModel, graphEditor: GraphEditor) {
-        this._block = options.nodeMaterialBlock as ReflectionTextureBlock;
-
-        super.prepare(options, nodes, model, graphEditor);
-    }
-
-}

+ 0 - 52
nodeEditor/src/components/diagram/reflectionTexture/reflectionTextureNodeWidget.tsx

@@ -1,52 +0,0 @@
-import * as React from "react";
-import { TextureLineComponent } from "../../../sharedComponents/textureLineComponent"
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { PortHelper } from '../portHelper';
-import { ReflectionTextureNodeModel } from './reflectionTextureNodeModel';
-
-/**
- * GenericNodeWidgetProps
- */
-export interface IReflectionTextureNodeWidgetProps {
-    node: Nullable<ReflectionTextureNodeModel>;
-    globalState: GlobalState;
-}
-
-/**
- * Used to display a node block for the node editor
- */
-export class ReflectionTextureNodeWidget extends React.Component<IReflectionTextureNodeWidgetProps> {
-	/**
-	 * Creates a GenericNodeWidget
-	 * @param props 
-	 */
-    constructor(props: IReflectionTextureNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    render() {
-        // Input/Output ports
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, false);
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node);
-
-        return (
-            <div className={"diagramBlock texture-block"}>
-                <div className="header">
-                    {this.props.node!.block!.name}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-                {
-                    this.props.node && this.props.node.texture &&
-                    <TextureLineComponent ref="textureView" width={140} height={140} texture={this.props.node.texture} hideChannelSelect={true} />
-                }
-            </div>
-        );
-    }
-}

+ 0 - 39
nodeEditor/src/components/diagram/remap/remapNodeFactory.tsx

@@ -1,39 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-import { RemapNodeModel } from './remapNodeModel';
-import { RemapNodeWidget } from './remapNodeWidget';
-
-/**
- * Node factory which creates editor nodes
- */
-export class RemapNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-	/**
-	 * Constructs a GenericNodeFactory
-	 */
-    constructor(globalState: GlobalState) {
-        super("remap");
-
-        this._globalState = globalState;
-    }
-
-	/**
-	 * Generates a node widget
-	 * @param diagramEngine diagram engine
-	 * @param node node to generate
-	 * @returns node widget jsx
-	 */
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: RemapNodeModel): JSX.Element {
-        return <RemapNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-	/**
-	 * Gets a new instance of a node model
-	 * @returns input node model
-	 */
-    getNewInstance() {
-        return new RemapNodeModel();
-    }
-}

+ 0 - 24
nodeEditor/src/components/diagram/remap/remapNodeModel.tsx

@@ -1,24 +0,0 @@
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { RemapBlock } from 'babylonjs/Materials/Node/Blocks/remapBlock';
-
-/**
- * Generic node model which stores information about a node editor block
- */
-export class RemapNodeModel extends DefaultNodeModel {
-
-    public get remapBlock(): RemapBlock {
-        return this.block as RemapBlock;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("remap");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-}

+ 0 - 86
nodeEditor/src/components/diagram/remap/remapNodeWidget.tsx

@@ -1,86 +0,0 @@
-import * as React from "react";
-import { RemapNodeModel } from './remapNodeModel';
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { PortHelper } from '../portHelper';
-import { RemapBlock } from 'babylonjs/Materials/Node/Blocks/remapBlock';
-import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
-import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
-
-/**
- * RemapNodeWidgetProps
- */
-export interface RemapNodeWidgetProps {
-    node: Nullable<RemapNodeModel>;
-    globalState: GlobalState;
-}
-
-/**
- * Used to display a node block for the node editor
- */
-export class RemapNodeWidget extends React.Component<RemapNodeWidgetProps> {
-	/**
-	 * Creates a GenericNodeWidget
-	 * @param props 
-	 */
-    constructor(props: RemapNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    renderValue(value: string) {
-        if (value) {
-            return (
-                <div className="value-text">
-                    {value}
-                </div>
-            )
-        }
-
-        return null;
-    }
-
-    extractInputValue(connectionPoint: NodeMaterialConnectionPoint) {
-        let connectedBlock = connectionPoint.connectedPoint!.ownerBlock;
-
-        if (connectedBlock.isInput) {
-            let inputBlock = connectedBlock as InputBlock;
-
-            if (inputBlock.isUniform && !inputBlock.isSystemValue) {
-                return inputBlock.value;
-            }
-        }
-
-        return "?";
-    }
-
-    render() {
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node, undefined, false);
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, false);
-        let remapBlock = this.props.node!.block! as RemapBlock;
-
-        let sourceRangeX = remapBlock.sourceMin.isConnected ? this.extractInputValue(remapBlock.sourceMin) : remapBlock.sourceRange.x;
-        let sourceRangeY = remapBlock.sourceMax.isConnected ? this.extractInputValue(remapBlock.sourceMax) : remapBlock.sourceRange.y;
-        let targetRangeX = remapBlock.targetMin.isConnected ? this.extractInputValue(remapBlock.targetMin) : remapBlock.targetRange.x;
-        let targetRangeY = remapBlock.targetMax.isConnected ? this.extractInputValue(remapBlock.targetMax) : remapBlock.targetRange.y;
-
-        return (
-            <div className={"diagramBlock remap"}>
-                <div className="header">
-                    {remapBlock.name}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-                <div className="value">  
-                {
-                    `[${sourceRangeX}, ${sourceRangeY}] -> [${targetRangeX}, ${targetRangeY}]`
-                }                 
-                </div>
-            </div>
-        );
-    }
-}

+ 0 - 39
nodeEditor/src/components/diagram/texture/textureNodeFactory.tsx

@@ -1,39 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import { TextureNodeWidget } from "./textureNodeWidget";
-import { TextureNodeModel } from "./textureNodeModel";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-
-/**
- * Node factory which creates editor nodes
- */
-export class TextureNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-	/**
-	 * Constructs a TextureNodeFactory
-	 */
-    constructor(globalState: GlobalState) {
-        super("texture");
-
-        this._globalState = globalState;
-    }
-
-	/**
-	 * Generates a node widget
-	 * @param diagramEngine diagram engine
-	 * @param node node to generate
-	 * @returns node widget jsx
-	 */
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: TextureNodeModel): JSX.Element {
-        return <TextureNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-	/**
-	 * Gets a new instance of a node model
-	 * @returns texture node model
-	 */
-    getNewInstance() {
-        return new TextureNodeModel();
-    }
-}

+ 0 - 43
nodeEditor/src/components/diagram/texture/textureNodeModel.tsx

@@ -1,43 +0,0 @@
-import { Nullable } from 'babylonjs/types';
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { NodeCreationOptions, GraphEditor } from '../../../graphEditor';
-import { DiagramModel } from 'storm-react-diagrams/dist/@types/src/models/DiagramModel';
-import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/textureBlock';
-import { Texture } from 'babylonjs/Materials/Textures/texture';
-
-/**
- * Texture node model which stores information about a node editor block
- */
-export class TextureNodeModel extends DefaultNodeModel {
-    private _block: TextureBlock;
-
-	/**
-	 * Texture for the node if it exists
-	 */
-    public get texture(): Nullable<Texture> {
-        return this._block.texture;
-    }
-
-    public set texture(value: Nullable<Texture>) {
-        this._block.texture = value;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("texture");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-
-    prepare(options: NodeCreationOptions, nodes: Array<DefaultNodeModel>, model: DiagramModel, graphEditor: GraphEditor) {
-        this._block = options.nodeMaterialBlock as TextureBlock;
-
-        super.prepare(options, nodes, model, graphEditor);
-    }
-
-}

+ 0 - 52
nodeEditor/src/components/diagram/texture/textureNodeWidget.tsx

@@ -1,52 +0,0 @@
-import * as React from "react";
-import { TextureNodeModel } from './textureNodeModel';
-import { TextureLineComponent } from "../../../sharedComponents/textureLineComponent"
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { PortHelper } from '../portHelper';
-
-/**
- * GenericNodeWidgetProps
- */
-export interface ITextureNodeWidgetProps {
-    node: Nullable<TextureNodeModel>;
-    globalState: GlobalState;
-}
-
-/**
- * Used to display a node block for the node editor
- */
-export class TextureNodeWidget extends React.Component<ITextureNodeWidgetProps> {
-	/**
-	 * Creates a GenericNodeWidget
-	 * @param props 
-	 */
-    constructor(props: ITextureNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    render() {
-        // Input/Output ports
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, false);
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node, ["uv"]);
-
-        return (
-            <div className={"diagramBlock texture-block"}>
-                <div className="header">
-                    {this.props.node!.block!.name}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-                {
-                    this.props.node && this.props.node.texture &&
-                    <TextureLineComponent ref="textureView" width={140} height={140} texture={this.props.node.texture} hideChannelSelect={true} />
-                }
-            </div>
-        );
-    }
-}

+ 0 - 39
nodeEditor/src/components/diagram/trigonometry/trigonometryNodeFactory.tsx

@@ -1,39 +0,0 @@
-import * as SRD from "storm-react-diagrams";
-import * as React from "react";
-import { GlobalState } from '../../../globalState';
-import { TrigonometryNodeModel } from './trigonometryNodeModel';
-import { TrigonometryNodeWidget } from './trigonometryNodeWidget';
-
-/**
- * Node factory which creates editor nodes
- */
-export class TrigonometryNodeFactory extends SRD.AbstractNodeFactory {
-    private _globalState: GlobalState;
-
-	/**
-	 * Constructs a GenericNodeFactory
-	 */
-    constructor(globalState: GlobalState) {
-        super("trigonometry");
-
-        this._globalState = globalState;
-    }
-
-	/**
-	 * Generates a node widget
-	 * @param diagramEngine diagram engine
-	 * @param node node to generate
-	 * @returns node widget jsx
-	 */
-    generateReactWidget(diagramEngine: SRD.DiagramEngine, node: TrigonometryNodeModel): JSX.Element {
-        return <TrigonometryNodeWidget node={node} globalState={this._globalState} />;
-    }
-
-	/**
-	 * Gets a new instance of a node model
-	 * @returns input node model
-	 */
-    getNewInstance() {
-        return new TrigonometryNodeModel();
-    }
-}

+ 0 - 24
nodeEditor/src/components/diagram/trigonometry/trigonometryNodeModel.tsx

@@ -1,24 +0,0 @@
-import { DefaultNodeModel } from '../defaultNodeModel';
-import { GlobalState } from '../../../globalState';
-import { TrigonometryBlock } from 'babylonjs/Materials/Node/Blocks/trigonometryBlock';
-
-/**
- * Generic node model which stores information about a node editor block
- */
-export class TrigonometryNodeModel extends DefaultNodeModel {
-
-    public get trigonometryBlock(): TrigonometryBlock {
-        return this.block as TrigonometryBlock;
-    }
-
-	/**
-	 * Constructs the node model
-	 */
-    constructor() {
-        super("trigonometry");
-    }
-
-    renderProperties(globalState: GlobalState) {
-        return null;
-    }
-}

+ 0 - 54
nodeEditor/src/components/diagram/trigonometry/trigonometryNodeWidget.tsx

@@ -1,54 +0,0 @@
-import * as React from "react";
-import { TrigonometryNodeModel } from './trigonometryNodeModel';
-import { Nullable } from 'babylonjs/types';
-import { GlobalState } from '../../../globalState';
-import { PortHelper } from '../portHelper';
-import { TrigonometryBlockOperations } from 'babylonjs/Materials/Node/Blocks/trigonometryBlock';
-
-/**
- * GenericNodeWidgetProps
- */
-export interface ITrigonometryNodeWidgetProps {
-    node: Nullable<TrigonometryNodeModel>;
-    globalState: GlobalState;
-}
-
-/**
- * Used to display a node block for the node editor
- */
-export class TrigonometryNodeWidget extends React.Component<ITrigonometryNodeWidgetProps> {
-	/**
-	 * Creates a GenericNodeWidget
-	 * @param props 
-	 */
-    constructor(props: ITrigonometryNodeWidgetProps) {
-        super(props);
-        this.state = {};
-    }
-
-    render() {
-        var outputPorts = PortHelper.GenerateOutputPorts(this.props.node, false);        
-        var inputPorts = PortHelper.GenerateInputPorts(this.props.node);
-
-        let trigonometryBlock = this.props.node!.trigonometryBlock;
-
-        return (
-            <div className={"diagramBlock trigonometry"}>
-                <div className="header">
-                    {trigonometryBlock.name}
-                </div>
-                <div className="inputs">
-                    {inputPorts}
-                </div>
-                <div className="outputs">
-                    {outputPorts}
-                </div>
-                <div className="value">
-                    <div className="value-text">
-                        {TrigonometryBlockOperations[trigonometryBlock.operation]}
-                    </div>
-                </div>
-            </div>
-        );
-    }
-}

+ 28 - 0
nodeEditor/src/diagram/display/clampDisplayManager.ts

@@ -0,0 +1,28 @@
+import { IDisplayManager } from './displayManager';
+import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+import { ClampBlock } from 'babylonjs/Materials/Node/Blocks/clampBlock';
+
+export class ClampDisplayManager implements IDisplayManager {
+    public getHeaderClass(block: NodeMaterialBlock) {
+        return "";
+    }
+
+    public shouldDisplayPortLabels(block: NodeMaterialBlock): boolean {
+        return false;
+    }
+
+    public getHeaderText(block: NodeMaterialBlock): string {
+        return block.name;
+    }
+
+    public getBackgroundColor(block: NodeMaterialBlock): string {
+        return "#4086BB";
+    }
+
+    public updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {       
+        const clampBlock = block as ClampBlock;
+
+        contentArea.classList.add("clamp-block");
+        contentArea.innerHTML = `[${clampBlock.minimum}, ${clampBlock.maximum}]`;
+    }
+}

+ 1 - 1
nodeEditor/src/diagram/previews/displayManager.ts

@@ -3,7 +3,7 @@ import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
 export interface IDisplayManager {
     getHeaderClass(block: NodeMaterialBlock): string;
     shouldDisplayPortLabels(block: NodeMaterialBlock): boolean;
-    setPreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void;
+    updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void;
     getBackgroundColor(block: NodeMaterialBlock): string;
     getHeaderText(block: NodeMaterialBlock): string;
 }

+ 29 - 0
nodeEditor/src/diagram/display/gradientDisplayManager.ts

@@ -0,0 +1,29 @@
+import { IDisplayManager } from './displayManager';
+import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+import { GradientBlock } from 'babylonjs/Materials/Node/Blocks/gradientBlock';
+
+export class GradientDisplayManager implements IDisplayManager {
+    public getHeaderClass(block: NodeMaterialBlock) {
+        return "";
+    }
+
+    public shouldDisplayPortLabels(block: NodeMaterialBlock): boolean {
+        return false;
+    }
+
+    public getHeaderText(block: NodeMaterialBlock): string {
+        return block.name;
+    }
+
+    public getBackgroundColor(block: NodeMaterialBlock): string {
+        let gradientBlock = block as GradientBlock;
+
+        let gradients = gradientBlock.colorSteps.map(c => `rgb(${c.color.r * 255}, ${c.color.g * 255}, ${c.color.b * 255}) ${c.step * 100}%`);
+
+        return gradients.length ? `linear-gradient(90deg, ${gradients.join(", ")})` : 'black';
+    }
+
+    public updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {       
+        contentArea.classList.add("gradient-block");
+    }
+}

+ 1 - 1
nodeEditor/src/diagram/previews/inputDisplayManager.ts

@@ -57,7 +57,7 @@ export class InputDisplayManager implements IDisplayManager {
         return color;
     }
 
-    public setPreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {
+    public updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {
         let value = "";
         let inputBlock = block as InputBlock;
 

+ 2 - 4
nodeEditor/src/diagram/previews/outputDisplayManager.ts

@@ -1,6 +1,5 @@
 import { IDisplayManager } from './displayManager';
 import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
-import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
 
 export class OutputDisplayManager implements IDisplayManager {
     public getHeaderClass(block: NodeMaterialBlock) {
@@ -12,15 +11,14 @@ export class OutputDisplayManager implements IDisplayManager {
     }
 
     public getHeaderText(block: NodeMaterialBlock): string {
-        let inputBlock = block as InputBlock;
-        return inputBlock.name;
+        return block.name;
     }
 
     public getBackgroundColor(block: NodeMaterialBlock): string {
         return "rgb(106, 44, 131)";
     }
 
-    public setPreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {       
+    public updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {       
         contentArea.classList.add("output-block");
     }
 }

+ 49 - 0
nodeEditor/src/diagram/display/remapDisplayManager.ts

@@ -0,0 +1,49 @@
+import { IDisplayManager } from './displayManager';
+import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
+import { RemapBlock } from 'babylonjs/Materials/Node/Blocks/remapBlock';
+import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
+
+export class RemapDisplayManager implements IDisplayManager {
+    public getHeaderClass(block: NodeMaterialBlock) {
+        return "";
+    }
+
+    public shouldDisplayPortLabels(block: NodeMaterialBlock): boolean {
+        return true;
+    }
+
+    public getHeaderText(block: NodeMaterialBlock): string {
+        return block.name;
+    }
+
+    public getBackgroundColor(block: NodeMaterialBlock): string {
+        return "#4086BB";
+    }
+
+    private _extractInputValue(connectionPoint: NodeMaterialConnectionPoint) {
+        let connectedBlock = connectionPoint.connectedPoint!.ownerBlock;
+
+        if (connectedBlock.isInput) {
+            let inputBlock = connectedBlock as InputBlock;
+
+            if (inputBlock.isUniform && !inputBlock.isSystemValue) {
+                return inputBlock.value;
+            }
+        }
+
+        return "?";
+    }
+
+    public updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {       
+        const remapBlock = block as RemapBlock;
+
+        let sourceRangeX = remapBlock.sourceMin.isConnected ? this._extractInputValue(remapBlock.sourceMin) : remapBlock.sourceRange.x;
+        let sourceRangeY = remapBlock.sourceMax.isConnected ? this._extractInputValue(remapBlock.sourceMax) : remapBlock.sourceRange.y;
+        let targetRangeX = remapBlock.targetMin.isConnected ? this._extractInputValue(remapBlock.targetMin) : remapBlock.targetRange.x;
+        let targetRangeY = remapBlock.targetMax.isConnected ? this._extractInputValue(remapBlock.targetMax) : remapBlock.targetRange.y;        
+
+        contentArea.classList.add("remap-block");
+        contentArea.innerHTML = `[${sourceRangeX}, ${sourceRangeY}] -> [${targetRangeX}, ${targetRangeY}]`;
+    }
+}

+ 46 - 0
nodeEditor/src/diagram/display/textureDisplayManager.ts

@@ -0,0 +1,46 @@
+import { IDisplayManager } from './displayManager';
+import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/textureBlock';
+import { ReflectionTextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock';
+import { TextureLineComponent } from '../../sharedComponents/textureLineComponent';
+
+export class TextureDisplayManager implements IDisplayManager {
+    private _previewCanvas: HTMLCanvasElement;
+
+    public getHeaderClass(block: NodeMaterialBlock) {
+        return "";
+    }
+
+    public shouldDisplayPortLabels(block: NodeMaterialBlock): boolean {
+        return true;
+    }
+
+    public getHeaderText(block: NodeMaterialBlock): string {
+        return block.name;
+    }
+
+    public getBackgroundColor(block: NodeMaterialBlock): string {
+        return "#323232";
+    }
+
+    public updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {       
+        const textureBlock = block as TextureBlock | ReflectionTextureBlock;
+
+        if (!this._previewCanvas) {
+            contentArea.classList.add("texture-block");
+
+            this._previewCanvas = contentArea.ownerDocument!.createElement("canvas");
+            contentArea.appendChild(this._previewCanvas);
+        }
+
+        if (textureBlock.texture) {
+            TextureLineComponent.UpdatePreview(this._previewCanvas, textureBlock.texture, 140, {
+                face: 0,
+                displayRed: true,
+                displayAlpha: true,
+                displayBlue: true,
+                displayGreen: true
+            });
+        }
+    }
+}

+ 28 - 0
nodeEditor/src/diagram/display/trigonometryDisplayManager.ts

@@ -0,0 +1,28 @@
+import { IDisplayManager } from './displayManager';
+import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+import { TrigonometryBlock, TrigonometryBlockOperations } from 'babylonjs/Materials/Node/Blocks/trigonometryBlock';
+
+export class TrigonometryDisplayManager implements IDisplayManager {
+    public getHeaderClass(block: NodeMaterialBlock) {
+        return "";
+    }
+
+    public shouldDisplayPortLabels(block: NodeMaterialBlock): boolean {
+        return false;
+    }
+
+    public getHeaderText(block: NodeMaterialBlock): string {
+        return block.name;
+    }
+
+    public getBackgroundColor(block: NodeMaterialBlock): string {
+        return "#405C86";
+    }
+
+    public updatePreviewContent(block: NodeMaterialBlock, contentArea: HTMLDivElement): void {       
+        const trigonometryBlock = block as TrigonometryBlock;
+
+        contentArea.classList.add("trigonometry-block");
+        contentArea.innerHTML = TrigonometryBlockOperations[trigonometryBlock.operation];
+    }
+}

+ 13 - 2
nodeEditor/src/diagram/displayLedger.ts

@@ -1,5 +1,10 @@
-import { InputDisplayManager } from './previews/inputDisplayManager';
-import { OutputDisplayManager } from './previews/outputDisplayManager';
+import { InputDisplayManager } from './display/inputDisplayManager';
+import { OutputDisplayManager } from './display/outputDisplayManager';
+import { ClampDisplayManager } from './display/clampDisplayManager';
+import { GradientDisplayManager } from './display/gradientDisplayManager';
+import { RemapDisplayManager } from './display/remapDisplayManager';
+import { TrigonometryDisplayManager } from './display/trigonometryDisplayManager';
+import { TextureDisplayManager } from './display/textureDisplayManager';
 
 export class DisplayLedger {
     public static RegisteredControls: {[key: string] : any} = {};
@@ -8,3 +13,9 @@ export class DisplayLedger {
 DisplayLedger.RegisteredControls["InputBlock"] = InputDisplayManager;
 DisplayLedger.RegisteredControls["VertexOutputBlock"] = OutputDisplayManager;
 DisplayLedger.RegisteredControls["FragmentOutputBlock"] = OutputDisplayManager;
+DisplayLedger.RegisteredControls["ClampBlock"] = ClampDisplayManager;
+DisplayLedger.RegisteredControls["GradientBlock"] = GradientDisplayManager;
+DisplayLedger.RegisteredControls["RemapBlock"] = RemapDisplayManager;
+DisplayLedger.RegisteredControls["TrigonometryBlock"] = TrigonometryDisplayManager;
+DisplayLedger.RegisteredControls["TextureBlock"] = TextureDisplayManager;
+DisplayLedger.RegisteredControls["ReflectionTextureBlock"] = TextureDisplayManager;

+ 49 - 0
nodeEditor/src/diagram/graphCanvas.scss

@@ -14,6 +14,7 @@
         height: 100%;
         left: 0;
         top: 0;
+        transform-origin: left top;
 
         .visual {
             width: 200px;
@@ -149,6 +150,54 @@
                     min-height: 0px;
                     height: 5px;
                 }
+
+                &.clamp-block {                    
+                    grid-row: 2;
+                    height: 34px;
+                    text-align: center;
+                    font-size: 18px;
+                    font-weight: bold;
+                    margin: 0 10px;
+                }
+
+                &.gradient-block {                    
+                    grid-row: 2;
+                    height: 34px;
+                }
+
+                &.texture-block {                    
+                    grid-row: 3;
+                    height: 140px;
+                    width: 140px;
+                    margin-top: -115px;
+                    overflow: hidden;
+                    border-bottom-left-radius: 7px;
+                    border: black 4px solid;
+                    border-left: 0px;
+                    border-bottom: 0px;
+
+                    canvas {
+                        width: 100%;
+                        height: 100%;
+                    }
+                }
+
+                &.remap-block {                    
+                    height: 34px;
+                    text-align: center;
+                    font-size: 18px;
+                    font-weight: bold;
+                    margin: 0 10px;
+                }      
+                
+                &.trigonometry-block {                    
+                    grid-row: 2;
+                    height: 34px;
+                    text-align: center;
+                    font-size: 18px;
+                    font-weight: bold;
+                    margin: 0 10px;
+                }
             }
         }
     }

+ 4 - 0
nodeEditor/src/diagram/graphCanvas.tsx

@@ -20,6 +20,10 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
     private _y = 0;
     private _zoom = 1;
 
+    public get nodes() {
+        return this._nodes;
+    }
+
     public get zoom() {
         return this._zoom;
     }

+ 51 - 21
nodeEditor/src/diagram/graphNode.ts

@@ -10,7 +10,7 @@ import { PropertyLedger } from './propertyLedger';
 import * as React from 'react';
 import { GenericPropertyTabComponent } from './properties/genericNodePropertyComponent';
 import { DisplayLedger } from './displayLedger';
-import { IDisplayManager } from './previews/displayManager';
+import { IDisplayManager } from './display/displayManager';
 
 export class GraphNode {
     private _visual: HTMLDivElement;
@@ -27,7 +27,10 @@ export class GraphNode {
     private _mouseStartPointY: Nullable<number> = null    
     private _globalState: GlobalState;
     private _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphNode>>>;   
+    private _onUpdateRequiredObserver: Nullable<Observer<void>>;  
     private _ownerCanvas: GraphCanvasComponent; 
+    private _isSelected: boolean;
+    private _displayManager: Nullable<IDisplayManager> = null;
 
     public get x() {
         return this._x;
@@ -63,6 +66,24 @@ export class GraphNode {
         return this.block.name;
     }
 
+    public get isSelected() {
+        return this._isSelected;
+    }
+
+    public set isSelected(value: boolean) {
+        if (this._isSelected === value) {
+            return;            
+        }
+
+        this._isSelected = value;
+
+        if (!value) {
+            this._visual.classList.remove("selected");
+        } else {
+            this._globalState.onSelectionChangedObservable.notifyObservers(this);  
+        }
+    }
+
     public constructor(public block: NodeMaterialBlock, globalState: GlobalState) {
         this._globalState = globalState;
 
@@ -72,7 +93,21 @@ export class GraphNode {
             } else {
                 this._visual.classList.remove("selected");
             }
-        })
+        });
+
+        this._onUpdateRequiredObserver = this._globalState.onUpdateRequiredObservable.add(() => {
+            this._refresh();
+        });
+    }
+
+    private _refresh() {
+        if (this._displayManager) {
+            this._header.innerHTML = this._displayManager.getHeaderText(this.block);
+            this._displayManager.updatePreviewContent(this.block, this._content);
+            this._visual.style.background = this._displayManager.getBackgroundColor(this.block);
+        } else {
+            this._header.innerHTML = this.block.name;
+        }
     }
 
     private _appendConnection(connectionPoint: NodeMaterialConnectionPoint, root: HTMLDivElement, displayManager: Nullable<IDisplayManager>) {
@@ -167,10 +202,10 @@ export class GraphNode {
 
         // Display manager
         let displayManagerClass = DisplayLedger.RegisteredControls[this.block.getClassName()];
-        let displayManager: Nullable<IDisplayManager> = null;
+        
 
         if (displayManagerClass) {
-            displayManager = new displayManagerClass();
+            this._displayManager = new displayManagerClass();
         }
 
         // DOM
@@ -181,21 +216,13 @@ export class GraphNode {
         this._visual.addEventListener("pointerup", evt => this._onUp(evt));
         this._visual.addEventListener("pointermove", evt => this._onMove(evt));
 
-        if (displayManager) {
-            this._visual.style.background = displayManager.getBackgroundColor(this.block);
-        }
-
         this._header = root.ownerDocument!.createElement("div");
         this._header.classList.add("header");
-        if (displayManager) {
-            this._header.innerHTML = displayManager.getHeaderText(this.block);
-        } else {
-            this._header.innerHTML = this.block.name;
-        }
+
         this._visual.appendChild(this._header);      
 
-        if (displayManager) {
-            let additionalClass = displayManager.getHeaderClass(this.block);
+        if (this._displayManager) {
+            let additionalClass = this._displayManager.getHeaderClass(this.block);
             if (additionalClass) {
                 this._header.classList.add(additionalClass);
             }
@@ -216,26 +243,29 @@ export class GraphNode {
         this._content = root.ownerDocument!.createElement("div");
         this._content.classList.add("content");
         this._visual.appendChild(this._content);     
-        
-        if (displayManager) {
-            displayManager.setPreviewContent(this.block, this._content);
-        }
+
 
         root.appendChild(this._visual);
 
         // Connections
         for (var input of this.block.inputs) {
-            this._inputPorts.push(this._appendConnection(input, this._inputsContainer, displayManager));
+            this._inputPorts.push(this._appendConnection(input, this._inputsContainer, this._displayManager));
         }
 
         for (var output of this.block.outputs) {
-            this._outputPorts.push(this._appendConnection(output, this._outputsContainer, displayManager));
+            this._outputPorts.push(this._appendConnection(output, this._outputsContainer, this._displayManager));
         }
+
+        this._refresh();
     }
 
     public dispose() {
         if (this._onSelectionChangedObserver) {
             this._globalState.onSelectionChangedObservable.remove(this._onSelectionChangedObserver);
         }
+
+        if (this._onUpdateRequiredObserver) {
+            this._globalState.onUpdateRequiredObservable.remove(this._onUpdateRequiredObserver);
+        }
     }
 }

+ 1 - 1
nodeEditor/src/diagram/properties/gradientNodePropertyComponent.tsx

@@ -4,7 +4,7 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
 import { TextLineComponent } from '../../sharedComponents/textLineComponent';
 import { GradientBlockColorStep, GradientBlock } from 'babylonjs/Materials/Node/Blocks/gradientBlock';
-import { GradientStepComponent } from '../../components/diagram/gradient/gradientStepComponent';
+import { GradientStepComponent } from './gradientStepComponent';
 import { ButtonLineComponent } from '../../sharedComponents/buttonLineComponent';
 import { Color3 } from 'babylonjs/Maths/math.color';
 import { IPropertyComponentProps } from './propertyComponentProps';

+ 1 - 1
nodeEditor/src/components/diagram/gradient/gradientStepComponent.tsx

@@ -1,5 +1,5 @@
 import * as React from 'react';
-import { GlobalState } from '../../../globalState';
+import { GlobalState } from '../../globalState';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { faTrash } from '@fortawesome/free-solid-svg-icons';
 import { Color3 } from 'babylonjs/Maths/math.color';

+ 8 - 1
nodeEditor/src/diagram/properties/inputNodePropertyComponent.tsx

@@ -234,7 +234,8 @@ export class InputPropertyTabComponent extends React.Component<IPropertyComponen
                                     inputBlock.setAsSystemValue(systemValuesOptions[0].value);
                                     break;
                             }
-                            this.forceUpdate();
+                            this.forceUpdate();                            
+                            this.props.globalState.onUpdateRequiredObservable.notifyObservers();
                             this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         }} />
                     {
@@ -242,6 +243,8 @@ export class InputPropertyTabComponent extends React.Component<IPropertyComponen
                         <OptionsLineComponent label="Attribute" valuesAreStrings={true} options={attributeOptions} target={inputBlock} propertyName="name" onSelect={(value: any) => {
                             inputBlock.setAsAttribute(value);
                             this.forceUpdate();
+                            
+                            this.props.globalState.onUpdateRequiredObservable.notifyObservers();
                             this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         }} />
                     }
@@ -249,6 +252,8 @@ export class InputPropertyTabComponent extends React.Component<IPropertyComponen
                         inputBlock.isUniform && animationOptions.length > 0 &&
                         <OptionsLineComponent label="Animation type" options={animationOptions} target={inputBlock} propertyName="animationType" onSelect={(value: any) => {
                             this.forceUpdate();
+                            
+                            this.props.globalState.onUpdateRequiredObservable.notifyObservers();
                             this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         }} />
                     }   
@@ -261,6 +266,8 @@ export class InputPropertyTabComponent extends React.Component<IPropertyComponen
                         <OptionsLineComponent label="System value" options={systemValuesOptions} target={inputBlock} propertyName="systemValue" onSelect={(value: any) => {
                             inputBlock.setAsSystemValue(value);
                             this.forceUpdate();
+                            
+                            this.props.globalState.onUpdateRequiredObservable.notifyObservers();
                             this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         }} />
                     }

+ 1 - 2
nodeEditor/src/globalState.ts

@@ -2,7 +2,6 @@ import { NodeMaterial } from "babylonjs/Materials/Node/nodeMaterial"
 import { Nullable } from "babylonjs/types"
 import { Observable } from 'babylonjs/Misc/observable';
 import { LogEntry } from './components/log/logComponent';
-import { NodeModel } from 'storm-react-diagrams';
 import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
 import { PreviewMeshType } from './components/preview/previewMeshType';
 import { DataStorage } from './dataStorage';
@@ -28,7 +27,7 @@ export class GlobalState {
     onBackFaceCullingChanged = new Observable<void>();
     onDepthPrePassChanged = new Observable<void>();
     onAnimationCommandActivated = new Observable<void>();
-    onGetNodeFromBlock: (block: NodeMaterialBlock) => NodeModel;
+    onGetNodeFromBlock: (block: NodeMaterialBlock) => GraphNode;
     previewMeshType: PreviewMeshType;
     previewMeshFile: File;
     rotatePreview: boolean;

+ 87 - 129
nodeEditor/src/graphEditor.tsx

@@ -1,6 +1,5 @@
 import {
     DiagramEngine,
-    DiagramModel,
     DiagramWidget,
     LinkModel
 } from "storm-react-diagrams";
@@ -8,43 +7,27 @@ import {
 import * as React from "react";
 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 } 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 { DefaultPortModel } from './components/diagram/port/defaultPortModel';
-import { InputNodeFactory } from './components/diagram/input/inputNodeFactory';
 import { LogComponent, LogEntry } from './components/log/logComponent';
-import { LightNodeFactory } from './components/diagram/light/lightNodeFactory';
 import { DataStorage } from './dataStorage';
 import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes';
 import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
 import { Nullable } from 'babylonjs/types';
 import { MessageDialogComponent } from './sharedComponents/messageDialog';
 import { BlockTools } from './blockTools';
-import { AdvancedLinkFactory } from './components/diagram/link/advancedLinkFactory';
-import { RemapNodeFactory } from './components/diagram/remap/remapNodeFactory';
 import { PreviewManager } from './components/preview/previewManager';
 import { INodeLocationInfo } from './nodeLocationInfo';
 import { PreviewMeshControlComponent } from './components/preview/previewMeshControlComponent';
-import { TrigonometryNodeFactory } from './components/diagram/trigonometry/trigonometryNodeFactory';
-import { ClampNodeFactory } from './components/diagram/clamp/clampNodeFactory';
-import { LightInformationNodeFactory } from './components/diagram/lightInformation/lightInformationNodeFactory';
 import { PreviewAreaComponent } from './components/preview/previewAreaComponent';
-import { GradientNodeFactory } from './components/diagram/gradient/gradientNodeFactory';
-import { ReflectionTextureNodeFactory } from './components/diagram/reflectionTexture/reflectionTextureNodeFactory';
 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");
-require("./components/diagram/diagram.scss");
 
 interface IGraphEditorProps {
     globalState: GlobalState;
@@ -60,7 +43,6 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
     private readonly NodeWidth = 100;
     private _graphCanvas: GraphCanvasComponent;
     private _engine: DiagramEngine;
-    private _model: DiagramModel;
 
     private _startX: number;
     private _moveInProgress: boolean;
@@ -68,13 +50,12 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
     private _leftWidth = DataStorage.ReadNumber("LeftWidth", 200);
     private _rightWidth = DataStorage.ReadNumber("RightWidth", 300);
 
-    private _nodes = new Array<GraphNode>();
     private _blocks = new Array<NodeMaterialBlock>();
 
     private _previewManager: PreviewManager;
-    private _copiedNodes: DefaultNodeModel[] = [];
-    private _mouseLocationX = 0;
-    private _mouseLocationY = 0;
+    // private _copiedNodes: GraphNode[] = [];
+    // private _mouseLocationX = 0;
+    // private _mouseLocationY = 0;
     private _onWidgetKeyUpPointer: any;
 
     private _altKeyIsPressed = false;
@@ -89,7 +70,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
      */
     public createNodeFromObject(options: NodeCreationOptions) {
         if (this._blocks.indexOf(options.nodeMaterialBlock) !== -1) {        
-            return this._nodes.filter(n => n.block === options.nodeMaterialBlock)[0];
+            return this._graphCanvas.nodes.filter(n => n.block === options.nodeMaterialBlock)[0];
         }
 
         this._blocks.push(options.nodeMaterialBlock);
@@ -168,7 +149,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
             ((this.props.globalState.hostDocument || document).querySelector(".blocker") as HTMLElement).style.visibility = "visible";
         }
 
-        this.build(true);
+        this.build();
     }
 
     componentWillUnmount() {
@@ -187,17 +168,6 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         // setup the diagram engine
         this._engine = new DiagramEngine();
         this._engine.installDefaultFactories()
-        this._engine.registerNodeFactory(new GenericNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new TextureNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new LightNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new InputNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new RemapNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new TrigonometryNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new ClampNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new LightInformationNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new GradientNodeFactory(this.props.globalState));
-        this._engine.registerNodeFactory(new ReflectionTextureNodeFactory(this.props.globalState));
-        this._engine.registerLinkFactory(new AdvancedLinkFactory());
 
         this.props.globalState.onRebuildRequiredObservable.add(() => {
             if (this.props.globalState.nodeMaterial) {
@@ -206,7 +176,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         });
 
         this.props.globalState.onResetRequiredObservable.add(() => {
-            this.build(false);
+            this.build();
             if (this.props.globalState.nodeMaterial) {
                 this.buildMaterial();
             }
@@ -224,9 +194,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._graphCanvas.nodes.filter(n => n.block === block)[0];
+        }
 
         this.props.globalState.hostDocument!.addEventListener("keydown", evt => {
             this._altKeyIsPressed = evt.altKey;
@@ -235,62 +205,62 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
                 return;
             }
 
-            if (evt.key === "c") {
-                let selectedItems = this._engine.diagramModel.getSelectedItems();
-                if (!selectedItems.length) {
-                    return;
-                }
+            // if (evt.key === "c") {
+            //     let selectedItems = this._engine.diagramModel.getSelectedItems();
+            //     if (!selectedItems.length) {
+            //         return;
+            //     }
     
-                let selectedItem = selectedItems[0] as DefaultNodeModel;
+            //     let selectedItem = selectedItems[0] as DefaultNodeModel;
     
-                if (!selectedItem.block) {
-                    return;
-                }
+            //     if (!selectedItem.block) {
+            //         return;
+            //     }
 
-                this._copiedNodes = selectedItems.map(i => (i as DefaultNodeModel)!);
-            } else if (evt.key === "v") {
-                if (!this._copiedNodes.length) {
-                    return;
-                }
+            //     this._copiedNodes = selectedItems.map(i => (i as DefaultNodeModel)!);
+            // } else if (evt.key === "v") {
+            //     if (!this._copiedNodes.length) {
+            //         return;
+            //     }
 
-                const rootElement = this.props.globalState.hostDocument!.querySelector(".diagram-container") as HTMLDivElement;
-                const zoomLevel = this._engine.diagramModel.getZoomLevel() / 100.0;
-                let currentX = (this._mouseLocationX - rootElement.offsetLeft - this._engine.diagramModel.getOffsetX() - this.NodeWidth) / zoomLevel;
-                let currentY = (this._mouseLocationY - rootElement.offsetTop - this._engine.diagramModel.getOffsetY() - 20) / zoomLevel;
-                let originalNode: Nullable<DefaultNodeModel> = null;
+            //     const rootElement = this.props.globalState.hostDocument!.querySelector(".diagram-container") as HTMLDivElement;
+            //     const zoomLevel = this._engine.diagramModel.getZoomLevel() / 100.0;
+            //     let currentX = (this._mouseLocationX - rootElement.offsetLeft - this._engine.diagramModel.getOffsetX() - this.NodeWidth) / zoomLevel;
+            //     let currentY = (this._mouseLocationY - rootElement.offsetTop - this._engine.diagramModel.getOffsetY() - 20) / zoomLevel;
+            //     let originalNode: Nullable<DefaultNodeModel> = null;
 
-                for (var node of this._copiedNodes) {
-                    let block = node.block;
+            //     for (var node of this._copiedNodes) {
+            //         let block = node.block;
 
-                    if (!block) {
-                        continue;
-                    }
+            //         if (!block) {
+            //             continue;
+            //         }
 
-                    let clone = block.clone(this.props.globalState.nodeMaterial.getScene());
+            //         let clone = block.clone(this.props.globalState.nodeMaterial.getScene());
 
-                    if (!clone) {
-                        return;
-                    }
+            //         if (!clone) {
+            //             return;
+            //         }
                     
-                    let newNode = this.createNodeFromObject({ nodeMaterialBlock: clone });
-
-                    let x = 0;
-                    let y = 0;
-                    if (originalNode) {
-                        x = currentX + node.x - originalNode.x;
-                        y = currentY + node.y - originalNode.y;
-                    } else {
-                        originalNode = node;
-                        x = currentX;
-                        y = currentY;
-                    }
+            //         let newNode = this.createNodeFromObject({ nodeMaterialBlock: clone });
+
+            //         let x = 0;
+            //         let y = 0;
+            //         if (originalNode) {
+            //             x = currentX + node.x - originalNode.x;
+            //             y = currentY + node.y - originalNode.y;
+            //         } else {
+            //             originalNode = node;
+            //             x = currentX;
+            //             y = currentY;
+            //         }
 
-                    newNode.x = x;
-                    newNode.y = y;
-                }
+            //         newNode.x = x;
+            //         newNode.y = y;
+            //     }
 
-                this._engine.repaintCanvas();
-            }
+            //     this._engine.repaintCanvas();
+            // }
 
         }, false);
     }
@@ -315,28 +285,26 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         SerializationTools.UpdateLocations(this.props.globalState.nodeMaterial, this.props.globalState);
     }
 
-    applyFragmentOutputConstraints(rootInput: DefaultPortModel) {
-        var model = rootInput.parent as GenericNodeModel;
-        for (var inputKey in model.getPorts()) {                                       
-            let input = model.getPorts()[inputKey];
-
-            if (rootInput.name === "rgba" && (inputKey === "a" || inputKey === "rgb")
-                ||
-                (rootInput.name === "a" || rootInput.name === "rgb") && inputKey === "rgba") {
-                    for (var key in input.links) {
-                        let other = input.links[key];
-                        other.remove();
-                    }
-                continue;
-            }
-        }
-    }
-
-    build(needToWait = false) {        
+    // applyFragmentOutputConstraints(rootInput: DefaultPortModel) {
+    //     var model = rootInput.parent as GenericNodeModel;
+    //     for (var inputKey in model.getPorts()) {                                       
+    //         let input = model.getPorts()[inputKey];
+
+    //         if (rootInput.name === "rgba" && (inputKey === "a" || inputKey === "rgb")
+    //             ||
+    //             (rootInput.name === "a" || rootInput.name === "rgb") && inputKey === "rgba") {
+    //                 for (var key in input.links) {
+    //                     let other = input.links[key];
+    //                     other.remove();
+    //                 }
+    //             continue;
+    //         }
+    //     }
+    // }
+
+    build() {        
         let locations: Nullable<INodeLocationInfo[]> = this.props.globalState.nodeMaterial.editorData;
         // setup the diagram model
-        this._model = new DiagramModel();
-        this._nodes = [];
         this._blocks = [];
         this._graphCanvas.reset();
 
@@ -501,36 +469,26 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
             });
         }
 
-        // load model into engine
-        setTimeout(() => {
-            if (this._toAdd) {
-                this._model.addAll(...this._toAdd);
-            }
-            this._toAdd = null;
-            this._engine.setDiagramModel(this._model);
-
-            this.forceUpdate();
-
-            this.reOrganize(locations);
-        }, needToWait ? 500 : 1);
+        this.reOrganize(locations);
     }
 
     reOrganize(locations: Nullable<INodeLocationInfo[]> = null) {
         if (!locations) {
             this._graphCanvas.distributeGraph();
         } else {
-            // 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._graphCanvas.x = 0;
+            this._graphCanvas.y = 0;
+            this._graphCanvas.zoom = 1;
+            for (var location of locations) {
+                for (var node of this._graphCanvas.nodes) {
+                    if (node.block && node.block.uniqueId === location.blockId) {
+                        node.x = location.x;
+                        node.y = location.y;
+                        break;
+                    }
+                }
+            }
         }
-
-        this._engine.repaintCanvas();
     }
 
     onPointerDown(evt: React.PointerEvent<HTMLDivElement>) {
@@ -650,8 +608,8 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
                         gridTemplateColumns: this.buildColumnLayout()
                     }}
                     onMouseMove={evt => {
-                        this._mouseLocationX = evt.pageX;
-                        this._mouseLocationY = evt.pageY;
+                        // this._mouseLocationX = evt.pageX;
+                        // this._mouseLocationY = evt.pageY;
                     }}
                     onMouseDown={(evt) => {
                         if ((evt.target as HTMLElement).nodeName === "INPUT") {

+ 26 - 19
nodeEditor/src/sharedComponents/textureLineComponent.tsx

@@ -15,7 +15,15 @@ interface ITextureLineComponentProps {
     hideChannelSelect?: boolean;
 }
 
-export class TextureLineComponent extends React.Component<ITextureLineComponentProps, { displayRed: boolean, displayGreen: boolean, displayBlue: boolean, displayAlpha: boolean, face: number }> {
+export interface ITextureLineComponentState {
+    displayRed: boolean, 
+    displayGreen: boolean, 
+    displayBlue: boolean, 
+    displayAlpha: boolean, 
+    face: number
+}
+
+export class TextureLineComponent extends React.Component<ITextureLineComponentProps, ITextureLineComponentState> {
     constructor(props: ITextureLineComponentProps) {
         super(props);
 
@@ -40,18 +48,20 @@ export class TextureLineComponent extends React.Component<ITextureLineComponentP
         this.updatePreview();
     }
 
-    updatePreview() {
-        var texture = this.props.texture;
+    public updatePreview() {
+        TextureLineComponent.UpdatePreview(this.refs.canvas as HTMLCanvasElement, this.props.texture, this.props.width, this.state, this.props.globalState);
+    }
+
+    public static UpdatePreview(previewCanvas: HTMLCanvasElement, texture: BaseTexture, width: number, options: ITextureLineComponentState, globalState?: any) {
         if (!texture.isReady() && texture._texture) {
             texture._texture.onLoadedObservable.addOnce(() => {
-                this.updatePreview();
+                TextureLineComponent.UpdatePreview(previewCanvas, texture, width, options, globalState);
             })
         }
         var scene = texture.getScene()!;
         var engine = scene.getEngine();
         var size = texture.getSize();
         var ratio = size.width / size.height;
-        var width = this.props.width;
         var height = (width / ratio) | 1;
 
         let passPostProcess: PostProcess;
@@ -60,7 +70,7 @@ export class TextureLineComponent extends React.Component<ITextureLineComponentP
             passPostProcess = new PassPostProcess("pass", 1, null, Texture.NEAREST_SAMPLINGMODE, engine, false, Constants.TEXTURETYPE_UNSIGNED_INT);
         } else {
             var passCubePostProcess = new PassCubePostProcess("pass", 1, null, Texture.NEAREST_SAMPLINGMODE, engine, false, Constants.TEXTURETYPE_UNSIGNED_INT);
-            passCubePostProcess.face = this.state.face;
+            passCubePostProcess.face = options.face;
 
             passPostProcess = passCubePostProcess;
         }
@@ -69,15 +79,13 @@ export class TextureLineComponent extends React.Component<ITextureLineComponentP
             // Try again later
             passPostProcess.dispose();
 
-            setTimeout(() => this.updatePreview(), 250);
+            setTimeout(() => TextureLineComponent.UpdatePreview(previewCanvas, texture, width, options, globalState), 250);
 
             return;
         }
 
-        const previewCanvas = this.refs.canvas as HTMLCanvasElement;
-
-        if (this.props.globalState) {
-            this.props.globalState.blockMutationUpdates = true;
+        if (globalState) {
+            globalState.blockMutationUpdates = true;
         }
 
         let rtt = new RenderTargetTexture(
@@ -102,22 +110,22 @@ export class TextureLineComponent extends React.Component<ITextureLineComponentP
             var data = engine.readPixels(0, 0, width, height);
 
             if (!texture.isCube) {
-                if (!this.state.displayRed || !this.state.displayGreen || !this.state.displayBlue) {
+                if (!options.displayRed || !options.displayGreen || !options.displayBlue) {
                     for (var i = 0; i < width * height * 4; i += 4) {
 
-                        if (!this.state.displayRed) {
+                        if (!options.displayRed) {
                             data[i] = 0;
                         }
 
-                        if (!this.state.displayGreen) {
+                        if (!options.displayGreen) {
                             data[i + 1] = 0;
                         }
 
-                        if (!this.state.displayBlue) {
+                        if (!options.displayBlue) {
                             data[i + 2] = 0;
                         }
 
-                        if (this.state.displayAlpha) {
+                        if (options.displayAlpha) {
                             var alpha = data[i + 2];
                             data[i] = alpha;
                             data[i + 1] = alpha;
@@ -163,10 +171,9 @@ export class TextureLineComponent extends React.Component<ITextureLineComponentP
         passPostProcess.dispose();
 
         previewCanvas.style.height = height + "px";
-        if (this.props.globalState) {
-            this.props.globalState.blockMutationUpdates = false;
+        if (globalState) {
+            globalState.blockMutationUpdates = false;
         }
-
     }
 
     render() {