Pārlūkot izejas kodu

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

noalak 7 gadi atpakaļ
vecāks
revīzija
3f8dfffcf1
94 mainītis faili ar 28199 papildinājumiem un 26796 dzēšanām
  1. 5792 5751
      dist/preview release/babylon.d.ts
  2. 40 40
      dist/preview release/babylon.js
  3. 744 362
      dist/preview release/babylon.max.js
  4. 5792 5751
      dist/preview release/babylon.module.d.ts
  5. 41 41
      dist/preview release/babylon.worker.js
  6. 6898 6857
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 40 40
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 744 362
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 6898 6857
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  10. 8 2
      src/Audio/babylon.sound.ts
  11. 1 1
      src/Behaviors/Cameras/babylon.bouncingBehavior.ts
  12. 1 1
      src/Behaviors/Cameras/babylon.framingBehavior.ts
  13. 16 10
      src/Collisions/babylon.collisionCoordinator.ts
  14. 4 2
      src/Culling/Octrees/babylon.octree.ts
  15. 1 1
      src/Debug/babylon.skeletonViewer.ts
  16. 34 21
      src/Engine/babylon.engine.ts
  17. 3 1
      src/Gamepad/Controllers/babylon.poseEnabledController.ts
  18. 9 0
      src/Gamepad/Controllers/babylon.windowsMotionController.ts
  19. 15 7
      src/Layer/babylon.highlightlayer.ts
  20. 1 1
      src/LensFlare/babylon.lensFlareSystem.ts
  21. 6 2
      src/Lights/Shadows/babylon.shadowGenerator.ts
  22. 16 12
      src/Materials/PBR/babylon.pbrBaseMaterial.ts
  23. 3 2
      src/Materials/Textures/Procedurals/babylon.customProceduralTexture.ts
  24. 49 24
      src/Materials/Textures/Procedurals/babylon.proceduralTexture.ts
  25. 23 16
      src/Materials/Textures/babylon.colorGradingTexture.ts
  26. 15 4
      src/Materials/Textures/babylon.cubeTexture.ts
  27. 15 8
      src/Materials/Textures/babylon.dynamicTexture.ts
  28. 1 1
      src/Materials/Textures/babylon.internalTexture.ts
  29. 13 5
      src/Materials/Textures/babylon.mirrorTexture.ts
  30. 7 5
      src/Materials/Textures/babylon.multiRenderTarget.ts
  31. 3 2
      src/Materials/Textures/babylon.rawTexture.ts
  32. 10 2
      src/Materials/Textures/babylon.refractionTexture.ts
  33. 10 5
      src/Materials/Textures/babylon.videoTexture.ts
  34. 1 1
      src/Materials/babylon.effect.ts
  35. 2 1
      src/Materials/babylon.imageProcessingConfiguration.ts
  36. 1 1
      src/Materials/babylon.material.ts
  37. 7 6
      src/Materials/babylon.materialHelper.ts
  38. 1 1
      src/Materials/babylon.pushMaterial.ts
  39. 4 1
      src/Materials/babylon.standardMaterial.ts
  40. 1 1
      src/Materials/babylon.uniformBuffer.ts
  41. 11 13
      src/Mesh/babylon.abstractMesh.ts
  42. 4 4
      src/Mesh/babylon.csg.ts
  43. 27 3
      src/Mesh/babylon.geometry.ts
  44. 5 0
      src/Mesh/babylon.groundMesh.ts
  45. 1 1
      src/Mesh/babylon.instancedMesh.ts
  46. 2 2
      src/Mesh/babylon.linesMesh.ts
  47. 175 68
      src/Mesh/babylon.mesh.ts
  48. 84 70
      src/Mesh/babylon.mesh.vertexData.ts
  49. 116 100
      src/Mesh/babylon.meshBuilder.ts
  50. 13 1
      src/Mesh/babylon.meshSimplification.ts
  51. 1 1
      src/Mesh/babylon.polygonMesh.ts
  52. 5 5
      src/Mesh/babylon.subMesh.ts
  53. 3 2
      src/Mesh/babylon.vertexBuffer.ts
  54. 3 3
      src/Morph/babylon.morphTarget.ts
  55. 8 6
      src/Morph/babylon.morphTargetManager.ts
  56. 2 2
      src/Particles/babylon.gpuParticleSystem.ts
  57. 21 17
      src/Particles/babylon.particleSystem.ts
  58. 27 26
      src/Particles/babylon.solidParticle.ts
  59. 46 39
      src/Particles/babylon.solidParticleSystem.ts
  60. 39 21
      src/Physics/Plugins/babylon.cannonJSPlugin.ts
  61. 22 11
      src/Physics/Plugins/babylon.oimoJSPlugin.ts
  62. 4 4
      src/Physics/babylon.physicsEngine.ts
  63. 5 5
      src/Physics/babylon.physicsImpostor.ts
  64. 3 3
      src/Physics/babylon.physicsJoint.ts
  65. 10 10
      src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts
  66. 13 11
      src/PostProcess/RenderPipeline/Pipelines/babylon.lensRenderingPipeline.ts
  67. 18 2
      src/PostProcess/RenderPipeline/Pipelines/babylon.ssao2RenderingPipeline.ts
  68. 58 45
      src/PostProcess/RenderPipeline/Pipelines/babylon.standardRenderingPipeline.ts
  69. 39 19
      src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.ts
  70. 40 24
      src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.ts
  71. 1 1
      src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.ts
  72. 1 1
      src/PostProcess/babylon.anaglyphPostProcess.ts
  73. 1 1
      src/PostProcess/babylon.displayPassPostProcess.ts
  74. 1 1
      src/PostProcess/babylon.filterPostProcess.ts
  75. 1 1
      src/PostProcess/babylon.fxaaPostProcess.ts
  76. 1 1
      src/PostProcess/babylon.highlightsPostProcess.ts
  77. 4 4
      src/PostProcess/babylon.imageProcessingPostProcess.ts
  78. 4 2
      src/PostProcess/babylon.postProcess.ts
  79. 1 1
      src/PostProcess/babylon.stereoscopicInterlacePostProcess.ts
  80. 1 1
      src/PostProcess/babylon.tonemapPostProcess.ts
  81. 22 14
      src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts
  82. 1 1
      src/PostProcess/babylon.vrDistortionCorrectionPostProcess.ts
  83. 5 3
      src/Probes/babylon.reflectionProbe.ts
  84. 9 6
      src/Rendering/babylon.boundingBoxRenderer.ts
  85. 14 7
      src/Rendering/babylon.depthRenderer.ts
  86. 10 5
      src/Rendering/babylon.edgesRenderer.ts
  87. 16 8
      src/Rendering/babylon.geometryBufferRenderer.ts
  88. 7 3
      src/Rendering/babylon.outlineRenderer.ts
  89. 6 2
      src/Rendering/babylon.renderingGroup.ts
  90. 5 1
      src/Tools/babylon.decorators.ts
  91. 2 2
      src/babylon.node.ts
  92. 4 2
      src/babylon.scene.ts
  93. 2 1
      src/babylon.types.ts
  94. 5 1
      tslint.json

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5792 - 5751
dist/preview release/babylon.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 40 - 40
dist/preview release/babylon.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 744 - 362
dist/preview release/babylon.max.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5792 - 5751
dist/preview release/babylon.module.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 41 - 41
dist/preview release/babylon.worker.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 6898 - 6857
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 40 - 40
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 744 - 362
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 6898 - 6857
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


+ 8 - 2
src/Audio/babylon.sound.ts

@@ -561,8 +561,14 @@ module BABYLON {
             }
             }
         }
         }
 
 
-        private _onRegisterAfterWorldMatrixUpdate(connectedMesh: AbstractMesh) {
-            this.setPosition(connectedMesh.getBoundingInfo().boundingSphere.centerWorld);
+        private _onRegisterAfterWorldMatrixUpdate(connectedMesh: AbstractMesh): void {
+            let boundingInfo = connectedMesh.getBoundingInfo();
+
+            if (!boundingInfo) {
+                return;
+            }
+
+            this.setPosition(boundingInfo.boundingSphere.centerWorld);
             if (Engine.audioEngine.canUseWebAudio && this._isDirectional && this.isPlaying) {
             if (Engine.audioEngine.canUseWebAudio && this._isDirectional && this.isPlaying) {
                 this._updateDirection();
                 this._updateDirection();
             }
             }

+ 1 - 1
src/Behaviors/Cameras/babylon.bouncingBehavior.ts

@@ -64,7 +64,7 @@ module BABYLON {
 					}
 					}
 
 
 					mesh.computeWorldMatrix(true);
 					mesh.computeWorldMatrix(true);
-					let diagonal = mesh.getBoundingInfo().diagonalLength;
+					let diagonal = (<BoundingInfo>mesh.getBoundingInfo()).diagonalLength;
 
 
 					this.lowerRadiusTransitionRange = diagonal * 0.05;
 					this.lowerRadiusTransitionRange = diagonal * 0.05;
 					this.upperRadiusTransitionRange = diagonal * 0.05;
 					this.upperRadiusTransitionRange = diagonal * 0.05;

+ 1 - 1
src/Behaviors/Cameras/babylon.framingBehavior.ts

@@ -220,7 +220,7 @@ module BABYLON {
 		public zoomOnMesh(mesh: AbstractMesh, focusOnOriginXZ: boolean = false, onAnimationEnd: Nullable<() => void> = null): void {
 		public zoomOnMesh(mesh: AbstractMesh, focusOnOriginXZ: boolean = false, onAnimationEnd: Nullable<() => void> = null): void {
 			mesh.computeWorldMatrix(true);
 			mesh.computeWorldMatrix(true);
 
 
-			let boundingBox = mesh.getBoundingInfo().boundingBox;
+			let boundingBox = (<BoundingInfo>mesh.getBoundingInfo()).boundingBox;
 			this.zoomOnBoundingInfo(boundingBox.minimumWorld, boundingBox.maximumWorld, focusOnOriginXZ, onAnimationEnd);
 			this.zoomOnBoundingInfo(boundingBox.minimumWorld, boundingBox.maximumWorld, focusOnOriginXZ, onAnimationEnd);
 		}
 		}
 
 

+ 16 - 10
src/Collisions/babylon.collisionCoordinator.ts

@@ -139,6 +139,8 @@ module BABYLON {
             var submeshes: Array<SerializedSubMesh> = [];
             var submeshes: Array<SerializedSubMesh> = [];
             if (mesh.subMeshes) {
             if (mesh.subMeshes) {
                 submeshes = mesh.subMeshes.map(function (sm, idx) {
                 submeshes = mesh.subMeshes.map(function (sm, idx) {
+                    let boundingInfo = <BoundingInfo>sm.getBoundingInfo();
+
                     return {
                     return {
                         position: idx,
                         position: idx,
                         verticesStart: sm.verticesStart,
                         verticesStart: sm.verticesStart,
@@ -146,30 +148,34 @@ module BABYLON {
                         indexStart: sm.indexStart,
                         indexStart: sm.indexStart,
                         indexCount: sm.indexCount,
                         indexCount: sm.indexCount,
                         hasMaterial: !!sm.getMaterial(),
                         hasMaterial: !!sm.getMaterial(),
-                        sphereCenter: sm.getBoundingInfo().boundingSphere.centerWorld.asArray(),
-                        sphereRadius: sm.getBoundingInfo().boundingSphere.radiusWorld,
-                        boxMinimum: sm.getBoundingInfo().boundingBox.minimumWorld.asArray(),
-                        boxMaximum: sm.getBoundingInfo().boundingBox.maximumWorld.asArray()
+                        sphereCenter: boundingInfo.boundingSphere.centerWorld.asArray(),
+                        sphereRadius: boundingInfo.boundingSphere.radiusWorld,
+                        boxMinimum: boundingInfo.boundingBox.minimumWorld.asArray(),
+                        boxMaximum: boundingInfo.boundingBox.maximumWorld.asArray()
                     }
                     }
                 });
                 });
             }
             }
 
 
             var geometryId: Nullable<string> = null;
             var geometryId: Nullable<string> = null;
             if (mesh instanceof Mesh) {
             if (mesh instanceof Mesh) {
-                geometryId = (<Mesh>mesh).geometry ? (<Mesh>mesh).geometry.id : null;
+                let geometry = (<Mesh>mesh).geometry;
+                geometryId = geometry ? geometry.id : null;
             } else if (mesh instanceof InstancedMesh) {
             } else if (mesh instanceof InstancedMesh) {
-                geometryId = ((<InstancedMesh>mesh).sourceMesh && (<InstancedMesh>mesh).sourceMesh.geometry) ? (<InstancedMesh>mesh).sourceMesh.geometry.id : null;
+                let geometry = (<InstancedMesh>mesh).sourceMesh.geometry;
+                geometryId = geometry ? geometry.id : null;
             }
             }
 
 
+            let boundingInfo = <BoundingInfo>mesh.getBoundingInfo();
+
             return {
             return {
                 uniqueId: mesh.uniqueId,
                 uniqueId: mesh.uniqueId,
                 id: mesh.id,
                 id: mesh.id,
                 name: mesh.name,
                 name: mesh.name,
                 geometryId: geometryId,
                 geometryId: geometryId,
-                sphereCenter: mesh.getBoundingInfo().boundingSphere.centerWorld.asArray(),
-                sphereRadius: mesh.getBoundingInfo().boundingSphere.radiusWorld,
-                boxMinimum: mesh.getBoundingInfo().boundingBox.minimumWorld.asArray(),
-                boxMaximum: mesh.getBoundingInfo().boundingBox.maximumWorld.asArray(),
+                sphereCenter: boundingInfo.boundingSphere.centerWorld.asArray(),
+                sphereRadius: boundingInfo.boundingSphere.radiusWorld,
+                boxMinimum: boundingInfo.boundingBox.minimumWorld.asArray(),
+                boxMaximum: boundingInfo.boundingBox.maximumWorld.asArray(),
                 worldMatrixFromCache: mesh.worldMatrixFromCache.asArray(),
                 worldMatrixFromCache: mesh.worldMatrixFromCache.asArray(),
                 subMeshes: submeshes,
                 subMeshes: submeshes,
                 checkCollisions: mesh.checkCollisions
                 checkCollisions: mesh.checkCollisions

+ 4 - 2
src/Culling/Octrees/babylon.octree.ts

@@ -96,13 +96,15 @@
         }
         }
 
 
         public static CreationFuncForMeshes = (entry: AbstractMesh, block: OctreeBlock<AbstractMesh>): void => {
         public static CreationFuncForMeshes = (entry: AbstractMesh, block: OctreeBlock<AbstractMesh>): void => {
-            if (!entry.isBlocked && entry.getBoundingInfo().boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
+            let boundingInfo = entry.getBoundingInfo();
+            if (!entry.isBlocked && boundingInfo && boundingInfo.boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
                 block.entries.push(entry);
                 block.entries.push(entry);
             }
             }
         }
         }
 
 
         public static CreationFuncForSubMeshes = (entry: SubMesh, block: OctreeBlock<SubMesh>): void => {
         public static CreationFuncForSubMeshes = (entry: SubMesh, block: OctreeBlock<SubMesh>): void => {
-            if (entry.getBoundingInfo().boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
+            let boundingInfo = entry.getBoundingInfo();
+            if (boundingInfo && boundingInfo.boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
                 block.entries.push(entry);
                 block.entries.push(entry);
             }
             }
         }
         }

+ 1 - 1
src/Debug/babylon.skeletonViewer.ts

@@ -114,7 +114,7 @@
             }
             }
 
 
             if (!this._debugMesh) {
             if (!this._debugMesh) {
-                this._debugMesh = BABYLON.MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true }, this._scene);
+                this._debugMesh = BABYLON.MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: null }, this._scene);
                 this._debugMesh.renderingGroupId = this.renderingGroupId;
                 this._debugMesh.renderingGroupId = this.renderingGroupId;
             } else {
             } else {
                 BABYLON.MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: this._debugMesh }, this._scene);
                 BABYLON.MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: this._debugMesh }, this._scene);

+ 34 - 21
src/Engine/babylon.engine.ts

@@ -2137,13 +2137,15 @@
                     }
                     }
 
 
                     var buffer = vertexBuffer.getBuffer();
                     var buffer = vertexBuffer.getBuffer();
-                    this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
-
-                    if (vertexBuffer.getIsInstanced()) {
-                        this._gl.vertexAttribDivisor(order, vertexBuffer.getInstanceDivisor());
-                        if (!this._vaoRecordInProgress) {
-                            this._currentInstanceLocations.push(order);
-                            this._currentInstanceBuffers.push(buffer);
+                    if (buffer) {
+                        this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
+
+                        if (vertexBuffer.getIsInstanced()) {
+                            this._gl.vertexAttribDivisor(order, vertexBuffer.getInstanceDivisor());
+                            if (!this._vaoRecordInProgress) {
+                                this._currentInstanceLocations.push(order);
+                                this._currentInstanceBuffers.push(buffer);
+                            }
                         }
                         }
                     }
                     }
                 }
                 }
@@ -3104,7 +3106,11 @@
             return internalFormat;
             return internalFormat;
         }
         }
 
 
-        public updateRawTexture(texture: InternalTexture, data: ArrayBufferView, format: number, invertY: boolean, compression: Nullable<string> = null): void {
+        public updateRawTexture(texture: Nullable<InternalTexture>, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null): void {
+            if (!texture) {
+                return;
+            }
+
             var internalFormat = this._getInternalFormat(format);
             var internalFormat = this._getInternalFormat(format);
             this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
             this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
             this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY === undefined ? 1 : (invertY ? 1 : 0));
             this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY === undefined ? 1 : (invertY ? 1 : 0));
@@ -3120,7 +3126,7 @@
                 this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
                 this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
             }
             }
 
 
-            if (compression) {
+            if (compression && data) {
                 this._gl.compressedTexImage2D(this._gl.TEXTURE_2D, 0, (<any>this.getCaps().s3tc)[compression], texture.width, texture.height, 0, data);
                 this._gl.compressedTexImage2D(this._gl.TEXTURE_2D, 0, (<any>this.getCaps().s3tc)[compression], texture.width, texture.height, 0, data);
             } else {
             } else {
                 this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, texture.width, texture.height, 0, internalFormat, this._gl.UNSIGNED_BYTE, data);
                 this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, texture.width, texture.height, 0, internalFormat, this._gl.UNSIGNED_BYTE, data);
@@ -3134,7 +3140,7 @@
             texture.isReady = true;
             texture.isReady = true;
         }
         }
 
 
-        public createRawTexture(data: ArrayBufferView, width: number, height: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null): InternalTexture {
+        public createRawTexture(data: Nullable<ArrayBufferView>, width: number, height: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null): InternalTexture {
             var texture = new InternalTexture(this, InternalTexture.DATASOURCE_RAW);
             var texture = new InternalTexture(this, InternalTexture.DATASOURCE_RAW);
             texture.baseWidth = width;
             texture.baseWidth = width;
             texture.baseHeight = height;
             texture.baseHeight = height;
@@ -3221,7 +3227,12 @@
             texture.samplingMode = samplingMode;
             texture.samplingMode = samplingMode;
         }
         }
 
 
-        public updateDynamicTexture(texture: InternalTexture, canvas: HTMLCanvasElement, invertY: boolean, premulAlpha: boolean = false, format?: number): void {
+        public updateDynamicTexture(texture: Nullable<InternalTexture>, canvas: HTMLCanvasElement, invertY: boolean, premulAlpha: boolean = false, format?: number): void {
+
+            if (!texture) {
+                return;
+            }
+
             this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
             this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
             this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY ? 1 : 0);
             this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY ? 1 : 0);
             if (premulAlpha) {
             if (premulAlpha) {
@@ -3240,8 +3251,8 @@
             texture.isReady = true;
             texture.isReady = true;
         }
         }
 
 
-        public updateVideoTexture(texture: InternalTexture, video: HTMLVideoElement, invertY: boolean): void {
-            if (texture._isDisabled) {
+        public updateVideoTexture(texture: Nullable<InternalTexture>, video: HTMLVideoElement, invertY: boolean): void {
+            if (!texture || texture._isDisabled) {
                 return;
                 return;
             }
             }
 
 
@@ -3705,7 +3716,9 @@
             return texture;
             return texture;
         }
         }
 
 
-        public createPrefilteredCubeTexture(rootUrl: string, scene: Nullable<Scene>, scale: number, offset: number, onLoad: (internalTexture: Nullable<InternalTexture>) => void, onError: Nullable<(message?: string, exception?: any) => void> = null, format?: number, forcedExtension: any = null): InternalTexture {
+        public createPrefilteredCubeTexture(rootUrl: string, scene: Nullable<Scene>, scale: number, offset: number, 
+                                            onLoad: Nullable<(internalTexture: Nullable<InternalTexture>) => void> = null, 
+                                            onError: Nullable<(message?: string, exception?: any) => void> = null, format?: number, forcedExtension: any = null): InternalTexture {
             var callback = (loadData: any) => {
             var callback = (loadData: any) => {
                 if (!loadData) {
                 if (!loadData) {
                     if (onLoad) {
                     if (onLoad) {
@@ -4135,7 +4148,7 @@
             return texture;
             return texture;
         };
         };
 
 
-        public updateRawTexture3D(texture: InternalTexture, data: ArrayBufferView, format: number, invertY: boolean, compression: Nullable<string> = null): void {
+        public updateRawTexture3D(texture: InternalTexture, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null): void {
             var internalFormat = this._getInternalFormat(format);
             var internalFormat = this._getInternalFormat(format);
             this._bindTextureDirectly(this._gl.TEXTURE_3D, texture);
             this._bindTextureDirectly(this._gl.TEXTURE_3D, texture);
             this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY === undefined ? 1 : (invertY ? 1 : 0));
             this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY === undefined ? 1 : (invertY ? 1 : 0));
@@ -4151,7 +4164,7 @@
                 this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
                 this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
             }
             }
 
 
-            if (compression) {
+            if (compression && data) {
                 this._gl.compressedTexImage3D(this._gl.TEXTURE_3D, 0, (<any>this.getCaps().s3tc)[compression], texture.width, texture.height, texture.depth, 0, data);
                 this._gl.compressedTexImage3D(this._gl.TEXTURE_3D, 0, (<any>this.getCaps().s3tc)[compression], texture.width, texture.height, texture.depth, 0, data);
             } else {
             } else {
                 this._gl.texImage3D(this._gl.TEXTURE_3D, 0, internalFormat, texture.width, texture.height, texture.depth, 0, internalFormat, this._gl.UNSIGNED_BYTE, data);
                 this._gl.texImage3D(this._gl.TEXTURE_3D, 0, internalFormat, texture.width, texture.height, texture.depth, 0, internalFormat, this._gl.UNSIGNED_BYTE, data);
@@ -4165,7 +4178,7 @@
             texture.isReady = true;
             texture.isReady = true;
         }
         }
 
 
-        public createRawTexture3D(data: ArrayBufferView, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null): InternalTexture {
+        public createRawTexture3D(data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null): InternalTexture {
             var texture = new InternalTexture(this, InternalTexture.DATASOURCE_RAW3D);
             var texture = new InternalTexture(this, InternalTexture.DATASOURCE_RAW3D);
             texture.baseWidth = width;
             texture.baseWidth = width;
             texture.baseHeight = height;
             texture.baseHeight = height;
@@ -4369,7 +4382,7 @@
             }
             }
         }
         }
 
 
-        public _bindTexture(channel: number, texture: InternalTexture): void {
+        public _bindTexture(channel: number, texture: Nullable<InternalTexture>): void {
             if (channel < 0) {
             if (channel < 0) {
                 return;
                 return;
             }
             }
@@ -4378,8 +4391,8 @@
             this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
             this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
         }
         }
 
 
-        public setTextureFromPostProcess(channel: number, postProcess: PostProcess): void {
-            this._bindTexture(channel, postProcess._textures.data[postProcess._currentRenderTextureInd]);
+        public setTextureFromPostProcess(channel: number, postProcess: Nullable<PostProcess>): void {
+            this._bindTexture(channel, postProcess ? postProcess._textures.data[postProcess._currentRenderTextureInd] : null);
         }
         }
 
 
         public unbindAllTextures(): void {
         public unbindAllTextures(): void {
@@ -4429,7 +4442,7 @@
 
 
             let internalTexture: InternalTexture;
             let internalTexture: InternalTexture;
             if (texture.isReady()) {
             if (texture.isReady()) {
-                internalTexture = texture.getInternalTexture();
+                internalTexture = <InternalTexture>texture.getInternalTexture();
             }
             }
             else if (texture.isCube) {
             else if (texture.isCube) {
                 internalTexture = this.emptyCubeTexture;
                 internalTexture = this.emptyCubeTexture;

+ 3 - 1
src/Gamepad/Controllers/babylon.poseEnabledController.ts

@@ -80,7 +80,9 @@ module BABYLON {
             
             
             if (this._mesh) {
             if (this._mesh) {
                 this._mesh.position.copyFrom(this._calculatedPosition);
                 this._mesh.position.copyFrom(this._calculatedPosition);
-                this._mesh.rotationQuaternion.copyFrom(this._calculatedRotation);
+                if (this._mesh.rotationQuaternion) {
+                    this._mesh.rotationQuaternion.copyFrom(this._calculatedRotation);
+                }
             }
             }
         }
         }
 
 

+ 9 - 0
src/Gamepad/Controllers/babylon.windowsMotionController.ts

@@ -138,6 +138,11 @@ module BABYLON {
             }
             }
 
 
             var meshInfo = this._loadedMeshInfo.buttonMeshes[buttonName];
             var meshInfo = this._loadedMeshInfo.buttonMeshes[buttonName];
+
+            if (!meshInfo.unpressed.rotationQuaternion || !meshInfo.pressed.rotationQuaternion || !meshInfo.value.rotationQuaternion) {
+                return;
+            }
+
             BABYLON.Quaternion.SlerpToRef(
             BABYLON.Quaternion.SlerpToRef(
                 meshInfo.unpressed.rotationQuaternion, 
                 meshInfo.unpressed.rotationQuaternion, 
                 meshInfo.pressed.rotationQuaternion, 
                 meshInfo.pressed.rotationQuaternion, 
@@ -160,6 +165,10 @@ module BABYLON {
                 return;
                 return;
             }
             }
 
 
+            if (!meshInfo.min.rotationQuaternion || !meshInfo.max.rotationQuaternion || !meshInfo.value.rotationQuaternion) {
+                return;
+            }            
+
             // Convert from gamepad value range (-1 to +1) to lerp range (0 to 1)
             // Convert from gamepad value range (-1 to +1) to lerp range (0 to 1)
             let lerpValue = axisValue * 0.5 + 0.5;
             let lerpValue = axisValue * 0.5 + 0.5;
             BABYLON.Quaternion.SlerpToRef(
             BABYLON.Quaternion.SlerpToRef(

+ 15 - 7
src/Layer/babylon.highlightlayer.ts

@@ -419,17 +419,21 @@ module BABYLON {
 
 
             // Custom render function
             // Custom render function
             var renderSubMesh = (subMesh: SubMesh): void => {
             var renderSubMesh = (subMesh: SubMesh): void => {
-
                 if (!this._meshes) {
                 if (!this._meshes) {
                     return;
                     return;
                 }
                 }
 
 
+                var material = subMesh.getMaterial();
                 var mesh = subMesh.getRenderingMesh();
                 var mesh = subMesh.getRenderingMesh();
                 var scene = this._scene;
                 var scene = this._scene;
                 var engine = scene.getEngine();
                 var engine = scene.getEngine();
 
 
+                if (!material) {
+                    return;
+                }
+
                 // Culling
                 // Culling
-                engine.setState(subMesh.getMaterial().backFaceCulling);
+                engine.setState(material.backFaceCulling);
 
 
                 // Managing instances
                 // Managing instances
                 var batch = mesh._getInstancesRenderList(subMesh._id);
                 var batch = mesh._getInstancesRenderList(subMesh._id);
@@ -445,7 +449,6 @@ module BABYLON {
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
 
 
                 var highlightLayerMesh = this._meshes[mesh.uniqueId];
                 var highlightLayerMesh = this._meshes[mesh.uniqueId];
-                var material = subMesh.getMaterial();
                 var emissiveTexture: Nullable<Texture> = null;
                 var emissiveTexture: Nullable<Texture> = null;
                 if (highlightLayerMesh && highlightLayerMesh.glowEmissiveOnly && material) {
                 if (highlightLayerMesh && highlightLayerMesh.glowEmissiveOnly && material) {
                     emissiveTexture = (<any>material).emissiveTexture;
                     emissiveTexture = (<any>material).emissiveTexture;
@@ -491,7 +494,7 @@ module BABYLON {
                     }
                     }
 
 
                     // Bones
                     // Bones
-                    if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                    if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                         this._glowMapGenerationEffect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                         this._glowMapGenerationEffect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     }
 
 
@@ -545,7 +548,13 @@ module BABYLON {
          * @return true if ready otherwise, false
          * @return true if ready otherwise, false
          */
          */
         private isReady(subMesh: SubMesh, useInstances: boolean, emissiveTexture: Nullable<Texture>): boolean {
         private isReady(subMesh: SubMesh, useInstances: boolean, emissiveTexture: Nullable<Texture>): boolean {
-            if (!subMesh.getMaterial().isReady(subMesh.getMesh(), useInstances)) {
+            let material = subMesh.getMaterial();
+
+            if (!material) {
+                return false;
+            }
+
+            if (!material.isReady(subMesh.getMesh(), useInstances)) {
                 return false;
                 return false;
             }
             }
 
 
@@ -554,7 +563,6 @@ module BABYLON {
             var attribs = [VertexBuffer.PositionKind];
             var attribs = [VertexBuffer.PositionKind];
 
 
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
-            var material = subMesh.getMaterial();
             var uv1 = false;
             var uv1 = false;
             var uv2 = false;
             var uv2 = false;
 
 
@@ -607,7 +615,7 @@ module BABYLON {
                     attribs.push(VertexBuffer.MatricesWeightsExtraKind);
                     attribs.push(VertexBuffer.MatricesWeightsExtraKind);
                 }
                 }
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
-                defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+                defines.push("#define BonesPerMesh " + (mesh.skeleton ? (mesh.skeleton.bones.length + 1) : 0));
             } else {
             } else {
                 defines.push("#define NUM_BONE_INFLUENCERS 0");
                 defines.push("#define NUM_BONE_INFLUENCERS 0");
             }
             }

+ 1 - 1
src/LensFlare/babylon.lensFlareSystem.ts

@@ -23,7 +23,7 @@
             this.id = name;
             this.id = name;
             scene.lensFlareSystems.push(this);
             scene.lensFlareSystems.push(this);
 
 
-            this.meshesSelectionPredicate = m => scene.activeCamera !== null && m.material && m.isVisible && m.isEnabled() && m.isBlocker && ((m.layerMask & scene.activeCamera.layerMask) != 0);
+            this.meshesSelectionPredicate = m => <boolean>(scene.activeCamera && m.material && m.isVisible && m.isEnabled() && m.isBlocker && ((m.layerMask & scene.activeCamera.layerMask) != 0));
 
 
             var engine = scene.getEngine();
             var engine = scene.getEngine();
 
 

+ 6 - 2
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -525,9 +525,14 @@
             var mesh = subMesh.getRenderingMesh();
             var mesh = subMesh.getRenderingMesh();
             var scene = this._scene;
             var scene = this._scene;
             var engine = scene.getEngine();
             var engine = scene.getEngine();
+            let material = subMesh.getMaterial();
+
+            if (!material) {
+                return;
+            }
 
 
             // Culling
             // Culling
-            engine.setState(subMesh.getMaterial().backFaceCulling);
+            engine.setState(material.backFaceCulling);
 
 
             // Managing instances
             // Managing instances
             var batch = mesh._getInstancesRenderList(subMesh._id);
             var batch = mesh._getInstancesRenderList(subMesh._id);
@@ -539,7 +544,6 @@
             if (this.isReady(subMesh, hardwareInstancedRendering)) {
             if (this.isReady(subMesh, hardwareInstancedRendering)) {
                 engine.enableEffect(this._effect);
                 engine.enableEffect(this._effect);
                 mesh._bind(subMesh, this._effect, Material.TriangleFillMode);
                 mesh._bind(subMesh, this._effect, Material.TriangleFillMode);
-                var material = subMesh.getMaterial();
 
 
                 this._effect.setFloat2("biasAndScale", this.bias, this.depthScale);
                 this._effect.setFloat2("biasAndScale", this.bias, this.depthScale);
 
 

+ 16 - 12
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -389,7 +389,7 @@
          * from cos thetav and roughness: 
          * from cos thetav and roughness: 
          * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
          * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
          */
          */
-        protected _environmentBRDFTexture: BaseTexture = null;
+        protected _environmentBRDFTexture: Nullable<BaseTexture> = null;
 
 
         /**
         /**
          * Force the shader to compute irradiance in the fragment shader in order to take bump in account.
          * Force the shader to compute irradiance in the fragment shader in order to take bump in account.
@@ -411,13 +411,13 @@
         /**
         /**
          * Keep track of the image processing observer to allow dispose and replace.
          * Keep track of the image processing observer to allow dispose and replace.
          */
          */
-        private _imageProcessingObserver: Observer<ImageProcessingConfiguration>;
+        private _imageProcessingObserver: Nullable<Observer<ImageProcessingConfiguration>>;
 
 
         /**
         /**
          * Attaches a new image processing configuration to the PBR Material.
          * Attaches a new image processing configuration to the PBR Material.
          * @param configuration 
          * @param configuration 
          */
          */
-        protected _attachImageProcessingConfiguration(configuration: ImageProcessingConfiguration): void {
+        protected _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>): void {
             if (configuration === this._imageProcessingConfiguration) {
             if (configuration === this._imageProcessingConfiguration) {
                 return;
                 return;
             }
             }
@@ -812,7 +812,7 @@
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
 
 
             // Values that need to be evaluated on every frame
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances, this._forceAlphaTest);
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._forceAlphaTest);
 
 
              // Attribs
              // Attribs
             if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true)) {
             if (MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true)) {
@@ -968,7 +968,7 @@
                 this.buildUniformLayout();
                 this.buildUniformLayout();
             }
             }
 
 
-            if (!subMesh.effect.isReady()) {
+            if (!subMesh.effect || !subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -1041,6 +1041,11 @@
             }
             }
 
 
             var effect = subMesh.effect;
             var effect = subMesh.effect;
+
+            if (!effect) {
+                return;
+            }
+
             this._activeEffect = effect;
             this._activeEffect = effect;
 
 
             // Matrices
             // Matrices
@@ -1051,11 +1056,12 @@
             // Bones
             // Bones
             MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
             MaterialHelper.BindBonesParameters(mesh, this._activeEffect);
 
 
+            let reflectionTexture: Nullable<BaseTexture> = null;
             if (mustRebind) {
             if (mustRebind) {
                 this._uniformBuffer.bindToEffect(effect, "Material");
                 this._uniformBuffer.bindToEffect(effect, "Material");
 
 
                 this.bindViewProjection(effect);
                 this.bindViewProjection(effect);
-                var reflectionTexture = this._getReflectionTexture();
+                reflectionTexture = this._getReflectionTexture();
                 var refractionTexture = this._getRefractionTexture();
                 var refractionTexture = this._getRefractionTexture();
                                
                                
                 if (!this._uniformBuffer.useUbo || !this.isFrozen || !this._uniformBuffer.isSync) {
                 if (!this._uniformBuffer.useUbo || !this.isFrozen || !this._uniformBuffer.isSync) {
@@ -1081,8 +1087,8 @@
                             this._uniformBuffer.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
                             this._uniformBuffer.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
                             this._uniformBuffer.updateFloat2("vReflectionInfos", reflectionTexture.level, 0);
                             this._uniformBuffer.updateFloat2("vReflectionInfos", reflectionTexture.level, 0);
 
 
-                            if (defines.USESPHERICALFROMREFLECTIONMAP) {
-                                var polynomials = reflectionTexture.sphericalPolynomial;
+                            var polynomials = reflectionTexture.sphericalPolynomial;
+                            if (defines.USESPHERICALFROMREFLECTIONMAP && polynomials) {
                                 this._activeEffect.setFloat3("vSphericalX", polynomials.x.x, polynomials.x.y, polynomials.x.z);
                                 this._activeEffect.setFloat3("vSphericalX", polynomials.x.x, polynomials.x.y, polynomials.x.z);
                                 this._activeEffect.setFloat3("vSphericalY", polynomials.y.x, polynomials.y.y, polynomials.y.z);
                                 this._activeEffect.setFloat3("vSphericalY", polynomials.y.x, polynomials.y.y, polynomials.y.z);
                                 this._activeEffect.setFloat3("vSphericalZ", polynomials.z.x, polynomials.z.y, polynomials.z.z);
                                 this._activeEffect.setFloat3("vSphericalZ", polynomials.z.x, polynomials.z.y, polynomials.z.z);
@@ -1259,7 +1265,7 @@
                 // Colors
                 // Colors
                 scene.ambientColor.multiplyToRef(this._ambientColor, this._globalAmbientColor);
                 scene.ambientColor.multiplyToRef(this._ambientColor, this._globalAmbientColor);
 
 
-                var eyePosition = scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.globalPosition;
+                var eyePosition = scene._mirroredCameraPosition ? scene._mirroredCameraPosition : (<Camera>scene.activeCamera).globalPosition;
                 var invertNormal = (scene.useRightHandedSystem === (scene._mirroredCameraPosition != null));
                 var invertNormal = (scene.useRightHandedSystem === (scene._mirroredCameraPosition != null));
                 effect.setFloat4("vEyePosition",
                 effect.setFloat4("vEyePosition",
                     eyePosition.x,
                     eyePosition.x,
@@ -1298,8 +1304,6 @@
             this._uniformBuffer.update();
             this._uniformBuffer.update();
 
 
             this._afterBind(mesh);
             this._afterBind(mesh);
-
-            scene = null;
         }
         }
 
 
         public getAnimatables(): IAnimatable[] {
         public getAnimatables(): IAnimatable[] {
@@ -1355,7 +1359,7 @@
             return this.getScene().environmentTexture;
             return this.getScene().environmentTexture;
         }
         }
 
 
-        private _getRefractionTexture(): BaseTexture {
+        private _getRefractionTexture(): Nullable<BaseTexture> {
             if (this._refractionTexture) {
             if (this._refractionTexture) {
                 return this._refractionTexture;
                 return this._refractionTexture;
             }
             }

+ 3 - 2
src/Materials/Textures/Procedurals/babylon.customProceduralTexture.ts

@@ -83,8 +83,9 @@ module BABYLON {
         }
         }
 
 
         public render(useCameraPostProcess?: boolean): void {
         public render(useCameraPostProcess?: boolean): void {
-            if (this._animate) {
-                this._time += this.getScene().getAnimationRatio() * 0.03;
+            let scene = this.getScene();
+            if (this._animate && scene) {
+                this._time += scene.getAnimationRatio() * 0.03;
                 this.updateShaderUniforms();
                 this.updateShaderUniforms();
             }
             }
 
 

+ 49 - 24
src/Materials/Textures/Procedurals/babylon.proceduralTexture.ts

@@ -8,8 +8,8 @@
 
 
         public onGenerated: () => void;
         public onGenerated: () => void;
 
 
-        private _vertexBuffers: { [key: string]: VertexBuffer } = {};
-        private _indexBuffer: WebGLBuffer;
+        private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
+        private _indexBuffer: Nullable<WebGLBuffer>;
         private _effect: Effect;
         private _effect: Effect;
 
 
         private _uniforms = new Array<string>();
         private _uniforms = new Array<string>();
@@ -25,15 +25,18 @@
         private _vectors3: {[key: string]: Vector3} = {};
         private _vectors3: {[key: string]: Vector3} = {};
         private _matrices: {[key: string]: Matrix} = {};
         private _matrices: {[key: string]: Matrix} = {};
 
 
-        private _fallbackTexture: Texture;
+        private _fallbackTexture: Nullable<Texture>;
 
 
         private _fallbackTextureUsed = false;
         private _fallbackTextureUsed = false;
+        private _engine: Engine;
 
 
-        constructor(name: string, size: any, fragment: any, scene: Scene, fallbackTexture?: Texture, generateMipMaps = true, public isCube = false) {
+        constructor(name: string, size: any, fragment: any, scene: Scene, fallbackTexture: Nullable<Texture> = null, generateMipMaps = true, public isCube = false) {
             super(null, scene, !generateMipMaps);
             super(null, scene, !generateMipMaps);
 
 
             scene._proceduralTextures.push(this);
             scene._proceduralTextures.push(this);
 
 
+            this._engine = scene.getEngine();
+
             this.name = name;
             this.name = name;
             this.isRenderTarget = true;
             this.isRenderTarget = true;
             this._size = size;
             this._size = size;
@@ -43,14 +46,12 @@
 
 
             this._fallbackTexture = fallbackTexture;
             this._fallbackTexture = fallbackTexture;
 
 
-            var engine = scene.getEngine();
-
             if (isCube) {
             if (isCube) {
-                this._texture = engine.createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps });
+                this._texture = this._engine.createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps });
                 this.setFloat("face", 0);
                 this.setFloat("face", 0);
             }
             }
             else {
             else {
-                this._texture = engine.createRenderTargetTexture(size, generateMipMaps);
+                this._texture = this._engine.createRenderTargetTexture(size, generateMipMaps);
             }
             }
 
 
             // VBO
             // VBO
@@ -60,13 +61,13 @@
             vertices.push(-1, -1);
             vertices.push(-1, -1);
             vertices.push(1, -1);
             vertices.push(1, -1);
 
 
-            this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, vertices, VertexBuffer.PositionKind, false, false, 2);
+            this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(this._engine, vertices, VertexBuffer.PositionKind, false, false, 2);
 
 
             this._createIndexBuffer();
             this._createIndexBuffer();
         }
         }
 
 
         private _createIndexBuffer(): void {
         private _createIndexBuffer(): void {
-            var engine = this.getScene().getEngine();
+            var engine = this._engine;
 
 
             // Indices
             // Indices
             var indices = [];
             var indices = [];
@@ -82,7 +83,12 @@
         }
         }
 
 
         public _rebuild(): void {
         public _rebuild(): void {
-            this._vertexBuffers[VertexBuffer.PositionKind]._rebuild();
+            let vb = this._vertexBuffers[VertexBuffer.PositionKind];
+
+            if (vb) {
+                vb._rebuild();
+            }
+            
             this._createIndexBuffer();
             this._createIndexBuffer();
 
 
             if (this.refreshRate === RenderTargetTexture.REFRESHRATE_RENDER_ONCE) {
             if (this.refreshRate === RenderTargetTexture.REFRESHRATE_RENDER_ONCE) {
@@ -93,14 +99,15 @@
         public reset(): void {
         public reset(): void {
             if (this._effect === undefined) {
             if (this._effect === undefined) {
                 return;
                 return;
-            }
-            var engine = this.getScene().getEngine();
+            }      
+            
+            var engine = this._engine;
             engine._releaseEffect(this._effect);
             engine._releaseEffect(this._effect);
         }
         }
 
 
 
 
         public isReady(): boolean {
         public isReady(): boolean {
-            var engine = this.getScene().getEngine();
+            var engine = this._engine;
             var shaders;
             var shaders;
 
 
             if (!this._fragment) {
             if (!this._fragment) {
@@ -122,12 +129,15 @@
                 [VertexBuffer.PositionKind],
                 [VertexBuffer.PositionKind],
                 this._uniforms,
                 this._uniforms,
                 this._samplers,
                 this._samplers,
-                "", null, null, () => {
+                "", undefined, undefined, () => {
                     this.releaseInternalTexture();
                     this.releaseInternalTexture();
 
 
                     if (this._fallbackTexture) {
                     if (this._fallbackTexture) {
                         this._texture = this._fallbackTexture._texture;
                         this._texture = this._fallbackTexture._texture;
-                        this._texture.incrementReferences();
+
+                        if (this._texture) {
+                            this._texture.incrementReferences();
+                        }
                     }
                     }
 
 
                     this._fallbackTextureUsed = true;
                     this._fallbackTextureUsed = true;
@@ -187,7 +197,7 @@
             }
             }
 
 
             this.releaseInternalTexture();
             this.releaseInternalTexture();
-            this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
+            this._texture = this._engine.createRenderTargetTexture(size, generateMipMaps);
         }
         }
 
 
         private _checkUniform(uniformName: string): void {
         private _checkUniform(uniformName: string): void {
@@ -254,9 +264,14 @@
             return this;
             return this;
         }
         }
 
 
-        public render(useCameraPostProcess?: boolean) {
+        public render(useCameraPostProcess?: boolean): void {
             var scene = this.getScene();
             var scene = this.getScene();
-            var engine = scene.getEngine();
+
+            if (!scene) {
+                return;
+            }
+
+            var engine = this._engine;
 
 
             // Render
             // Render
             engine.enableEffect(this._effect);
             engine.enableEffect(this._effect);
@@ -301,7 +316,11 @@
             // Matrix      
             // Matrix      
             for (name in this._matrices) {
             for (name in this._matrices) {
                 this._effect.setMatrix(name, this._matrices[name]);
                 this._effect.setMatrix(name, this._matrices[name]);
-            }            
+            }           
+            
+            if (!this._texture) {
+                return;
+            }
 
 
             if (this.isCube) {
             if (this.isCube) {
                 for (var face = 0; face < 6; face++) {
                 for (var face = 0; face < 6; face++) {
@@ -346,7 +365,7 @@
 
 
         public clone(): ProceduralTexture {
         public clone(): ProceduralTexture {
             var textureSize = this.getSize();
             var textureSize = this.getSize();
-            var newTexture = new ProceduralTexture(this.name, textureSize.width, this._fragment, this.getScene(), this._fallbackTexture, this._generateMipMaps);
+            var newTexture = new ProceduralTexture(this.name, textureSize.width, this._fragment, <Scene>this.getScene(), this._fallbackTexture, this._generateMipMaps);
 
 
             // Base texture
             // Base texture
             newTexture.hasAlpha = this.hasAlpha;
             newTexture.hasAlpha = this.hasAlpha;
@@ -359,10 +378,16 @@
         }
         }
 
 
         public dispose(): void {
         public dispose(): void {
-            var index = this.getScene()._proceduralTextures.indexOf(this);
+            let scene = this.getScene();
+
+            if (!scene) {
+                return;
+            }
+
+            var index = scene._proceduralTextures.indexOf(this);
 
 
             if (index >= 0) {
             if (index >= 0) {
-                this.getScene()._proceduralTextures.splice(index, 1);
+                scene._proceduralTextures.splice(index, 1);
             }
             }
 
 
             var vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];
             var vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];
@@ -371,7 +396,7 @@
                 this._vertexBuffers[VertexBuffer.PositionKind] = null;
                 this._vertexBuffers[VertexBuffer.PositionKind] = null;
             }
             }
 
 
-            if (this._indexBuffer && this.getScene().getEngine()._releaseBuffer(this._indexBuffer)) {
+            if (this._indexBuffer && this._engine._releaseBuffer(this._indexBuffer)) {
                 this._indexBuffer = null;
                 this._indexBuffer = null;
             }
             }
 
 

+ 23 - 16
src/Materials/Textures/babylon.colorGradingTexture.ts

@@ -24,6 +24,8 @@ module BABYLON {
          */
          */
         private static _noneEmptyLineRegex = /\S+/;
         private static _noneEmptyLineRegex = /\S+/;
 
 
+        private _engine: Engine;
+
         /**
         /**
          * Instantiates a ColorGradingTexture from the following parameters.
          * Instantiates a ColorGradingTexture from the following parameters.
          * 
          * 
@@ -37,12 +39,13 @@ module BABYLON {
                 return;
                 return;
             }
             }
 
 
+            this._engine = scene.getEngine();
             this._textureMatrix = Matrix.Identity();
             this._textureMatrix = Matrix.Identity();
             this.name = url;
             this.name = url;
             this.url = url;
             this.url = url;
             this.hasAlpha = false;
             this.hasAlpha = false;
             this.isCube = false;
             this.isCube = false;
-            this.is3D = scene.getEngine().webGLVersion > 1;
+            this.is3D = this._engine.webGLVersion > 1;
             this.wrapU = Texture.CLAMP_ADDRESSMODE;
             this.wrapU = Texture.CLAMP_ADDRESSMODE;
             this.wrapV = Texture.CLAMP_ADDRESSMODE;
             this.wrapV = Texture.CLAMP_ADDRESSMODE;
             this.wrapR = Texture.CLAMP_ADDRESSMODE;
             this.wrapR = Texture.CLAMP_ADDRESSMODE;
@@ -72,7 +75,7 @@ module BABYLON {
          * Occurs when the file being loaded is a .3dl LUT file.
          * Occurs when the file being loaded is a .3dl LUT file.
          */
          */
         private load3dlTexture() {
         private load3dlTexture() {
-            var engine = this.getScene().getEngine();
+            var engine = this._engine;
             var texture: InternalTexture;
             var texture: InternalTexture;
             if (engine.webGLVersion === 1) {
             if (engine.webGLVersion === 1) {
                 texture = engine.createRawTexture(null, 1, 1, BABYLON.Engine.TEXTUREFORMAT_RGBA, false, false, Texture.BILINEAR_SAMPLINGMODE);
                 texture = engine.createRawTexture(null, 1, 1, BABYLON.Engine.TEXTUREFORMAT_RGBA, false, false, Texture.BILINEAR_SAMPLINGMODE);
@@ -84,8 +87,8 @@ module BABYLON {
             this._texture = texture;
             this._texture = texture;
 
 
             var callback = (text: string) => {
             var callback = (text: string) => {
-                var data: Uint8Array;
-                var tempData: Float32Array;
+                var data: Nullable<Uint8Array> = null;
+                var tempData: Nullable<Float32Array> = null;
 
 
                 var line: string;
                 var line: string;
                 var lines = text.split('\n');
                 var lines = text.split('\n');
@@ -121,9 +124,11 @@ module BABYLON {
 
 
                         var pixelStorageIndex = (pixelIndexW + pixelIndexSlice * size + pixelIndexH * size * size) * 4;
                         var pixelStorageIndex = (pixelIndexW + pixelIndexSlice * size + pixelIndexH * size * size) * 4;
 
 
-                        tempData[pixelStorageIndex + 0] = r;
-                        tempData[pixelStorageIndex + 1] = g;
-                        tempData[pixelStorageIndex + 2] = b;
+                        if (tempData) {
+                            tempData[pixelStorageIndex + 0] = r;
+                            tempData[pixelStorageIndex + 1] = g;
+                            tempData[pixelStorageIndex + 2] = b;
+                        }
 
 
                         pixelIndexSlice++;
                         pixelIndexSlice++;
                         if (pixelIndexSlice % size == 0) {
                         if (pixelIndexSlice % size == 0) {
@@ -137,13 +142,15 @@ module BABYLON {
                     }
                     }
                 }
                 }
 
 
-                for (let i = 0; i < tempData.length; i++) {
-                    if (i > 0 && (i+1) % 4 === 0) {
-                        data[i] = 255;
-                    }
-                    else {
-                        var value = tempData[i];
-                        data[i] = (value / maxColor * 255);
+                if (tempData && data) {
+                    for (let i = 0; i < tempData.length; i++) {
+                        if (i > 0 && (i+1) % 4 === 0) {
+                            data[i] = 255;
+                        }
+                        else {
+                            var value = tempData[i];
+                            data[i] = (value / maxColor * 255);
+                        }
                     }
                     }
                 }
                 }
 
 
@@ -174,7 +181,7 @@ module BABYLON {
          * Clones the color gradind texture.
          * Clones the color gradind texture.
          */
          */
         public clone(): ColorGradingTexture {
         public clone(): ColorGradingTexture {
-            var newTexture = new ColorGradingTexture(this.url, this.getScene());
+            var newTexture = new ColorGradingTexture(this.url, <Scene>this.getScene());
 
 
             // Base texture
             // Base texture
             newTexture.level = this.level;
             newTexture.level = this.level;
@@ -205,7 +212,7 @@ module BABYLON {
          * @param rootUrl The root url of the data assets to load
          * @param rootUrl The root url of the data assets to load
          * @return A color gradind texture
          * @return A color gradind texture
          */
          */
-        public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): ColorGradingTexture {
+        public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): Nullable<ColorGradingTexture> {
             var texture = null;
             var texture = null;
             if (parsedTexture.name && !parsedTexture.isRenderTarget) {
             if (parsedTexture.name && !parsedTexture.isRenderTarget) {
                 texture = new BABYLON.ColorGradingTexture(parsedTexture.name, scene);
                 texture = new BABYLON.ColorGradingTexture(parsedTexture.name, scene);

+ 15 - 4
src/Materials/Textures/babylon.cubeTexture.ts

@@ -18,7 +18,8 @@
             return new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension);
             return new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension);
         }
         }
 
 
-        constructor(rootUrl: string, scene: Scene, extensions?: string[], noMipmap?: boolean, files?: string[], onLoad: () => void = null, onError: (message?: string, exception?: any) => void = null, format: number = Engine.TEXTUREFORMAT_RGBA, prefiltered = false, forcedExtension: any = null) {
+        constructor(rootUrl: string, scene: Scene, extensions: Nullable<string[]> = null, noMipmap: boolean = false, files: Nullable<string[]> = null,
+            onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, format: number = Engine.TEXTUREFORMAT_RGBA, prefiltered = false, forcedExtension: any = null) {
             super(scene);
             super(scene);
 
 
             this.name = rootUrl;
             this.name = rootUrl;
@@ -82,15 +83,20 @@
                 return;
                 return;
             }
             }
 
 
+            let scene = this.getScene();
+
+            if (!scene) {
+                return;
+            }
             this.delayLoadState = Engine.DELAYLOADSTATE_LOADED;
             this.delayLoadState = Engine.DELAYLOADSTATE_LOADED;
             this._texture = this._getFromCache(this.url, this._noMipmap);
             this._texture = this._getFromCache(this.url, this._noMipmap);
 
 
             if (!this._texture) {
             if (!this._texture) {
                 if (this._prefiltered) {
                 if (this._prefiltered) {
-                    this._texture = this.getScene().getEngine().createPrefilteredCubeTexture(this.url, this.getScene(), this.lodGenerationScale, this.lodGenerationOffset, undefined, undefined, this._format);
+                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, undefined, undefined, this._format);
                 }
                 }
                 else {
                 else {
-                    this._texture = this.getScene().getEngine().createCubeTexture(this.url, this.getScene(), this._files, this._noMipmap, undefined, undefined, this._format);
+                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, undefined, undefined, this._format);
                 }
                 }
             }
             }
         }
         }
@@ -122,7 +128,12 @@
 
 
         public clone(): CubeTexture {
         public clone(): CubeTexture {
             return SerializationHelper.Clone(() => {
             return SerializationHelper.Clone(() => {
-                return new CubeTexture(this.url, this.getScene(), this._extensions, this._noMipmap, this._files);
+                let scene = this.getScene();
+                
+                if (!scene) {
+                    return this;
+                }
+                return new CubeTexture(this.url, scene, this._extensions, this._noMipmap, this._files);
             }, this);
             }, this);
         }
         }
     }
     }

+ 15 - 8
src/Materials/Textures/babylon.dynamicTexture.ts

@@ -5,12 +5,13 @@ module BABYLON {
         private _generateMipMaps: boolean;
         private _generateMipMaps: boolean;
         private _canvas: HTMLCanvasElement;
         private _canvas: HTMLCanvasElement;
         private _context: CanvasRenderingContext2D;
         private _context: CanvasRenderingContext2D;
+        private _engine: Engine;
 
 
         constructor(name: string, options: any, scene: Scene, generateMipMaps: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, format: number = Engine.TEXTUREFORMAT_RGBA) {
         constructor(name: string, options: any, scene: Scene, generateMipMaps: boolean, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, format: number = Engine.TEXTUREFORMAT_RGBA) {
             super(null, scene, !generateMipMaps, undefined, samplingMode, undefined, undefined, undefined, undefined, format);
             super(null, scene, !generateMipMaps, undefined, samplingMode, undefined, undefined, undefined, undefined, format);
 
 
             this.name = name;
             this.name = name;
-            var engine = this.getScene().getEngine();
+            this._engine = (<Scene>this.getScene()).getEngine();
             this.wrapU = Texture.CLAMP_ADDRESSMODE;
             this.wrapU = Texture.CLAMP_ADDRESSMODE;
             this.wrapV = Texture.CLAMP_ADDRESSMODE;
             this.wrapV = Texture.CLAMP_ADDRESSMODE;
 
 
@@ -18,14 +19,14 @@ module BABYLON {
 
 
             if (options.getContext) {
             if (options.getContext) {
                 this._canvas = options;
                 this._canvas = options;
-                this._texture = engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
+                this._texture = this._engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
             } else {
             } else {
                 this._canvas = document.createElement("canvas");
                 this._canvas = document.createElement("canvas");
 
 
                 if (options.width) {
                 if (options.width) {
-                    this._texture = engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
+                    this._texture = this._engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
                 } else {
                 } else {
-                    this._texture = engine.createDynamicTexture(options, options, generateMipMaps, samplingMode);
+                    this._texture = this._engine.createDynamicTexture(options, options, generateMipMaps, samplingMode);
                 }
                 }
             }
             }
 
 
@@ -33,7 +34,7 @@ module BABYLON {
 
 
             this._canvas.width = textureSize.width;
             this._canvas.width = textureSize.width;
             this._canvas.height = textureSize.height;
             this._canvas.height = textureSize.height;
-            this._context = this._canvas.getContext("2d");
+            this._context = <CanvasRenderingContext2D>this._canvas.getContext("2d");
         }
         }
 
 
         public get canRescale(): boolean {
         public get canRescale(): boolean {
@@ -46,7 +47,7 @@ module BABYLON {
 
 
             this.releaseInternalTexture();
             this.releaseInternalTexture();
 
 
-            this._texture = this.getScene().getEngine().createDynamicTexture(textureSize.width, textureSize.height, this._generateMipMaps, this._samplingMode);
+            this._texture = this._engine.createDynamicTexture(textureSize.width, textureSize.height, this._generateMipMaps, this._samplingMode);
         }
         }
 
 
         public scale(ratio: number): void {
         public scale(ratio: number): void {
@@ -77,7 +78,7 @@ module BABYLON {
         }
         }
 
 
         public update(invertY?: boolean): void {
         public update(invertY?: boolean): void {
-            this.getScene().getEngine().updateDynamicTexture(this._texture, this._canvas, invertY === undefined ? true : invertY, undefined, this._format);
+            this._engine.updateDynamicTexture(this._texture, this._canvas, invertY === undefined ? true : invertY, undefined, this._format || undefined);
         }
         }
 
 
         public drawText(text: string, x: number, y: number, font: string, color: string, clearColor: string, invertY?: boolean, update = true) {
         public drawText(text: string, x: number, y: number, font: string, color: string, clearColor: string, invertY?: boolean, update = true) {
@@ -106,8 +107,14 @@ module BABYLON {
         }
         }
 
 
         public clone(): DynamicTexture {
         public clone(): DynamicTexture {
+            let scene = this.getScene();
+
+            if (!scene) {
+                return this;
+            }
+
             var textureSize = this.getSize();
             var textureSize = this.getSize();
-            var newTexture = new DynamicTexture(this.name, textureSize, this.getScene(), this._generateMipMaps);
+            var newTexture = new DynamicTexture(this.name, textureSize, scene, this._generateMipMaps);
 
 
             // Base texture
             // Base texture
             newTexture.hasAlpha = this.hasAlpha;
             newTexture.hasAlpha = this.hasAlpha;

+ 1 - 1
src/Materials/Textures/babylon.internalTexture.ts

@@ -34,7 +34,7 @@ module BABYLON {
         // Private
         // Private
         public _dataSource = InternalTexture.DATASOURCE_UNKNOWN;
         public _dataSource = InternalTexture.DATASOURCE_UNKNOWN;
         public _buffer: Nullable<ArrayBuffer | HTMLImageElement>;
         public _buffer: Nullable<ArrayBuffer | HTMLImageElement>;
-        public _bufferView: ArrayBufferView;
+        public _bufferView: Nullable<ArrayBufferView>;
         public _bufferViewArray: Nullable<ArrayBufferView[]>;
         public _bufferViewArray: Nullable<ArrayBufferView[]>;
         public _size: number;
         public _size: number;
         public _extension: string;
         public _extension: string;

+ 13 - 5
src/Materials/Textures/babylon.mirrorTexture.ts

@@ -75,7 +75,7 @@ module BABYLON {
 
 
                 scene.getEngine().cullBackFaces = false;
                 scene.getEngine().cullBackFaces = false;
 
 
-                scene._mirroredCameraPosition = Vector3.TransformCoordinates(scene.activeCamera.globalPosition, this._mirrorMatrix);
+                scene._mirroredCameraPosition = Vector3.TransformCoordinates((<Camera>scene.activeCamera).globalPosition, this._mirrorMatrix);
             });
             });
 
 
             this.onAfterRenderObservable.add(() => {
             this.onAfterRenderObservable.add(() => {
@@ -91,14 +91,14 @@ module BABYLON {
             this.clearPostProcesses(true);
             this.clearPostProcesses(true);
 
 
             if (this._blurKernelX && this._blurKernelY) {
             if (this._blurKernelX && this._blurKernelY) {
-                var engine = this.getScene().getEngine();
+                var engine = (<Scene>this.getScene()).getEngine();
 
 
                 var textureType = engine.getCaps().textureFloatRender ? Engine.TEXTURETYPE_FLOAT : Engine.TEXTURETYPE_HALF_FLOAT;
                 var textureType = engine.getCaps().textureFloatRender ? Engine.TEXTURETYPE_FLOAT : Engine.TEXTURETYPE_HALF_FLOAT;
 
 
                 this._blurX = new BABYLON.BlurPostProcess("horizontal blur", new BABYLON.Vector2(1.0, 0), this._blurKernelX, this._blurRatio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, textureType);
                 this._blurX = new BABYLON.BlurPostProcess("horizontal blur", new BABYLON.Vector2(1.0, 0), this._blurKernelX, this._blurRatio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, textureType);
                 this._blurX.autoClear = false;
                 this._blurX.autoClear = false;
 
 
-                if (this._blurRatio === 1 && this.samples < 2) {
+                if (this._blurRatio === 1 && this.samples < 2 && this._texture) {
                     this._blurX.outputTexture = this._texture;
                     this._blurX.outputTexture = this._texture;
                 } else {
                 } else {
                     this._blurX.alwaysForcePOT = true;
                     this._blurX.alwaysForcePOT = true;
@@ -114,11 +114,17 @@ module BABYLON {
         }   
         }   
 
 
         public clone(): MirrorTexture {
         public clone(): MirrorTexture {
+            let scene = this.getScene();
+
+            if (!scene) {
+                return this;
+            }
+
             var textureSize = this.getSize();
             var textureSize = this.getSize();
             var newTexture = new MirrorTexture(
             var newTexture = new MirrorTexture(
                 this.name,
                 this.name,
                 textureSize.width,
                 textureSize.width,
-                this.getScene(),
+                scene,
                 this._renderTargetOptions.generateMipMaps,
                 this._renderTargetOptions.generateMipMaps,
                 this._renderTargetOptions.type,
                 this._renderTargetOptions.type,
                 this._renderTargetOptions.samplingMode,
                 this._renderTargetOptions.samplingMode,
@@ -131,7 +137,9 @@ module BABYLON {
 
 
             // Mirror Texture
             // Mirror Texture
             newTexture.mirrorPlane = this.mirrorPlane.clone();
             newTexture.mirrorPlane = this.mirrorPlane.clone();
-            newTexture.renderList = this.renderList.slice(0);
+            if (this.renderList) {
+                newTexture.renderList = this.renderList.slice(0);
+            }
 
 
             return newTexture;
             return newTexture;
         }
         }

+ 7 - 5
src/Materials/Textures/babylon.multiRenderTarget.ts

@@ -13,10 +13,10 @@ module BABYLON {
         private _internalTextures: InternalTexture[];
         private _internalTextures: InternalTexture[];
         private _textures: Texture[];
         private _textures: Texture[];
         private _count: number;
         private _count: number;
+        private _engine: Engine;
 
 
         public get isSupported(): boolean {
         public get isSupported(): boolean {
-            var engine = this.getScene().getEngine();
-            return engine.webGLVersion > 1 || engine.getCaps().drawBuffersExtension;
+            return this._engine.webGLVersion > 1 || this._engine.getCaps().drawBuffersExtension;
         }
         }
 
 
         private _multiRenderTargetOptions: IMultiRenderTargetOptions;
         private _multiRenderTargetOptions: IMultiRenderTargetOptions;
@@ -54,6 +54,8 @@ module BABYLON {
 
 
             super(name, size, scene, generateMipMaps, doNotChangeAspectRatio);
             super(name, size, scene, generateMipMaps, doNotChangeAspectRatio);
 
 
+            this._engine = scene.getEngine();            
+
             if (!this.isSupported) {
             if (!this.isSupported) {
                 this.dispose();
                 this.dispose();
                 return;
                 return;
@@ -109,7 +111,7 @@ module BABYLON {
         }
         }
 
 
         private _createInternalTextures(): void {
         private _createInternalTextures(): void {
-            this._internalTextures = this.getScene().getEngine().createMultipleRenderTarget(this._size , this._multiRenderTargetOptions);
+            this._internalTextures = this._engine.createMultipleRenderTarget(this._size , this._multiRenderTargetOptions);
         }
         }
 
 
         private _createTextures(): void {
         private _createTextures(): void {
@@ -134,13 +136,13 @@ module BABYLON {
             }
             }
             
             
             for (var i = 0 ; i < this._internalTextures.length; i++) {
             for (var i = 0 ; i < this._internalTextures.length; i++) {
-                this._samples = this.getScene().getEngine().updateRenderTargetTextureSampleCount(this._internalTextures[i], value);
+                this._samples = this._engine.updateRenderTargetTextureSampleCount(this._internalTextures[i], value);
             }
             }
         }
         }
 
 
         public resize(size: any) {
         public resize(size: any) {
             this.releaseInternalTextures();
             this.releaseInternalTextures();
-            this._internalTextures = this.getScene().getEngine().createMultipleRenderTarget(size, this._multiRenderTargetOptions);
+            this._internalTextures = this._engine.createMultipleRenderTarget(size, this._multiRenderTargetOptions);
             this._createInternalTextures();
             this._createInternalTextures();
         }
         }
 
 

+ 3 - 2
src/Materials/Textures/babylon.rawTexture.ts

@@ -1,8 +1,9 @@
 module BABYLON {
 module BABYLON {
     export class RawTexture extends Texture {
     export class RawTexture extends Texture {
+        private _engine: Engine;
         constructor(data: ArrayBufferView, width: number, height: number, public format: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
         constructor(data: ArrayBufferView, width: number, height: number, public format: number, scene: Scene, generateMipMaps: boolean = true, invertY: boolean = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
             super(null, scene, !generateMipMaps, invertY);
             super(null, scene, !generateMipMaps, invertY);
-
+            this._engine = scene.getEngine();
             this._texture = scene.getEngine().createRawTexture(data, width, height, format, generateMipMaps, invertY, samplingMode);
             this._texture = scene.getEngine().createRawTexture(data, width, height, format, generateMipMaps, invertY, samplingMode);
 
 
             this.wrapU = Texture.CLAMP_ADDRESSMODE;
             this.wrapU = Texture.CLAMP_ADDRESSMODE;
@@ -10,7 +11,7 @@
         }
         }
 
 
         public update(data: ArrayBufferView): void {
         public update(data: ArrayBufferView): void {
-            this.getScene().getEngine().updateRawTexture(this._texture, data, this.format, this._invertY);
+            this._engine.updateRawTexture(this._texture, data, this.format, this._invertY);
         }
         }
 
 
         // Statics
         // Statics

+ 10 - 2
src/Materials/Textures/babylon.refractionTexture.ts

@@ -24,8 +24,14 @@ module BABYLON {
         }
         }
 
 
         public clone(): RefractionTexture {
         public clone(): RefractionTexture {
+            let scene = this.getScene();
+
+            if (!scene) {
+                return this;
+            }
+
             var textureSize = this.getSize();
             var textureSize = this.getSize();
-            var newTexture = new RefractionTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
+            var newTexture = new RefractionTexture(this.name, textureSize.width, scene, this._generateMipMaps);
 
 
             // Base texture
             // Base texture
             newTexture.hasAlpha = this.hasAlpha;
             newTexture.hasAlpha = this.hasAlpha;
@@ -33,7 +39,9 @@ module BABYLON {
 
 
             // Refraction Texture
             // Refraction Texture
             newTexture.refractionPlane = this.refractionPlane.clone();
             newTexture.refractionPlane = this.refractionPlane.clone();
-            newTexture.renderList = this.renderList.slice(0);
+            if (this.renderList) {
+                newTexture.renderList = this.renderList.slice(0);
+            }
             newTexture.depth = this.depth;
             newTexture.depth = this.depth;
 
 
             return newTexture;
             return newTexture;

+ 10 - 5
src/Materials/Textures/babylon.videoTexture.ts

@@ -6,6 +6,8 @@
         private _lastUpdate: number;
         private _lastUpdate: number;
         private _generateMipMaps: boolean
         private _generateMipMaps: boolean
         private _setTextureReady: () => void;
         private _setTextureReady: () => void;
+        private _engine: Engine;
+
         /**
         /**
          * Creates a video texture.
          * Creates a video texture.
          * Sample : https://doc.babylonjs.com/tutorials/01._Advanced_Texturing
          * Sample : https://doc.babylonjs.com/tutorials/01._Advanced_Texturing
@@ -18,7 +20,7 @@
         constructor(name: string, urlsOrVideo: string[] | HTMLVideoElement, scene: Scene, generateMipMaps = false, invertY = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
         constructor(name: string, urlsOrVideo: string[] | HTMLVideoElement, scene: Scene, generateMipMaps = false, invertY = false, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
             super(null, scene, !generateMipMaps, invertY);
             super(null, scene, !generateMipMaps, invertY);
 
 
-            var urls: string[];
+            var urls: Nullable<string[]> = null;
             this.name = name;
             this.name = name;
 
 
             if (urlsOrVideo instanceof HTMLVideoElement) {
             if (urlsOrVideo instanceof HTMLVideoElement) {
@@ -31,10 +33,11 @@
                 this.video.loop = true;
                 this.video.loop = true;
             }
             }
 
 
+            this._engine = (<Scene>this.getScene()).getEngine();
             this._generateMipMaps = generateMipMaps;
             this._generateMipMaps = generateMipMaps;
             this._samplingMode = samplingMode;
             this._samplingMode = samplingMode;
 
 
-            if (!this.getScene().getEngine().needPOTTextures ||(Tools.IsExponentOfTwo(this.video.videoWidth) && Tools.IsExponentOfTwo(this.video.videoHeight))) {
+            if (!this._engine.needPOTTextures ||(Tools.IsExponentOfTwo(this.video.videoWidth) && Tools.IsExponentOfTwo(this.video.videoHeight))) {
                 this.wrapU = Texture.WRAP_ADDRESSMODE;
                 this.wrapU = Texture.WRAP_ADDRESSMODE;
                 this.wrapV = Texture.WRAP_ADDRESSMODE;
                 this.wrapV = Texture.WRAP_ADDRESSMODE;
             } else {
             } else {
@@ -60,11 +63,13 @@
         }
         }
 
 
         private __setTextureReady(): void {
         private __setTextureReady(): void {
-            this._texture.isReady = true;
+            if (this._texture) {
+                this._texture.isReady = true;
+            }
         }
         }
 
 
         private _createTexture(): void {
         private _createTexture(): void {
-            this._texture = this.getScene().getEngine().createDynamicTexture(this.video.videoWidth, this.video.videoHeight, this._generateMipMaps, this._samplingMode);
+            this._texture = this._engine.createDynamicTexture(this.video.videoWidth, this.video.videoHeight, this._generateMipMaps, this._samplingMode);
 
 
             if (this._autoLaunch) {
             if (this._autoLaunch) {
                 this._autoLaunch = false;
                 this._autoLaunch = false;
@@ -87,7 +92,7 @@
             }
             }
 
 
             this._lastUpdate = now;
             this._lastUpdate = now;
-            this.getScene().getEngine().updateVideoTexture(this._texture, this.video, this._invertY);
+            this._engine.updateVideoTexture(this._texture, this.video, this._invertY);
             return true;
             return true;
         }
         }
 
 

+ 1 - 1
src/Materials/babylon.effect.ts

@@ -664,7 +664,7 @@
             this._engine.setTextureArray(this._samplers.indexOf(channel), this.getUniform(channel), textures);
             this._engine.setTextureArray(this._samplers.indexOf(channel), this.getUniform(channel), textures);
         }
         }
 
 
-        public setTextureFromPostProcess(channel: string, postProcess: PostProcess): void {
+        public setTextureFromPostProcess(channel: string, postProcess: Nullable<PostProcess>): void {
             this._engine.setTextureFromPostProcess(this._samplers.indexOf(channel), postProcess);
             this._engine.setTextureFromPostProcess(this._samplers.indexOf(channel), postProcess);
         }
         }
 
 

+ 2 - 1
src/Materials/babylon.imageProcessingConfiguration.ts

@@ -345,6 +345,7 @@ module BABYLON {
                 defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess;
                 defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess;
                 return;
                 return;
             }
             }
+
             defines.VIGNETTE = this.vignetteEnabled;
             defines.VIGNETTE = this.vignetteEnabled;
             defines.VIGNETTEBLENDMODEMULTIPLY = (this.vignetteBlendMode === ImageProcessingConfiguration._VIGNETTEMODE_MULTIPLY);
             defines.VIGNETTEBLENDMODEMULTIPLY = (this.vignetteBlendMode === ImageProcessingConfiguration._VIGNETTEMODE_MULTIPLY);
             defines.VIGNETTEBLENDMODEOPAQUE = !defines.VIGNETTEBLENDMODEMULTIPLY;
             defines.VIGNETTEBLENDMODEOPAQUE = !defines.VIGNETTEBLENDMODEMULTIPLY;
@@ -353,7 +354,7 @@ module BABYLON {
             defines.EXPOSURE = (this.exposure !== 1.0);
             defines.EXPOSURE = (this.exposure !== 1.0);
             defines.COLORCURVES = (this.colorCurvesEnabled && !!this.colorCurves);
             defines.COLORCURVES = (this.colorCurvesEnabled && !!this.colorCurves);
             defines.COLORGRADING = (this.colorGradingEnabled && !!this.colorGradingTexture);
             defines.COLORGRADING = (this.colorGradingEnabled && !!this.colorGradingTexture);
-            defines.COLORGRADING3D = defines.COLORGRADING && (this.colorGradingTexture.getScene().getEngine().webGLVersion > 1);
+            defines.COLORGRADING3D = defines.COLORGRADING && ((<Scene>this.colorGradingTexture.getScene()).getEngine().webGLVersion > 1);
             defines.SAMPLER3DGREENDEPTH = this.colorGradingWithGreenDepth;
             defines.SAMPLER3DGREENDEPTH = this.colorGradingWithGreenDepth;
             defines.SAMPLER3DBGRMAP = this.colorGradingBGR;
             defines.SAMPLER3DBGRMAP = this.colorGradingBGR;
             defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess;
             defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess;

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

@@ -462,7 +462,7 @@
             this._wasPreviouslyReady = false;
             this._wasPreviouslyReady = false;
         }
         }
 
 
-        public _preBind(effect?: Effect, overrideOrientation? : number): boolean {
+        public _preBind(effect?: Effect, overrideOrientation : Nullable<number> = null): boolean {
             var engine = this._scene.getEngine();
             var engine = this._scene.getEngine();
 
 
             var orientation = (overrideOrientation == null) ? this.sideOrientation : overrideOrientation;
             var orientation = (overrideOrientation == null) ? this.sideOrientation : overrideOrientation;

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

@@ -99,8 +99,8 @@
             }
             }
 
 
             if (useMorphTargets) {
             if (useMorphTargets) {
-                if ((<any>mesh).morphTargetManager) {
-                    var manager = (<Mesh>mesh).morphTargetManager;
+                var manager = (<Mesh>mesh).morphTargetManager;
+                if (manager) {
                     defines["MORPHTARGETS_TANGENT"] = manager.supportsTangents && defines["TANGENT"];
                     defines["MORPHTARGETS_TANGENT"] = manager.supportsTangents && defines["TANGENT"];
                     defines["MORPHTARGETS_NORMAL"] = manager.supportsNormals && defines["NORMAL"] ;
                     defines["MORPHTARGETS_NORMAL"] = manager.supportsNormals && defines["NORMAL"] ;
                     defines["MORPHTARGETS"] = (manager.numInfluencers > 0);
                     defines["MORPHTARGETS"] = (manager.numInfluencers > 0);
@@ -303,8 +303,8 @@
             if (influencers > 0 && Engine.LastCreatedEngine) {
             if (influencers > 0 && Engine.LastCreatedEngine) {
                 var maxAttributesCount = Engine.LastCreatedEngine.getCaps().maxVertexAttribs;
                 var maxAttributesCount = Engine.LastCreatedEngine.getCaps().maxVertexAttribs;
                 var manager = (<Mesh>mesh).morphTargetManager;
                 var manager = (<Mesh>mesh).morphTargetManager;
-                var normal = manager.supportsNormals && defines["NORMAL"];
-                var tangent = manager.supportsTangents && defines["TANGENT"];
+                var normal = manager && manager.supportsNormals && defines["NORMAL"];
+                var tangent = manager && manager.supportsTangents && defines["TANGENT"];
                 for (var index = 0; index < influencers; index++) {
                 for (var index = 0; index < influencers; index++) {
                     attribs.push(VertexBuffer.PositionKind + index);
                     attribs.push(VertexBuffer.PositionKind + index);
 
 
@@ -404,11 +404,12 @@
         }
         }
 
 
         public static BindMorphTargetParameters(abstractMesh: AbstractMesh, effect: Effect): void {
         public static BindMorphTargetParameters(abstractMesh: AbstractMesh, effect: Effect): void {
-            if (!abstractMesh || !(<Mesh>abstractMesh).morphTargetManager) {
+            let manager = (<Mesh>abstractMesh).morphTargetManager;
+            if (!abstractMesh || !manager) {
                 return;
                 return;
             }
             }
 
 
-            effect.setFloatArray("morphTargetInfluences", (<Mesh>abstractMesh).morphTargetManager.influences);
+            effect.setFloatArray("morphTargetInfluences", manager.influences);
         }
         }
 
 
         public static BindLogDepth(defines: any, effect: Effect, scene: Scene): void {
         public static BindLogDepth(defines: any, effect: Effect, scene: Scene): void {

+ 1 - 1
src/Materials/babylon.pushMaterial.ts

@@ -36,7 +36,7 @@
             this.bindForSubMesh(world, mesh, mesh.subMeshes[0]);
             this.bindForSubMesh(world, mesh, mesh.subMeshes[0]);
         }
         }
 
 
-        protected _afterBind(mesh: Mesh, effect?: Effect): void {
+        protected _afterBind(mesh: Mesh, effect: Nullable<Effect> = null): void {
             super._afterBind(mesh);
             super._afterBind(mesh);
             this.getScene()._cachedEffect = effect;
             this.getScene()._cachedEffect = effect;
         }
         }

+ 4 - 1
src/Materials/babylon.standardMaterial.ts

@@ -885,7 +885,7 @@ module BABYLON {
                 this.buildUniformLayout();
                 this.buildUniformLayout();
             }
             }
 
 
-            if (!subMesh.effect.isReady()) {
+            if (!subMesh.effect || !subMesh.effect.isReady()) {
                 return false;
                 return false;
             }
             }
 
 
@@ -958,6 +958,9 @@ module BABYLON {
             }
             }
 
 
             var effect = subMesh.effect;
             var effect = subMesh.effect;
+            if (!effect) {
+                return;
+            }
             this._activeEffect = effect;
             this._activeEffect = effect;
 
 
             // Matrices        
             // Matrices        

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

@@ -577,7 +577,7 @@ module BABYLON {
          * @param {string} name Name of the sampler.
          * @param {string} name Name of the sampler.
          * @param {Texture} texture
          * @param {Texture} texture
          */
          */
-        public setTexture(name: string, texture: BaseTexture) {
+        public setTexture(name: string, texture: Nullable<BaseTexture>) {
             this._currentEffect.setTexture(name, texture);
             this._currentEffect.setTexture(name, texture);
         }
         }
 
 

+ 11 - 13
src/Mesh/babylon.abstractMesh.ts

@@ -448,7 +448,7 @@
         }
         }
 
 
         // Constructor
         // Constructor
-        constructor(name: string, scene: Scene) {
+        constructor(name: string, scene: Nullable<Scene> = null) {
             super(name, scene);
             super(name, scene);
 
 
             this.getScene().addMesh(this);
             this.getScene().addMesh(this);
@@ -2077,8 +2077,6 @@
          * Returns the AbstractMesh.  
          * Returns the AbstractMesh.  
          */
          */
         public setParent(mesh: Nullable<AbstractMesh>): AbstractMesh {
         public setParent(mesh: Nullable<AbstractMesh>): AbstractMesh {
-
-            var child = this;
             var parent = (<AbstractMesh>mesh);
             var parent = (<AbstractMesh>mesh);
 
 
             if (mesh == null) {
             if (mesh == null) {
@@ -2087,17 +2085,17 @@
                 var position = Tmp.Vector3[0];
                 var position = Tmp.Vector3[0];
                 var scale = Tmp.Vector3[1];
                 var scale = Tmp.Vector3[1];
 
 
-                child.getWorldMatrix().decompose(scale, rotation, position);
+                this.getWorldMatrix().decompose(scale, rotation, position);
 
 
-                if (child.rotationQuaternion) {
-                    child.rotationQuaternion.copyFrom(rotation);
+                if (this.rotationQuaternion) {
+                    this.rotationQuaternion.copyFrom(rotation);
                 } else {
                 } else {
-                    rotation.toEulerAnglesToRef(child.rotation);
+                    rotation.toEulerAnglesToRef(this.rotation);
                 }
                 }
 
 
-                child.position.x = position.x;
-                child.position.y = position.y;
-                child.position.z = position.z;
+                this.position.x = position.x;
+                this.position.y = position.y;
+                this.position.z = position.z;
 
 
             } else {
             } else {
 
 
@@ -2105,11 +2103,11 @@
                 var m1 = Tmp.Matrix[0];
                 var m1 = Tmp.Matrix[0];
 
 
                 parent.getWorldMatrix().invertToRef(m1);
                 parent.getWorldMatrix().invertToRef(m1);
-                Vector3.TransformCoordinatesToRef(child.position, m1, position);
+                Vector3.TransformCoordinatesToRef(this.position, m1, position);
 
 
-                child.position.copyFrom(position);
+                this.position.copyFrom(position);
             }
             }
-            child.parent = parent;
+            this.parent = parent;
             return this;
             return this;
         }
         }
 
 

+ 4 - 4
src/Mesh/babylon.csg.ts

@@ -306,10 +306,10 @@
                 throw 'BABYLON.CSG: Wrong Mesh type, must be BABYLON.Mesh';
                 throw 'BABYLON.CSG: Wrong Mesh type, must be BABYLON.Mesh';
             }
             }
 
 
-            var indices = mesh.getIndices(),
-                positions = mesh.getVerticesData(VertexBuffer.PositionKind),
-                normals = mesh.getVerticesData(VertexBuffer.NormalKind),
-                uvs = mesh.getVerticesData(VertexBuffer.UVKind);
+            var indices = <IndicesArray>mesh.getIndices(),
+                positions = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind),
+                normals = <FloatArray>mesh.getVerticesData(VertexBuffer.NormalKind),
+                uvs = <FloatArray>mesh.getVerticesData(VertexBuffer.UVKind);
 
 
             var subMeshes = mesh.subMeshes;
             var subMeshes = mesh.subMeshes;
 
 

+ 27 - 3
src/Mesh/babylon.geometry.ts

@@ -46,6 +46,14 @@
             this.updateBoundingInfo(true, null);
             this.updateBoundingInfo(true, null);
         }
         }
 
 
+        public static CreateGeometryForMesh(mesh: Mesh): Geometry {
+            let geometry = new Geometry(Geometry.RandomId(), mesh.getScene());
+            
+            geometry.applyToMesh(mesh);
+
+            return geometry;
+        }
+
         constructor(id: string, scene: Scene, vertexData?: VertexData, updatable: boolean = false, mesh: Nullable<Mesh> = null) {
         constructor(id: string, scene: Scene, vertexData?: VertexData, updatable: boolean = false, mesh: Nullable<Mesh> = null) {
             this.id = id;
             this.id = id;
             this._engine = scene.getEngine();
             this._engine = scene.getEngine();
@@ -151,7 +159,7 @@
             this._vertexBuffers[kind] = buffer;
             this._vertexBuffers[kind] = buffer;
 
 
             if (kind === VertexBuffer.PositionKind) {
             if (kind === VertexBuffer.PositionKind) {
-                var data = buffer.getData();
+                var data = <FloatArray>buffer.getData();
                 var stride = buffer.getStrideSize();
                 var stride = buffer.getStrideSize();
 
 
                 this._totalVertices = data.length / stride;
                 this._totalVertices = data.length / stride;
@@ -271,7 +279,7 @@
             if (!vertexBuffer) {
             if (!vertexBuffer) {
                 return null;
                 return null;
             }
             }
-            var orig = vertexBuffer.getData();
+            var orig = <FloatArray>vertexBuffer.getData();
             if (!forceCopy && (!copyWhenShared || this._meshes.length === 1)) {
             if (!forceCopy && (!copyWhenShared || this._meshes.length === 1)) {
                 return orig;
                 return orig;
             } else {
             } else {
@@ -284,6 +292,22 @@
             }
             }
         }
         }
 
 
+        /**
+         * Returns a boolean defining if the vertex data for the requested `kind` is updatable.
+         * Possible `kind` values :
+         * - BABYLON.VertexBuffer.PositionKind
+         * - BABYLON.VertexBuffer.UVKind
+         * - BABYLON.VertexBuffer.UV2Kind
+         * - BABYLON.VertexBuffer.UV3Kind
+         * - BABYLON.VertexBuffer.UV4Kind
+         * - BABYLON.VertexBuffer.UV5Kind
+         * - BABYLON.VertexBuffer.UV6Kind
+         * - BABYLON.VertexBuffer.ColorKind
+         * - BABYLON.VertexBuffer.MatricesIndicesKind
+         * - BABYLON.VertexBuffer.MatricesIndicesExtraKind
+         * - BABYLON.VertexBuffer.MatricesWeightsKind
+         * - BABYLON.VertexBuffer.MatricesWeightsExtraKind
+         */        
         public isVertexBufferUpdatable(kind: string): boolean {
         public isVertexBufferUpdatable(kind: string): boolean {
             let vb = this._vertexBuffers[kind];
             let vb = this._vertexBuffers[kind];
 
 
@@ -460,7 +484,7 @@
 
 
         private updateExtend(data: Nullable<FloatArray> = null, stride? : number) {
         private updateExtend(data: Nullable<FloatArray> = null, stride? : number) {
             if (!data) {
             if (!data) {
-                data = this._vertexBuffers[VertexBuffer.PositionKind].getData();
+                data = <FloatArray>this._vertexBuffers[VertexBuffer.PositionKind].getData();
             }
             }
 
 
             this._extend = Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, stride);
             this._extend = Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, stride);

+ 5 - 0
src/Mesh/babylon.groundMesh.ts

@@ -161,6 +161,11 @@ module BABYLON {
         // Returns the GroundMesh.  
         // Returns the GroundMesh.  
         private _computeHeightQuads(): GroundMesh {
         private _computeHeightQuads(): GroundMesh {
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
+
+            if (!positions) {
+                return this;
+            }
+
             var v1 = Tmp.Vector3[3];
             var v1 = Tmp.Vector3[3];
             var v2 = Tmp.Vector3[2];
             var v2 = Tmp.Vector3[2];
             var v3 = Tmp.Vector3[1];
             var v3 = Tmp.Vector3[1];

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

@@ -167,7 +167,7 @@
             return this._sourceMesh.getIndices();
             return this._sourceMesh.getIndices();
         }
         }
 
 
-        public get _positions(): Vector3[] {
+        public get _positions(): Nullable<Vector3[]> {
             return this._sourceMesh._positions;
             return this._sourceMesh._positions;
         }
         }
 
 

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

@@ -34,7 +34,7 @@ module BABYLON {
         private _intersectionThreshold: number;
         private _intersectionThreshold: number;
         private _colorShader: ShaderMaterial;
         private _colorShader: ShaderMaterial;
 
 
-        constructor(name: string, scene: Scene, parent: Nullable<Node> = null, source?: LinesMesh, doNotCloneChildren?: boolean, public useVertexColor? : boolean) {
+        constructor(name: string, scene: Nullable<Scene> = null, parent: Nullable<Node> = null, source?: LinesMesh, doNotCloneChildren?: boolean, public useVertexColor? : boolean) {
             super(name, scene, parent, source, doNotCloneChildren);
             super(name, scene, parent, source, doNotCloneChildren);
 
 
             if (source) {
             if (source) {
@@ -56,7 +56,7 @@ module BABYLON {
                 options.needAlphaBlending = true;
                 options.needAlphaBlending = true;
             }
             }
 
 
-            this._colorShader = new ShaderMaterial("colorShader", scene, "color", options);
+            this._colorShader = new ShaderMaterial("colorShader", this.getScene(), "color", options);
         }
         }
 
 
         /**
         /**

+ 175 - 68
src/Mesh/babylon.mesh.ts

@@ -1,7 +1,7 @@
 module BABYLON {
 module BABYLON {
     export class _InstancesBatch {
     export class _InstancesBatch {
         public mustReturn = false;
         public mustReturn = false;
-        public visibleInstances = new Array<Array<InstancedMesh>>();
+        public visibleInstances = new Array<Nullable<Array<InstancedMesh>>>();
         public renderSelf = new Array<boolean>();
         public renderSelf = new Array<boolean>();
     }
     }
 
 
@@ -101,13 +101,13 @@
         public onLODLevelSelection: (distance: number, mesh: Mesh, selectedLevel: Mesh) => void;
         public onLODLevelSelection: (distance: number, mesh: Mesh, selectedLevel: Mesh) => void;
 
 
         // Morph
         // Morph
-        private _morphTargetManager: MorphTargetManager;
+        private _morphTargetManager: Nullable<MorphTargetManager>;
 
 
-        public get morphTargetManager(): MorphTargetManager {
+        public get morphTargetManager(): Nullable<MorphTargetManager> {
             return this._morphTargetManager;
             return this._morphTargetManager;
         }
         }
 
 
-        public set morphTargetManager(value: MorphTargetManager) {
+        public set morphTargetManager(value: Nullable<MorphTargetManager>) {
             if (this._morphTargetManager === value) {
             if (this._morphTargetManager === value) {
                 return;
                 return;
             }
             }
@@ -124,7 +124,7 @@
         private _renderIdForInstances = new Array<number>();
         private _renderIdForInstances = new Array<number>();
         private _batchCache = new _InstancesBatch();
         private _batchCache = new _InstancesBatch();
         private _instancesBufferSize = 32 * 16 * 4; // let's start with a maximum of 32 instances
         private _instancesBufferSize = 32 * 16 * 4; // let's start with a maximum of 32 instances
-        private _instancesBuffer: Buffer;
+        private _instancesBuffer: Nullable<Buffer>;
         private _instancesData: Float32Array;
         private _instancesData: Float32Array;
         private _overridenInstanceCount: number;
         private _overridenInstanceCount: number;
 
 
@@ -160,9 +160,11 @@
          *                  This will make creation of children, recursive.
          *                  This will make creation of children, recursive.
          * @param {boolean} clonePhysicsImpostor When cloning, include cloning mesh physics impostor, default True.
          * @param {boolean} clonePhysicsImpostor When cloning, include cloning mesh physics impostor, default True.
          */
          */
-        constructor(name: string, scene: Scene, parent: Nullable<Node> = null, source?: Mesh, doNotCloneChildren?: boolean, clonePhysicsImpostor: boolean = true) {
+        constructor(name: string, scene: Nullable<Scene> = null, parent: Nullable<Node> = null, source: Nullable<Mesh> = null, doNotCloneChildren?: boolean, clonePhysicsImpostor: boolean = true) {
             super(name, scene);
             super(name, scene);
 
 
+            scene = this.getScene();
+
             if (source) {
             if (source) {
                 // Source mesh
                 // Source mesh
                 this._source = source;
                 this._source = source;
@@ -492,6 +494,33 @@
             }
             }
             return this._geometry.isVerticesDataPresent(kind);
             return this._geometry.isVerticesDataPresent(kind);
         }
         }
+
+
+        /**
+         * Returns a boolean defining if the vertex data for the requested `kind` is updatable.
+         * Possible `kind` values :
+         * - BABYLON.VertexBuffer.PositionKind
+         * - BABYLON.VertexBuffer.UVKind
+         * - BABYLON.VertexBuffer.UV2Kind
+         * - BABYLON.VertexBuffer.UV3Kind
+         * - BABYLON.VertexBuffer.UV4Kind
+         * - BABYLON.VertexBuffer.UV5Kind
+         * - BABYLON.VertexBuffer.UV6Kind
+         * - BABYLON.VertexBuffer.ColorKind
+         * - BABYLON.VertexBuffer.MatricesIndicesKind
+         * - BABYLON.VertexBuffer.MatricesIndicesExtraKind
+         * - BABYLON.VertexBuffer.MatricesWeightsKind
+         * - BABYLON.VertexBuffer.MatricesWeightsExtraKind
+         */
+        public isVertexBufferUpdatable(kind: string): boolean {
+            if (!this._geometry) {
+                if (this._delayInfo) {
+                    return this._delayInfo.indexOf(kind) !== -1;
+                }
+                return false;
+            }
+            return this._geometry.isVertexBufferUpdatable(kind);
+        }        
         /**
         /**
          * Returns a string : the list of existing `kinds` of Vertex Data for this mesh.  
          * Returns a string : the list of existing `kinds` of Vertex Data for this mesh.  
          * Possible `kind` values :
          * Possible `kind` values :
@@ -783,9 +812,7 @@
          */
          */
         public setVerticesBuffer(buffer: VertexBuffer): Mesh {
         public setVerticesBuffer(buffer: VertexBuffer): Mesh {
             if (!this._geometry) {
             if (!this._geometry) {
-                var scene = this.getScene();
-
-                new Geometry(Geometry.RandomId(), scene).applyToMesh(this);
+                this._geometry = Geometry.CreateGeometryForMesh(this);
             }
             }
 
 
             this._geometry.setVerticesBuffer(buffer);
             this._geometry.setVerticesBuffer(buffer);
@@ -839,11 +866,21 @@
          */
          */
         public updateMeshPositions(positionFunction: (data: FloatArray) => void, computeNormals: boolean = true): Mesh {
         public updateMeshPositions(positionFunction: (data: FloatArray) => void, computeNormals: boolean = true): Mesh {
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
+            if (!positions) {
+                return this;
+            }
+
             positionFunction(positions);
             positionFunction(positions);
             this.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);
             this.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);
+
             if (computeNormals) {
             if (computeNormals) {
                 var indices = this.getIndices();
                 var indices = this.getIndices();
                 var normals = this.getVerticesData(VertexBuffer.NormalKind);
                 var normals = this.getVerticesData(VertexBuffer.NormalKind);
+
+                if (!normals) {
+                    return this;
+                }
+
                 VertexData.ComputeNormals(positions, indices, normals);
                 VertexData.ComputeNormals(positions, indices, normals);
                 this.updateVerticesData(VertexBuffer.NormalKind, normals, false, false);
                 this.updateVerticesData(VertexBuffer.NormalKind, normals, false, false);
             }
             }
@@ -915,6 +952,10 @@
         }
         }
 
 
         public _bind(subMesh: SubMesh, effect: Effect, fillMode: number): Mesh {
         public _bind(subMesh: SubMesh, effect: Effect, fillMode: number): Mesh {
+            if (!this._geometry) {
+                return this;
+            }
+
             var engine = this.getScene().getEngine();
             var engine = this.getScene().getEngine();
 
 
             // Wireframe
             // Wireframe
@@ -928,7 +969,7 @@
                         indexToBind = null;
                         indexToBind = null;
                         break;
                         break;
                     case Material.WireFrameFillMode:
                     case Material.WireFrameFillMode:
-                        indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
+                        indexToBind = subMesh.getLinesIndexBuffer(<IndicesArray>this.getIndices(), engine);
                         break;
                         break;
                     default:
                     default:
                     case Material.TriangleFillMode:
                     case Material.TriangleFillMode:
@@ -975,6 +1016,9 @@
 
 
             if (scene._isAlternateRenderingEnabled && !alternate) {
             if (scene._isAlternateRenderingEnabled && !alternate) {
                 let effect = subMesh.effect || this._effectiveMaterial.getEffect();
                 let effect = subMesh.effect || this._effectiveMaterial.getEffect();
+                if (!effect || !scene.activeCamera) {
+                    return this;
+                }
                 scene._switchToAlternateCameraConfiguration(true);
                 scene._switchToAlternateCameraConfiguration(true);
                 this._effectiveMaterial.bindView(effect);
                 this._effectiveMaterial.bindView(effect);
                 this._effectiveMaterial.bindViewProjection(effect);
                 this._effectiveMaterial.bindViewProjection(effect);
@@ -1048,7 +1092,8 @@
                     selfRenderId = Math.max(this._visibleInstances.selfDefaultRenderId, currentRenderId);
                     selfRenderId = Math.max(this._visibleInstances.selfDefaultRenderId, currentRenderId);
                 }
                 }
 
 
-                if (this._batchCache.visibleInstances[subMeshId] && this._batchCache.visibleInstances[subMeshId].length) {
+                let visibleInstancesForSubMesh = this._batchCache.visibleInstances[subMeshId];
+                if (visibleInstancesForSubMesh && visibleInstancesForSubMesh.length) {
                     if (this._renderIdForInstances[subMeshId] === currentRenderId) {
                     if (this._renderIdForInstances[subMeshId] === currentRenderId) {
                         this._batchCache.mustReturn = true;
                         this._batchCache.mustReturn = true;
                         return this._batchCache;
                         return this._batchCache;
@@ -1067,6 +1112,10 @@
 
 
         public _renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: Engine): Mesh {
         public _renderWithInstances(subMesh: SubMesh, fillMode: number, batch: _InstancesBatch, effect: Effect, engine: Engine): Mesh {
             var visibleInstances = batch.visibleInstances[subMesh._id];
             var visibleInstances = batch.visibleInstances[subMesh._id];
+            if (!visibleInstances) {
+                return this;
+            }
+
             var matricesCount = visibleInstances.length + 1;
             var matricesCount = visibleInstances.length + 1;
             var bufferSize = matricesCount * 16 * 4;
             var bufferSize = matricesCount * 16 * 4;
 
 
@@ -1140,9 +1189,11 @@
                     this._draw(subMesh, fillMode, this._overridenInstanceCount);
                     this._draw(subMesh, fillMode, this._overridenInstanceCount);
                 }
                 }
 
 
-                if (batch.visibleInstances[subMesh._id]) {
-                    for (var instanceIndex = 0; instanceIndex < batch.visibleInstances[subMesh._id].length; instanceIndex++) {
-                        var instance = batch.visibleInstances[subMesh._id][instanceIndex];
+                let visibleInstancesForSubMesh = batch.visibleInstances[subMesh._id];
+
+                if (visibleInstancesForSubMesh) {                
+                    for (var instanceIndex = 0; instanceIndex < visibleInstancesForSubMesh.length; instanceIndex++) {
+                        var instance = visibleInstancesForSubMesh[instanceIndex];
 
 
                         // World
                         // World
                         var world = instance.getWorldMatrix();
                         var world = instance.getWorldMatrix();
@@ -1190,12 +1241,14 @@
             var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
             var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
 
 
             // Material
             // Material
-            this._effectiveMaterial = subMesh.getMaterial();
+            let material = subMesh.getMaterial();
 
 
-            if (!this._effectiveMaterial) {
+            if (!material) {
                 return this;
                 return this;
             }
             }
 
 
+            this._effectiveMaterial = material
+
             if (this._effectiveMaterial.storeEffectOnSubMeshes) {
             if (this._effectiveMaterial.storeEffectOnSubMeshes) {
                 if (!this._effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
                 if (!this._effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
                     return this;
                     return this;
@@ -1217,13 +1270,17 @@
                 engine.setDepthWrite(savedDepthWrite);
                 engine.setDepthWrite(savedDepthWrite);
             }
             }
 
 
-            var effect: Effect;
+            var effect: Nullable<Effect>;
             if (this._effectiveMaterial.storeEffectOnSubMeshes) {
             if (this._effectiveMaterial.storeEffectOnSubMeshes) {
                 effect = subMesh.effect;
                 effect = subMesh.effect;
             } else {
             } else {
                 effect = this._effectiveMaterial.getEffect();
                 effect = this._effectiveMaterial.getEffect();
             }
             }
 
 
+            if (!effect) {
+                return this;
+            }
+
             var reverse = this._effectiveMaterial._preBind(effect, this.overrideMaterialSideOrientation);
             var reverse = this._effectiveMaterial._preBind(effect, this.overrideMaterialSideOrientation);
 
 
             if (this._effectiveMaterial.forceDepthWrite) {
             if (this._effectiveMaterial.forceDepthWrite) {
@@ -1435,25 +1492,26 @@
 
 
             this._resetPointsArrayCache();
             this._resetPointsArrayCache();
 
 
-            var data = this.getVerticesData(VertexBuffer.PositionKind);
+            var data = <FloatArray>this.getVerticesData(VertexBuffer.PositionKind);
+
             var temp = new Array<number>();
             var temp = new Array<number>();
             var index: number;
             var index: number;
             for (index = 0; index < data.length; index += 3) {
             for (index = 0; index < data.length; index += 3) {
                 Vector3.TransformCoordinates(Vector3.FromArray(data, index), transform).toArray(temp, index);
                 Vector3.TransformCoordinates(Vector3.FromArray(data, index), transform).toArray(temp, index);
             }
             }
 
 
-            this.setVerticesData(VertexBuffer.PositionKind, temp, this.getVertexBuffer(VertexBuffer.PositionKind).isUpdatable());
+            this.setVerticesData(VertexBuffer.PositionKind, temp, (<VertexBuffer>this.getVertexBuffer(VertexBuffer.PositionKind)).isUpdatable());
 
 
             // Normals
             // Normals
             if (!this.isVerticesDataPresent(VertexBuffer.NormalKind)) {
             if (!this.isVerticesDataPresent(VertexBuffer.NormalKind)) {
                 return this;
                 return this;
             }
             }
-            data = this.getVerticesData(VertexBuffer.NormalKind);
+            data = <FloatArray>this.getVerticesData(VertexBuffer.NormalKind);
             temp = [];
             temp = [];
             for (index = 0; index < data.length; index += 3) {
             for (index = 0; index < data.length; index += 3) {
                 Vector3.TransformNormal(Vector3.FromArray(data, index), transform).normalize().toArray(temp, index);
                 Vector3.TransformNormal(Vector3.FromArray(data, index), transform).normalize().toArray(temp, index);
             }
             }
-            this.setVerticesData(VertexBuffer.NormalKind, temp, this.getVertexBuffer(VertexBuffer.NormalKind).isUpdatable());
+            this.setVerticesData(VertexBuffer.NormalKind, temp, (<VertexBuffer>this.getVertexBuffer(VertexBuffer.NormalKind)).isUpdatable());
 
 
             // flip faces?
             // flip faces?
             if (transform.m[0] * transform.m[5] * transform.m[10] < 0) { this.flipFaces(); }
             if (transform.m[0] * transform.m[5] * transform.m[10] < 0) { this.flipFaces(); }
@@ -1486,7 +1544,7 @@
         }
         }
 
 
         // Cache
         // Cache
-        public get _positions(): Vector3[] {
+        public get _positions(): Nullable<Vector3[]> {
             if (this._geometry) {
             if (this._geometry) {
                 return this._geometry._positions;
                 return this._geometry._positions;
             }
             }
@@ -1524,7 +1582,7 @@
          * This also frees the memory allocated under the hood to all the buffers used by WebGL.
          * This also frees the memory allocated under the hood to all the buffers used by WebGL.
          */
          */
         public dispose(doNotRecurse?: boolean): void {
         public dispose(doNotRecurse?: boolean): void {
-            this.morphTargetManager = undefined;
+            this.morphTargetManager = null;
 
 
             if (this._geometry) {
             if (this._geometry) {
                 this._geometry.releaseForMesh(this, true);
                 this._geometry.releaseForMesh(this, true);
@@ -1580,7 +1638,7 @@
             var onload = (img: HTMLImageElement) => {
             var onload = (img: HTMLImageElement) => {
                 // Getting height map data
                 // Getting height map data
                 var canvas = document.createElement("canvas");
                 var canvas = document.createElement("canvas");
-                var context = canvas.getContext("2d");
+                var context = <CanvasRenderingContext2D>canvas.getContext("2d");
                 var heightMapWidth = img.width;
                 var heightMapWidth = img.width;
                 var heightMapHeight = img.height;
                 var heightMapHeight = img.height;
                 canvas.width = heightMapWidth;
                 canvas.width = heightMapWidth;
@@ -1624,9 +1682,9 @@
                 return this;
                 return this;
             }
             }
 
 
-            var positions = this.getVerticesData(VertexBuffer.PositionKind);
-            var normals = this.getVerticesData(VertexBuffer.NormalKind);
-            var uvs = this.getVerticesData(VertexBuffer.UVKind);
+            var positions = <FloatArray>this.getVerticesData(VertexBuffer.PositionKind);
+            var normals = <FloatArray>this.getVerticesData(VertexBuffer.NormalKind);
+            var uvs = <number[]>this.getVerticesData(VertexBuffer.UVKind);
             var position = Vector3.Zero();
             var position = Vector3.Zero();
             var normal = Vector3.Zero();
             var normal = Vector3.Zero();
             var uv = Vector2.Zero();
             var uv = Vector2.Zero();
@@ -1683,7 +1741,7 @@
             var kind: string;
             var kind: string;
             for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
             for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
                 kind = kinds[kindIndex];
                 kind = kinds[kindIndex];
-                var vertexBuffer = this.getVertexBuffer(kind);
+                var vertexBuffer = <VertexBuffer>this.getVertexBuffer(kind);
 
 
                 if (kind === VertexBuffer.NormalKind) {
                 if (kind === VertexBuffer.NormalKind) {
                     updatableNormals = vertexBuffer.isUpdatable();
                     updatableNormals = vertexBuffer.isUpdatable();
@@ -1693,14 +1751,14 @@
                 }
                 }
 
 
                 vbs[kind] = vertexBuffer;
                 vbs[kind] = vertexBuffer;
-                data[kind] = vbs[kind].getData();
+                data[kind] = <FloatArray>vbs[kind].getData();
                 newdata[kind] = [];
                 newdata[kind] = [];
             }
             }
 
 
             // Save previous submeshes
             // Save previous submeshes
             var previousSubmeshes = this.subMeshes.slice(0);
             var previousSubmeshes = this.subMeshes.slice(0);
 
 
-            var indices = this.getIndices();
+            var indices = <IndicesArray>this.getIndices();
             var totalIndices = this.getTotalIndices();
             var totalIndices = this.getTotalIndices();
 
 
             // Generating unique vertices per face
             // Generating unique vertices per face
@@ -1781,16 +1839,16 @@
             var kind: string;
             var kind: string;
             for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
             for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
                 kind = kinds[kindIndex];
                 kind = kinds[kindIndex];
-                var vertexBuffer = this.getVertexBuffer(kind);
+                var vertexBuffer = <VertexBuffer>this.getVertexBuffer(kind);
                 vbs[kind] = vertexBuffer;
                 vbs[kind] = vertexBuffer;
-                data[kind] = vbs[kind].getData();
+                data[kind] = <FloatArray>vbs[kind].getData();
                 newdata[kind] = [];
                 newdata[kind] = [];
             }
             }
 
 
             // Save previous submeshes
             // Save previous submeshes
             var previousSubmeshes = this.subMeshes.slice(0);
             var previousSubmeshes = this.subMeshes.slice(0);
 
 
-            var indices = this.getIndices();
+            var indices = <IndicesArray>this.getIndices();
             var totalIndices = this.getTotalIndices();
             var totalIndices = this.getTotalIndices();
 
 
             // Generating unique vertices per face
             // Generating unique vertices per face
@@ -1844,18 +1902,20 @@
         public flipFaces(flipNormals: boolean = false): Mesh {
         public flipFaces(flipNormals: boolean = false): Mesh {
             var vertex_data = VertexData.ExtractFromMesh(this);
             var vertex_data = VertexData.ExtractFromMesh(this);
             var i: number;
             var i: number;
-            if (flipNormals && this.isVerticesDataPresent(VertexBuffer.NormalKind)) {
+            if (flipNormals && this.isVerticesDataPresent(VertexBuffer.NormalKind) && vertex_data.normals) {
                 for (i = 0; i < vertex_data.normals.length; i++) {
                 for (i = 0; i < vertex_data.normals.length; i++) {
                     vertex_data.normals[i] *= -1;
                     vertex_data.normals[i] *= -1;
                 }
                 }
             }
             }
 
 
-            var temp;
-            for (i = 0; i < vertex_data.indices.length; i += 3) {
-                // reassign indices
-                temp = vertex_data.indices[i + 1];
-                vertex_data.indices[i + 1] = vertex_data.indices[i + 2];
-                vertex_data.indices[i + 2] = temp;
+            if (vertex_data.indices) {
+                var temp;
+                for (i = 0; i < vertex_data.indices.length; i += 3) {
+                    // reassign indices
+                    temp = vertex_data.indices[i + 1];
+                    vertex_data.indices[i + 1] = vertex_data.indices[i + 2];
+                    vertex_data.indices[i + 2] = temp;
+                }
             }
             }
 
 
             vertex_data.applyToMesh(this);
             vertex_data.applyToMesh(this);
@@ -1919,8 +1979,13 @@
          * @param successCallback an optional success callback to be called after the optimization finished.   
          * @param successCallback an optional success callback to be called after the optimization finished.   
          */
          */
         public optimizeIndices(successCallback?: (mesh?: Mesh) => void): Mesh {
         public optimizeIndices(successCallback?: (mesh?: Mesh) => void): Mesh {
-            var indices = this.getIndices();
+            var indices = <IndicesArray>this.getIndices();
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
             var positions = this.getVerticesData(VertexBuffer.PositionKind);
+
+            if (!positions || !indices) {
+                return this;
+            }
+
             var vectorPositions = new Array<Vector3>();
             var vectorPositions = new Array<Vector3>();
             for (var pos = 0; pos < positions.length; pos = pos + 3) {
             for (var pos = 0; pos < positions.length; pos = pos + 3) {
                 vectorPositions.push(Vector3.FromArray(positions, pos));
                 vectorPositions.push(Vector3.FromArray(positions, pos));
@@ -2031,12 +2096,13 @@
 
 
             // Physics
             // Physics
             //TODO implement correct serialization for physics impostors.
             //TODO implement correct serialization for physics impostors.
-            if (this.getPhysicsImpostor()) {
-                var impostor = this.getPhysicsImpostor();
+            
+            let impostor = this.getPhysicsImpostor();
+            if (impostor) {
                 serializationObject.physicsMass = impostor.getParam("mass");
                 serializationObject.physicsMass = impostor.getParam("mass");
                 serializationObject.physicsFriction = impostor.getParam("friction");
                 serializationObject.physicsFriction = impostor.getParam("friction");
                 serializationObject.physicsRestitution = impostor.getParam("mass");
                 serializationObject.physicsRestitution = impostor.getParam("mass");
-                serializationObject.physicsImpostor = this.getPhysicsImpostor().type;
+                serializationObject.physicsImpostor = impostor.type;
             }
             }
 
 
             // Metadata
             // Metadata
@@ -2099,15 +2165,16 @@
 
 
             this._markSubMeshesAsAttributesDirty();
             this._markSubMeshesAsAttributesDirty();
 
 
-            if (this._morphTargetManager && this._morphTargetManager.vertexCount) {
-                if (this._morphTargetManager.vertexCount !== this.getTotalVertices()) {
+            let morphTargetManager = this._morphTargetManager;
+            if (morphTargetManager && morphTargetManager.vertexCount) {
+                if (morphTargetManager.vertexCount !== this.getTotalVertices()) {
                     Tools.Error("Mesh is incompatible with morph targets. Targets and mesh must all have the same vertices count.");
                     Tools.Error("Mesh is incompatible with morph targets. Targets and mesh must all have the same vertices count.");
-                    this.morphTargetManager = undefined;
+                    this.morphTargetManager = null;
                     return;
                     return;
                 }
                 }
 
 
-                for (var index = 0; index < this.morphTargetManager.numInfluencers; index++) {
-                    var morphTarget = this.morphTargetManager.getActiveTarget(index);
+                for (var index = 0; index < morphTargetManager.numInfluencers; index++) {
+                    var morphTarget = morphTargetManager.getActiveTarget(index);
                     this.geometry.setVerticesData(VertexBuffer.PositionKind + index, morphTarget.getPositions(), false, 3);
                     this.geometry.setVerticesData(VertexBuffer.PositionKind + index, morphTarget.getPositions(), false, 3);
 
 
                     if (morphTarget.hasNormals) {
                     if (morphTarget.hasNormals) {
@@ -2404,7 +2471,7 @@
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateRibbon(name: string, pathArray: Vector3[][], closeArray: boolean, closePath: boolean, offset: number, scene?: Scene, updatable?: boolean, sideOrientation?: number, instance?: Mesh): Mesh {
+        public static CreateRibbon(name: string, pathArray: Vector3[][], closeArray: boolean = false, closePath: boolean, offset: number, scene?: Scene, updatable: boolean = false, sideOrientation?: number, instance?: Mesh): Mesh {
             return MeshBuilder.CreateRibbon(name, {
             return MeshBuilder.CreateRibbon(name, {
                 pathArray: pathArray,
                 pathArray: pathArray,
                 closeArray: closeArray,
                 closeArray: closeArray,
@@ -2424,7 +2491,7 @@
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateDisc(name: string, radius: number, tessellation: number, scene?: Scene, updatable?: boolean, sideOrientation?: number): Mesh {
+        public static CreateDisc(name: string, radius: number, tessellation: number, scene: Nullable<Scene> = null, updatable?: boolean, sideOrientation?: number): Mesh {
             var options = {
             var options = {
                 radius: radius,
                 radius: radius,
                 tessellation: tessellation,
                 tessellation: tessellation,
@@ -2442,7 +2509,7 @@
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateBox(name: string, size: number, scene?: Scene, updatable?: boolean, sideOrientation?: number): Mesh {
+        public static CreateBox(name: string, size: number, scene: Nullable<Scene> = null, updatable?: boolean, sideOrientation?: number): Mesh {
             var options = {
             var options = {
                 size: size,
                 size: size,
                 sideOrientation: sideOrientation,
                 sideOrientation: sideOrientation,
@@ -2588,7 +2655,7 @@
          * When updating an instance, remember that only point positions can change, not the number of points.      
          * When updating an instance, remember that only point positions can change, not the number of points.      
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateDashedLines(name: string, points: Vector3[], dashSize: number, gapSize: number, dashNb: number, scene?: Scene, updatable?: boolean, instance?: LinesMesh): LinesMesh {
+        public static CreateDashedLines(name: string, points: Vector3[], dashSize: number, gapSize: number, dashNb: number, scene: Nullable<Scene> = null, updatable?: boolean, instance?: LinesMesh): LinesMesh {
             var options = {
             var options = {
                 points: points,
                 points: points,
                 dashSize: dashSize,
                 dashSize: dashSize,
@@ -2652,7 +2719,7 @@
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static ExtrudeShape(name: string, shape: Vector3[], path: Vector3[], scale: number, rotation: number, cap: number, scene?: Scene, updatable?: boolean, sideOrientation?: number, instance?: Mesh): Mesh {
+        public static ExtrudeShape(name: string, shape: Vector3[], path: Vector3[], scale: number, rotation: number, cap: number, scene: Nullable<Scene> = null, updatable?: boolean, sideOrientation?: number, instance?: Mesh): Mesh {
             var options = {
             var options = {
                 shape: shape,
                 shape: shape,
                 path: path,
                 path: path,
@@ -2925,13 +2992,15 @@
          * @returns original positions used for CPU skinning.  Useful for integrating Morphing with skeletons in same mesh.
          * @returns original positions used for CPU skinning.  Useful for integrating Morphing with skeletons in same mesh.
          */
          */
         public setPositionsForCPUSkinning(): Float32Array {
         public setPositionsForCPUSkinning(): Float32Array {
-            var source: FloatArray;
             if (!this._sourcePositions) {
             if (!this._sourcePositions) {
-                source = this.getVerticesData(VertexBuffer.PositionKind);
+                let source = this.getVerticesData(VertexBuffer.PositionKind);
+                if (!source) {
+                    return this._sourcePositions;
+                }
 
 
                 this._sourcePositions = new Float32Array(<any>source);
                 this._sourcePositions = new Float32Array(<any>source);
 
 
-                if (!this.getVertexBuffer(VertexBuffer.PositionKind).isUpdatable()) {
+                if (!this.isVertexBufferUpdatable(VertexBuffer.PositionKind)) {
                     this.setVerticesData(VertexBuffer.PositionKind, source, true);
                     this.setVerticesData(VertexBuffer.PositionKind, source, true);
                 }
                 }
             }
             }
@@ -2942,13 +3011,16 @@
          * @returns original normals used for CPU skinning.  Useful for integrating Morphing with skeletons in same mesh.
          * @returns original normals used for CPU skinning.  Useful for integrating Morphing with skeletons in same mesh.
          */
          */
         public setNormalsForCPUSkinning(): Float32Array {
         public setNormalsForCPUSkinning(): Float32Array {
-            var source: FloatArray;
             if (!this._sourceNormals) {
             if (!this._sourceNormals) {
-                source = this.getVerticesData(VertexBuffer.NormalKind);
+                let source = this.getVerticesData(VertexBuffer.NormalKind);
+
+                if (!source) {
+                    return this._sourceNormals;
+                }
 
 
                 this._sourceNormals = new Float32Array(<any>source);
                 this._sourceNormals = new Float32Array(<any>source);
 
 
-                if (!this.getVertexBuffer(VertexBuffer.NormalKind).isUpdatable()) {
+                if (!this.isVertexBufferUpdatable(VertexBuffer.NormalKind)) {
                     this.setVerticesData(VertexBuffer.NormalKind, source, true);
                     this.setVerticesData(VertexBuffer.NormalKind, source, true);
                 }
                 }
             }
             }
@@ -2997,23 +3069,41 @@
 
 
             // positionsData checks for not being Float32Array will only pass at most once
             // positionsData checks for not being Float32Array will only pass at most once
             var positionsData = this.getVerticesData(VertexBuffer.PositionKind);
             var positionsData = this.getVerticesData(VertexBuffer.PositionKind);
+
+            if (!positionsData) {
+                return this;
+            }
+
             if (!(positionsData instanceof Float32Array)) {
             if (!(positionsData instanceof Float32Array)) {
                 positionsData = new Float32Array(positionsData);
                 positionsData = new Float32Array(positionsData);
             }
             }
 
 
             // normalsData checks for not being Float32Array will only pass at most once
             // normalsData checks for not being Float32Array will only pass at most once
             var normalsData = this.getVerticesData(VertexBuffer.NormalKind);
             var normalsData = this.getVerticesData(VertexBuffer.NormalKind);
+
+            if (!normalsData) {
+                return this;
+            }
+
             if (!(normalsData instanceof Float32Array)) {
             if (!(normalsData instanceof Float32Array)) {
                 normalsData = new Float32Array(normalsData);
                 normalsData = new Float32Array(normalsData);
             }
             }
 
 
             var matricesIndicesData = this.getVerticesData(VertexBuffer.MatricesIndicesKind);
             var matricesIndicesData = this.getVerticesData(VertexBuffer.MatricesIndicesKind);
             var matricesWeightsData = this.getVerticesData(VertexBuffer.MatricesWeightsKind);
             var matricesWeightsData = this.getVerticesData(VertexBuffer.MatricesWeightsKind);
+            
+            if (!matricesWeightsData || !matricesIndicesData) {
+                return this;
+            }
 
 
             var needExtras = this.numBoneInfluencers > 4;
             var needExtras = this.numBoneInfluencers > 4;
             var matricesIndicesExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;
             var matricesIndicesExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;
             var matricesWeightsExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;
             var matricesWeightsExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;
 
 
+            if (!matricesWeightsExtraData || !matricesIndicesExtraData) {
+                return this;
+            }            
+
             var skeletonMatrices = skeleton.getTransformMatrices(this);
             var skeletonMatrices = skeleton.getTransformMatrices(this);
 
 
             var tempVector3 = Vector3.Zero();
             var tempVector3 = Vector3.Zero();
@@ -3064,11 +3154,18 @@
          * This min and max Vector3 are the minimum and maximum vectors of each mesh bounding box from the passed array, in the World system
          * This min and max Vector3 are the minimum and maximum vectors of each mesh bounding box from the passed array, in the World system
          */
          */
         public static MinMax(meshes: AbstractMesh[]): { min: Vector3; max: Vector3 } {
         public static MinMax(meshes: AbstractMesh[]): { min: Vector3; max: Vector3 } {
-            var minVector: Vector3 = null;
-            var maxVector: Vector3 = null;
+            var minVector: Nullable<Vector3> = null;
+            var maxVector: Nullable<Vector3> = null;
+            
             meshes.forEach(function (mesh, index, array) {
             meshes.forEach(function (mesh, index, array) {
-                var boundingBox = mesh.getBoundingInfo().boundingBox;
-                if (!minVector) {
+                let boundingInfo = mesh.getBoundingInfo();
+
+                if (!boundingInfo) {
+                    return;
+                }
+
+                let boundingBox = boundingInfo.boundingBox;
+                if (!minVector || !maxVector) {
                     minVector = boundingBox.minimumWorld;
                     minVector = boundingBox.minimumWorld;
                     maxVector = boundingBox.maximumWorld;
                     maxVector = boundingBox.maximumWorld;
                 } else {
                 } else {
@@ -3077,6 +3174,13 @@
                 }
                 }
             });
             });
 
 
+            if (!minVector || !maxVector) {
+                return {
+                    min: Vector3.Zero(),
+                    max: Vector3.Zero()
+                }
+            }
+
             return {
             return {
                 min: minVector,
                 min: minVector,
                 max: maxVector
                 max: maxVector
@@ -3098,7 +3202,7 @@
          * @param {Mesh} meshSubclass - When set, vertices inserted into this Mesh.  Meshes can then be merged into a Mesh sub-class.
          * @param {Mesh} meshSubclass - When set, vertices inserted into this Mesh.  Meshes can then be merged into a Mesh sub-class.
          * @param {boolean} subdivideWithSubMeshes - When true (false default), subdivide mesh to his subMesh array with meshes source.
          * @param {boolean} subdivideWithSubMeshes - When true (false default), subdivide mesh to his subMesh array with meshes source.
          */
          */
-        public static MergeMeshes(meshes: Array<Mesh>, disposeSource = true, allow32BitsIndices?: boolean, meshSubclass?: Mesh, subdivideWithSubMeshes?: boolean): Mesh {
+        public static MergeMeshes(meshes: Array<Mesh>, disposeSource = true, allow32BitsIndices?: boolean, meshSubclass?: Mesh, subdivideWithSubMeshes?: boolean): Nullable<Mesh> {
             var index: number;
             var index: number;
             if (!allow32BitsIndices) {
             if (!allow32BitsIndices) {
                 var totalVertices = 0;
                 var totalVertices = 0;
@@ -3117,10 +3221,10 @@
             }
             }
 
 
             // Merge
             // Merge
-            var vertexData: VertexData;
+            var vertexData: Nullable<VertexData> = null;
             var otherVertexData: VertexData;
             var otherVertexData: VertexData;
             var indiceArray: Array<number> = new Array<number>();
             var indiceArray: Array<number> = new Array<number>();
-            var source: Mesh;
+            var source: Nullable<Mesh> = null;
             for (index = 0; index < meshes.length; index++) {
             for (index = 0; index < meshes.length; index++) {
                 if (meshes[index]) {
                 if (meshes[index]) {
                     meshes[index].computeWorldMatrix(true);
                     meshes[index].computeWorldMatrix(true);
@@ -3140,10 +3244,13 @@
                 }
                 }
             }
             }
 
 
+            source = <Mesh>source;
+
             if (!meshSubclass) {
             if (!meshSubclass) {
                 meshSubclass = new Mesh(source.name + "_merged", source.getScene());
                 meshSubclass = new Mesh(source.name + "_merged", source.getScene());
             }
             }
-            vertexData.applyToMesh(meshSubclass);
+
+            (<VertexData>vertexData).applyToMesh(meshSubclass);
 
 
             // Setting properties
             // Setting properties
             meshSubclass.material = source.material;
             meshSubclass.material = source.material;

+ 84 - 70
src/Mesh/babylon.mesh.vertexData.ts

@@ -1,6 +1,4 @@
 module BABYLON {
 module BABYLON {
-    export type IndicesArray = number[] | Int32Array | Uint32Array | Uint16Array;
-
     export interface IGetSetVerticesData
     export interface IGetSetVerticesData
     {
     {
         isVerticesDataPresent(kind: string): boolean;
         isVerticesDataPresent(kind: string): boolean;
@@ -12,21 +10,21 @@
     }
     }
 
 
     export class VertexData {
     export class VertexData {
-        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 positions: Nullable<FloatArray>;
+        public normals: Nullable<FloatArray>;
+        public tangents: Nullable<FloatArray>;
+        public uvs: Nullable<FloatArray>;
+        public uvs2: Nullable<FloatArray>;
+        public uvs3: Nullable<FloatArray>;
+        public uvs4: Nullable<FloatArray>;
+        public uvs5: Nullable<FloatArray>;
+        public uvs6: Nullable<FloatArray>;
+        public colors: Nullable<FloatArray>;
+        public matricesIndices: Nullable<FloatArray>;
+        public matricesWeights: Nullable<FloatArray>;
+        public matricesIndicesExtra: Nullable<FloatArray>;
+        public matricesWeightsExtra: Nullable<FloatArray>;
+        public indices: Nullable<IndicesArray>;
 
 
         public set(data: FloatArray, kind: string) {
         public set(data: FloatArray, kind: string) {
             switch (kind) {
             switch (kind) {
@@ -113,7 +111,7 @@
             return this;
             return this;
         }
         }
 
 
-        private _applyTo(meshOrGeometry: IGetSetVerticesData, updatable?: boolean): VertexData {
+        private _applyTo(meshOrGeometry: IGetSetVerticesData, updatable: boolean = false): VertexData {
             if (this.positions) {
             if (this.positions) {
                 meshOrGeometry.setVerticesData(VertexBuffer.PositionKind, this.positions, updatable);
                 meshOrGeometry.setVerticesData(VertexBuffer.PositionKind, this.positions, updatable);
             }
             }
@@ -311,6 +309,10 @@
 
 
             this.positions = this._mergeElement(this.positions, other.positions);
             this.positions = this._mergeElement(this.positions, other.positions);
 
 
+            if (!this.positions) {
+                return this;
+            }
+
             var count = this.positions.length / 3;
             var count = this.positions.length / 3;
 
 
             this.normals = this._mergeElement(this.normals, other.normals, count * 3);
             this.normals = this._mergeElement(this.normals, other.normals, count * 3);
@@ -329,13 +331,13 @@
             return this;
             return this;
         }
         }
 
 
-        private _mergeElement(source: FloatArray, other: FloatArray, length = 0): FloatArray {
+        private _mergeElement(source: Nullable<FloatArray>, other: Nullable<FloatArray>, length = 0): Nullable<FloatArray> {
             if (!other && !source) {
             if (!other && !source) {
                 return null;
                 return null;
             }
             }
 
 
             if (!other) {
             if (!other) {
-                return this._mergeElement(source, new Float32Array(source.length), length);
+                return this._mergeElement(source, new Float32Array((<FloatArray>source).length), length);
             }
             }
 
 
             if (!source) {
             if (!source) {
@@ -606,8 +608,8 @@
             // vertical distances (v)
             // vertical distances (v)
             var path1: Vector3[];
             var path1: Vector3[];
             var path2: Vector3[];
             var path2: Vector3[];
-            var vertex1: Vector3;
-            var vertex2: Vector3;
+            var vertex1: Nullable<Vector3> = null;
+            var vertex2: Nullable<Vector3> = null;
             for (i = 0; i < minlg + closePathCorr; i++) {
             for (i = 0; i < minlg + closePathCorr; i++) {
                 vTotalDistance[i] = 0;
                 vTotalDistance[i] = 0;
                 vs[i] = [0];
                 vs[i] = [0];
@@ -627,7 +629,8 @@
                     vs[i].push(dist);
                     vs[i].push(dist);
                     vTotalDistance[i] = dist;
                     vTotalDistance[i] = dist;
                 }
                 }
-                if (closeArray) {
+
+                if (closeArray && vertex2 && vertex1) {
                     path1 = pathArray[p];
                     path1 = pathArray[p];
                     path2 = pathArray[0];
                     path2 = pathArray[0];
                     if (i === minlg) {   // closePath
                     if (i === minlg) {   // closePath
@@ -721,8 +724,9 @@
             VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
             VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
 
 
             // Colors
             // Colors
+            let colors: Nullable<Float32Array> = null;
             if (customColors) {
             if (customColors) {
-                var colors = new Float32Array(customColors.length * 4);
+                colors = new Float32Array(customColors.length * 4);
                 for (var c = 0; c < customColors.length; c++) {
                 for (var c = 0; c < customColors.length; c++) {
                     colors[c * 4] = customColors[c].r;
                     colors[c * 4] = customColors[c].r;
                     colors[c * 4 + 1] = customColors[c].g;
                     colors[c * 4 + 1] = customColors[c].g;
@@ -741,7 +745,7 @@
             vertexData.positions = positions32;
             vertexData.positions = positions32;
             vertexData.normals = normals32;
             vertexData.normals = normals32;
             vertexData.uvs = uvs32;
             vertexData.uvs = uvs32;
-            if (customColors) {
+            if (colors) {
                 vertexData.set(colors, VertexBuffer.ColorKind);
                 vertexData.set(colors, VertexBuffer.ColorKind);
             }
             }
 
 
@@ -775,7 +779,7 @@
             var depth = options.depth || options.size || 1;
             var depth = options.depth || options.size || 1;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
             var faceUV: Vector4[] = options.faceUV || new Array<Vector4>(6);
             var faceUV: Vector4[] = options.faceUV || new Array<Vector4>(6);
-            var faceColors: Color4[] = options.faceColors;
+            var faceColors = options.faceColors;
             var colors = [];
             var colors = [];
 
 
             // default face colors and UV if undefined
             // default face colors and UV if undefined
@@ -869,8 +873,8 @@
             var diameterX: number = options.diameterX || options.diameter || 1;
             var diameterX: number = options.diameterX || options.diameter || 1;
             var diameterY: number = options.diameterY || options.diameter || 1;
             var diameterY: number = options.diameterY || options.diameter || 1;
             var diameterZ: number = options.diameterZ || options.diameter || 1;
             var diameterZ: number = options.diameterZ || options.diameter || 1;
-            var arc: number = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
-            var slice: number = (options.slice <= 0) ? 1.0 : options.slice || 1.0;
+            var arc: number = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
+            var slice: number = options.slice && (options.slice <= 0) ? 1.0 : options.slice || 1.0;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
 
 
             var radius = new Vector3(diameterX / 2, diameterY / 2, diameterZ / 2);
             var radius = new Vector3(diameterX / 2, diameterY / 2, diameterZ / 2);
@@ -942,12 +946,12 @@
             var diameterBottom: number = (options.diameterBottom === 0) ? 0 : options.diameterBottom || options.diameter || 1;
             var diameterBottom: number = (options.diameterBottom === 0) ? 0 : options.diameterBottom || options.diameter || 1;
             var tessellation: number = options.tessellation || 24;
             var tessellation: number = options.tessellation || 24;
             var subdivisions: number = options.subdivisions || 1;
             var subdivisions: number = options.subdivisions || 1;
-            var hasRings: boolean = options.hasRings;
-            var enclose: boolean = options.enclose;
-            var arc: number = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
+            var hasRings: boolean = options.hasRings ? true : false;
+            var enclose: boolean = options.enclose ? true : false
+            var arc: number = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
             var sideOrientation: number = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
             var sideOrientation: number = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
             var faceUV: Vector4[] = options.faceUV || new Array<Vector4>(3);
             var faceUV: Vector4[] = options.faceUV || new Array<Vector4>(3);
-            var faceColors: Color4[] = options.faceColors;
+            var faceColors = options.faceColors;
             // default face colors and UV if undefined
             // default face colors and UV if undefined
             var quadNb: number = (arc !== 1 && enclose) ? 2 : 0;
             var quadNb: number = (arc !== 1 && enclose) ? 2 : 0;
             var ringNb: number = (hasRings) ? subdivisions : 1;
             var ringNb: number = (hasRings) ? subdivisions : 1;
@@ -1090,11 +1094,15 @@
             var s: number;
             var s: number;
             i = 0;
             i = 0;
             for (s = 0; s < subdivisions; s++) {
             for (s = 0; s < subdivisions; s++) {
+                let i0: number = 0;
+                let i1: number = 0;
+                let i2: number = 0;
+                let i3: number = 0;
                 for (j = 0; j < tessellation; j++) {
                 for (j = 0; j < tessellation; j++) {
-                    var i0 = i * (e + 1) + j;
-                    var i1 = (i + 1) * (e + 1) + j;
-                    var i2 = i * (e + 1) + (j + 1);
-                    var i3 = (i + 1) * (e + 1) + (j + 1);
+                    i0 = i * (e + 1) + j;
+                    i1 = (i + 1) * (e + 1) + j;
+                    i2 = i * (e + 1) + (j + 1);
+                    i3 = (i + 1) * (e + 1) + (j + 1);
                     indices.push(i0, i1, i2);
                     indices.push(i0, i1, i2);
                     indices.push(i3, i2, i1);
                     indices.push(i3, i2, i1);
                 }
                 }
@@ -1119,7 +1127,7 @@
                 var circleVector;
                 var circleVector;
                 var i: number;
                 var i: number;
                 var u: Vector4 = (isTop) ? faceUV[surfaceNb - 1] : faceUV[0];
                 var u: Vector4 = (isTop) ? faceUV[surfaceNb - 1] : faceUV[0];
-                var c: Color4;
+                var c: Nullable<Color4> = null;
                 if (faceColors) {
                 if (faceColors) {
                     c = (isTop) ? faceColors[surfaceNb - 1] : faceColors[0];
                     c = (isTop) ? faceColors[surfaceNb - 1] : faceColors[0];
                 }
                 }
@@ -1130,7 +1138,7 @@
                 positions.push(center.x, center.y, center.z);
                 positions.push(center.x, center.y, center.z);
                 normals.push(0, isTop ? 1 : -1, 0);
                 normals.push(0, isTop ? 1 : -1, 0);
                 uvs.push(u.x + (u.z - u.x) * 0.5, u.y + (u.w - u.y) * 0.5);
                 uvs.push(u.x + (u.z - u.x) * 0.5, u.y + (u.w - u.y) * 0.5);
-                if (faceColors) {
+                if (c) {
                     colors.push(c.r, c.g, c.b, c.a);
                     colors.push(c.r, c.g, c.b, c.a);
                 }
                 }
 
 
@@ -1144,7 +1152,7 @@
                     positions.push(circleVector.x, circleVector.y, circleVector.z);
                     positions.push(circleVector.x, circleVector.y, circleVector.z);
                     normals.push(0, isTop ? 1 : -1, 0);
                     normals.push(0, isTop ? 1 : -1, 0);
                     uvs.push(u.x + (u.z - u.x) * textureCoordinate.x, u.y + (u.w - u.y) * textureCoordinate.y);
                     uvs.push(u.x + (u.z - u.x) * textureCoordinate.x, u.y + (u.w - u.y) * textureCoordinate.y);
-                    if (faceColors) {
+                    if (c) {
                         colors.push(c.r, c.g, c.b, c.a);
                         colors.push(c.r, c.g, c.b, c.a);
                     }
                     }
                 }
                 }
@@ -1594,7 +1602,7 @@
 
 
             var radius = options.radius || 0.5;
             var radius = options.radius || 0.5;
             var tessellation = options.tessellation || 64;
             var tessellation = options.tessellation || 64;
-            var arc: number = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
+            var arc: number = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
 
 
             // positions and uvs
             // positions and uvs
@@ -1641,7 +1649,7 @@
          */
          */
         public static CreatePolygon(polygon: Mesh, sideOrientation: number, fUV?:Vector4[], fColors?: Color4[], frontUVs?: Vector4, backUVs?: Vector4) {
         public static CreatePolygon(polygon: Mesh, sideOrientation: number, fUV?:Vector4[], fColors?: Color4[], frontUVs?: Vector4, backUVs?: Vector4) {
 			var faceUV: Vector4[] = fUV || new Array<Vector4>(3);
 			var faceUV: Vector4[] = fUV || new Array<Vector4>(3);
-            var faceColors: Color4[] = fColors;
+            var faceColors = fColors;
             var colors = [];
             var colors = [];
 
 
             // default face colors and UV if undefined
             // default face colors and UV if undefined
@@ -1654,11 +1662,11 @@
                 }
                 }
             }
             }
             
             
-            var positions = polygon.getVerticesData(VertexBuffer.PositionKind);
-			var normals = polygon.getVerticesData(VertexBuffer.NormalKind);
-			var uvs = polygon.getVerticesData(VertexBuffer.UVKind);
-			var indices = polygon.getIndices();
-
+            var positions = <FloatArray>polygon.getVerticesData(VertexBuffer.PositionKind);
+			var normals = <FloatArray>polygon.getVerticesData(VertexBuffer.NormalKind);
+			var uvs = <FloatArray>polygon.getVerticesData(VertexBuffer.UVKind);
+            var indices = <IndicesArray>polygon.getIndices();
+            
             // set face colours and textures
             // set face colours and textures
             var idx: number = 0;
             var idx: number = 0;
             var face: number = 0;
             var face: number = 0;
@@ -2002,8 +2010,8 @@
                 face: [[15, 18, 21], [12, 20, 16], [6, 10, 2], [3, 0, 1], [9, 7, 13], [2, 8, 4, 0], [0, 4, 5, 1], [1, 5, 11, 7], [7, 11, 17, 13], [13, 17, 22, 18], [18, 22, 24, 21], [21, 24, 23, 20], [20, 23, 19, 16], [16, 19, 14, 10], [10, 14, 8, 2], [15, 9, 13, 18], [12, 15, 21, 20], [6, 12, 16, 10], [3, 6, 2, 0], [9, 3, 1, 7], [9, 15, 12, 6, 3], [22, 17, 11, 5, 4, 8, 14, 19, 23, 24]]
                 face: [[15, 18, 21], [12, 20, 16], [6, 10, 2], [3, 0, 1], [9, 7, 13], [2, 8, 4, 0], [0, 4, 5, 1], [1, 5, 11, 7], [7, 11, 17, 13], [13, 17, 22, 18], [18, 22, 24, 21], [21, 24, 23, 20], [20, 23, 19, 16], [16, 19, 14, 10], [10, 14, 8, 2], [15, 9, 13, 18], [12, 15, 21, 20], [6, 12, 16, 10], [3, 6, 2, 0], [9, 3, 1, 7], [9, 15, 12, 6, 3], [22, 17, 11, 5, 4, 8, 14, 19, 23, 24]]
             };
             };
 
 
-            var type: number = (options.type < 0 || options.type >= polyhedra.length) ? 0 : options.type || 0;
-            var size: number = options.size;
+            var type: number = options.type && (options.type < 0 || options.type >= polyhedra.length) ? 0 : options.type || 0;
+            var size = options.size;
             var sizeX: number = options.sizeX || size || 1;
             var sizeX: number = options.sizeX || size || 1;
             var sizeY: number = options.sizeY || size || 1;
             var sizeY: number = options.sizeY || size || 1;
             var sizeZ: number = options.sizeZ || size || 1;
             var sizeZ: number = options.sizeZ || size || 1;
@@ -2237,15 +2245,21 @@
             var computeFacetPositions = false;
             var computeFacetPositions = false;
             var computeFacetPartitioning = false;
             var computeFacetPartitioning = false;
             var faceNormalSign = 1;
             var faceNormalSign = 1;
+            let ratio = 0;
             if (options) {
             if (options) {
                 computeFacetNormals = (options.facetNormals) ? true : false;
                 computeFacetNormals = (options.facetNormals) ? true : false;
                 computeFacetPositions = (options.facetPositions) ? true : false;
                 computeFacetPositions = (options.facetPositions) ? true : false;
                 computeFacetPartitioning = (options.facetPartitioning) ? true : false;
                 computeFacetPartitioning = (options.facetPartitioning) ? true : false;
                 faceNormalSign = (options.useRightHandedSystem === true) ? -1 : 1;
                 faceNormalSign = (options.useRightHandedSystem === true) ? -1 : 1;
+                ratio = options.ratio || 0;
             }
             }
 
 
             // facetPartitioning reinit if needed
             // facetPartitioning reinit if needed
-            if (computeFacetPartitioning) {
+            let xSubRatio = 0;
+            let ySubRatio = 0;
+            let zSubRatio = 0;
+            let subSq = 0;
+            if (computeFacetPartitioning && options && options.bbSize) {
                 var ox = 0;                 // X partitioning index for facet position
                 var ox = 0;                 // X partitioning index for facet position
                 var oy = 0;                 // Y partinioning index for facet position
                 var oy = 0;                 // Y partinioning index for facet position
                 var oz = 0;                 // Z partinioning index for facet position
                 var oz = 0;                 // Z partinioning index for facet position
@@ -2265,10 +2279,10 @@
 
 
                 var bbSizeMax = (options.bbSize.x > options.bbSize.y) ? options.bbSize.x : options.bbSize.y;
                 var bbSizeMax = (options.bbSize.x > options.bbSize.y) ? options.bbSize.x : options.bbSize.y;
                 bbSizeMax = (bbSizeMax > options.bbSize.z) ? bbSizeMax : options.bbSize.z;
                 bbSizeMax = (bbSizeMax > options.bbSize.z) ? bbSizeMax : options.bbSize.z;
-                var xSubRatio = options.subDiv.X * options.ratio / options.bbSize.x;
-                var ySubRatio = options.subDiv.Y * options.ratio / options.bbSize.y;
-                var zSubRatio = options.subDiv.Z * options.ratio / options.bbSize.z;
-                var subSq = options.subDiv.max * options.subDiv.max;
+                xSubRatio = options.subDiv.X * ratio / options.bbSize.x;
+                ySubRatio = options.subDiv.Y * ratio / options.bbSize.y;
+                zSubRatio = options.subDiv.Z * ratio / options.bbSize.z;
+                subSq = options.subDiv.max * options.subDiv.max;
                 options.facetPartitioning.length = 0;
                 options.facetPartitioning.length = 0;
             }
             }
 
 
@@ -2311,34 +2325,34 @@
                 faceNormaly /= length;
                 faceNormaly /= length;
                 faceNormalz /= length;
                 faceNormalz /= length;
 
 
-                if (computeFacetNormals) {
+                if (computeFacetNormals && options) {
                     options.facetNormals[index].x = faceNormalx;
                     options.facetNormals[index].x = faceNormalx;
                     options.facetNormals[index].y = faceNormaly;
                     options.facetNormals[index].y = faceNormaly;
                     options.facetNormals[index].z = faceNormalz;
                     options.facetNormals[index].z = faceNormalz;
                 }
                 }
 
 
-                if (computeFacetPositions) {
+                if (computeFacetPositions && options) {
                     // compute and the facet barycenter coordinates in the array facetPositions 
                     // compute and the facet barycenter coordinates in the array facetPositions 
                     options.facetPositions[index].x = (positions[v1x] + positions[v2x] + positions[v3x]) / 3.0;
                     options.facetPositions[index].x = (positions[v1x] + positions[v2x] + positions[v3x]) / 3.0;
                     options.facetPositions[index].y = (positions[v1y] + positions[v2y] + positions[v3y]) / 3.0;
                     options.facetPositions[index].y = (positions[v1y] + positions[v2y] + positions[v3y]) / 3.0;
                     options.facetPositions[index].z = (positions[v1z] + positions[v2z] + positions[v3z]) / 3.0;
                     options.facetPositions[index].z = (positions[v1z] + positions[v2z] + positions[v3z]) / 3.0;
                 }
                 }
 
 
-                if (computeFacetPartitioning) {
+                if (computeFacetPartitioning && options) {
                     // store the facet indexes in arrays in the main facetPartitioning array :
                     // store the facet indexes in arrays in the main facetPartitioning array :
                     // compute each facet vertex (+ facet barycenter) index in the partiniong array
                     // compute each facet vertex (+ facet barycenter) index in the partiniong array
-                    ox = Math.floor((options.facetPositions[index].x - options.bInfo.minimum.x * options.ratio) * xSubRatio);
-                    oy = Math.floor((options.facetPositions[index].y - options.bInfo.minimum.y * options.ratio) * ySubRatio);
-                    oz = Math.floor((options.facetPositions[index].z - options.bInfo.minimum.z * options.ratio) * zSubRatio);
-                    b1x = Math.floor((positions[v1x] - options.bInfo.minimum.x * options.ratio) * xSubRatio);
-                    b1y = Math.floor((positions[v1y] - options.bInfo.minimum.y * options.ratio) * ySubRatio);
-                    b1z = Math.floor((positions[v1z] - options.bInfo.minimum.z * options.ratio) * zSubRatio);
-                    b2x = Math.floor((positions[v2x] - options.bInfo.minimum.x * options.ratio) * xSubRatio);
-                    b2y = Math.floor((positions[v2y] - options.bInfo.minimum.y * options.ratio) * ySubRatio);
-                    b2z = Math.floor((positions[v2z] - options.bInfo.minimum.z * options.ratio) * zSubRatio);
-                    b3x = Math.floor((positions[v3x] - options.bInfo.minimum.x * options.ratio) * xSubRatio);
-                    b3y = Math.floor((positions[v3y] - options.bInfo.minimum.y * options.ratio) * ySubRatio);
-                    b3z = Math.floor((positions[v3z] - options.bInfo.minimum.z * options.ratio) * zSubRatio);
+                    ox = Math.floor((options.facetPositions[index].x - options.bInfo.minimum.x * ratio) * xSubRatio);
+                    oy = Math.floor((options.facetPositions[index].y - options.bInfo.minimum.y * ratio) * ySubRatio);
+                    oz = Math.floor((options.facetPositions[index].z - options.bInfo.minimum.z * ratio) * zSubRatio);
+                    b1x = Math.floor((positions[v1x] - options.bInfo.minimum.x * ratio) * xSubRatio);
+                    b1y = Math.floor((positions[v1y] - options.bInfo.minimum.y * ratio) * ySubRatio);
+                    b1z = Math.floor((positions[v1z] - options.bInfo.minimum.z * ratio) * zSubRatio);
+                    b2x = Math.floor((positions[v2x] - options.bInfo.minimum.x * ratio) * xSubRatio);
+                    b2y = Math.floor((positions[v2y] - options.bInfo.minimum.y * ratio) * ySubRatio);
+                    b2z = Math.floor((positions[v2z] - options.bInfo.minimum.z * ratio) * zSubRatio);
+                    b3x = Math.floor((positions[v3x] - options.bInfo.minimum.x * ratio) * xSubRatio);
+                    b3y = Math.floor((positions[v3y] - options.bInfo.minimum.y * ratio) * ySubRatio);
+                    b3z = Math.floor((positions[v3z] - options.bInfo.minimum.z * ratio) * zSubRatio);
 
 
                     block_idx_v1 = b1x + options.subDiv.max * b1y + subSq * b1z;
                     block_idx_v1 = b1x + options.subDiv.max * b1y + subSq * b1z;
                     block_idx_v2 = b2x + options.subDiv.max * b2y + subSq * b2z;
                     block_idx_v2 = b2x + options.subDiv.max * b2y + subSq * b2z;
@@ -2443,8 +2457,8 @@
                     for (u = 0; u < lu; u++) {
                     for (u = 0; u < lu; u++) {
                         uvs[u + lu] = uvs[u];                       
                         uvs[u + lu] = uvs[u];                       
                     }
                     }
-                    var frontUVs = frontUVs ? frontUVs : new Vector4(0.0, 0.0, 1.0, 1.0);
-                    var backUVs = backUVs ? backUVs : new Vector4(0.0, 0.0, 1.0, 1.0); 
+                    frontUVs = frontUVs ? frontUVs : new Vector4(0.0, 0.0, 1.0, 1.0);
+                    backUVs = backUVs ? backUVs : new Vector4(0.0, 0.0, 1.0, 1.0); 
                     u = 0;
                     u = 0;
                     for (i = 0; i < lu / 2; i++) {    
                     for (i = 0; i < lu / 2; i++) {    
                         uvs[u] = frontUVs.x + (frontUVs.z - frontUVs.x) * uvs[u];
                         uvs[u] = frontUVs.x + (frontUVs.z - frontUVs.x) * uvs[u];

+ 116 - 100
src/Mesh/babylon.meshBuilder.ts

@@ -1,6 +1,6 @@
 module BABYLON {
 module BABYLON {
     export class MeshBuilder {
     export class MeshBuilder {
-        private static updateSideOrientation(orientation: number, scene: Scene): number {
+        private static updateSideOrientation(orientation?: number): number {
             if (orientation == Mesh.DOUBLESIDE) {
             if (orientation == Mesh.DOUBLESIDE) {
                 return Mesh.DOUBLESIDE;
                 return Mesh.DOUBLESIDE;
             }
             }
@@ -24,12 +24,12 @@
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateBox(name: string, options: { size?: number, width?: number, height?: number, depth?: number, faceUV?: Vector4[], faceColors?: Color4[], sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, updatable?: boolean }, scene: Scene): Mesh {
+        public static CreateBox(name: string, options: { size?: number, width?: number, height?: number, depth?: number, faceUV?: Vector4[], faceColors?: Color4[], sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, updatable?: boolean }, scene: Nullable<Scene> = null): Mesh {
             var box = new Mesh(name, scene);
             var box = new Mesh(name, scene);
 
 
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             box._originalBuilderSideOrientation = options.sideOrientation;
             box._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreateBox(options);
             var vertexData = VertexData.CreateBox(options);
 
 
             vertexData.applyToMesh(box, options.updatable);
             vertexData.applyToMesh(box, options.updatable);
@@ -53,9 +53,9 @@
         public static CreateSphere(name: string, options: { segments?: number, diameter?: number, diameterX?: number, diameterY?: number, diameterZ?: number, arc?: number, slice?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, updatable?: boolean }, scene: any): Mesh {
         public static CreateSphere(name: string, options: { segments?: number, diameter?: number, diameterX?: number, diameterY?: number, diameterZ?: number, arc?: number, slice?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, updatable?: boolean }, scene: any): Mesh {
             var sphere = new Mesh(name, scene);
             var sphere = new Mesh(name, scene);
 
 
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             sphere._originalBuilderSideOrientation = options.sideOrientation;
             sphere._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreateSphere(options);
             var vertexData = VertexData.CreateSphere(options);
 
 
             vertexData.applyToMesh(sphere, options.updatable);
             vertexData.applyToMesh(sphere, options.updatable);
@@ -74,12 +74,12 @@
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation    
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateDisc(name: string, options: { radius?: number, tessellation?: number, arc?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: Scene): Mesh {
+        public static CreateDisc(name: string, options: { radius?: number, tessellation?: number, arc?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: Nullable<Scene> = null): Mesh {
             var disc = new Mesh(name, scene);
             var disc = new Mesh(name, scene);
 
 
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             disc._originalBuilderSideOrientation = options.sideOrientation;
             disc._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreateDisc(options);
             var vertexData = VertexData.CreateDisc(options);
 
 
             vertexData.applyToMesh(disc, options.updatable);
             vertexData.applyToMesh(disc, options.updatable);
@@ -102,9 +102,9 @@
         public static CreateIcoSphere(name: string, options: { radius?: number, radiusX?: number, radiusY?: number, radiusZ?: number, flat?: boolean, subdivisions?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, updatable?: boolean }, scene: Scene): Mesh {
         public static CreateIcoSphere(name: string, options: { radius?: number, radiusX?: number, radiusY?: number, radiusZ?: number, flat?: boolean, subdivisions?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, updatable?: boolean }, scene: Scene): Mesh {
             var sphere = new Mesh(name, scene);
             var sphere = new Mesh(name, scene);
 
 
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             sphere._originalBuilderSideOrientation = options.sideOrientation;
             sphere._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreateIcoSphere(options);
             var vertexData = VertexData.CreateIcoSphere(options);
 
 
             vertexData.applyToMesh(sphere, options.updatable);
             vertexData.applyToMesh(sphere, options.updatable);
@@ -134,11 +134,11 @@
          * Moreover, you can use the parameter `color` with `instance` (to update the ribbon), only if you previously used it at creation time.  
          * Moreover, you can use the parameter `color` with `instance` (to update the ribbon), only if you previously used it at creation time.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateRibbon(name: string, options: { pathArray: Vector3[][], closeArray?: boolean, closePath?: boolean, offset?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, instance?: Mesh, invertUV?: boolean, uvs?: Vector2[], colors?: Color4[] }, scene?: Scene): Mesh {
+        public static CreateRibbon(name: string, options: { pathArray: Vector3[][], closeArray?: boolean, closePath?: boolean, offset?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, instance?: Mesh, invertUV?: boolean, uvs?: Vector2[], colors?: Color4[] }, scene: Nullable<Scene> = null): Mesh {
             var pathArray = options.pathArray;
             var pathArray = options.pathArray;
             var closeArray = options.closeArray;
             var closeArray = options.closeArray;
             var closePath = options.closePath;
             var closePath = options.closePath;
-            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             var instance = options.instance;
             var instance = options.instance;
             var updatable = options.updatable;
             var updatable = options.updatable;
 
 
@@ -150,7 +150,7 @@
                 var positionFunction = (positions: FloatArray) => {
                 var positionFunction = (positions: FloatArray) => {
                     var minlg = pathArray[0].length;
                     var minlg = pathArray[0].length;
                     var i = 0;
                     var i = 0;
-                    var ns = (instance._originalBuilderSideOrientation === Mesh.DOUBLESIDE) ? 2 : 1;
+                    var ns = ((<Mesh>instance)._originalBuilderSideOrientation === Mesh.DOUBLESIDE) ? 2 : 1;
                     for (var si = 1; si <= ns; si++) {
                     for (var si = 1; si <= ns; si++) {
                         for (var p = 0; p < pathArray.length; p++) {
                         for (var p = 0; p < pathArray.length; p++) {
                             var path = pathArray[p];
                             var path = pathArray[p];
@@ -191,13 +191,13 @@
                         }
                         }
                     }
                     }
                 };
                 };
-                var positions = instance.getVerticesData(VertexBuffer.PositionKind);
+                var positions = <FloatArray>instance.getVerticesData(VertexBuffer.PositionKind);
                 positionFunction(positions);
                 positionFunction(positions);
                 instance._boundingInfo = new BoundingInfo(Tmp.Vector3[0], Tmp.Vector3[1]);
                 instance._boundingInfo = new BoundingInfo(Tmp.Vector3[0], Tmp.Vector3[1]);
                 instance._boundingInfo.update(instance._worldMatrix);
                 instance._boundingInfo.update(instance._worldMatrix);
                 instance.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);
                 instance.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);
                 if (options.colors) {
                 if (options.colors) {
-                    var colors = instance.getVerticesData(VertexBuffer.ColorKind);
+                    var colors = <FloatArray>instance.getVerticesData(VertexBuffer.ColorKind);
                     for (var c = 0; c < options.colors.length; c++) {
                     for (var c = 0; c < options.colors.length; c++) {
                         colors[c * 4] = options.colors[c].r;
                         colors[c * 4] = options.colors[c].r;
                         colors[c * 4 + 1] = options.colors[c].g;
                         colors[c * 4 + 1] = options.colors[c].g;
@@ -207,7 +207,7 @@
                     instance.updateVerticesData(VertexBuffer.ColorKind, colors, false, false);
                     instance.updateVerticesData(VertexBuffer.ColorKind, colors, false, false);
                 }
                 }
                 if (options.uvs) {
                 if (options.uvs) {
-                    var uvs = instance.getVerticesData(VertexBuffer.UVKind);
+                    var uvs = <FloatArray>instance.getVerticesData(VertexBuffer.UVKind);
                     for (var i = 0; i < options.uvs.length; i++) {
                     for (var i = 0; i < options.uvs.length; i++) {
                         uvs[i * 2] = options.uvs[i].x;
                         uvs[i * 2] = options.uvs[i].x;
                         uvs[i * 2 + 1] = options.uvs[i].y;
                         uvs[i * 2 + 1] = options.uvs[i].y;
@@ -216,7 +216,7 @@
                 }
                 }
                 if (!instance.areNormalsFrozen || instance.isFacetDataEnabled) {
                 if (!instance.areNormalsFrozen || instance.isFacetDataEnabled) {
                     var indices = instance.getIndices();
                     var indices = instance.getIndices();
-                    var normals = instance.getVerticesData(VertexBuffer.NormalKind);
+                    var normals = <FloatArray>instance.getVerticesData(VertexBuffer.NormalKind);
                     var params = instance.isFacetDataEnabled ? instance.getFacetDataParameters() : null;
                     var params = instance.isFacetDataEnabled ? instance.getFacetDataParameters() : null;
                     VertexData.ComputeNormals(positions, indices, normals, params);
                     VertexData.ComputeNormals(positions, indices, normals, params);
 
 
@@ -290,10 +290,10 @@
          */
          */
         public static CreateCylinder(name: string, options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], updatable?: boolean, hasRings?: boolean, enclose?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: any): Mesh {
         public static CreateCylinder(name: string, options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], updatable?: boolean, hasRings?: boolean, enclose?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: any): Mesh {
             var cylinder = new Mesh(name, scene);
             var cylinder = new Mesh(name, scene);
-            
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             cylinder._originalBuilderSideOrientation = options.sideOrientation;
             cylinder._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreateCylinder(options);
             var vertexData = VertexData.CreateCylinder(options);
 
 
             vertexData.applyToMesh(cylinder, options.updatable);
             vertexData.applyToMesh(cylinder, options.updatable);
@@ -315,9 +315,9 @@
         public static CreateTorus(name: string, options: { diameter?: number, thickness?: number, tessellation?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: any): Mesh {
         public static CreateTorus(name: string, options: { diameter?: number, thickness?: number, tessellation?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: any): Mesh {
             var torus = new Mesh(name, scene);
             var torus = new Mesh(name, scene);
 
 
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             torus._originalBuilderSideOrientation = options.sideOrientation;
             torus._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreateTorus(options);
             var vertexData = VertexData.CreateTorus(options);
 
 
             vertexData.applyToMesh(torus, options.updatable);
             vertexData.applyToMesh(torus, options.updatable);
@@ -340,9 +340,9 @@
         public static CreateTorusKnot(name: string, options: { radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, p?: number, q?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: any): Mesh {
         public static CreateTorusKnot(name: string, options: { radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, p?: number, q?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: any): Mesh {
             var torusKnot = new Mesh(name, scene);
             var torusKnot = new Mesh(name, scene);
 
 
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             torusKnot._originalBuilderSideOrientation = options.sideOrientation;
             torusKnot._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreateTorusKnot(options);
             var vertexData = VertexData.CreateTorusKnot(options);
 
 
             vertexData.applyToMesh(torusKnot, options.updatable);
             vertexData.applyToMesh(torusKnot, options.updatable);
@@ -362,7 +362,7 @@
          * When updating an instance, remember that only line point positions can change, not the number of points, neither the number of lines.      
          * When updating an instance, remember that only line point positions can change, not the number of points, neither the number of lines.      
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateLineSystem(name: string, options: { lines: Vector3[][], updatable: boolean, instance?: LinesMesh }, scene: Nullable<Scene>): LinesMesh {
+        public static CreateLineSystem(name: string, options: { lines: Vector3[][], updatable: boolean, instance: Nullable<LinesMesh> }, scene: Nullable<Scene>): LinesMesh {
             var instance = options.instance;
             var instance = options.instance;
             var lines = options.lines;
             var lines = options.lines;
 
 
@@ -382,7 +382,7 @@
                 instance.updateMeshPositions(positionFunction, false);
                 instance.updateMeshPositions(positionFunction, false);
                 return instance;
                 return instance;
             }
             }
-            
+
             // line system creation
             // line system creation
             var lineSystem = new LinesMesh(name, scene);
             var lineSystem = new LinesMesh(name, scene);
             var vertexData = VertexData.CreateLineSystem(options);
             var vertexData = VertexData.CreateLineSystem(options);
@@ -418,7 +418,7 @@
          * When updating an instance, remember that only point positions can change, not the number of points.      
          * When updating an instance, remember that only point positions can change, not the number of points.      
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static CreateDashedLines(name: string, options: { points: Vector3[], dashSize?: number, gapSize?: number, dashNb?: number, updatable?: boolean, instance?: LinesMesh }, scene: Scene): LinesMesh {
+        public static CreateDashedLines(name: string, options: { points: Vector3[], dashSize?: number, gapSize?: number, dashNb?: number, updatable?: boolean, instance?: LinesMesh }, scene: Nullable<Scene> = null): LinesMesh {
             var points = options.points;
             var points = options.points;
             var instance = options.instance;
             var instance = options.instance;
             var gapSize = options.gapSize || 1;
             var gapSize = options.gapSize || 1;
@@ -498,18 +498,18 @@
          * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture.  
          * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.  
          */
          */
-        public static ExtrudeShape(name: string, options: { shape: Vector3[], path: Vector3[], scale?: number, rotation?: number, cap?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, instance?: Mesh, invertUV?: boolean }, scene: Scene): Mesh {
+        public static ExtrudeShape(name: string, options: { shape: Vector3[], path: Vector3[], scale?: number, rotation?: number, cap?: number, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, instance?: Mesh, invertUV?: boolean }, scene: Nullable<Scene> = null): Mesh {
             var path = options.path;
             var path = options.path;
             var shape = options.shape;
             var shape = options.shape;
             var scale = options.scale || 1;
             var scale = options.scale || 1;
             var rotation = options.rotation || 0;
             var rotation = options.rotation || 0;
             var cap = (options.cap === 0) ? 0 : options.cap || Mesh.NO_CAP;
             var cap = (options.cap === 0) ? 0 : options.cap || Mesh.NO_CAP;
             var updatable = options.updatable;
             var updatable = options.updatable;
-            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            var instance = options.instance;
+            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
+            var instance = options.instance || null;
             var invertUV = options.invertUV || false;
             var invertUV = options.invertUV || false;
 
 
-            return MeshBuilder._ExtrudeShapeGeneric(name, shape, path, scale, rotation, null, null, false, false, cap, false, scene, updatable, sideOrientation, instance, invertUV, options.frontUVs, options.backUVs);
+            return MeshBuilder._ExtrudeShapeGeneric(name, shape, path, scale, rotation, null, null, false, false, cap, false, scene, updatable ? true : false, sideOrientation, instance, invertUV, options.frontUVs || null, options.backUVs || null);
         }
         }
 
 
         /**
         /**
@@ -557,10 +557,10 @@
             var ribbonClosePath = options.ribbonClosePath || false;
             var ribbonClosePath = options.ribbonClosePath || false;
             var cap = (options.cap === 0) ? 0 : options.cap || Mesh.NO_CAP;
             var cap = (options.cap === 0) ? 0 : options.cap || Mesh.NO_CAP;
             var updatable = options.updatable;
             var updatable = options.updatable;
-            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             var instance = options.instance;
             var instance = options.instance;
             var invertUV = options.invertUV || false;
             var invertUV = options.invertUV || false;
-            return MeshBuilder._ExtrudeShapeGeneric(name, shape, path, null, null, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, cap, true, scene, updatable, sideOrientation, instance, invertUV, options.frontUVs, options.backUVs);
+            return MeshBuilder._ExtrudeShapeGeneric(name, shape, path, null, null, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, cap, true, scene, updatable ? true : false, sideOrientation, instance || null, invertUV, options.frontUVs || null, options.backUVs || null);
         }
         }
 
 
         /**
         /**
@@ -588,7 +588,7 @@
             var radius = options.radius || 1;
             var radius = options.radius || 1;
             var tessellation = options.tessellation || 64;
             var tessellation = options.tessellation || 64;
             var updatable = options.updatable;
             var updatable = options.updatable;
-            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             var cap = options.cap || Mesh.NO_CAP;
             var cap = options.cap || Mesh.NO_CAP;
             var pi2 = Math.PI * 2;
             var pi2 = Math.PI * 2;
             var paths = new Array();
             var paths = new Array();
@@ -635,9 +635,9 @@
         public static CreatePlane(name: string, options: { size?: number, width?: number, height?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, updatable?: boolean, sourcePlane?: Plane }, scene: Scene): Mesh {
         public static CreatePlane(name: string, options: { size?: number, width?: number, height?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, updatable?: boolean, sourcePlane?: Plane }, scene: Scene): Mesh {
             var plane = new Mesh(name, scene);
             var plane = new Mesh(name, scene);
 
 
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             plane._originalBuilderSideOrientation = options.sideOrientation;
             plane._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreatePlane(options);
             var vertexData = VertexData.CreatePlane(options);
 
 
             vertexData.applyToMesh(plane, options.updatable);
             vertexData.applyToMesh(plane, options.updatable);
@@ -724,7 +724,7 @@
         public static CreateGroundFromHeightMap(name: string, url: string, options: { width?: number, height?: number, subdivisions?: number, minHeight?: number, maxHeight?: number, colorFilter?: Color3, updatable?: boolean, onReady?: (mesh: GroundMesh) => void }, scene: Scene): GroundMesh {
         public static CreateGroundFromHeightMap(name: string, url: string, options: { width?: number, height?: number, subdivisions?: number, minHeight?: number, maxHeight?: number, colorFilter?: Color3, updatable?: boolean, onReady?: (mesh: GroundMesh) => void }, scene: Scene): GroundMesh {
             var width = options.width || 10.0;
             var width = options.width || 10.0;
             var height = options.height || 10.0;
             var height = options.height || 10.0;
-            var subdivisions = options.subdivisions || 1|0;
+            var subdivisions = options.subdivisions || 1 | 0;
             var minHeight = options.minHeight || 0.0;
             var minHeight = options.minHeight || 0.0;
             var maxHeight = options.maxHeight || 1.0;
             var maxHeight = options.maxHeight || 1.0;
             var filter = options.colorFilter || new Color3(0.3, 0.59, 0.11);
             var filter = options.colorFilter || new Color3(0.3, 0.59, 0.11);
@@ -747,6 +747,11 @@
                 // Getting height map data
                 // Getting height map data
                 var canvas = document.createElement("canvas");
                 var canvas = document.createElement("canvas");
                 var context = canvas.getContext("2d");
                 var context = canvas.getContext("2d");
+
+                if (!context) {
+                    throw new Error("Unable to get 2d context for CreateGroundFromHeightMap");
+                }
+
                 var bufferWidth = img.width;
                 var bufferWidth = img.width;
                 var bufferHeight = img.height;
                 var bufferHeight = img.height;
                 canvas.width = bufferWidth;
                 canvas.width = bufferWidth;
@@ -788,37 +793,37 @@
          * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4).  
          * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4).  
          * Remember you can only change the shape positions, not their number when updating a polygon.
          * Remember you can only change the shape positions, not their number when updating a polygon.
          */
          */
-        public static CreatePolygon(name: string, options: {shape: Vector3[], holes?: Vector3[][], depth?: number, faceUV?: Vector4[], faceColors?: Color4[], updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4}, scene: Scene): Mesh {
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-			var shape = options.shape;
-			var holes = options.holes || [];
-			var depth = options.depth || 0;
-			var contours: Array<Vector2> = [];
-			var hole: Array<Vector2> = [];
-            
-			for(var i=0; i < shape.length; i++) {
-				contours[i] = new Vector2(shape[i].x, shape[i].z);
-			}
-			var epsilon = 0.00000001;
-			if(contours[0].equalsWithEpsilon(contours[contours.length - 1], epsilon)) {
+        public static CreatePolygon(name: string, options: { shape: Vector3[], holes?: Vector3[][], depth?: number, faceUV?: Vector4[], faceColors?: Color4[], updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: Scene): Mesh {
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
+            var shape = options.shape;
+            var holes = options.holes || [];
+            var depth = options.depth || 0;
+            var contours: Array<Vector2> = [];
+            var hole: Array<Vector2> = [];
+
+            for (var i = 0; i < shape.length; i++) {
+                contours[i] = new Vector2(shape[i].x, shape[i].z);
+            }
+            var epsilon = 0.00000001;
+            if (contours[0].equalsWithEpsilon(contours[contours.length - 1], epsilon)) {
                 contours.pop();
                 contours.pop();
-			}
-			
-			var polygonTriangulation = new PolygonMeshBuilder(name, contours, scene);
-			for(var hNb = 0; hNb < holes.length; hNb++) {
-				hole = [];
-				for(var hPoint = 0; hPoint < holes[hNb].length; hPoint++) {
-					hole.push(new Vector2(holes[hNb][hPoint].x, holes[hNb][hPoint].z));
-				}
-				polygonTriangulation.addHole(hole);
-			}
-			var polygon = polygonTriangulation.build(options.updatable, depth);
+            }
+
+            var polygonTriangulation = new PolygonMeshBuilder(name, contours, scene);
+            for (var hNb = 0; hNb < holes.length; hNb++) {
+                hole = [];
+                for (var hPoint = 0; hPoint < holes[hNb].length; hPoint++) {
+                    hole.push(new Vector2(holes[hNb][hPoint].x, holes[hNb][hPoint].z));
+                }
+                polygonTriangulation.addHole(hole);
+            }
+            var polygon = polygonTriangulation.build(options.updatable, depth);
             polygon._originalBuilderSideOrientation = options.sideOrientation;
             polygon._originalBuilderSideOrientation = options.sideOrientation;
-			var vertexData = VertexData.CreatePolygon(polygon, options.sideOrientation, options.faceUV, options.faceColors, options.frontUVs, options.backUVs);
-            vertexData.applyToMesh(polygon, options.updatable);			
-			
+            var vertexData = VertexData.CreatePolygon(polygon, options.sideOrientation, options.faceUV, options.faceColors, options.frontUVs, options.backUVs);
+            vertexData.applyToMesh(polygon, options.updatable);
+
             return polygon;
             return polygon;
-		};
+        };
 
 
         /**
         /**
          * Creates an extruded polygon mesh, with depth in the Y direction. 
          * Creates an extruded polygon mesh, with depth in the Y direction. 
@@ -826,10 +831,10 @@
          * Please read this tutorial : http://doc.babylonjs.com/tutorials/CreateBox_Per_Face_Textures_And_Colors  
          * Please read this tutorial : http://doc.babylonjs.com/tutorials/CreateBox_Per_Face_Textures_And_Colors  
 		*/
 		*/
 
 
-		public static ExtrudePolygon(name: string, options: {shape: Vector3[], holes?: Vector3[][], depth?: number, faceUV?: Vector4[], faceColors?: Color4[], updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4}, scene: Scene): Mesh {
-			return MeshBuilder.CreatePolygon(name, options, scene);
-		};
-         
+        public static ExtrudePolygon(name: string, options: { shape: Vector3[], holes?: Vector3[][], depth?: number, faceUV?: Vector4[], faceColors?: Color4[], updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: Scene): Mesh {
+            return MeshBuilder.CreatePolygon(name, options, scene);
+        };
+
 
 
         /**
         /**
          * Creates a tube mesh.    
          * Creates a tube mesh.    
@@ -866,17 +871,17 @@
             if (options.radius !== undefined) {
             if (options.radius !== undefined) {
                 radius = options.radius;
                 radius = options.radius;
             };
             };
-            var tessellation = options.tessellation || 64|0;
-            var radiusFunction = options.radiusFunction;
+            var tessellation = options.tessellation || 64 | 0;
+            var radiusFunction = options.radiusFunction || null;
             var cap = options.cap || Mesh.NO_CAP;
             var cap = options.cap || Mesh.NO_CAP;
             var invertUV = options.invertUV || false;
             var invertUV = options.invertUV || false;
             var updatable = options.updatable;
             var updatable = options.updatable;
-            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            options.arc = (options.arc <= 0.0 || options.arc > 1.0) ? 1.0 : options.arc || 1.0;
+            var sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
+            options.arc = options.arc && (options.arc <= 0.0 || options.arc > 1.0) ? 1.0 : options.arc || 1.0;
 
 
             // tube geometry
             // tube geometry
-            var tubePathArray = (path: Vector3[], path3D: Path3D, circlePaths: Vector3[][], radius: number, tessellation: number, 
-                                radiusFunction: { (i: number, distance: number): number; }, cap: number, arc: number) => {
+            var tubePathArray = (path: Vector3[], path3D: Path3D, circlePaths: Vector3[][], radius: number, tessellation: number,
+                radiusFunction: Nullable<{ (i: number, distance: number): number; }>, cap: number, arc: number) => {
                 var tangents = path3D.getTangents();
                 var tangents = path3D.getTangents();
                 var normals = path3D.getNormals();
                 var normals = path3D.getNormals();
                 var distances = path3D.getDistances();
                 var distances = path3D.getDistances();
@@ -942,7 +947,7 @@
                 var arc = options.arc || (<any>instance).arc;
                 var arc = options.arc || (<any>instance).arc;
                 path3D = ((<any>instance).path3D).update(path);
                 path3D = ((<any>instance).path3D).update(path);
                 pathArray = tubePathArray(path, path3D, (<any>instance).pathArray, radius, (<any>instance).tessellation, radiusFunction, (<any>instance).cap, arc);
                 pathArray = tubePathArray(path, path3D, (<any>instance).pathArray, radius, (<any>instance).tessellation, radiusFunction, (<any>instance).cap, arc);
-                instance = MeshBuilder.CreateRibbon(null, { pathArray: pathArray, instance: instance });
+                instance = MeshBuilder.CreateRibbon("", { pathArray: pathArray, instance: instance });
                 (<any>instance).path3D = path3D;
                 (<any>instance).path3D = path3D;
                 (<any>instance).pathArray = pathArray;
                 (<any>instance).pathArray = pathArray;
                 (<any>instance).arc = arc;
                 (<any>instance).arc = arc;
@@ -988,9 +993,9 @@
         public static CreatePolyhedron(name: string, options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], flat?: boolean, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: Scene): Mesh {
         public static CreatePolyhedron(name: string, options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], flat?: boolean, updatable?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }, scene: Scene): Mesh {
             var polyhedron = new Mesh(name, scene);
             var polyhedron = new Mesh(name, scene);
 
 
-            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
+            options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation);
             polyhedron._originalBuilderSideOrientation = options.sideOrientation;
             polyhedron._originalBuilderSideOrientation = options.sideOrientation;
-            
+
             var vertexData = VertexData.CreatePolyhedron(options);
             var vertexData = VertexData.CreatePolyhedron(options);
 
 
             vertexData.applyToMesh(polyhedron, options.updatable);
             vertexData.applyToMesh(polyhedron, options.updatable);
@@ -1008,7 +1013,7 @@
          * The parameter `angle` (float in radian, default 0) sets the angle to rotate the decal.  
          * The parameter `angle` (float in radian, default 0) sets the angle to rotate the decal.  
          */
          */
         public static CreateDecal(name: string, sourceMesh: AbstractMesh, options: { position?: Vector3, normal?: Vector3, size?: Vector3, angle?: number }): Mesh {
         public static CreateDecal(name: string, sourceMesh: AbstractMesh, options: { position?: Vector3, normal?: Vector3, size?: Vector3, angle?: number }): Mesh {
-            var indices = sourceMesh.getIndices();
+            var indices = <IndicesArray>sourceMesh.getIndices();
             var positions = sourceMesh.getVerticesData(VertexBuffer.PositionKind);
             var positions = sourceMesh.getVerticesData(VertexBuffer.PositionKind);
             var normals = sourceMesh.getVerticesData(VertexBuffer.NormalKind);
             var normals = sourceMesh.getVerticesData(VertexBuffer.NormalKind);
             var position = options.position || Vector3.Zero();
             var position = options.position || Vector3.Zero();
@@ -1019,7 +1024,7 @@
             // Getting correct rotation
             // Getting correct rotation
             if (!normal) {
             if (!normal) {
                 var target = new Vector3(0, 0, 1);
                 var target = new Vector3(0, 0, 1);
-                var camera = sourceMesh.getScene().activeCamera;
+                var camera = <Camera>sourceMesh.getScene().activeCamera;
                 var cameraWorldTarget = Vector3.TransformCoordinates(target, camera.getWorldMatrix());
                 var cameraWorldTarget = Vector3.TransformCoordinates(target, camera.getWorldMatrix());
 
 
                 normal = camera.globalPosition.subtract(cameraWorldTarget);
                 normal = camera.globalPosition.subtract(cameraWorldTarget);
@@ -1044,8 +1049,12 @@
             var currentVertexDataIndex = 0;
             var currentVertexDataIndex = 0;
 
 
             var extractDecalVector3 = (indexId: number): PositionNormalVertex => {
             var extractDecalVector3 = (indexId: number): PositionNormalVertex => {
-                var vertexId = indices[indexId];
                 var result = new PositionNormalVertex();
                 var result = new PositionNormalVertex();
+                if (!indices || !positions || !normals) {
+                    return result;
+                }
+
+                var vertexId = indices[indexId];
                 result.position = new Vector3(positions[vertexId * 3], positions[vertexId * 3 + 1], positions[vertexId * 3 + 2]);
                 result.position = new Vector3(positions[vertexId * 3], positions[vertexId * 3 + 1], positions[vertexId * 3 + 2]);
 
 
                 // Send vector to decal local world
                 // Send vector to decal local world
@@ -1057,7 +1066,7 @@
 
 
                 return result;
                 return result;
             }; // Inspired by https://github.com/mrdoob/three.js/blob/eee231960882f6f3b6113405f524956145148146/examples/js/geometries/DecalGeometry.js
             }; // Inspired by https://github.com/mrdoob/three.js/blob/eee231960882f6f3b6113405f524956145148146/examples/js/geometries/DecalGeometry.js
-            var clip = (vertices: PositionNormalVertex[], axis: Vector3): PositionNormalVertex[]=> {
+            var clip = (vertices: PositionNormalVertex[], axis: Vector3): PositionNormalVertex[] => {
                 if (vertices.length === 0) {
                 if (vertices.length === 0) {
                     return vertices;
                     return vertices;
                 }
                 }
@@ -1079,7 +1088,10 @@
                     var v2Out: boolean;
                     var v2Out: boolean;
                     var v3Out: boolean;
                     var v3Out: boolean;
                     var total = 0;
                     var total = 0;
-                    var nV1: PositionNormalVertex, nV2: PositionNormalVertex, nV3: PositionNormalVertex, nV4: PositionNormalVertex;
+                    let nV1: Nullable<PositionNormalVertex> = null;
+                    let nV2: Nullable<PositionNormalVertex> = null;
+                    let nV3: Nullable<PositionNormalVertex> = null;
+                    let nV4: Nullable<PositionNormalVertex> = null;
 
 
                     var d1 = Vector3.Dot(vertices[index].position, axis) - clipSize;
                     var d1 = Vector3.Dot(vertices[index].position, axis) - clipSize;
                     var d2 = Vector3.Dot(vertices[index + 1].position, axis) - clipSize;
                     var d2 = Vector3.Dot(vertices[index + 1].position, axis) - clipSize;
@@ -1128,13 +1140,15 @@
                                 nV4 = clipVertices(vertices[index + 2], nV2);
                                 nV4 = clipVertices(vertices[index + 2], nV2);
                             }
                             }
 
 
-                            result.push(nV1.clone());
-                            result.push(nV2.clone());
-                            result.push(nV3);
+                            if (nV1 && nV2 && nV3 && nV4) {
+                                result.push(nV1.clone());
+                                result.push(nV2.clone());
+                                result.push(nV3);
 
 
-                            result.push(nV4);
-                            result.push(nV3.clone());
-                            result.push(nV2.clone());
+                                result.push(nV4);
+                                result.push(nV3.clone());
+                                result.push(nV2.clone());
+                            }
                             break;
                             break;
                         case 2:
                         case 2:
                             if (!v1Out) {
                             if (!v1Out) {
@@ -1214,20 +1228,22 @@
         }
         }
 
 
         // Privates
         // Privates
-        private static _ExtrudeShapeGeneric(name: string, shape: Vector3[], curve: Vector3[], scale: number, rotation: number, scaleFunction: { (i: number, distance: number): number; }, rotateFunction: { (i: number, distance: number): number; }, rbCA: boolean, rbCP: boolean, cap: number, custom: boolean, scene: Scene, updtbl: boolean, side: number, instance: Mesh, invertUV: boolean, frontUVs: Vector4, backUVs: Vector4): Mesh {
+        private static _ExtrudeShapeGeneric(name: string, shape: Vector3[], curve: Vector3[], scale: Nullable<number>, rotation: Nullable<number>, scaleFunction: Nullable<{ (i: number, distance: number): number; }>,
+            rotateFunction: Nullable<{ (i: number, distance: number): number; }>, rbCA: boolean, rbCP: boolean, cap: number, custom: boolean,
+            scene: Nullable<Scene>, updtbl: boolean, side: number, instance: Nullable<Mesh>, invertUV: boolean, frontUVs: Nullable<Vector4>, backUVs: Nullable<Vector4>): Mesh {
             // extrusion geometry
             // extrusion geometry
-            var extrusionPathArray = (shape: Vector3[], curve: Vector3[], path3D: Path3D, shapePaths: Vector3[][], scale: number, rotation: number, 
-                                        scaleFunction:{ (i: number, distance: number): number; } , rotateFunction:{ (i: number, distance: number): number; } , cap: number, custom: boolean) => {
+            var extrusionPathArray = (shape: Vector3[], curve: Vector3[], path3D: Path3D, shapePaths: Vector3[][], scale: Nullable<number>, rotation: Nullable<number>,
+                scaleFunction: Nullable<{ (i: number, distance: number): number; }>, rotateFunction: Nullable<{ (i: number, distance: number): number; }>, cap: number, custom: boolean) => {
                 var tangents = path3D.getTangents();
                 var tangents = path3D.getTangents();
                 var normals = path3D.getNormals();
                 var normals = path3D.getNormals();
                 var binormals = path3D.getBinormals();
                 var binormals = path3D.getBinormals();
                 var distances = path3D.getDistances();
                 var distances = path3D.getDistances();
 
 
                 var angle = 0;
                 var angle = 0;
-                var returnScale: { (i: number, distance: number): number; } = () => { return scale; };
-                var returnRotation: { (i: number, distance: number): number; } = () => { return rotation; };
-                var rotate: { (i: number, distance: number): number; } = custom ? rotateFunction : returnRotation;
-                var scl: { (i: number, distance: number): number; } = custom ? scaleFunction : returnScale;
+                var returnScale: { (i: number, distance: number): number; } = () => { return scale !== null ? scale : 1; };
+                var returnRotation: { (i: number, distance: number): number; } = () => { return rotation!== null ? rotation : 0; };
+                var rotate: { (i: number, distance: number): number; } = custom && rotateFunction ? rotateFunction : returnRotation;
+                var scl: { (i: number, distance: number): number; } = custom && scaleFunction ? scaleFunction : returnScale;
                 var index = (cap === Mesh.NO_CAP || cap === Mesh.CAP_END) ? 0 : 2;
                 var index = (cap === Mesh.NO_CAP || cap === Mesh.CAP_END) ? 0 : 2;
                 var rotationMatrix: Matrix = Tmp.Matrix[0];
                 var rotationMatrix: Matrix = Tmp.Matrix[0];
 
 
@@ -1248,7 +1264,7 @@
                     index++;
                     index++;
                 }
                 }
                 // cap
                 // cap
-                var capPath = (shapePath: Vector3[])  => {
+                var capPath = (shapePath: Vector3[]) => {
                     var pointCap = Array<Vector3>();
                     var pointCap = Array<Vector3>();
                     var barycenter = Vector3.Zero();
                     var barycenter = Vector3.Zero();
                     var i: number;
                     var i: number;
@@ -1288,7 +1304,7 @@
             if (instance) { // instance update
             if (instance) { // instance update
                 path3D = ((<any>instance).path3D).update(curve);
                 path3D = ((<any>instance).path3D).update(curve);
                 pathArray = extrusionPathArray(shape, curve, (<any>instance).path3D, (<any>instance).pathArray, scale, rotation, scaleFunction, rotateFunction, (<any>instance).cap, custom);
                 pathArray = extrusionPathArray(shape, curve, (<any>instance).path3D, (<any>instance).pathArray, scale, rotation, scaleFunction, rotateFunction, (<any>instance).cap, custom);
-                instance = Mesh.CreateRibbon(null, pathArray, null, null, null, scene, null, null, instance);
+                instance = Mesh.CreateRibbon("", pathArray, false, false, 0, scene || undefined, false, 0, instance);
 
 
                 return instance;
                 return instance;
             }
             }
@@ -1297,7 +1313,7 @@
             var newShapePaths = new Array<Array<Vector3>>();
             var newShapePaths = new Array<Array<Vector3>>();
             cap = (cap < 0 || cap > 3) ? 0 : cap;
             cap = (cap < 0 || cap > 3) ? 0 : cap;
             pathArray = extrusionPathArray(shape, curve, path3D, newShapePaths, scale, rotation, scaleFunction, rotateFunction, cap, custom);
             pathArray = extrusionPathArray(shape, curve, path3D, newShapePaths, scale, rotation, scaleFunction, rotateFunction, cap, custom);
-            var extrudedGeneric = MeshBuilder.CreateRibbon(name, {pathArray: pathArray, closeArray: rbCA, closePath: rbCP, updatable: updtbl, sideOrientation: side, invertUV: invertUV, frontUVs: frontUVs, backUVs: backUVs}, scene);
+            var extrudedGeneric = MeshBuilder.CreateRibbon(name, { pathArray: pathArray, closeArray: rbCA, closePath: rbCP, updatable: updtbl, sideOrientation: side, invertUV: invertUV, frontUVs: frontUVs || undefined, backUVs: backUVs || undefined }, scene);
             (<any>extrudedGeneric).pathArray = pathArray;
             (<any>extrudedGeneric).pathArray = pathArray;
             (<any>extrudedGeneric).path3D = path3D;
             (<any>extrudedGeneric).path3D = path3D;
             (<any>extrudedGeneric).cap = cap;
             (<any>extrudedGeneric).cap = cap;

+ 13 - 1
src/Mesh/babylon.meshSimplification.ts

@@ -392,6 +392,10 @@
             var vertexReferences: Array<number> = [];
             var vertexReferences: Array<number> = [];
 
 
             var vertexInit = (i: number) => {
             var vertexInit = (i: number) => {
+                if (!positionData) {
+                    return;
+                }
+
                 var offset = i + submesh.verticesStart;
                 var offset = i + submesh.verticesStart;
                 var position = Vector3.FromArray(positionData, offset * 3);
                 var position = Vector3.FromArray(positionData, offset * 3);
 
 
@@ -407,6 +411,10 @@
             AsyncLoop.SyncAsyncForLoop(totalVertices,(this.syncIterations / 4) >> 0, vertexInit,() => {
             AsyncLoop.SyncAsyncForLoop(totalVertices,(this.syncIterations / 4) >> 0, vertexInit,() => {
 
 
                 var indicesInit = (i: number) => {
                 var indicesInit = (i: number) => {
+                    if (!indices) {
+                        return;
+                    }
+
                     var offset = (submesh.indexStart / 3) + i;
                     var offset = (submesh.indexStart / 3) + i;
                     var pos = (offset * 3);
                     var pos = (offset * 3);
                     var i0 = indices[pos + 0];
                     var i0 = indices[pos + 0];
@@ -483,6 +491,10 @@
                 vertex.id = vertexCount;
                 vertex.id = vertexCount;
                 if (vertex.triangleCount) {
                 if (vertex.triangleCount) {
                     vertex.originalOffsets.forEach(originalOffset => {
                     vertex.originalOffsets.forEach(originalOffset => {
+                        if (!normalData) {
+                            return;
+                        }
+
                         newPositionData.push(vertex.position.x);
                         newPositionData.push(vertex.position.x);
                         newPositionData.push(vertex.position.y);
                         newPositionData.push(vertex.position.y);
                         newPositionData.push(vertex.position.z);
                         newPositionData.push(vertex.position.z);
@@ -510,7 +522,7 @@
             this._reconstructedMesh.subMeshes = [];
             this._reconstructedMesh.subMeshes = [];
 
 
             var newIndicesArray: number[] = <number[]>this._reconstructedMesh.getIndices(); //[];
             var newIndicesArray: number[] = <number[]>this._reconstructedMesh.getIndices(); //[];
-            var originalIndices = this._mesh.getIndices();
+            var originalIndices = <IndicesArray>this._mesh.getIndices();
             for (i = 0; i < newTriangles.length; ++i) {
             for (i = 0; i < newTriangles.length; ++i) {
                 t = newTriangles[i]; //now get the new referencing point for each vertex
                 t = newTriangles[i]; //now get the new referencing point for each vertex
                 [0, 1, 2].forEach(idx => {
                 [0, 1, 2].forEach(idx => {

+ 1 - 1
src/Mesh/babylon.polygonMesh.ts

@@ -147,7 +147,7 @@ module BABYLON {
             return this;
             return this;
         }
         }
 
 
-        build(updatable: boolean = false, depth?:number): Mesh {
+        build(updatable: boolean = false, depth:number = 0): Mesh {
             var result = new Mesh(this._name, this._scene);
             var result = new Mesh(this._name, this._scene);
 
 
             var normals = new Array<number>();
             var normals = new Array<number>();

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

@@ -35,7 +35,7 @@
         public _distanceToCamera: number;
         public _distanceToCamera: number;
         public _id: number;
         public _id: number;
 
 
-        private _currentMaterial: Material;
+        private _currentMaterial: Nullable<Material>;
 
 
         public static AddToMesh(materialIndex: number, verticesStart: number, verticesCount: number, indexStart: number, indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox: boolean = true): SubMesh {
         public static AddToMesh(materialIndex: number, verticesStart: number, verticesCount: number, indexStart: number, indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox: boolean = true): SubMesh {
             return new SubMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh, renderingMesh, createBoundingBox);
             return new SubMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh, renderingMesh, createBoundingBox);
@@ -98,7 +98,7 @@
         /**
         /**
          * Returns the submesh material.  
          * Returns the submesh material.  
          */
          */
-        public getMaterial(): Material {
+        public getMaterial(): Nullable<Material> {
             var rootMaterial = this._renderingMesh.material;
             var rootMaterial = this._renderingMesh.material;
 
 
             if (rootMaterial && (<MultiMaterial>rootMaterial).getSubMaterial) {
             if (rootMaterial && (<MultiMaterial>rootMaterial).getSubMaterial) {
@@ -128,7 +128,7 @@
         public refreshBoundingInfo(): SubMesh {
         public refreshBoundingInfo(): SubMesh {
             this._lastColliderWorldVertices = null;
             this._lastColliderWorldVertices = null;
 
 
-            if (this.IsGlobal) {
+            if (this.IsGlobal || !this._renderingMesh || !this._renderingMesh.geometry) {
                 return this;
                 return this;
             }
             }
             var data = this._renderingMesh.getVerticesData(VertexBuffer.PositionKind);
             var data = this._renderingMesh.getVerticesData(VertexBuffer.PositionKind);
@@ -138,7 +138,7 @@
                 return this;
                 return this;
             }
             }
 
 
-            var indices = this._renderingMesh.getIndices();
+            var indices = <IndicesArray>this._renderingMesh.getIndices();
             var extend: { minimum: Vector3, maximum: Vector3 };
             var extend: { minimum: Vector3, maximum: Vector3 };
 
 
             //is this the only submesh?
             //is this the only submesh?
@@ -364,7 +364,7 @@
             var maxVertexIndex = -Number.MAX_VALUE;
             var maxVertexIndex = -Number.MAX_VALUE;
 
 
             renderingMesh = (<Mesh>(renderingMesh || <Mesh>mesh));
             renderingMesh = (<Mesh>(renderingMesh || <Mesh>mesh));
-            var indices = renderingMesh.getIndices();
+            var indices = <IndicesArray>renderingMesh.getIndices();
 
 
             for (var index = startIndex; index < startIndex + indexCount; index++) {
             for (var index = startIndex; index < startIndex + indexCount; index++) {
                 var vertexIndex = indices[index];
                 var vertexIndex = indices[index];

+ 3 - 2
src/Mesh/babylon.vertexBuffer.ts

@@ -35,6 +35,7 @@
                         break;
                         break;
                     case VertexBuffer.MatricesWeightsKind:
                     case VertexBuffer.MatricesWeightsKind:
                     case VertexBuffer.MatricesWeightsExtraKind:
                     case VertexBuffer.MatricesWeightsExtraKind:
+                    default:
                         stride = 4;
                         stride = 4;
                         break;
                         break;
                 }
                 }
@@ -86,14 +87,14 @@
         /**
         /**
          * Returns an array of numbers or a Float32Array containing the VertexBuffer data.  
          * Returns an array of numbers or a Float32Array containing the VertexBuffer data.  
          */
          */
-        public getData(): FloatArray {
+        public getData(): Nullable<FloatArray> {
             return this._buffer.getData();
             return this._buffer.getData();
         }
         }
 
 
         /**
         /**
          * Returns the WebGLBuffer associated to the VertexBuffer.  
          * Returns the WebGLBuffer associated to the VertexBuffer.  
          */
          */
-        public getBuffer(): WebGLBuffer {
+        public getBuffer(): Nullable<WebGLBuffer> {
             return this._buffer.getBuffer();
             return this._buffer.getBuffer();
         }
         }
 
 

+ 3 - 3
src/Morph/babylon.morphTarget.ts

@@ -118,13 +118,13 @@ module BABYLON {
 
 
             var result = new MorphTarget(name, influence);
             var result = new MorphTarget(name, influence);
 
 
-            result.setPositions(mesh.getVerticesData(VertexBuffer.PositionKind));
+            result.setPositions(<FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind));
 
 
             if (mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
             if (mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
-                result.setNormals(mesh.getVerticesData(VertexBuffer.NormalKind));
+                result.setNormals(<FloatArray>mesh.getVerticesData(VertexBuffer.NormalKind));
             }
             }
             if (mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
             if (mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
-                result.setTangents(mesh.getVerticesData(VertexBuffer.TangentKind));
+                result.setTangents(<FloatArray>mesh.getVerticesData(VertexBuffer.TangentKind));
             }
             }
 
 
             return result;
             return result;

+ 8 - 6
src/Morph/babylon.morphTargetManager.ts

@@ -1,9 +1,9 @@
 module BABYLON {
 module BABYLON {
     export class MorphTargetManager {
     export class MorphTargetManager {
         private _targets = new Array<MorphTarget>();
         private _targets = new Array<MorphTarget>();
-        private _targetObservable = new Array<Observer<boolean>>();
+        private _targetObservable = new Array<Nullable<Observer<boolean>>>();
         private _activeTargets = new SmartArray<MorphTarget>(16);
         private _activeTargets = new SmartArray<MorphTarget>(16);
-        private _scene: Scene;
+        private _scene: Nullable<Scene>;
         private _influences: Float32Array;
         private _influences: Float32Array;
         private _supportsNormals = false;
         private _supportsNormals = false;
         private _supportsTangents = false;
         private _supportsTangents = false;
@@ -11,16 +11,18 @@ module BABYLON {
         private _uniqueId = 0;
         private _uniqueId = 0;
         private _tempInfluences = new Array<number>();
         private _tempInfluences = new Array<number>();
 
 
-        public constructor(scene?: Scene) {
+        public constructor(scene: Nullable<Scene> = null) {
             if (!scene) {
             if (!scene) {
                 scene = Engine.LastCreatedScene;
                 scene = Engine.LastCreatedScene;
             }
             }
 
 
             this._scene = scene;
             this._scene = scene;
 
 
-            this._scene.morphTargetManagers.push(this);
+            if (this._scene) {
+                this._scene.morphTargetManagers.push(this);
 
 
-            this._uniqueId = scene.getUniqueId();
+                this._uniqueId = this._scene.getUniqueId();
+            }
         }
         }
 
 
         public get uniqueId(): number {
         public get uniqueId(): number {
@@ -129,7 +131,7 @@ module BABYLON {
                 this._influences[index] = this._tempInfluences[index];
                 this._influences[index] = this._tempInfluences[index];
             }
             }
             
             
-            if (needUpdate) {
+            if (needUpdate && this._scene) {
                 // Flag meshes as dirty to resync with the active targets
                 // Flag meshes as dirty to resync with the active targets
                 for (var mesh of this._scene.meshes) {
                 for (var mesh of this._scene.meshes) {
                     if ((<any>mesh).morphTargetManager === this) {
                     if ((<any>mesh).morphTargetManager === this) {

+ 2 - 2
src/Particles/babylon.gpuParticleSystem.ts

@@ -2,7 +2,7 @@
     export class GPUParticleSystem implements IDisposable, IParticleSystem {
     export class GPUParticleSystem implements IDisposable, IParticleSystem {
         // Members
         // Members
         public id: string;
         public id: string;
-        public emitter: AbstractMesh | Vector3 = null;       
+        public emitter: Nullable<AbstractMesh | Vector3> = null;       
         public renderingGroupId = 0;        
         public renderingGroupId = 0;        
         public layerMask: number = 0x0FFFFFFF;
         public layerMask: number = 0x0FFFFFFF;
 
 
@@ -50,7 +50,7 @@
         }
         }
 
 
         //TODO: Clone / Parse / serialize
         //TODO: Clone / Parse / serialize
-        public clone(name: string, newEmitter: any): GPUParticleSystem {
+        public clone(name: string, newEmitter: any): Nullable<GPUParticleSystem> {
             return null;
             return null;
         }
         }
 
 

+ 21 - 17
src/Particles/babylon.particleSystem.ts

@@ -12,14 +12,14 @@
     export interface IParticleSystem {
     export interface IParticleSystem {
         id: string;
         id: string;
         name: string;
         name: string;
-        emitter: AbstractMesh | Vector3;
+        emitter: Nullable<AbstractMesh | Vector3>; 
         renderingGroupId: number;
         renderingGroupId: number;
         layerMask: number;
         layerMask: number;
         isStarted(): boolean;
         isStarted(): boolean;
         animate(): void;
         animate(): void;
         render(): number;
         render(): number;
         dispose(): void;
         dispose(): void;
-        clone(name: string, newEmitter: any): IParticleSystem;
+        clone(name: string, newEmitter: any): Nullable<IParticleSystem>;
         serialize(): any;
         serialize(): any;
 
 
         rebuild(): void
         rebuild(): void
@@ -35,7 +35,7 @@
 
 
         public id: string;
         public id: string;
         public renderingGroupId = 0;
         public renderingGroupId = 0;
-        public emitter: AbstractMesh | Vector3 = null;
+        public emitter: Nullable<AbstractMesh | Vector3> = null;
         public emitRate = 10;
         public emitRate = 10;
         public manualEmitCount = -1;
         public manualEmitCount = -1;
         public updateSpeed = 0.01;
         public updateSpeed = 0.01;
@@ -53,7 +53,7 @@
         public minAngularSpeed = 0;
         public minAngularSpeed = 0;
         public maxAngularSpeed = 0;
         public maxAngularSpeed = 0;
 
 
-        public particleTexture: Texture;
+        public particleTexture: Nullable<Texture>;
 
 
         public layerMask: number = 0x0FFFFFFF;
         public layerMask: number = 0x0FFFFFFF;
 
 
@@ -69,7 +69,7 @@
         */
         */
         public onDisposeObservable = new Observable<ParticleSystem>();
         public onDisposeObservable = new Observable<ParticleSystem>();
 
 
-        private _onDisposeObserver: Observer<ParticleSystem>;
+        private _onDisposeObserver: Nullable<Observer<ParticleSystem>>;
         public set onDispose(callback: () => void) {
         public set onDispose(callback: () => void) {
             if (this._onDisposeObserver) {
             if (this._onDisposeObserver) {
                 this.onDisposeObservable.remove(this._onDisposeObserver);
                 this.onDisposeObservable.remove(this._onDisposeObserver);
@@ -78,7 +78,7 @@
         }
         }
 
 
         public updateFunction: (particles: Particle[]) => void;
         public updateFunction: (particles: Particle[]) => void;
-        public onAnimationEnd: () => void = null;
+        public onAnimationEnd: Nullable<() => void> = null;
 
 
         public blendMode = ParticleSystem.BLENDMODE_ONEONE;
         public blendMode = ParticleSystem.BLENDMODE_ONEONE;
 
 
@@ -103,11 +103,11 @@
         private _stockParticles = new Array<Particle>();
         private _stockParticles = new Array<Particle>();
         private _newPartsExcess = 0;
         private _newPartsExcess = 0;
         private _vertexData: Float32Array;
         private _vertexData: Float32Array;
-        private _vertexBuffer: Buffer;
+        private _vertexBuffer: Nullable<Buffer>;
         private _vertexBuffers: { [key: string]: VertexBuffer } = {};
         private _vertexBuffers: { [key: string]: VertexBuffer } = {};
-        private _indexBuffer: WebGLBuffer;
+        private _indexBuffer: Nullable<WebGLBuffer>;
         private _effect: Effect;
         private _effect: Effect;
-        private _customEffect: Effect;
+        private _customEffect: Nullable<Effect>;
         private _cachedDefines: string;
         private _cachedDefines: string;
 
 
         private _scaledColorStep = new Color4(0, 0, 0, 0);
         private _scaledColorStep = new Color4(0, 0, 0, 0);
@@ -137,7 +137,7 @@
         }
         }
         // end of sheet animation
         // end of sheet animation
 
 
-        constructor(public name: string, capacity: number, scene: Scene, customEffect?: Effect, private _isAnimationSheetEnabled: boolean = false, epsilon: number = 0.01) {
+        constructor(public name: string, capacity: number, scene: Scene, customEffect: Nullable<Effect> = null, private _isAnimationSheetEnabled: boolean = false, epsilon: number = 0.01) {
             this.id = name;
             this.id = name;
             this._capacity = capacity;
             this._capacity = capacity;
 
 
@@ -238,7 +238,7 @@
         }
         }
 
 
         public recycleParticle(particle: Particle): void {
         public recycleParticle(particle: Particle): void {
-            var lastParticle = this.particles.pop();
+            var lastParticle = <Particle>this.particles.pop();
 
 
             if (lastParticle !== particle) {
             if (lastParticle !== particle) {
                 lastParticle.copyTo(particle);
                 lastParticle.copyTo(particle);
@@ -336,7 +336,7 @@
                 }
                 }
 
 
                 if (this._stockParticles.length !== 0) {
                 if (this._stockParticles.length !== 0) {
-                    particle = this._stockParticles.pop();
+                    particle = <Particle>this._stockParticles.pop();
                     particle.age = 0;
                     particle.age = 0;
                     particle.cellIndex = this.startSpriteCellID;
                     particle.cellIndex = this.startSpriteCellID;
                 } else {
                 } else {
@@ -484,10 +484,12 @@
                 offset += 4;
                 offset += 4;
             }
             }
 
 
-            this._vertexBuffer.update(this._vertexData);
+            if (this._vertexBuffer) {
+                this._vertexBuffer.update(this._vertexData);
+            }
         }
         }
 
 
-        public appendParticleVertexes: (offset: number, particle: Particle) => void = null;
+        public appendParticleVertexes: Nullable<(offset: number, particle: Particle) => void> = null;
 
 
         private appenedParticleVertexesWithSheet(offset: number, particle: Particle) {
         private appenedParticleVertexesWithSheet(offset: number, particle: Particle) {
             this._appendParticleVertexWithAnimation(offset++, particle, 0, 0);
             this._appendParticleVertexWithAnimation(offset++, particle, 0, 0);
@@ -506,7 +508,9 @@
         public rebuild(): void {
         public rebuild(): void {
             this._createIndexBuffer();
             this._createIndexBuffer();
 
 
-            this._vertexBuffer._rebuild();
+            if (this._vertexBuffer) {
+                this._vertexBuffer._rebuild();
+            }
         }
         }
 
 
         public render(): number {
         public render(): number {
@@ -591,7 +595,7 @@
 
 
         // Clone
         // Clone
         public clone(name: string, newEmitter: any): ParticleSystem {
         public clone(name: string, newEmitter: any): ParticleSystem {
-            var custom: Effect = null;
+            var custom: Nullable<Effect> = null;
             var program: any = null;
             var program: any = null;
             if (this.customShader != null) {
             if (this.customShader != null) {
                 program = this.customShader;
                 program = this.customShader;
@@ -673,7 +677,7 @@
 
 
         public static Parse(parsedParticleSystem: any, scene: Scene, rootUrl: string): ParticleSystem {
         public static Parse(parsedParticleSystem: any, scene: Scene, rootUrl: string): ParticleSystem {
             var name = parsedParticleSystem.name;
             var name = parsedParticleSystem.name;
-            var custom: Effect = null;
+            var custom: Nullable<Effect> = null;
             var program: any = null;
             var program: any = null;
             if (parsedParticleSystem.customShader) {
             if (parsedParticleSystem.customShader) {
                 program = parsedParticleSystem.customShader;
                 program = parsedParticleSystem.customShader;

+ 27 - 26
src/Particles/babylon.solidParticle.ts

@@ -1,25 +1,25 @@
 module BABYLON {
 module BABYLON {
     
     
         export class SolidParticle {
         export class SolidParticle {
-            public idx: number = 0;                         // particle global index
-            public color = new Color4(1.0, 1.0, 1.0, 1.0);  // color
-            public position = Vector3.Zero();               // position
-            public rotation = Vector3.Zero();               // rotation
-            public rotationQuaternion: Quaternion;          // quaternion, will overwrite rotation
-            public scaling = Vector3.One();                 // scaling
-            public uvs = new Vector4(0.0, 0.0, 1.0, 1.0);   // uvs
-            public velocity = Vector3.Zero();               // velocity
-            public alive = true;                            // alive
-            public isVisible = true;                        // visibility
-            public _pos: number = 0;                        // index of this particle in the global "positions" array
-            public _ind: number = 0;                        // index of this particle in the global "indices" array
-            public _model: ModelShape;                      // model shape reference
-            public shapeId: number = 0;                     // model shape id
-            public idxInShape: number = 0;                  // index of the particle in its shape id
-            public _modelBoundingInfo: BoundingInfo;        // reference to the shape model BoundingInfo object
-            public _boundingInfo: BoundingInfo;             // particle BoundingInfo
-            public _sps: SolidParticleSystem;               // reference to the SPS what the particle belongs to
-            public _stillInvisible: boolean = false;         // still set as invisible in order to skip useless computations
+            public idx: number = 0;                                             // particle global index
+            public color: Nullable<Color4> = new Color4(1.0, 1.0, 1.0, 1.0);    // color
+            public position = Vector3.Zero();                                   // position
+            public rotation = Vector3.Zero();                                   // rotation
+            public rotationQuaternion: Nullable<Quaternion>;                    // quaternion, will overwrite rotation
+            public scaling = Vector3.One();                                     // scaling
+            public uvs = new Vector4(0.0, 0.0, 1.0, 1.0);                       // uvs
+            public velocity = Vector3.Zero();                                   // velocity
+            public alive = true;                                                // alive
+            public isVisible = true;                                            // visibility
+            public _pos: number = 0;                                            // index of this particle in the global "positions" array
+            public _ind: number = 0;                                            // index of this particle in the global "indices" array
+            public _model: ModelShape;                                          // model shape reference
+            public shapeId: number = 0;                                         // model shape id
+            public idxInShape: number = 0;                                      // index of the particle in its shape id
+            public _modelBoundingInfo: BoundingInfo;                            // reference to the shape model BoundingInfo object
+            public _boundingInfo: BoundingInfo;                                 // particle BoundingInfo
+            public _sps: SolidParticleSystem;                                   // reference to the SPS what the particle belongs to
+            public _stillInvisible: boolean = false;                            // still set as invisible in order to skip useless computations
     
     
             /**
             /**
              * Creates a Solid Particle object.
              * Creates a Solid Particle object.
@@ -32,11 +32,11 @@ module BABYLON {
              * `idxInShape` (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
              * `idxInShape` (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
              * `modelBoundingInfo` is the reference to the model BoundingInfo used for intersection computations.
              * `modelBoundingInfo` is the reference to the model BoundingInfo used for intersection computations.
              */
              */
-            constructor(particleIndex: number, positionIndex: number, indiceIndex: number, model: ModelShape, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: BoundingInfo) {
+            constructor(particleIndex: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo: Nullable<BoundingInfo> = null) {
                 this.idx = particleIndex;
                 this.idx = particleIndex;
                 this._pos = positionIndex;
                 this._pos = positionIndex;
                 this._ind = indiceIndex;
                 this._ind = indiceIndex;
-                this._model = model;
+                this._model = <ModelShape>model;
                 this.shapeId = shapeId;
                 this.shapeId = shapeId;
                 this.idxInShape = idxInShape;
                 this.idxInShape = idxInShape;
                 this._sps = sps;
                 this._sps = sps;
@@ -60,11 +60,11 @@ module BABYLON {
             /**
             /**
              * legacy support, changed quaternion to rotationQuaternion
              * legacy support, changed quaternion to rotationQuaternion
              */ 
              */ 
-            public get quaternion(): Quaternion {
+            public get quaternion(): Nullable<Quaternion> {
                 return this.rotationQuaternion;
                 return this.rotationQuaternion;
             }
             }
     
     
-            public set quaternion(q: Quaternion) {
+            public set quaternion(q: Nullable<Quaternion>) {
                 this.rotationQuaternion = q;
                 this.rotationQuaternion = q;
             }
             }
     
     
@@ -89,14 +89,15 @@ module BABYLON {
             public _shape: Vector3[];                   // flat array of model positions
             public _shape: Vector3[];                   // flat array of model positions
             public _shapeUV: number[];                  // flat array of model UVs
             public _shapeUV: number[];                  // flat array of model UVs
             public _indicesLength: number = 0;          // length of the shape in the model indices array
             public _indicesLength: number = 0;          // length of the shape in the model indices array
-            public _positionFunction: (particle: SolidParticle, i: number, s: number) => void;
-            public _vertexFunction: (particle: SolidParticle, vertex: Vector3, i: number) => void;
+            public _positionFunction: Nullable<(particle: SolidParticle, i: number, s: number) => void>;
+            public _vertexFunction: Nullable<(particle: SolidParticle, vertex: Vector3, i: number) => void>;
     
     
             /**
             /**
              * Creates a ModelShape object. This is an internal simplified reference to a mesh used as for a model to replicate particles from by the SPS.
              * Creates a ModelShape object. This is an internal simplified reference to a mesh used as for a model to replicate particles from by the SPS.
              * SPS internal tool, don't use it manually.  
              * SPS internal tool, don't use it manually.  
              */
              */
-            constructor(id: number, shape: Vector3[], indicesLength: number, shapeUV: number[], posFunction: (particle: SolidParticle, i: number, s: number) => void, vtxFunction: (particle: SolidParticle, vertex: Vector3, i: number) => void) {
+            constructor(id: number, shape: Vector3[], indicesLength: number, shapeUV: number[], 
+                            posFunction: Nullable<(particle: SolidParticle, i: number, s: number) => void>, vtxFunction: Nullable<(particle: SolidParticle, vertex: Vector3, i: number) => void>) {
                 this.shapeID = id;
                 this.shapeID = id;
                 this._shape = shape;
                 this._shape = shape;
                 this._indicesLength = indicesLength;
                 this._indicesLength = indicesLength;

+ 46 - 39
src/Particles/babylon.solidParticleSystem.ts

@@ -73,7 +73,7 @@
             private _alwaysVisible: boolean = false;
             private _alwaysVisible: boolean = false;
             private _depthSort: boolean = false;
             private _depthSort: boolean = false;
             private _shapeCounter: number = 0;
             private _shapeCounter: number = 0;
-            private _copy: SolidParticle = new SolidParticle(null, null, null, null, null, null, null);
+            private _copy: SolidParticle = new SolidParticle(0, 0, 0, null, 0, 0, this);
             private _shape: Vector3[];
             private _shape: Vector3[];
             private _shapeUV: number[];
             private _shapeUV: number[];
             private _color: Color4 = new Color4(0, 0, 0, 0);
             private _color: Color4 = new Color4(0, 0, 0, 0);
@@ -141,10 +141,10 @@
                 this.name = name;
                 this.name = name;
                 this._scene = scene || Engine.LastCreatedScene;
                 this._scene = scene || Engine.LastCreatedScene;
                 this._camera = <TargetCamera>scene.activeCamera;
                 this._camera = <TargetCamera>scene.activeCamera;
-                this._pickable = options ? options.isPickable : false;
-                this._depthSort = options ? options.enableDepthSort : false;
-                this._particlesIntersect = options ? options.particleIntersection : false;
-                this._bSphereOnly= options ? options.boundingSphereOnly : false;
+                this._pickable = options ? <boolean>options.isPickable : false;
+                this._depthSort = options ? <boolean>options.enableDepthSort : false;
+                this._particlesIntersect = options ? <boolean>options.particleIntersection : false;
+                this._bSphereOnly= options ? <boolean>options.boundingSphereOnly : false;
                 this._bSphereRadiusFactor = (options && options.bSphereRadiusFactor) ? options.bSphereRadiusFactor : 1.0;
                 this._bSphereRadiusFactor = (options && options.bSphereRadiusFactor) ? options.bSphereRadiusFactor : 1.0;
                 if (options && options.updatable) {
                 if (options && options.updatable) {
                     this._updatable = options.updatable;
                     this._updatable = options.updatable;
@@ -202,10 +202,10 @@
                 this.mesh.isPickable = this._pickable;
                 this.mesh.isPickable = this._pickable;
     
     
                 // free memory
                 // free memory
-                this._positions = null;
-                this._normals = null;
-                this._uvs = null;
-                this._colors = null;
+                (<any>this._positions) = null;
+                (<any>this._normals) = null;
+                (<any>this._uvs) = null;
+                (<any>this._colors) = null;
     
     
                 if (!this._updatable) {
                 if (!this._updatable) {
                     this.particles.length = 0;
                     this.particles.length = 0;
@@ -225,13 +225,13 @@
             */
             */
             public digest(mesh: Mesh, options?: { facetNb?: number; number?: number; delta?: number }): SolidParticleSystem {
             public digest(mesh: Mesh, options?: { facetNb?: number; number?: number; delta?: number }): SolidParticleSystem {
                 var size: number = (options && options.facetNb) || 1;
                 var size: number = (options && options.facetNb) || 1;
-                var number: number = (options && options.number);
+                var number: number = (options && options.number) || 0;
                 var delta: number = (options && options.delta) || 0;
                 var delta: number = (options && options.delta) || 0;
-                var meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
-                var meshInd = mesh.getIndices();
-                var meshUV = mesh.getVerticesData(VertexBuffer.UVKind);
-                var meshCol = mesh.getVerticesData(VertexBuffer.ColorKind);
-                var meshNor = mesh.getVerticesData(VertexBuffer.NormalKind);
+                var meshPos = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind);
+                var meshInd = <IndicesArray>mesh.getIndices();
+                var meshUV = <FloatArray>mesh.getVerticesData(VertexBuffer.UVKind);
+                var meshCol = <FloatArray>mesh.getVerticesData(VertexBuffer.ColorKind);
+                var meshNor = <FloatArray>mesh.getVerticesData(VertexBuffer.NormalKind);
     
     
                 var f: number = 0;                              // facet counter
                 var f: number = 0;                              // facet counter
                 var totalFacets: number = meshInd.length / 3;   // a facet is a triangle, so 3 indices
                 var totalFacets: number = meshInd.length / 3;   // a facet is a triangle, so 3 indices
@@ -477,7 +477,7 @@
             }
             }
     
     
             // adds a new particle object in the particles array
             // adds a new particle object in the particles array
-            private _addParticle(idx: number, idxpos: number, idxind: number, model: ModelShape, shapeId: number, idxInShape: number, bInfo?: BoundingInfo): SolidParticle {
+            private _addParticle(idx: number, idxpos: number, idxind: number, model: ModelShape, shapeId: number, idxInShape: number, bInfo: Nullable<BoundingInfo> = null): SolidParticle {
                 var sp = new SolidParticle(idx, idxpos, idxind, model, shapeId, idxInShape, this, bInfo);
                 var sp = new SolidParticle(idx, idxpos, idxind, model, shapeId, idxInShape, this, bInfo);
                 this.particles.push(sp);
                 this.particles.push(sp);
                 return sp;
                 return sp;
@@ -492,11 +492,11 @@
             * `vertexFunction` is an optional javascript function to called for each vertex of each particle on SPS creation
             * `vertexFunction` is an optional javascript function to called for each vertex of each particle on SPS creation
             */
             */
             public addShape(mesh: Mesh, nb: number, options?: { positionFunction?: any; vertexFunction?: any }): number {
             public addShape(mesh: Mesh, nb: number, options?: { positionFunction?: any; vertexFunction?: any }): number {
-                var meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
-                var meshInd = mesh.getIndices();
-                var meshUV = mesh.getVerticesData(VertexBuffer.UVKind);
-                var meshCol = mesh.getVerticesData(VertexBuffer.ColorKind);
-                var meshNor = mesh.getVerticesData(VertexBuffer.NormalKind);
+                var meshPos = <FloatArray>mesh.getVerticesData(VertexBuffer.PositionKind);
+                var meshInd = <IndicesArray>mesh.getIndices();
+                var meshUV = <FloatArray>mesh.getVerticesData(VertexBuffer.UVKind);
+                var meshCol = <FloatArray>mesh.getVerticesData(VertexBuffer.ColorKind);
+                var meshNor = <FloatArray>mesh.getVerticesData(VertexBuffer.NormalKind);
                 var bbInfo;
                 var bbInfo;
                 if (this._particlesIntersect) {
                 if (this._particlesIntersect) {
                     bbInfo = mesh.getBoundingInfo();
                     bbInfo = mesh.getBoundingInfo();
@@ -522,10 +522,10 @@
                         sp = this._addParticle(idx, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo);
                         sp = this._addParticle(idx, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo);
                         sp.position.copyFrom(currentCopy.position);
                         sp.position.copyFrom(currentCopy.position);
                         sp.rotation.copyFrom(currentCopy.rotation);
                         sp.rotation.copyFrom(currentCopy.rotation);
-                        if (currentCopy.rotationQuaternion) {
+                        if (currentCopy.rotationQuaternion && sp.rotationQuaternion) {
                             sp.rotationQuaternion.copyFrom(currentCopy.rotationQuaternion);
                             sp.rotationQuaternion.copyFrom(currentCopy.rotationQuaternion);
                         }
                         }
-                        if (currentCopy.color) {
+                        if (currentCopy.color && sp.color) {
                             sp.color.copyFrom(currentCopy.color);
                             sp.color.copyFrom(currentCopy.color);
                         }
                         }
                         sp.scaling.copyFrom(currentCopy.scaling);
                         sp.scaling.copyFrom(currentCopy.scaling);
@@ -674,8 +674,10 @@
                         Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, this._maximum);
                         Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, this._maximum);
                     }
                     }
                     else {      // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.
                     else {      // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.
-                        this._minimum.copyFrom(this.mesh._boundingInfo.boundingBox.minimum);
-                        this._maximum.copyFrom(this.mesh._boundingInfo.boundingBox.maximum);
+                        if (this.mesh._boundingInfo) {
+                            this._minimum.copyFrom(this.mesh._boundingInfo.boundingBox.minimum);
+                            this._maximum.copyFrom(this.mesh._boundingInfo.boundingBox.maximum);
+                        }
                     }
                     }
                 }
                 }
     
     
@@ -793,7 +795,7 @@
                                 this._normals32[idx + 2] = this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;                          
                                 this._normals32[idx + 2] = this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;                          
                             }
                             }
     
     
-                            if (this._computeParticleColor) {
+                            if (this._computeParticleColor && this._particle.color) {
                                 this._colors32[colidx] = this._particle.color.r;
                                 this._colors32[colidx] = this._particle.color.r;
                                 this._colors32[colidx + 1] = this._particle.color.g;
                                 this._colors32[colidx + 1] = this._particle.color.g;
                                 this._colors32[colidx + 2] = this._particle.color.b;
                                 this._colors32[colidx + 2] = this._particle.color.b;
@@ -820,7 +822,7 @@
                             this._normals32[idx] = 0.0;
                             this._normals32[idx] = 0.0;
                             this._normals32[idx + 1] = 0.0;
                             this._normals32[idx + 1] = 0.0;
                             this._normals32[idx + 2] = 0.0;
                             this._normals32[idx + 2] = 0.0;
-                            if (this._computeParticleColor) {
+                            if (this._computeParticleColor && this._particle.color) {
                                 this._colors32[colidx] = this._particle.color.r;
                                 this._colors32[colidx] = this._particle.color.r;
                                 this._colors32[colidx + 1] = this._particle.color.g;
                                 this._colors32[colidx + 1] = this._particle.color.g;
                                 this._colors32[colidx + 2] = this._particle.color.b;
                                 this._colors32[colidx + 2] = this._particle.color.b;
@@ -964,17 +966,17 @@
                 this.mesh.dispose();
                 this.mesh.dispose();
                 this.vars = null;
                 this.vars = null;
                 // drop references to internal big arrays for the GC
                 // drop references to internal big arrays for the GC
-                this._positions = null;
-                this._indices = null;
-                this._normals = null;
-                this._uvs = null;
-                this._colors = null;
-                this._positions32 = null;
-                this._normals32 = null;
-                this._fixedNormal32 = null;
-                this._uvs32 = null;
-                this._colors32 = null;
-                this.pickedParticles = null;
+                (<any>this._positions) = null;
+                (<any>this._indices) = null;
+                (<any>this._normals) = null;
+                (<any>this._uvs) = null;
+                (<any>this._colors) = null;
+                (<any>this._positions32) = null;
+                (<any>this._normals32) = null;
+                (<any>this._fixedNormal32) = null;
+                (<any>this._uvs32) = null;
+                (<any>this._colors32) = null;
+                (<any>this.pickedParticles) = null;
             }
             }
     
     
             /**
             /**
@@ -1021,7 +1023,12 @@
             */
             */
             public set isVisibilityBoxLocked(val: boolean) {
             public set isVisibilityBoxLocked(val: boolean) {
                 this._isVisibilityBoxLocked = val;
                 this._isVisibilityBoxLocked = val;
-                this.mesh.getBoundingInfo().isLocked = val;
+
+                let boundingInfo = this.mesh.getBoundingInfo();
+
+                if (boundingInfo) {
+                    boundingInfo.isLocked = val;
+                }
             }
             }
     
     
             public get isVisibilityBoxLocked(): boolean {
             public get isVisibilityBoxLocked(): boolean {

+ 39 - 21
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -112,9 +112,14 @@
 
 
         private _processChildMeshes(mainImpostor: PhysicsImpostor) {
         private _processChildMeshes(mainImpostor: PhysicsImpostor) {
             var meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes(true) : [];
             var meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes(true) : [];
-            let currentRotation: Quaternion = mainImpostor.object.rotationQuaternion;
+            let currentRotation: Nullable<Quaternion> = mainImpostor.object.rotationQuaternion;
             if (meshChildren.length) {
             if (meshChildren.length) {
                 var processMesh = (localPosition: Vector3, mesh: AbstractMesh) => {
                 var processMesh = (localPosition: Vector3, mesh: AbstractMesh) => {
+
+                    if (!currentRotation || ! mesh.rotationQuaternion) {
+                        return;
+                    }
+
                     var childImpostor = mesh.getPhysicsImpostor();
                     var childImpostor = mesh.getPhysicsImpostor();
                     if (childImpostor) {
                     if (childImpostor) {
                         var parent = childImpostor.parent;
                         var parent = childImpostor.parent;
@@ -275,19 +280,18 @@
         }
         }
 
 
         private _createHeightmap(object: IPhysicsEnabledObject, pointDepth?: number) {
         private _createHeightmap(object: IPhysicsEnabledObject, pointDepth?: number) {
-            var pos = object.getVerticesData(VertexBuffer.PositionKind);
+            var pos = <FloatArray>(object.getVerticesData(VertexBuffer.PositionKind));
             var matrix = new Array<Array<any>>();
             var matrix = new Array<Array<any>>();
 
 
             //For now pointDepth will not be used and will be automatically calculated.
             //For now pointDepth will not be used and will be automatically calculated.
             //Future reference - try and find the best place to add a reference to the pointDepth variable.
             //Future reference - try and find the best place to add a reference to the pointDepth variable.
             var arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);
             var arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);
-
-            var dim = Math.min(object.getBoundingInfo().boundingBox.extendSizeWorld.x, object.getBoundingInfo().boundingBox.extendSizeWorld.z);
-
+            let boundingInfo = <BoundingInfo>(object.getBoundingInfo());
+            var dim = Math.min(boundingInfo.boundingBox.extendSizeWorld.x, boundingInfo.boundingBox.extendSizeWorld.z);
+            var minY = boundingInfo.boundingBox.extendSizeWorld.y;
+            
             var elementSize = dim * 2 / arraySize;
             var elementSize = dim * 2 / arraySize;
 
 
-            var minY = object.getBoundingInfo().boundingBox.extendSizeWorld.y;
-
             for (var i = 0; i < pos.length; i = i + 3) {
             for (var i = 0; i < pos.length; i = i + 3) {
                 var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
                 var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
                 var z = Math.round(((pos[i + 2]) / elementSize - arraySize / 2) * -1);
                 var z = Math.round(((pos[i + 2]) / elementSize - arraySize / 2) * -1);
@@ -349,6 +353,11 @@
             this._tmpDeltaPosition.copyFrom(object.position.subtract(center));
             this._tmpDeltaPosition.copyFrom(object.position.subtract(center));
             this._tmpPosition.copyFrom(center);
             this._tmpPosition.copyFrom(center);
             var quaternion = object.rotationQuaternion;
             var quaternion = object.rotationQuaternion;
+
+            if (!quaternion) {
+                return;
+            }
+
             //is shape is a plane or a heightmap, it must be rotated 90 degs in the X axis.
             //is shape is a plane or a heightmap, it must be rotated 90 degs in the X axis.
             if (impostor.type === PhysicsImpostor.PlaneImpostor || impostor.type === PhysicsImpostor.HeightmapImpostor || impostor.type === PhysicsImpostor.CylinderImpostor) {
             if (impostor.type === PhysicsImpostor.PlaneImpostor || impostor.type === PhysicsImpostor.HeightmapImpostor || impostor.type === PhysicsImpostor.CylinderImpostor) {
                 //-90 DEG in X, precalculated
                 //-90 DEG in X, precalculated
@@ -361,6 +370,7 @@
             //If it is a heightfield, if should be centered.
             //If it is a heightfield, if should be centered.
             if (impostor.type === PhysicsImpostor.HeightmapImpostor) {
             if (impostor.type === PhysicsImpostor.HeightmapImpostor) {
                 var mesh = <AbstractMesh>(<any>object);
                 var mesh = <AbstractMesh>(<any>object);
+                let boundingInfo = <BoundingInfo>mesh.getBoundingInfo();
                 //calculate the correct body position:
                 //calculate the correct body position:
                 var rotationQuaternion = mesh.rotationQuaternion;
                 var rotationQuaternion = mesh.rotationQuaternion;
                 mesh.rotationQuaternion = this._tmpUnityRotation;
                 mesh.rotationQuaternion = this._tmpUnityRotation;
@@ -375,17 +385,17 @@
                 mesh.rotationQuaternion = rotationQuaternion;
                 mesh.rotationQuaternion = rotationQuaternion;
 
 
                 //calculate the new center using a pivot (since this.BJSCANNON.js doesn't center height maps)
                 //calculate the new center using a pivot (since this.BJSCANNON.js doesn't center height maps)
-                var p = Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSizeWorld.x, 0, -mesh.getBoundingInfo().boundingBox.extendSizeWorld.z);
+                var p = Matrix.Translation(boundingInfo.boundingBox.extendSizeWorld.x, 0, -boundingInfo.boundingBox.extendSizeWorld.z);
                 mesh.setPivotMatrix(p);
                 mesh.setPivotMatrix(p);
                 mesh.computeWorldMatrix(true);
                 mesh.computeWorldMatrix(true);
 
 
                 //calculate the translation
                 //calculate the translation
-                var translation = mesh.getBoundingInfo().boundingBox.centerWorld.subtract(center).subtract(mesh.position).negate();
+                var translation = boundingInfo.boundingBox.centerWorld.subtract(center).subtract(mesh.position).negate();
 
 
-                this._tmpPosition.copyFromFloats(translation.x, translation.y - mesh.getBoundingInfo().boundingBox.extendSizeWorld.y, translation.z);
+                this._tmpPosition.copyFromFloats(translation.x, translation.y - boundingInfo.boundingBox.extendSizeWorld.y, translation.z);
                 //add it inverted to the delta
                 //add it inverted to the delta
-                this._tmpDeltaPosition.copyFrom(mesh.getBoundingInfo().boundingBox.centerWorld.subtract(c));
-                this._tmpDeltaPosition.y += mesh.getBoundingInfo().boundingBox.extendSizeWorld.y;
+                this._tmpDeltaPosition.copyFrom(boundingInfo.boundingBox.centerWorld.subtract(c));
+                this._tmpDeltaPosition.y += boundingInfo.boundingBox.extendSizeWorld.y;
 
 
                 mesh.setPivotMatrix(oldPivot);
                 mesh.setPivotMatrix(oldPivot);
                 mesh.computeWorldMatrix(true);
                 mesh.computeWorldMatrix(true);
@@ -402,7 +412,9 @@
 
 
         public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {
         public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {
             impostor.object.position.copyFrom(impostor.physicsBody.position);
             impostor.object.position.copyFrom(impostor.physicsBody.position);
-            impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.quaternion);
+            if (impostor.object.rotationQuaternion) {
+                impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.quaternion);
+            }
         }
         }
 
 
         public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
         public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
@@ -422,14 +434,18 @@
             impostor.physicsBody.angularVelocity.copy(velocity);
             impostor.physicsBody.angularVelocity.copy(velocity);
         }
         }
 
 
-        public getLinearVelocity(impostor: PhysicsImpostor): Vector3 {
+        public getLinearVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {
             var v = impostor.physicsBody.velocity;
             var v = impostor.physicsBody.velocity;
-            if (!v) return null;
+            if (!v) {
+                return null;
+            }
             return new Vector3(v.x, v.y, v.z)
             return new Vector3(v.x, v.y, v.z)
         }
         }
-        public getAngularVelocity(impostor: PhysicsImpostor): Vector3 {
+        public getAngularVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {
             var v = impostor.physicsBody.angularVelocity;
             var v = impostor.physicsBody.angularVelocity;
-            if (!v) return null;
+            if (!v) {
+                return null;
+            }
             return new Vector3(v.x, v.y, v.z)
             return new Vector3(v.x, v.y, v.z)
         }
         }
 
 
@@ -504,10 +520,12 @@
             mesh.position.y = body.position.y;
             mesh.position.y = body.position.y;
             mesh.position.z = body.position.z;
             mesh.position.z = body.position.z;
 
 
-            mesh.rotationQuaternion.x = body.quaternion.x;
-            mesh.rotationQuaternion.y = body.quaternion.y;
-            mesh.rotationQuaternion.z = body.quaternion.z;
-            mesh.rotationQuaternion.w = body.quaternion.w;
+            if (mesh.rotationQuaternion) {
+                mesh.rotationQuaternion.x = body.quaternion.x;
+                mesh.rotationQuaternion.y = body.quaternion.y;
+                mesh.rotationQuaternion.z = body.quaternion.z;
+                mesh.rotationQuaternion.w = body.quaternion.w;
+            }
         }
         }
 
 
         public getRadius(impostor: PhysicsImpostor): number {
         public getRadius(impostor: PhysicsImpostor): number {

+ 22 - 11
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -120,7 +120,9 @@ module BABYLON {
                 }
                 }
 
 
                 impostors.forEach((i) => {
                 impostors.forEach((i) => {
-
+                    if (!impostor.object.rotationQuaternion) {
+                        return;
+                    }
                     //get the correct bounding box
                     //get the correct bounding box
                     var oldQuaternion = i.object.rotationQuaternion;
                     var oldQuaternion = i.object.rotationQuaternion;
                     var rot = new this.BJSOIMO.Euler().setFromQuaternion({
                     var rot = new this.BJSOIMO.Euler().setFromQuaternion({
@@ -316,8 +318,11 @@ module BABYLON {
                     impostor.object.position.copyFrom(impostor.physicsBody.getPosition());
                     impostor.object.position.copyFrom(impostor.physicsBody.getPosition());
 
 
                 }
                 }
-                impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.getQuaternion());
-                impostor.object.rotationQuaternion.normalize();
+
+                if (impostor.object.rotationQuaternion) {
+                    impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.getQuaternion());
+                    impostor.object.rotationQuaternion.normalize();
+                }
             }
             }
         }
         }
 
 
@@ -347,14 +352,18 @@ module BABYLON {
             impostor.physicsBody.angularVelocity.init(velocity.x, velocity.y, velocity.z);
             impostor.physicsBody.angularVelocity.init(velocity.x, velocity.y, velocity.z);
         }
         }
 
 
-        public getLinearVelocity(impostor: PhysicsImpostor): Vector3 {
+        public getLinearVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {
             var v = impostor.physicsBody.linearVelocity;
             var v = impostor.physicsBody.linearVelocity;
-            if (!v) return null;
+            if (!v) {
+                return null;
+            }
             return new Vector3(v.x, v.y, v.z)
             return new Vector3(v.x, v.y, v.z)
         }
         }
-        public getAngularVelocity(impostor: PhysicsImpostor): Vector3 {
+        public getAngularVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {
             var v = impostor.physicsBody.angularVelocity;
             var v = impostor.physicsBody.angularVelocity;
-            if (!v) return null;
+            if (!v) {
+                return null;
+            }
             return new Vector3(v.x, v.y, v.z)
             return new Vector3(v.x, v.y, v.z)
         }
         }
 
 
@@ -424,10 +433,12 @@ module BABYLON {
             mesh.position.y = body.position.y;
             mesh.position.y = body.position.y;
             mesh.position.z = body.position.z;
             mesh.position.z = body.position.z;
 
 
-            mesh.rotationQuaternion.x = body.orientation.x;
-            mesh.rotationQuaternion.y = body.orientation.y;
-            mesh.rotationQuaternion.z = body.orientation.z;
-            mesh.rotationQuaternion.w = body.orientation.s;
+            if (mesh.rotationQuaternion) {
+                mesh.rotationQuaternion.x = body.orientation.x;
+                mesh.rotationQuaternion.y = body.orientation.y;
+                mesh.rotationQuaternion.z = body.orientation.z;
+                mesh.rotationQuaternion.w = body.orientation.s;
+            }
         }
         }
 
 
         public getRadius(impostor: PhysicsImpostor): number {
         public getRadius(impostor: PhysicsImpostor): number {

+ 4 - 4
src/Physics/babylon.physicsEngine.ts

@@ -184,10 +184,10 @@
         isSupported(): boolean;
         isSupported(): boolean;
         setTransformationFromPhysicsBody(impostor: PhysicsImpostor): void;
         setTransformationFromPhysicsBody(impostor: PhysicsImpostor): void;
         setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion): void;
         setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion): void;
-        setLinearVelocity(impostor: PhysicsImpostor, velocity: Vector3): void;
-        setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3): void;
-        getLinearVelocity(impostor: PhysicsImpostor) : Vector3;
-        getAngularVelocity(impostor: PhysicsImpostor) : Vector3;
+        setLinearVelocity(impostor: PhysicsImpostor, velocity: Nullable<Vector3>): void;
+        setAngularVelocity(impostor: PhysicsImpostor, velocity: Nullable<Vector3>): void;
+        getLinearVelocity(impostor: PhysicsImpostor): Nullable<Vector3>;
+        getAngularVelocity(impostor: PhysicsImpostor): Nullable<Vector3>;
         setBodyMass(impostor: PhysicsImpostor, mass: number): void;
         setBodyMass(impostor: PhysicsImpostor, mass: number): void;
         getBodyMass(impostor: PhysicsImpostor): number;
         getBodyMass(impostor: PhysicsImpostor): number;
         getBodyFriction(impostor: PhysicsImpostor): number;
         getBodyFriction(impostor: PhysicsImpostor): number;

+ 5 - 5
src/Physics/babylon.physicsImpostor.ts

@@ -17,7 +17,7 @@ module BABYLON {
         computeWorldMatrix?(force: boolean): void;
         computeWorldMatrix?(force: boolean): void;
         getWorldMatrix?(): Matrix;
         getWorldMatrix?(): Matrix;
         getChildMeshes?(directDescendantsOnly?: boolean): Array<AbstractMesh>;
         getChildMeshes?(directDescendantsOnly?: boolean): Array<AbstractMesh>;
-        getVerticesData?(kind: string): Nullable<Array<number> | Float32Array>;
+        getVerticesData(kind: string): Nullable<Array<number> | Float32Array>;
         getIndices?(): Nullable<IndicesArray>;
         getIndices?(): Nullable<IndicesArray>;
         getScene?(): Scene;
         getScene?(): Scene;
         getAbsolutePosition(): Vector3;
         getAbsolutePosition(): Vector3;
@@ -284,21 +284,21 @@ module BABYLON {
             }
             }
         }
         }
 
 
-        public getLinearVelocity(): Vector3 {
+        public getLinearVelocity(): Nullable<Vector3> {
             return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this) : Vector3.Zero();
             return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this) : Vector3.Zero();
         }
         }
 
 
-        public setLinearVelocity(velocity: Vector3) {
+        public setLinearVelocity(velocity: Nullable<Vector3>) {
             if (this._physicsEngine) {
             if (this._physicsEngine) {
                 this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
                 this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
             }
             }
         }
         }
 
 
-        public getAngularVelocity(): Vector3 {
+        public getAngularVelocity(): Nullable<Vector3> {
             return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this) : Vector3.Zero();
             return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this) : Vector3.Zero();
         }
         }
 
 
-        public setAngularVelocity(velocity: Vector3) {
+        public setAngularVelocity(velocity: Nullable<Vector3>) {
             if (this._physicsEngine) {
             if (this._physicsEngine) {
                 this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
                 this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
             }
             }

+ 3 - 3
src/Physics/babylon.physicsJoint.ts

@@ -101,7 +101,7 @@ module BABYLON {
          * @param {number} maxForce max force for this motor.
          * @param {number} maxForce max force for this motor.
          */
          */
         public setMotor(force?: number, maxForce?: number) {
         public setMotor(force?: number, maxForce?: number) {
-            this._physicsPlugin.setMotor(this, force, maxForce);
+            this._physicsPlugin.setMotor(this, force || 0, maxForce);
         }
         }
         
         
         /**
         /**
@@ -129,7 +129,7 @@ module BABYLON {
          * @param {number} maxForce max force for this motor.
          * @param {number} maxForce max force for this motor.
          */
          */
         public setMotor(force?: number, maxForce?: number) {
         public setMotor(force?: number, maxForce?: number) {
-            this._physicsPlugin.setMotor(this, force, maxForce);
+            this._physicsPlugin.setMotor(this, force || 0, maxForce);
         }
         }
         
         
         /**
         /**
@@ -158,7 +158,7 @@ module BABYLON {
          * @param {motorIndex} the motor's index, 0 or 1.
          * @param {motorIndex} the motor's index, 0 or 1.
          */
          */
         public setMotor(force?: number, maxForce?: number, motorIndex: number = 0) {
         public setMotor(force?: number, maxForce?: number, motorIndex: number = 0) {
-            this._physicsPlugin.setMotor(this, force, maxForce, motorIndex);
+            this._physicsPlugin.setMotor(this, force || 0, maxForce, motorIndex);
         }
         }
         
         
         /**
         /**

+ 10 - 10
src/PostProcess/RenderPipeline/Pipelines/babylon.defaultRenderingPipeline.ts

@@ -193,7 +193,7 @@
 				this.blurX.alwaysForcePOT = true;
 				this.blurX.alwaysForcePOT = true;
 				this.blurX.autoClear = false;
 				this.blurX.autoClear = false;
 				this.blurX.onActivateObservable.add(() => {
 				this.blurX.onActivateObservable.add(() => {
-					let dw = this.blurX.width / engine.getRenderingCanvas().width;
+					let dw = this.blurX.width / engine.getRenderWidth(true);
 					this.blurX.kernel = this.bloomKernel * dw;
 					this.blurX.kernel = this.bloomKernel * dw;
 				});
 				});
 
 
@@ -202,7 +202,7 @@
 				this.blurY.alwaysForcePOT = true;
 				this.blurY.alwaysForcePOT = true;
 				this.blurY.autoClear = false;
 				this.blurY.autoClear = false;
 				this.blurY.onActivateObservable.add(() => {
 				this.blurY.onActivateObservable.add(() => {
-					let dh = this.blurY.height / engine.getRenderingCanvas().height;
+					let dh = this.blurY.height / engine.getRenderHeight(true);
 					this.blurY.kernel = this.bloomKernel * dh;
 					this.blurY.kernel = this.bloomKernel * dh;
 				});				
 				});				
 
 
@@ -302,14 +302,14 @@
                 }                
                 }                
             }
             }
 
 
-            this.pass = null;
-            this.highlights = null;
-            this.blurX = null;
-            this.blurY = null;
-            this.copyBack = null;
-            this.imageProcessing = null;
-            this.fxaa = null;
-            this.finalMerge = null;
+            (<any>this.pass) = null;
+            (<any>this.highlights) = null;
+            (<any>this.blurX) = null;
+            (<any>this.blurY) = null;
+            (<any>this.copyBack) = null;
+            (<any>this.imageProcessing) = null;
+            (<any>this.fxaa) = null;
+            (<any>this.finalMerge) = null;
         }
         }
 
 
         // Dispose
         // Dispose

+ 13 - 11
src/PostProcess/RenderPipeline/Pipelines/babylon.lensRenderingPipeline.ts

@@ -167,9 +167,9 @@ module BABYLON {
         public dispose(disableDepthRender: boolean = false): void {
         public dispose(disableDepthRender: boolean = false): void {
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
 
 
-            this._chromaticAberrationPostProcess = undefined;
-            this._highlightsPostProcess = undefined;
-            this._depthOfFieldPostProcess = undefined;
+            (<any>this._chromaticAberrationPostProcess) = null;
+            (<any>this._highlightsPostProcess) = null;
+            (<any>this._depthOfFieldPostProcess) = null;
 
 
             this._grainTexture.dispose();
             this._grainTexture.dispose();
 
 
@@ -187,8 +187,8 @@ module BABYLON {
 
 
             this._chromaticAberrationPostProcess.onApply = (effect: Effect) => {
             this._chromaticAberrationPostProcess.onApply = (effect: Effect) => {
                 effect.setFloat('chromatic_aberration', this._chromaticAberration);
                 effect.setFloat('chromatic_aberration', this._chromaticAberration);
-                effect.setFloat('screen_width', this._scene.getEngine().getRenderingCanvas().width);
-                effect.setFloat('screen_height', this._scene.getEngine().getRenderingCanvas().height);
+                effect.setFloat('screen_width', this._scene.getEngine().getRenderWidth());
+                effect.setFloat('screen_height', this._scene.getEngine().getRenderHeight());
             };
             };
         }
         }
 
 
@@ -205,8 +205,8 @@ module BABYLON {
                 effect.setFloat('gain', this._highlightsGain);
                 effect.setFloat('gain', this._highlightsGain);
                 effect.setFloat('threshold', this._highlightsThreshold);
                 effect.setFloat('threshold', this._highlightsThreshold);
                 effect.setTextureFromPostProcess("textureSampler", this._chromaticAberrationPostProcess);
                 effect.setTextureFromPostProcess("textureSampler", this._chromaticAberrationPostProcess);
-                effect.setFloat('screen_width', this._scene.getEngine().getRenderingCanvas().width);
-                effect.setFloat('screen_height', this._scene.getEngine().getRenderingCanvas().height);
+                effect.setFloat('screen_width', this._scene.getEngine().getRenderWidth());
+                effect.setFloat('screen_height', this._scene.getEngine().getRenderHeight());
             };
             };
         }
         }
 
 
@@ -231,8 +231,8 @@ module BABYLON {
                 effect.setFloat('grain_amount', this._grainAmount);
                 effect.setFloat('grain_amount', this._grainAmount);
                 effect.setBool('blur_noise', this._blurNoise);
                 effect.setBool('blur_noise', this._blurNoise);
 
 
-                effect.setFloat('screen_width', this._scene.getEngine().getRenderingCanvas().width);
-                effect.setFloat('screen_height', this._scene.getEngine().getRenderingCanvas().height);
+                effect.setFloat('screen_width', this._scene.getEngine().getRenderWidth());
+                effect.setFloat('screen_height', this._scene.getEngine().getRenderHeight());
 
 
                 effect.setFloat('distortion', this._distortion);
                 effect.setFloat('distortion', this._distortion);
 
 
@@ -245,8 +245,10 @@ module BABYLON {
 
 
                 effect.setBool('highlights', (this._highlightsGain !== -1));
                 effect.setBool('highlights', (this._highlightsGain !== -1));
 
 
-                effect.setFloat('near', this._scene.activeCamera.minZ);
-                effect.setFloat('far', this._scene.activeCamera.maxZ);
+                if (this._scene.activeCamera) {
+                    effect.setFloat('near', this._scene.activeCamera.minZ);
+                    effect.setFloat('far', this._scene.activeCamera.maxZ);
+                }
             };
             };
         }
         }
 
 

+ 18 - 2
src/PostProcess/RenderPipeline/Pipelines/babylon.ssao2RenderingPipeline.ts

@@ -120,6 +120,9 @@
         */
         */
         public static get IsSupported(): boolean {
         public static get IsSupported(): boolean {
             var engine = Engine.LastCreatedEngine;
             var engine = Engine.LastCreatedEngine;
+            if (!engine) {
+                return false;
+            }
             return engine.getCaps().drawBuffersExtension;
             return engine.getCaps().drawBuffersExtension;
         }
         }
 
 
@@ -164,9 +167,10 @@
             };
             };
 
 
             // Set up assets
             // Set up assets
+            let geometryBufferRenderer = <GeometryBufferRenderer>scene.enableGeometryBufferRenderer();
             this._createRandomTexture();
             this._createRandomTexture();
-            this._depthTexture = scene.enableGeometryBufferRenderer().getGBuffer().textures[0]; 
-            this._normalTexture = scene.enableGeometryBufferRenderer().getGBuffer().textures[1];
+            this._depthTexture = geometryBufferRenderer.getGBuffer().textures[0]; 
+            this._normalTexture = geometryBufferRenderer.getGBuffer().textures[1];
 
 
             this._originalColorPostProcess = new PassPostProcess("SSAOOriginalSceneColor", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
             this._originalColorPostProcess = new PassPostProcess("SSAOOriginalSceneColor", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
             this._createSSAOPostProcess(1.0);
             this._createSSAOPostProcess(1.0);
@@ -224,6 +228,10 @@
 
 
             this._blurHPostProcess = new PostProcess("BlurH", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], ssaoRatio, null, Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_H\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
             this._blurHPostProcess = new PostProcess("BlurH", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], ssaoRatio, null, Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_H\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
             this._blurHPostProcess.onApply = (effect: Effect) => {
             this._blurHPostProcess.onApply = (effect: Effect) => {
+                if (!this._scene.activeCamera) {
+                    return;
+                }
+
                 effect.setFloat("outSize", this._ssaoCombinePostProcess.width);
                 effect.setFloat("outSize", this._ssaoCombinePostProcess.width);
                 effect.setFloat("near", this._scene.activeCamera.minZ);
                 effect.setFloat("near", this._scene.activeCamera.minZ);
                 effect.setFloat("far", this._scene.activeCamera.maxZ);
                 effect.setFloat("far", this._scene.activeCamera.maxZ);
@@ -237,6 +245,10 @@
 
 
             this._blurVPostProcess = new PostProcess("BlurV", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], blurRatio, null, Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_V\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
             this._blurVPostProcess = new PostProcess("BlurV", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], blurRatio, null, Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_V\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
             this._blurVPostProcess.onApply = (effect: Effect) => {
             this._blurVPostProcess.onApply = (effect: Effect) => {
+                if (!this._scene.activeCamera) {
+                    return;
+                }
+
                 effect.setFloat("outSize", this._ssaoCombinePostProcess.height);
                 effect.setFloat("outSize", this._ssaoCombinePostProcess.height);
                 effect.setFloat("near", this._scene.activeCamera.minZ);
                 effect.setFloat("near", this._scene.activeCamera.minZ);
                 effect.setFloat("far", this._scene.activeCamera.maxZ);
                 effect.setFloat("far", this._scene.activeCamera.maxZ);
@@ -306,6 +318,10 @@
                     effect.setFloat("randTextureTiles", 4.0);
                     effect.setFloat("randTextureTiles", 4.0);
                 }
                 }
 
 
+                if (!this._scene.activeCamera) {
+                    return;
+                }
+
                 effect.setFloat("samplesFactor", 1 / this.samples);
                 effect.setFloat("samplesFactor", 1 / this.samples);
                 effect.setFloat("totalStrength", this.totalStrength);
                 effect.setFloat("totalStrength", this.totalStrength);
                 effect.setFloat2("texelSize", 1 / this._ssaoPostProcess.width, 1 / this._ssaoPostProcess.height);
                 effect.setFloat2("texelSize", 1 / this._ssaoPostProcess.width, 1 / this._ssaoPostProcess.height);

+ 58 - 45
src/PostProcess/RenderPipeline/Pipelines/babylon.standardRenderingPipeline.ts

@@ -4,33 +4,33 @@
         * Public members
         * Public members
         */
         */
         // Post-processes
         // Post-processes
-        public originalPostProcess: PostProcess;
-        public downSampleX4PostProcess: PostProcess = null;
-        public brightPassPostProcess: PostProcess = null;
+        public originalPostProcess: Nullable<PostProcess>;
+        public downSampleX4PostProcess: Nullable<PostProcess> = null;
+        public brightPassPostProcess: Nullable<PostProcess> = null;
         public blurHPostProcesses: PostProcess[] = [];
         public blurHPostProcesses: PostProcess[] = [];
         public blurVPostProcesses: PostProcess[] = [];
         public blurVPostProcesses: PostProcess[] = [];
-        public textureAdderPostProcess: PostProcess = null;
+        public textureAdderPostProcess: Nullable<PostProcess> = null;
 
 
-        public volumetricLightPostProcess: PostProcess = null;
-        public volumetricLightSmoothXPostProcess: BlurPostProcess = null;
-        public volumetricLightSmoothYPostProcess: BlurPostProcess = null;
-        public volumetricLightMergePostProces: PostProcess = null;
-        public volumetricLightFinalPostProcess: PostProcess = null;
+        public volumetricLightPostProcess: Nullable<PostProcess> = null;
+        public volumetricLightSmoothXPostProcess: Nullable<BlurPostProcess> = null;
+        public volumetricLightSmoothYPostProcess: Nullable<BlurPostProcess> = null;
+        public volumetricLightMergePostProces: Nullable<PostProcess> = null;
+        public volumetricLightFinalPostProcess: Nullable<PostProcess> = null;
 
 
-        public luminancePostProcess: PostProcess = null;
+        public luminancePostProcess: Nullable<PostProcess> = null;
         public luminanceDownSamplePostProcesses: PostProcess[] = [];
         public luminanceDownSamplePostProcesses: PostProcess[] = [];
-        public hdrPostProcess: PostProcess = null;
+        public hdrPostProcess: Nullable<PostProcess> = null;
 
 
-        public textureAdderFinalPostProcess: PostProcess = null;
-        public lensFlareFinalPostProcess: PostProcess = null;
-        public hdrFinalPostProcess: PostProcess = null;
+        public textureAdderFinalPostProcess: Nullable<PostProcess> = null;
+        public lensFlareFinalPostProcess: Nullable<PostProcess> = null;
+        public hdrFinalPostProcess: Nullable<PostProcess> = null;
 
 
-        public lensFlarePostProcess: PostProcess = null;
-        public lensFlareComposePostProcess: PostProcess = null;
+        public lensFlarePostProcess: Nullable<PostProcess> = null;
+        public lensFlareComposePostProcess: Nullable<PostProcess> = null;
 
 
-        public motionBlurPostProcess: PostProcess = null;
+        public motionBlurPostProcess: Nullable<PostProcess> = null;
 
 
-        public depthOfFieldPostProcess: PostProcess = null;
+        public depthOfFieldPostProcess: Nullable<PostProcess> = null;
 
 
         // Values
         // Values
         @serialize()
         @serialize()
@@ -44,7 +44,7 @@
         @serialize()
         @serialize()
         public exposure: number = 1.0;
         public exposure: number = 1.0;
         @serializeAsTexture("lensTexture")
         @serializeAsTexture("lensTexture")
-        public lensTexture: Texture = null;
+        public lensTexture: Nullable<Texture> = null;
 
 
         @serialize()
         @serialize()
         public volumetricLightCoefficient: number = 0.2;
         public volumetricLightCoefficient: number = 0.2;
@@ -53,7 +53,7 @@
         @serialize()
         @serialize()
         public volumetricLightBlurScale: number = 64.0;
         public volumetricLightBlurScale: number = 64.0;
 
 
-        public sourceLight: SpotLight | DirectionalLight = null;
+        public sourceLight: Nullable<SpotLight | DirectionalLight> = null;
 
 
         @serialize()
         @serialize()
         public hdrMinimumLuminance: number = 1.0;
         public hdrMinimumLuminance: number = 1.0;
@@ -63,7 +63,7 @@
         public hdrIncreaseRate: number = 0.5;
         public hdrIncreaseRate: number = 0.5;
 
 
         @serializeAsTexture("lensColorTexture")
         @serializeAsTexture("lensColorTexture")
-        public lensColorTexture: Texture = null;
+        public lensColorTexture: Nullable<Texture> = null;
         @serialize()
         @serialize()
         public lensFlareStrength: number = 20.0;
         public lensFlareStrength: number = 20.0;
         @serialize()
         @serialize()
@@ -73,9 +73,9 @@
         @serialize()
         @serialize()
         public lensFlareDistortionStrength: number = 16.0;
         public lensFlareDistortionStrength: number = 16.0;
         @serializeAsTexture("lensStarTexture")
         @serializeAsTexture("lensStarTexture")
-        public lensStarTexture: Texture = null;
+        public lensStarTexture: Nullable<Texture> = null;
         @serializeAsTexture("lensFlareDirtTexture")
         @serializeAsTexture("lensFlareDirtTexture")
-        public lensFlareDirtTexture: Texture = null;
+        public lensFlareDirtTexture: Nullable<Texture> = null;
 
 
         @serialize()
         @serialize()
         public depthOfFieldDistance: number = 10.0;
         public depthOfFieldDistance: number = 10.0;
@@ -93,8 +93,8 @@
         * Private members
         * Private members
         */
         */
         private _scene: Scene;
         private _scene: Scene;
-        private _currentDepthOfFieldSource: PostProcess = null;
-        private _basePostProcess: PostProcess;
+        private _currentDepthOfFieldSource: Nullable<PostProcess> = null;
+        private _basePostProcess: Nullable<PostProcess>;
 
 
         private _hdrCurrentLuminance: number = 1.0;
         private _hdrCurrentLuminance: number = 1.0;
 
 
@@ -238,7 +238,7 @@
          * @param {BABYLON.PostProcess} originalPostProcess - the custom original color post-process. Must be "reusable". Can be null.
          * @param {BABYLON.PostProcess} originalPostProcess - the custom original color post-process. Must be "reusable". Can be null.
          * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to
          * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to
          */
          */
-        constructor(name: string, scene: Scene, ratio: number, originalPostProcess: PostProcess = null, cameras?: Camera[]) {
+        constructor(name: string, scene: Scene, ratio: number, originalPostProcess: Nullable<PostProcess> = null, cameras?: Camera[]) {
             super(scene.getEngine(), name);
             super(scene.getEngine(), name);
             this._cameras = cameras || [];
             this._cameras = cameras || [];
 
 
@@ -350,10 +350,14 @@
 
 
             this.downSampleX4PostProcess.onApply = (effect: Effect) => {
             this.downSampleX4PostProcess.onApply = (effect: Effect) => {
                 var id = 0;
                 var id = 0;
+                let width = (<PostProcess>this.downSampleX4PostProcess).width;
+                let height = (<PostProcess>this.downSampleX4PostProcess).height;
+
+
                 for (var i = -2; i < 2; i++) {
                 for (var i = -2; i < 2; i++) {
                     for (var j = -2; j < 2; j++) {
                     for (var j = -2; j < 2; j++) {
-                        downSampleX4Offsets[id] = (i + 0.5) * (1.0 / this.downSampleX4PostProcess.width);
-                        downSampleX4Offsets[id + 1] = (j + 0.5) * (1.0 / this.downSampleX4PostProcess.height);
+                        downSampleX4Offsets[id] = (i + 0.5) * (1.0 / width);
+                        downSampleX4Offsets[id + 1] = (j + 0.5) * (1.0 / height);
                         id += 2;
                         id += 2;
                     }
                     }
                 }
                 }
@@ -371,8 +375,8 @@
             this.brightPassPostProcess = new PostProcess("HDRBrightPass", "standard", ["dsOffsets", "brightThreshold"], [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define BRIGHT_PASS", Engine.TEXTURETYPE_UNSIGNED_INT);
             this.brightPassPostProcess = new PostProcess("HDRBrightPass", "standard", ["dsOffsets", "brightThreshold"], [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define BRIGHT_PASS", Engine.TEXTURETYPE_UNSIGNED_INT);
 
 
             this.brightPassPostProcess.onApply = (effect: Effect) => {
             this.brightPassPostProcess.onApply = (effect: Effect) => {
-                var sU = (1.0 / this.brightPassPostProcess.width);
-                var sV = (1.0 / this.brightPassPostProcess.height);
+                var sU = (1.0 / (<PostProcess>this.brightPassPostProcess).width);
+                var sV = (1.0 / (<PostProcess>this.brightPassPostProcess).height);
 
 
                 brightOffsets[0] = -0.5 * sU;
                 brightOffsets[0] = -0.5 * sU;
                 brightOffsets[1] = 0.5 * sV;
                 brightOffsets[1] = 0.5 * sV;
@@ -399,12 +403,12 @@
             var blurY = new BlurPostProcess("HDRBlurV" + "_" + indice, new Vector2(0, 1), (<any>this)[blurWidthKey], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, Engine.TEXTURETYPE_UNSIGNED_INT);
             var blurY = new BlurPostProcess("HDRBlurV" + "_" + indice, new Vector2(0, 1), (<any>this)[blurWidthKey], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, Engine.TEXTURETYPE_UNSIGNED_INT);
 
 
             blurX.onActivateObservable.add(() => {
             blurX.onActivateObservable.add(() => {
-                let dw = blurX.width / engine.getRenderingCanvas().width;
+                let dw = blurX.width / engine.getRenderWidth();
                 blurX.kernel = (<any>this)[blurWidthKey] * dw;
                 blurX.kernel = (<any>this)[blurWidthKey] * dw;
             });
             });
 
 
             blurY.onActivateObservable.add(() => {
             blurY.onActivateObservable.add(() => {
-                let dw = blurY.height / engine.getRenderingCanvas().height;
+                let dw = blurY.height / engine.getRenderHeight();
                 blurY.kernel = this.horizontalBlur ? 64 * dw : (<any>this)[blurWidthKey] * dw;
                 blurY.kernel = this.horizontalBlur ? 64 * dw : (<any>this)[blurWidthKey] * dw;
             });
             });
 
 
@@ -432,7 +436,7 @@
         }
         }
 
 
         private _createVolumetricLightPostProcess(scene: Scene, ratio: number): void {
         private _createVolumetricLightPostProcess(scene: Scene, ratio: number): void {
-            var geometryRenderer = scene.enableGeometryBufferRenderer();
+            var geometryRenderer = <GeometryBufferRenderer>scene.enableGeometryBufferRenderer();
             geometryRenderer.enablePosition = true;
             geometryRenderer.enablePosition = true;
 
 
             var geometry = geometryRenderer.getGBuffer();
             var geometry = geometryRenderer.getGBuffer();
@@ -450,7 +454,7 @@
             var depthValues = Vector2.Zero();
             var depthValues = Vector2.Zero();
 
 
             this.volumetricLightPostProcess.onApply = (effect: Effect) => {
             this.volumetricLightPostProcess.onApply = (effect: Effect) => {
-                if (this.sourceLight && this.sourceLight.getShadowGenerator()) {
+                if (this.sourceLight && this.sourceLight.getShadowGenerator() && this._scene.activeCamera) {
                     var generator = <ShadowGenerator>this.sourceLight.getShadowGenerator();
                     var generator = <ShadowGenerator>this.sourceLight.getShadowGenerator();
 
 
                     effect.setTexture("shadowMapSampler", generator.getShadowMap());
                     effect.setTexture("shadowMapSampler", generator.getShadowMap());
@@ -459,7 +463,7 @@
                     effect.setColor3("sunColor", this.sourceLight.diffuse);
                     effect.setColor3("sunColor", this.sourceLight.diffuse);
                     effect.setVector3("sunDirection", this.sourceLight.getShadowDirection());
                     effect.setVector3("sunDirection", this.sourceLight.getShadowDirection());
                     
                     
-                    effect.setVector3("cameraPosition", scene.activeCamera.globalPosition);
+                    effect.setVector3("cameraPosition", this._scene.activeCamera.globalPosition);
                     effect.setMatrix("shadowViewProjection", generator.getTransformMatrix());
                     effect.setMatrix("shadowViewProjection", generator.getTransformMatrix());
 
 
                     effect.setFloat("scatteringCoefficient", this.volumetricLightCoefficient);
                     effect.setFloat("scatteringCoefficient", this.volumetricLightCoefficient);
@@ -496,8 +500,8 @@
 
 
             var offsets: number[] = [];
             var offsets: number[] = [];
             this.luminancePostProcess.onApply = (effect: Effect) => {
             this.luminancePostProcess.onApply = (effect: Effect) => {
-                var sU = (1.0 / this.luminancePostProcess.width);
-                var sV = (1.0 / this.luminancePostProcess.height);
+                var sU = (1.0 / (<PostProcess>this.luminancePostProcess).width);
+                var sV = (1.0 / (<PostProcess>this.luminancePostProcess).height);
 
 
                 offsets[0] = -0.5 * sU;
                 offsets[0] = -0.5 * sU;
                 offsets[1] = 0.5 * sV;
                 offsets[1] = 0.5 * sV;
@@ -528,12 +532,16 @@
             }
             }
 
 
             // Create callbacks and add effects
             // Create callbacks and add effects
-            var lastLuminance = this.luminancePostProcess;
+            var lastLuminance: Nullable<PostProcess> = this.luminancePostProcess;
 
 
             this.luminanceDownSamplePostProcesses.forEach((pp, index) => {
             this.luminanceDownSamplePostProcesses.forEach((pp, index) => {
                 var downSampleOffsets = new Array<number>(18);
                 var downSampleOffsets = new Array<number>(18);
 
 
                 pp.onApply = (effect: Effect) => {
                 pp.onApply = (effect: Effect) => {
+                    if (!lastLuminance) {
+                        return;
+                    }
+
                     var id = 0;
                     var id = 0;
                     for (var x = -1; x < 2; x++) {
                     for (var x = -1; x < 2; x++) {
                         for (var y = -1; y < 2; y++) {
                         for (var y = -1; y < 2; y++) {
@@ -627,8 +635,8 @@
                 effect.setFloat("haloWidth", this.lensFlareHaloWidth);
                 effect.setFloat("haloWidth", this.lensFlareHaloWidth);
 
 
                 // Shift
                 // Shift
-                resolution.x = this.lensFlarePostProcess.width;
-                resolution.y = this.lensFlarePostProcess.height;
+                resolution.x = (<PostProcess>this.lensFlarePostProcess).width;
+                resolution.y = (<PostProcess>this.lensFlarePostProcess).height;
                 effect.setVector2("resolution", resolution);
                 effect.setVector2("resolution", resolution);
 
 
                 effect.setFloat("distortionStrength", this.lensFlareDistortionStrength);
                 effect.setFloat("distortionStrength", this.lensFlareDistortionStrength);
@@ -650,13 +658,17 @@
             );
             );
 
 
             this.lensFlareComposePostProcess.onApply = (effect: Effect) => {
             this.lensFlareComposePostProcess.onApply = (effect: Effect) => {
+                if (!this._scene.activeCamera) {
+                    return;
+                }
+
                 effect.setTextureFromPostProcess("otherSampler", this._currentDepthOfFieldSource);
                 effect.setTextureFromPostProcess("otherSampler", this._currentDepthOfFieldSource);
                 effect.setTexture("lensDirtSampler", this.lensFlareDirtTexture);
                 effect.setTexture("lensDirtSampler", this.lensFlareDirtTexture);
                 effect.setTexture("lensStarSampler", this.lensStarTexture);
                 effect.setTexture("lensStarSampler", this.lensStarTexture);
 
 
                 // Lens start rotation matrix
                 // Lens start rotation matrix
-                var camerax = this._scene.activeCamera.getViewMatrix().getRow(0);
-                var cameraz = this._scene.activeCamera.getViewMatrix().getRow(2);
+                var camerax = (<Vector4>this._scene.activeCamera.getViewMatrix().getRow(0));
+                var cameraz = (<Vector4>this._scene.activeCamera.getViewMatrix().getRow(2));
                 var camRot = Vector3.Dot(camerax.toVector3(), new Vector3(1.0, 0.0, 0.0)) + Vector3.Dot(cameraz.toVector3(), new Vector3(0.0, 0.0, 1.0));
                 var camRot = Vector3.Dot(camerax.toVector3(), new Vector3(1.0, 0.0, 0.0)) + Vector3.Dot(cameraz.toVector3(), new Vector3(0.0, 0.0, 1.0));
                 camRot *= 4.0;
                 camRot *= 4.0;
 
 
@@ -711,8 +723,8 @@
                 effect.setMatrix("prevViewProjection", prevViewProjection);
                 effect.setMatrix("prevViewProjection", prevViewProjection);
                 prevViewProjection = viewProjection;
                 prevViewProjection = viewProjection;
 
 
-                screenSize.x = this.motionBlurPostProcess.width;
-                screenSize.y = this.motionBlurPostProcess.height;
+                screenSize.x = (<PostProcess>this.motionBlurPostProcess).width;
+                screenSize.y = (<PostProcess>this.motionBlurPostProcess).height;
                 effect.setVector2("screenSize", screenSize);
                 effect.setVector2("screenSize", screenSize);
 
 
                 motionScale = scene.getEngine().getFps() / 60.0;
                 motionScale = scene.getEngine().getFps() / 60.0;
@@ -727,7 +739,8 @@
 
 
         private _getDepthTexture(): Texture {
         private _getDepthTexture(): Texture {
             if (this._scene.getEngine().getCaps().drawBuffersExtension) {
             if (this._scene.getEngine().getCaps().drawBuffersExtension) {
-                return this._scene.enableGeometryBufferRenderer().getGBuffer().textures[0];
+                let renderer = <GeometryBufferRenderer>this._scene.enableGeometryBufferRenderer();
+                return renderer.getGBuffer().textures[0];
             }
             }
 
 
             return this._scene.enableDepthRenderer().getDepthMap();
             return this._scene.enableDepthRenderer().getDepthMap();

+ 39 - 19
src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.ts

@@ -3,11 +3,11 @@ module BABYLON {
         private _engine: Engine;
         private _engine: Engine;
 
 
         private _postProcesses: any;
         private _postProcesses: any;
-        private _getPostProcess: () => PostProcess;
+        private _getPostProcess: () => Nullable<PostProcess>;
 
 
         private _singleInstance: boolean;
         private _singleInstance: boolean;
 
 
-        private _cameras: { [key:string]: Camera};
+        private _cameras: { [key:string]: Nullable<Camera>};
         private _indicesForCamera: { [key:string]: number[]};
         private _indicesForCamera: { [key:string]: number[]};
 
 
         private _renderPasses: any;
         private _renderPasses: any;
@@ -18,7 +18,7 @@ module BABYLON {
 
 
         public applyParameters: (postProcess: PostProcess) => void;
         public applyParameters: (postProcess: PostProcess) => void;
 
 
-        constructor(engine: Engine, name: string, getPostProcess: () => PostProcess, singleInstance?: boolean) {
+        constructor(engine: Engine, name: string, getPostProcess: () => Nullable<PostProcess>, singleInstance?: boolean) {
             this._engine = engine;
             this._engine = engine;
             this._name = name;
             this._name = name;
             this._singleInstance = singleInstance || true;
             this._singleInstance = singleInstance || true;
@@ -67,7 +67,7 @@ module BABYLON {
             this._linkParameters();
             this._linkParameters();
         }
         }
 
 
-        public getPass(passName: string): PostProcessRenderPass {
+        public getPass(passName: string): Nullable<PostProcessRenderPass> {
             for (var renderPassName in this._renderPasses) {
             for (var renderPassName in this._renderPasses) {
                 if (renderPassName === passName) {
                 if (renderPassName === passName) {
                     return this._renderPasses[passName];
                     return this._renderPasses[passName];
@@ -89,10 +89,14 @@ module BABYLON {
         public _attachCameras(cameras: any): void {
         public _attachCameras(cameras: any): void {
             var cameraKey;
             var cameraKey;
 
 
-            var _cam = Tools.MakeArray(cameras || this._cameras);
+            var cams = Tools.MakeArray(cameras || this._cameras);
 
 
-            for (var i = 0; i < _cam.length; i++) {
-                var camera = _cam[i];
+            if (!cams) {
+                return;
+            }
+
+            for (var i = 0; i < cams.length; i++) {
+                var camera = cams[i];
                 var cameraName = camera.name;
                 var cameraName = camera.name;
 
 
                 if (this._singleInstance) {
                 if (this._singleInstance) {
@@ -128,10 +132,14 @@ module BABYLON {
         public _detachCameras(cameras: Camera): void;
         public _detachCameras(cameras: Camera): void;
         public _detachCameras(cameras: Camera[]): void;
         public _detachCameras(cameras: Camera[]): void;
         public _detachCameras(cameras: any): void {
         public _detachCameras(cameras: any): void {
-            var _cam = Tools.MakeArray(cameras || this._cameras);
+            var cams = Tools.MakeArray(cameras || this._cameras);
 
 
-            for (var i = 0; i < _cam.length; i++) {
-                var camera: Camera = _cam[i];
+            if (!cams) {
+                return;
+            }
+
+            for (var i = 0; i < cams.length; i++) {
+                var camera: Camera = cams[i];
                 var cameraName: string = camera.name;
                 var cameraName: string = camera.name;
 
 
                 camera.detachPostProcess(this._postProcesses[this._singleInstance ? 0 : cameraName]);
                 camera.detachPostProcess(this._postProcesses[this._singleInstance ? 0 : cameraName]);
@@ -149,12 +157,16 @@ module BABYLON {
 
 
         // private
         // private
         public _enable(cameras: Camera): void;
         public _enable(cameras: Camera): void;
-        public _enable(cameras: Camera[]): void;
+        public _enable(cameras: Nullable<Camera[]>): void;
         public _enable(cameras: any): void {
         public _enable(cameras: any): void {
-            var _cam = Tools.MakeArray(cameras || this._cameras);
+            var cams = Tools.MakeArray(cameras || this._cameras);
+
+            if (!cams) {
+                return;
+            }
 
 
-            for (var i = 0; i < _cam.length; i++) {
-                var camera = _cam[i];
+            for (var i = 0; i < cams.length; i++) {
+                var camera = cams[i];
                 var cameraName = camera.name;
                 var cameraName = camera.name;
 
 
                 for (var j = 0; j < this._indicesForCamera[cameraName].length; j++) {
                 for (var j = 0; j < this._indicesForCamera[cameraName].length; j++) {
@@ -171,12 +183,16 @@ module BABYLON {
 
 
         // private
         // private
         public _disable(cameras: Camera): void;
         public _disable(cameras: Camera): void;
-        public _disable(cameras: Camera[]): void;
+        public _disable(cameras: Nullable<Camera[]>): void;
         public _disable(cameras: any): void {
         public _disable(cameras: any): void {
-            var _cam = Tools.MakeArray(cameras || this._cameras);
+            var cams = Tools.MakeArray(cameras || this._cameras);
+
+            if (!cams) {
+                return;
+            }
 
 
-            for (var i = 0; i < _cam.length; i++) {
-                var camera = _cam[i];
+            for (var i = 0; i < cams.length; i++) {
+                var camera = cams[i];
                 var cameraName = camera.Name;
                 var cameraName = camera.Name;
 
 
                 camera.detachPostProcess(this._postProcesses[this._singleInstance ? 0 : cameraName]);
                 camera.detachPostProcess(this._postProcesses[this._singleInstance ? 0 : cameraName]);
@@ -187,11 +203,15 @@ module BABYLON {
             }
             }
         }
         }
 
 
-        public getPostProcess(camera?: Camera): PostProcess {
+        public getPostProcess(camera?: Camera): Nullable<PostProcess> {
             if (this._singleInstance) {
             if (this._singleInstance) {
                 return this._postProcesses[0];
                 return this._postProcesses[0];
             }
             }
             else {
             else {
+
+                if (!camera) {
+                    return null;
+                }
                 return this._postProcesses[camera.name];
                 return this._postProcesses[camera.name];
             }
             }
         }
         }

+ 40 - 24
src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.ts

@@ -62,9 +62,9 @@ module BABYLON {
             renderEffects._enable(Tools.MakeArray(cameras || this._cameras));
             renderEffects._enable(Tools.MakeArray(cameras || this._cameras));
         }
         }
 
 
-        public _disableEffect(renderEffectName: string, cameras: Camera[]): void;
-        public _disableEffect(renderEffectName: string, cameras: Camera[]): void;
-        public _disableEffect(renderEffectName: string, cameras: Camera[]): void {
+        public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void;
+        public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void;
+        public _disableEffect(renderEffectName: string, cameras: Nullable<Camera[]>): void {
             var renderEffects: PostProcessRenderEffect = (<any>this._renderEffects)[renderEffectName];
             var renderEffects: PostProcessRenderEffect = (<any>this._renderEffects)[renderEffectName];
 
 
             if (!renderEffects) {
             if (!renderEffects) {
@@ -77,12 +77,16 @@ module BABYLON {
         public _attachCameras(cameras: Camera, unique: boolean): void;
         public _attachCameras(cameras: Camera, unique: boolean): void;
         public _attachCameras(cameras: Camera[], unique: boolean): void;
         public _attachCameras(cameras: Camera[], unique: boolean): void;
         public _attachCameras(cameras: any, unique: boolean): void {
         public _attachCameras(cameras: any, unique: boolean): void {
-            var _cam = Tools.MakeArray(cameras || this._cameras);
+            var cams = Tools.MakeArray(cameras || this._cameras);
+
+            if (!cams) {
+                return;
+            }
 
 
             var indicesToDelete = [];
             var indicesToDelete = [];
             var i: number;
             var i: number;
-            for (i = 0; i < _cam.length; i++) {
-                var camera = _cam[i];
+            for (i = 0; i < cams.length; i++) {
+                var camera = cams[i];
                 var cameraName = camera.name;
                 var cameraName = camera.name;
 
 
                 if (this._cameras.indexOf(camera) === -1) {
                 if (this._cameras.indexOf(camera) === -1) {
@@ -99,33 +103,41 @@ module BABYLON {
 
 
             for (var renderEffectName in this._renderEffects) {
             for (var renderEffectName in this._renderEffects) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
-                    this._renderEffects[renderEffectName]._attachCameras(_cam);
+                    this._renderEffects[renderEffectName]._attachCameras(cams);
                 }
                 }
             }
             }
         }
         }
 
 
         public _detachCameras(cameras: Camera): void;
         public _detachCameras(cameras: Camera): void;
-        public _detachCameras(cameras: Camera[]): void;
+        public _detachCameras(cameras: Nullable<Camera[]>): void;
         public _detachCameras(cameras: any): void {
         public _detachCameras(cameras: any): void {
-            var _cam = Tools.MakeArray(cameras || this._cameras);
+            var cams = Tools.MakeArray(cameras || this._cameras);
+
+            if (!cams) {
+                return;
+            }
 
 
             for (var renderEffectName in this._renderEffects) {
             for (var renderEffectName in this._renderEffects) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
-                    this._renderEffects[renderEffectName]._detachCameras(_cam);
+                    this._renderEffects[renderEffectName]._detachCameras(cams);
                 }
                 }
             }
             }
 
 
-            for (var i = 0; i < _cam.length; i++) {
-                this._cameras.splice(this._cameras.indexOf(_cam[i]), 1);
+            for (var i = 0; i < cams.length; i++) {
+                this._cameras.splice(this._cameras.indexOf(cams[i]), 1);
             }
             }
         }
         }
 
 
         public _enableDisplayOnlyPass(passName: string, cameras: Camera): void;
         public _enableDisplayOnlyPass(passName: string, cameras: Camera): void;
-        public _enableDisplayOnlyPass(passName: string, cameras: Camera[]): void;
+        public _enableDisplayOnlyPass(passName: string, cameras: Nullable<Camera[]>): void;
         public _enableDisplayOnlyPass(passName: string, cameras: any): void {
         public _enableDisplayOnlyPass(passName: string, cameras: any): void {
-            var _cam = Tools.MakeArray(cameras || this._cameras);
+            var cams = Tools.MakeArray(cameras || this._cameras);
 
 
-            var pass: PostProcessRenderPass = null;
+            if (!cams) {
+                return;
+            }
+
+            var pass: Nullable<PostProcessRenderPass> = null;
             var renderEffectName;
             var renderEffectName;
             for (renderEffectName in this._renderEffects) {
             for (renderEffectName in this._renderEffects) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
@@ -143,18 +155,18 @@ module BABYLON {
 
 
             for (renderEffectName in this._renderEffects) {
             for (renderEffectName in this._renderEffects) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
-                    this._renderEffects[renderEffectName]._disable(_cam);
+                    this._renderEffects[renderEffectName]._disable(cams);
                 }
                 }
             }
             }
 
 
             pass._name = PostProcessRenderPipeline.PASS_SAMPLER_NAME;
             pass._name = PostProcessRenderPipeline.PASS_SAMPLER_NAME;
 
 
-            for (var i = 0; i < _cam.length; i++) {
-                var camera = _cam[i];
+            for (var i = 0; i < cams.length; i++) {
+                var camera = cams[i];
                 var cameraName = camera.name;
                 var cameraName = camera.name;
 
 
                 this._renderEffectsForIsolatedPass[cameraName] = this._renderEffectsForIsolatedPass[cameraName] || new PostProcessRenderEffect(this._engine, PostProcessRenderPipeline.PASS_EFFECT_NAME,
                 this._renderEffectsForIsolatedPass[cameraName] = this._renderEffectsForIsolatedPass[cameraName] || new PostProcessRenderEffect(this._engine, PostProcessRenderPipeline.PASS_EFFECT_NAME,
-                    () => {return new DisplayPassPostProcess(PostProcessRenderPipeline.PASS_EFFECT_NAME, 1.0, null, null, this._engine, true) });
+                    () => {return new DisplayPassPostProcess(PostProcessRenderPipeline.PASS_EFFECT_NAME, 1.0, null, undefined, this._engine, true) });
                 this._renderEffectsForIsolatedPass[cameraName].emptyPasses();
                 this._renderEffectsForIsolatedPass[cameraName].emptyPasses();
                 this._renderEffectsForIsolatedPass[cameraName].addPass(pass);
                 this._renderEffectsForIsolatedPass[cameraName].addPass(pass);
                 this._renderEffectsForIsolatedPass[cameraName]._attachCameras(camera);
                 this._renderEffectsForIsolatedPass[cameraName]._attachCameras(camera);
@@ -164,20 +176,24 @@ module BABYLON {
         public _disableDisplayOnlyPass(cameras: Camera): void;
         public _disableDisplayOnlyPass(cameras: Camera): void;
         public _disableDisplayOnlyPass(cameras: Camera[]): void;
         public _disableDisplayOnlyPass(cameras: Camera[]): void;
         public _disableDisplayOnlyPass(cameras: any): void {
         public _disableDisplayOnlyPass(cameras: any): void {
-            var _cam = Tools.MakeArray(cameras || this._cameras);
+            var cams = Tools.MakeArray(cameras || this._cameras);
+
+            if (!cams) {
+                return;
+            }
 
 
-            for (var i = 0; i < _cam.length; i++) {
-                var camera = _cam[i];
+            for (var i = 0; i < cams.length; i++) {
+                var camera = cams[i];
                 var cameraName = camera.name;
                 var cameraName = camera.name;
 
 
                 this._renderEffectsForIsolatedPass[cameraName] = this._renderEffectsForIsolatedPass[cameraName] || new PostProcessRenderEffect(this._engine, PostProcessRenderPipeline.PASS_EFFECT_NAME, 
                 this._renderEffectsForIsolatedPass[cameraName] = this._renderEffectsForIsolatedPass[cameraName] || new PostProcessRenderEffect(this._engine, PostProcessRenderPipeline.PASS_EFFECT_NAME, 
-                                    () => {return new DisplayPassPostProcess(PostProcessRenderPipeline.PASS_EFFECT_NAME, 1.0, null, null, this._engine, true) });
+                                    () => {return new DisplayPassPostProcess(PostProcessRenderPipeline.PASS_EFFECT_NAME, 1.0, null, undefined, this._engine, true) });
                 this._renderEffectsForIsolatedPass[cameraName]._disable(camera);
                 this._renderEffectsForIsolatedPass[cameraName]._disable(camera);
             }
             }
 
 
             for (var renderEffectName in this._renderEffects) {
             for (var renderEffectName in this._renderEffects) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                 if (this._renderEffects.hasOwnProperty(renderEffectName)) {
-                    this._renderEffects[renderEffectName]._enable(_cam);
+                    this._renderEffects[renderEffectName]._enable(cams);
                 }
                 }
             }
             }
         }
         }

+ 1 - 1
src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.ts

@@ -12,7 +12,7 @@ module BABYLON {
 
 
         public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: Camera, unique?: boolean): void;
         public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: Camera, unique?: boolean): void;
         public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: Camera[], unique?: boolean): void;
         public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: Camera[], unique?: boolean): void;
-        public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: any, unique?: boolean): void {
+        public attachCamerasToRenderPipeline(renderPipelineName: string, cameras: any, unique: boolean = false): void {
             var renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];
             var renderPipeline: PostProcessRenderPipeline = this._renderPipelines[renderPipelineName];
 
 
             if (!renderPipeline) {
             if (!renderPipeline) {

+ 1 - 1
src/PostProcess/babylon.anaglyphPostProcess.ts

@@ -1,6 +1,6 @@
 module BABYLON {
 module BABYLON {
     export class AnaglyphPostProcess extends PostProcess {
     export class AnaglyphPostProcess extends PostProcess {
-        private _passedProcess : PostProcess;
+        private _passedProcess : Nullable<PostProcess>;
 
 
         constructor(name: string, options: number | PostProcessOptions,  rigCameras: Camera[], samplingMode?: number, engine?: Engine, reusable?: boolean) {
         constructor(name: string, options: number | PostProcessOptions,  rigCameras: Camera[], samplingMode?: number, engine?: Engine, reusable?: boolean) {
             super(name, "anaglyph", null, ["leftSampler"], options, rigCameras[1], samplingMode, engine, reusable);
             super(name, "anaglyph", null, ["leftSampler"], options, rigCameras[1], samplingMode, engine, reusable);

+ 1 - 1
src/PostProcess/babylon.displayPassPostProcess.ts

@@ -1,6 +1,6 @@
 module BABYLON {
 module BABYLON {
     export class DisplayPassPostProcess extends PostProcess {
     export class DisplayPassPostProcess extends PostProcess {
-        constructor(name: string, options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
+        constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean) {
             super(name, "displayPass", ["passSampler"], ["passSampler"], options, camera, samplingMode, engine, reusable);
             super(name, "displayPass", ["passSampler"], ["passSampler"], options, camera, samplingMode, engine, reusable);
         }
         }
     }
     }

+ 1 - 1
src/PostProcess/babylon.filterPostProcess.ts

@@ -1,6 +1,6 @@
 module BABYLON {
 module BABYLON {
     export class FilterPostProcess extends PostProcess {
     export class FilterPostProcess extends PostProcess {
-        constructor(name: string, public kernelMatrix: Matrix, options: number | PostProcessOptions, camera?: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
+        constructor(name: string, public kernelMatrix: Matrix, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean) {
             super(name, "filter", ["kernelMatrix"], null, options, camera, samplingMode, engine, reusable);
             super(name, "filter", ["kernelMatrix"], null, options, camera, samplingMode, engine, reusable);
 
 
             this.onApply = (effect: Effect) => {
             this.onApply = (effect: Effect) => {

+ 1 - 1
src/PostProcess/babylon.fxaaPostProcess.ts

@@ -3,7 +3,7 @@
         public texelWidth: number;
         public texelWidth: number;
         public texelHeight: number;
         public texelHeight: number;
 
 
-        constructor(name: string, options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
+        constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
             super(name, "fxaa", ["texelSize"], null, options, camera, samplingMode || BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "fxaa");
             super(name, "fxaa", ["texelSize"], null, options, camera, samplingMode || BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "fxaa");
 
 
             this.onApplyObservable.add((effect: Effect) => {
             this.onApplyObservable.add((effect: Effect) => {

+ 1 - 1
src/PostProcess/babylon.highlightsPostProcess.ts

@@ -1,6 +1,6 @@
 module BABYLON {
 module BABYLON {
     export class HighlightsPostProcess extends PostProcess {
     export class HighlightsPostProcess extends PostProcess {
-        constructor(name: string, options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
+        constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
             super(name, "highlights", null, null, options, camera, samplingMode, engine, reusable, null, textureType);
             super(name, "highlights", null, null, options, camera, samplingMode, engine, reusable, null, textureType);
         }
         }
     }
     }

+ 4 - 4
src/PostProcess/babylon.imageProcessingPostProcess.ts

@@ -25,13 +25,13 @@
         /**
         /**
          * Keep track of the image processing observer to allow dispose and replace.
          * Keep track of the image processing observer to allow dispose and replace.
          */
          */
-        private _imageProcessingObserver: Observer<ImageProcessingConfiguration>;
+        private _imageProcessingObserver: Nullable<Observer<ImageProcessingConfiguration>>;
 
 
         /**
         /**
          * Attaches a new image processing configuration to the PBR Material.
          * Attaches a new image processing configuration to the PBR Material.
          * @param configuration 
          * @param configuration 
          */
          */
-        protected _attachImageProcessingConfiguration(configuration: ImageProcessingConfiguration, doNotBuild = false): void {
+        protected _attachImageProcessingConfiguration(configuration: Nullable<ImageProcessingConfiguration>, doNotBuild = false): void {
             if (configuration === this._imageProcessingConfiguration) {
             if (configuration === this._imageProcessingConfiguration) {
                 return;
                 return;
             }
             }
@@ -58,7 +58,7 @@
                     scene = BABYLON.Engine.LastCreatedScene;
                     scene = BABYLON.Engine.LastCreatedScene;
                 }
                 }
 
 
-                this._imageProcessingConfiguration = scene.imageProcessingConfiguration;
+                this._imageProcessingConfiguration = (<Scene>scene).imageProcessingConfiguration;
             }
             }
             else {
             else {
                 this._imageProcessingConfiguration = configuration;
                 this._imageProcessingConfiguration = configuration;
@@ -312,7 +312,7 @@
             EXPOSURE: false,
             EXPOSURE: false,
         }
         }
 
 
-        constructor(name: string, options: number | PostProcessOptions, camera?: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
+        constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
             super(name, "imageProcessing", [], [], options, camera, samplingMode, engine, reusable,
             super(name, "imageProcessing", [], [], options, camera, samplingMode, engine, reusable,
                                             null, textureType, "postprocess", null, true);
                                             null, textureType, "postprocess", null, true);
 
 

+ 4 - 2
src/PostProcess/babylon.postProcess.ts

@@ -50,11 +50,13 @@
         public onActivateObservable = new Observable<Camera>();
         public onActivateObservable = new Observable<Camera>();
 
 
         private _onActivateObserver: Nullable<Observer<Camera>>;
         private _onActivateObserver: Nullable<Observer<Camera>>;
-        public set onActivate(callback: (camera: Camera) => void) {
+        public set onActivate(callback: Nullable<(camera: Camera) => void>) {
             if (this._onActivateObserver) {
             if (this._onActivateObserver) {
                 this.onActivateObservable.remove(this._onActivateObserver);
                 this.onActivateObservable.remove(this._onActivateObserver);
             }
             }
-            this._onActivateObserver = this.onActivateObservable.add(callback);
+            if (callback) {
+                this._onActivateObserver = this.onActivateObservable.add(callback);
+            }
         }
         }
 
 
         /**
         /**

+ 1 - 1
src/PostProcess/babylon.stereoscopicInterlacePostProcess.ts

@@ -1,7 +1,7 @@
 module BABYLON {
 module BABYLON {
     export class StereoscopicInterlacePostProcess extends PostProcess {
     export class StereoscopicInterlacePostProcess extends PostProcess {
         private _stepSize : Vector2;
         private _stepSize : Vector2;
-        private _passedProcess : PostProcess;
+        private _passedProcess : Nullable<PostProcess>;
 
 
         constructor(name: string, rigCameras: Camera[], isStereoscopicHoriz: boolean, samplingMode?: number, engine?: Engine, reusable?: boolean) {
         constructor(name: string, rigCameras: Camera[], isStereoscopicHoriz: boolean, samplingMode?: number, engine?: Engine, reusable?: boolean) {
             super(name, "stereoscopicInterlace", ['stepSize'], ['camASampler'], 1, rigCameras[1], samplingMode, engine, reusable, isStereoscopicHoriz ? "#define IS_STEREOSCOPIC_HORIZ 1" : undefined);
             super(name, "stereoscopicInterlace", ['stepSize'], ['camASampler'], 1, rigCameras[1], samplingMode, engine, reusable, isStereoscopicHoriz ? "#define IS_STEREOSCOPIC_HORIZ 1" : undefined);

+ 1 - 1
src/PostProcess/babylon.tonemapPostProcess.ts

@@ -9,7 +9,7 @@
     export class TonemapPostProcess extends PostProcess {
     export class TonemapPostProcess extends PostProcess {
 
 
         constructor(name: string, private _operator: TonemappingOperator, public exposureAdjustment: number, camera: Camera, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, textureFormat = Engine.TEXTURETYPE_UNSIGNED_INT) {
         constructor(name: string, private _operator: TonemappingOperator, public exposureAdjustment: number, camera: Camera, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, textureFormat = Engine.TEXTURETYPE_UNSIGNED_INT) {
-            super(name, "tonemap", ["_ExposureAdjustment"], null, 1.0, camera, samplingMode, engine, true, defines, textureFormat);
+            super(name, "tonemap", ["_ExposureAdjustment"], null, 1.0, camera, samplingMode, engine, true, null, textureFormat);
 
 
             var defines = "#define ";
             var defines = "#define ";
 
 

+ 22 - 14
src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts

@@ -100,13 +100,13 @@
          */
          */
         constructor(name: string, ratio: any, camera: Camera, mesh?: Mesh, samples: number = 100, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, scene?: Scene) {
         constructor(name: string, ratio: any, camera: Camera, mesh?: Mesh, samples: number = 100, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, scene?: Scene) {
             super(name, "volumetricLightScattering", ["decay", "exposure", "weight", "meshPositionOnScreen", "density"], ["lightScatteringSampler"], ratio.postProcessRatio || ratio, camera, samplingMode, engine, reusable, "#define NUM_SAMPLES " + samples);
             super(name, "volumetricLightScattering", ["decay", "exposure", "weight", "meshPositionOnScreen", "density"], ["lightScatteringSampler"], ratio.postProcessRatio || ratio, camera, samplingMode, engine, reusable, "#define NUM_SAMPLES " + samples);
-            scene = (camera === null) ? scene : camera.getScene(); // parameter "scene" can be null.
+            scene = <Scene>((camera === null) ? scene : camera.getScene()) // parameter "scene" can be null.
 
 
-            var engine = scene.getEngine();
+            engine = scene.getEngine();
             this._viewPort = new Viewport(0, 0, 1, 1).toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
             this._viewPort = new Viewport(0, 0, 1, 1).toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
 
 
             // Configure mesh
             // Configure mesh
-            this.mesh = (mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene);
+            this.mesh = (<Mesh>((mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene)));
 
 
             // Configure
             // Configure
             this._createPass(scene, ratio.passRatio || ratio);
             this._createPass(scene, ratio.passRatio || ratio);
@@ -120,7 +120,7 @@
             };
             };
 
 
             this.onApplyObservable.add((effect: Effect) => {
             this.onApplyObservable.add((effect: Effect) => {
-                this._updateMeshScreenCoordinates(scene);
+                this._updateMeshScreenCoordinates(<Scene>scene);
 
 
                 effect.setTexture("lightScatteringSampler", this._volumetricLightScatteringRTT);
                 effect.setTexture("lightScatteringSampler", this._volumetricLightScatteringRTT);
                 effect.setFloat("exposure", this.exposure);
                 effect.setFloat("exposure", this.exposure);
@@ -139,7 +139,7 @@
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
 
 
             // Render this.mesh as default
             // Render this.mesh as default
-            if (mesh === this.mesh) {
+            if (mesh === this.mesh && mesh.material) {
                 return mesh.material.isReady(mesh);
                 return mesh.material.isReady(mesh);
             }
             }
 
 
@@ -168,7 +168,7 @@
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
-                defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+                defines.push("#define BonesPerMesh " + (mesh.skeleton ? (mesh.skeleton.bones.length + 1) : 0));
             } else {
             } else {
                 defines.push("#define NUM_BONE_INFLUENCERS 0"); 
                 defines.push("#define NUM_BONE_INFLUENCERS 0"); 
             }
             }
@@ -265,12 +265,18 @@
                 if (this._meshExcluded(mesh)) {
                 if (this._meshExcluded(mesh)) {
                     return;
                     return;
                 }
                 }
+                
+                let material = subMesh.getMaterial();
+
+                if (!material) {
+                    return;
+                }
 
 
                 var scene = mesh.getScene();
                 var scene = mesh.getScene();
                 var engine = scene.getEngine();
                 var engine = scene.getEngine();
 
 
                 // Culling
                 // Culling
-                engine.setState(subMesh.getMaterial().backFaceCulling);
+                engine.setState(material.backFaceCulling);
 
 
                 // Managing instances
                 // Managing instances
                 var batch = mesh._getInstancesRenderList(subMesh._id);
                 var batch = mesh._getInstancesRenderList(subMesh._id);
@@ -287,7 +293,7 @@
                         if (subMesh.effect) {
                         if (subMesh.effect) {
                             effect = subMesh.effect;
                             effect = subMesh.effect;
                         } else {
                         } else {
-                            effect = subMesh.getMaterial().getEffect();
+                            effect = <Effect>material.getEffect();
                         }
                         }
                     }
                     }
 
 
@@ -295,11 +301,9 @@
                     mesh._bind(subMesh, effect, Material.TriangleFillMode);
                     mesh._bind(subMesh, effect, Material.TriangleFillMode);
 
 
                     if (mesh === this.mesh) {
                     if (mesh === this.mesh) {
-                        subMesh.getMaterial().bind(mesh.getWorldMatrix(), mesh);
+                        material.bind(mesh.getWorldMatrix(), mesh);
                     }
                     }
                     else {
                     else {
-                        var material: any = subMesh.getMaterial();
-
                         this._volumetricLightScatteringPass.setMatrix("viewProjection", scene.getTransformMatrix());
                         this._volumetricLightScatteringPass.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
                         // Alpha test
                         // Alpha test
@@ -314,7 +318,7 @@
                         }
                         }
 
 
                         // Bones
                         // Bones
-                        if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                             this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                             this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                         }
                         }
                     }
                     }
@@ -364,8 +368,12 @@
                     // Sort sub meshes
                     // Sort sub meshes
                     for (index = 0; index < transparentSubMeshes.length; index++) {
                     for (index = 0; index < transparentSubMeshes.length; index++) {
                         var submesh = transparentSubMeshes.data[index];
                         var submesh = transparentSubMeshes.data[index];
-                        submesh._alphaIndex = submesh.getMesh().alphaIndex;
-                        submesh._distanceToCamera = submesh.getBoundingInfo().boundingSphere.centerWorld.subtract(scene.activeCamera.position).length();
+                        let boundingInfo = submesh.getBoundingInfo();
+
+                        if (boundingInfo && scene.activeCamera) {
+                            submesh._alphaIndex = submesh.getMesh().alphaIndex;
+                            submesh._distanceToCamera = boundingInfo.boundingSphere.centerWorld.subtract(scene.activeCamera.position).length();
+                        }
                     }
                     }
 
 
                     var sortedArray = transparentSubMeshes.data.slice(0, transparentSubMeshes.length);
                     var sortedArray = transparentSubMeshes.data.slice(0, transparentSubMeshes.length);

+ 1 - 1
src/PostProcess/babylon.vrDistortionCorrectionPostProcess.ts

@@ -16,7 +16,7 @@
                 'Scale',
                 'Scale',
                 'ScaleIn',
                 'ScaleIn',
                 'HmdWarpParam'
                 'HmdWarpParam'
-            ], null, vrMetrics.postProcessScaleFactor, camera, Texture.BILINEAR_SAMPLINGMODE, null, null);
+            ], null, vrMetrics.postProcessScaleFactor, camera, Texture.BILINEAR_SAMPLINGMODE);
 
 
             this._isRightEye = isRightEye;
             this._isRightEye = isRightEye;
             this._distortionFactors = vrMetrics.distortionK;
             this._distortionFactors = vrMetrics.distortionK;

+ 5 - 3
src/Probes/babylon.reflectionProbe.ts

@@ -56,7 +56,9 @@
                 scene.updateTransformMatrix(true);
                 scene.updateTransformMatrix(true);
             });
             });
 
 
-            this._projectionMatrix = Matrix.PerspectiveFovLH(Math.PI / 2, 1, scene.activeCamera.minZ, scene.activeCamera.maxZ);
+            if (scene.activeCamera) {
+                this._projectionMatrix = Matrix.PerspectiveFovLH(Math.PI / 2, 1, scene.activeCamera.minZ, scene.activeCamera.maxZ);
+            }
         }
         }
 
 
         public get samples(): number {
         public get samples(): number {
@@ -83,7 +85,7 @@
             return this._renderTargetTexture;
             return this._renderTargetTexture;
         }
         }
 
 
-        public get renderList(): AbstractMesh[] {
+        public get renderList(): Nullable<AbstractMesh[]> {
             return this._renderTargetTexture.renderList;
             return this._renderTargetTexture.renderList;
         }
         }
 
 
@@ -111,7 +113,7 @@
 
 
             if (this._renderTargetTexture) {
             if (this._renderTargetTexture) {
                 this._renderTargetTexture.dispose();
                 this._renderTargetTexture.dispose();
-                this._renderTargetTexture = null;
+                (<any>this._renderTargetTexture) = null;
             }
             }
         }
         }
     }    
     }    

+ 9 - 6
src/Rendering/babylon.boundingBoxRenderer.ts

@@ -7,7 +7,7 @@
 
 
         private _scene: Scene;
         private _scene: Scene;
         private _colorShader: ShaderMaterial;
         private _colorShader: ShaderMaterial;
-        private _vertexBuffers: { [key: string]: VertexBuffer } = {};
+        private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
         private _indexBuffer: WebGLBuffer;
         private _indexBuffer: WebGLBuffer;
 
 
         constructor(scene: Scene) {
         constructor(scene: Scene) {
@@ -28,7 +28,7 @@
 
 
             var engine = this._scene.getEngine();
             var engine = this._scene.getEngine();
             var boxdata = VertexData.CreateBox({ size: 1.0 });
             var boxdata = VertexData.CreateBox({ size: 1.0 });
-            this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, boxdata.positions, VertexBuffer.PositionKind, false);
+            this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, <FloatArray>boxdata.positions, VertexBuffer.PositionKind, false);
             this._createIndexBuffer();
             this._createIndexBuffer();
         }
         }
 
 
@@ -38,7 +38,10 @@
         }
         }
 
 
         public _rebuild(): void {
         public _rebuild(): void {
-            this._vertexBuffers[VertexBuffer.PositionKind]._rebuild();
+            let vb = this._vertexBuffers[VertexBuffer.PositionKind];
+            if (vb) {
+                vb._rebuild();
+            }
             this._createIndexBuffer();
             this._createIndexBuffer();
         }
         }
 
 
@@ -72,7 +75,7 @@
                     .multiply(boundingBox.getWorldMatrix());
                     .multiply(boundingBox.getWorldMatrix());
 
 
                 // VBOs
                 // VBOs
-                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._colorShader.getEffect());
+                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, <Effect>this._colorShader.getEffect());
 
 
                 if (this.showBackLines) {
                 if (this.showBackLines) {
                     // Back
                     // Back
@@ -103,7 +106,7 @@
 
 
             this._prepareRessources();
             this._prepareRessources();
 
 
-            if (!this._colorShader.isReady()) {
+            if (!this._colorShader.isReady() || !mesh._boundingInfo) {
                 return;
                 return;
             }
             }
 
 
@@ -122,7 +125,7 @@
                 .multiply(Matrix.Translation(median.x, median.y, median.z))
                 .multiply(Matrix.Translation(median.x, median.y, median.z))
                 .multiply(boundingBox.getWorldMatrix());
                 .multiply(boundingBox.getWorldMatrix());
 
 
-            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._colorShader.getEffect());
+            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, <Effect>this._colorShader.getEffect());
 
 
             engine.setDepthFunctionToLess();
             engine.setDepthFunctionToLess();
             this._scene.resetCachedMaterial();
             this._scene.resetCachedMaterial();

+ 14 - 7
src/Rendering/babylon.depthRenderer.ts

@@ -28,9 +28,14 @@
                 var mesh = subMesh.getRenderingMesh();
                 var mesh = subMesh.getRenderingMesh();
                 var scene = this._scene;
                 var scene = this._scene;
                 var engine = scene.getEngine();
                 var engine = scene.getEngine();
+                let material = subMesh.getMaterial();
+
+                if (!material) {
+                    return;
+                }
 
 
                 // Culling
                 // Culling
-                engine.setState(subMesh.getMaterial().backFaceCulling);
+                engine.setState(material.backFaceCulling);
 
 
                 // Managing instances
                 // Managing instances
                 var batch = mesh._getInstancesRenderList(subMesh._id);
                 var batch = mesh._getInstancesRenderList(subMesh._id);
@@ -41,10 +46,9 @@
 
 
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null);
                 var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null);
 
 
-                if (this.isReady(subMesh, hardwareInstancedRendering)) {
+                if (this.isReady(subMesh, hardwareInstancedRendering) && scene.activeCamera) {
                     engine.enableEffect(this._effect);
                     engine.enableEffect(this._effect);
                     mesh._bind(subMesh, this._effect, Material.TriangleFillMode);
                     mesh._bind(subMesh, this._effect, Material.TriangleFillMode);
-                    var material = subMesh.getMaterial();
 
 
                     this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
                     this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
@@ -53,12 +57,15 @@
                     // Alpha test
                     // Alpha test
                     if (material && material.needAlphaTesting()) {
                     if (material && material.needAlphaTesting()) {
                         var alphaTexture = material.getAlphaTestTexture();
                         var alphaTexture = material.getAlphaTestTexture();
-                        this._effect.setTexture("diffuseSampler", alphaTexture);
-                        this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
+
+                        if (alphaTexture) {
+                            this._effect.setTexture("diffuseSampler", alphaTexture);
+                            this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
+                        }
                     }
                     }
 
 
                     // Bones
                     // Bones
-                    if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                    if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                         this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                         this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     }
 
 
@@ -123,7 +130,7 @@
                     attribs.push(VertexBuffer.MatricesWeightsExtraKind);
                     attribs.push(VertexBuffer.MatricesWeightsExtraKind);
                 }
                 }
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
-                defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+                defines.push("#define BonesPerMesh " + (mesh.skeleton ? mesh.skeleton.bones.length + 1 : 0));
             } else {
             } else {
                 defines.push("#define NUM_BONE_INFLUENCERS 0");
                 defines.push("#define NUM_BONE_INFLUENCERS 0");
             }
             }

+ 10 - 5
src/Rendering/babylon.edgesRenderer.ts

@@ -20,7 +20,7 @@
 
 
         private _lineShader: ShaderMaterial;
         private _lineShader: ShaderMaterial;
         private _ib: WebGLBuffer;
         private _ib: WebGLBuffer;
-        private _buffers: { [key: string]: VertexBuffer; } = {};
+        private _buffers: { [key: string]: Nullable<VertexBuffer> } = {};
         private _checkVerticesInsteadOfIndices = false;
         private _checkVerticesInsteadOfIndices = false;
 
 
         // Beware when you use this class with complex objects as the adjacencies computation can be really long
         // Beware when you use this class with complex objects as the adjacencies computation can be really long
@@ -182,6 +182,10 @@
             var positions = this._source.getVerticesData(VertexBuffer.PositionKind);
             var positions = this._source.getVerticesData(VertexBuffer.PositionKind);
             var indices = this._source.getIndices();
             var indices = this._source.getIndices();
 
 
+            if (!indices || !positions) {
+                return;
+            }
+
             // First let's find adjacencies
             // First let's find adjacencies
             var adjacencies = new Array<FaceAdjacencies>();
             var adjacencies = new Array<FaceAdjacencies>();
             var faceNormals = new Array<Vector3>();
             var faceNormals = new Array<Vector3>();
@@ -226,7 +230,7 @@
                     var otherP2 = indices[otherIndex * 3 + 2];
                     var otherP2 = indices[otherIndex * 3 + 2];
 
 
                     for (var edgeIndex = 0; edgeIndex < 3; edgeIndex++) {
                     for (var edgeIndex = 0; edgeIndex < 3; edgeIndex++) {
-                        var otherEdgeIndex: number;
+                        var otherEdgeIndex: number = 0;
 
 
                         if (faceAdjacencies.edges[edgeIndex] !== undefined) {
                         if (faceAdjacencies.edges[edgeIndex] !== undefined) {
                             continue;
                             continue;
@@ -295,16 +299,17 @@
         }
         }
 
 
         public render(): void {
         public render(): void {
-            if (!this._lineShader.isReady()) {
+            var scene = this._source.getScene();
+
+            if (!this._lineShader.isReady() || !scene.activeCamera) {
                 return;
                 return;
             }
             }
 
 
-            var scene = this._source.getScene();
             var engine = scene.getEngine();
             var engine = scene.getEngine();
             this._lineShader._preBind();
             this._lineShader._preBind();
 
 
             // VBOs
             // VBOs
-            engine.bindBuffers(this._buffers, this._ib, this._lineShader.getEffect());
+            engine.bindBuffers(this._buffers, this._ib, <Effect>this._lineShader.getEffect());
 
 
             scene.resetCachedMaterial();
             scene.resetCachedMaterial();
             this._lineShader.setColor4("color", this._source.edgesColor);
             this._lineShader.setColor4("color", this._source.edgesColor);

+ 16 - 8
src/Rendering/babylon.geometryBufferRenderer.ts

@@ -75,7 +75,7 @@ module BABYLON {
                     attribs.push(VertexBuffer.MatricesWeightsExtraKind);
                     attribs.push(VertexBuffer.MatricesWeightsExtraKind);
                 }
                 }
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
-                defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+                defines.push("#define BonesPerMesh " + (mesh.skeleton ? mesh.skeleton.bones.length + 1 : 0));
             } else {
             } else {
                 defines.push("#define NUM_BONE_INFLUENCERS 0");
                 defines.push("#define NUM_BONE_INFLUENCERS 0");
             }
             }
@@ -97,7 +97,7 @@ module BABYLON {
                     attribs,
                     attribs,
                     ["world", "mBones", "viewProjection", "diffuseMatrix", "view"],
                     ["world", "mBones", "viewProjection", "diffuseMatrix", "view"],
                     ["diffuseSampler"], join,
                     ["diffuseSampler"], join,
-                    null, null, null,
+                    undefined, undefined, undefined,
                     { buffersCount: this._enablePosition ? 3 : 2 });
                     { buffersCount: this._enablePosition ? 3 : 2 });
             }
             }
 
 
@@ -119,7 +119,7 @@ module BABYLON {
 
 
             this._multiRenderTarget = new MultiRenderTarget("gBuffer", { width: engine.getRenderWidth() * this._ratio, height: engine.getRenderHeight() * this._ratio }, count, this._scene, { generateMipMaps : false, generateDepthTexture: true });
             this._multiRenderTarget = new MultiRenderTarget("gBuffer", { width: engine.getRenderWidth() * this._ratio, height: engine.getRenderHeight() * this._ratio }, count, this._scene, { generateMipMaps : false, generateDepthTexture: true });
             if (!this.isSupported) {
             if (!this.isSupported) {
-                return null;
+                return;
             }
             }
             this._multiRenderTarget.wrapU = Texture.CLAMP_ADDRESSMODE;
             this._multiRenderTarget.wrapU = Texture.CLAMP_ADDRESSMODE;
             this._multiRenderTarget.wrapV = Texture.CLAMP_ADDRESSMODE;
             this._multiRenderTarget.wrapV = Texture.CLAMP_ADDRESSMODE;
@@ -137,9 +137,14 @@ module BABYLON {
                 var mesh = subMesh.getRenderingMesh();
                 var mesh = subMesh.getRenderingMesh();
                 var scene = this._scene;
                 var scene = this._scene;
                 var engine = scene.getEngine();
                 var engine = scene.getEngine();
+                let material = subMesh.getMaterial();
+
+                if (!material) {
+                    return;
+                }
 
 
                 // Culling
                 // Culling
-                engine.setState(subMesh.getMaterial().backFaceCulling);
+                engine.setState(material.backFaceCulling);
 
 
                 // Managing instances
                 // Managing instances
                 var batch = mesh._getInstancesRenderList(subMesh._id);
                 var batch = mesh._getInstancesRenderList(subMesh._id);
@@ -153,7 +158,7 @@ module BABYLON {
                 if (this.isReady(subMesh, hardwareInstancedRendering)) {
                 if (this.isReady(subMesh, hardwareInstancedRendering)) {
                     engine.enableEffect(this._effect);
                     engine.enableEffect(this._effect);
                     mesh._bind(subMesh, this._effect, Material.TriangleFillMode);
                     mesh._bind(subMesh, this._effect, Material.TriangleFillMode);
-                    var material = subMesh.getMaterial();
+                    
 
 
                     this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
                     this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
                     this._effect.setMatrix("view", scene.getViewMatrix());
                     this._effect.setMatrix("view", scene.getViewMatrix());
@@ -161,12 +166,15 @@ module BABYLON {
                     // Alpha test
                     // Alpha test
                     if (material && material.needAlphaTesting()) {
                     if (material && material.needAlphaTesting()) {
                         var alphaTexture = material.getAlphaTestTexture();
                         var alphaTexture = material.getAlphaTestTexture();
-                        this._effect.setTexture("diffuseSampler", alphaTexture);
-                        this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
+
+                        if (alphaTexture) {
+                            this._effect.setTexture("diffuseSampler", alphaTexture);
+                            this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
+                        }
                     }
                     }
 
 
                     // Bones
                     // Bones
-                    if (mesh.useBones && mesh.computeBonesUsingShaders) {
+                    if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                         this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                         this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     }
 
 

+ 7 - 3
src/Rendering/babylon.outlineRenderer.ts

@@ -10,7 +10,7 @@
             this._scene = scene;
             this._scene = scene;
         }
         }
 
 
-        public render(subMesh: SubMesh, batch: _InstancesBatch, useOverlay: boolean = false) {
+        public render(subMesh: SubMesh, batch: _InstancesBatch, useOverlay: boolean = false): void {
             var scene = this._scene;
             var scene = this._scene;
             var engine = this._scene.getEngine();
             var engine = this._scene.getEngine();
 
 
@@ -23,6 +23,10 @@
             var mesh = subMesh.getRenderingMesh();
             var mesh = subMesh.getRenderingMesh();
             var material = subMesh.getMaterial();
             var material = subMesh.getMaterial();
 
 
+            if (!material || !scene.activeCamera) {
+                return;
+            }
+
             engine.enableEffect(this._effect);
             engine.enableEffect(this._effect);
 
 
             // Logarithmic depth
             // Logarithmic depth
@@ -36,7 +40,7 @@
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
             // Bones
             // Bones
-            if (mesh.useBones && mesh.computeBonesUsingShaders) {
+            if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                 this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                 this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
             }
             }
 
 
@@ -95,7 +99,7 @@
                     attribs.push(VertexBuffer.MatricesWeightsExtraKind);
                     attribs.push(VertexBuffer.MatricesWeightsExtraKind);
                 }
                 }
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
-                defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+                defines.push("#define BonesPerMesh " + (mesh.skeleton ? mesh.skeleton.bones.length + 1 : 0));
             } else {
             } else {
                 defines.push("#define NUM_BONE_INFLUENCERS 0");
                 defines.push("#define NUM_BONE_INFLUENCERS 0");
             }
             }

+ 6 - 2
src/Rendering/babylon.renderingGroup.ts

@@ -187,7 +187,7 @@
             for (; subIndex < subMeshes.length; subIndex++) {
             for (; subIndex < subMeshes.length; subIndex++) {
                 subMesh = subMeshes.data[subIndex];
                 subMesh = subMeshes.data[subIndex];
                 subMesh._alphaIndex = subMesh.getMesh().alphaIndex;
                 subMesh._alphaIndex = subMesh.getMesh().alphaIndex;
-                subMesh._distanceToCamera = subMesh.getBoundingInfo().boundingSphere.centerWorld.subtract(cameraPosition).length();
+                subMesh._distanceToCamera = (<BoundingInfo>subMesh.getBoundingInfo()).boundingSphere.centerWorld.subtract(cameraPosition).length();
             }
             }
 
 
             let sortedArray = subMeshes.data.slice(0, subMeshes.length);
             let sortedArray = subMeshes.data.slice(0, subMeshes.length);
@@ -202,7 +202,7 @@
                 if (transparent) {
                 if (transparent) {
                     let material = subMesh.getMaterial();
                     let material = subMesh.getMaterial();
 
 
-                    if (material.needDepthPrePass) {
+                    if (material && material.needDepthPrePass) {
                         let engine = material.getScene().getEngine();
                         let engine = material.getScene().getEngine();
                         engine.setColorWrite(false);
                         engine.setColorWrite(false);
                         engine.setAlphaTesting(true);
                         engine.setAlphaTesting(true);
@@ -320,6 +320,10 @@
             var material = subMesh.getMaterial();
             var material = subMesh.getMaterial();
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
 
 
+            if (!material) {
+                return;
+            }
+
             if (material.needAlphaBlending() || mesh.visibility < 1.0 || mesh.hasVertexAlpha) { // Transparent
             if (material.needAlphaBlending() || mesh.visibility < 1.0 || mesh.hasVertexAlpha) { // Transparent
                 this._transparentSubMeshes.push(subMesh);
                 this._transparentSubMeshes.push(subMesh);
             } else if (material.needAlphaTesting()) { // Alpha test
             } else if (material.needAlphaTesting()) { // Alpha test

+ 5 - 1
src/Tools/babylon.decorators.ts

@@ -238,9 +238,13 @@
             return serializationObject;
             return serializationObject;
         }
         }
 
 
-        public static Parse<T>(creationFunction: () => T, source: any, scene: Nullable<Scene>, rootUrl: string = ""): T {
+        public static Parse<T>(creationFunction: () => T, source: any, scene: Nullable<Scene>, rootUrl: Nullable<string> = null): T {
             var destination = creationFunction();
             var destination = creationFunction();
 
 
+            if (!rootUrl) {
+                rootUrl = "";
+            }
+
             // Tags
             // Tags
             if (Tags) {
             if (Tags) {
                 Tags.AddTagsTo(destination, source.tags);
                 Tags.AddTagsTo(destination, source.tags);

+ 2 - 2
src/babylon.node.ts

@@ -90,10 +90,10 @@ module BABYLON {
          * @param {string} name - the name and id to be given to this node
          * @param {string} name - the name and id to be given to this node
          * @param {BABYLON.Scene} the scene this node will be added to
          * @param {BABYLON.Scene} the scene this node will be added to
          */
          */
-        constructor(name: string, scene: Scene) {
+        constructor(name: string, scene: Nullable<Scene> = null) {
             this.name = name;
             this.name = name;
             this.id = name;
             this.id = name;
-            this._scene = scene || Engine.LastCreatedScene;
+            this._scene = <Scene>(scene || Engine.LastCreatedScene);
             this.uniqueId = this._scene.getUniqueId();
             this.uniqueId = this._scene.getUniqueId();
             this._initCache();
             this._initCache();
         }
         }

+ 4 - 2
src/babylon.scene.ts

@@ -437,7 +437,7 @@
         private _currentInternalStep: number = 0;
         private _currentInternalStep: number = 0;
 
 
         // Mirror
         // Mirror
-        public _mirroredCameraPosition: Vector3;
+        public _mirroredCameraPosition: Nullable<Vector3>;
 
 
         // Keyboard
         // Keyboard
 
 
@@ -760,6 +760,7 @@
 
 
         public _toBeDisposed = new SmartArray<Nullable<IDisposable>>(256);
         public _toBeDisposed = new SmartArray<Nullable<IDisposable>>(256);
         private _pendingData = new Array();
         private _pendingData = new Array();
+        private _isDisposed = false;
 
 
         private _activeMeshes = new SmartArray<AbstractMesh>(256);
         private _activeMeshes = new SmartArray<AbstractMesh>(256);
         private _processedMaterials = new SmartArray<Material>(256);
         private _processedMaterials = new SmartArray<Material>(256);
@@ -3729,10 +3730,11 @@
             }
             }
 
 
             this._engine.wipeCaches();
             this._engine.wipeCaches();
+            this._isDisposed = true;
         }
         }
 
 
         public get isDisposed(): boolean {
         public get isDisposed(): boolean {
-            return !this._engine;
+            return this._isDisposed;
         }
         }
 
 
         // Release sounds & sounds tracks
         // Release sounds & sounds tracks

+ 2 - 1
src/babylon.types.ts

@@ -3,4 +3,5 @@ type float = number;
 type double = number;
 type double = number;
 type int = number;
 type int = number;
 
 
-type FloatArray = number[] | Float32Array;
+type FloatArray = number[] | Float32Array;
+type IndicesArray = number[] | Int32Array | Uint32Array | Uint16Array;

+ 5 - 1
tslint.json

@@ -1,3 +1,7 @@
 {
 {
-	"rules": {	}
+    "rules": {  
+        "no-invalid-this": true,
+        "no-this-assignment": true,
+        "completed-docs": true
+    }
 }
 }