David Catuhe 5 years ago
parent
commit
552707b8f2
31 changed files with 258 additions and 126 deletions
  1. 11 6
      dist/preview release/babylon.d.ts
  2. 1 1
      dist/preview release/babylon.js
  3. 55 50
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 22 12
      dist/preview release/babylon.module.d.ts
  6. 11 6
      dist/preview release/documentation.d.ts
  7. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  8. 3 2
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  9. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  10. 5 0
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  11. 1 1
      dist/preview release/loaders/babylon.glTF1FileLoader.js.map
  12. 1 1
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  13. 5 0
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  14. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  15. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  16. 5 0
      dist/preview release/loaders/babylon.glTFFileLoader.js
  17. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  18. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  19. 5 0
      dist/preview release/loaders/babylonjs.loaders.js
  20. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  21. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  22. 2 0
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  23. 7 7
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  24. 74 5
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  25. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  26. 4 0
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  27. 22 12
      dist/preview release/viewer/babylon.module.d.ts
  28. 7 7
      dist/preview release/viewer/babylon.viewer.js
  29. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  30. 1 0
      src/Materials/Node/nodeMaterial.ts
  31. 3 3
      src/Misc/assetsManager.ts

+ 11 - 6
dist/preview release/babylon.d.ts

@@ -57445,6 +57445,10 @@ declare module BABYLON {
         /** Get the inspector from bundle or global */
         private _getGlobalNodeMaterialEditor;
         /**
+         * Snippet ID if the material was created from the snippet server
+         */
+        snippetId: string;
+        /**
          * Gets or sets data used by visual editor
          * @see https://nme.babylonjs.com
          */
@@ -57703,9 +57707,10 @@ declare module BABYLON {
          * @param snippetId defines the snippet to load
          * @param scene defines the hosting scene
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
+         * @param nodeMaterial defines a node material to update (instead of creating a new one)
          * @returns a promise that will resolve to the new node material
          */
-        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string): Promise<NodeMaterial>;
+        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string, nodeMaterial?: NodeMaterial): Promise<NodeMaterial>;
         /**
          * Creates a new node material set to default basic configuration
          * @param name defines the name of the material
@@ -67984,9 +67989,9 @@ declare module BABYLON {
          */
         noMipmap?: boolean | undefined;
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined;
+        invertY: boolean;
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
@@ -68008,7 +68013,7 @@ declare module BABYLON {
          * @param name defines the name of the task
          * @param url defines the location of the file to load
          * @param noMipmap defines if mipmap should not be generated (default is false)
-         * @param invertY defines if texture must be inverted on Y axis (default is false)
+         * @param invertY defines if texture must be inverted on Y axis (default is true)
          * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
         constructor(
@@ -68025,9 +68030,9 @@ declare module BABYLON {
          */
         noMipmap?: boolean | undefined, 
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined, 
+        invertY?: boolean, 
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 55 - 50
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 22 - 12
dist/preview release/babylon.module.d.ts

@@ -60107,6 +60107,10 @@ declare module "babylonjs/Materials/Node/nodeMaterial" {
         /** Get the inspector from bundle or global */
         private _getGlobalNodeMaterialEditor;
         /**
+         * Snippet ID if the material was created from the snippet server
+         */
+        snippetId: string;
+        /**
          * Gets or sets data used by visual editor
          * @see https://nme.babylonjs.com
          */
@@ -60365,9 +60369,10 @@ declare module "babylonjs/Materials/Node/nodeMaterial" {
          * @param snippetId defines the snippet to load
          * @param scene defines the hosting scene
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
+         * @param nodeMaterial defines a node material to update (instead of creating a new one)
          * @returns a promise that will resolve to the new node material
          */
-        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string): Promise<NodeMaterial>;
+        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string, nodeMaterial?: NodeMaterial): Promise<NodeMaterial>;
         /**
          * Creates a new node material set to default basic configuration
          * @param name defines the name of the material
@@ -71651,9 +71656,9 @@ declare module "babylonjs/Misc/assetsManager" {
          */
         noMipmap?: boolean | undefined;
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined;
+        invertY: boolean;
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
@@ -71675,7 +71680,7 @@ declare module "babylonjs/Misc/assetsManager" {
          * @param name defines the name of the task
          * @param url defines the location of the file to load
          * @param noMipmap defines if mipmap should not be generated (default is false)
-         * @param invertY defines if texture must be inverted on Y axis (default is false)
+         * @param invertY defines if texture must be inverted on Y axis (default is true)
          * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
         constructor(
@@ -71692,9 +71697,9 @@ declare module "babylonjs/Misc/assetsManager" {
          */
         noMipmap?: boolean | undefined, 
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined, 
+        invertY?: boolean, 
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
@@ -131562,6 +131567,10 @@ declare module BABYLON {
         /** Get the inspector from bundle or global */
         private _getGlobalNodeMaterialEditor;
         /**
+         * Snippet ID if the material was created from the snippet server
+         */
+        snippetId: string;
+        /**
          * Gets or sets data used by visual editor
          * @see https://nme.babylonjs.com
          */
@@ -131820,9 +131829,10 @@ declare module BABYLON {
          * @param snippetId defines the snippet to load
          * @param scene defines the hosting scene
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
+         * @param nodeMaterial defines a node material to update (instead of creating a new one)
          * @returns a promise that will resolve to the new node material
          */
-        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string): Promise<NodeMaterial>;
+        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string, nodeMaterial?: NodeMaterial): Promise<NodeMaterial>;
         /**
          * Creates a new node material set to default basic configuration
          * @param name defines the name of the material
@@ -142101,9 +142111,9 @@ declare module BABYLON {
          */
         noMipmap?: boolean | undefined;
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined;
+        invertY: boolean;
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
@@ -142125,7 +142135,7 @@ declare module BABYLON {
          * @param name defines the name of the task
          * @param url defines the location of the file to load
          * @param noMipmap defines if mipmap should not be generated (default is false)
-         * @param invertY defines if texture must be inverted on Y axis (default is false)
+         * @param invertY defines if texture must be inverted on Y axis (default is true)
          * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
         constructor(
@@ -142142,9 +142152,9 @@ declare module BABYLON {
          */
         noMipmap?: boolean | undefined, 
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined, 
+        invertY?: boolean, 
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */

+ 11 - 6
dist/preview release/documentation.d.ts

@@ -57445,6 +57445,10 @@ declare module BABYLON {
         /** Get the inspector from bundle or global */
         private _getGlobalNodeMaterialEditor;
         /**
+         * Snippet ID if the material was created from the snippet server
+         */
+        snippetId: string;
+        /**
          * Gets or sets data used by visual editor
          * @see https://nme.babylonjs.com
          */
@@ -57703,9 +57707,10 @@ declare module BABYLON {
          * @param snippetId defines the snippet to load
          * @param scene defines the hosting scene
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
+         * @param nodeMaterial defines a node material to update (instead of creating a new one)
          * @returns a promise that will resolve to the new node material
          */
-        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string): Promise<NodeMaterial>;
+        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string, nodeMaterial?: NodeMaterial): Promise<NodeMaterial>;
         /**
          * Creates a new node material set to default basic configuration
          * @param name defines the name of the material
@@ -67984,9 +67989,9 @@ declare module BABYLON {
          */
         noMipmap?: boolean | undefined;
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined;
+        invertY: boolean;
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
@@ -68008,7 +68013,7 @@ declare module BABYLON {
          * @param name defines the name of the task
          * @param url defines the location of the file to load
          * @param noMipmap defines if mipmap should not be generated (default is false)
-         * @param invertY defines if texture must be inverted on Y axis (default is false)
+         * @param invertY defines if texture must be inverted on Y axis (default is true)
          * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
         constructor(
@@ -68025,9 +68030,9 @@ declare module BABYLON {
          */
         noMipmap?: boolean | undefined, 
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined, 
+        invertY?: boolean, 
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


+ 3 - 2
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -47621,7 +47621,7 @@ var ParticleSystemPropertyGridComponent = /** @class */ (function (_super) {
                         navigator.clipboard.writeText(system.snippetId);
                     }
                     var windowAsAny = window;
-                    if (windowAsAny.Playground) {
+                    if (windowAsAny.Playground && oldId) {
                         windowAsAny.Playground.onRequestCodeChangeObservable.notifyObservers({
                             regex: new RegExp(oldId, "g"),
                             replace: system.snippetId
@@ -47697,7 +47697,8 @@ var ParticleSystemPropertyGridComponent = /** @class */ (function (_super) {
                     } })),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "FILE" },
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_fileButtonLineComponent__WEBPACK_IMPORTED_MODULE_22__["FileButtonLineComponent"], { label: "Load", onClick: function (file) { return _this.loadFromFile(file); }, accept: ".json" }),
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_6__["ButtonLineComponent"], { label: "Save", onClick: function () { return _this.saveToFile(); } }),
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_6__["ButtonLineComponent"], { label: "Save", onClick: function () { return _this.saveToFile(); } })),
+            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__["LineContainerComponent"], { globalState: this.props.globalState, title: "SNIPPET" },
                 system.snippetId &&
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_3__["TextLineComponent"], { label: "Snippet ID", value: system.snippetId }),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_lines_buttonLineComponent__WEBPACK_IMPORTED_MODULE_6__["ButtonLineComponent"], { label: "Load from snippet server", onClick: function () { return _this.loadFromSnippet(); } }),

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 5 - 0
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -3206,6 +3206,10 @@ var GLTFFileLoader = /** @class */ (function () {
             _this.onTextureLoadedObservable.add(function (texture) {
                 textures.push(texture);
             });
+            var cameras = [];
+            _this.onCameraLoadedObservable.add(function (camera) {
+                cameras.push(camera);
+            });
             return _this._loader.importMeshAsync(null, scene, true, data, rootUrl, onProgress, fileName).then(function (result) {
                 var container = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["AssetContainer"](scene);
                 Array.prototype.push.apply(container.meshes, result.meshes);
@@ -3216,6 +3220,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 Array.prototype.push.apply(container.textures, textures);
                 Array.prototype.push.apply(container.lights, result.lights);
                 Array.prototype.push.apply(container.transformNodes, result.transformNodes);
+                Array.prototype.push.apply(container.cameras, cameras);
                 return container;
             });
         });

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 5 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -4676,6 +4676,10 @@ var GLTFFileLoader = /** @class */ (function () {
             _this.onTextureLoadedObservable.add(function (texture) {
                 textures.push(texture);
             });
+            var cameras = [];
+            _this.onCameraLoadedObservable.add(function (camera) {
+                cameras.push(camera);
+            });
             return _this._loader.importMeshAsync(null, scene, true, data, rootUrl, onProgress, fileName).then(function (result) {
                 var container = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["AssetContainer"](scene);
                 Array.prototype.push.apply(container.meshes, result.meshes);
@@ -4686,6 +4690,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 Array.prototype.push.apply(container.textures, textures);
                 Array.prototype.push.apply(container.lights, result.lights);
                 Array.prototype.push.apply(container.transformNodes, result.transformNodes);
+                Array.prototype.push.apply(container.cameras, cameras);
                 return container;
             });
         });

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 5 - 0
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -7256,6 +7256,10 @@ var GLTFFileLoader = /** @class */ (function () {
             _this.onTextureLoadedObservable.add(function (texture) {
                 textures.push(texture);
             });
+            var cameras = [];
+            _this.onCameraLoadedObservable.add(function (camera) {
+                cameras.push(camera);
+            });
             return _this._loader.importMeshAsync(null, scene, true, data, rootUrl, onProgress, fileName).then(function (result) {
                 var container = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["AssetContainer"](scene);
                 Array.prototype.push.apply(container.meshes, result.meshes);
@@ -7266,6 +7270,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 Array.prototype.push.apply(container.textures, textures);
                 Array.prototype.push.apply(container.lights, result.lights);
                 Array.prototype.push.apply(container.transformNodes, result.transformNodes);
+                Array.prototype.push.apply(container.cameras, cameras);
                 return container;
             });
         });

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 5 - 0
dist/preview release/loaders/babylonjs.loaders.js

@@ -8636,6 +8636,10 @@ var GLTFFileLoader = /** @class */ (function () {
             _this.onTextureLoadedObservable.add(function (texture) {
                 textures.push(texture);
             });
+            var cameras = [];
+            _this.onCameraLoadedObservable.add(function (camera) {
+                cameras.push(camera);
+            });
             return _this._loader.importMeshAsync(null, scene, true, data, rootUrl, onProgress, fileName).then(function (result) {
                 var container = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["AssetContainer"](scene);
                 Array.prototype.push.apply(container.meshes, result.meshes);
@@ -8646,6 +8650,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 Array.prototype.push.apply(container.textures, textures);
                 Array.prototype.push.apply(container.lights, result.lights);
                 Array.prototype.push.apply(container.transformNodes, result.transformNodes);
+                Array.prototype.push.apply(container.cameras, cameras);
                 return container;
             });
         });

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


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

@@ -1241,6 +1241,8 @@ declare module NODEEDITOR {
         load(file: File): void;
         save(): void;
         customSave(): void;
+        saveToSnippetServer(): void;
+        loadFromSnippet(): void;
         render(): JSX.Element;
     }
 }

File diff suppressed because it is too large
+ 7 - 7
dist/preview release/nodeEditor/babylon.nodeEditor.js


+ 74 - 5
dist/preview release/nodeEditor/babylon.nodeEditor.max.js

@@ -52884,6 +52884,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 __webpack_require__(/*! ./propertyTab.scss */ "./components/propertyTab/propertyTab.scss");
 var PropertyTabComponent = /** @class */ (function (_super) {
     Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"])(PropertyTabComponent, _super);
@@ -52968,6 +52969,66 @@ var PropertyTabComponent = /** @class */ (function (_super) {
             _this.props.globalState.onLogRequiredObservable.notifyObservers({ message: err, isError: true });
         });
     };
+    PropertyTabComponent.prototype.saveToSnippetServer = function () {
+        var _this = this;
+        var material = this.props.globalState.nodeMaterial;
+        var xmlHttp = new XMLHttpRequest();
+        var json = _serializationTools__WEBPACK_IMPORTED_MODULE_7__["SerializationTools"].Serialize(material, this.props.globalState);
+        xmlHttp.onreadystatechange = function () {
+            if (xmlHttp.readyState == 4) {
+                if (xmlHttp.status == 200) {
+                    var snippet = JSON.parse(xmlHttp.responseText);
+                    var oldId = material.snippetId;
+                    material.snippetId = snippet.id;
+                    if (snippet.version && snippet.version != "0") {
+                        material.snippetId += "#" + snippet.version;
+                    }
+                    _this.forceUpdate();
+                    if (navigator.clipboard) {
+                        navigator.clipboard.writeText(material.snippetId);
+                    }
+                    var windowAsAny = window;
+                    if (windowAsAny.Playground && oldId) {
+                        windowAsAny.Playground.onRequestCodeChangeObservable.notifyObservers({
+                            regex: new RegExp(oldId, "g"),
+                            replace: material.snippetId
+                        });
+                    }
+                    alert("NodeMaterial saved with ID: " + material.snippetId + " (please note that the id was also saved to your clipboard)");
+                }
+                else {
+                    alert("Unable to save your node material. It may be too large (" + (dataToSend.payload.length / 1024).toFixed(2) + " KB) because of embedded textures. Please reduce texture sizes or point to a specific url instead of embedding them and try again.");
+                }
+            }
+        };
+        xmlHttp.open("POST", babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_6__["NodeMaterial"].SnippetUrl + (material.snippetId ? "/" + material.snippetId : ""), true);
+        xmlHttp.setRequestHeader("Content-Type", "application/json");
+        var dataToSend = {
+            payload: JSON.stringify({
+                nodeMaterial: json
+            }),
+            name: "",
+            description: "",
+            tags: ""
+        };
+        xmlHttp.send(JSON.stringify(dataToSend));
+    };
+    PropertyTabComponent.prototype.loadFromSnippet = function () {
+        var _this = this;
+        var material = this.props.globalState.nodeMaterial;
+        var scene = material.getScene();
+        var snippedID = window.prompt("Please enter the snippet ID to use");
+        if (!snippedID) {
+            return;
+        }
+        this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
+        babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_6__["NodeMaterial"].ParseFromSnippetAsync(snippedID, scene, "", material).then(function () {
+            material.build();
+            _this.props.globalState.onResetRequiredObservable.notifyObservers();
+        }).catch(function (err) {
+            alert("Unable to load your node material: " + err);
+        });
+    };
     PropertyTabComponent.prototype.render = function () {
         var _this = this;
         if (this.state.currentNode) {
@@ -53021,16 +53082,24 @@ var PropertyTabComponent = /** @class */ (function (_super) {
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_buttonLineComponent__WEBPACK_IMPORTED_MODULE_2__["ButtonLineComponent"], { label: "Save", onClick: function () {
                             _this.save();
                         } }),
-                    this.props.globalState.customSave &&
-                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_buttonLineComponent__WEBPACK_IMPORTED_MODULE_2__["ButtonLineComponent"], { label: this.props.globalState.customSave.label, onClick: function () {
-                                _this.customSave();
-                            } }),
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_buttonLineComponent__WEBPACK_IMPORTED_MODULE_2__["ButtonLineComponent"], { label: "Generate code", onClick: function () {
                             _stringTools__WEBPACK_IMPORTED_MODULE_4__["StringTools"].DownloadAsFile(_this.props.globalState.hostDocument, _this.props.globalState.nodeMaterial.generateCode(), "code.txt");
                         } }),
                     react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_buttonLineComponent__WEBPACK_IMPORTED_MODULE_2__["ButtonLineComponent"], { label: "Export shaders", onClick: function () {
                             _stringTools__WEBPACK_IMPORTED_MODULE_4__["StringTools"].DownloadAsFile(_this.props.globalState.hostDocument, _this.props.globalState.nodeMaterial.compiledShaders, "shaders.txt");
-                        } })),
+                        } }),
+                    this.props.globalState.customSave &&
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_buttonLineComponent__WEBPACK_IMPORTED_MODULE_2__["ButtonLineComponent"], { label: this.props.globalState.customSave.label, onClick: function () {
+                                _this.customSave();
+                            } })),
+                !this.props.globalState.customSave &&
+                    react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { title: "SNIPPET" },
+                        this.props.globalState.nodeMaterial.snippetId &&
+                            react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_textLineComponent__WEBPACK_IMPORTED_MODULE_12__["TextLineComponent"], { label: "Snippet ID", value: this.props.globalState.nodeMaterial.snippetId }),
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_buttonLineComponent__WEBPACK_IMPORTED_MODULE_2__["ButtonLineComponent"], { label: "Load from snippet server", onClick: function () { return _this.loadFromSnippet(); } }),
+                        react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_buttonLineComponent__WEBPACK_IMPORTED_MODULE_2__["ButtonLineComponent"], { label: "Save to snippet server", onClick: function () {
+                                _this.saveToSnippetServer();
+                            } })),
                 react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { title: "INPUTS" }, this.props.globalState.nodeMaterial.getInputBlocks().map(function (ib) {
                     if (!ib.isUniform || ib.isSystemValue || !ib.name) {
                         return null;

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


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

@@ -1499,6 +1499,8 @@ declare module "babylonjs-node-editor/components/propertyTab/propertyTabComponen
         load(file: File): void;
         save(): void;
         customSave(): void;
+        saveToSnippetServer(): void;
+        loadFromSnippet(): void;
         render(): JSX.Element;
     }
 }
@@ -2951,6 +2953,8 @@ declare module NODEEDITOR {
         load(file: File): void;
         save(): void;
         customSave(): void;
+        saveToSnippetServer(): void;
+        loadFromSnippet(): void;
         render(): JSX.Element;
     }
 }

+ 22 - 12
dist/preview release/viewer/babylon.module.d.ts

@@ -60107,6 +60107,10 @@ declare module "babylonjs/Materials/Node/nodeMaterial" {
         /** Get the inspector from bundle or global */
         private _getGlobalNodeMaterialEditor;
         /**
+         * Snippet ID if the material was created from the snippet server
+         */
+        snippetId: string;
+        /**
          * Gets or sets data used by visual editor
          * @see https://nme.babylonjs.com
          */
@@ -60365,9 +60369,10 @@ declare module "babylonjs/Materials/Node/nodeMaterial" {
          * @param snippetId defines the snippet to load
          * @param scene defines the hosting scene
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
+         * @param nodeMaterial defines a node material to update (instead of creating a new one)
          * @returns a promise that will resolve to the new node material
          */
-        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string): Promise<NodeMaterial>;
+        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string, nodeMaterial?: NodeMaterial): Promise<NodeMaterial>;
         /**
          * Creates a new node material set to default basic configuration
          * @param name defines the name of the material
@@ -71651,9 +71656,9 @@ declare module "babylonjs/Misc/assetsManager" {
          */
         noMipmap?: boolean | undefined;
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined;
+        invertY: boolean;
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
@@ -71675,7 +71680,7 @@ declare module "babylonjs/Misc/assetsManager" {
          * @param name defines the name of the task
          * @param url defines the location of the file to load
          * @param noMipmap defines if mipmap should not be generated (default is false)
-         * @param invertY defines if texture must be inverted on Y axis (default is false)
+         * @param invertY defines if texture must be inverted on Y axis (default is true)
          * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
         constructor(
@@ -71692,9 +71697,9 @@ declare module "babylonjs/Misc/assetsManager" {
          */
         noMipmap?: boolean | undefined, 
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined, 
+        invertY?: boolean, 
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
@@ -131562,6 +131567,10 @@ declare module BABYLON {
         /** Get the inspector from bundle or global */
         private _getGlobalNodeMaterialEditor;
         /**
+         * Snippet ID if the material was created from the snippet server
+         */
+        snippetId: string;
+        /**
          * Gets or sets data used by visual editor
          * @see https://nme.babylonjs.com
          */
@@ -131820,9 +131829,10 @@ declare module BABYLON {
          * @param snippetId defines the snippet to load
          * @param scene defines the hosting scene
          * @param rootUrl defines the root URL to use to load textures and relative dependencies
+         * @param nodeMaterial defines a node material to update (instead of creating a new one)
          * @returns a promise that will resolve to the new node material
          */
-        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string): Promise<NodeMaterial>;
+        static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl?: string, nodeMaterial?: NodeMaterial): Promise<NodeMaterial>;
         /**
          * Creates a new node material set to default basic configuration
          * @param name defines the name of the material
@@ -142101,9 +142111,9 @@ declare module BABYLON {
          */
         noMipmap?: boolean | undefined;
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined;
+        invertY: boolean;
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
@@ -142125,7 +142135,7 @@ declare module BABYLON {
          * @param name defines the name of the task
          * @param url defines the location of the file to load
          * @param noMipmap defines if mipmap should not be generated (default is false)
-         * @param invertY defines if texture must be inverted on Y axis (default is false)
+         * @param invertY defines if texture must be inverted on Y axis (default is true)
          * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */
         constructor(
@@ -142142,9 +142152,9 @@ declare module BABYLON {
          */
         noMipmap?: boolean | undefined, 
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        invertY?: boolean | undefined, 
+        invertY?: boolean, 
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */

File diff suppressed because it is too large
+ 7 - 7
dist/preview release/viewer/babylon.viewer.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -1342,6 +1342,7 @@ export class NodeMaterial extends PushMaterial {
      * @param snippetId defines the snippet to load
      * @param scene defines the hosting scene
      * @param rootUrl defines the root URL to use to load textures and relative dependencies
+     * @param nodeMaterial defines a node material to update (instead of creating a new one)
      * @returns a promise that will resolve to the new node material
      */
     public static ParseFromSnippetAsync(snippetId: string, scene: Scene, rootUrl: string = "", nodeMaterial?: NodeMaterial): Promise<NodeMaterial> {

+ 3 - 3
src/Misc/assetsManager.ts

@@ -490,7 +490,7 @@ export class TextureAssetTask extends AbstractAssetTask implements ITextureAsset
      * @param name defines the name of the task
      * @param url defines the location of the file to load
      * @param noMipmap defines if mipmap should not be generated (default is false)
-     * @param invertY defines if texture must be inverted on Y axis (default is false)
+     * @param invertY defines if texture must be inverted on Y axis (default is true)
      * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
      */
     constructor(
@@ -507,9 +507,9 @@ export class TextureAssetTask extends AbstractAssetTask implements ITextureAsset
          */
         public noMipmap?: boolean,
         /**
-         * Defines if texture must be inverted on Y axis (default is false)
+         * Defines if texture must be inverted on Y axis (default is true)
          */
-        public invertY: boolean = false, // note that Texture defaults to true when using its constructor
+        public invertY: boolean = true,
         /**
          * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
          */