Browse Source

Associated with #6012 - NodeMaterial serialization

David Catuhe 6 years ago
parent
commit
74d663ce9f

+ 6 - 6
nodeEditor/src/graphEditor.tsx

@@ -80,6 +80,12 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
     private _engine: DiagramEngine;
     private _model: DiagramModel;
 
+    private _startX: number;
+    private _moveInProgress: boolean;
+
+    private _leftWidth = DataStorage.ReadNumber("LeftWidth", 200);
+    private _rightWidth = DataStorage.ReadNumber("RightWidth", 300);
+
     private _nodes = new Array<DefaultNodeModel>();
 
     /** @hidden */
@@ -386,12 +392,6 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
         return localNode;
     }
 
-    private _startX: number;
-    private _moveInProgress: boolean;
-
-    private _leftWidth = DataStorage.ReadNumber("LeftWidth", 200);
-    private _rightWidth = DataStorage.ReadNumber("RightWidth", 300);
-
     onPointerDown(evt: React.PointerEvent<HTMLDivElement>) {
         this._startX = evt.clientX;
         this._moveInProgress = true;

+ 19 - 0
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -13,6 +13,7 @@ import { InputBlock } from '../Input/inputBlock';
 import { Light } from '../../../../Lights/light';
 import { Nullable } from '../../../../types';
 import { _TypeStore } from '../../../../Misc/typeStore';
+import { Scene } from '../../../../scene';
 
 /**
  * Block used to add light in the fragment shader
@@ -231,6 +232,24 @@ export class LightBlock extends NodeMaterialBlock {
 
         return this;
     }
+
+    public serialize(): any {
+        let serializationObject = super.serialize();
+
+        if (this.light) {
+            serializationObject.lightId = this.light.id;
+        }
+
+        return serializationObject;
+    }
+
+    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        super._deserialize(serializationObject, scene, rootUrl);
+
+        if (serializationObject.lightId) {
+            this.light = scene.getLightByID(serializationObject.lightId);
+        }
+    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.LightBlock"] = LightBlock;

+ 20 - 0
src/Materials/Node/Blocks/Dual/textureBlock.ts

@@ -11,6 +11,8 @@ import { Effect } from '../../../effect';
 import { Mesh } from '../../../../Meshes/mesh';
 import { Nullable } from '../../../../types';
 import { _TypeStore } from '../../../../Misc/typeStore';
+import { Texture } from '../../../Textures/texture';
+import { Scene } from '../../../../scene';
 
 /**
  * Block used to read a texture from a sampler
@@ -192,6 +194,24 @@ export class TextureBlock extends NodeMaterialBlock {
 
         return this;
     }
+
+    public serialize(): any {
+        let serializationObject = super.serialize();
+
+        if (this.texture) {
+            serializationObject.texture = this.texture.serialize();
+        }
+
+        return serializationObject;
+    }
+
+    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        super._deserialize(serializationObject, scene, rootUrl);
+
+        if (serializationObject.texture) {
+            this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl);
+        }
+    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.TextureBlock"] = TextureBlock;

+ 42 - 0
src/Materials/Node/Blocks/Input/inputBlock.ts

@@ -424,6 +424,48 @@ export class InputBlock extends NodeMaterialBlock {
 
         this._emit(state);
     }
+
+    public serialize(): any {
+        let serializationObject = super.serialize();
+
+        serializationObject.type = this.type;
+        serializationObject.mode = this._mode;
+        serializationObject.wellKnownValue = this._wellKnownValue;
+
+        if (this._storedValue != null && this._mode === NodeMaterialBlockConnectionPointMode.Uniform) {
+            if (this._storedValue.asArray) {
+                serializationObject.valueType = "BABYLON." + this._storedValue.getClassName();
+                serializationObject.value = this._storedValue.asArray();
+            } else {
+                serializationObject.valueType = "number";
+                serializationObject.value = this._storedValue;
+            }
+        }
+
+        return serializationObject;
+    }
+
+    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        super._deserialize(serializationObject, scene, rootUrl);
+
+        this._type = serializationObject.type;
+        this._mode = serializationObject.mode;
+        this._wellKnownValue = serializationObject.wellKnownValue;
+
+        if (!serializationObject.valueType) {
+            return;
+        }
+
+        if (serializationObject.valueType === "number") {
+            this._storedValue = serializationObject.value;
+        } else {
+            let valueType = _TypeStore.GetClass(serializationObject.valueType);
+
+            if (valueType) {
+                this._storedValue = valueType.FromArray(serializationObject.value);
+            }
+        }
+    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.InputBlock"] = InputBlock;

+ 21 - 9
src/Materials/Node/nodeMaterial.ts

@@ -879,8 +879,8 @@ export class NodeMaterial extends PushMaterial {
         }
         list.push(rootNode);
 
-        for (var inputs of rootNode.inputs) {
-            let connectedPoint = inputs.connectedPoint;
+        for (var input of rootNode.inputs) {
+            let connectedPoint = input.connectedPoint;
             if (connectedPoint) {
                 let block = connectedPoint.ownerBlock;
                 if (block !== rootNode) {
@@ -930,7 +930,7 @@ export class NodeMaterial extends PushMaterial {
      * @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 {
+    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} = {};
@@ -940,19 +940,31 @@ export class NodeMaterial extends PushMaterial {
             let blockType = _TypeStore.GetClass(parsedBlock.customType);
             if (blockType) {
                 let block: NodeMaterialBlock = new blockType();
-
+                block._deserialize(parsedBlock, scene, rootUrl);
                 map[parsedBlock.id] = block;
             }
         }
 
         // Connections
-        // for (var parsedBlock of source.blocks) {
-        //     let block = map[parsedBlock.id];
 
-        //     for (var input of parsedBlock.inputs) {
+        // Play them in reverse to make sure types are defined            
+        for (var blockIndex = source.blocks.length - 1; blockIndex >=0; blockIndex--) {       
+            let parsedBlock = source.blocks[blockIndex];
+            let block = map[parsedBlock.id];
+
+            for (var input of parsedBlock.inputs) {
+                if (!input.targetBlockId) {
+                    continue;
+                }
+                let inputPoint = block.getInputByName(input.inputName);
+                let targetBlock = map[input.targetBlockId];
+                let outputPoint = targetBlock.getOutputByName(input.targetConnectionName);
 
-        //     }
-        // }
+                if (inputPoint && outputPoint) {
+                    outputPoint.connectTo(inputPoint);
+                }
+            }
+        }
 
         // Outputs
         for (var outputNodeId of source.outputNodes) {

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

@@ -9,6 +9,7 @@ import { Mesh } from '../../Meshes/mesh';
 import { NodeMaterial, NodeMaterialDefines } from './nodeMaterial';
 import { InputBlock } from './Blocks/Input/inputBlock';
 import { UniqueIdGenerator } from '../../Misc/uniqueIdGenerator';
+import { Scene } from '../../scene';
 
 /**
  * Defines a block that can be used inside a node based material
@@ -481,6 +482,7 @@ export class NodeMaterialBlock {
         let serializationObject: any = {};
         serializationObject.customType = "BABYLON." + this.getClassName();
         serializationObject.id = this.uniqueId;
+        serializationObject.name = this.name;
 
         serializationObject.inputs = [];
 
@@ -490,4 +492,9 @@ export class NodeMaterialBlock {
 
         return serializationObject;
     }
+
+    /** @hidden */
+    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        this.name = serializationObject.name ;
+    }
 }

+ 3 - 1
src/Materials/Node/nodeMaterialBlockConnectionPoint.ts

@@ -238,7 +238,9 @@ export class NodeMaterialConnectionPoint {
         serializationObject.swizzle = this.swizzle;
 
         if (this.connectedPoint) {
-            serializationObject.connectedPointPath = this.name + ">" + this.connectedPoint.ownerBlock.uniqueId + "." + this.connectedPoint.name;
+            serializationObject.inputName = this.name;
+            serializationObject.targetBlockId = this.connectedPoint.ownerBlock.uniqueId;
+            serializationObject.targetConnectionName = this.connectedPoint.name;
         }
 
         return serializationObject;

+ 5 - 1
src/Maths/math.color.ts

@@ -2,6 +2,7 @@ import { DeepImmutable, FloatArray } from '../types';
 import { Scalar } from './math.scalar';
 import { ToLinearSpace, ToGammaSpace } from './math.constants';
 import { ArrayTools } from '../Misc/arrayTools';
+import { _TypeStore } from '../Misc/typeStore';
 
 /**
  * Class used to hold a RBG color
@@ -989,4 +990,7 @@ export class Color4 {
 export class TmpColors {
     public static Color3: Color3[] = ArrayTools.BuildArray(3, Color3.Black);
     public static Color4: Color4[] = ArrayTools.BuildArray(3, () => new Color4(0, 0, 0, 0));
-}
+}
+
+_TypeStore.RegisteredTypes["BABYLON.Color3"] = Color3;
+_TypeStore.RegisteredTypes["BABYLON.Color4"] = Color4;

+ 6 - 0
src/Maths/math.vector.ts

@@ -4,6 +4,7 @@ import { Viewport } from './math.viewport';
 import { DeepImmutable, Nullable, FloatArray, float } from "../types";
 import { ArrayTools } from '../Misc/arrayTools';
 import { IPlaneLike } from './math.like';
+import { _TypeStore } from '../Misc/typeStore';
 
 /**
  * Class representing a vector containing 2 coordinates
@@ -5257,3 +5258,8 @@ export class TmpVectors {
     public static Quaternion: Quaternion[] = ArrayTools.BuildArray(2, Quaternion.Zero); // 2 temp Quaternion at once should be enough
     public static Matrix: Matrix[] = ArrayTools.BuildArray(8, Matrix.Identity); // 8 temp Matrices at once should be enough
 }
+
+_TypeStore.RegisteredTypes["BABYLON.Vector2"] = Vector2;
+_TypeStore.RegisteredTypes["BABYLON.Vector3"] = Vector3;
+_TypeStore.RegisteredTypes["BABYLON.Vector4"] = Vector4;
+_TypeStore.RegisteredTypes["BABYLON.Matrix"] = Matrix;