浏览代码

"Let me here, I slow you down" - step 7

David Catuhe 7 年之前
父节点
当前提交
01a11b0a4d
共有 32 个文件被更改,包括 22981 次插入22520 次删除
  1. 6479 6478
      dist/preview release/babylon.d.ts
  2. 36 36
      dist/preview release/babylon.js
  3. 246 103
      dist/preview release/babylon.max.js
  4. 6479 6478
      dist/preview release/babylon.module.d.ts
  5. 36 36
      dist/preview release/babylon.worker.js
  6. 4502 4501
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 36 36
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 246 103
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 4502 4501
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  10. 2 2
      src/Collisions/babylon.pickingInfo.ts
  11. 16 9
      src/Engine/babylon.engine.ts
  12. 3 3
      src/Engine/babylon.nullEngine.ts
  13. 65 37
      src/Materials/Textures/babylon.hdrCubeTexture.ts
  14. 17 16
      src/Materials/babylon.material.ts
  15. 11 7
      src/Materials/babylon.materialHelper.ts
  16. 19 13
      src/Materials/babylon.multiMaterial.ts
  17. 8 4
      src/Materials/babylon.shaderMaterial.ts
  18. 2 2
      src/Materials/babylon.uniformBuffer.ts
  19. 4 4
      src/Math/babylon.math.ts
  20. 9 9
      src/Mesh/babylon.abstractMesh.ts
  21. 5 5
      src/Mesh/babylon.buffer.ts
  22. 14 10
      src/Mesh/babylon.geometry.ts
  23. 5 5
      src/Mesh/babylon.instancedMesh.ts
  24. 5 3
      src/Mesh/babylon.linesMesh.ts
  25. 53 21
      src/Mesh/babylon.mesh.ts
  26. 20 20
      src/Mesh/babylon.mesh.vertexData.ts
  27. 2 2
      src/Mesh/babylon.meshBuilder.ts
  28. 5 5
      src/Mesh/babylon.vertexBuffer.ts
  29. 132 52
      src/Physics/babylon.physicsImpostor.ts
  30. 8 8
      src/Tools/babylon.dds.ts
  31. 11 10
      src/Tools/babylon.tools.ts
  32. 3 1
      src/babylon.types.ts

文件差异内容过多而无法显示
+ 6479 - 6478
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 36 - 36
dist/preview release/babylon.js


+ 246 - 103
dist/preview release/babylon.max.js

@@ -6108,7 +6108,7 @@ var BABYLON;
         Tools.LoadFile = function (url, callback, progressCallBack, database, useArrayBuffer, onError) {
             url = Tools.CleanUrl(url);
             url = Tools.PreprocessUrl(url);
-            var request;
+            var request = null;
             var noIndexedDB = function () {
                 request = new XMLHttpRequest();
                 var loadUrl = Tools.BaseUrl + url;
@@ -6120,16 +6120,17 @@ var BABYLON;
                     request.onprogress = progressCallBack;
                 }
                 request.onreadystatechange = function () {
+                    var req = request;
                     // In case of undefined state in some browsers.
-                    if (request.readyState === (XMLHttpRequest.DONE || 4)) {
-                        request.onreadystatechange = function () { }; //some browsers have issues where onreadystatechange can be called multiple times with the same value
-                        if (request.status >= 200 && request.status < 300 || (!Tools.IsWindowObjectExist() && (request.status === 0))) {
-                            callback(!useArrayBuffer ? request.responseText : request.response);
+                    if (req.readyState === (XMLHttpRequest.DONE || 4)) {
+                        req.onreadystatechange = function () { }; //some browsers have issues where onreadystatechange can be called multiple times with the same value
+                        if (req.status >= 200 && req.status < 300 || (!Tools.IsWindowObjectExist() && (req.status === 0))) {
+                            callback(!useArrayBuffer ? req.responseText : req.response);
                         }
                         else {
-                            var e = new Error("Error status: " + request.status + " - Unable to load " + loadUrl);
+                            var e = new Error("Error status: " + req.status + " - Unable to load " + loadUrl);
                             if (onError) {
-                                onError(request, e);
+                                onError(req, e);
                             }
                             else {
                                 throw e;
@@ -9780,6 +9781,9 @@ var BABYLON;
             return results;
         };
         Engine.prototype.enableEffect = function (effect) {
+            if (!effect) {
+                return;
+            }
             // Use program
             this.setProgram(effect.getProgram());
             this._currentEffect = effect;
@@ -11062,6 +11066,9 @@ var BABYLON;
             var internalCallback = function (data) {
                 var width = texture.width;
                 var faceDataArrays = callback(data);
+                if (!faceDataArrays) {
+                    return;
+                }
                 if (mipmmapGenerator) {
                     var textureType = _this._getWebGLTextureType(type);
                     var internalFormat = _this._getInternalFormat(format);
@@ -22182,7 +22189,16 @@ var BABYLON;
                 }
             }
             if (fullDetails) {
-                ret += ", flat shading: " + (this._geometry ? (this.getVerticesData(BABYLON.VertexBuffer.PositionKind).length / 3 === this.getIndices().length ? "YES" : "NO") : "UNKNOWN");
+                if (this._geometry) {
+                    var ib = this.getIndices();
+                    var vb = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
+                    if (vb && ib) {
+                        ret += ", flat shading: " + (vb.length / 3 === ib.length ? "YES" : "NO");
+                    }
+                }
+                else {
+                    ret += ", flat shading: UNKNOWN";
+                }
             }
             return ret;
         };
@@ -22269,7 +22285,18 @@ var BABYLON;
             if (!this._LODLevels || this._LODLevels.length === 0) {
                 return this;
             }
-            var distanceToCamera = (boundingSphere ? boundingSphere : this.getBoundingInfo().boundingSphere).centerWorld.subtract(camera.globalPosition).length();
+            var bSphere;
+            if (boundingSphere) {
+                bSphere = boundingSphere;
+            }
+            else {
+                var boundingInfo = this.getBoundingInfo();
+                if (!boundingInfo) {
+                    return this;
+                }
+                bSphere = boundingInfo.boundingSphere;
+            }
+            var distanceToCamera = bSphere.centerWorld.subtract(camera.globalPosition).length();
             if (this._LODLevels[this._LODLevels.length - 1].distance > distanceToCamera) {
                 if (this.onLODLevelSelection) {
                     this.onLODLevelSelection(distanceToCamera, this, this._LODLevels[this._LODLevels.length - 1].mesh);
@@ -22340,7 +22367,7 @@ var BABYLON;
         };
         /**
          * Returns the mesh VertexBuffer object from the requested `kind` : positions, indices, normals, etc.
-         * Returns `undefined` if the mesh has no geometry.
+         * Returns `null` if the mesh has no geometry.
          * Possible `kind` values :
          * - BABYLON.VertexBuffer.PositionKind
          * - BABYLON.VertexBuffer.UVKind
@@ -22357,7 +22384,7 @@ var BABYLON;
          */
         Mesh.prototype.getVertexBuffer = function (kind) {
             if (!this._geometry) {
-                return undefined;
+                return null;
             }
             return this._geometry.getVertexBuffer(kind);
         };
@@ -22526,7 +22553,7 @@ var BABYLON;
          * Returns the Mesh.
          */
         Mesh.prototype.refreshBoundingInfo = function () {
-            if (this._boundingInfo.isLocked) {
+            if (this._boundingInfo && this._boundingInfo.isLocked) {
                 return this;
             }
             var data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
@@ -22549,7 +22576,11 @@ var BABYLON;
             }
             // Check if we need to recreate the submeshes
             if (this.subMeshes && this.subMeshes.length > 0) {
-                var totalIndices = this.getIndices().length;
+                var ib = this.getIndices();
+                if (!ib) {
+                    return null;
+                }
+                var totalIndices = ib.length;
                 var needToRecreate = false;
                 if (force) {
                     needToRecreate = true;
@@ -22635,7 +22666,8 @@ var BABYLON;
         };
         Mesh.prototype.markVerticesDataAsUpdatable = function (kind, updatable) {
             if (updatable === void 0) { updatable = true; }
-            if (this.getVertexBuffer(kind).isUpdatable() === updatable) {
+            var vb = this.getVertexBuffer(kind);
+            if (!vb || vb.isUpdatable() === updatable) {
                 return;
             }
             this.setVerticesData(kind, this.getVerticesData(kind), updatable);
@@ -25977,7 +26009,7 @@ var BABYLON;
                 defines["VERTEXALPHA"] = mesh.hasVertexAlpha;
             }
             if (useBones) {
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                     defines["NUM_BONE_INFLUENCERS"] = mesh.numBoneInfluencers;
                     defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
                 }
@@ -26099,7 +26131,8 @@ var BABYLON;
         };
         MaterialHelper.PrepareUniformsAndSamplersList = function (uniformsListOrOptions, samplersList, defines, maxSimultaneousLights) {
             if (maxSimultaneousLights === void 0) { maxSimultaneousLights = 4; }
-            var uniformsList, uniformBuffersList, samplersList, defines;
+            var uniformsList;
+            var uniformBuffersList = null;
             if (uniformsListOrOptions.uniformsNames) {
                 var options = uniformsListOrOptions;
                 uniformsList = options.uniformsNames;
@@ -26110,6 +26143,9 @@ var BABYLON;
             }
             else {
                 uniformsList = uniformsListOrOptions;
+                if (!samplersList) {
+                    samplersList = [];
+                }
             }
             for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
                 if (!defines["LIGHT" + lightIndex]) {
@@ -26150,7 +26186,7 @@ var BABYLON;
         };
         MaterialHelper.PrepareAttributesForMorphTargets = function (attribs, mesh, defines) {
             var influencers = defines["NUM_MORPH_INFLUENCERS"];
-            if (influencers > 0) {
+            if (influencers > 0 && BABYLON.Engine.LastCreatedEngine) {
                 var maxAttributesCount = BABYLON.Engine.LastCreatedEngine.getCaps().maxVertexAttribs;
                 var manager = mesh.morphTargetManager;
                 var normal = manager.supportsNormals && defines["NORMAL"];
@@ -26232,9 +26268,9 @@ var BABYLON;
             }
         };
         MaterialHelper.BindBonesParameters = function (mesh, effect) {
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                 var matrices = mesh.skeleton.getTransformMatrices(mesh);
-                if (matrices) {
+                if (matrices && effect) {
                     effect.setMatrices("mBones", matrices);
                 }
             }
@@ -26719,7 +26755,9 @@ var BABYLON;
             else {
                 this._scene._cachedVisibility = 1;
             }
-            this.onBindObservable.notifyObservers(mesh);
+            if (mesh) {
+                this.onBindObservable.notifyObservers(mesh);
+            }
             if (this.disableDepthWrite) {
                 var engine = this._scene.getEngine();
                 this._cachedDepthWriteState = engine.getDepthWrite();
@@ -26868,11 +26906,14 @@ var BABYLON;
                 if (mesh.material === this) {
                     mesh.material = null;
                     if (mesh.geometry) {
-                        var geometry = mesh.geometry;
+                        var geometry = (mesh.geometry);
                         if (this.storeEffectOnSubMeshes) {
                             for (var _i = 0, _a = mesh.subMeshes; _i < _a.length; _i++) {
                                 var subMesh = _a[_i];
                                 geometry._releaseVertexArrayObject(subMesh._materialEffect);
+                                if (forceDisposeEffect && subMesh._materialEffect) {
+                                    this._scene.getEngine()._releaseEffect(subMesh._materialEffect);
+                                }
                             }
                         }
                         else {
@@ -26884,13 +26925,7 @@ var BABYLON;
             this._uniformBuffer.dispose();
             // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
             if (forceDisposeEffect && this._effect) {
-                if (this.storeEffectOnSubMeshes) {
-                    for (var _b = 0, _c = mesh.subMeshes; _b < _c.length; _b++) {
-                        var subMesh = _c[_b];
-                        this._scene.getEngine()._releaseEffect(subMesh._materialEffect);
-                    }
-                }
-                else {
+                if (!this.storeEffectOnSubMeshes) {
                     this._scene.getEngine()._releaseEffect(this._effect);
                 }
                 this._effect = null;
@@ -29886,6 +29921,9 @@ var BABYLON;
             }
         };
         Geometry.prototype._bind = function (effect, indexToBind) {
+            if (!effect) {
+                return;
+            }
             if (indexToBind === undefined) {
                 indexToBind = this._indexBuffer;
             }
@@ -30033,6 +30071,7 @@ var BABYLON;
             return this._indexBuffer;
         };
         Geometry.prototype._releaseVertexArrayObject = function (effect) {
+            if (effect === void 0) { effect = null; }
             if (!effect || !this._vertexArrayObjects) {
                 return;
             }
@@ -45883,10 +45922,12 @@ var BABYLON;
             configurable: true
         });
         LinesMesh.prototype.createInstance = function (name) {
-            BABYLON.Tools.Log("LinesMeshes do not support createInstance.");
-            return null;
+            throw new Error("LinesMeshes do not support createInstance.");
         };
         LinesMesh.prototype._bind = function (subMesh, effect, fillMode) {
+            if (!this._geometry) {
+                return this;
+            }
             // VBOs
             this._geometry._bind(this._colorShader.getEffect());
             // Color
@@ -46083,7 +46124,7 @@ var BABYLON;
                 defines.push("#define VERTEXCOLOR");
             }
             // Bones
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                 attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                 attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
                 if (mesh.numBoneInfluencers > 4) {
@@ -46133,6 +46174,9 @@ var BABYLON;
         };
         ShaderMaterial.prototype.bindOnlyWorldMatrix = function (world) {
             var scene = this.getScene();
+            if (!this._effect) {
+                return;
+            }
             if (this._options.uniforms.indexOf("world") !== -1) {
                 this._effect.setMatrix("world", world);
             }
@@ -46147,7 +46191,7 @@ var BABYLON;
         ShaderMaterial.prototype.bind = function (world, mesh) {
             // Std values
             this.bindOnlyWorldMatrix(world);
-            if (this.getScene().getCachedMaterial() !== this) {
+            if (this._effect && this.getScene().getCachedMaterial() !== this) {
                 if (this._options.uniforms.indexOf("view") !== -1) {
                     this._effect.setMatrix("view", this.getScene().getViewMatrix());
                 }
@@ -46297,9 +46341,9 @@ var BABYLON;
                 serializationObject.floats[name] = this._floats[name];
             }
             // Float s   
-            serializationObject.floatArrays = {};
+            serializationObject.FloatArrays = {};
             for (name in this._floatsArrays) {
-                serializationObject.floatArrays[name] = this._floatsArrays[name];
+                serializationObject.FloatArrays[name] = this._floatsArrays[name];
             }
             // Color3    
             serializationObject.colors3 = {};
@@ -53503,7 +53547,14 @@ var BABYLON;
             return this.subMaterials[index];
         };
         MultiMaterial.prototype.getActiveTextures = function () {
-            return (_a = _super.prototype.getActiveTextures.call(this)).concat.apply(_a, this.subMaterials.map(function (subMaterial) { return subMaterial.getActiveTextures(); }));
+            return (_a = _super.prototype.getActiveTextures.call(this)).concat.apply(_a, this.subMaterials.map(function (subMaterial) {
+                if (subMaterial) {
+                    return subMaterial.getActiveTextures();
+                }
+                else {
+                    return [];
+                }
+            }));
             var _a;
         };
         // Methods
@@ -53514,13 +53565,13 @@ var BABYLON;
             for (var index = 0; index < this.subMaterials.length; index++) {
                 var subMaterial = this.subMaterials[index];
                 if (subMaterial) {
-                    if (this.subMaterials[index].storeEffectOnSubMeshes) {
-                        if (!this.subMaterials[index].isReadyForSubMesh(mesh, subMesh, useInstances)) {
+                    if (subMaterial.storeEffectOnSubMeshes) {
+                        if (!subMaterial.isReadyForSubMesh(mesh, subMesh, useInstances)) {
                             return false;
                         }
                         continue;
                     }
-                    if (!this.subMaterials[index].isReady(mesh)) {
+                    if (!subMaterial.isReady(mesh)) {
                         return false;
                     }
                 }
@@ -53531,8 +53582,9 @@ var BABYLON;
             var newMultiMaterial = new MultiMaterial(name, this.getScene());
             for (var index = 0; index < this.subMaterials.length; index++) {
                 var subMaterial = null;
-                if (cloneChildren) {
-                    subMaterial = this.subMaterials[index].clone(name + "-" + this.subMaterials[index].name);
+                var current = this.subMaterials[index];
+                if (cloneChildren && current) {
+                    subMaterial = current.clone(name + "-" + current.name);
                 }
                 else {
                     subMaterial = this.subMaterials[index];
@@ -62568,22 +62620,22 @@ var BABYLON;
             _this._onLoad = onLoad;
             _this._onError = onError;
             _this.gammaSpace = false;
+            var caps = scene.getEngine().getCaps();
             if (size) {
                 _this._isBABYLONPreprocessed = false;
                 _this._noMipmap = noMipmap;
                 _this._size = size;
                 _this._useInGammaSpace = useInGammaSpace;
                 _this._usePMREMGenerator = usePMREMGenerator &&
-                    scene.getEngine().getCaps().textureLOD &&
-                    _this.getScene().getEngine().getCaps().textureFloat &&
+                    caps.textureLOD &&
+                    caps.textureFloat &&
                     !_this._useInGammaSpace;
             }
             else {
                 _this._isBABYLONPreprocessed = true;
                 _this._noMipmap = false;
                 _this._useInGammaSpace = false;
-                _this._usePMREMGenerator = scene.getEngine().getCaps().textureLOD &&
-                    _this.getScene().getEngine().getCaps().textureFloat &&
+                _this._usePMREMGenerator = caps.textureLOD && caps.textureFloat &&
                     !_this._useInGammaSpace;
             }
             _this.isPMREM = _this._usePMREMGenerator;
@@ -62621,8 +62673,12 @@ var BABYLON;
             var _this = this;
             var mipLevels = 0;
             var floatArrayView = null;
-            var mipmapGenerator = (!this._useInGammaSpace && this.getScene().getEngine().getCaps().textureFloat) ? function (data) {
+            var scene = this.getScene();
+            var mipmapGenerator = (!this._useInGammaSpace && scene && scene.getEngine().getCaps().textureFloat) ? function (data) {
                 var mips = new Array();
+                if (!floatArrayView) {
+                    return mips;
+                }
                 var startIndex = 30;
                 for (var level = 0; level < mipLevels; level++) {
                     mips.push([]);
@@ -62637,6 +62693,10 @@ var BABYLON;
                 return mips;
             } : null;
             var callback = function (buffer) {
+                var scene = _this.getScene();
+                if (!scene) {
+                    return null;
+                }
                 // Create Native Array Views
                 var intArrayView = new Int32Array(buffer);
                 floatArrayView = new Float32Array(buffer);
@@ -62644,6 +62704,9 @@ var BABYLON;
                 var version = intArrayView[0]; // Version 1. (MAy be use in case of format changes for backward compaibility)
                 _this._size = intArrayView[1]; // CubeMap max mip face size.
                 // Update Texture Information.
+                if (!_this._texture) {
+                    return null;
+                }
                 _this._texture.updateSize(_this._size, _this._size);
                 // Fill polynomial information.
                 var sphericalPolynomial = new BABYLON.SphericalPolynomial();
@@ -62677,8 +62740,8 @@ var BABYLON;
                         dataFace = data[j];
                     }
                     // If special cases.
-                    if (!mipmapGenerator) {
-                        if (!_this.getScene().getEngine().getCaps().textureFloat) {
+                    if (!mipmapGenerator && dataFace) {
+                        if (!scene.getEngine().getCaps().textureFloat) {
                             // 3 channels of 1 bytes per pixel in bytes.
                             var byteBuffer = new ArrayBuffer(faceSize);
                             byteArray = new Uint8Array(byteBuffer);
@@ -62719,7 +62782,9 @@ var BABYLON;
                 }
                 return results;
             };
-            this._texture = this.getScene().getEngine().createRawCubeTextureFromUrl(this.url, this.getScene(), this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, this.getScene().getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, mipmapGenerator, this._onLoad, this._onError);
+            if (scene) {
+                this._texture = scene.getEngine().createRawCubeTextureFromUrl(this.url, scene, this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, scene.getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, mipmapGenerator, this._onLoad, this._onError);
+            }
         };
         /**
          * Occurs when the file is raw .hdr file.
@@ -62727,6 +62792,10 @@ var BABYLON;
         HDRCubeTexture.prototype.loadHDRTexture = function () {
             var _this = this;
             var callback = function (buffer) {
+                var scene = _this.getScene();
+                if (!scene) {
+                    return null;
+                }
                 // Extract the raw linear data.
                 var data = BABYLON.Internals.HDRTools.GetCubeMapTextureData(buffer, _this._size);
                 // Generate harmonics if needed.
@@ -62739,7 +62808,7 @@ var BABYLON;
                 // Push each faces.
                 for (var j = 0; j < 6; j++) {
                     // Create uintarray fallback.
-                    if (!_this.getScene().getEngine().getCaps().textureFloat) {
+                    if (!scene.getEngine().getCaps().textureFloat) {
                         // 3 channels of 1 bytes per pixel in bytes.
                         var byteBuffer = new ArrayBuffer(_this._size * _this._size * 3);
                         byteArray = new Uint8Array(byteBuffer);
@@ -62801,7 +62870,10 @@ var BABYLON;
             //         return generator.filterCubeMap();
             //     };
             // }
-            this._texture = this.getScene().getEngine().createRawCubeTextureFromUrl(this.url, this.getScene(), this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, this.getScene().getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, mipmapGenerator, this._onLoad, this._onError);
+            var scene = this.getScene();
+            if (scene) {
+                this._texture = scene.getEngine().createRawCubeTextureFromUrl(this.url, scene, this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, scene.getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, mipmapGenerator, this._onLoad, this._onError);
+            }
         };
         /**
          * Starts the loading process of the texture.
@@ -62815,8 +62887,12 @@ var BABYLON;
             }
         };
         HDRCubeTexture.prototype.clone = function () {
-            var size = this._isBABYLONPreprocessed ? null : this._size;
-            var newTexture = new HDRCubeTexture(this.url, this.getScene(), size, this._noMipmap, this._generateHarmonics, this._useInGammaSpace, this._usePMREMGenerator);
+            var scene = this.getScene();
+            if (!scene) {
+                return this;
+            }
+            var size = (this._isBABYLONPreprocessed ? null : this._size);
+            var newTexture = new HDRCubeTexture(this.url, scene, size, this._noMipmap, this._generateHarmonics, this._useInGammaSpace, this._usePMREMGenerator);
             // Base texture
             newTexture.level = this.level;
             newTexture.wrapU = this.wrapU;
@@ -62913,15 +62989,14 @@ var BABYLON;
             if (onError === void 0) { onError = null; }
             // Needs the url tho create the texture.
             if (!url) {
-                return null;
+                return;
             }
             // Check Power of two size.
             if (!BABYLON.Tools.IsExponentOfTwo(size)) {
-                return null;
+                return;
             }
-            // Coming Back in 3.1.
+            // Coming Back in 3.x.
             BABYLON.Tools.Error("Generation of Babylon HDR is coming back in 3.1.");
-            return null;
         };
         HDRCubeTexture._facesMapping = [
             "right",
@@ -64708,13 +64783,18 @@ var BABYLON;
              * this function is executed by the physics engine.
              */
             this.beforeStep = function () {
+                if (!_this._physicsEngine) {
+                    return;
+                }
                 _this.object.position.subtractToRef(_this._deltaPosition, _this._tmpPositionWithDelta);
                 //conjugate deltaRotation
-                if (_this._deltaRotationConjugated) {
-                    _this.object.rotationQuaternion.multiplyToRef(_this._deltaRotationConjugated, _this._tmpRotationWithDelta);
-                }
-                else {
-                    _this._tmpRotationWithDelta.copyFrom(_this.object.rotationQuaternion);
+                if (_this.object.rotationQuaternion) {
+                    if (_this._deltaRotationConjugated) {
+                        _this.object.rotationQuaternion.multiplyToRef(_this._deltaRotationConjugated, _this._tmpRotationWithDelta);
+                    }
+                    else {
+                        _this._tmpRotationWithDelta.copyFrom(_this.object.rotationQuaternion);
+                    }
                 }
                 _this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(_this, _this._tmpPositionWithDelta, _this._tmpRotationWithDelta);
                 _this._onBeforePhysicsStepCallbacks.forEach(function (func) {
@@ -64725,12 +64805,15 @@ var BABYLON;
              * this function is executed by the physics engine.
              */
             this.afterStep = function () {
+                if (!_this._physicsEngine) {
+                    return;
+                }
                 _this._onAfterPhysicsStepCallbacks.forEach(function (func) {
                     func(_this);
                 });
                 _this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(_this);
                 _this.object.position.addInPlace(_this._deltaPosition);
-                if (_this._deltaRotation) {
+                if (_this._deltaRotation && _this.object.rotationQuaternion) {
                     _this.object.rotationQuaternion.multiplyInPlace(_this._deltaRotation);
                 }
             };
@@ -64740,8 +64823,12 @@ var BABYLON;
             this.onCollideEvent = null;
             //event and body object due to cannon's event-based architecture.
             this.onCollide = function (e) {
-                if (!_this._onPhysicsCollideCallbacks.length && !_this.onCollideEvent)
+                if (!_this._onPhysicsCollideCallbacks.length && !_this.onCollideEvent) {
                     return;
+                }
+                if (!_this._physicsEngine) {
+                    return;
+                }
                 var otherImpostor = _this._physicsEngine.getImpostorWithPhysicsBody(e.body);
                 if (otherImpostor) {
                     // Legacy collision detection event support
@@ -64764,6 +64851,9 @@ var BABYLON;
             if (!this._scene && object.getScene) {
                 this._scene = object.getScene();
             }
+            if (!this._scene) {
+                return;
+            }
             this._physicsEngine = this._scene.getPhysicsEngine();
             if (!this._physicsEngine) {
                 BABYLON.Tools.Error("Physics not enabled. Please use scene.enablePhysics(...) before creating impostors.");
@@ -64814,6 +64904,9 @@ var BABYLON;
                 return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyFriction(this) : 0;
             },
             set: function (value) {
+                if (!this._physicsEngine) {
+                    return;
+                }
                 this._physicsEngine.getPhysicsPlugin().setBodyFriction(this, value);
             },
             enumerable: true,
@@ -64821,9 +64914,12 @@ var BABYLON;
         });
         Object.defineProperty(PhysicsImpostor.prototype, "restitution", {
             get: function () {
-                return this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this);
+                return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this) : 0;
             },
             set: function (value) {
+                if (!this._physicsEngine) {
+                    return;
+                }
                 this._physicsEngine.getPhysicsPlugin().setBodyRestitution(this, value);
             },
             enumerable: true,
@@ -64836,6 +64932,9 @@ var BABYLON;
          * of the child mesh.
          */
         PhysicsImpostor.prototype._init = function () {
+            if (!this._physicsEngine) {
+                return;
+            }
             this._physicsEngine.removeImpostor(this);
             this.physicsBody = null;
             this._parent = this._parent || this._getPhysicsParent();
@@ -64883,7 +64982,7 @@ var BABYLON;
              * Set the physics body. Used mainly by the physics engine/plugin
              */
             set: function (physicsBody) {
-                if (this._physicsBody) {
+                if (this._physicsBody && this._physicsEngine) {
                     this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this);
                 }
                 this._physicsBody = physicsBody;
@@ -64912,7 +65011,14 @@ var BABYLON;
                 this.object.rotationQuaternion = PhysicsImpostor.IDENTITY_QUATERNION;
                 //calculate the world matrix with no rotation
                 this.object.computeWorldMatrix && this.object.computeWorldMatrix(true);
-                var size = this.object.getBoundingInfo().boundingBox.extendSizeWorld.scale(2);
+                var boundingInfo = this.object.getBoundingInfo();
+                var size = void 0;
+                if (boundingInfo) {
+                    size = boundingInfo.boundingBox.extendSizeWorld.scale(2);
+                }
+                else {
+                    size = BABYLON.Vector3.Zero();
+                }
                 //bring back the rotation
                 this.object.rotationQuaternion = q;
                 //calculate the world matrix with the new rotation
@@ -64925,7 +65031,11 @@ var BABYLON;
         };
         PhysicsImpostor.prototype.getObjectCenter = function () {
             if (this.object.getBoundingInfo) {
-                return this.object.getBoundingInfo().boundingBox.centerWorld;
+                var boundingInfo = this.object.getBoundingInfo();
+                if (!boundingInfo) {
+                    return this.object.position;
+                }
+                return boundingInfo.boundingBox.centerWorld;
             }
             else {
                 return this.object.position;
@@ -64951,26 +65061,34 @@ var BABYLON;
             if (this.getParam("mass") !== mass) {
                 this.setParam("mass", mass);
             }
-            this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
+            }
         };
         PhysicsImpostor.prototype.getLinearVelocity = function () {
-            return this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this) : BABYLON.Vector3.Zero();
         };
         PhysicsImpostor.prototype.setLinearVelocity = function (velocity) {
-            this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
+            }
         };
         PhysicsImpostor.prototype.getAngularVelocity = function () {
-            return this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this) : BABYLON.Vector3.Zero();
         };
         PhysicsImpostor.prototype.setAngularVelocity = function (velocity) {
-            this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
+            }
         };
         /**
          * Execute a function with the physics plugin native code.
          * Provide a function the will have two variables - the world object and the physics body object.
          */
         PhysicsImpostor.prototype.executeNativeFunction = function (func) {
-            func(this._physicsEngine.getPhysicsPlugin().world, this.physicsBody);
+            if (this._physicsEngine) {
+                func(this._physicsEngine.getPhysicsPlugin().world, this.physicsBody);
+            }
         };
         /**
          * Register a function that will be executed before the physics world is stepping forward.
@@ -65023,13 +65141,19 @@ var BABYLON;
          * Apply a force
          */
         PhysicsImpostor.prototype.applyForce = function (force, contactPoint) {
-            this._physicsEngine.getPhysicsPlugin().applyForce(this, force, contactPoint);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().applyForce(this, force, contactPoint);
+            }
+            return this;
         };
         /**
          * Apply an impulse
          */
         PhysicsImpostor.prototype.applyImpulse = function (force, contactPoint) {
-            this._physicsEngine.getPhysicsPlugin().applyImpulse(this, force, contactPoint);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().applyImpulse(this, force, contactPoint);
+            }
+            return this;
         };
         /**
          * A help function to create a joint.
@@ -65037,6 +65161,7 @@ var BABYLON;
         PhysicsImpostor.prototype.createJoint = function (otherImpostor, jointType, jointData) {
             var joint = new BABYLON.PhysicsJoint(jointType, jointData);
             this.addJoint(otherImpostor, joint);
+            return this;
         };
         /**
          * Add a joint to this impostor with a different impostor.
@@ -65046,19 +65171,28 @@ var BABYLON;
                 otherImpostor: otherImpostor,
                 joint: joint
             });
-            this._physicsEngine.addJoint(this, otherImpostor, joint);
+            if (this._physicsEngine) {
+                this._physicsEngine.addJoint(this, otherImpostor, joint);
+            }
+            return this;
         };
         /**
          * Will keep this body still, in a sleep mode.
          */
         PhysicsImpostor.prototype.sleep = function () {
-            this._physicsEngine.getPhysicsPlugin().sleepBody(this);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().sleepBody(this);
+            }
+            return this;
         };
         /**
          * Wake the body up.
          */
         PhysicsImpostor.prototype.wakeUp = function () {
-            this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
+            }
+            return this;
         };
         PhysicsImpostor.prototype.clone = function (newObject) {
             if (!newObject)
@@ -65072,7 +65206,9 @@ var BABYLON;
                 return;
             }
             this._joints.forEach(function (j) {
-                _this._physicsEngine.removeJoint(_this, j.otherImpostor, j.joint);
+                if (_this._physicsEngine) {
+                    _this._physicsEngine.removeJoint(_this, j.otherImpostor, j.joint);
+                }
             });
             //dispose the physics body
             this._physicsEngine.removeImpostor(this);
@@ -65102,10 +65238,13 @@ var BABYLON;
             this._deltaRotationConjugated = this._deltaRotation.conjugate();
         };
         PhysicsImpostor.prototype.getBoxSizeToRef = function (result) {
-            this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);
+            }
+            return this;
         };
         PhysicsImpostor.prototype.getRadius = function () {
-            return this._physicsEngine.getPhysicsPlugin().getRadius(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getRadius(this) : 0;
         };
         /**
          * Sync a bone with this impostor
@@ -65118,13 +65257,15 @@ var BABYLON;
         PhysicsImpostor.prototype.syncBoneWithImpostor = function (bone, boneMesh, jointPivot, distToJoint, adjustRotation) {
             var tempVec = PhysicsImpostor._tmpVecs[0];
             var mesh = this.object;
-            if (adjustRotation) {
-                var tempQuat = PhysicsImpostor._tmpQuat;
-                mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);
-                bone.setRotationQuaternion(tempQuat, BABYLON.Space.WORLD, boneMesh);
-            }
-            else {
-                bone.setRotationQuaternion(mesh.rotationQuaternion, BABYLON.Space.WORLD, boneMesh);
+            if (mesh.rotationQuaternion) {
+                if (adjustRotation) {
+                    var tempQuat = PhysicsImpostor._tmpQuat;
+                    mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);
+                    bone.setRotationQuaternion(tempQuat, BABYLON.Space.WORLD, boneMesh);
+                }
+                else {
+                    bone.setRotationQuaternion(mesh.rotationQuaternion, BABYLON.Space.WORLD, boneMesh);
+                }
             }
             tempVec.x = 0;
             tempVec.y = 0;
@@ -65163,13 +65304,15 @@ var BABYLON;
          */
         PhysicsImpostor.prototype.syncImpostorWithBone = function (bone, boneMesh, jointPivot, distToJoint, adjustRotation, boneAxis) {
             var mesh = this.object;
-            if (adjustRotation) {
-                var tempQuat = PhysicsImpostor._tmpQuat;
-                bone.getRotationQuaternionToRef(BABYLON.Space.WORLD, boneMesh, tempQuat);
-                tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);
-            }
-            else {
-                bone.getRotationQuaternionToRef(BABYLON.Space.WORLD, boneMesh, mesh.rotationQuaternion);
+            if (mesh.rotationQuaternion) {
+                if (adjustRotation) {
+                    var tempQuat = PhysicsImpostor._tmpQuat;
+                    bone.getRotationQuaternionToRef(BABYLON.Space.WORLD, boneMesh, tempQuat);
+                    tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);
+                }
+                else {
+                    bone.getRotationQuaternionToRef(BABYLON.Space.WORLD, boneMesh, mesh.rotationQuaternion);
+                }
             }
             var pos = PhysicsImpostor._tmpVecs[0];
             var boneDir = PhysicsImpostor._tmpVecs[1];
@@ -66849,13 +66992,13 @@ var BABYLON;
                             var i = (lodIndex === -1) ? mip : 0;
                             if (!info.isCompressed && info.isFourCC) {
                                 dataLength = width * height * 4;
-                                var floatArray = null;
+                                var FloatArray = null;
                                 if (engine.badOS || engine.badDesktopOS || (!engine.getCaps().textureHalfFloat && !engine.getCaps().textureFloat)) {
                                     if (bpp === 128) {
-                                        floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                     }
                                     else if (bpp === 64) {
-                                        floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                     }
                                     info.textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT;
                                     format = engine._getWebGLTextureType(info.textureType);
@@ -66863,20 +67006,20 @@ var BABYLON;
                                 }
                                 else {
                                     if (bpp === 128) {
-                                        floatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                     }
                                     else if (bpp === 64 && !engine.getCaps().textureHalfFloat) {
-                                        floatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                         info.textureType = BABYLON.Engine.TEXTURETYPE_FLOAT;
                                         format = engine._getWebGLTextureType(info.textureType);
                                         internalFormat = engine._getRGBABufferInternalSizedFormat(info.textureType);
                                     }
                                     else {
-                                        floatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                     }
                                 }
-                                if (floatArray) {
-                                    engine._uploadDataToTexture(sampler, i, internalFormat, width, height, gl.RGBA, format, floatArray);
+                                if (FloatArray) {
+                                    engine._uploadDataToTexture(sampler, i, internalFormat, width, height, gl.RGBA, format, FloatArray);
                                 }
                             }
                             else if (info.isRGB) {

文件差异内容过多而无法显示
+ 6479 - 6478
dist/preview release/babylon.module.d.ts


文件差异内容过多而无法显示
+ 36 - 36
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 4502 - 4501
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


文件差异内容过多而无法显示
+ 36 - 36
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 246 - 103
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -6108,7 +6108,7 @@ var BABYLON;
         Tools.LoadFile = function (url, callback, progressCallBack, database, useArrayBuffer, onError) {
             url = Tools.CleanUrl(url);
             url = Tools.PreprocessUrl(url);
-            var request;
+            var request = null;
             var noIndexedDB = function () {
                 request = new XMLHttpRequest();
                 var loadUrl = Tools.BaseUrl + url;
@@ -6120,16 +6120,17 @@ var BABYLON;
                     request.onprogress = progressCallBack;
                 }
                 request.onreadystatechange = function () {
+                    var req = request;
                     // In case of undefined state in some browsers.
-                    if (request.readyState === (XMLHttpRequest.DONE || 4)) {
-                        request.onreadystatechange = function () { }; //some browsers have issues where onreadystatechange can be called multiple times with the same value
-                        if (request.status >= 200 && request.status < 300 || (!Tools.IsWindowObjectExist() && (request.status === 0))) {
-                            callback(!useArrayBuffer ? request.responseText : request.response);
+                    if (req.readyState === (XMLHttpRequest.DONE || 4)) {
+                        req.onreadystatechange = function () { }; //some browsers have issues where onreadystatechange can be called multiple times with the same value
+                        if (req.status >= 200 && req.status < 300 || (!Tools.IsWindowObjectExist() && (req.status === 0))) {
+                            callback(!useArrayBuffer ? req.responseText : req.response);
                         }
                         else {
-                            var e = new Error("Error status: " + request.status + " - Unable to load " + loadUrl);
+                            var e = new Error("Error status: " + req.status + " - Unable to load " + loadUrl);
                             if (onError) {
-                                onError(request, e);
+                                onError(req, e);
                             }
                             else {
                                 throw e;
@@ -9780,6 +9781,9 @@ var BABYLON;
             return results;
         };
         Engine.prototype.enableEffect = function (effect) {
+            if (!effect) {
+                return;
+            }
             // Use program
             this.setProgram(effect.getProgram());
             this._currentEffect = effect;
@@ -11062,6 +11066,9 @@ var BABYLON;
             var internalCallback = function (data) {
                 var width = texture.width;
                 var faceDataArrays = callback(data);
+                if (!faceDataArrays) {
+                    return;
+                }
                 if (mipmmapGenerator) {
                     var textureType = _this._getWebGLTextureType(type);
                     var internalFormat = _this._getInternalFormat(format);
@@ -22182,7 +22189,16 @@ var BABYLON;
                 }
             }
             if (fullDetails) {
-                ret += ", flat shading: " + (this._geometry ? (this.getVerticesData(BABYLON.VertexBuffer.PositionKind).length / 3 === this.getIndices().length ? "YES" : "NO") : "UNKNOWN");
+                if (this._geometry) {
+                    var ib = this.getIndices();
+                    var vb = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
+                    if (vb && ib) {
+                        ret += ", flat shading: " + (vb.length / 3 === ib.length ? "YES" : "NO");
+                    }
+                }
+                else {
+                    ret += ", flat shading: UNKNOWN";
+                }
             }
             return ret;
         };
@@ -22269,7 +22285,18 @@ var BABYLON;
             if (!this._LODLevels || this._LODLevels.length === 0) {
                 return this;
             }
-            var distanceToCamera = (boundingSphere ? boundingSphere : this.getBoundingInfo().boundingSphere).centerWorld.subtract(camera.globalPosition).length();
+            var bSphere;
+            if (boundingSphere) {
+                bSphere = boundingSphere;
+            }
+            else {
+                var boundingInfo = this.getBoundingInfo();
+                if (!boundingInfo) {
+                    return this;
+                }
+                bSphere = boundingInfo.boundingSphere;
+            }
+            var distanceToCamera = bSphere.centerWorld.subtract(camera.globalPosition).length();
             if (this._LODLevels[this._LODLevels.length - 1].distance > distanceToCamera) {
                 if (this.onLODLevelSelection) {
                     this.onLODLevelSelection(distanceToCamera, this, this._LODLevels[this._LODLevels.length - 1].mesh);
@@ -22340,7 +22367,7 @@ var BABYLON;
         };
         /**
          * Returns the mesh VertexBuffer object from the requested `kind` : positions, indices, normals, etc.
-         * Returns `undefined` if the mesh has no geometry.
+         * Returns `null` if the mesh has no geometry.
          * Possible `kind` values :
          * - BABYLON.VertexBuffer.PositionKind
          * - BABYLON.VertexBuffer.UVKind
@@ -22357,7 +22384,7 @@ var BABYLON;
          */
         Mesh.prototype.getVertexBuffer = function (kind) {
             if (!this._geometry) {
-                return undefined;
+                return null;
             }
             return this._geometry.getVertexBuffer(kind);
         };
@@ -22526,7 +22553,7 @@ var BABYLON;
          * Returns the Mesh.
          */
         Mesh.prototype.refreshBoundingInfo = function () {
-            if (this._boundingInfo.isLocked) {
+            if (this._boundingInfo && this._boundingInfo.isLocked) {
                 return this;
             }
             var data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
@@ -22549,7 +22576,11 @@ var BABYLON;
             }
             // Check if we need to recreate the submeshes
             if (this.subMeshes && this.subMeshes.length > 0) {
-                var totalIndices = this.getIndices().length;
+                var ib = this.getIndices();
+                if (!ib) {
+                    return null;
+                }
+                var totalIndices = ib.length;
                 var needToRecreate = false;
                 if (force) {
                     needToRecreate = true;
@@ -22635,7 +22666,8 @@ var BABYLON;
         };
         Mesh.prototype.markVerticesDataAsUpdatable = function (kind, updatable) {
             if (updatable === void 0) { updatable = true; }
-            if (this.getVertexBuffer(kind).isUpdatable() === updatable) {
+            var vb = this.getVertexBuffer(kind);
+            if (!vb || vb.isUpdatable() === updatable) {
                 return;
             }
             this.setVerticesData(kind, this.getVerticesData(kind), updatable);
@@ -25977,7 +26009,7 @@ var BABYLON;
                 defines["VERTEXALPHA"] = mesh.hasVertexAlpha;
             }
             if (useBones) {
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                     defines["NUM_BONE_INFLUENCERS"] = mesh.numBoneInfluencers;
                     defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
                 }
@@ -26099,7 +26131,8 @@ var BABYLON;
         };
         MaterialHelper.PrepareUniformsAndSamplersList = function (uniformsListOrOptions, samplersList, defines, maxSimultaneousLights) {
             if (maxSimultaneousLights === void 0) { maxSimultaneousLights = 4; }
-            var uniformsList, uniformBuffersList, samplersList, defines;
+            var uniformsList;
+            var uniformBuffersList = null;
             if (uniformsListOrOptions.uniformsNames) {
                 var options = uniformsListOrOptions;
                 uniformsList = options.uniformsNames;
@@ -26110,6 +26143,9 @@ var BABYLON;
             }
             else {
                 uniformsList = uniformsListOrOptions;
+                if (!samplersList) {
+                    samplersList = [];
+                }
             }
             for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
                 if (!defines["LIGHT" + lightIndex]) {
@@ -26150,7 +26186,7 @@ var BABYLON;
         };
         MaterialHelper.PrepareAttributesForMorphTargets = function (attribs, mesh, defines) {
             var influencers = defines["NUM_MORPH_INFLUENCERS"];
-            if (influencers > 0) {
+            if (influencers > 0 && BABYLON.Engine.LastCreatedEngine) {
                 var maxAttributesCount = BABYLON.Engine.LastCreatedEngine.getCaps().maxVertexAttribs;
                 var manager = mesh.morphTargetManager;
                 var normal = manager.supportsNormals && defines["NORMAL"];
@@ -26232,9 +26268,9 @@ var BABYLON;
             }
         };
         MaterialHelper.BindBonesParameters = function (mesh, effect) {
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                 var matrices = mesh.skeleton.getTransformMatrices(mesh);
-                if (matrices) {
+                if (matrices && effect) {
                     effect.setMatrices("mBones", matrices);
                 }
             }
@@ -26719,7 +26755,9 @@ var BABYLON;
             else {
                 this._scene._cachedVisibility = 1;
             }
-            this.onBindObservable.notifyObservers(mesh);
+            if (mesh) {
+                this.onBindObservable.notifyObservers(mesh);
+            }
             if (this.disableDepthWrite) {
                 var engine = this._scene.getEngine();
                 this._cachedDepthWriteState = engine.getDepthWrite();
@@ -26868,11 +26906,14 @@ var BABYLON;
                 if (mesh.material === this) {
                     mesh.material = null;
                     if (mesh.geometry) {
-                        var geometry = mesh.geometry;
+                        var geometry = (mesh.geometry);
                         if (this.storeEffectOnSubMeshes) {
                             for (var _i = 0, _a = mesh.subMeshes; _i < _a.length; _i++) {
                                 var subMesh = _a[_i];
                                 geometry._releaseVertexArrayObject(subMesh._materialEffect);
+                                if (forceDisposeEffect && subMesh._materialEffect) {
+                                    this._scene.getEngine()._releaseEffect(subMesh._materialEffect);
+                                }
                             }
                         }
                         else {
@@ -26884,13 +26925,7 @@ var BABYLON;
             this._uniformBuffer.dispose();
             // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
             if (forceDisposeEffect && this._effect) {
-                if (this.storeEffectOnSubMeshes) {
-                    for (var _b = 0, _c = mesh.subMeshes; _b < _c.length; _b++) {
-                        var subMesh = _c[_b];
-                        this._scene.getEngine()._releaseEffect(subMesh._materialEffect);
-                    }
-                }
-                else {
+                if (!this.storeEffectOnSubMeshes) {
                     this._scene.getEngine()._releaseEffect(this._effect);
                 }
                 this._effect = null;
@@ -29886,6 +29921,9 @@ var BABYLON;
             }
         };
         Geometry.prototype._bind = function (effect, indexToBind) {
+            if (!effect) {
+                return;
+            }
             if (indexToBind === undefined) {
                 indexToBind = this._indexBuffer;
             }
@@ -30033,6 +30071,7 @@ var BABYLON;
             return this._indexBuffer;
         };
         Geometry.prototype._releaseVertexArrayObject = function (effect) {
+            if (effect === void 0) { effect = null; }
             if (!effect || !this._vertexArrayObjects) {
                 return;
             }
@@ -45883,10 +45922,12 @@ var BABYLON;
             configurable: true
         });
         LinesMesh.prototype.createInstance = function (name) {
-            BABYLON.Tools.Log("LinesMeshes do not support createInstance.");
-            return null;
+            throw new Error("LinesMeshes do not support createInstance.");
         };
         LinesMesh.prototype._bind = function (subMesh, effect, fillMode) {
+            if (!this._geometry) {
+                return this;
+            }
             // VBOs
             this._geometry._bind(this._colorShader.getEffect());
             // Color
@@ -46083,7 +46124,7 @@ var BABYLON;
                 defines.push("#define VERTEXCOLOR");
             }
             // Bones
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                 attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                 attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
                 if (mesh.numBoneInfluencers > 4) {
@@ -46133,6 +46174,9 @@ var BABYLON;
         };
         ShaderMaterial.prototype.bindOnlyWorldMatrix = function (world) {
             var scene = this.getScene();
+            if (!this._effect) {
+                return;
+            }
             if (this._options.uniforms.indexOf("world") !== -1) {
                 this._effect.setMatrix("world", world);
             }
@@ -46147,7 +46191,7 @@ var BABYLON;
         ShaderMaterial.prototype.bind = function (world, mesh) {
             // Std values
             this.bindOnlyWorldMatrix(world);
-            if (this.getScene().getCachedMaterial() !== this) {
+            if (this._effect && this.getScene().getCachedMaterial() !== this) {
                 if (this._options.uniforms.indexOf("view") !== -1) {
                     this._effect.setMatrix("view", this.getScene().getViewMatrix());
                 }
@@ -46297,9 +46341,9 @@ var BABYLON;
                 serializationObject.floats[name] = this._floats[name];
             }
             // Float s   
-            serializationObject.floatArrays = {};
+            serializationObject.FloatArrays = {};
             for (name in this._floatsArrays) {
-                serializationObject.floatArrays[name] = this._floatsArrays[name];
+                serializationObject.FloatArrays[name] = this._floatsArrays[name];
             }
             // Color3    
             serializationObject.colors3 = {};
@@ -53503,7 +53547,14 @@ var BABYLON;
             return this.subMaterials[index];
         };
         MultiMaterial.prototype.getActiveTextures = function () {
-            return (_a = _super.prototype.getActiveTextures.call(this)).concat.apply(_a, this.subMaterials.map(function (subMaterial) { return subMaterial.getActiveTextures(); }));
+            return (_a = _super.prototype.getActiveTextures.call(this)).concat.apply(_a, this.subMaterials.map(function (subMaterial) {
+                if (subMaterial) {
+                    return subMaterial.getActiveTextures();
+                }
+                else {
+                    return [];
+                }
+            }));
             var _a;
         };
         // Methods
@@ -53514,13 +53565,13 @@ var BABYLON;
             for (var index = 0; index < this.subMaterials.length; index++) {
                 var subMaterial = this.subMaterials[index];
                 if (subMaterial) {
-                    if (this.subMaterials[index].storeEffectOnSubMeshes) {
-                        if (!this.subMaterials[index].isReadyForSubMesh(mesh, subMesh, useInstances)) {
+                    if (subMaterial.storeEffectOnSubMeshes) {
+                        if (!subMaterial.isReadyForSubMesh(mesh, subMesh, useInstances)) {
                             return false;
                         }
                         continue;
                     }
-                    if (!this.subMaterials[index].isReady(mesh)) {
+                    if (!subMaterial.isReady(mesh)) {
                         return false;
                     }
                 }
@@ -53531,8 +53582,9 @@ var BABYLON;
             var newMultiMaterial = new MultiMaterial(name, this.getScene());
             for (var index = 0; index < this.subMaterials.length; index++) {
                 var subMaterial = null;
-                if (cloneChildren) {
-                    subMaterial = this.subMaterials[index].clone(name + "-" + this.subMaterials[index].name);
+                var current = this.subMaterials[index];
+                if (cloneChildren && current) {
+                    subMaterial = current.clone(name + "-" + current.name);
                 }
                 else {
                     subMaterial = this.subMaterials[index];
@@ -62568,22 +62620,22 @@ var BABYLON;
             _this._onLoad = onLoad;
             _this._onError = onError;
             _this.gammaSpace = false;
+            var caps = scene.getEngine().getCaps();
             if (size) {
                 _this._isBABYLONPreprocessed = false;
                 _this._noMipmap = noMipmap;
                 _this._size = size;
                 _this._useInGammaSpace = useInGammaSpace;
                 _this._usePMREMGenerator = usePMREMGenerator &&
-                    scene.getEngine().getCaps().textureLOD &&
-                    _this.getScene().getEngine().getCaps().textureFloat &&
+                    caps.textureLOD &&
+                    caps.textureFloat &&
                     !_this._useInGammaSpace;
             }
             else {
                 _this._isBABYLONPreprocessed = true;
                 _this._noMipmap = false;
                 _this._useInGammaSpace = false;
-                _this._usePMREMGenerator = scene.getEngine().getCaps().textureLOD &&
-                    _this.getScene().getEngine().getCaps().textureFloat &&
+                _this._usePMREMGenerator = caps.textureLOD && caps.textureFloat &&
                     !_this._useInGammaSpace;
             }
             _this.isPMREM = _this._usePMREMGenerator;
@@ -62621,8 +62673,12 @@ var BABYLON;
             var _this = this;
             var mipLevels = 0;
             var floatArrayView = null;
-            var mipmapGenerator = (!this._useInGammaSpace && this.getScene().getEngine().getCaps().textureFloat) ? function (data) {
+            var scene = this.getScene();
+            var mipmapGenerator = (!this._useInGammaSpace && scene && scene.getEngine().getCaps().textureFloat) ? function (data) {
                 var mips = new Array();
+                if (!floatArrayView) {
+                    return mips;
+                }
                 var startIndex = 30;
                 for (var level = 0; level < mipLevels; level++) {
                     mips.push([]);
@@ -62637,6 +62693,10 @@ var BABYLON;
                 return mips;
             } : null;
             var callback = function (buffer) {
+                var scene = _this.getScene();
+                if (!scene) {
+                    return null;
+                }
                 // Create Native Array Views
                 var intArrayView = new Int32Array(buffer);
                 floatArrayView = new Float32Array(buffer);
@@ -62644,6 +62704,9 @@ var BABYLON;
                 var version = intArrayView[0]; // Version 1. (MAy be use in case of format changes for backward compaibility)
                 _this._size = intArrayView[1]; // CubeMap max mip face size.
                 // Update Texture Information.
+                if (!_this._texture) {
+                    return null;
+                }
                 _this._texture.updateSize(_this._size, _this._size);
                 // Fill polynomial information.
                 var sphericalPolynomial = new BABYLON.SphericalPolynomial();
@@ -62677,8 +62740,8 @@ var BABYLON;
                         dataFace = data[j];
                     }
                     // If special cases.
-                    if (!mipmapGenerator) {
-                        if (!_this.getScene().getEngine().getCaps().textureFloat) {
+                    if (!mipmapGenerator && dataFace) {
+                        if (!scene.getEngine().getCaps().textureFloat) {
                             // 3 channels of 1 bytes per pixel in bytes.
                             var byteBuffer = new ArrayBuffer(faceSize);
                             byteArray = new Uint8Array(byteBuffer);
@@ -62719,7 +62782,9 @@ var BABYLON;
                 }
                 return results;
             };
-            this._texture = this.getScene().getEngine().createRawCubeTextureFromUrl(this.url, this.getScene(), this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, this.getScene().getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, mipmapGenerator, this._onLoad, this._onError);
+            if (scene) {
+                this._texture = scene.getEngine().createRawCubeTextureFromUrl(this.url, scene, this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, scene.getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, mipmapGenerator, this._onLoad, this._onError);
+            }
         };
         /**
          * Occurs when the file is raw .hdr file.
@@ -62727,6 +62792,10 @@ var BABYLON;
         HDRCubeTexture.prototype.loadHDRTexture = function () {
             var _this = this;
             var callback = function (buffer) {
+                var scene = _this.getScene();
+                if (!scene) {
+                    return null;
+                }
                 // Extract the raw linear data.
                 var data = BABYLON.Internals.HDRTools.GetCubeMapTextureData(buffer, _this._size);
                 // Generate harmonics if needed.
@@ -62739,7 +62808,7 @@ var BABYLON;
                 // Push each faces.
                 for (var j = 0; j < 6; j++) {
                     // Create uintarray fallback.
-                    if (!_this.getScene().getEngine().getCaps().textureFloat) {
+                    if (!scene.getEngine().getCaps().textureFloat) {
                         // 3 channels of 1 bytes per pixel in bytes.
                         var byteBuffer = new ArrayBuffer(_this._size * _this._size * 3);
                         byteArray = new Uint8Array(byteBuffer);
@@ -62801,7 +62870,10 @@ var BABYLON;
             //         return generator.filterCubeMap();
             //     };
             // }
-            this._texture = this.getScene().getEngine().createRawCubeTextureFromUrl(this.url, this.getScene(), this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, this.getScene().getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, mipmapGenerator, this._onLoad, this._onError);
+            var scene = this.getScene();
+            if (scene) {
+                this._texture = scene.getEngine().createRawCubeTextureFromUrl(this.url, scene, this._size, BABYLON.Engine.TEXTUREFORMAT_RGB, scene.getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, mipmapGenerator, this._onLoad, this._onError);
+            }
         };
         /**
          * Starts the loading process of the texture.
@@ -62815,8 +62887,12 @@ var BABYLON;
             }
         };
         HDRCubeTexture.prototype.clone = function () {
-            var size = this._isBABYLONPreprocessed ? null : this._size;
-            var newTexture = new HDRCubeTexture(this.url, this.getScene(), size, this._noMipmap, this._generateHarmonics, this._useInGammaSpace, this._usePMREMGenerator);
+            var scene = this.getScene();
+            if (!scene) {
+                return this;
+            }
+            var size = (this._isBABYLONPreprocessed ? null : this._size);
+            var newTexture = new HDRCubeTexture(this.url, scene, size, this._noMipmap, this._generateHarmonics, this._useInGammaSpace, this._usePMREMGenerator);
             // Base texture
             newTexture.level = this.level;
             newTexture.wrapU = this.wrapU;
@@ -62913,15 +62989,14 @@ var BABYLON;
             if (onError === void 0) { onError = null; }
             // Needs the url tho create the texture.
             if (!url) {
-                return null;
+                return;
             }
             // Check Power of two size.
             if (!BABYLON.Tools.IsExponentOfTwo(size)) {
-                return null;
+                return;
             }
-            // Coming Back in 3.1.
+            // Coming Back in 3.x.
             BABYLON.Tools.Error("Generation of Babylon HDR is coming back in 3.1.");
-            return null;
         };
         HDRCubeTexture._facesMapping = [
             "right",
@@ -64708,13 +64783,18 @@ var BABYLON;
              * this function is executed by the physics engine.
              */
             this.beforeStep = function () {
+                if (!_this._physicsEngine) {
+                    return;
+                }
                 _this.object.position.subtractToRef(_this._deltaPosition, _this._tmpPositionWithDelta);
                 //conjugate deltaRotation
-                if (_this._deltaRotationConjugated) {
-                    _this.object.rotationQuaternion.multiplyToRef(_this._deltaRotationConjugated, _this._tmpRotationWithDelta);
-                }
-                else {
-                    _this._tmpRotationWithDelta.copyFrom(_this.object.rotationQuaternion);
+                if (_this.object.rotationQuaternion) {
+                    if (_this._deltaRotationConjugated) {
+                        _this.object.rotationQuaternion.multiplyToRef(_this._deltaRotationConjugated, _this._tmpRotationWithDelta);
+                    }
+                    else {
+                        _this._tmpRotationWithDelta.copyFrom(_this.object.rotationQuaternion);
+                    }
                 }
                 _this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(_this, _this._tmpPositionWithDelta, _this._tmpRotationWithDelta);
                 _this._onBeforePhysicsStepCallbacks.forEach(function (func) {
@@ -64725,12 +64805,15 @@ var BABYLON;
              * this function is executed by the physics engine.
              */
             this.afterStep = function () {
+                if (!_this._physicsEngine) {
+                    return;
+                }
                 _this._onAfterPhysicsStepCallbacks.forEach(function (func) {
                     func(_this);
                 });
                 _this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(_this);
                 _this.object.position.addInPlace(_this._deltaPosition);
-                if (_this._deltaRotation) {
+                if (_this._deltaRotation && _this.object.rotationQuaternion) {
                     _this.object.rotationQuaternion.multiplyInPlace(_this._deltaRotation);
                 }
             };
@@ -64740,8 +64823,12 @@ var BABYLON;
             this.onCollideEvent = null;
             //event and body object due to cannon's event-based architecture.
             this.onCollide = function (e) {
-                if (!_this._onPhysicsCollideCallbacks.length && !_this.onCollideEvent)
+                if (!_this._onPhysicsCollideCallbacks.length && !_this.onCollideEvent) {
                     return;
+                }
+                if (!_this._physicsEngine) {
+                    return;
+                }
                 var otherImpostor = _this._physicsEngine.getImpostorWithPhysicsBody(e.body);
                 if (otherImpostor) {
                     // Legacy collision detection event support
@@ -64764,6 +64851,9 @@ var BABYLON;
             if (!this._scene && object.getScene) {
                 this._scene = object.getScene();
             }
+            if (!this._scene) {
+                return;
+            }
             this._physicsEngine = this._scene.getPhysicsEngine();
             if (!this._physicsEngine) {
                 BABYLON.Tools.Error("Physics not enabled. Please use scene.enablePhysics(...) before creating impostors.");
@@ -64814,6 +64904,9 @@ var BABYLON;
                 return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyFriction(this) : 0;
             },
             set: function (value) {
+                if (!this._physicsEngine) {
+                    return;
+                }
                 this._physicsEngine.getPhysicsPlugin().setBodyFriction(this, value);
             },
             enumerable: true,
@@ -64821,9 +64914,12 @@ var BABYLON;
         });
         Object.defineProperty(PhysicsImpostor.prototype, "restitution", {
             get: function () {
-                return this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this);
+                return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this) : 0;
             },
             set: function (value) {
+                if (!this._physicsEngine) {
+                    return;
+                }
                 this._physicsEngine.getPhysicsPlugin().setBodyRestitution(this, value);
             },
             enumerable: true,
@@ -64836,6 +64932,9 @@ var BABYLON;
          * of the child mesh.
          */
         PhysicsImpostor.prototype._init = function () {
+            if (!this._physicsEngine) {
+                return;
+            }
             this._physicsEngine.removeImpostor(this);
             this.physicsBody = null;
             this._parent = this._parent || this._getPhysicsParent();
@@ -64883,7 +64982,7 @@ var BABYLON;
              * Set the physics body. Used mainly by the physics engine/plugin
              */
             set: function (physicsBody) {
-                if (this._physicsBody) {
+                if (this._physicsBody && this._physicsEngine) {
                     this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this);
                 }
                 this._physicsBody = physicsBody;
@@ -64912,7 +65011,14 @@ var BABYLON;
                 this.object.rotationQuaternion = PhysicsImpostor.IDENTITY_QUATERNION;
                 //calculate the world matrix with no rotation
                 this.object.computeWorldMatrix && this.object.computeWorldMatrix(true);
-                var size = this.object.getBoundingInfo().boundingBox.extendSizeWorld.scale(2);
+                var boundingInfo = this.object.getBoundingInfo();
+                var size = void 0;
+                if (boundingInfo) {
+                    size = boundingInfo.boundingBox.extendSizeWorld.scale(2);
+                }
+                else {
+                    size = BABYLON.Vector3.Zero();
+                }
                 //bring back the rotation
                 this.object.rotationQuaternion = q;
                 //calculate the world matrix with the new rotation
@@ -64925,7 +65031,11 @@ var BABYLON;
         };
         PhysicsImpostor.prototype.getObjectCenter = function () {
             if (this.object.getBoundingInfo) {
-                return this.object.getBoundingInfo().boundingBox.centerWorld;
+                var boundingInfo = this.object.getBoundingInfo();
+                if (!boundingInfo) {
+                    return this.object.position;
+                }
+                return boundingInfo.boundingBox.centerWorld;
             }
             else {
                 return this.object.position;
@@ -64951,26 +65061,34 @@ var BABYLON;
             if (this.getParam("mass") !== mass) {
                 this.setParam("mass", mass);
             }
-            this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
+            }
         };
         PhysicsImpostor.prototype.getLinearVelocity = function () {
-            return this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this) : BABYLON.Vector3.Zero();
         };
         PhysicsImpostor.prototype.setLinearVelocity = function (velocity) {
-            this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
+            }
         };
         PhysicsImpostor.prototype.getAngularVelocity = function () {
-            return this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this) : BABYLON.Vector3.Zero();
         };
         PhysicsImpostor.prototype.setAngularVelocity = function (velocity) {
-            this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
+            }
         };
         /**
          * Execute a function with the physics plugin native code.
          * Provide a function the will have two variables - the world object and the physics body object.
          */
         PhysicsImpostor.prototype.executeNativeFunction = function (func) {
-            func(this._physicsEngine.getPhysicsPlugin().world, this.physicsBody);
+            if (this._physicsEngine) {
+                func(this._physicsEngine.getPhysicsPlugin().world, this.physicsBody);
+            }
         };
         /**
          * Register a function that will be executed before the physics world is stepping forward.
@@ -65023,13 +65141,19 @@ var BABYLON;
          * Apply a force
          */
         PhysicsImpostor.prototype.applyForce = function (force, contactPoint) {
-            this._physicsEngine.getPhysicsPlugin().applyForce(this, force, contactPoint);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().applyForce(this, force, contactPoint);
+            }
+            return this;
         };
         /**
          * Apply an impulse
          */
         PhysicsImpostor.prototype.applyImpulse = function (force, contactPoint) {
-            this._physicsEngine.getPhysicsPlugin().applyImpulse(this, force, contactPoint);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().applyImpulse(this, force, contactPoint);
+            }
+            return this;
         };
         /**
          * A help function to create a joint.
@@ -65037,6 +65161,7 @@ var BABYLON;
         PhysicsImpostor.prototype.createJoint = function (otherImpostor, jointType, jointData) {
             var joint = new BABYLON.PhysicsJoint(jointType, jointData);
             this.addJoint(otherImpostor, joint);
+            return this;
         };
         /**
          * Add a joint to this impostor with a different impostor.
@@ -65046,19 +65171,28 @@ var BABYLON;
                 otherImpostor: otherImpostor,
                 joint: joint
             });
-            this._physicsEngine.addJoint(this, otherImpostor, joint);
+            if (this._physicsEngine) {
+                this._physicsEngine.addJoint(this, otherImpostor, joint);
+            }
+            return this;
         };
         /**
          * Will keep this body still, in a sleep mode.
          */
         PhysicsImpostor.prototype.sleep = function () {
-            this._physicsEngine.getPhysicsPlugin().sleepBody(this);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().sleepBody(this);
+            }
+            return this;
         };
         /**
          * Wake the body up.
          */
         PhysicsImpostor.prototype.wakeUp = function () {
-            this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
+            }
+            return this;
         };
         PhysicsImpostor.prototype.clone = function (newObject) {
             if (!newObject)
@@ -65072,7 +65206,9 @@ var BABYLON;
                 return;
             }
             this._joints.forEach(function (j) {
-                _this._physicsEngine.removeJoint(_this, j.otherImpostor, j.joint);
+                if (_this._physicsEngine) {
+                    _this._physicsEngine.removeJoint(_this, j.otherImpostor, j.joint);
+                }
             });
             //dispose the physics body
             this._physicsEngine.removeImpostor(this);
@@ -65102,10 +65238,13 @@ var BABYLON;
             this._deltaRotationConjugated = this._deltaRotation.conjugate();
         };
         PhysicsImpostor.prototype.getBoxSizeToRef = function (result) {
-            this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);
+            }
+            return this;
         };
         PhysicsImpostor.prototype.getRadius = function () {
-            return this._physicsEngine.getPhysicsPlugin().getRadius(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getRadius(this) : 0;
         };
         /**
          * Sync a bone with this impostor
@@ -65118,13 +65257,15 @@ var BABYLON;
         PhysicsImpostor.prototype.syncBoneWithImpostor = function (bone, boneMesh, jointPivot, distToJoint, adjustRotation) {
             var tempVec = PhysicsImpostor._tmpVecs[0];
             var mesh = this.object;
-            if (adjustRotation) {
-                var tempQuat = PhysicsImpostor._tmpQuat;
-                mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);
-                bone.setRotationQuaternion(tempQuat, BABYLON.Space.WORLD, boneMesh);
-            }
-            else {
-                bone.setRotationQuaternion(mesh.rotationQuaternion, BABYLON.Space.WORLD, boneMesh);
+            if (mesh.rotationQuaternion) {
+                if (adjustRotation) {
+                    var tempQuat = PhysicsImpostor._tmpQuat;
+                    mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);
+                    bone.setRotationQuaternion(tempQuat, BABYLON.Space.WORLD, boneMesh);
+                }
+                else {
+                    bone.setRotationQuaternion(mesh.rotationQuaternion, BABYLON.Space.WORLD, boneMesh);
+                }
             }
             tempVec.x = 0;
             tempVec.y = 0;
@@ -65163,13 +65304,15 @@ var BABYLON;
          */
         PhysicsImpostor.prototype.syncImpostorWithBone = function (bone, boneMesh, jointPivot, distToJoint, adjustRotation, boneAxis) {
             var mesh = this.object;
-            if (adjustRotation) {
-                var tempQuat = PhysicsImpostor._tmpQuat;
-                bone.getRotationQuaternionToRef(BABYLON.Space.WORLD, boneMesh, tempQuat);
-                tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);
-            }
-            else {
-                bone.getRotationQuaternionToRef(BABYLON.Space.WORLD, boneMesh, mesh.rotationQuaternion);
+            if (mesh.rotationQuaternion) {
+                if (adjustRotation) {
+                    var tempQuat = PhysicsImpostor._tmpQuat;
+                    bone.getRotationQuaternionToRef(BABYLON.Space.WORLD, boneMesh, tempQuat);
+                    tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);
+                }
+                else {
+                    bone.getRotationQuaternionToRef(BABYLON.Space.WORLD, boneMesh, mesh.rotationQuaternion);
+                }
             }
             var pos = PhysicsImpostor._tmpVecs[0];
             var boneDir = PhysicsImpostor._tmpVecs[1];
@@ -66849,13 +66992,13 @@ var BABYLON;
                             var i = (lodIndex === -1) ? mip : 0;
                             if (!info.isCompressed && info.isFourCC) {
                                 dataLength = width * height * 4;
-                                var floatArray = null;
+                                var FloatArray = null;
                                 if (engine.badOS || engine.badDesktopOS || (!engine.getCaps().textureHalfFloat && !engine.getCaps().textureFloat)) {
                                     if (bpp === 128) {
-                                        floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                     }
                                     else if (bpp === 64) {
-                                        floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                     }
                                     info.textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT;
                                     format = engine._getWebGLTextureType(info.textureType);
@@ -66863,20 +67006,20 @@ var BABYLON;
                                 }
                                 else {
                                     if (bpp === 128) {
-                                        floatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                     }
                                     else if (bpp === 64 && !engine.getCaps().textureHalfFloat) {
-                                        floatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                         info.textureType = BABYLON.Engine.TEXTURETYPE_FLOAT;
                                         format = engine._getWebGLTextureType(info.textureType);
                                         internalFormat = engine._getRGBABufferInternalSizedFormat(info.textureType);
                                     }
                                     else {
-                                        floatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                        FloatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                     }
                                 }
-                                if (floatArray) {
-                                    engine._uploadDataToTexture(sampler, i, internalFormat, width, height, gl.RGBA, format, floatArray);
+                                if (FloatArray) {
+                                    engine._uploadDataToTexture(sampler, i, internalFormat, width, height, gl.RGBA, format, FloatArray);
                                 }
                             }
                             else if (info.isRGB) {

文件差异内容过多而无法显示
+ 4502 - 4501
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


+ 2 - 2
src/Collisions/babylon.pickingInfo.ts

@@ -33,7 +33,7 @@
             var result: Vector3;
 
             if (useVerticesNormals) {
-                var normals = (<number[] | Float32Array>this.pickedMesh.getVerticesData(VertexBuffer.NormalKind));
+                var normals = (<FloatArray>this.pickedMesh.getVerticesData(VertexBuffer.NormalKind));
 
                 var normal0 = Vector3.FromArray(normals, indices[this.faceId * 3] * 3);
                 var normal1 = Vector3.FromArray(normals, indices[this.faceId * 3 + 1] * 3);
@@ -45,7 +45,7 @@
 
                 result = new Vector3(normal0.x + normal1.x + normal2.x, normal0.y + normal1.y + normal2.y, normal0.z + normal1.z + normal2.z);
             } else {
-                var positions = (<number[] | Float32Array>this.pickedMesh.getVerticesData(VertexBuffer.PositionKind));
+                var positions = (<FloatArray>this.pickedMesh.getVerticesData(VertexBuffer.PositionKind));
 
                 var vertex1 = Vector3.FromArray(positions, indices[this.faceId * 3] * 3);
                 var vertex2 = Vector3.FromArray(positions, indices[this.faceId * 3 + 1] * 3);

+ 16 - 9
src/Engine/babylon.engine.ts

@@ -1822,7 +1822,7 @@
         }
 
         // UBOs
-        public createUniformBuffer(elements: number[] | Float32Array): WebGLBuffer {
+        public createUniformBuffer(elements: FloatArray): WebGLBuffer {
             var ubo = this._gl.createBuffer();
 
             if (!ubo) {
@@ -1843,7 +1843,7 @@
             return ubo;
         }
 
-        public createDynamicUniformBuffer(elements: number[] | Float32Array): WebGLBuffer {
+        public createDynamicUniformBuffer(elements: FloatArray): WebGLBuffer {
             var ubo = this._gl.createBuffer();
 
             if (!ubo) {
@@ -1864,7 +1864,7 @@
             return ubo;
         }
 
-        public updateUniformBuffer(uniformBuffer: WebGLBuffer, elements: number[] | Float32Array, offset?: number, count?: number): void {
+        public updateUniformBuffer(uniformBuffer: WebGLBuffer, elements: FloatArray, offset?: number, count?: number): void {
             this.bindUniformBuffer(uniformBuffer);
 
             if (offset === undefined) {
@@ -1895,7 +1895,7 @@
             this._cachedVertexBuffers = null;
         }
 
-        public createVertexBuffer(vertices: number[] | Float32Array): WebGLBuffer {
+        public createVertexBuffer(vertices: FloatArray): WebGLBuffer {
             var vbo = this._gl.createBuffer();
 
             if (!vbo) {
@@ -1915,7 +1915,7 @@
             return vbo;
         }
 
-        public createDynamicVertexBuffer(vertices: number[] | Float32Array): WebGLBuffer {
+        public createDynamicVertexBuffer(vertices: FloatArray): WebGLBuffer {
             var vbo = this._gl.createBuffer();
 
             if (!vbo) {
@@ -1951,7 +1951,7 @@
             this._resetIndexBufferBinding();
         }
 
-        public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: number[] | Float32Array, offset?: number, count?: number): void {
+        public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, offset?: number, count?: number): void {
             this.bindArrayBuffer(vertexBuffer);
 
             if (offset === undefined) {
@@ -2488,7 +2488,10 @@
             return results;
         }
 
-        public enableEffect(effect: Effect): void {
+        public enableEffect(effect: Nullable<Effect>): void {
+            if (!effect) {
+                return;
+            }
             // Use program
             this.setProgram(effect.getProgram());
 
@@ -4040,8 +4043,8 @@
         }
 
         public createRawCubeTextureFromUrl(url: string, scene: Scene, size: number, format: number, type: number, noMipmap: boolean,
-            callback: (ArrayBuffer: ArrayBuffer) => ArrayBufferView[],
-            mipmmapGenerator: ((faces: ArrayBufferView[]) => ArrayBufferView[][]),
+            callback: (ArrayBuffer: ArrayBuffer) => Nullable<ArrayBufferView[]>,
+            mipmmapGenerator: Nullable<((faces: ArrayBufferView[]) => ArrayBufferView[][])>,
             onLoad: Nullable<() => void> = null,
             onError: Nullable<(message?: string, exception?: any) => void> = null,
             samplingMode = Texture.TRILINEAR_SAMPLINGMODE,
@@ -4064,6 +4067,10 @@
                 var width = texture.width;
                 var faceDataArrays = callback(data);
 
+                if (!faceDataArrays) {
+                    return;
+                }
+
                 if (mipmmapGenerator) {
                     var textureType = this._getWebGLTextureType(type);
                     var internalFormat = this._getInternalFormat(format);

+ 3 - 3
src/Engine/babylon.nullEngine.ts

@@ -79,7 +79,7 @@
             }   
         }
 
-        public createVertexBuffer(vertices: number[] | Float32Array): WebGLBuffer {
+        public createVertexBuffer(vertices: FloatArray): WebGLBuffer {
             return {
                 capacity: 0,
                 references: 1,
@@ -350,7 +350,7 @@
             this._currentFramebuffer = null;
         }
 
-        public createDynamicVertexBuffer(vertices: number[] | Float32Array): WebGLBuffer {
+        public createDynamicVertexBuffer(vertices: FloatArray): WebGLBuffer {
             var vbo = {
                 capacity: 1,
                 references: 1,                
@@ -363,7 +363,7 @@
         public updateDynamicIndexBuffer(indexBuffer: WebGLBuffer, indices: IndicesArray, offset: number = 0): void {
         }
 
-        public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: number[] | Float32Array, offset?: number, count?: number): void {
+        public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, offset?: number, count?: number): void {
         }        
 
         public _bindTextureDirectly(target: number, texture: InternalTexture): void {

+ 65 - 37
src/Materials/Textures/babylon.hdrCubeTexture.ts

@@ -24,8 +24,8 @@ module BABYLON {
         private _size: number;
         private _usePMREMGenerator: boolean;
         private _isBABYLONPreprocessed = false;
-        private _onLoad: () => void = null;
-        private _onError: () => void = null;
+        private _onLoad: Nullable<() => void> = null;
+        private _onError: Nullable<() => void> = null;
 
         /**
          * The texture URL.
@@ -68,7 +68,7 @@ module BABYLON {
          * @param useInGammaSpace Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)
          * @param usePMREMGenerator Specifies wether or not to generate the CubeMap through CubeMapGen to avoid seams issue at run time.
          */
-        constructor(url: string, scene: Scene, size?: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false, usePMREMGenerator = false, onLoad: () => void = null, onError: (message?: string, exception?: any) => void = null) {
+        constructor(url: string, scene: Scene, size?: number, noMipmap = false, generateHarmonics = true, useInGammaSpace = false, usePMREMGenerator = false, onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null) {
             super(scene);
 
             if (!url) {
@@ -84,22 +84,23 @@ module BABYLON {
             this._onError = onError;
             this.gammaSpace = false;
 
+            let caps = scene.getEngine().getCaps();
+
             if (size) {
                 this._isBABYLONPreprocessed = false;
                 this._noMipmap = noMipmap;
                 this._size = size;
                 this._useInGammaSpace = useInGammaSpace;
                 this._usePMREMGenerator = usePMREMGenerator &&
-                    scene.getEngine().getCaps().textureLOD &&
-                    this.getScene().getEngine().getCaps().textureFloat &&
+                        caps.textureLOD &&
+                        caps.textureFloat &&
                     !this._useInGammaSpace;
             }
             else {
                 this._isBABYLONPreprocessed = true;
                 this._noMipmap = false;
                 this._useInGammaSpace = false;
-                this._usePMREMGenerator = scene.getEngine().getCaps().textureLOD &&
-                    this.getScene().getEngine().getCaps().textureFloat &&
+                this._usePMREMGenerator = caps.textureLOD && caps.textureFloat &&
                     !this._useInGammaSpace;
             }
             this.isPMREM = this._usePMREMGenerator;
@@ -121,10 +122,15 @@ module BABYLON {
         private loadBabylonTexture() {
 
             var mipLevels = 0;
-            var floatArrayView: Float32Array = null;
+            var floatArrayView: Nullable<Float32Array> = null;
+            let scene = this.getScene();
 
-            var mipmapGenerator = (!this._useInGammaSpace && this.getScene().getEngine().getCaps().textureFloat) ? (data: ArrayBufferView[]): Array<Array<Float32Array>> => {
+            var mipmapGenerator = (!this._useInGammaSpace && scene && scene.getEngine().getCaps().textureFloat) ? (data: ArrayBufferView[]): Array<Array<Float32Array>> => {
                 var mips = new Array<Array<Float32Array>>();
+
+                if (!floatArrayView) {
+                    return mips;
+                }
                 var startIndex = 30;
                 for (var level = 0; level < mipLevels; level++) {
                     mips.push([]);
@@ -143,6 +149,11 @@ module BABYLON {
             } : null;
 
             var callback = (buffer: ArrayBuffer) => {
+                let scene = this.getScene();
+
+                if (!scene) {
+                    return null;
+                }
                 // Create Native Array Views
                 var intArrayView = new Int32Array(buffer);
                 floatArrayView = new Float32Array(buffer);
@@ -152,6 +163,9 @@ module BABYLON {
                 this._size = intArrayView[1]; // CubeMap max mip face size.
 
                 // Update Texture Information.
+                if (!this._texture) {
+                    return null;
+                }
                 this._texture.updateSize(this._size, this._size);
 
                 // Fill polynomial information.
@@ -178,7 +192,7 @@ module BABYLON {
                 }
 
                 var results = [];
-                var byteArray: Uint8Array = null;
+                var byteArray: Nullable<Uint8Array> = null;
 
                 // Push each faces.
                 for (var k = 0; k < 6; k++) {
@@ -191,8 +205,8 @@ module BABYLON {
                     }
 
                     // If special cases.
-                    if (!mipmapGenerator) {
-                        if (!this.getScene().getEngine().getCaps().textureFloat) {
+                    if (!mipmapGenerator && dataFace) {
+                        if (!scene.getEngine().getCaps().textureFloat) {
                             // 3 channels of 1 bytes per pixel in bytes.
                             var byteBuffer = new ArrayBuffer(faceSize);
                             byteArray = new Uint8Array(byteBuffer);
@@ -242,19 +256,26 @@ module BABYLON {
                 return results;
             }
 
-            this._texture = (<any>this.getScene().getEngine()).createRawCubeTextureFromUrl(this.url, this.getScene(), this._size,
-                Engine.TEXTUREFORMAT_RGB,
-                this.getScene().getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT,
-                this._noMipmap,
-                callback,
-                mipmapGenerator, this._onLoad, this._onError);
+            if (scene) {
+                this._texture = (<any>scene.getEngine()).createRawCubeTextureFromUrl(this.url, scene, this._size,
+                    Engine.TEXTUREFORMAT_RGB,
+                    scene.getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT,
+                    this._noMipmap,
+                    callback,
+                    mipmapGenerator, this._onLoad, this._onError);
+            }
         }
 
         /**
          * Occurs when the file is raw .hdr file.
          */
         private loadHDRTexture() {
-            var callback = (buffer: ArrayBuffer) => {
+            var callback = (buffer: ArrayBuffer): Nullable<ArrayBufferView[]> => {
+                let scene = this.getScene();
+
+                if (!scene) {
+                    return null;
+                }
                 // Extract the raw linear data.
                 var data = BABYLON.Internals.HDRTools.GetCubeMapTextureData(buffer, this._size);
 
@@ -265,13 +286,13 @@ module BABYLON {
                 }
 
                 var results = [];
-                var byteArray: Uint8Array = null;
+                var byteArray: Nullable<Uint8Array> = null;
 
                 // Push each faces.
                 for (var j = 0; j < 6; j++) {
 
                     // Create uintarray fallback.
-                    if (!this.getScene().getEngine().getCaps().textureFloat) {
+                    if (!scene.getEngine().getCaps().textureFloat) {
                         // 3 channels of 1 bytes per pixel in bytes.
                         var byteBuffer = new ArrayBuffer(this._size * this._size * 3);
                         byteArray = new Uint8Array(byteBuffer);
@@ -343,13 +364,16 @@ module BABYLON {
             //         return generator.filterCubeMap();
             //     };
             // }
-
-            this._texture = this.getScene().getEngine().createRawCubeTextureFromUrl(this.url, this.getScene(), this._size,
-                Engine.TEXTUREFORMAT_RGB,
-                this.getScene().getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT,
-                this._noMipmap,
-                callback,
-                mipmapGenerator, this._onLoad, this._onError);
+            let scene = this.getScene();
+
+            if (scene) {
+                this._texture = scene.getEngine().createRawCubeTextureFromUrl(this.url, scene, this._size,
+                    Engine.TEXTUREFORMAT_RGB,
+                    scene.getEngine().getCaps().textureFloat ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT,
+                    this._noMipmap,
+                    callback,
+                    mipmapGenerator, this._onLoad, this._onError);
+            }
         }
 
         /**
@@ -365,8 +389,13 @@ module BABYLON {
         }
 
         public clone(): HDRCubeTexture {
-            var size = this._isBABYLONPreprocessed ? null : this._size;
-            var newTexture = new HDRCubeTexture(this.url, this.getScene(), size, this._noMipmap,
+            let scene = this.getScene();
+            if (!scene) {
+                return this;
+            }
+
+            var size = <number>(this._isBABYLONPreprocessed ? null : this._size);
+            var newTexture = new HDRCubeTexture(this.url, scene, size, this._noMipmap,
                 this._generateHarmonics, this._useInGammaSpace, this._usePMREMGenerator);
 
             // Base texture
@@ -401,7 +430,7 @@ module BABYLON {
             this._textureMatrix = value;
         }
 
-        public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): HDRCubeTexture {
+        public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): Nullable<HDRCubeTexture> {
             var texture = null;
             if (parsedTexture.name && !parsedTexture.isRenderTarget) {
                 var size = parsedTexture.isBABYLONPreprocessed ? null : parsedTexture.size;
@@ -448,7 +477,7 @@ module BABYLON {
          * @param onError Method called if any error happens during download.
          * @return The packed binary data.
          */
-        public static generateBabylonHDROnDisk(url: string, size: number, onError: (() => void) = null): void {
+        public static generateBabylonHDROnDisk(url: string, size: number, onError: Nullable<(() => void)> = null): void {
             var callback = function (buffer: ArrayBuffer) {
                 var data = new Blob([buffer], { type: 'application/octet-stream' });
 
@@ -476,20 +505,19 @@ module BABYLON {
          * @param onError Method called if any error happens during download.
          * @return The packed binary data.
          */
-        public static generateBabylonHDR(url: string, size: number, callback: ((ArrayBuffer: ArrayBuffer) => void), onError: (() => void) = null): void {
+        public static generateBabylonHDR(url: string, size: number, callback: ((ArrayBuffer: ArrayBuffer) => void), onError: Nullable<(() => void)> = null): void {
             // Needs the url tho create the texture.
             if (!url) {
-                return null;
+                return;
             }
 
             // Check Power of two size.
             if (!Tools.IsExponentOfTwo(size)) { // Need to check engine.needPOTTextures 
-                return null;
+                return;
             }
 
-            // Coming Back in 3.1.
+            // Coming Back in 3.x.
             Tools.Error("Generation of Babylon HDR is coming back in 3.1.");
-            return null;
         }
     }
 }

+ 17 - 16
src/Materials/babylon.material.ts

@@ -254,7 +254,7 @@
         */
         public onDisposeObservable = new Observable<Material>();
 
-        private _onDisposeObserver: Observer<Material>;
+        private _onDisposeObserver: Nullable<Observer<Material>>;
         public set onDispose(callback: () => void) {
             if (this._onDisposeObserver) {
                 this.onDisposeObservable.remove(this._onDisposeObserver);
@@ -268,7 +268,7 @@
         */
         public onBindObservable = new Observable<AbstractMesh>();
 
-        private _onBindObserver: Observer<AbstractMesh>;
+        private _onBindObserver: Nullable<Observer<AbstractMesh>>;
         public set onBind(callback: (Mesh: AbstractMesh) => void) {
             if (this._onBindObserver) {
                 this.onBindObservable.remove(this._onBindObserver);
@@ -370,7 +370,7 @@
             this.markAsDirty(Material.MiscDirtyFlag);
         }
 
-        public _effect: Effect;
+        public _effect: Nullable<Effect>;
         public _wasPreviouslyReady = false;
         private _useUBO: boolean;
         private _scene: Scene;
@@ -438,7 +438,7 @@
             return false;            
         }
 
-        public getEffect(): Effect {
+        public getEffect(): Nullable<Effect> {
             return this._effect;
         }
 
@@ -454,7 +454,7 @@
             return false;
         }
 
-        public getAlphaTestTexture(): BaseTexture {
+        public getAlphaTestTexture(): Nullable<BaseTexture> {
             return null;
         }
         
@@ -503,7 +503,7 @@
             }
         }
 
-        protected _afterBind(mesh: Mesh): void {
+        protected _afterBind(mesh?: Mesh): void {
             this._scene._cachedMaterial = this;
             if (mesh) {
                 this._scene._cachedVisibility = mesh.visibility;
@@ -511,7 +511,9 @@
                 this._scene._cachedVisibility = 1;
             }
 
-            this.onBindObservable.notifyObservers(mesh);
+            if (mesh) {
+                this.onBindObservable.notifyObservers(mesh);
+            }
 
             if (this.disableDepthWrite) {
                 var engine = this._scene.getEngine();
@@ -538,7 +540,7 @@
             return false;
         }
 
-        public clone(name: string): Material {
+        public clone(name: string): Nullable<Material> {
             return null;
         }
 
@@ -697,11 +699,14 @@
                     mesh.material = null;
                 
                     if ((<Mesh>mesh).geometry) {
-                        var geometry = (<Mesh>mesh).geometry;
+                        var geometry = <Geometry>((<Mesh>mesh).geometry);
 
                         if (this.storeEffectOnSubMeshes) {
                             for (var subMesh of mesh.subMeshes) {
                                 geometry._releaseVertexArrayObject(subMesh._materialEffect);
+                                if (forceDisposeEffect && subMesh._materialEffect) {
+                                    this._scene.getEngine()._releaseEffect(subMesh._materialEffect); 
+                                }
                             }
                         } else {
                             geometry._releaseVertexArrayObject(this._effect)
@@ -714,13 +719,9 @@
 
             // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
             if (forceDisposeEffect && this._effect) {
-                    if (this.storeEffectOnSubMeshes) {
-                        for (var subMesh of mesh.subMeshes) {
-                            this._scene.getEngine()._releaseEffect(subMesh._materialEffect); 
-                        }
-                    } else {
-                        this._scene.getEngine()._releaseEffect(this._effect);                    
-                    }
+                if (!this.storeEffectOnSubMeshes) {
+                    this._scene.getEngine()._releaseEffect(this._effect);                    
+                }
 
                 this._effect = null;
             }

+ 11 - 7
src/Materials/babylon.materialHelper.ts

@@ -89,7 +89,7 @@
             }
 
             if (useBones) {
-                if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                     defines["NUM_BONE_INFLUENCERS"] = mesh.numBoneInfluencers;
                     defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
                 } else {
@@ -224,7 +224,8 @@
         }
 
         public static PrepareUniformsAndSamplersList(uniformsListOrOptions: string[] | EffectCreationOptions, samplersList?: string[], defines?: any, maxSimultaneousLights = 4): void {
-            var uniformsList: string[], uniformBuffersList: string[], samplersList: string[], defines: any;
+            let uniformsList: string[];
+            let uniformBuffersList: Nullable<string[]> = null;
 
             if ((<EffectCreationOptions>uniformsListOrOptions).uniformsNames) {
                 var options = <EffectCreationOptions>uniformsListOrOptions;
@@ -235,6 +236,9 @@
                 maxSimultaneousLights = options.maxSimultaneousLights;
             } else {
                 uniformsList = <string[]>uniformsListOrOptions;
+                if (!samplersList) {
+                    samplersList = [];
+                }
             }
 
             for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
@@ -296,7 +300,7 @@
         public static PrepareAttributesForMorphTargets(attribs: string[], mesh: AbstractMesh, defines: any): void {
             var influencers = defines["NUM_MORPH_INFLUENCERS"];
 
-            if (influencers > 0) {
+            if (influencers > 0 && Engine.LastCreatedEngine) {
                 var maxAttributesCount = Engine.LastCreatedEngine.getCaps().maxVertexAttribs;
                 var manager = (<Mesh>mesh).morphTargetManager;
                 var normal = manager.supportsNormals && defines["NORMAL"];
@@ -389,11 +393,11 @@
             }
         }
 
-        public static BindBonesParameters(mesh: AbstractMesh, effect: Effect): void {
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+        public static BindBonesParameters(mesh?: AbstractMesh, effect?: Effect): void {
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                 var matrices = mesh.skeleton.getTransformMatrices(mesh);
 
-                if (matrices) {
+                if (matrices && effect) {
                     effect.setMatrices("mBones", matrices);
                 }
             }
@@ -409,7 +413,7 @@
 
         public static BindLogDepth(defines: any, effect: Effect, scene: Scene): void {
             if (defines["LOGARITHMICDEPTH"]) {
-                effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
+                effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log((<Camera>scene.activeCamera).maxZ + 1.0) / Math.LN2));
             }
         }
 

+ 19 - 13
src/Materials/babylon.multiMaterial.ts

@@ -1,11 +1,11 @@
 module BABYLON {
     export class MultiMaterial extends Material {
-        private _subMaterials: Material[];
-        public get subMaterials(): Material[] {
+        private _subMaterials: Nullable<Material>[];
+        public get subMaterials(): Nullable<Material>[] {
             return this._subMaterials;
         }
 
-        public set subMaterials(value: Material[]) {
+        public set subMaterials(value: Nullable<Material>[]) {
             this._subMaterials = value;
             this._hookArray(value);
         }
@@ -20,9 +20,9 @@
             this.storeEffectOnSubMeshes = true; // multimaterial is considered like a push material
         }
 
-        private _hookArray(array: Material[]): void {
+        private _hookArray(array: Nullable<Material>[]): void {
             var oldPush = array.push;
-            array.push = (...items: Material[]) => {
+            array.push = (...items: Nullable<Material>[]) => {
                 var result = oldPush.apply(array, items);
 
                 this._markAllSubMeshesAsTexturesDirty();
@@ -41,7 +41,7 @@
         }    
 
         // Properties
-        public getSubMaterial(index: number): Material {
+        public getSubMaterial(index: number): Nullable<Material> {
             if (index < 0 || index >= this.subMaterials.length) {
                 return this.getScene().defaultMaterial;
             }
@@ -50,7 +50,12 @@
         }
 
         public getActiveTextures(): BaseTexture[] {
-            return super.getActiveTextures().concat(...this.subMaterials.map(subMaterial => subMaterial.getActiveTextures()));
+            return super.getActiveTextures().concat(...this.subMaterials.map(subMaterial => {
+                if (subMaterial) {
+                return subMaterial.getActiveTextures();
+            } else {
+                return [];
+            }}));
         }
 
         // Methods
@@ -62,14 +67,14 @@
             for (var index = 0; index < this.subMaterials.length; index++) {
                 var subMaterial = this.subMaterials[index];
                 if (subMaterial) {
-                    if (this.subMaterials[index].storeEffectOnSubMeshes) {
-                        if (!this.subMaterials[index].isReadyForSubMesh(mesh, subMesh, useInstances)) {
+                    if (subMaterial.storeEffectOnSubMeshes) {
+                        if (!subMaterial.isReadyForSubMesh(mesh, subMesh, useInstances)) {
                             return false;
                         }
                         continue;
                     }
 
-                    if (!this.subMaterials[index].isReady(mesh)) {
+                    if (!subMaterial.isReady(mesh)) {
                         return false;
                     }
                 }
@@ -82,9 +87,10 @@
             var newMultiMaterial = new MultiMaterial(name, this.getScene());
 
             for (var index = 0; index < this.subMaterials.length; index++) {
-                var subMaterial: Material = null;
-                if (cloneChildren) {
-                    subMaterial = this.subMaterials[index].clone(name + "-" + this.subMaterials[index].name);
+                var subMaterial: Nullable<Material> = null;
+                let current = this.subMaterials[index];
+                if (cloneChildren && current) {
+                    subMaterial = current.clone(name + "-" + current.name);
                 } else {
                     subMaterial = this.subMaterials[index];
                 }

+ 8 - 4
src/Materials/babylon.shaderMaterial.ts

@@ -204,7 +204,7 @@
             }
             
             // Bones
-            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
+            if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
                 if (mesh.numBoneInfluencers > 4) {
@@ -265,6 +265,10 @@
         public bindOnlyWorldMatrix(world: Matrix): void {
             var scene = this.getScene();
 
+            if (!this._effect) {
+                return;
+            }
+
             if (this._options.uniforms.indexOf("world") !== -1) {
                 this._effect.setMatrix("world", world);
             }
@@ -283,7 +287,7 @@
             // Std values
             this.bindOnlyWorldMatrix(world);
 
-            if (this.getScene().getCachedMaterial() !== this) {
+            if (this._effect && this.getScene().getCachedMaterial() !== this) {
                 if (this._options.uniforms.indexOf("view") !== -1) {
                     this._effect.setMatrix("view", this.getScene().getViewMatrix());
                 }
@@ -473,9 +477,9 @@
             }
 
             // Float s   
-            serializationObject.floatArrays = {};
+            serializationObject.FloatArrays = {};
             for (name in this._floatsArrays) {
-                serializationObject.floatArrays[name] = this._floatsArrays[name];
+                serializationObject.FloatArrays[name] = this._floatsArrays[name];
             }
 
             // Color3    

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

@@ -414,7 +414,7 @@ module BABYLON {
          * @param {number[]|Float32Array} data Flattened data
          * @param {number} size Size of the data.
          */
-        public updateUniform(uniformName: string, data: number[] | Float32Array, size: number) {
+        public updateUniform(uniformName: string, data: FloatArray, size: number) {
 
             var location = this._uniformLocations[uniformName];
             if (location === undefined) {
@@ -586,7 +586,7 @@ module BABYLON {
          * @param {string} uniformName Name of the uniform, as used in the uniform block in the shader.
          * @param {number[]|Float32Array} data Flattened data
          */
-        public updateUniformDirectly(uniformName: string, data: number[] | Float32Array) {
+        public updateUniformDirectly(uniformName: string, data: FloatArray) {
             this.updateUniform(uniformName, data, data.length);
 
             this.update();

+ 4 - 4
src/Math/babylon.math.ts

@@ -38,7 +38,7 @@
          * Stores in the passed array from the passed starting index the red, green, blue values as successive elements.  
          * Returns the Color3.  
          */
-        public toArray(array: number[] | Float32Array, index?: number): Color3 {
+        public toArray(array: FloatArray, index?: number): Color3 {
             if (index === undefined) {
                 index = 0;
             }
@@ -624,7 +624,7 @@
          * Sets the Vector2 coordinates in the passed array or Float32Array from the passed index.  
          * Returns the Vector2.  
          */
-        public toArray(array: number[] | Float32Array, index: number = 0): Vector2 {
+        public toArray(array: FloatArray, index: number = 0): Vector2 {
             array[index] = this.x;
             array[index + 1] = this.y;
             return this;
@@ -1075,7 +1075,7 @@
          * Populates the passed array or Float32Array from the passed index with the successive coordinates of the Vector3.  
          * Returns the Vector3.  
          */
-        public toArray(array: number[] | Float32Array, index: number = 0): Vector3 {
+        public toArray(array: FloatArray, index: number = 0): Vector3 {
             array[index] = this.x;
             array[index + 1] = this.y;
             array[index + 2] = this.z;
@@ -1852,7 +1852,7 @@
          * Populates the passed array from the passed index with the Vector4 coordinates.  
          * Returns the Vector4.  
          */
-        public toArray(array: number[] | Float32Array, index?: number): Vector4 {
+        public toArray(array: FloatArray, index?: number): Vector4 {
             if (index === undefined) {
                 index = 0;
             }

+ 9 - 9
src/Mesh/babylon.abstractMesh.ts

@@ -207,11 +207,11 @@
         public isBlocker = false;
         public enablePointerMoveEvents = false;
         public renderingGroupId = 0;
-        private _material: Material
-        public get material(): Material {
+        private _material: Nullable<Material>
+        public get material(): Nullable<Material> {
             return this._material;
         }
-        public set material(value: Material) {
+        public set material(value: Nullable<Material>) {
             if (this._material === value) {
                 return;
             }
@@ -392,7 +392,7 @@
         private _collisionsTransformMatrix = Matrix.Zero();
         private _collisionsScalingMatrix = Matrix.Zero();
         private _isDirty = false;
-        public _masterMesh: AbstractMesh;
+        public _masterMesh: Nullable<AbstractMesh>;
 
         public _boundingInfo: Nullable<BoundingInfo>;
         private _pivotMatrix = Matrix.Identity();
@@ -703,7 +703,7 @@
          * Returns the array of the requested vertex data kind. Used by the class Mesh. Returns null here. 
          * Returned type : float array or Float32Array 
          */
-        public getVerticesData(kind: string): Nullable<number[] | Float32Array> {
+        public getVerticesData(kind: string): Nullable<FloatArray> {
             return null;
         }
         /**
@@ -731,7 +731,7 @@
          * 
          * Returns the Mesh.  
          */
-        public setVerticesData(kind: string, data: number[] | Float32Array, updatable?: boolean, stride?: number): AbstractMesh {
+        public setVerticesData(kind: string, data: FloatArray, updatable?: boolean, stride?: number): AbstractMesh {
             return this;
         }
 
@@ -759,7 +759,7 @@
          * 
          * Returns the Mesh.  
          */
-        public updateVerticesData(kind: string, data: number[] | Float32Array, updateExtends?: boolean, makeItUnique?: boolean): AbstractMesh {
+        public updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): AbstractMesh {
             return this;
         }
 
@@ -2407,10 +2407,10 @@
         public createNormals(updatable: boolean) {
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
             var indices = this.getIndices();
-            var normals: number[] | Float32Array;
+            var normals: FloatArray;
 
             if (this.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                normals = (<number[] | Float32Array>this.getVerticesData(VertexBuffer.NormalKind));
+                normals = (<FloatArray>this.getVerticesData(VertexBuffer.NormalKind));
             } else {
                 normals = [];
             }

+ 5 - 5
src/Mesh/babylon.buffer.ts

@@ -2,13 +2,13 @@
     export class Buffer {
         private _engine: Engine;
         private _buffer: Nullable<WebGLBuffer>;
-        private _data: Nullable<number[] | Float32Array>;
+        private _data: Nullable<FloatArray>;
         private _updatable: boolean;
         private _strideSize: number;
         private _instanced: boolean;
         private _instanceDivisor: number;
 
-        constructor(engine: any, data: number[] | Float32Array, updatable: boolean, stride: number, postponeInternalCreation?: boolean, instanced: boolean = false) {
+        constructor(engine: any, data: FloatArray, updatable: boolean, stride: number, postponeInternalCreation?: boolean, instanced: boolean = false) {
             if (engine instanceof Mesh) { // old versions of BABYLON.VertexBuffer accepted 'mesh' instead of 'engine'
                 this._engine = engine.getScene().getEngine();
             }
@@ -40,7 +40,7 @@
             return this._updatable;
         }
 
-        public getData(): Nullable<number[] | Float32Array> {
+        public getData(): Nullable<FloatArray> {
             return this._data;
         }
 
@@ -70,7 +70,7 @@
         }
 
         // Methods
-        public create(data: Nullable<number[] | Float32Array> = null): void {
+        public create(data: Nullable<FloatArray> = null): void {
             if (!data && this._buffer) {
                 return; // nothing to do
             }
@@ -99,7 +99,7 @@
             this.create(this._data);
         }
 
-        public update(data: number[] | Float32Array): void {
+        public update(data: FloatArray): void {
             this.create(data);
         }
 

+ 14 - 10
src/Mesh/babylon.geometry.ts

@@ -129,7 +129,7 @@
             this.notifyUpdate();
         }
 
-        public setVerticesData(kind: string, data: number[] | Float32Array, updatable: boolean = false, stride?: number): void {
+        public setVerticesData(kind: string, data: FloatArray, updatable: boolean = false, stride?: number): void {
             var buffer = new VertexBuffer(this._engine, data, kind, updatable, this._meshes.length === 0, stride);
 
             this.setVerticesBuffer(buffer);
@@ -189,7 +189,7 @@
             this.notifyUpdate(kind);
         }
 
-        public updateVerticesData(kind: string, data: number[] | Float32Array, updateExtends: boolean = false): void {
+        public updateVerticesData(kind: string, data: FloatArray, updateExtends: boolean = false): void {
             var vertexBuffer = this.getVertexBuffer(kind);
 
             if (!vertexBuffer) {
@@ -208,7 +208,7 @@
             this.notifyUpdate(kind);
         }
 
-        private updateBoundingInfo(updateExtends: boolean, data: Nullable<number[] | Float32Array>) {
+        private updateBoundingInfo(updateExtends: boolean, data: Nullable<FloatArray>) {
             if (updateExtends) {
                 this.updateExtend(data);
             }
@@ -231,7 +231,11 @@
             }
         }
 
-        public _bind(effect: Effect, indexToBind?: Nullable<WebGLBuffer>): void {
+        public _bind(effect: Nullable<Effect>, indexToBind?: Nullable<WebGLBuffer>): void {
+            if (!effect) {
+                return;
+            }
+
             if (indexToBind === undefined) {
                 indexToBind = this._indexBuffer;
             }
@@ -262,7 +266,7 @@
             return this._totalVertices;
         }
 
-        public getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<number[] | Float32Array> {
+        public getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray> {
             var vertexBuffer = this.getVertexBuffer(kind);
             if (!vertexBuffer) {
                 return null;
@@ -399,7 +403,7 @@
             return this._indexBuffer;
         }
 
-        public _releaseVertexArrayObject(effect: Effect) {
+        public _releaseVertexArrayObject(effect: Nullable<Effect> = null) {
             if (!effect || !this._vertexArrayObjects) {
                 return;
             }
@@ -454,7 +458,7 @@
             }
         }
 
-        private updateExtend(data: Nullable<number[] | Float32Array> = null, stride? : number) {
+        private updateExtend(data: Nullable<FloatArray> = null, stride? : number) {
             if (!data) {
                 data = this._vertexBuffers[VertexBuffer.PositionKind].getData();
             }
@@ -1054,8 +1058,8 @@
             } else {
                 return;
             }
-            let matricesIndices = mesh.getVerticesData(VertexBuffer.MatricesIndicesKind);
-            let matricesIndicesExtra = mesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind);
+            let matricesIndices = (<FloatArray>mesh.getVerticesData(VertexBuffer.MatricesIndicesKind));
+            let matricesIndicesExtra = (<FloatArray>mesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind));
             let matricesWeights = parsedGeometry.matricesWeights;
             let matricesWeightsExtra = parsedGeometry.matricesWeightsExtra;
             let influencers = parsedGeometry.numBoneInfluencer;
@@ -1214,7 +1218,7 @@
                 super.setAllVerticesData(vertexData, false);
             }
 
-            public setVerticesData(kind: string, data: number[] | Float32Array, updatable?: boolean): void {
+            public setVerticesData(kind: string, data: FloatArray, updatable?: boolean): void {
                 if (!this._beingRegenerated) {
                     return;
                 }

+ 5 - 5
src/Mesh/babylon.instancedMesh.ts

@@ -42,7 +42,7 @@
             return this._sourceMesh.receiveShadows;
         }
 
-        public get material(): Material {
+        public get material(): Nullable<Material> {
             return this._sourceMesh.material;
         }
 
@@ -72,7 +72,7 @@
         /**
          * Returns a float array or a Float32Array of the requested kind of data : positons, normals, uvs, etc.  
          */
-        public getVerticesData(kind: string, copyWhenShared?: boolean): number[] | Float32Array {
+        public getVerticesData(kind: string, copyWhenShared?: boolean): Nullable<FloatArray> {
             return this._sourceMesh.getVerticesData(kind, copyWhenShared);
         }
 
@@ -101,7 +101,7 @@
          * 
          * Returns the Mesh.  
          */
-        public setVerticesData(kind: string, data: number[] | Float32Array, updatable?: boolean, stride?: number): Mesh {
+        public setVerticesData(kind: string, data: FloatArray, updatable?: boolean, stride?: number): Mesh {
             if (this.sourceMesh) {
                this.sourceMesh.setVerticesData(kind, data, updatable, stride);
             }
@@ -132,7 +132,7 @@
          * 
          * Returns the Mesh.  
          */
-        public updateVerticesData(kind: string, data: number[] | Float32Array, updateExtends?: boolean, makeItUnique?: boolean): Mesh {
+        public updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): Mesh {
             if (this.sourceMesh) {
                this.sourceMesh.updateVerticesData(kind, data, updateExtends, makeItUnique);
             }
@@ -163,7 +163,7 @@
         /**
          * Returns an array of indices (IndicesArray).  
          */
-        public getIndices(): IndicesArray {
+        public getIndices(): Nullable<IndicesArray> {
             return this._sourceMesh.getIndices();
         }
 

+ 5 - 3
src/Mesh/babylon.linesMesh.ts

@@ -34,7 +34,7 @@ module BABYLON {
         private _intersectionThreshold: number;
         private _colorShader: ShaderMaterial;
 
-        constructor(name: string, scene: Scene, parent: Node = null, source?: LinesMesh, doNotCloneChildren?: boolean, public useVertexColor? : boolean) {
+        constructor(name: string, scene: Scene, parent: Nullable<Node> = null, source?: LinesMesh, doNotCloneChildren?: boolean, public useVertexColor? : boolean) {
             super(name, scene, parent, source, doNotCloneChildren);
 
             if (source) {
@@ -75,11 +75,13 @@ module BABYLON {
         }
 
         public createInstance(name: string): InstancedMesh {
-            Tools.Log("LinesMeshes do not support createInstance.");
-            return null;
+            throw new Error("LinesMeshes do not support createInstance.");
         }
 
         public _bind(subMesh: SubMesh, effect: Effect, fillMode: number): LinesMesh {
+            if (!this._geometry) {
+                return this;
+            }
             // VBOs
             this._geometry._bind(this._colorShader.getEffect() );
 

+ 53 - 21
src/Mesh/babylon.mesh.ts

@@ -249,7 +249,17 @@
             }
 
             if (fullDetails) {
-                ret += ", flat shading: " + (this._geometry ? (this.getVerticesData(VertexBuffer.PositionKind).length / 3 === this.getIndices().length ? "YES" : "NO") : "UNKNOWN");
+
+                if (this._geometry) {
+                    let ib = this.getIndices();
+                    let vb = this.getVerticesData(VertexBuffer.PositionKind);
+
+                    if (vb && ib) {
+                        ret += ", flat shading: " + (vb.length / 3 === ib.length ? "YES" : "NO");
+                    }
+                } else {
+                    ret += ", flat shading: UNKNOWN";
+                }
             }
             return ret;
         }
@@ -305,7 +315,7 @@
          * tuto : http://doc.babylonjs.com/tutorials/How_to_use_LOD   
          * Returns an object Mesh or `null`.  
          */
-        public getLODLevelAtDistance(distance: number): Mesh {
+        public getLODLevelAtDistance(distance: number): Nullable<Mesh> {
             for (var index = 0; index < this._LODLevels.length; index++) {
                 var level = this._LODLevels[index];
 
@@ -346,7 +356,21 @@
                 return this;
             }
 
-            var distanceToCamera = (boundingSphere ? boundingSphere : this.getBoundingInfo().boundingSphere).centerWorld.subtract(camera.globalPosition).length();
+            let bSphere: BoundingSphere;
+
+            if (boundingSphere) {
+                bSphere = boundingSphere;
+            } else {
+                let boundingInfo = this.getBoundingInfo();
+
+                if (!boundingInfo) {
+                    return this;
+                }
+
+                bSphere =  boundingInfo.boundingSphere;
+            }
+
+            var distanceToCamera = bSphere.centerWorld.subtract(camera.globalPosition).length();
 
             if (this._LODLevels[this._LODLevels.length - 1].distance > distanceToCamera) {
                 if (this.onLODLevelSelection) {
@@ -379,7 +403,7 @@
         /**
          * Returns the mesh internal Geometry object.  
          */
-        public get geometry(): Geometry {
+        public get geometry(): Nullable<Geometry> {
             return this._geometry;
         }
 
@@ -412,7 +436,7 @@
          * - BABYLON.VertexBuffer.MatricesWeightsKind
          * - BABYLON.VertexBuffer.MatricesWeightsExtraKind 
          */
-        public getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): number[] | Float32Array {
+        public getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray> {
             if (!this._geometry) {
                 return null;
             }
@@ -421,7 +445,7 @@
 
         /**
          * Returns the mesh VertexBuffer object from the requested `kind` : positions, indices, normals, etc.
-         * Returns `undefined` if the mesh has no geometry.   
+         * Returns `null` if the mesh has no geometry.   
          * Possible `kind` values :
          * - BABYLON.VertexBuffer.PositionKind
          * - BABYLON.VertexBuffer.UVKind
@@ -436,9 +460,9 @@
          * - BABYLON.VertexBuffer.MatricesWeightsKind
          * - BABYLON.VertexBuffer.MatricesWeightsExtraKind 
          */
-        public getVertexBuffer(kind: string): VertexBuffer {
+        public getVertexBuffer(kind: string): Nullable<VertexBuffer> {
             if (!this._geometry) {
-                return undefined;
+                return null;
             }
             return this._geometry.getVertexBuffer(kind);
         }
@@ -513,7 +537,7 @@
          * If the parameter `copyWhenShared` is true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.
          * Returns an empty array if the mesh has no geometry.
          */
-        public getIndices(copyWhenShared?: boolean): IndicesArray {
+        public getIndices(copyWhenShared?: boolean): Nullable<IndicesArray> {
 
             if (!this._geometry) {
                 return [];
@@ -613,7 +637,7 @@
          * Returns the Mesh.  
          */
         public refreshBoundingInfo(): Mesh {
-            if (this._boundingInfo.isLocked) {
+            if (this._boundingInfo && this._boundingInfo.isLocked) {
                 return this;
             }
             var data = this.getVerticesData(VertexBuffer.PositionKind);
@@ -633,7 +657,7 @@
             return this;
         }
 
-        public _createGlobalSubMesh(force: boolean): SubMesh {
+        public _createGlobalSubMesh(force: boolean): Nullable<SubMesh> {
             var totalVertices = this.getTotalVertices();
             if (!totalVertices || !this.getIndices()) {
                 return null;
@@ -641,7 +665,13 @@
 
             // Check if we need to recreate the submeshes
             if (this.subMeshes && this.subMeshes.length > 0) {
-                var totalIndices = this.getIndices().length;
+                let ib = this.getIndices();
+
+                if (!ib) {
+                    return null;
+                }
+
+                var totalIndices = ib.length;
                 let needToRecreate = false;
 
                 if (force) {
@@ -722,7 +752,7 @@
          * 
          * Returns the Mesh.  
          */
-        public setVerticesData(kind: string, data: number[] | Float32Array, updatable: boolean = false, stride?: number): Mesh {
+        public setVerticesData(kind: string, data: FloatArray, updatable: boolean = false, stride?: number): Mesh {
             if (!this._geometry) {
                 var vertexData = new VertexData();
                 vertexData.set(data, kind);
@@ -738,11 +768,13 @@
         }
 
         public markVerticesDataAsUpdatable(kind: string, updatable = true) {
-            if (this.getVertexBuffer(kind).isUpdatable() === updatable) {
+            let vb = this.getVertexBuffer(kind);
+
+            if (!vb || vb.isUpdatable() === updatable) {
                 return;
             }
 
-            this.setVerticesData(kind, this.getVerticesData(kind), updatable);
+            this.setVerticesData(kind, (<FloatArray>this.getVerticesData(kind)), updatable);
         }
 
         /**
@@ -784,7 +816,7 @@
          * 
          * Returns the Mesh.  
          */
-        public updateVerticesData(kind: string, data: number[] | Float32Array, updateExtends?: boolean, makeItUnique?: boolean): Mesh {
+        public updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): Mesh {
             if (!this._geometry) {
                 return this;
             }
@@ -805,7 +837,7 @@
          * The parameter `computeNormals` is a boolean (default true) to enable/disable the mesh normal recomputation after the vertex position update.     
          * Returns the Mesh.  
          */
-        public updateMeshPositions(positionFunction: (data: number[] | Float32Array) => void, computeNormals: boolean = true): Mesh {
+        public updateMeshPositions(positionFunction: (data: FloatArray) => void, computeNormals: boolean = true): Mesh {
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
             positionFunction(positions);
             this.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);
@@ -1644,7 +1676,7 @@
 
             var kinds = this.getVerticesDataKinds();
             var vbs: { [key: string]: VertexBuffer } = {};
-            var data: { [key: string]: number[] | Float32Array } = {};
+            var data: { [key: string]: FloatArray } = {};
             var newdata: { [key: string]: Array<number> } = {};
             var updatableNormals = false;
             var kindIndex: number;
@@ -1743,7 +1775,7 @@
 
             var kinds = this.getVerticesDataKinds();
             var vbs: { [key: string]: VertexBuffer } = {};
-            var data: { [key: string]: number[] | Float32Array } = {};
+            var data: { [key: string]: FloatArray } = {};
             var newdata: { [key: string]: Array<number> } = {};
             var kindIndex: number;
             var kind: string;
@@ -2893,7 +2925,7 @@
          * @returns original positions used for CPU skinning.  Useful for integrating Morphing with skeletons in same mesh.
          */
         public setPositionsForCPUSkinning(): Float32Array {
-            var source: number[] | Float32Array;
+            var source: FloatArray;
             if (!this._sourcePositions) {
                 source = this.getVerticesData(VertexBuffer.PositionKind);
 
@@ -2910,7 +2942,7 @@
          * @returns original normals used for CPU skinning.  Useful for integrating Morphing with skeletons in same mesh.
          */
         public setNormalsForCPUSkinning(): Float32Array {
-            var source: number[] | Float32Array;
+            var source: FloatArray;
             if (!this._sourceNormals) {
                 source = this.getVerticesData(VertexBuffer.NormalKind);
 

+ 20 - 20
src/Mesh/babylon.mesh.vertexData.ts

@@ -4,31 +4,31 @@
     export interface IGetSetVerticesData
     {
         isVerticesDataPresent(kind: string): boolean;
-        getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<number[] | Float32Array>;
+        getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray>;
         getIndices(copyWhenShared?: boolean): Nullable<IndicesArray>;
-        setVerticesData(kind: string, data: number[] | Float32Array, updatable: boolean): void;
-        updateVerticesData(kind: string, data: number[] | Float32Array, updateExtends?: boolean, makeItUnique?: boolean): void;
+        setVerticesData(kind: string, data: FloatArray, updatable: boolean): void;
+        updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): void;
         setIndices(indices: IndicesArray, totalVertices: Nullable<number>, updatable?: boolean): void;
     }
 
     export class VertexData {
-        public positions: number[] | Float32Array;
-        public normals: number[] | Float32Array;
-        public tangents: number[] | Float32Array;
-        public uvs: number[] | Float32Array;
-        public uvs2: number[] | Float32Array;
-        public uvs3: number[] | Float32Array;
-        public uvs4: number[] | Float32Array;
-        public uvs5: number[] | Float32Array;
-        public uvs6: number[] | Float32Array;
-        public colors: number[] | Float32Array;
-        public matricesIndices: number[] | Float32Array;
-        public matricesWeights: number[] | Float32Array;
-        public matricesIndicesExtra: number[] | Float32Array;
-        public matricesWeightsExtra: number[] | Float32Array;
+        public positions: FloatArray;
+        public normals: FloatArray;
+        public tangents: FloatArray;
+        public uvs: FloatArray;
+        public uvs2: FloatArray;
+        public uvs3: FloatArray;
+        public uvs4: FloatArray;
+        public uvs5: FloatArray;
+        public uvs6: FloatArray;
+        public colors: FloatArray;
+        public matricesIndices: FloatArray;
+        public matricesWeights: FloatArray;
+        public matricesIndicesExtra: FloatArray;
+        public matricesWeightsExtra: FloatArray;
         public indices: IndicesArray;
 
-        public set(data: number[] | Float32Array, kind: string) {
+        public set(data: FloatArray, kind: string) {
             switch (kind) {
                 case VertexBuffer.PositionKind:
                     this.positions = data;
@@ -329,7 +329,7 @@
             return this;
         }
 
-        private _mergeElement(source: number[] | Float32Array, other: number[] | Float32Array, length = 0): number[] | Float32Array {
+        private _mergeElement(source: FloatArray, other: FloatArray, length = 0): FloatArray {
             if (!other && !source) {
                 return null;
             }
@@ -2392,7 +2392,7 @@
             }
         }
 
-        private static _ComputeSides(sideOrientation: number, positions: number[] | Float32Array, indices: number[] | Float32Array, normals: number[] | Float32Array, uvs: number[] | Float32Array, frontUVs?: Vector4, backUVs?: Vector4) {
+        private static _ComputeSides(sideOrientation: number, positions: FloatArray, indices: FloatArray, normals: FloatArray, uvs: FloatArray, frontUVs?: Vector4, backUVs?: Vector4) {
             var li: number = indices.length;
             var ln: number = normals.length;
             var i: number;

+ 2 - 2
src/Mesh/babylon.meshBuilder.ts

@@ -147,7 +147,7 @@
                 // only pathArray and sideOrientation parameters are taken into account for positions update
                 Vector3.FromFloatsToRef(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, Tmp.Vector3[0]);         // minimum
                 Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, Tmp.Vector3[1]);
-                var positionFunction = (positions: number[] | Float32Array) => {
+                var positionFunction = (positions: FloatArray) => {
                     var minlg = pathArray[0].length;
                     var i = 0;
                     var ns = (instance._originalBuilderSideOrientation === Mesh.DOUBLESIDE) ? 2 : 1;
@@ -367,7 +367,7 @@
             var lines = options.lines;
 
             if (instance) { // lines update
-                var positionFunction = (positions: number[] | Float32Array) => {
+                var positionFunction = (positions: FloatArray) => {
                     var i = 0;
                     for (var l = 0; l < lines.length; l++) {
                         var points = lines[l];

+ 5 - 5
src/Mesh/babylon.vertexBuffer.ts

@@ -7,7 +7,7 @@
         private _stride: number;
         private _ownsBuffer: boolean;
 
-        constructor(engine: any, data: number[] | Float32Array | Buffer, kind: string, updatable: boolean, postponeInternalCreation?: boolean, stride?: number, instanced?: boolean, offset?: number, size?: number) {
+        constructor(engine: any, data: FloatArray | Buffer, kind: string, updatable: boolean, postponeInternalCreation?: boolean, stride?: number, instanced?: boolean, offset?: number, size?: number) {
             if (!stride) {
                 // Deduce stride from kind
                 switch (kind) {
@@ -47,7 +47,7 @@
                 this._buffer = data;
                 this._ownsBuffer = false;
             } else {
-                this._buffer = new Buffer(engine, <number[] | Float32Array>data, updatable, stride, postponeInternalCreation, instanced);
+                this._buffer = new Buffer(engine, <FloatArray>data, updatable, stride, postponeInternalCreation, instanced);
                 this._ownsBuffer = true;
             }
 
@@ -86,7 +86,7 @@
         /**
          * Returns an array of numbers or a Float32Array containing the VertexBuffer data.  
          */
-        public getData(): number[] | Float32Array {
+        public getData(): FloatArray {
             return this._buffer.getData();
         }
 
@@ -138,7 +138,7 @@
          * Creates the underlying WebGLBuffer from the passed numeric array or Float32Array.  
          * Returns the created WebGLBuffer.   
          */
-        public create(data?: number[] | Float32Array): void {
+        public create(data?: FloatArray): void {
             return this._buffer.create(data);
         }
 
@@ -146,7 +146,7 @@
          * Updates the underlying WebGLBuffer according to the passed numeric array or Float32Array.  
          * Returns the updated WebGLBuffer.  
          */
-        public update(data: number[] | Float32Array): void {
+        public update(data: FloatArray): void {
             return this._buffer.update(data);
         }
 

+ 132 - 52
src/Physics/babylon.physicsImpostor.ts

@@ -16,9 +16,9 @@ module BABYLON {
         getBoundingInfo(): Nullable<BoundingInfo>;
         computeWorldMatrix?(force: boolean): void;
         getWorldMatrix?(): Matrix;
-        getChildMeshes?(directDecendantsOnly?: boolean): Array<AbstractMesh>;
-        getVerticesData?(kind: string): Array<number> | Float32Array;
-        getIndices?(): IndicesArray;
+        getChildMeshes?(directDescendantsOnly?: boolean): Array<AbstractMesh>;
+        getVerticesData?(kind: string): Nullable<Array<number> | Float32Array>;
+        getIndices?(): Nullable<IndicesArray>;
         getScene?(): Scene;
         getAbsolutePosition(): Vector3;
     }
@@ -67,14 +67,20 @@ module BABYLON {
         }
 
         set friction(value: number) {
+            if (!this._physicsEngine) {
+                return;
+            }
             this._physicsEngine.getPhysicsPlugin().setBodyFriction(this, value);
         }
 
         get restitution(): number {
-            return this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this) : 0;
         }
 
         set restitution(value: number) {
+            if (!this._physicsEngine) {
+                return;
+            }            
             this._physicsEngine.getPhysicsPlugin().setBodyRestitution(this, value);
         }
 
@@ -99,6 +105,10 @@ module BABYLON {
                 this._scene = object.getScene()
             }
 
+            if (!this._scene) {
+                return;
+            }
+
             this._physicsEngine = this._scene.getPhysicsEngine();
             if (!this._physicsEngine) {
                 Tools.Error("Physics not enabled. Please use scene.enablePhysics(...) before creating impostors.")
@@ -133,6 +143,10 @@ module BABYLON {
          * of the child mesh.
          */
         public _init() {
+            if (!this._physicsEngine) {
+                return;
+            }
+
             this._physicsEngine.removeImpostor(this);
             this.physicsBody = null;
             this._parent = this._parent || this._getPhysicsParent();
@@ -194,7 +208,7 @@ module BABYLON {
          * Set the physics body. Used mainly by the physics engine/plugin
          */
         public set physicsBody(physicsBody: any) {
-            if (this._physicsBody) {
+            if (this._physicsBody && this._physicsEngine) {
                 this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this);
             }
             this._physicsBody = physicsBody;
@@ -212,7 +226,14 @@ module BABYLON {
                 this.object.rotationQuaternion = PhysicsImpostor.IDENTITY_QUATERNION;
                 //calculate the world matrix with no rotation
                 this.object.computeWorldMatrix && this.object.computeWorldMatrix(true);
-                let size = this.object.getBoundingInfo().boundingBox.extendSizeWorld.scale(2)
+                let boundingInfo = this.object.getBoundingInfo();
+                let size: Vector3;
+                if (boundingInfo) {
+                    size = boundingInfo.boundingBox.extendSizeWorld.scale(2)
+                } else {
+                    size = Vector3.Zero();
+                }
+
                 //bring back the rotation
                 this.object.rotationQuaternion = q;
                 //calculate the world matrix with the new rotation
@@ -226,7 +247,11 @@ module BABYLON {
 
         public getObjectCenter(): Vector3 {
             if (this.object.getBoundingInfo) {
-                return this.object.getBoundingInfo().boundingBox.centerWorld;
+                let boundingInfo = this.object.getBoundingInfo();
+                if (!boundingInfo) {
+                    return this.object.position;
+                }
+                return boundingInfo.boundingBox.centerWorld;
             } else {
                 return this.object.position;
             }
@@ -254,23 +279,29 @@ module BABYLON {
             if (this.getParam("mass") !== mass) {
                 this.setParam("mass", mass);
             }
-            this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
+            }
         }
 
         public getLinearVelocity(): Vector3 {
-            return this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this) : Vector3.Zero();
         }
 
         public setLinearVelocity(velocity: Vector3) {
-            this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
+            }
         }
 
         public getAngularVelocity(): Vector3 {
-            return this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this) : Vector3.Zero();
         }
 
         public setAngularVelocity(velocity: Vector3) {
-            this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
+            }
         }
 
         /**
@@ -278,7 +309,9 @@ module BABYLON {
          * Provide a function the will have two variables - the world object and the physics body object.
          */
         public executeNativeFunction(func: (world: any, physicsBody: any) => void) {
-            func(this._physicsEngine.getPhysicsPlugin().world, this.physicsBody);
+            if (this._physicsEngine) {
+                func(this._physicsEngine.getPhysicsPlugin().world, this.physicsBody);
+            }
         }
 
         /**
@@ -341,13 +374,17 @@ module BABYLON {
          * this function is executed by the physics engine.
          */
         public beforeStep = () => {
-
+            if (!this._physicsEngine) {
+                return;
+            }
             this.object.position.subtractToRef(this._deltaPosition, this._tmpPositionWithDelta);
             //conjugate deltaRotation
-            if (this._deltaRotationConjugated) {
-                this.object.rotationQuaternion.multiplyToRef(this._deltaRotationConjugated, this._tmpRotationWithDelta);
-            } else {
-                this._tmpRotationWithDelta.copyFrom(this.object.rotationQuaternion);
+            if (this.object.rotationQuaternion) {
+                if (this._deltaRotationConjugated) {
+                    this.object.rotationQuaternion.multiplyToRef(this._deltaRotationConjugated, this._tmpRotationWithDelta);
+                } else {
+                    this._tmpRotationWithDelta.copyFrom(this.object.rotationQuaternion);
+                }
             }
 
             this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(this, this._tmpPositionWithDelta, this._tmpRotationWithDelta);
@@ -361,6 +398,10 @@ module BABYLON {
          * this function is executed by the physics engine.
          */
         public afterStep = () => {
+            if (!this._physicsEngine) {
+                return;
+            }
+
             this._onAfterPhysicsStepCallbacks.forEach((func) => {
                 func(this);
             });
@@ -368,7 +409,7 @@ module BABYLON {
             this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(this);
 
             this.object.position.addInPlace(this._deltaPosition)
-            if (this._deltaRotation) {
+            if (this._deltaRotation && this.object.rotationQuaternion) {
                 this.object.rotationQuaternion.multiplyInPlace(this._deltaRotation);
             }
         }
@@ -376,11 +417,18 @@ module BABYLON {
         /**
          * Legacy collision detection event support
          */
-        public onCollideEvent: (collider: BABYLON.PhysicsImpostor, collidedWith: BABYLON.PhysicsImpostor) => void = null;
+        public onCollideEvent: Nullable<(collider: BABYLON.PhysicsImpostor, collidedWith: BABYLON.PhysicsImpostor) => void> = null;
 
         //event and body object due to cannon's event-based architecture.
         public onCollide = (e: { body: any }) => {
-            if (!this._onPhysicsCollideCallbacks.length && !this.onCollideEvent) return;
+            if (!this._onPhysicsCollideCallbacks.length && !this.onCollideEvent) {
+                return;
+            }
+
+            if (!this._physicsEngine) {
+                return;
+
+            }
             var otherImpostor = this._physicsEngine.getImpostorWithPhysicsBody(e.body);
             if (otherImpostor) {
                 // Legacy collision detection event support
@@ -388,9 +436,9 @@ module BABYLON {
                     this.onCollideEvent(this, otherImpostor);
                 }
                 this._onPhysicsCollideCallbacks.filter((obj) => {
-                    return obj.otherImpostors.indexOf(otherImpostor) !== -1
+                    return obj.otherImpostors.indexOf((<PhysicsImpostor>otherImpostor)) !== -1
                 }).forEach((obj) => {
-                    obj.callback(this, otherImpostor);
+                    obj.callback(this, <PhysicsImpostor>otherImpostor);
                 })
             }
         }
@@ -398,51 +446,73 @@ module BABYLON {
         /**
          * Apply a force 
          */
-        public applyForce(force: Vector3, contactPoint: Vector3) {
-            this._physicsEngine.getPhysicsPlugin().applyForce(this, force, contactPoint);
+        public applyForce(force: Vector3, contactPoint: Vector3): PhysicsImpostor {
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().applyForce(this, force, contactPoint);
+            }
+            return this;
         }
 
         /**
          * Apply an impulse
          */
-        public applyImpulse(force: Vector3, contactPoint: Vector3) {
-            this._physicsEngine.getPhysicsPlugin().applyImpulse(this, force, contactPoint);
+        public applyImpulse(force: Vector3, contactPoint: Vector3): PhysicsImpostor {
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().applyImpulse(this, force, contactPoint);
+            }
+
+            return this;
         }
 
         /**
          * A help function to create a joint.
          */
-        public createJoint(otherImpostor: PhysicsImpostor, jointType: number, jointData: PhysicsJointData) {
+        public createJoint(otherImpostor: PhysicsImpostor, jointType: number, jointData: PhysicsJointData): PhysicsImpostor {
             var joint = new PhysicsJoint(jointType, jointData);
             this.addJoint(otherImpostor, joint);
+
+            return this;
         }
 
         /**
          * Add a joint to this impostor with a different impostor.
          */
-        public addJoint(otherImpostor: PhysicsImpostor, joint: PhysicsJoint) {
+        public addJoint(otherImpostor: PhysicsImpostor, joint: PhysicsJoint): PhysicsImpostor {
             this._joints.push({
                 otherImpostor: otherImpostor,
                 joint: joint
-            })
-            this._physicsEngine.addJoint(this, otherImpostor, joint);
+            });
+
+            if (this._physicsEngine) {
+                this._physicsEngine.addJoint(this, otherImpostor, joint);
+            }
+
+            return this;
         }
 
         /**
          * Will keep this body still, in a sleep mode.
          */
-        public sleep() {
-            this._physicsEngine.getPhysicsPlugin().sleepBody(this);
+        public sleep(): PhysicsImpostor {
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().sleepBody(this);
+            }
+
+            return this;
         }
 
         /**
          * Wake the body up.
          */
-        public wakeUp() {
-            this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
+        public wakeUp(): PhysicsImpostor {
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
+            }
+
+            return this;
         }
 
-        public clone(newObject: IPhysicsEnabledObject) {
+        public clone(newObject: IPhysicsEnabledObject): Nullable<PhysicsImpostor> {
             if (!newObject) return null;
             return new PhysicsImpostor(newObject, this.type, this._options, this._scene);
         }
@@ -454,7 +524,9 @@ module BABYLON {
             }
 
             this._joints.forEach((j) => {
-                this._physicsEngine.removeJoint(this, j.otherImpostor, j.joint);
+                if (this._physicsEngine) {
+                    this._physicsEngine.removeJoint(this, j.otherImpostor, j.joint);
+                }
             })
             //dispose the physics body
             this._physicsEngine.removeImpostor(this);
@@ -486,12 +558,16 @@ module BABYLON {
             this._deltaRotationConjugated = this._deltaRotation.conjugate();
         }
 
-        public getBoxSizeToRef(result: Vector3) {
-            this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);
+        public getBoxSizeToRef(result: Vector3): PhysicsImpostor {
+            if (this._physicsEngine) {
+                this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);
+            }
+
+            return this;
         }
 
         public getRadius(): number {
-            return this._physicsEngine.getPhysicsPlugin().getRadius(this);
+            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getRadius(this) : 0;
         }
 
         /**
@@ -507,12 +583,14 @@ module BABYLON {
             var tempVec = PhysicsImpostor._tmpVecs[0];
             var mesh = <AbstractMesh>this.object;
 
-            if (adjustRotation) {
-                var tempQuat = PhysicsImpostor._tmpQuat;
-                mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);
-                bone.setRotationQuaternion(tempQuat, Space.WORLD, boneMesh);
-            } else {
-                bone.setRotationQuaternion(mesh.rotationQuaternion, Space.WORLD, boneMesh);
+            if (mesh.rotationQuaternion) {
+                if (adjustRotation) {
+                    var tempQuat = PhysicsImpostor._tmpQuat;
+                    mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);
+                    bone.setRotationQuaternion(tempQuat, Space.WORLD, boneMesh);
+                } else {
+                    bone.setRotationQuaternion(mesh.rotationQuaternion, Space.WORLD, boneMesh);
+                }
             }
 
             tempVec.x = 0;
@@ -560,12 +638,14 @@ module BABYLON {
 
             var mesh = <AbstractMesh>this.object;
 
-            if (adjustRotation) {
-                var tempQuat = PhysicsImpostor._tmpQuat;
-                bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, tempQuat);
-                tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);
-            } else {
-                bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, mesh.rotationQuaternion);
+            if (mesh.rotationQuaternion) {
+                if (adjustRotation) {
+                    var tempQuat = PhysicsImpostor._tmpQuat;
+                    bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, tempQuat);
+                    tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);
+                } else {
+                    bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, mesh.rotationQuaternion);
+                }
             }
 
             var pos = PhysicsImpostor._tmpVecs[0];

+ 8 - 8
src/Tools/babylon.dds.ts

@@ -462,14 +462,14 @@
 
                         if (!info.isCompressed && info.isFourCC) {
                             dataLength = width * height * 4;
-                            var floatArray: Nullable<ArrayBufferView> = null;
+                            var FloatArray: Nullable<ArrayBufferView> = null;
 
                             if (engine.badOS || engine.badDesktopOS || (!engine.getCaps().textureHalfFloat && !engine.getCaps().textureFloat)) { // Required because iOS has many issues with float and half float generation
                                 if (bpp === 128) {
-                                    floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);                                    
+                                    FloatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);                                    
                                 }
                                 else if (bpp === 64) {
-                                    floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                    FloatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                 }
 
                                 info.textureType = Engine.TEXTURETYPE_UNSIGNED_INT;
@@ -478,20 +478,20 @@
                             }
                             else {
                                 if (bpp === 128) {
-                                    floatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                    FloatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                 } else if (bpp === 64 && !engine.getCaps().textureHalfFloat) {
-                                    floatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                    FloatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
 
                                     info.textureType = Engine.TEXTURETYPE_FLOAT;
                                     format = engine._getWebGLTextureType(info.textureType);    
                                     internalFormat = engine._getRGBABufferInternalSizedFormat(info.textureType);                            
                                 } else { // 64
-                                    floatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                    FloatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                 }
                             }
 
-                            if (floatArray) {
-                                engine._uploadDataToTexture(sampler, i, internalFormat, width, height, gl.RGBA, format, floatArray);
+                            if (FloatArray) {
+                                engine._uploadDataToTexture(sampler, i, internalFormat, width, height, gl.RGBA, format, FloatArray);
                             }
                         } else if (info.isRGB) {
                             if (bpp === 24) {

+ 11 - 10
src/Tools/babylon.tools.ts

@@ -203,7 +203,7 @@
             return "data:image/png;base64," + output;
         }
 
-        public static ExtractMinAndMaxIndexed(positions: number[] | Float32Array, indices: IndicesArray, indexStart: number, indexCount: number, bias: Nullable<Vector2> = null): { minimum: Vector3; maximum: Vector3 } {
+        public static ExtractMinAndMaxIndexed(positions: FloatArray, indices: IndicesArray, indexStart: number, indexCount: number, bias: Nullable<Vector2> = null): { minimum: Vector3; maximum: Vector3 } {
             var minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
             var maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
 
@@ -229,7 +229,7 @@
             };
         }
 
-        public static ExtractMinAndMax(positions: number[] | Float32Array, start: number, count: number, bias: Nullable<Vector2> = null, stride?: number): { minimum: Vector3; maximum: Vector3 } {
+        public static ExtractMinAndMax(positions: FloatArray, start: number, count: number, bias: Nullable<Vector2> = null, stride?: number): { minimum: Vector3; maximum: Vector3 } {
             var minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
             var maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
 
@@ -481,12 +481,12 @@
         }
 
         //ANY
-        public static LoadFile(url: string, callback: (data: any) => void, progressCallBack?: (data: any) => void, database?: Database, useArrayBuffer?: boolean, onError?: (request?: XMLHttpRequest, exception?: any) => void): XMLHttpRequest {
+        public static LoadFile(url: string, callback: (data: any) => void, progressCallBack?: (data: any) => void, database?: Database, useArrayBuffer?: boolean, onError?: (request?: XMLHttpRequest, exception?: any) => void): Nullable<XMLHttpRequest> {
             url = Tools.CleanUrl(url);
 
             url = Tools.PreprocessUrl(url);
 
-            var request: XMLHttpRequest;
+            var request: Nullable<XMLHttpRequest> = null;
 
             var noIndexedDB = () => {
                 request = new XMLHttpRequest();
@@ -502,16 +502,17 @@
                 }
 
                 request.onreadystatechange = () => {
+                    let req = <XMLHttpRequest>request;
                     // In case of undefined state in some browsers.
-                    if (request.readyState === (XMLHttpRequest.DONE || 4)) {
-                        request.onreadystatechange = () => {};//some browsers have issues where onreadystatechange can be called multiple times with the same value
+                    if (req.readyState === (XMLHttpRequest.DONE || 4)) {
+                        req.onreadystatechange = () => {};//some browsers have issues where onreadystatechange can be called multiple times with the same value
 
-                        if (request.status >= 200 && request.status < 300 || (!Tools.IsWindowObjectExist() && (request.status === 0))) {
-                            callback(!useArrayBuffer ? request.responseText : request.response);
+                        if (req.status >= 200 && req.status < 300 || (!Tools.IsWindowObjectExist() && (req.status === 0))) {
+                            callback(!useArrayBuffer ? req.responseText : req.response);
                         } else { // Failed
-                            let e = new Error("Error status: " + request.status + " - Unable to load " + loadUrl);
+                            let e = new Error("Error status: " + req.status + " - Unable to load " + loadUrl);
                             if (onError) {
-                                onError(request, e);
+                                onError(req, e);
                             } else {
                                 throw e;
                             }

+ 3 - 1
src/babylon.types.ts

@@ -1,4 +1,6 @@
 type Nullable<T> = T | null;
 type float = number;
 type double = number;
-type int = number;
+type int = number;
+
+type FloatArray = number[] | Float32Array;