David Catuhe il y a 6 ans
Parent
commit
a90de92d0a
27 fichiers modifiés avec 260 ajouts et 47 suppressions
  1. 2 1
      .vscode/settings.json
  2. 4 1
      src/Materials/Node/Blocks/Dual/fogBlock.ts
  3. 4 1
      src/Materials/Node/Blocks/Dual/lightBlock.ts
  4. 4 1
      src/Materials/Node/Blocks/Dual/textureBlock.ts
  5. 4 1
      src/Materials/Node/Blocks/Fragment/alphaTestBlock.ts
  6. 4 1
      src/Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts
  7. 4 1
      src/Materials/Node/Blocks/Fragment/imageProcessingBlock.ts
  8. 4 1
      src/Materials/Node/Blocks/Fragment/rgbMergerBlock.ts
  9. 4 1
      src/Materials/Node/Blocks/Fragment/rgbSplitterBlock.ts
  10. 4 1
      src/Materials/Node/Blocks/Fragment/rgbaMergerBlock.ts
  11. 4 1
      src/Materials/Node/Blocks/Fragment/rgbaSplitterBlock.ts
  12. 4 1
      src/Materials/Node/Blocks/Input/inputBlock.ts
  13. 4 1
      src/Materials/Node/Blocks/Vertex/bonesBlock.ts
  14. 4 1
      src/Materials/Node/Blocks/Vertex/instancesBlock.ts
  15. 4 1
      src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts
  16. 4 1
      src/Materials/Node/Blocks/Vertex/vertexOutputBlock.ts
  17. 4 1
      src/Materials/Node/Blocks/addBlock.ts
  18. 4 1
      src/Materials/Node/Blocks/clampBlock.ts
  19. 4 1
      src/Materials/Node/Blocks/crossBlock.ts
  20. 4 1
      src/Materials/Node/Blocks/dotBlock.ts
  21. 4 1
      src/Materials/Node/Blocks/multiplyBlock.ts
  22. 4 1
      src/Materials/Node/Blocks/vectorTransformBlock.ts
  23. 94 1
      src/Materials/Node/nodeMaterial.ts
  24. 25 0
      src/Materials/Node/nodeMaterialBlock.ts
  25. 36 18
      src/Materials/Node/nodeMaterialBlockConnectionPoint.ts
  26. 17 0
      src/Misc/uniqueIdGenerator.ts
  27. 2 6
      src/scene.ts

+ 2 - 1
.vscode/settings.json

@@ -56,5 +56,6 @@
         "assets": true
     },
     "editor.tabSize": 4,
-    "typescript.tsdk": "node_modules\\typescript\\lib"
+    "typescript.tsdk": "node_modules\\typescript\\lib",
+    "typescript.preferences.importModuleSpecifier": "relative"
 }

+ 4 - 1
src/Materials/Node/Blocks/Dual/fogBlock.ts

@@ -10,6 +10,7 @@ import { AbstractMesh } from '../../../../Meshes/abstractMesh';
 import { MaterialHelper } from '../../../materialHelper';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 import { InputBlock } from '../Input/inputBlock';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to add support for scene fog
@@ -144,4 +145,6 @@ export class FogBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.FogBlock"] = FogBlock;

+ 4 - 1
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -12,6 +12,7 @@ import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
 import { InputBlock } from '../Input/inputBlock';
 import { Light } from '../../../../Lights/light';
 import { Nullable } from '../../../../types';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to add light in the fragment shader
@@ -230,4 +231,6 @@ export class LightBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.LightBlock"] = LightBlock;

+ 4 - 1
src/Materials/Node/Blocks/Dual/textureBlock.ts

@@ -10,6 +10,7 @@ import { InputBlock } from '../Input/inputBlock';
 import { Effect } from '../../../effect';
 import { Mesh } from '../../../../Meshes/mesh';
 import { Nullable } from '../../../../types';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to read a texture from a sampler
@@ -191,4 +192,6 @@ export class TextureBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.TextureBlock"] = TextureBlock;

+ 4 - 1
src/Materials/Node/Blocks/Fragment/alphaTestBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockCo
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to add an alpha test in the fragment shader
@@ -48,4 +49,6 @@ export class AlphaTestBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.AlphaTestBlock"] = AlphaTestBlock;

+ 4 - 1
src/Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockCo
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to output the final color
@@ -53,4 +54,6 @@ export class FragmentOutputBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.FragmentOutputBlock"] = FragmentOutputBlock;

+ 4 - 1
src/Materials/Node/Blocks/Fragment/imageProcessingBlock.ts

@@ -7,6 +7,7 @@ import { AbstractMesh } from '../../../../Meshes/abstractMesh';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 import { Effect } from '../../../effect';
 import { Mesh } from '../../../../Meshes/mesh';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to add image processing support to fragment shader
@@ -138,4 +139,6 @@ export class ImageProcessingBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.ImageProcessingBlock"] = ImageProcessingBlock;

+ 4 - 1
src/Materials/Node/Blocks/Fragment/rgbMergerBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockCo
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to create a Color3 out of 3 inputs (one for each component)
@@ -71,4 +72,6 @@ export class RGBMergerBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.RGBMergerBlock"] = RGBMergerBlock;

+ 4 - 1
src/Materials/Node/Blocks/Fragment/rgbSplitterBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockCo
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to expand a Color3 or a Vector3 into 3 outputs (one for each component)
@@ -56,4 +57,6 @@ export class RGBSplitterBlock extends NodeMaterialBlock {
         }
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.RGBSplitterBlock"] = RGBSplitterBlock;

+ 4 - 1
src/Materials/Node/Blocks/Fragment/rgbaMergerBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockCo
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to create a Color4 out of 4 inputs (one for each component)
@@ -92,4 +93,6 @@ export class RGBAMergerBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.RGBAMergerBlock"] = RGBAMergerBlock;

+ 4 - 1
src/Materials/Node/Blocks/Fragment/rgbaSplitterBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockCo
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to expand a Color4 or a Vector4 into 4 outputs (one for each component)
@@ -62,4 +63,6 @@ export class RGBASplitterBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.RGBASplitterBlock"] = RGBASplitterBlock;

+ 4 - 1
src/Materials/Node/Blocks/Input/inputBlock.ts

@@ -9,6 +9,7 @@ import { Scene } from '../../../../scene';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to expose an input value
@@ -423,4 +424,6 @@ export class InputBlock extends NodeMaterialBlock {
 
         this._emit(state);
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.InputBlock"] = InputBlock;

+ 4 - 1
src/Materials/Node/Blocks/Vertex/bonesBlock.ts

@@ -10,6 +10,7 @@ import { MaterialHelper } from '../../../materialHelper';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 import { InputBlock } from '../Input/inputBlock';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to add support for vertex skinning (bones)
@@ -190,4 +191,6 @@ export class BonesBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.BonesBlock"] = BonesBlock;

+ 4 - 1
src/Materials/Node/Blocks/Vertex/instancesBlock.ts

@@ -7,6 +7,7 @@ import { AbstractMesh } from '../../../../Meshes/abstractMesh';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
 import { InputBlock } from '../Input/inputBlock';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to add support for instances
@@ -141,4 +142,6 @@ export class InstancesBlock extends NodeMaterialBlock {
         state.compilationString += `#endif\r\n`;
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.InstancesBlock"] = InstancesBlock;

+ 4 - 1
src/Materials/Node/Blocks/Vertex/morphTargetsBlock.ts

@@ -10,6 +10,7 @@ import { Mesh } from '../../../../Meshes/mesh';
 import { MaterialHelper } from '../../../materialHelper';
 import { VertexBuffer } from '../../../../Meshes/buffer';
 import { InputBlock } from '../Input/inputBlock';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to add morph targets support to vertex shader
@@ -248,4 +249,6 @@ export class MorphTargetsBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.MorphTargetsBlock"] = MorphTargetsBlock;

+ 4 - 1
src/Materials/Node/Blocks/Vertex/vertexOutputBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockCo
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
 
 /**
  * Block used to output the vertex position
@@ -43,4 +44,6 @@ export class VertexOutputBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.VertexOutputBlock"] = VertexOutputBlock;

+ 4 - 1
src/Materials/Node/Blocks/addBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../nodeMaterialBlockConne
 import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockTargets } from '../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
 /**
  * Block used to add 2 vectors
  */
@@ -59,4 +60,6 @@ export class AddBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.AddBlock"] = AddBlock;

+ 4 - 1
src/Materials/Node/Blocks/clampBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../nodeMaterialBlockConne
 import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockTargets } from '../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
 /**
  * Block used to clamp a float
  */
@@ -55,4 +56,6 @@ export class ClampBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.ClampBlock"] = ClampBlock;

+ 4 - 1
src/Materials/Node/Blocks/crossBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../nodeMaterialBlockConne
 import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockTargets } from '../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
 /**
  * Block used to apply a cross product between 2 vectors
  */
@@ -59,4 +60,6 @@ export class CrossBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.CrossBlock"] = CrossBlock;

+ 4 - 1
src/Materials/Node/Blocks/dotBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../nodeMaterialBlockConne
 import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockTargets } from '../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
 /**
  * Block used to apply a dot product between 2 vectors
  */
@@ -57,4 +58,6 @@ export class DotBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.DotBlock"] = DotBlock;

+ 4 - 1
src/Materials/Node/Blocks/multiplyBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../nodeMaterialBlockConne
 import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
 import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
 import { NodeMaterialBlockTargets } from '../nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
 /**
  * Block used to multiply 2 values
  */
@@ -59,4 +60,6 @@ export class MultiplyBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.MultiplyBlock"] = MultiplyBlock;

+ 4 - 1
src/Materials/Node/Blocks/vectorTransformBlock.ts

@@ -3,6 +3,7 @@ import { NodeMaterialBlockConnectionPointTypes } from '../nodeMaterialBlockConne
 import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../Misc/typeStore';
 
 /**
  * Block used to transform a vector (2, 3 or 4) with a matrix. It will generate a Vector4
@@ -81,4 +82,6 @@ export class VectorTransformBlock extends NodeMaterialBlock {
 
         return this;
     }
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.VectorTransformBlock"] = VectorTransformBlock;

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

@@ -23,6 +23,8 @@ import { VectorTransformBlock } from './Blocks/vectorTransformBlock';
 import { VertexOutputBlock } from './Blocks/Vertex/vertexOutputBlock';
 import { FragmentOutputBlock } from './Blocks/Fragment/fragmentOutputBlock';
 import { InputBlock } from './Blocks/Input/inputBlock';
+import { _TypeStore } from '../../Misc/typeStore';
+import { SerializationHelper } from '../../Misc/decorators';
 
 // declare NODEEDITOR namespace for compilation issue
 declare var NODEEDITOR: any;
@@ -870,4 +872,95 @@ export class NodeMaterial extends PushMaterial {
         this.addOutputNode(vertexOutput);
         this.addOutputNode(pixelOutput);
     }
-}
+
+    _gatherBlocks(rootNode: NodeMaterialBlock, list: NodeMaterialBlock[]) {
+        if (list.indexOf(rootNode) !== -1) {
+            return;
+        }
+        list.push(rootNode);
+
+        for (var inputs of rootNode.inputs) {
+            let connectedPoint = inputs.connectedPoint;
+            if (connectedPoint) {
+                let block = connectedPoint.ownerBlock;
+                if (block !== rootNode) {
+                    this._gatherBlocks(block, list);
+                }
+            }
+        }
+    }
+
+    /**
+     * Serializes this material in a JSON representation
+     * @returns the serialized material object
+     */
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.NodeMaterial";
+
+        serializationObject.outputNodes = [];
+
+        let blocks: NodeMaterialBlock[] = [];
+
+        // Outputs
+        for (var outputNode of this._vertexOutputNodes) {
+            this._gatherBlocks(outputNode, blocks);
+            serializationObject.outputNodes.push(outputNode.uniqueId);
+        }
+
+        for (var outputNode of this._fragmentOutputNodes) {
+            this._gatherBlocks(outputNode, blocks);
+            serializationObject.outputNodes.push(outputNode.uniqueId);
+        }
+
+        // Blocks
+        serializationObject.blocks = [];
+
+        for (var block of blocks) {
+            serializationObject.blocks.push(block.serialize());
+        }
+
+        return serializationObject;
+    }
+
+    /**
+     * Creates a node material from parsed material data
+     * @param source defines the JSON representation of the material
+     * @param scene defines the hosting scene
+     * @param rootUrl defines the root URL to use to load textures and relative dependencies
+     * @returns a new node material
+     */
+    public static Parse(source: any, scene: Scene, rootUrl: string): NodeMaterial {
+        let nodeMaterial = SerializationHelper.Parse(() => new NodeMaterial(source.name, scene), source, scene, rootUrl);
+
+        let map: {[key: number]: NodeMaterialBlock} = {};
+
+        // Create blocks
+        for (var parsedBlock of source.blocks) {
+            let blockType = _TypeStore.GetClass(parsedBlock.customType);
+            if (blockType) {
+                let block: NodeMaterialBlock = new blockType;
+
+                map[parsedBlock.id] = block;
+            }
+        }
+
+        // Connections
+        // for (var parsedBlock of source.blocks) {
+        //     let block = map[parsedBlock.id];
+
+        //     for (var input of parsedBlock.inputs) {
+
+        //     }
+        // }
+
+        // Outputs
+        for (var outputNodeId of source.outputNodes) {
+            nodeMaterial.addOutputNode(map[outputNodeId]);
+        }
+
+        return nodeMaterial;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.NodeMaterial"] = NodeMaterial;

+ 25 - 0
src/Materials/Node/nodeMaterialBlock.ts

@@ -8,6 +8,7 @@ import { AbstractMesh } from '../../Meshes/abstractMesh';
 import { Mesh } from '../../Meshes/mesh';
 import { NodeMaterial, NodeMaterialDefines } from './nodeMaterial';
 import { InputBlock } from './Blocks/Input/inputBlock';
+import { UniqueIdGenerator } from '../../Misc/uniqueIdGenerator';
 
 /**
  * Defines a block that can be used inside a node based material
@@ -30,6 +31,11 @@ export class NodeMaterialBlock {
     public name: string;
 
     /**
+     * Gets or sets the unique id of the node
+     */
+    public uniqueId: number;
+
+    /**
      * Gets a boolean indicating that this block is an end block (e.g. it is generating a system value)
      */
     public get isFinalMerger(): boolean {
@@ -124,6 +130,7 @@ export class NodeMaterialBlock {
 
         this._isFinalMerger = isFinalMerger;
         this._isInput = isInput;
+        this.uniqueId = UniqueIdGenerator.UniqueId;
     }
 
     /**
@@ -465,4 +472,22 @@ export class NodeMaterialBlock {
         }
         return false;
     }
+
+    /**
+     * Serializes this block in a JSON representation
+     * @returns the serialized block object
+     */
+    public serialize(): any {
+        let serializationObject: any = {};
+        serializationObject.customType = "BABYLON." + this.getClassName();
+        serializationObject.id = this.uniqueId;
+
+        serializationObject.inputs = [];
+
+        for (var input of this.inputs) {
+            serializationObject.inputs.push(input.serialize());
+        }
+
+        return serializationObject;
+    }
 }

+ 36 - 18
src/Materials/Node/nodeMaterialBlockConnectionPoint.ts

@@ -168,23 +168,6 @@ export class NodeMaterialConnectionPoint {
         return "NodeMaterialConnectionPoint";
     }
 
-    private _getTypeLength(type: NodeMaterialBlockConnectionPointTypes) {
-        switch (type) {
-            case NodeMaterialBlockConnectionPointTypes.Float:
-                return 1;
-            case NodeMaterialBlockConnectionPointTypes.Vector2:
-                return 2;
-            case NodeMaterialBlockConnectionPointTypes.Vector3:
-            case NodeMaterialBlockConnectionPointTypes.Color3:
-                return 3;
-            case NodeMaterialBlockConnectionPointTypes.Vector4:
-            case NodeMaterialBlockConnectionPointTypes.Color4:
-                return 3;
-        }
-
-        return -1;
-    }
-
     /**
      * Gets an boolean indicating if the current point can be connected to another point
      * @param connectionPoint defines the other connection point
@@ -196,7 +179,7 @@ export class NodeMaterialConnectionPoint {
             // Check swizzle
             if (this.swizzle) {
                 let swizzleLength = this.swizzle.length;
-                let connectionLength = this._getTypeLength(connectionPoint.type);
+                let connectionLength = NodeMaterialConnectionPoint._GetTypeLength(connectionPoint.type);
 
                 if (swizzleLength === connectionLength) {
                     fail = false;
@@ -243,4 +226,39 @@ export class NodeMaterialConnectionPoint {
         this._enforceAssociatedVariableName = false;
         return this;
     }
+
+    /**
+     * Serializes this point in a JSON representation
+     * @returns the serialized point object
+     */
+    public serialize(): any {
+        let serializationObject: any = {};
+
+        serializationObject.name = this.name;
+        serializationObject.swizzle = this.swizzle;
+
+        if (this.connectedPoint) {
+            serializationObject.connectedPointPath = this.name + ">" + this.connectedPoint.ownerBlock.uniqueId + "." + this.connectedPoint.name;
+        }
+
+        return serializationObject;
+    }
+
+    // Statics
+    private static _GetTypeLength(type: NodeMaterialBlockConnectionPointTypes) {
+        switch (type) {
+            case NodeMaterialBlockConnectionPointTypes.Float:
+                return 1;
+            case NodeMaterialBlockConnectionPointTypes.Vector2:
+                return 2;
+            case NodeMaterialBlockConnectionPointTypes.Vector3:
+            case NodeMaterialBlockConnectionPointTypes.Color3:
+                return 3;
+            case NodeMaterialBlockConnectionPointTypes.Vector4:
+            case NodeMaterialBlockConnectionPointTypes.Color4:
+                return 3;
+        }
+
+        return -1;
+    }
 }

+ 17 - 0
src/Misc/uniqueIdGenerator.ts

@@ -0,0 +1,17 @@
+/**
+ * Helper class used to generate session unique ID
+ */
+export class UniqueIdGenerator {
+    // Statics
+    private static _UniqueIdCounter = 0;
+
+    /**
+     * Gets an unique (relatively to the current scene) Id
+     * @returns an unique number for the scene
+     */
+    public static get UniqueId() {
+        var result = this._UniqueIdCounter;
+        this._UniqueIdCounter++;
+        return result;
+    }
+}

+ 2 - 6
src/scene.ts

@@ -53,6 +53,7 @@ import { IFileRequest } from './Misc/fileRequest';
 import { Color4, Color3 } from './Maths/math.color';
 import { Plane } from './Maths/math.plane';
 import { Frustum } from './Maths/math.frustum';
+import { UniqueIdGenerator } from './Misc/uniqueIdGenerator';
 
 declare type Ray = import("./Culling/ray").Ray;
 declare type TrianglePickingPredicate = import("./Culling/ray").TrianglePickingPredicate;
@@ -101,9 +102,6 @@ export interface SceneOptions {
  * @see http://doc.babylonjs.com/features/scene
  */
 export class Scene extends AbstractScene implements IAnimatable {
-    // Statics
-    private static _uniqueIdCounter = 0;
-
     /** The fog is deactivated */
     public static readonly FOGMODE_NONE = 0;
     /** The fog density is following an exponential function */
@@ -1956,9 +1954,7 @@ export class Scene extends AbstractScene implements IAnimatable {
      * @returns an unique number for the scene
      */
     public getUniqueId() {
-        var result = Scene._uniqueIdCounter;
-        Scene._uniqueIdCounter++;
-        return result;
+        return UniqueIdGenerator.UniqueId;
     }
 
     /**