Browse Source

Merge remote-tracking branch 'upstream/master'

CHRISTOPHER HAUGEN 8 years ago
parent
commit
f64719f461
29 changed files with 19552 additions and 19201 deletions
  1. 3 3
      Exporters/3ds Max/BabylonExport.Entities/BabylonScene.cs
  2. 1 1
      dist/babylon.d.ts
  3. 3493 3489
      dist/preview release/babylon.d.ts
  4. 28 28
      dist/preview release/babylon.js
  5. 89 13
      dist/preview release/babylon.max.js
  6. 3493 3489
      dist/preview release/babylon.module.d.ts
  7. 28 28
      dist/preview release/babylon.worker.js
  8. 6024 6020
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  9. 19 19
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  10. 117 27
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  11. 6024 6020
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  12. 6 6
      gui/package.json
  13. 4 0
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  14. 9 0
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  15. 27 13
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  16. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  17. 9 0
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  18. 27 13
      dist/preview release/loaders/babylon.glTFFileLoader.js
  19. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  20. 15 2
      loaders/src/glTF/2.0/Extensions/MSFT_lod.ts
  21. 15 11
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  22. 4 0
      loaders/src/glTF/babylon.glTFFileLoader.ts
  23. 14 0
      sandbox/index.js
  24. 1 1
      src/Lights/Shadows/babylon.shadowGenerator.ts
  25. 4 0
      src/Loading/babylon.sceneLoader.ts
  26. 2 2
      src/Materials/Textures/babylon.renderTargetTexture.ts
  27. 2 2
      src/Materials/babylon.material.ts
  28. 4 1
      src/Mesh/babylon.geometry.ts
  29. 86 9
      src/Tools/babylon.filesInput.ts

+ 3 - 3
Exporters/3ds Max/BabylonExport.Entities/BabylonScene.cs

@@ -171,10 +171,10 @@ namespace BabylonExport.Entities
                 LightsList.Add(light);
             }
 
-            cameras = CamerasList.ToArray();
-            lights = LightsList.ToArray();
+            cameras = (CamerasList.Count > 0) ? CamerasList.ToArray() : null;
+            lights = (LightsList.Count > 0) ? LightsList.ToArray() : null;
 
-            if (activeCameraID == null)
+            if (activeCameraID == null && CamerasList.Count > 0)
             {
                 activeCameraID = CamerasList[0].id;
             }

+ 1 - 1
dist/babylon.d.ts

@@ -9169,7 +9169,7 @@ declare module BABYLON {
          * Clones the mesh, used by the class Mesh.
          * Just returns `null` for an AbstractMesh.
          */
-        clone(name: string, newParent: Node, doNotCloneChildren?: boolean): AbstractMesh;
+        clone(name: string, newParent?: Node, doNotCloneChildren?: boolean): AbstractMesh;
         /**
          * Disposes all the mesh submeshes.
          * Returns the AbstractMesh.

File diff suppressed because it is too large
+ 3493 - 3489
dist/preview release/babylon.d.ts


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


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

@@ -24908,7 +24908,7 @@ var BABYLON;
                 var alphaTestState = engine.getAlphaTesting();
                 var clipPlaneState = scene.clipPlane;
                 engine.setAlphaTesting(options ? options.alphaTest : _this.needAlphaTesting());
-                if (options.clipPlane) {
+                if (options && options.clipPlane) {
                     scene.clipPlane = new BABYLON.Plane(0, 0, 0, 1);
                 }
                 if (_this.storeEffectOnSubMeshes) {
@@ -24932,7 +24932,7 @@ var BABYLON;
                     }
                 }
                 engine.setAlphaTesting(alphaTestState);
-                if (options.clipPlane) {
+                if (options && options.clipPlane) {
                     scene.clipPlane = clipPlaneState;
                 }
             };
@@ -27822,6 +27822,7 @@ var BABYLON;
             //Init vertex buffer cache
             this._vertexBuffers = {};
             this._indices = [];
+            this._updatable = updatable;
             // vertexData
             if (vertexData) {
                 this.setAllVerticesData(vertexData, updatable);
@@ -28333,6 +28334,7 @@ var BABYLON;
         Geometry.prototype.serialize = function () {
             var serializationObject = {};
             serializationObject.id = this.id;
+            serializationObject.updatable = this._updatable;
             if (BABYLON.Tags && BABYLON.Tags.HasTags(this)) {
                 serializationObject.tags = BABYLON.Tags.GetTags(this);
             }
@@ -28610,7 +28612,7 @@ var BABYLON;
             if (scene.getGeometryByID(parsedVertexData.id)) {
                 return null; // null since geometry could be something else than a box...
             }
-            var geometry = new Geometry(parsedVertexData.id, scene);
+            var geometry = new Geometry(parsedVertexData.id, scene, null, parsedVertexData.updatable);
             if (BABYLON.Tags) {
                 BABYLON.Tags.AddTagsTo(geometry, parsedVertexData.tags);
             }
@@ -44836,14 +44838,14 @@ var BABYLON;
             var camera;
             if (this.activeCamera) {
                 camera = this.activeCamera;
-                engine.setViewport(this.activeCamera.viewport);
+                engine.setViewport(this.activeCamera.viewport, this._size, this._size);
                 if (this.activeCamera !== scene.activeCamera) {
                     scene.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix(true));
                 }
             }
             else {
                 camera = scene.activeCamera;
-                engine.setViewport(scene.activeCamera.viewport);
+                engine.setViewport(scene.activeCamera.viewport, this._size, this._size);
             }
             // Prepare renderingManager
             this._renderingManager.reset();
@@ -47017,6 +47019,7 @@ var BABYLON;
             var plugin = registeredPlugin.plugin;
             var useArrayBuffer = registeredPlugin.isBinary;
             var database;
+            SceneLoader.OnPluginActivatedObservable.notifyObservers(registeredPlugin.plugin);
             var dataCallback = function (data) {
                 if (scene.isDisposed) {
                     onError("Scene has been disposed");
@@ -47208,6 +47211,7 @@ var BABYLON;
     SceneLoader._ShowLoadingScreen = true;
     SceneLoader._loggingLevel = SceneLoader.NO_LOGGING;
     // Members
+    SceneLoader.OnPluginActivatedObservable = new BABYLON.Observable();
     SceneLoader._registeredPlugins = {};
     BABYLON.SceneLoader = SceneLoader;
     ;
@@ -47819,7 +47823,47 @@ var BABYLON;
             eventDrop.preventDefault();
             this.loadFiles(eventDrop);
         };
+        FilesInput.prototype._handleFolderDrop = function (entry, files, callback) {
+            var reader = entry.createReader(), relativePath = entry.fullPath.replace(/^\//, "").replace(/(.+?)\/?$/, "$1/");
+            reader.readEntries(function (fileEntries) {
+                var remaining = fileEntries.length;
+                for (var _i = 0, fileEntries_1 = fileEntries; _i < fileEntries_1.length; _i++) {
+                    var fileEntry = fileEntries_1[_i];
+                    if (fileEntry.isFile) {
+                        fileEntry.file(function (file) {
+                            file.correctName = relativePath + file.name;
+                            files.push(file);
+                            remaining--;
+                            if (remaining === 0) {
+                                callback();
+                            }
+                        });
+                    }
+                    else {
+                        remaining--;
+                        if (remaining === 0) {
+                            callback();
+                        }
+                    }
+                }
+            });
+        };
+        FilesInput.prototype._processFiles = function (files) {
+            for (var i = 0; i < files.length; i++) {
+                var name = files[i].correctName.toLowerCase();
+                var extension = name.split('.').pop();
+                if ((extension === "babylon" || extension === "stl" || extension === "obj" || extension === "gltf" || extension === "glb")
+                    && name.indexOf(".binary.babylon") === -1 && name.indexOf(".incremental.babylon") === -1) {
+                    this._sceneFileToLoad = files[i];
+                }
+                else {
+                    FilesInput.FilesToLoad[name] = files[i];
+                }
+            }
+            this.reload();
+        };
         FilesInput.prototype.loadFiles = function (event) {
+            var _this = this;
             if (this._startingProcessingFilesCallback)
                 this._startingProcessingFilesCallback();
             // Handling data transfer via drag'n'drop
@@ -47831,19 +47875,51 @@ var BABYLON;
                 this._filesToLoad = event.target.files;
             }
             if (this._filesToLoad && this._filesToLoad.length > 0) {
+                var files_1 = [];
+                var folders = [];
                 for (var i = 0; i < this._filesToLoad.length; i++) {
-                    var name_1 = this._filesToLoad[i].name.toLowerCase();
-                    var extension = name_1.split('.').pop();
-                    var type = this._filesToLoad[i].type;
-                    if ((extension === "babylon" || extension === "stl" || extension === "obj" || extension === "gltf" || extension === "glb")
-                        && name_1.indexOf(".binary.babylon") === -1 && name_1.indexOf(".incremental.babylon") === -1) {
-                        this._sceneFileToLoad = this._filesToLoad[i];
+                    var fileToLoad = this._filesToLoad[i];
+                    var name_1 = fileToLoad.name.toLowerCase();
+                    var type = fileToLoad.type;
+                    var entry = void 0;
+                    fileToLoad.correctName = name_1;
+                    if (event.dataTransfer.items) {
+                        var item = event.dataTransfer.items[i];
+                        if (item.getAsEntry) {
+                            entry = item.getAsEntry();
+                        }
+                        else if (item.webkitGetAsEntry) {
+                            entry = item.webkitGetAsEntry();
+                        }
+                    }
+                    if (!entry) {
+                        files_1.push(fileToLoad);
                     }
                     else {
-                        FilesInput.FilesToLoad[name_1] = this._filesToLoad[i];
+                        if (entry.isDirectory) {
+                            folders.push(entry);
+                        }
+                        else {
+                            files_1.push(fileToLoad);
+                        }
+                    }
+                }
+                if (folders.length === 0) {
+                    this._processFiles(files_1);
+                }
+                else {
+                    var remaining = folders.length;
+                    // Extract folder content
+                    for (var _i = 0, folders_1 = folders; _i < folders_1.length; _i++) {
+                        var folder = folders_1[_i];
+                        this._handleFolderDrop(folder, files_1, function () {
+                            remaining--;
+                            if (remaining === 0) {
+                                _this._processFiles(files_1);
+                            }
+                        });
                     }
                 }
-                this.reload();
             }
         };
         FilesInput.prototype.reload = function () {

File diff suppressed because it is too large
+ 3493 - 3489
dist/preview release/babylon.module.d.ts


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


File diff suppressed because it is too large
+ 6024 - 6020
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


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


+ 117 - 27
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -24908,7 +24908,7 @@ var BABYLON;
                 var alphaTestState = engine.getAlphaTesting();
                 var clipPlaneState = scene.clipPlane;
                 engine.setAlphaTesting(options ? options.alphaTest : _this.needAlphaTesting());
-                if (options.clipPlane) {
+                if (options && options.clipPlane) {
                     scene.clipPlane = new BABYLON.Plane(0, 0, 0, 1);
                 }
                 if (_this.storeEffectOnSubMeshes) {
@@ -24932,7 +24932,7 @@ var BABYLON;
                     }
                 }
                 engine.setAlphaTesting(alphaTestState);
-                if (options.clipPlane) {
+                if (options && options.clipPlane) {
                     scene.clipPlane = clipPlaneState;
                 }
             };
@@ -27822,6 +27822,7 @@ var BABYLON;
             //Init vertex buffer cache
             this._vertexBuffers = {};
             this._indices = [];
+            this._updatable = updatable;
             // vertexData
             if (vertexData) {
                 this.setAllVerticesData(vertexData, updatable);
@@ -28333,6 +28334,7 @@ var BABYLON;
         Geometry.prototype.serialize = function () {
             var serializationObject = {};
             serializationObject.id = this.id;
+            serializationObject.updatable = this._updatable;
             if (BABYLON.Tags && BABYLON.Tags.HasTags(this)) {
                 serializationObject.tags = BABYLON.Tags.GetTags(this);
             }
@@ -28610,7 +28612,7 @@ var BABYLON;
             if (scene.getGeometryByID(parsedVertexData.id)) {
                 return null; // null since geometry could be something else than a box...
             }
-            var geometry = new Geometry(parsedVertexData.id, scene);
+            var geometry = new Geometry(parsedVertexData.id, scene, null, parsedVertexData.updatable);
             if (BABYLON.Tags) {
                 BABYLON.Tags.AddTagsTo(geometry, parsedVertexData.tags);
             }
@@ -32447,14 +32449,14 @@ var BABYLON;
             var camera;
             if (this.activeCamera) {
                 camera = this.activeCamera;
-                engine.setViewport(this.activeCamera.viewport);
+                engine.setViewport(this.activeCamera.viewport, this._size, this._size);
                 if (this.activeCamera !== scene.activeCamera) {
                     scene.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix(true));
                 }
             }
             else {
                 camera = scene.activeCamera;
-                engine.setViewport(scene.activeCamera.viewport);
+                engine.setViewport(scene.activeCamera.viewport, this._size, this._size);
             }
             // Prepare renderingManager
             this._renderingManager.reset();
@@ -34927,7 +34929,7 @@ var BABYLON;
             }
             var checkReady = function () {
                 var subMesh = subMeshes[currentIndex];
-                if (_this.isReady(subMesh, options ? options.useInstances : false)) {
+                if (_this._scene && _this._scene.getEngine() && _this.isReady(subMesh, options ? options.useInstances : false)) {
                     currentIndex++;
                     if (currentIndex >= subMeshes.length) {
                         if (onCompiled) {
@@ -48425,6 +48427,7 @@ var BABYLON;
             var plugin = registeredPlugin.plugin;
             var useArrayBuffer = registeredPlugin.isBinary;
             var database;
+            SceneLoader.OnPluginActivatedObservable.notifyObservers(registeredPlugin.plugin);
             var dataCallback = function (data) {
                 if (scene.isDisposed) {
                     onError("Scene has been disposed");
@@ -48616,6 +48619,7 @@ var BABYLON;
     SceneLoader._ShowLoadingScreen = true;
     SceneLoader._loggingLevel = SceneLoader.NO_LOGGING;
     // Members
+    SceneLoader.OnPluginActivatedObservable = new BABYLON.Observable();
     SceneLoader._registeredPlugins = {};
     BABYLON.SceneLoader = SceneLoader;
     ;
@@ -49227,7 +49231,47 @@ var BABYLON;
             eventDrop.preventDefault();
             this.loadFiles(eventDrop);
         };
+        FilesInput.prototype._handleFolderDrop = function (entry, files, callback) {
+            var reader = entry.createReader(), relativePath = entry.fullPath.replace(/^\//, "").replace(/(.+?)\/?$/, "$1/");
+            reader.readEntries(function (fileEntries) {
+                var remaining = fileEntries.length;
+                for (var _i = 0, fileEntries_1 = fileEntries; _i < fileEntries_1.length; _i++) {
+                    var fileEntry = fileEntries_1[_i];
+                    if (fileEntry.isFile) {
+                        fileEntry.file(function (file) {
+                            file.correctName = relativePath + file.name;
+                            files.push(file);
+                            remaining--;
+                            if (remaining === 0) {
+                                callback();
+                            }
+                        });
+                    }
+                    else {
+                        remaining--;
+                        if (remaining === 0) {
+                            callback();
+                        }
+                    }
+                }
+            });
+        };
+        FilesInput.prototype._processFiles = function (files) {
+            for (var i = 0; i < files.length; i++) {
+                var name = files[i].correctName.toLowerCase();
+                var extension = name.split('.').pop();
+                if ((extension === "babylon" || extension === "stl" || extension === "obj" || extension === "gltf" || extension === "glb")
+                    && name.indexOf(".binary.babylon") === -1 && name.indexOf(".incremental.babylon") === -1) {
+                    this._sceneFileToLoad = files[i];
+                }
+                else {
+                    FilesInput.FilesToLoad[name] = files[i];
+                }
+            }
+            this.reload();
+        };
         FilesInput.prototype.loadFiles = function (event) {
+            var _this = this;
             if (this._startingProcessingFilesCallback)
                 this._startingProcessingFilesCallback();
             // Handling data transfer via drag'n'drop
@@ -49239,19 +49283,51 @@ var BABYLON;
                 this._filesToLoad = event.target.files;
             }
             if (this._filesToLoad && this._filesToLoad.length > 0) {
+                var files_1 = [];
+                var folders = [];
                 for (var i = 0; i < this._filesToLoad.length; i++) {
-                    var name_1 = this._filesToLoad[i].name.toLowerCase();
-                    var extension = name_1.split('.').pop();
-                    var type = this._filesToLoad[i].type;
-                    if ((extension === "babylon" || extension === "stl" || extension === "obj" || extension === "gltf" || extension === "glb")
-                        && name_1.indexOf(".binary.babylon") === -1 && name_1.indexOf(".incremental.babylon") === -1) {
-                        this._sceneFileToLoad = this._filesToLoad[i];
+                    var fileToLoad = this._filesToLoad[i];
+                    var name_1 = fileToLoad.name.toLowerCase();
+                    var type = fileToLoad.type;
+                    var entry = void 0;
+                    fileToLoad.correctName = name_1;
+                    if (event.dataTransfer && event.dataTransfer.items) {
+                        var item = event.dataTransfer.items[i];
+                        if (item.getAsEntry) {
+                            entry = item.getAsEntry();
+                        }
+                        else if (item.webkitGetAsEntry) {
+                            entry = item.webkitGetAsEntry();
+                        }
+                    }
+                    if (!entry) {
+                        files_1.push(fileToLoad);
                     }
                     else {
-                        FilesInput.FilesToLoad[name_1] = this._filesToLoad[i];
+                        if (entry.isDirectory) {
+                            folders.push(entry);
+                        }
+                        else {
+                            files_1.push(fileToLoad);
+                        }
+                    }
+                }
+                if (folders.length === 0) {
+                    this._processFiles(files_1);
+                }
+                else {
+                    var remaining = folders.length;
+                    // Extract folder content
+                    for (var _i = 0, folders_1 = folders; _i < folders_1.length; _i++) {
+                        var folder = folders_1[_i];
+                        this._handleFolderDrop(folder, files_1, function () {
+                            remaining--;
+                            if (remaining === 0) {
+                                _this._processFiles(files_1);
+                            }
+                        });
                     }
                 }
-                this.reload();
             }
         };
         FilesInput.prototype.reload = function () {
@@ -52275,13 +52351,14 @@ var BABYLON;
                                         if (isNew && _this._parent.onMaterialLoaded) {
                                             _this._parent.onMaterialLoaded(babylonMaterial);
                                         }
-                                        // Note: Removing force compilation from loader as this will be delegated to users as they
-                                        // may want to add more options to the material before compiling it
-                                        //this.addPendingData(material);
-                                        //babylonMaterial.forceCompilation(babylonMesh, babylonMaterial => {
-                                        babylonMultiMaterial.subMaterials[i] = babylonMaterial;
-                                        //    this.removePendingData(material);
-                                        //});
+                                        if (_this._parent.onBeforeMaterialReadyAsync) {
+                                            _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, babylonMesh, babylonMultiMaterial.subMaterials[i] != null, function () {
+                                                babylonMultiMaterial.subMaterials[i] = babylonMaterial;
+                                            });
+                                        }
+                                        else {
+                                            babylonMultiMaterial.subMaterials[i] = babylonMaterial;
+                                        }
                                     });
                                 }
                             }
@@ -52716,12 +52793,15 @@ var BABYLON;
                 }
                 this.removeLoaderPendingData(data);
             };
+            GLTFLoader.prototype.addLoaderNonBlockingPendingData = function (data) {
+                if (!this._nonBlockingData) {
+                    this._nonBlockingData = new Array();
+                }
+                this._nonBlockingData.push(data);
+            };
             GLTFLoader.prototype.addLoaderPendingData = function (data) {
                 if (this._blockPendingTracking) {
-                    if (!this._nonBlockingData) {
-                        this._nonBlockingData = new Array();
-                    }
-                    this._nonBlockingData.push(data);
+                    this.addLoaderNonBlockingPendingData(data);
                     return;
                 }
                 this._loaderPendingCount++;
@@ -53094,9 +53174,12 @@ var BABYLON;
                     // Clear out the extension so that it won't get loaded again.
                     material.extensions[this.name] = undefined;
                     // Tell the loader not to clear its state until the highest LOD is loaded.
+                    var materialLODs = [material.index].concat(properties.ids);
                     loader.addLoaderPendingData(material);
+                    for (var index = 0; index < materialLODs.length; index++) {
+                        loader.addLoaderNonBlockingPendingData(index);
+                    }
                     // Start with the lowest quality LOD.
-                    var materialLODs = [material.index].concat(properties.ids);
                     this.loadMaterialLOD(loader, material, materialLODs, materialLODs.length - 1, assign);
                     return true;
                 };
@@ -53108,6 +53191,7 @@ var BABYLON;
                     }
                     loader.loadMaterial(materialLOD, function (babylonMaterial, isNew) {
                         assign(babylonMaterial, isNew);
+                        loader.removeLoaderPendingData(lod);
                         // Loading is considered complete if this is the lowest quality LOD.
                         if (lod === materialLODs.length - 1) {
                             loader.removeLoaderPendingData(material);
@@ -53120,13 +53204,19 @@ var BABYLON;
                         // all active material textures of the current LOD are loaded.
                         loader.executeWhenRenderReady(function () {
                             BABYLON.BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), function () {
-                                _this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                                setTimeout(function () {
+                                    _this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                                }, MSFTLOD.MinimalLODDelay);
                             });
                         });
                     });
                 };
                 return MSFTLOD;
             }(GLTF2.GLTFLoaderExtension));
+            /**
+             * Specify the minimal delay between LODs in ms (default = 250)
+             */
+            MSFTLOD.MinimalLODDelay = 250;
             Extensions.MSFTLOD = MSFTLOD;
             GLTF2.GLTFLoader.RegisterExtension(new MSFTLOD());
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));

File diff suppressed because it is too large
+ 6024 - 6020
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


+ 6 - 6
gui/package.json

@@ -4,20 +4,20 @@
   },
   "name": "babylonjs-gui",
   "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-  "version": "3.1.0-alpha1.1",
+  "version": "3.1.0-alpha1.2",
   "repository": {
     "type": "git",
     "url": "https://github.com/BabylonJS/Babylon.js.git"
   },
-  "main": "../dist/preview release/gui/babylon.gui.js",
+  "main": "babylon.gui.js",
   "files": [
-    "../dist/preview release/gui/babylon.gui.js",
-    "../dist/preview release/gui/babylon.gui.min.js",
-    "../dist/preview release/gui/babylon.gui.d.ts",
+    "babylon.gui.js",
+    "babylon.gui.min.js",
+    "babylon.gui.d.ts",
 
     "package.json"
   ],
-  "typings": "../dist/preview release/gui/babylon.gui.d.ts",
+  "typings": "babylon.gui.d.ts",
   "keywords": [
     "3D",
     "javascript",

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

@@ -22,6 +22,10 @@ declare module BABYLON {
         onTextureLoaded: (texture: BaseTexture) => void;
         onMaterialLoaded: (material: Material) => void;
         /**
+         * Let the user decides if he needs to process the material (like precompilation) before affecting it to meshes
+         */
+        onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
+        /**
          * Raised when all LODs are complete (or if there is no LOD and model is complete)
          */
         onComplete: () => void;

+ 9 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -22,6 +22,10 @@ declare module BABYLON {
         onTextureLoaded: (texture: BaseTexture) => void;
         onMaterialLoaded: (material: Material) => void;
         /**
+         * Let the user decides if he needs to process the material (like precompilation) before affecting it to meshes
+         */
+        onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
+        /**
          * Raised when all LODs are complete (or if there is no LOD and model is complete)
          */
         onComplete: () => void;
@@ -346,6 +350,7 @@ declare module BABYLON.GLTF2 {
         blockPendingTracking: boolean;
         addPendingData(data: any): void;
         removePendingData(data: any): void;
+        addLoaderNonBlockingPendingData(data: any): void;
         addLoaderPendingData(data: any): void;
         removeLoaderPendingData(data: any): void;
         private _getDefaultMaterial();
@@ -400,6 +405,10 @@ declare module BABYLON.GLTF2 {
 
 declare module BABYLON.GLTF2.Extensions {
     class MSFTLOD extends GLTFLoaderExtension {
+        /**
+         * Specify the minimal delay between LODs in ms (default = 250)
+         */
+        static MinimalLODDelay: number;
         readonly name: string;
         protected loadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean;
         private loadMaterialLOD(loader, material, materialLODs, lod, assign);

+ 27 - 13
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -647,13 +647,14 @@ var BABYLON;
                                         if (isNew && _this._parent.onMaterialLoaded) {
                                             _this._parent.onMaterialLoaded(babylonMaterial);
                                         }
-                                        // Note: Removing force compilation from loader as this will be delegated to users as they
-                                        // may want to add more options to the material before compiling it
-                                        //this.addPendingData(material);
-                                        //babylonMaterial.forceCompilation(babylonMesh, babylonMaterial => {
-                                        babylonMultiMaterial.subMaterials[i] = babylonMaterial;
-                                        //    this.removePendingData(material);
-                                        //});
+                                        if (_this._parent.onBeforeMaterialReadyAsync) {
+                                            _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, babylonMesh, babylonMultiMaterial.subMaterials[i] != null, function () {
+                                                babylonMultiMaterial.subMaterials[i] = babylonMaterial;
+                                            });
+                                        }
+                                        else {
+                                            babylonMultiMaterial.subMaterials[i] = babylonMaterial;
+                                        }
                                     });
                                 }
                             }
@@ -1088,12 +1089,15 @@ var BABYLON;
                 }
                 this.removeLoaderPendingData(data);
             };
+            GLTFLoader.prototype.addLoaderNonBlockingPendingData = function (data) {
+                if (!this._nonBlockingData) {
+                    this._nonBlockingData = new Array();
+                }
+                this._nonBlockingData.push(data);
+            };
             GLTFLoader.prototype.addLoaderPendingData = function (data) {
                 if (this._blockPendingTracking) {
-                    if (!this._nonBlockingData) {
-                        this._nonBlockingData = new Array();
-                    }
-                    this._nonBlockingData.push(data);
+                    this.addLoaderNonBlockingPendingData(data);
                     return;
                 }
                 this._loaderPendingCount++;
@@ -1475,9 +1479,12 @@ var BABYLON;
                     // Clear out the extension so that it won't get loaded again.
                     material.extensions[this.name] = undefined;
                     // Tell the loader not to clear its state until the highest LOD is loaded.
+                    var materialLODs = [material.index].concat(properties.ids);
                     loader.addLoaderPendingData(material);
+                    for (var index = 0; index < materialLODs.length; index++) {
+                        loader.addLoaderNonBlockingPendingData(index);
+                    }
                     // Start with the lowest quality LOD.
-                    var materialLODs = [material.index].concat(properties.ids);
                     this.loadMaterialLOD(loader, material, materialLODs, materialLODs.length - 1, assign);
                     return true;
                 };
@@ -1489,6 +1496,7 @@ var BABYLON;
                     }
                     loader.loadMaterial(materialLOD, function (babylonMaterial, isNew) {
                         assign(babylonMaterial, isNew);
+                        loader.removeLoaderPendingData(lod);
                         // Loading is considered complete if this is the lowest quality LOD.
                         if (lod === materialLODs.length - 1) {
                             loader.removeLoaderPendingData(material);
@@ -1501,13 +1509,19 @@ var BABYLON;
                         // all active material textures of the current LOD are loaded.
                         loader.executeWhenRenderReady(function () {
                             BABYLON.BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), function () {
-                                _this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                                setTimeout(function () {
+                                    _this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                                }, MSFTLOD.MinimalLODDelay);
                             });
                         });
                     });
                 };
                 return MSFTLOD;
             }(GLTF2.GLTFLoaderExtension));
+            /**
+             * Specify the minimal delay between LODs in ms (default = 250)
+             */
+            MSFTLOD.MinimalLODDelay = 250;
             Extensions.MSFTLOD = MSFTLOD;
             GLTF2.GLTFLoader.RegisterExtension(new MSFTLOD());
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));

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


+ 9 - 0
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -22,6 +22,10 @@ declare module BABYLON {
         onTextureLoaded: (texture: BaseTexture) => void;
         onMaterialLoaded: (material: Material) => void;
         /**
+         * Let the user decides if he needs to process the material (like precompilation) before affecting it to meshes
+         */
+        onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
+        /**
          * Raised when all LODs are complete (or if there is no LOD and model is complete)
          */
         onComplete: () => void;
@@ -841,6 +845,7 @@ declare module BABYLON.GLTF2 {
         blockPendingTracking: boolean;
         addPendingData(data: any): void;
         removePendingData(data: any): void;
+        addLoaderNonBlockingPendingData(data: any): void;
         addLoaderPendingData(data: any): void;
         removeLoaderPendingData(data: any): void;
         private _getDefaultMaterial();
@@ -895,6 +900,10 @@ declare module BABYLON.GLTF2 {
 
 declare module BABYLON.GLTF2.Extensions {
     class MSFTLOD extends GLTFLoaderExtension {
+        /**
+         * Specify the minimal delay between LODs in ms (default = 250)
+         */
+        static MinimalLODDelay: number;
         readonly name: string;
         protected loadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean;
         private loadMaterialLOD(loader, material, materialLODs, lod, assign);

+ 27 - 13
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -2805,13 +2805,14 @@ var BABYLON;
                                         if (isNew && _this._parent.onMaterialLoaded) {
                                             _this._parent.onMaterialLoaded(babylonMaterial);
                                         }
-                                        // Note: Removing force compilation from loader as this will be delegated to users as they
-                                        // may want to add more options to the material before compiling it
-                                        //this.addPendingData(material);
-                                        //babylonMaterial.forceCompilation(babylonMesh, babylonMaterial => {
-                                        babylonMultiMaterial.subMaterials[i] = babylonMaterial;
-                                        //    this.removePendingData(material);
-                                        //});
+                                        if (_this._parent.onBeforeMaterialReadyAsync) {
+                                            _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, babylonMesh, babylonMultiMaterial.subMaterials[i] != null, function () {
+                                                babylonMultiMaterial.subMaterials[i] = babylonMaterial;
+                                            });
+                                        }
+                                        else {
+                                            babylonMultiMaterial.subMaterials[i] = babylonMaterial;
+                                        }
                                     });
                                 }
                             }
@@ -3246,12 +3247,15 @@ var BABYLON;
                 }
                 this.removeLoaderPendingData(data);
             };
+            GLTFLoader.prototype.addLoaderNonBlockingPendingData = function (data) {
+                if (!this._nonBlockingData) {
+                    this._nonBlockingData = new Array();
+                }
+                this._nonBlockingData.push(data);
+            };
             GLTFLoader.prototype.addLoaderPendingData = function (data) {
                 if (this._blockPendingTracking) {
-                    if (!this._nonBlockingData) {
-                        this._nonBlockingData = new Array();
-                    }
-                    this._nonBlockingData.push(data);
+                    this.addLoaderNonBlockingPendingData(data);
                     return;
                 }
                 this._loaderPendingCount++;
@@ -3633,9 +3637,12 @@ var BABYLON;
                     // Clear out the extension so that it won't get loaded again.
                     material.extensions[this.name] = undefined;
                     // Tell the loader not to clear its state until the highest LOD is loaded.
+                    var materialLODs = [material.index].concat(properties.ids);
                     loader.addLoaderPendingData(material);
+                    for (var index = 0; index < materialLODs.length; index++) {
+                        loader.addLoaderNonBlockingPendingData(index);
+                    }
                     // Start with the lowest quality LOD.
-                    var materialLODs = [material.index].concat(properties.ids);
                     this.loadMaterialLOD(loader, material, materialLODs, materialLODs.length - 1, assign);
                     return true;
                 };
@@ -3647,6 +3654,7 @@ var BABYLON;
                     }
                     loader.loadMaterial(materialLOD, function (babylonMaterial, isNew) {
                         assign(babylonMaterial, isNew);
+                        loader.removeLoaderPendingData(lod);
                         // Loading is considered complete if this is the lowest quality LOD.
                         if (lod === materialLODs.length - 1) {
                             loader.removeLoaderPendingData(material);
@@ -3659,13 +3667,19 @@ var BABYLON;
                         // all active material textures of the current LOD are loaded.
                         loader.executeWhenRenderReady(function () {
                             BABYLON.BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), function () {
-                                _this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                                setTimeout(function () {
+                                    _this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                                }, MSFTLOD.MinimalLODDelay);
                             });
                         });
                     });
                 };
                 return MSFTLOD;
             }(GLTF2.GLTFLoaderExtension));
+            /**
+             * Specify the minimal delay between LODs in ms (default = 250)
+             */
+            MSFTLOD.MinimalLODDelay = 250;
             Extensions.MSFTLOD = MSFTLOD;
             GLTF2.GLTFLoader.RegisterExtension(new MSFTLOD());
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));

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


+ 15 - 2
loaders/src/glTF/2.0/Extensions/MSFT_lod.ts

@@ -6,6 +6,11 @@ module BABYLON.GLTF2.Extensions {
     }
 
     export class MSFTLOD extends GLTFLoaderExtension {
+        /**
+         * Specify the minimal delay between LODs in ms (default = 250)
+         */
+        public static MinimalLODDelay = 250;
+
         public get name() {
             return "MSFT_lod";
         }
@@ -24,10 +29,14 @@ module BABYLON.GLTF2.Extensions {
             material.extensions[this.name] = undefined;
 
             // Tell the loader not to clear its state until the highest LOD is loaded.
+            var materialLODs = [material.index, ...properties.ids];
+
             loader.addLoaderPendingData(material);
+            for (var index = 0; index < materialLODs.length; index++) {
+                loader.addLoaderNonBlockingPendingData(index);
+            }
 
             // Start with the lowest quality LOD.
-            var materialLODs = [material.index, ...properties.ids];
             this.loadMaterialLOD(loader, material, materialLODs, materialLODs.length - 1, assign);
 
             return true;
@@ -43,6 +52,8 @@ module BABYLON.GLTF2.Extensions {
             loader.loadMaterial(materialLOD, (babylonMaterial, isNew) => {
                 assign(babylonMaterial, isNew);
 
+                loader.removeLoaderPendingData(lod);
+
                 // Loading is considered complete if this is the lowest quality LOD.
                 if (lod === materialLODs.length - 1) {
                     loader.removeLoaderPendingData(material);
@@ -57,7 +68,9 @@ module BABYLON.GLTF2.Extensions {
                 // all active material textures of the current LOD are loaded.
                 loader.executeWhenRenderReady(() => {
                     BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), () => {
-                        this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                        setTimeout(()=> {
+                            this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                        }, MSFTLOD.MinimalLODDelay);
                     });
                 });
             });

+ 15 - 11
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -412,14 +412,14 @@ module BABYLON.GLTF2 {
                                     if (isNew && this._parent.onMaterialLoaded) {
                                         this._parent.onMaterialLoaded(babylonMaterial);
                                     }
-
-                                    // Note: Removing force compilation from loader as this will be delegated to users as they
-                                    // may want to add more options to the material before compiling it
-                                    //this.addPendingData(material);
-                                    //babylonMaterial.forceCompilation(babylonMesh, babylonMaterial => {
+                                    
+                                    if (this._parent.onBeforeMaterialReadyAsync) {
+                                        this._parent.onBeforeMaterialReadyAsync(babylonMaterial, babylonMesh, babylonMultiMaterial.subMaterials[i] != null, () => {
+                                            babylonMultiMaterial.subMaterials[i] = babylonMaterial;
+                                        });
+                                    } else {
                                         babylonMultiMaterial.subMaterials[i] = babylonMaterial;
-                                    //    this.removePendingData(material);
-                                    //});
+                                    }
                                 });
                             }
                         }
@@ -884,12 +884,16 @@ module BABYLON.GLTF2 {
             this.removeLoaderPendingData(data);
         }
 
+        public addLoaderNonBlockingPendingData(data: any): void {
+            if (!this._nonBlockingData) {
+                this._nonBlockingData = new Array<any>();
+            }
+            this._nonBlockingData.push(data);
+        }
+
         public addLoaderPendingData(data: any) {
             if (this._blockPendingTracking) {
-                if (!this._nonBlockingData) {
-                    this._nonBlockingData = new Array<any>();
-                }
-                this._nonBlockingData.push(data);
+                this.addLoaderNonBlockingPendingData(data);
                 return;
             }            
             this._loaderPendingCount++;

+ 4 - 0
loaders/src/glTF/babylon.glTFFileLoader.ts

@@ -36,6 +36,10 @@ module BABYLON {
         public onTextureLoaded: (texture: BaseTexture) => void;
         public onMaterialLoaded: (material: Material) => void;
         /**
+         * Let the user decides if he needs to process the material (like precompilation) before affecting it to meshes
+         */
+        public onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
+        /**
          * Raised when all LODs are complete (or if there is no LOD and model is complete)
          */
         public onComplete: () => void;

+ 14 - 0
sandbox/index.js

@@ -22,6 +22,20 @@
 
     if (!currentHelpCounter) currentHelpCounter = 0;
 
+    // Setting up some GLTF values
+    BABYLON.SceneLoader.OnPluginActivatedObservable.add(function(plugin) {
+        if (plugin.name !== "gltf") {
+            return;
+        }
+        plugin.onBeforeMaterialReadyAsync = function(material, mesh, isLOD, callback) {
+            if (!isLOD) {
+                callback();
+                return;
+            }
+            material.forceCompilation(mesh, callback);
+        }
+    });
+
     // Resize
     window.addEventListener("resize", function () {
         engine.resize();

+ 1 - 1
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -528,7 +528,7 @@
             var checkReady = () => {
                 let subMesh = subMeshes[currentIndex];
 
-                if (this.isReady(subMesh, options ? options.useInstances : false)) {
+                if (this._scene && this._scene.getEngine() && this.isReady(subMesh, options ? options.useInstances : false)) {
                     currentIndex++;
                     if (currentIndex >= subMeshes.length) {
                         if (onCompiled) {

+ 4 - 0
src/Loading/babylon.sceneLoader.ts

@@ -74,6 +74,8 @@
         }
 
         // Members
+        public static OnPluginActivatedObservable = new Observable<ISceneLoaderPlugin | ISceneLoaderPluginAsync>();
+
         private static _registeredPlugins: { [extension: string]: IRegisteredPlugin } = {};
 
         private static _getDefaultPlugin(): IRegisteredPlugin {
@@ -134,6 +136,8 @@
             var useArrayBuffer = registeredPlugin.isBinary;
             var database: Database;
 
+            SceneLoader.OnPluginActivatedObservable.notifyObservers(registeredPlugin.plugin);
+
             var dataCallback = data => {
                 if (scene.isDisposed) {
                     onError("Scene has been disposed");

+ 2 - 2
src/Materials/Textures/babylon.renderTargetTexture.ts

@@ -327,7 +327,7 @@
             let camera: Camera;
             if (this.activeCamera) {
                 camera = this.activeCamera;
-                engine.setViewport(this.activeCamera.viewport);
+                engine.setViewport(this.activeCamera.viewport, this._size, this._size);
 
                 if (this.activeCamera !== scene.activeCamera)
                 {
@@ -336,7 +336,7 @@
             }
             else {
                 camera = scene.activeCamera;
-                engine.setViewport(scene.activeCamera.viewport);
+                engine.setViewport(scene.activeCamera.viewport, this._size, this._size);
             }
 
             // Prepare renderingManager

+ 2 - 2
src/Materials/babylon.material.ts

@@ -534,7 +534,7 @@
 
                 engine.setAlphaTesting(options ? options.alphaTest : this.needAlphaTesting());
 
-                if (options.clipPlane) {
+                if (options && options.clipPlane) {
                     scene.clipPlane = new Plane(0, 0, 0, 1);
                 }
 
@@ -560,7 +560,7 @@
 
                 engine.setAlphaTesting(alphaTestState);
 
-                if (options.clipPlane) {
+                if (options && options.clipPlane) {
                     scene.clipPlane = clipPlaneState;
                 }
             };

+ 4 - 1
src/Mesh/babylon.geometry.ts

@@ -22,6 +22,7 @@
         public _delayLoadingFunction: (any: any, geometry: Geometry) => void;
         public _softwareSkinningRenderId: number;
         private _vertexArrayObjects: { [key: string]: WebGLVertexArrayObject; };
+        private _updatable: boolean;
 
         // Cache
         public _positions: Vector3[];
@@ -52,6 +53,7 @@
             //Init vertex buffer cache
             this._vertexBuffers = {};
             this._indices = [];
+            this._updatable = updatable;
 
             // vertexData
             if (vertexData) {
@@ -654,6 +656,7 @@
             var serializationObject: any = {};
 
             serializationObject.id = this.id;
+            serializationObject.updatable = this._updatable;
 
             if (Tags && Tags.HasTags(this)) {
                 serializationObject.tags = Tags.GetTags(this);
@@ -993,7 +996,7 @@
                 return null; // null since geometry could be something else than a box...
             }
 
-            var geometry = new Geometry(parsedVertexData.id, scene);
+            var geometry = new Geometry(parsedVertexData.id, scene, null, parsedVertexData.updatable);
 
             if (Tags) {
                 Tags.AddTagsTo(geometry, parsedVertexData.tags);

+ 86 - 9
src/Tools/babylon.filesInput.ts

@@ -66,6 +66,51 @@
             this.loadFiles(eventDrop);
         }
 
+        private _handleFolderDrop(entry: any, files: Array<any>, callback: () => void): void {
+            var reader = entry.createReader(),
+ 			relativePath = entry.fullPath.replace(/^\//, "").replace(/(.+?)\/?$/, "$1/");
+ 			reader.readEntries((fileEntries) => {
+                var remaining = fileEntries.length;
+                for (let fileEntry of fileEntries) {
+                    if (fileEntry.isFile) { // We only support one level
+                        fileEntry.file(function(file) {
+                            file.correctName = relativePath + file.name;
+                            files.push(file);
+            
+                            remaining--;
+
+                            if (remaining === 0) {
+                                callback();
+                            }
+                        });
+                    } else {
+                        remaining--;
+
+                        if (remaining === 0) {
+                            callback();
+                        }
+                    }
+                }
+            });
+        }
+
+        private _processFiles(files: Array<any>): void {
+            for (var i = 0; i < files.length; i++) {
+                var name = files[i].correctName.toLowerCase();
+                var extension = name.split('.').pop();
+                
+                if ((extension === "babylon" || extension === "stl" || extension === "obj" || extension === "gltf" || extension === "glb") 
+                    && name.indexOf(".binary.babylon") === -1 && name.indexOf(".incremental.babylon") === -1) {
+                    this._sceneFileToLoad = files[i];
+                }
+                else {
+                    FilesInput.FilesToLoad[name] = files[i];
+                }
+            }
+
+            this.reload();
+        }
+
         public loadFiles(event): void {
             if (this._startingProcessingFilesCallback) this._startingProcessingFilesCallback();
 
@@ -80,21 +125,53 @@
             }
 
             if (this._filesToLoad && this._filesToLoad.length > 0) {
+        
+                let files = [];
+                let folders = [];
                 for (var i = 0; i < this._filesToLoad.length; i++) {
-                    let name = this._filesToLoad[i].name.toLowerCase();
-                    let extension = name.split('.').pop();
-                    let type = this._filesToLoad[i].type;
+                    let fileToLoad:any =  this._filesToLoad[i];
+                    let name = fileToLoad.name.toLowerCase();
+                    let type = fileToLoad.type;
+                    let entry;
+
+                    fileToLoad.correctName = name;
                     
-                    if ((extension === "babylon" || extension === "stl" || extension === "obj" || extension === "gltf" || extension === "glb") 
-                        && name.indexOf(".binary.babylon") === -1 && name.indexOf(".incremental.babylon") === -1) {
-                        this._sceneFileToLoad = this._filesToLoad[i];
+                    if (event.dataTransfer && event.dataTransfer.items) {
+                        let item = event.dataTransfer.items[i];
+                        if (item.getAsEntry) {
+                            entry = item.getAsEntry();
+                        } else if (item.webkitGetAsEntry) {
+                            entry = item.webkitGetAsEntry();
+                        }                     
                     }
-                    else {
-                        FilesInput.FilesToLoad[name] = this._filesToLoad[i];
+
+                    if (!entry) {    
+                        files.push(fileToLoad);
+                    } else {
+                        if (entry.isDirectory) {
+                            folders.push(entry);
+                        } else {
+                            files.push(fileToLoad);
+                        }
                     }
                 }
 
-                this.reload();
+                if (folders.length === 0) {
+                    this._processFiles(files);
+                } else {
+                    var remaining = folders.length;
+
+                    // Extract folder content
+                    for (var folder of folders) {
+                        this._handleFolderDrop(folder, files, () => {
+                            remaining--;
+
+                            if (remaining === 0) {
+                                this._processFiles(files);
+                            }
+                        });
+                    }
+                }
             }
         }