David Catuhe 6 năm trước cách đây
mục cha
commit
1b91b474b1
30 tập tin đã thay đổi với 423 bổ sung56 xóa
  1. 16 1
      Playground/babylon.d.txt
  2. 2 0
      dist/preview release/babylon.d.ts
  3. 1 1
      dist/preview release/babylon.js
  4. 13 2
      dist/preview release/babylon.max.js
  5. 1 1
      dist/preview release/babylon.max.js.map
  6. 4 0
      dist/preview release/babylon.module.d.ts
  7. 16 1
      dist/preview release/documentation.d.ts
  8. 13 0
      dist/preview release/gui/babylon.gui.d.ts
  9. 84 0
      dist/preview release/gui/babylon.gui.js
  10. 1 1
      dist/preview release/gui/babylon.gui.js.map
  11. 1 1
      dist/preview release/gui/babylon.gui.min.js
  12. 26 0
      dist/preview release/gui/babylon.gui.module.d.ts
  13. 8 0
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  14. 2 2
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  15. 82 17
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  16. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  17. 16 0
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  18. 4 0
      dist/preview release/viewer/babylon.module.d.ts
  19. 1 1
      dist/preview release/viewer/babylon.viewer.js
  20. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  21. 2 1
      nodeEditor/public/index.html
  22. 5 1
      nodeEditor/public/index.js
  23. 21 9
      nodeEditor/src/components/preview/previewManager.ts
  24. 6 1
      nodeEditor/src/components/propertyTab/properties/matrixPropertyTabComponent.tsx
  25. 4 0
      nodeEditor/src/components/propertyTab/propertyTab.scss
  26. 3 1
      nodeEditor/src/graphEditor.tsx
  27. 70 9
      nodeEditor/src/sharedComponents/matrixLineComponent.tsx
  28. 2 1
      nodeEditor/src/sharedComponents/optionsLineComponent.tsx
  29. 1 1
      src/Engines/engine.ts
  30. 16 2
      src/Materials/Node/Blocks/Input/inputBlock.ts

+ 16 - 1
Playground/babylon.d.txt

@@ -14391,7 +14391,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Reprasents a camera frustum
+     * Represents a camera frustum
      */
     export class Frustum {
         /**
@@ -52239,6 +52239,8 @@ declare module BABYLON {
         min: number;
         /** Gets or set a value used to limit the range of float values */
         max: number;
+        /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+        matrixMode: number;
         /** @hidden */
private _systemValue: Nullable<NodeMaterialSystemValues>;
         /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
         visibleInInspector: boolean;
@@ -63266,6 +63268,10 @@ declare module BABYLON.GUI {
          */
         onImageLoadedObservable: BABYLON.Observable<Image>;
         /**
+         * BABYLON.Observable notified when _sourceLeft, _sourceTop, _sourceWidth and _sourceHeight are computed
+         */
+        onSVGAttributesComputedObservable: BABYLON.Observable<Image>;
+        /**
          * Gets a boolean indicating that the content is loaded
          */
         readonly isLoaded: boolean;
@@ -63328,6 +63334,15 @@ declare module BABYLON.GUI {
          */
         source: BABYLON.Nullable<string>;
         /**
+         * Checks for svg document with icon id present
+         */
+        private _svgCheck;
+        /**
+         * Sets sourceLeft, sourceTop, sourceWidth, sourceHeight automatically
+         * given external svg file and icon id
+         */
+        private _getSVGAttribs;
+        /**
          * Gets or sets the cell width to use when animation sheet is enabled
          * @see http://doc.babylonjs.com/how_to/gui#image
          */

+ 2 - 0
dist/preview release/babylon.d.ts

@@ -53058,6 +53058,8 @@ declare module BABYLON {
         min: number;
         /** Gets or set a value used to limit the range of float values */
         max: number;
+        /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+        matrixMode: number;
         /** @hidden */
         _systemValue: Nullable<NodeMaterialSystemValues>;
         /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/babylon.js


+ 13 - 2
dist/preview release/babylon.max.js

@@ -62282,6 +62282,8 @@ var InputBlock = /** @class */ (function (_super) {
         _this.min = 0;
         /** Gets or set a value used to limit the range of float values */
         _this.max = 0;
+        /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+        _this.matrixMode = 0;
         /** @hidden */
         _this._systemValue = null;
         /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
@@ -62604,8 +62606,11 @@ var InputBlock = /** @class */ (function (_super) {
             var valueString = "";
             switch (this.type) {
                 case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float:
-                    valueString = this.value.toString();
-                    break;
+                    var returnValue = this._codeVariableName + ".value = " + this.value + ";\r\n";
+                    returnValue += this._codeVariableName + ".min = " + this.min + ";\r\n";
+                    returnValue += this._codeVariableName + ".max = " + this.max + ";\r\n";
+                    returnValue += this._codeVariableName + ".matrixMode = " + this.matrixMode + ";\r\n";
+                    return returnValue;
                 case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2:
                     valueString = "new BABYLON.Vector2(" + this.value.x + ", " + this.value.y + ")";
                     break;
@@ -62775,6 +62780,9 @@ var InputBlock = /** @class */ (function (_super) {
         serializationObject.systemValue = this._systemValue;
         serializationObject.animationType = this._animationType;
         serializationObject.visibleInInspector = this.visibleInInspector;
+        serializationObject.min = this.min;
+        serializationObject.max = this.max;
+        serializationObject.matrixMode = this.matrixMode;
         if (this._storedValue != null && this._mode === _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Uniform) {
             if (this._storedValue.asArray) {
                 serializationObject.valueType = "BABYLON." + this._storedValue.getClassName();
@@ -62794,6 +62802,9 @@ var InputBlock = /** @class */ (function (_super) {
         this._systemValue = serializationObject.systemValue || serializationObject.wellKnownValue;
         this._animationType = serializationObject.animationType;
         this.visibleInInspector = serializationObject.visibleInInspector;
+        this.min = serializationObject.min || 0;
+        this.max = serializationObject.max || 0;
+        this.matrixMode = serializationObject.matrixMode || 0;
         if (!serializationObject.valueType) {
             return;
         }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 4 - 0
dist/preview release/babylon.module.d.ts

@@ -55540,6 +55540,8 @@ declare module "babylonjs/Materials/Node/Blocks/Input/inputBlock" {
         min: number;
         /** Gets or set a value used to limit the range of float values */
         max: number;
+        /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+        matrixMode: number;
         /** @hidden */
         _systemValue: Nullable<NodeMaterialSystemValues>;
         /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
@@ -118668,6 +118670,8 @@ declare module BABYLON {
         min: number;
         /** Gets or set a value used to limit the range of float values */
         max: number;
+        /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+        matrixMode: number;
         /** @hidden */
         _systemValue: Nullable<NodeMaterialSystemValues>;
         /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */

+ 16 - 1
dist/preview release/documentation.d.ts

@@ -14553,7 +14553,7 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Reprasents a camera frustum
+     * Represents a camera frustum
      */
     export class Frustum {
         /**
@@ -53058,6 +53058,8 @@ declare module BABYLON {
         min: number;
         /** Gets or set a value used to limit the range of float values */
         max: number;
+        /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+        matrixMode: number;
         /** @hidden */
         _systemValue: Nullable<NodeMaterialSystemValues>;
         /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
@@ -64223,6 +64225,10 @@ declare module BABYLON.GUI {
          */
         onImageLoadedObservable: BABYLON.Observable<Image>;
         /**
+         * BABYLON.Observable notified when _sourceLeft, _sourceTop, _sourceWidth and _sourceHeight are computed
+         */
+        onSVGAttributesComputedObservable: BABYLON.Observable<Image>;
+        /**
          * Gets a boolean indicating that the content is loaded
          */
         readonly isLoaded: boolean;
@@ -64285,6 +64291,15 @@ declare module BABYLON.GUI {
          */
         source: BABYLON.Nullable<string>;
         /**
+         * Checks for svg document with icon id present
+         */
+        private _svgCheck;
+        /**
+         * Sets sourceLeft, sourceTop, sourceWidth, sourceHeight automatically
+         * given external svg file and icon id
+         */
+        private _getSVGAttribs;
+        /**
          * Gets or sets the cell width to use when animation sheet is enabled
          * @see http://doc.babylonjs.com/how_to/gui#image
          */

+ 13 - 0
dist/preview release/gui/babylon.gui.d.ts

@@ -1440,6 +1440,10 @@ declare module BABYLON.GUI {
          */
         onImageLoadedObservable: BABYLON.Observable<Image>;
         /**
+         * BABYLON.Observable notified when _sourceLeft, _sourceTop, _sourceWidth and _sourceHeight are computed
+         */
+        onSVGAttributesComputedObservable: BABYLON.Observable<Image>;
+        /**
          * Gets a boolean indicating that the content is loaded
          */
         readonly isLoaded: boolean;
@@ -1502,6 +1506,15 @@ declare module BABYLON.GUI {
          */
         source: BABYLON.Nullable<string>;
         /**
+         * Checks for svg document with icon id present
+         */
+        private _svgCheck;
+        /**
+         * Sets sourceLeft, sourceTop, sourceWidth, sourceHeight automatically
+         * given external svg file and icon id
+         */
+        private _getSVGAttribs;
+        /**
          * Gets or sets the cell width to use when animation sheet is enabled
          * @see http://doc.babylonjs.com/how_to/gui#image
          */

+ 84 - 0
dist/preview release/gui/babylon.gui.js

@@ -6311,6 +6311,10 @@ var Image = /** @class */ (function (_super) {
          * Observable notified when the content is loaded
          */
         _this.onImageLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
+        /**
+         * Observable notified when _sourceLeft, _sourceTop, _sourceWidth and _sourceHeight are computed
+         */
+        _this.onSVGAttributesComputedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
         _this.source = url;
         return _this;
     }
@@ -6619,6 +6623,9 @@ var Image = /** @class */ (function (_super) {
             }
             this._loaded = false;
             this._source = value;
+            if (value) {
+                this._svgCheck(value);
+            }
             this._domImage = document.createElement("img");
             this._domImage.onload = function () {
                 _this._onImageLoaded();
@@ -6631,6 +6638,82 @@ var Image = /** @class */ (function (_super) {
         enumerable: true,
         configurable: true
     });
+    /**
+     * Checks for svg document with icon id present
+     */
+    Image.prototype._svgCheck = function (value) {
+        var _this = this;
+        if ((value.search(/.svg#/gi) !== -1) && (value.indexOf("#") === value.lastIndexOf("#"))) {
+            var svgsrc = value.split('#')[0];
+            var elemid = value.split('#')[1];
+            // check if object alr exist in document
+            var svgExist = document.body.querySelector('object[data="' + svgsrc + '"]');
+            if (svgExist) {
+                if (svgExist.contentDocument) {
+                    // svg object alr exists
+                    this._getSVGAttribs(svgExist, elemid);
+                }
+                else {
+                    // wait for object to load
+                    svgExist.addEventListener("load", function () {
+                        _this._getSVGAttribs(svgExist, elemid);
+                    });
+                }
+            }
+            else {
+                // create document object
+                var svgImage = document.createElement("object");
+                svgImage.data = svgsrc;
+                svgImage.type = "image/svg+xml";
+                svgImage.width = "0%";
+                svgImage.height = "0%";
+                document.body.appendChild(svgImage);
+                // when the object has loaded, get the element attribs
+                svgImage.onload = function () {
+                    var svgobj = document.body.querySelector('object[data="' + svgsrc + '"]');
+                    if (svgobj) {
+                        _this._getSVGAttribs(svgobj, elemid);
+                    }
+                };
+            }
+        }
+    };
+    /**
+     * Sets sourceLeft, sourceTop, sourceWidth, sourceHeight automatically
+     * given external svg file and icon id
+     */
+    Image.prototype._getSVGAttribs = function (svgsrc, elemid) {
+        var svgDoc = svgsrc.contentDocument;
+        // get viewbox width and height, get svg document width and height in px
+        if (svgDoc && svgDoc.documentElement) {
+            var vb = svgDoc.documentElement.getAttribute("viewBox");
+            var docwidth = Number(svgDoc.documentElement.getAttribute("width"));
+            var docheight = Number(svgDoc.documentElement.getAttribute("height"));
+            // get element bbox and matrix transform
+            var elem = svgDoc.getElementById(elemid);
+            if (elem instanceof SVGElement && vb && docwidth && docheight) {
+                var vb_width = Number(vb.split(" ")[2]);
+                var vb_height = Number(vb.split(" ")[3]);
+                var elem_bbox = elem.getBBox();
+                var elem_matrix_a = 1;
+                var elem_matrix_d = 1;
+                var elem_matrix_e = 0;
+                var elem_matrix_f = 0;
+                if (elem.transform && elem.transform.baseVal.consolidate()) {
+                    elem_matrix_a = elem.transform.baseVal.consolidate().matrix.a;
+                    elem_matrix_d = elem.transform.baseVal.consolidate().matrix.d;
+                    elem_matrix_e = elem.transform.baseVal.consolidate().matrix.e;
+                    elem_matrix_f = elem.transform.baseVal.consolidate().matrix.f;
+                }
+                // compute source coordinates and dimensions
+                this.sourceLeft = ((elem_matrix_a * elem_bbox.x + elem_matrix_e) * docwidth) / vb_width;
+                this.sourceTop = ((elem_matrix_d * elem_bbox.y + elem_matrix_f) * docheight) / vb_height;
+                this.sourceWidth = (elem_bbox.width * elem_matrix_a) * (docwidth / vb_width);
+                this.sourceHeight = (elem_bbox.height * elem_matrix_d) * (docheight / vb_height);
+                this.onSVGAttributesComputedObservable.notifyObservers(this);
+            }
+        }
+    };
     Object.defineProperty(Image.prototype, "cellWidth", {
         /**
          * Gets or sets the cell width to use when animation sheet is enabled
@@ -6858,6 +6941,7 @@ var Image = /** @class */ (function (_super) {
     Image.prototype.dispose = function () {
         _super.prototype.dispose.call(this);
         this.onImageLoadedObservable.clear();
+        this.onSVGAttributesComputedObservable.clear();
     };
     Image._WorkingCanvas = null;
     // Static

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/gui/babylon.gui.js.map


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


+ 26 - 0
dist/preview release/gui/babylon.gui.module.d.ts

@@ -1483,6 +1483,10 @@ declare module "babylonjs-gui/2D/controls/image" {
          */
         onImageLoadedObservable: Observable<Image>;
         /**
+         * Observable notified when _sourceLeft, _sourceTop, _sourceWidth and _sourceHeight are computed
+         */
+        onSVGAttributesComputedObservable: Observable<Image>;
+        /**
          * Gets a boolean indicating that the content is loaded
          */
         readonly isLoaded: boolean;
@@ -1545,6 +1549,15 @@ declare module "babylonjs-gui/2D/controls/image" {
          */
         source: Nullable<string>;
         /**
+         * Checks for svg document with icon id present
+         */
+        private _svgCheck;
+        /**
+         * Sets sourceLeft, sourceTop, sourceWidth, sourceHeight automatically
+         * given external svg file and icon id
+         */
+        private _getSVGAttribs;
+        /**
          * Gets or sets the cell width to use when animation sheet is enabled
          * @see http://doc.babylonjs.com/how_to/gui#image
          */
@@ -5313,6 +5326,10 @@ declare module BABYLON.GUI {
          */
         onImageLoadedObservable: BABYLON.Observable<Image>;
         /**
+         * BABYLON.Observable notified when _sourceLeft, _sourceTop, _sourceWidth and _sourceHeight are computed
+         */
+        onSVGAttributesComputedObservable: BABYLON.Observable<Image>;
+        /**
          * Gets a boolean indicating that the content is loaded
          */
         readonly isLoaded: boolean;
@@ -5375,6 +5392,15 @@ declare module BABYLON.GUI {
          */
         source: BABYLON.Nullable<string>;
         /**
+         * Checks for svg document with icon id present
+         */
+        private _svgCheck;
+        /**
+         * Sets sourceLeft, sourceTop, sourceWidth, sourceHeight automatically
+         * given external svg file and icon id
+         */
+        private _getSVGAttribs;
+        /**
          * Gets or sets the cell width to use when animation sheet is enabled
          * @see http://doc.babylonjs.com/how_to/gui#image
          */

+ 8 - 0
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts

@@ -599,6 +599,7 @@ declare module NODEEDITOR {
     interface IOptionsLineComponentProps {
         label: string;
         target: any;
+        className?: string;
         propertyName?: string;
         options: ListLineOption[];
         noDirectUpdate?: boolean;
@@ -716,19 +717,26 @@ declare module NODEEDITOR {
         propertyName: string;
         step?: number;
         onChange?: (newValue: BABYLON.Matrix) => void;
+        onModeChange?: (mode: number) => void;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        mode?: number;
     }
     export class MatrixLineComponent extends React.Component<IMatrixLineComponentProps, {
         value: BABYLON.Matrix;
+        mode: number;
+        angle: number;
     }> {
         private _localChange;
         constructor(props: IMatrixLineComponentProps);
         shouldComponentUpdate(nextProps: IMatrixLineComponentProps, nextState: {
             value: BABYLON.Matrix;
+            mode: number;
+            angle: number;
         }): boolean;
         raiseOnPropertyChanged(previousValue: BABYLON.Vector3): void;
         updateMatrix(): void;
         updateRow(value: BABYLON.Vector4, row: number): void;
+        updateBasedOnMode(value: number): void;
         render(): JSX.Element;
     }
 }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 82 - 17
dist/preview release/nodeEditor/babylon.nodeEditor.max.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


+ 16 - 0
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts

@@ -724,6 +724,7 @@ declare module "babylonjs-node-editor/sharedComponents/optionsLineComponent" {
     interface IOptionsLineComponentProps {
         label: string;
         target: any;
+        className?: string;
         propertyName?: string;
         options: ListLineOption[];
         noDirectUpdate?: boolean;
@@ -862,19 +863,26 @@ declare module "babylonjs-node-editor/sharedComponents/matrixLineComponent" {
         propertyName: string;
         step?: number;
         onChange?: (newValue: Matrix) => void;
+        onModeChange?: (mode: number) => void;
         onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+        mode?: number;
     }
     export class MatrixLineComponent extends React.Component<IMatrixLineComponentProps, {
         value: Matrix;
+        mode: number;
+        angle: number;
     }> {
         private _localChange;
         constructor(props: IMatrixLineComponentProps);
         shouldComponentUpdate(nextProps: IMatrixLineComponentProps, nextState: {
             value: Matrix;
+            mode: number;
+            angle: number;
         }): boolean;
         raiseOnPropertyChanged(previousValue: Vector3): void;
         updateMatrix(): void;
         updateRow(value: Vector4, row: number): void;
+        updateBasedOnMode(value: number): void;
         render(): JSX.Element;
     }
 }
@@ -2240,6 +2248,7 @@ declare module NODEEDITOR {
     interface IOptionsLineComponentProps {
         label: string;
         target: any;
+        className?: string;
         propertyName?: string;
         options: ListLineOption[];
         noDirectUpdate?: boolean;
@@ -2357,19 +2366,26 @@ declare module NODEEDITOR {
         propertyName: string;
         step?: number;
         onChange?: (newValue: BABYLON.Matrix) => void;
+        onModeChange?: (mode: number) => void;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        mode?: number;
     }
     export class MatrixLineComponent extends React.Component<IMatrixLineComponentProps, {
         value: BABYLON.Matrix;
+        mode: number;
+        angle: number;
     }> {
         private _localChange;
         constructor(props: IMatrixLineComponentProps);
         shouldComponentUpdate(nextProps: IMatrixLineComponentProps, nextState: {
             value: BABYLON.Matrix;
+            mode: number;
+            angle: number;
         }): boolean;
         raiseOnPropertyChanged(previousValue: BABYLON.Vector3): void;
         updateMatrix(): void;
         updateRow(value: BABYLON.Vector4, row: number): void;
+        updateBasedOnMode(value: number): void;
         render(): JSX.Element;
     }
 }

+ 4 - 0
dist/preview release/viewer/babylon.module.d.ts

@@ -55540,6 +55540,8 @@ declare module "babylonjs/Materials/Node/Blocks/Input/inputBlock" {
         min: number;
         /** Gets or set a value used to limit the range of float values */
         max: number;
+        /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+        matrixMode: number;
         /** @hidden */
         _systemValue: Nullable<NodeMaterialSystemValues>;
         /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
@@ -118668,6 +118670,8 @@ declare module BABYLON {
         min: number;
         /** Gets or set a value used to limit the range of float values */
         max: number;
+        /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+        matrixMode: number;
         /** @hidden */
         _systemValue: Nullable<NodeMaterialSystemValues>;
         /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 2 - 1
nodeEditor/public/index.html

@@ -10,7 +10,8 @@
     <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
     <link rel="stylesheet" href="https://use.typekit.net/cta4xsb.css"></style>
     <script src="https://preview.babylonjs.com/babylon.js"></script>
-    <script src="https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.js"></script>
+    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
+    <script src="https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.js"></script>    
     
     <style>
         html,

+ 5 - 1
nodeEditor/public/index.js

@@ -35,7 +35,11 @@ var checkHash = function () {
                                 customLoadObservable.notifyObservers(serializationObject);
                             } else {
                                 nodeMaterial.loadFromSerialization(serializationObject);
-                                nodeMaterial.build(true);
+                                try {
+                                    nodeMaterial.build(true);
+                                } catch (err) {
+                                     // Swallow the error here
+                                }
                                 showEditor();
                             }
                         }

+ 21 - 9
nodeEditor/src/components/preview/previewManager.ts

@@ -169,15 +169,27 @@ export class PreviewManager {
     }
 
     private _updatePreview(serializationObject: any) {
-        if (this._material) {
-            this._material.dispose();
-        }        
-
-        this._material = NodeMaterial.Parse(serializationObject, this._scene);
-        this._material.build();
-
-        for (var mesh of this._meshes) {
-            mesh.material = this._material;
+        let tempMaterial = NodeMaterial.Parse(serializationObject, this._scene);
+        try {
+            tempMaterial.build();
+
+            if (this._meshes.length) {
+                tempMaterial.forceCompilation(this._meshes[0], () => {
+                    for (var mesh of this._meshes) {
+                        mesh.material = tempMaterial;
+                    }
+        
+                    if (this._material) {
+                        this._material.dispose();
+                    }      
+        
+                    this._material = tempMaterial;    
+                });
+            } else {
+                this._material = tempMaterial;    
+            }
+        } catch(err) {
+            // Ignore the error
         }
     }
 

+ 6 - 1
nodeEditor/src/components/propertyTab/properties/matrixPropertyTabComponent.tsx

@@ -15,7 +15,12 @@ export class MatrixPropertyTabComponent extends React.Component<IMatrixPropertyT
         return (
             <MatrixLineComponent label="Value" target={this.props.inputBlock} propertyName="value" onChange={() => {
                 this.props.globalState.onUpdateRequiredObservable.notifyObservers();
-            }}></MatrixLineComponent>
+            }}
+            mode={this.props.inputBlock.matrixMode}
+            onModeChange={mode => {
+                this.props.inputBlock.matrixMode = mode;
+            }}
+            ></MatrixLineComponent>
         );
     }
 }

+ 4 - 0
nodeEditor/src/components/propertyTab/propertyTab.scss

@@ -256,6 +256,10 @@
             padding-right: 5px;  
             border-left: 1px solid rgb(51, 122, 183);
 
+            .no-right-margin {
+                margin-right: 0;
+            }
+
             .numeric {
                 display: grid;
                 grid-template-columns: 1fr auto;

+ 3 - 1
nodeEditor/src/graphEditor.tsx

@@ -174,7 +174,9 @@ export class GraphEditor extends React.Component<IGraphEditorProps> {
             this.props.globalState.hostDocument!.removeEventListener("keyup", this._onWidgetKeyUpPointer, false);
         }
 
-        this._previewManager.dispose();
+        if (this._previewManager) {
+            this._previewManager.dispose();
+        }
     }
 
     constructor(props: IGraphEditorProps) {

+ 70 - 9
nodeEditor/src/sharedComponents/matrixLineComponent.tsx

@@ -3,6 +3,8 @@ import { Vector3, Matrix, Vector4 } from "babylonjs/Maths/math";
 import { Observable } from "babylonjs/Misc/observable";
 import { PropertyChangedEvent } from "./propertyChangedEvent";
 import { Vector4LineComponent } from './vector4LineComponent';
+import { OptionsLineComponent } from './optionsLineComponent';
+import { SliderLineComponent } from './sliderLineComponent';
 
 interface IMatrixLineComponentProps {
     label: string;
@@ -10,10 +12,12 @@ interface IMatrixLineComponentProps {
     propertyName: string;
     step?: number;
     onChange?: (newValue: Matrix) => void;
+    onModeChange?: (mode: number) => void;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    mode?: number;
 }
 
-export class MatrixLineComponent extends React.Component<IMatrixLineComponentProps, { value: Matrix}> {
+export class MatrixLineComponent extends React.Component<IMatrixLineComponentProps, { value: Matrix, mode: number, angle: number}> {
    private _localChange = false;
 
     constructor(props: IMatrixLineComponentProps) {
@@ -21,10 +25,10 @@ export class MatrixLineComponent extends React.Component<IMatrixLineComponentPro
 
         let matrix: Matrix = this.props.target[this.props.propertyName].clone();
 
-        this.state = { value:matrix }
+        this.state = { value:matrix, mode: this.props.mode || 0, angle: 0 }
     }
 
-    shouldComponentUpdate(nextProps: IMatrixLineComponentProps, nextState: { value: Matrix }) {
+    shouldComponentUpdate(nextProps: IMatrixLineComponentProps, nextState: { value: Matrix, mode: number, angle: number }) {
         const nextPropsValue = nextProps.target[nextProps.propertyName];
 
         if (!nextPropsValue.equals(nextState.value) || this._localChange) {
@@ -32,7 +36,7 @@ export class MatrixLineComponent extends React.Component<IMatrixLineComponentPro
             this._localChange = false;
             return true;
         }
-        return false;
+        return nextState.mode !== this.state.mode || nextState.angle !== this.state.angle;
     }
 
     raiseOnPropertyChanged(previousValue: Vector3) {
@@ -67,7 +71,35 @@ export class MatrixLineComponent extends React.Component<IMatrixLineComponentPro
         this.updateMatrix();
     }
 
+    updateBasedOnMode(value: number) {
+
+        switch (this.state.mode) {
+            case 1: {
+                Matrix.RotationXToRef(this.state.angle, this.state.value);
+                break;
+            }
+            case 2: {
+                Matrix.RotationYToRef(this.state.angle, this.state.value);
+                break;
+            }
+            case 3: {
+                Matrix.RotationZToRef(this.state.angle, this.state.value);
+                break;
+            }
+        }
+        this.updateMatrix();
+
+        this.setState({angle: value});
+    }
+
     render() {
+        var modeOptions = [
+            { label: "User-defined", value: 0 },
+            { label: "Rotation over X axis", value: 1 },
+            { label: "Rotation over Y axis", value: 2 },
+            { label: "Rotation over Z axis", value: 3 },
+        ];
+
         return (
             <div className="vector3Line">
                 <div className="firstLine">
@@ -76,11 +108,40 @@ export class MatrixLineComponent extends React.Component<IMatrixLineComponentPro
                     </div>
                 </div>
                 <div className="secondLine">
-                    <Vector4LineComponent label="Row #0" value={this.state.value.getRow(0)!} onChange={value => this.updateRow(value, 0)}/>
-                    <Vector4LineComponent label="Row #1" value={this.state.value.getRow(1)!} onChange={value => this.updateRow(value, 1)}/>
-                    <Vector4LineComponent label="Row #2" value={this.state.value.getRow(2)!} onChange={value => this.updateRow(value, 2)}/>
-                    <Vector4LineComponent label="Row #3" value={this.state.value.getRow(3)!} onChange={value => this.updateRow(value, 3)}/>
-                </div>
+                    <OptionsLineComponent label="Mode"
+                        className="no-right-margin"
+                        options={modeOptions} target={this} 
+                        noDirectUpdate={true}
+                        getSelection={() => {
+                            return this.state.mode;
+                        }}
+                        onSelect={(value: any) => {
+                            this.props.target[this.props.propertyName] = Matrix.Identity();
+                            Matrix.IdentityToRef(this.state.value);
+                            this.setState({mode: value, angle: 0});
+                            
+                            this.updateMatrix();
+
+                            if (this.props.onModeChange) {
+                                this.props.onModeChange(value);
+                            }
+                        }} />                
+                    </div>
+                {
+                    this.state.mode === 0 &&
+                    <div className="secondLine">
+                        <Vector4LineComponent label="Row #0" value={this.state.value.getRow(0)!} onChange={value => this.updateRow(value, 0)}/>
+                        <Vector4LineComponent label="Row #1" value={this.state.value.getRow(1)!} onChange={value => this.updateRow(value, 1)}/>
+                        <Vector4LineComponent label="Row #2" value={this.state.value.getRow(2)!} onChange={value => this.updateRow(value, 2)}/>
+                        <Vector4LineComponent label="Row #3" value={this.state.value.getRow(3)!} onChange={value => this.updateRow(value, 3)}/>
+                    </div>
+                }
+                {
+                    this.state.mode !== 0 &&
+                    <div className="secondLine">
+                        <SliderLineComponent label="Angle" minimum={0} maximum={2 * Math.PI} useEuler={true} step={0.1} directValue={this.state.angle} onChange={value => this.updateBasedOnMode(value)}/>
+                    </div>
+                }
             </div>
         );
     }

+ 2 - 1
nodeEditor/src/sharedComponents/optionsLineComponent.tsx

@@ -11,6 +11,7 @@ class ListLineOption {
 interface IOptionsLineComponentProps {
     label: string,
     target: any,
+    className?: string,
     propertyName?: string,
     options: ListLineOption[],
     noDirectUpdate?: boolean,
@@ -88,7 +89,7 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
                     {this.props.label}
 
                 </div>
-                <div className="options">
+                <div className={"options" + (this.props.className ? " " + this.props.className : "")}>
                     <select onChange={evt => this.updateValue(evt.target.value)} value={this.state.value}>
                         {
                             this.props.options.map(option => {

+ 1 - 1
src/Engines/engine.ts

@@ -1176,7 +1176,7 @@ export class Engine {
             }
         } else {
             this._gl = <WebGLRenderingContext>canvasOrContext;
-            this._renderingCanvas = this._gl.canvas;
+            this._renderingCanvas = this._gl.canvas as HTMLCanvasElement;
 
             if (this._gl.renderbufferStorageMultisample) {
                 this._webGLVersion = 2.0;

+ 16 - 2
src/Materials/Node/Blocks/Input/inputBlock.ts

@@ -30,6 +30,9 @@ export class InputBlock extends NodeMaterialBlock {
     /** Gets or set a value used to limit the range of float values */
     public max: number = 0;
 
+    /** Gets or sets a value used by the Node Material editor to determine how to configure the current value if it is a matrix */
+    public matrixMode: number = 0;
+
     /** @hidden */
     public _systemValue: Nullable<NodeMaterialSystemValues> = null;
 
@@ -349,8 +352,13 @@ export class InputBlock extends NodeMaterialBlock {
             let valueString = "";
             switch (this.type) {
                 case NodeMaterialBlockConnectionPointTypes.Float:
-                    valueString = this.value.toString();
-                    break;
+                    let returnValue = `${this._codeVariableName}.value = ${this.value};\r\n`;
+
+                    returnValue += `${this._codeVariableName}.min = ${this.min};\r\n`;
+                    returnValue += `${this._codeVariableName}.max = ${this.max};\r\n`;
+                    returnValue += `${this._codeVariableName}.matrixMode = ${this.matrixMode};\r\n`;
+
+                    return returnValue;
                 case NodeMaterialBlockConnectionPointTypes.Vector2:
                     valueString = `new BABYLON.Vector2(${this.value.x}, ${this.value.y})`;
                     break;
@@ -540,6 +548,9 @@ export class InputBlock extends NodeMaterialBlock {
         serializationObject.systemValue = this._systemValue;
         serializationObject.animationType = this._animationType;
         serializationObject.visibleInInspector = this.visibleInInspector;
+        serializationObject.min = this.min;
+        serializationObject.max = this.max;
+        serializationObject.matrixMode = this.matrixMode;
 
         if (this._storedValue != null && this._mode === NodeMaterialBlockConnectionPointMode.Uniform) {
             if (this._storedValue.asArray) {
@@ -562,6 +573,9 @@ export class InputBlock extends NodeMaterialBlock {
         this._systemValue = serializationObject.systemValue || serializationObject.wellKnownValue;
         this._animationType = serializationObject.animationType;
         this.visibleInInspector = serializationObject.visibleInInspector;
+        this.min = serializationObject.min || 0;
+        this.max = serializationObject.max || 0;
+        this.matrixMode = serializationObject.matrixMode || 0;
 
         if (!serializationObject.valueType) {
             return;