浏览代码

Merge pull request #3001 from BabylonJS/master

Nightly
David Catuhe 8 年之前
父节点
当前提交
0fe71e167e
共有 100 个文件被更改,包括 35021 次插入35473 次删除
  1. 0 22
      Tools/Gulp/config.json
  2. 7542 7738
      dist/preview release/babylon.d.ts
  3. 48 48
      dist/preview release/babylon.js
  4. 1555 1556
      dist/preview release/babylon.max.js
  5. 7542 7738
      dist/preview release/babylon.module.d.ts
  6. 49 49
      dist/preview release/babylon.worker.js
  7. 7291 7487
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  8. 50 50
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  9. 1804 1761
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  10. 7291 7487
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  11. 27 27
      dist/preview release/gui/babylon.gui.js
  12. 3 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  13. 0 3
      dist/preview release/inspector/babylon.inspector.d.ts
  14. 55 64
      dist/preview release/inspector/babylon.inspector.js
  15. 3 4
      dist/preview release/inspector/babylon.inspector.min.js
  16. 6 9
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  17. 30 21
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  18. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  19. 10 12
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  20. 243 200
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  21. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  22. 11 12
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  23. 253 207
      dist/preview release/loaders/babylon.glTFFileLoader.js
  24. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  25. 2 2
      dist/preview release/loaders/babylon.objFileLoader.js
  26. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  27. 1 1
      dist/preview release/loaders/babylon.stlFileLoader.js
  28. 256 210
      dist/preview release/loaders/babylonjs.loaders.js
  29. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  30. 11 12
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  31. 1 1
      dist/preview release/loaders/readme.md
  32. 2 2
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  33. 7 7
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  34. 2 2
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  35. 2 2
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  36. 2 2
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  37. 2 2
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  38. 2 2
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  39. 2 2
      dist/preview release/materialsLibrary/babylon.legacyPbrMaterial.js
  40. 2 2
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  41. 2 2
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  42. 2 2
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  43. 2 2
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  44. 2 2
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  45. 2 2
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  46. 2 2
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  47. 35 35
      dist/preview release/materialsLibrary/babylonjs.materials.js
  48. 1 1
      dist/preview release/materialsLibrary/readme.md
  49. 2 2
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js
  50. 2 2
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js
  51. 4 4
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js
  52. 1 1
      dist/preview release/postProcessesLibrary/readme.md
  53. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js
  54. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.cloudProceduralTexture.js
  55. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.fireProceduralTexture.js
  56. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.grassProceduralTexture.js
  57. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.marbleProceduralTexture.js
  58. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.js
  59. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.perlinNoiseProceduralTexture.js
  60. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.roadProceduralTexture.js
  61. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.js
  62. 1 1
      dist/preview release/proceduralTexturesLibrary/babylon.woodProceduralTexture.js
  63. 10 10
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js
  64. 1 1
      dist/preview release/proceduralTexturesLibrary/readme.md
  65. 1 1
      dist/preview release/serializers/babylon.objSerializer.js
  66. 1 1
      dist/preview release/serializers/babylonjs.serializers.js
  67. 2 1
      dist/preview release/what's new.md
  68. 0 3
      inspector/src/properties.ts
  69. 1 8
      inspector/src/tabs/TextureTab.ts
  70. 4 0
      loaders/src/glTF/1.0/babylon.glTFLoader.ts
  71. 3 3
      loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts
  72. 11 7
      loaders/src/glTF/2.0/Extensions/MSFT_lod.ts
  73. 284 269
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  74. 3 4
      loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts
  75. 5 5
      loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts
  76. 47 45
      loaders/src/glTF/babylon.glTFFileLoader.ts
  77. 1 1
      src/Actions/babylon.actionManager.ts
  78. 9 7
      src/Audio/babylon.analyser.ts
  79. 8 5
      src/Audio/babylon.audioEngine.ts
  80. 46 31
      src/Audio/babylon.sound.ts
  81. 5 5
      src/Audio/babylon.soundtrack.ts
  82. 27 8
      src/Behaviors/Cameras/babylon.autoRotationBehavior.ts
  83. 39 10
      src/Behaviors/Cameras/babylon.bouncingBehavior.ts
  84. 72 28
      src/Behaviors/Cameras/babylon.framingBehavior.ts
  85. 53 62
      src/Bones/babylon.bone.ts
  86. 28 22
      src/Bones/babylon.boneIKController.ts
  87. 4 4
      src/Bones/babylon.boneLookController.ts
  88. 32 20
      src/Bones/babylon.skeleton.ts
  89. 3 3
      src/Cameras/Inputs/babylon.arcRotateCameraGamepadInput.ts
  90. 8 4
      src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts
  91. 2 2
      src/Cameras/Inputs/babylon.arcRotateCameraMouseWheelInput.ts
  92. 43 29
      src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts
  93. 11 3
      src/Cameras/Inputs/babylon.arcRotateCameraVRDeviceOrientationInput.ts
  94. 3 3
      src/Cameras/Inputs/babylon.freeCameraDeviceOrientationInput.ts
  95. 3 3
      src/Cameras/Inputs/babylon.freeCameraGamepadInput.ts
  96. 9 4
      src/Cameras/Inputs/babylon.freeCameraKeyboardMoveInput.ts
  97. 9 6
      src/Cameras/Inputs/babylon.freeCameraMouseInput.ts
  98. 17 12
      src/Cameras/Inputs/babylon.freeCameraTouchInput.ts
  99. 31 17
      src/Cameras/VR/babylon.vrExperienceHelper.ts
  100. 0 0
      src/Cameras/VR/babylon.webVRCamera.ts

+ 0 - 22
Tools/Gulp/config.json

@@ -67,8 +67,6 @@
             "optimizations",
             "highlights",
             "assetsManager",
-            "mapTexture",
-            "dynamicFloatArray",
             "serialization",
             "probes",
             "layer",
@@ -143,8 +141,6 @@
             "optimizations",
             "highlights",
             "assetsManager",
-            "mapTexture",
-            "dynamicFloatArray",
             "serialization",
             "probes",
             "layer",
@@ -924,7 +920,6 @@
                 "additionalMeshes",
                 "standardMaterial",
                 "stringDictionary",
-                "dynamicFloatArray",
                 "actions"
             ],
             "shaders": [
@@ -1030,23 +1025,6 @@
                 "core"
             ]
         },
-        "mapTexture": {
-            "files": [
-                "../../src/Materials/Textures/babylon.mapTexture.js",
-                "../../src/Tools/babylon.rectPackingMap.js"
-            ],
-            "dependUpon": [
-                "core"
-            ]
-        },
-        "dynamicFloatArray": {
-            "files": [
-                "../../src/Tools/babylon.dynamicFloatArray.js"
-            ],
-            "dependUpon": [
-                "core"
-            ]
-        },
         "serialization": {
             "files": [
                 "../../src/Tools/babylon.sceneSerializer.js"

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


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


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


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


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


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


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


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


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


+ 27 - 27
dist/preview release/gui/babylon.gui.js

@@ -22,7 +22,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var AdvancedDynamicTexture = (function (_super) {
+        var AdvancedDynamicTexture = /** @class */ (function (_super) {
             __extends(AdvancedDynamicTexture, _super);
             function AdvancedDynamicTexture(name, width, height, scene, generateMipMaps, samplingMode) {
                 if (width === void 0) { width = 0; }
@@ -430,7 +430,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Measure = (function () {
+        var Measure = /** @class */ (function () {
             function Measure(left, top, width, height) {
                 this.left = left;
                 this.top = top;
@@ -475,7 +475,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Vector2WithInfo = (function (_super) {
+        var Vector2WithInfo = /** @class */ (function (_super) {
             __extends(Vector2WithInfo, _super);
             function Vector2WithInfo(source, buttonIndex) {
                 if (buttonIndex === void 0) { buttonIndex = 0; }
@@ -486,7 +486,7 @@ var BABYLON;
             return Vector2WithInfo;
         }(BABYLON.Vector2));
         GUI.Vector2WithInfo = Vector2WithInfo;
-        var Matrix2D = (function () {
+        var Matrix2D = /** @class */ (function () {
             function Matrix2D(m00, m01, m10, m11, m20, m21) {
                 this.m = new Float32Array(6);
                 this.fromValues(m00, m01, m10, m11, m20, m21);
@@ -607,7 +607,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var ValueAndUnit = (function () {
+        var ValueAndUnit = /** @class */ (function () {
             function ValueAndUnit(value, unit, negativeValueAllowed) {
                 if (unit === void 0) { unit = ValueAndUnit.UNITMODE_PIXEL; }
                 if (negativeValueAllowed === void 0) { negativeValueAllowed = true; }
@@ -725,7 +725,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Control = (function () {
+        var Control = /** @class */ (function () {
             // Functions
             function Control(name) {
                 this.name = name;
@@ -1771,7 +1771,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Container = (function (_super) {
+        var Container = /** @class */ (function (_super) {
             __extends(Container, _super);
             function Container(name) {
                 var _this = _super.call(this, name) || this;
@@ -1950,7 +1950,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var StackPanel = (function (_super) {
+        var StackPanel = /** @class */ (function (_super) {
             __extends(StackPanel, _super);
             function StackPanel(name) {
                 var _this = _super.call(this, name) || this;
@@ -2092,7 +2092,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Rectangle = (function (_super) {
+        var Rectangle = /** @class */ (function (_super) {
             __extends(Rectangle, _super);
             function Rectangle(name) {
                 var _this = _super.call(this, name) || this;
@@ -2208,7 +2208,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Ellipse = (function (_super) {
+        var Ellipse = /** @class */ (function (_super) {
             __extends(Ellipse, _super);
             function Ellipse(name) {
                 var _this = _super.call(this, name) || this;
@@ -2274,7 +2274,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Line = (function (_super) {
+        var Line = /** @class */ (function (_super) {
             __extends(Line, _super);
             function Line(name) {
                 var _this = _super.call(this, name) || this;
@@ -2474,7 +2474,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Slider = (function (_super) {
+        var Slider = /** @class */ (function (_super) {
             __extends(Slider, _super);
             function Slider(name) {
                 var _this = _super.call(this, name) || this;
@@ -2684,7 +2684,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Checkbox = (function (_super) {
+        var Checkbox = /** @class */ (function (_super) {
             __extends(Checkbox, _super);
             function Checkbox(name) {
                 var _this = _super.call(this, name) || this;
@@ -2800,7 +2800,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var RadioButton = (function (_super) {
+        var RadioButton = /** @class */ (function (_super) {
             __extends(RadioButton, _super);
             function RadioButton(name) {
                 var _this = _super.call(this, name) || this;
@@ -2937,7 +2937,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var TextBlock = (function (_super) {
+        var TextBlock = /** @class */ (function (_super) {
             __extends(TextBlock, _super);
             function TextBlock(name, text) {
                 if (text === void 0) { text = ""; }
@@ -3146,7 +3146,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Image = (function (_super) {
+        var Image = /** @class */ (function (_super) {
             __extends(Image, _super);
             function Image(name, url) {
                 var _this = _super.call(this, name) || this;
@@ -3388,7 +3388,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var Button = (function (_super) {
+        var Button = /** @class */ (function (_super) {
             __extends(Button, _super);
             function Button(name) {
                 var _this = _super.call(this, name) || this;
@@ -3517,7 +3517,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var ColorPicker = (function (_super) {
+        var ColorPicker = /** @class */ (function (_super) {
             __extends(ColorPicker, _super);
             function ColorPicker(name) {
                 var _this = _super.call(this, name) || this;
@@ -3863,7 +3863,7 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var InputText = (function (_super) {
+        var InputText = /** @class */ (function (_super) {
             __extends(InputText, _super);
             function InputText(name, text) {
                 if (text === void 0) { text = ""; }
@@ -4112,12 +4112,12 @@ var BABYLON;
                         return;
                 }
                 // Printable characters
-                if ((keyCode === -1) ||
-                    (keyCode === 32) ||
-                    (keyCode > 47 && keyCode < 58) ||
-                    (keyCode > 64 && keyCode < 91) ||
-                    (keyCode > 185 && keyCode < 193) ||
-                    (keyCode > 218 && keyCode < 223) ||
+                if ((keyCode === -1) || // Direct access
+                    (keyCode === 32) || // Space
+                    (keyCode > 47 && keyCode < 58) || // Numbers
+                    (keyCode > 64 && keyCode < 91) || // Letters
+                    (keyCode > 185 && keyCode < 193) || // Special characters
+                    (keyCode > 218 && keyCode < 223) || // Special characters
                     (keyCode > 95 && keyCode < 112)) {
                     if (this._cursorOffset === 0) {
                         this.text += key;
@@ -4276,13 +4276,13 @@ var BABYLON;
 (function (BABYLON) {
     var GUI;
     (function (GUI) {
-        var KeyPropertySet = (function () {
+        var KeyPropertySet = /** @class */ (function () {
             function KeyPropertySet() {
             }
             return KeyPropertySet;
         }());
         GUI.KeyPropertySet = KeyPropertySet;
-        var VirtualKeyboard = (function (_super) {
+        var VirtualKeyboard = /** @class */ (function (_super) {
             __extends(VirtualKeyboard, _super);
             function VirtualKeyboard() {
                 var _this = _super !== null && _super.apply(this, arguments) || this;

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


+ 0 - 3
dist/preview release/inspector/babylon.inspector.d.ts

@@ -139,9 +139,6 @@ declare module INSPECTOR {
             properties: string[];
             format: (tex: BABYLON.Texture) => string;
         };
-        'MapTexture': {
-            type: typeof BABYLON.MapTexture;
-        };
         'RenderTargetTexture': {
             type: typeof BABYLON.RenderTargetTexture;
         };

+ 55 - 64
dist/preview release/inspector/babylon.inspector.js

@@ -1,6 +1,6 @@
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Inspector = (function () {
+    var Inspector = /** @class */ (function () {
         /** The inspector is created with the given engine.
          * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
          * If the parameter 'popup' is true, the inspector is created in another popup.
@@ -406,9 +406,6 @@ var INSPECTOR;
             ],
             format: function (tex) { return tex.name; }
         },
-        'MapTexture': {
-            type: BABYLON.MapTexture
-        },
         'RenderTargetTexture': {
             type: BABYLON.RenderTargetTexture
         },
@@ -783,7 +780,7 @@ var INSPECTOR;
      * Represents a html div element.
      * The div is built when an instance of BasicElement is created.
      */
-    var BasicElement = (function () {
+    var BasicElement = /** @class */ (function () {
         function BasicElement() {
             this._div = INSPECTOR.Helpers.CreateDiv();
         }
@@ -810,7 +807,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Adapter = (function () {
+    var Adapter = /** @class */ (function () {
         function Adapter(obj) {
             this._obj = obj;
         }
@@ -865,7 +862,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var CameraAdapter = (function (_super) {
+    var CameraAdapter = /** @class */ (function (_super) {
         __extends(CameraAdapter, _super);
         function CameraAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -914,7 +911,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PhysicsImpostorAdapter = (function (_super) {
+    var PhysicsImpostorAdapter = /** @class */ (function (_super) {
         __extends(PhysicsImpostorAdapter, _super);
         function PhysicsImpostorAdapter(obj, viewer) {
             var _this = _super.call(this, obj) || this;
@@ -975,7 +972,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var GUIAdapter = (function (_super) {
+    var GUIAdapter = /** @class */ (function (_super) {
         __extends(GUIAdapter, _super);
         function GUIAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -1026,7 +1023,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var SoundAdapter = (function (_super) {
+    var SoundAdapter = /** @class */ (function (_super) {
         __extends(SoundAdapter, _super);
         function SoundAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -1082,7 +1079,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var TextureAdapter = (function (_super) {
+    var TextureAdapter = /** @class */ (function (_super) {
         __extends(TextureAdapter, _super);
         function TextureAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -1128,7 +1125,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var LightAdapter = (function (_super) {
+    var LightAdapter = /** @class */ (function (_super) {
         __extends(LightAdapter, _super);
         function LightAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -1179,7 +1176,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var MaterialAdapter = (function (_super) {
+    var MaterialAdapter = /** @class */ (function (_super) {
         __extends(MaterialAdapter, _super);
         function MaterialAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -1223,7 +1220,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var MeshAdapter = (function (_super) {
+    var MeshAdapter = /** @class */ (function (_super) {
         __extends(MeshAdapter, _super);
         function MeshAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -1313,7 +1310,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var DetailPanel = (function (_super) {
+    var DetailPanel = /** @class */ (function (_super) {
         __extends(DetailPanel, _super);
         function DetailPanel(dr) {
             var _this = _super.call(this) || this;
@@ -1461,7 +1458,7 @@ var INSPECTOR;
     /**
      * A property is a link between a data (string) and an object.
      */
-    var Property = (function () {
+    var Property = /** @class */ (function () {
         function Property(prop, obj) {
             this._property = prop;
             this._obj = obj;
@@ -1509,7 +1506,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PropertyFormatter = (function () {
+    var PropertyFormatter = /** @class */ (function () {
         function PropertyFormatter() {
         }
         /**
@@ -1536,7 +1533,7 @@ var INSPECTOR;
      * If this instance has no link to other instances, its type is ALWAYS a simple one (see above).
      *
      */
-    var PropertyLine = (function () {
+    var PropertyLine = /** @class */ (function () {
         function PropertyLine(prop, parent, level) {
             if (level === void 0) { level = 0; }
             // If the type is complex, this property will have child to update
@@ -1975,7 +1972,7 @@ var INSPECTOR;
     /**
     * Display a very small div corresponding to the given color
     */
-    var ColorElement = (function (_super) {
+    var ColorElement = /** @class */ (function (_super) {
         __extends(ColorElement, _super);
         // The color as hexadecimal string
         function ColorElement(color) {
@@ -2025,7 +2022,7 @@ var INSPECTOR;
      * Represents a html div element.
      * The div is built when an instance of BasicElement is created.
      */
-    var ColorPickerElement = (function (_super) {
+    var ColorPickerElement = /** @class */ (function (_super) {
         __extends(ColorPickerElement, _super);
         function ColorPickerElement(color, propertyLine) {
             var _this = _super.call(this) || this;
@@ -2095,7 +2092,7 @@ var INSPECTOR;
     * Display a very small div. A new canvas is created, with a new Babylon.js scene, containing only the
     * cube texture in a cube
     */
-    var CubeTextureElement = (function (_super) {
+    var CubeTextureElement = /** @class */ (function (_super) {
         __extends(CubeTextureElement, _super);
         /** The texture given as a parameter should be cube. */
         function CubeTextureElement(tex) {
@@ -2210,7 +2207,7 @@ var INSPECTOR;
     * Display a very small div. A new canvas is created, with a new Babylon.js scene, containing only the
     * cube texture in a cube
     */
-    var HDRCubeTextureElement = (function (_super) {
+    var HDRCubeTextureElement = /** @class */ (function (_super) {
         __extends(HDRCubeTextureElement, _super);
         /** The texture given as a parameter should be cube. */
         function HDRCubeTextureElement(tex) {
@@ -2254,7 +2251,7 @@ var INSPECTOR;
      * A search bar can be used to filter elements in the tree panel.
      * At each keypress on the input, the treepanel will be filtered.
      */
-    var SearchBar = (function (_super) {
+    var SearchBar = /** @class */ (function (_super) {
         __extends(SearchBar, _super);
         function SearchBar(tab) {
             var _this = _super.call(this) || this;
@@ -2300,7 +2297,7 @@ var INSPECTOR;
     /**
     * Display a very small div corresponding to the given texture. On mouse over, display the full image
     */
-    var TextureElement = (function (_super) {
+    var TextureElement = /** @class */ (function (_super) {
         __extends(TextureElement, _super);
         function TextureElement(tex) {
             var _this = _super.call(this) || this;
@@ -2336,7 +2333,7 @@ var INSPECTOR;
     /**
      * Creates a tooltip for the parent of the given html element
      */
-    var Tooltip = (function () {
+    var Tooltip = /** @class */ (function () {
         function Tooltip(elem, tip, attachTo) {
             var _this = this;
             this._elem = elem;
@@ -2357,7 +2354,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Helpers = (function () {
+    var Helpers = /** @class */ (function () {
         function Helpers() {
         }
         /**
@@ -2544,7 +2541,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Scheduler = (function () {
+    var Scheduler = /** @class */ (function () {
         function Scheduler() {
             /** Is this scheduler in pause ? */
             this.pause = false;
@@ -2597,7 +2594,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Tab = (function (_super) {
+    var Tab = /** @class */ (function (_super) {
         __extends(Tab, _super);
         function Tab(tabbar, name) {
             var _this = _super.call(this) || this;
@@ -2676,7 +2673,7 @@ var INSPECTOR;
      * in which properties will be displayed.
      * Both panels are separated by a resize bar
      */
-    var PropertyTab = (function (_super) {
+    var PropertyTab = /** @class */ (function (_super) {
         __extends(PropertyTab, _super);
         function PropertyTab(tabbar, name, insp) {
             var _this = _super.call(this, tabbar, name) || this;
@@ -2820,7 +2817,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var CameraTab = (function (_super) {
+    var CameraTab = /** @class */ (function (_super) {
         __extends(CameraTab, _super);
         function CameraTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Camera', inspector) || this;
@@ -2853,7 +2850,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var GUITab = (function (_super) {
+    var GUITab = /** @class */ (function (_super) {
         __extends(GUITab, _super);
         function GUITab(tabbar, inspector) {
             return _super.call(this, tabbar, 'GUI', inspector) || this;
@@ -2908,7 +2905,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PhysicsTab = (function (_super) {
+    var PhysicsTab = /** @class */ (function (_super) {
         __extends(PhysicsTab, _super);
         function PhysicsTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Physics', inspector) || this;
@@ -2948,7 +2945,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var SoundTab = (function (_super) {
+    var SoundTab = /** @class */ (function (_super) {
         __extends(SoundTab, _super);
         function SoundTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Audio', inspector) || this;
@@ -2985,7 +2982,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var TextureTab = (function (_super) {
+    var TextureTab = /** @class */ (function (_super) {
         __extends(TextureTab, _super);
         function TextureTab(tabbar, inspector) {
             var _this = _super.call(this, tabbar, 'Textures') || this;
@@ -3054,13 +3051,7 @@ var INSPECTOR;
             for (var i = 0; i < 5; i++) {
                 imgs.push(INSPECTOR.Helpers.CreateElement('img', 'texture-image', this._imagePanel));
             }
-            if (texture instanceof BABYLON.MapTexture) {
-                // instance of Map texture
-                texture.bindTextureForPosSize(new BABYLON.Vector2(0, 0), new BABYLON.Size(texture.getSize().width, texture.getSize().height), false);
-                BABYLON.Tools.DumpFramebuffer(texture.getSize().width, texture.getSize().height, this._inspector.scene.getEngine(), function (data) { return img.src = data; });
-                texture.unbindTexture();
-            }
-            else if (texture instanceof BABYLON.RenderTargetTexture) {
+            if (texture instanceof BABYLON.RenderTargetTexture) {
                 // RenderTarget textures
                 var scene = this._inspector.scene;
                 var engine_1 = scene.getEngine();
@@ -3160,7 +3151,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var LightTab = (function (_super) {
+    var LightTab = /** @class */ (function (_super) {
         __extends(LightTab, _super);
         function LightTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Light', inspector) || this;
@@ -3193,7 +3184,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var MaterialTab = (function (_super) {
+    var MaterialTab = /** @class */ (function (_super) {
         __extends(MaterialTab, _super);
         function MaterialTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Material', inspector) || this;
@@ -3227,7 +3218,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var MeshTab = (function (_super) {
+    var MeshTab = /** @class */ (function (_super) {
         __extends(MeshTab, _super);
         function MeshTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Mesh', inspector) || this;
@@ -3299,7 +3290,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var SceneTab = (function (_super) {
+    var SceneTab = /** @class */ (function (_super) {
         __extends(SceneTab, _super);
         function SceneTab(tabbar, insp) {
             var _this = _super.call(this, tabbar, 'Scene') || this;
@@ -3486,7 +3477,7 @@ var INSPECTOR;
      * - hook all console.log call and display them in this panel (and in the browser console as well)
      * - display all Babylon logs (called with Tools.Log...)
      */
-    var ConsoleTab = (function (_super) {
+    var ConsoleTab = /** @class */ (function (_super) {
         __extends(ConsoleTab, _super);
         function ConsoleTab(tabbar, insp) {
             var _this = _super.call(this, tabbar, 'Console') || this;
@@ -3620,7 +3611,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var StatsTab = (function (_super) {
+    var StatsTab = /** @class */ (function (_super) {
         __extends(StatsTab, _super);
         function StatsTab(tabbar, insp) {
             var _this = _super.call(this, tabbar, 'Stats') || this;
@@ -3909,7 +3900,7 @@ var INSPECTOR;
      * A tab bar will contains each view the inspector can have : Canvas2D, Meshes...
      * The default active tab is the first one of the list.
      */
-    var TabBar = (function (_super) {
+    var TabBar = /** @class */ (function (_super) {
         __extends(TabBar, _super);
         function TabBar(inspector, initialTab) {
             var _this = _super.call(this) || this;
@@ -4103,7 +4094,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var AbstractTool = (function () {
+    var AbstractTool = /** @class */ (function () {
         function AbstractTool(icon, parent, inspector, tooltip) {
             var _this = this;
             this._inspector = inspector;
@@ -4150,7 +4141,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PauseScheduleTool = (function (_super) {
+    var PauseScheduleTool = /** @class */ (function (_super) {
         __extends(PauseScheduleTool, _super);
         function PauseScheduleTool(parent, inspector) {
             var _this = _super.call(this, 'fa-pause', parent, inspector, 'Pause the automatic update of properties') || this;
@@ -4186,7 +4177,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PickTool = (function (_super) {
+    var PickTool = /** @class */ (function (_super) {
         __extends(PickTool, _super);
         function PickTool(parent, inspector) {
             var _this = _super.call(this, 'fa-mouse-pointer', parent, inspector, 'Select a mesh in the scene') || this;
@@ -4247,7 +4238,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PopupTool = (function (_super) {
+    var PopupTool = /** @class */ (function (_super) {
         __extends(PopupTool, _super);
         function PopupTool(parent, inspector) {
             return _super.call(this, 'fa-external-link', parent, inspector, 'Open the inspector in a popup') || this;
@@ -4273,7 +4264,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var RefreshTool = (function (_super) {
+    var RefreshTool = /** @class */ (function (_super) {
         __extends(RefreshTool, _super);
         function RefreshTool(parent, inspector) {
             return _super.call(this, 'fa-refresh', parent, inspector, 'Refresh the current tab') || this;
@@ -4299,7 +4290,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var LabelTool = (function (_super) {
+    var LabelTool = /** @class */ (function (_super) {
         __extends(LabelTool, _super);
         function LabelTool(parent, inspector) {
             var _this = _super.call(this, 'fa-tags', parent, inspector, 'Display mesh names on the canvas') || this;
@@ -4416,7 +4407,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Toolbar = (function (_super) {
+    var Toolbar = /** @class */ (function (_super) {
         __extends(Toolbar, _super);
         function Toolbar(inspector) {
             var _this = _super.call(this) || this;
@@ -4482,7 +4473,7 @@ var INSPECTOR;
     /**
      * Removes the inspector panel
      */
-    var DisposeTool = (function (_super) {
+    var DisposeTool = /** @class */ (function (_super) {
         __extends(DisposeTool, _super);
         function DisposeTool(parent, inspector) {
             return _super.call(this, 'fa-times', parent, inspector, 'Close the inspector panel') || this;
@@ -4508,7 +4499,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var TreeItem = (function (_super) {
+    var TreeItem = /** @class */ (function (_super) {
         __extends(TreeItem, _super);
         function TreeItem(tab, obj) {
             var _this = _super.call(this) || this;
@@ -4665,7 +4656,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var AbstractTreeTool = (function () {
+    var AbstractTreeTool = /** @class */ (function () {
         function AbstractTreeTool() {
             /** Is the tool enabled ? */
             this._on = false;
@@ -4710,7 +4701,7 @@ var INSPECTOR;
     /**
      * Checkbox to display/hide the primitive
      */
-    var BoundingBox = (function (_super) {
+    var BoundingBox = /** @class */ (function (_super) {
         __extends(BoundingBox, _super);
         function BoundingBox(obj) {
             var _this = _super.call(this) || this;
@@ -4757,7 +4748,7 @@ var INSPECTOR;
     /**
      *
      */
-    var CameraPOV = (function (_super) {
+    var CameraPOV = /** @class */ (function (_super) {
         __extends(CameraPOV, _super);
         function CameraPOV(camera) {
             var _this = _super.call(this) || this;
@@ -4801,7 +4792,7 @@ var INSPECTOR;
     /**
      *
      */
-    var SoundInteractions = (function (_super) {
+    var SoundInteractions = /** @class */ (function (_super) {
         __extends(SoundInteractions, _super);
         function SoundInteractions(playSound) {
             var _this = _super.call(this) || this;
@@ -4849,7 +4840,7 @@ var INSPECTOR;
     /**
      * Checkbox to display/hide the primitive
      */
-    var Checkbox = (function (_super) {
+    var Checkbox = /** @class */ (function (_super) {
         __extends(Checkbox, _super);
         function Checkbox(obj) {
             var _this = _super.call(this) || this;
@@ -4899,7 +4890,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var DebugArea = (function (_super) {
+    var DebugArea = /** @class */ (function (_super) {
         __extends(DebugArea, _super);
         function DebugArea(obj) {
             var _this = _super.call(this) || this;
@@ -4939,7 +4930,7 @@ var INSPECTOR;
     /**
      * Checkbox to display/hide the primitive
      */
-    var Info = (function (_super) {
+    var Info = /** @class */ (function (_super) {
         __extends(Info, _super);
         function Info(obj) {
             var _this = _super.call(this) || this;

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


+ 6 - 9
dist/preview release/loaders/babylon.glTF1FileLoader.d.ts

@@ -9,11 +9,11 @@ declare module BABYLON {
         json: Object;
         bin: ArrayBufferView;
     }
-    interface IGLTFLoader {
+    interface IGLTFLoader extends IDisposable {
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
     }
-    class GLTFFileLoader implements ISceneLoaderPluginAsync {
+    class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync {
         static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
         onParsed: (data: IGLTFLoaderData) => void;
@@ -27,19 +27,15 @@ declare module BABYLON {
          */
         onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
         /**
-         * Raised when the visible components (geometry, materials, textures, etc.) are first ready to be rendered.
-         * For assets with LODs, raised when the first LOD is complete.
-         * For assets without LODs, raised when the model is complete just before onComplete.
-         */
-        onReady: () => void;
-        /**
          * Raised when the asset is completely loaded, just before the loader is disposed.
          * For assets with LODs, raised when all of the LODs are complete.
-         * For assets without LODs, raised when the model is complete just after onReady.
+         * For assets without LODs, raised when the model is complete just after onSuccess.
          */
         onComplete: () => void;
+        private _loader;
         name: string;
         extensions: ISceneLoaderPluginExtensions;
+        dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         canDirectLoad(data: string): boolean;
@@ -447,6 +443,7 @@ declare module BABYLON.GLTF1 {
             [name: string]: GLTFLoaderExtension;
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
+        dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): boolean;
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         private _loadShadersAsync(gltfRuntime, onload);

+ 30 - 21
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -11,7 +11,7 @@ var BABYLON;
         // Sets the useRightHandedSystem flag on the scene.
         GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 2] = "FORCE_RIGHT_HANDED";
     })(GLTFLoaderCoordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode || (BABYLON.GLTFLoaderCoordinateSystemMode = {}));
-    var GLTFFileLoader = (function () {
+    var GLTFFileLoader = /** @class */ (function () {
         function GLTFFileLoader() {
             // V2 options
             this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
@@ -21,6 +21,12 @@ var BABYLON;
                 ".glb": { isBinary: true }
             };
         }
+        GLTFFileLoader.prototype.dispose = function () {
+            if (this._loader) {
+                this._loader.dispose();
+                this._loader = null;
+            }
+        };
         GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
             var loaderData = GLTFFileLoader._parse(data, onError);
             if (!loaderData) {
@@ -29,11 +35,11 @@ var BABYLON;
             if (this.onParsed) {
                 this.onParsed(loaderData);
             }
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
-            loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         };
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) {
             var loaderData = GLTFFileLoader._parse(data, onError);
@@ -43,11 +49,11 @@ var BABYLON;
             if (this.onParsed) {
                 this.onParsed(loaderData);
             }
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
-            return loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            return this._loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         };
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
@@ -163,18 +169,18 @@ var BABYLON;
             // Look for BIN chunk
             var bin = null;
             while (binaryReader.getPosition() < binaryReader.getLength()) {
-                chunkLength = binaryReader.readUint32();
-                chunkFormat = binaryReader.readUint32();
-                switch (chunkFormat) {
+                var chunkLength_1 = binaryReader.readUint32();
+                var chunkFormat_1 = binaryReader.readUint32();
+                switch (chunkFormat_1) {
                     case ChunkFormat.JSON:
                         onError("Unexpected JSON chunk");
                         return null;
                     case ChunkFormat.BIN:
-                        bin = binaryReader.readUint8Array(chunkLength);
+                        bin = binaryReader.readUint8Array(chunkLength_1);
                         break;
                     default:
                         // ignore unrecognized chunkFormat
-                        binaryReader.skipBytes(chunkLength);
+                        binaryReader.skipBytes(chunkLength_1);
                         break;
                 }
             }
@@ -207,7 +213,7 @@ var BABYLON;
         GLTFFileLoader._decodeBufferToText = function (buffer) {
             var result = "";
             var length = buffer.byteLength;
-            for (var i = 0; i < length; ++i) {
+            for (var i = 0; i < length; i++) {
                 result += String.fromCharCode(buffer[i]);
             }
             return result;
@@ -218,7 +224,7 @@ var BABYLON;
         return GLTFFileLoader;
     }());
     BABYLON.GLTFFileLoader = GLTFFileLoader;
-    var BinaryReader = (function () {
+    var BinaryReader = /** @class */ (function () {
         function BinaryReader(arrayBuffer) {
             this._arrayBuffer = arrayBuffer;
             this._dataView = new DataView(arrayBuffer);
@@ -364,7 +370,7 @@ var BABYLON;
             ETokenType[ETokenType["UNKNOWN"] = 2] = "UNKNOWN";
             ETokenType[ETokenType["END_OF_INPUT"] = 3] = "END_OF_INPUT";
         })(ETokenType || (ETokenType = {}));
-        var Tokenizer = (function () {
+        var Tokenizer = /** @class */ (function () {
             function Tokenizer(toParse) {
                 this._pos = 0;
                 this.isLetterOrDigitPattern = /^[a-zA-Z0-9]+$/;
@@ -1292,7 +1298,7 @@ var BABYLON;
         /**
         * Implementation of the base glTF spec
         */
-        var GLTFLoaderBase = (function () {
+        var GLTFLoaderBase = /** @class */ (function () {
             function GLTFLoaderBase() {
             }
             GLTFLoaderBase.CreateRuntime = function (parsedData, scene, rootUrl) {
@@ -1587,7 +1593,7 @@ var BABYLON;
         /**
         * glTF V1 Loader
         */
-        var GLTFLoader = (function () {
+        var GLTFLoader = /** @class */ (function () {
             function GLTFLoader() {
             }
             GLTFLoader.RegisterExtension = function (extension) {
@@ -1597,6 +1603,9 @@ var BABYLON;
                 }
                 GLTFLoader.Extensions[extension.name] = extension;
             };
+            GLTFLoader.prototype.dispose = function () {
+                // do nothing
+            };
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
                 var _this = this;
                 scene.useRightHandedSystem = true;
@@ -1771,7 +1780,7 @@ var BABYLON;
         /**
         * Utils functions for GLTF
         */
-        var GLTFUtils = (function () {
+        var GLTFUtils = /** @class */ (function () {
             function GLTFUtils() {
             }
             /**
@@ -2021,7 +2030,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF1;
     (function (GLTF1) {
-        var GLTFLoaderExtension = (function () {
+        var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension(name) {
                 this._name = name;
             }
@@ -2175,7 +2184,7 @@ var BABYLON;
         var BinaryExtensionBufferName = "binary_glTF";
         ;
         ;
-        var GLTFBinaryExtension = (function (_super) {
+        var GLTFBinaryExtension = /** @class */ (function (_super) {
             __extends(GLTFBinaryExtension, _super);
             function GLTFBinaryExtension() {
                 return _super.call(this, "KHR_binary_glTF") || this;
@@ -2252,7 +2261,7 @@ var BABYLON;
         ;
         ;
         ;
-        var GLTFMaterialsCommonExtension = (function (_super) {
+        var GLTFMaterialsCommonExtension = /** @class */ (function (_super) {
             __extends(GLTFMaterialsCommonExtension, _super);
             function GLTFMaterialsCommonExtension() {
                 return _super.call(this, "KHR_materials_common") || this;

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


+ 10 - 12
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -9,11 +9,11 @@ declare module BABYLON {
         json: Object;
         bin: ArrayBufferView;
     }
-    interface IGLTFLoader {
+    interface IGLTFLoader extends IDisposable {
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
     }
-    class GLTFFileLoader implements ISceneLoaderPluginAsync {
+    class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync {
         static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
         onParsed: (data: IGLTFLoaderData) => void;
@@ -27,19 +27,15 @@ declare module BABYLON {
          */
         onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
         /**
-         * Raised when the visible components (geometry, materials, textures, etc.) are first ready to be rendered.
-         * For assets with LODs, raised when the first LOD is complete.
-         * For assets without LODs, raised when the model is complete just before onComplete.
-         */
-        onReady: () => void;
-        /**
          * Raised when the asset is completely loaded, just before the loader is disposed.
          * For assets with LODs, raised when all of the LODs are complete.
-         * For assets without LODs, raised when the model is complete just after onReady.
+         * For assets without LODs, raised when the model is complete just after onSuccess.
          */
         onComplete: () => void;
+        private _loader;
         name: string;
         extensions: ISceneLoaderPluginExtensions;
+        dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         canDirectLoad(data: string): boolean;
@@ -305,9 +301,10 @@ declare module BABYLON.GLTF2 {
 
 
 declare module BABYLON.GLTF2 {
-    class GLTFLoader implements IGLTFLoader, IDisposable {
+    class GLTFLoader implements IGLTFLoader {
         _gltf: IGLTF;
         _babylonScene: Scene;
+        private _disposed;
         private _parent;
         private _rootUrl;
         private _defaultMaterial;
@@ -316,7 +313,7 @@ declare module BABYLON.GLTF2 {
         private _progressCallback;
         private _errorCallback;
         private _renderReady;
-        private _disposed;
+        private _requests;
         private _renderReadyObservable;
         private _renderPendingCount;
         private _loaderPendingCount;
@@ -364,7 +361,7 @@ declare module BABYLON.GLTF2 {
         private _loadBufferViewAsync(context, bufferView, onSuccess);
         private _loadAccessorAsync(context, accessor, onSuccess);
         private _getNumComponentsOfType(type);
-        private _buildArrayBuffer<T>(typedArray, context, data, byteOffset, count, numComponents, byteStride);
+        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride);
         _addPendingData(data: any): void;
         _removePendingData(data: any): void;
         _addLoaderPendingData(data: any): void;
@@ -378,6 +375,7 @@ declare module BABYLON.GLTF2 {
         _loadMaterialAlphaProperties(context: string, material: IGLTFMaterial, colorFactor: number[]): void;
         _loadTexture(context: string, texture: IGLTFTexture, coordinatesIndex: number): Texture;
         private _loadImage(context, image, onSuccess);
+        _loadUri(context: string, uri: string, onSuccess: (data: ArrayBufferView) => void): void;
         _tryCatchOnError(handler: () => void): void;
     }
 }

+ 243 - 200
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -11,7 +11,7 @@ var BABYLON;
         // Sets the useRightHandedSystem flag on the scene.
         GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 2] = "FORCE_RIGHT_HANDED";
     })(GLTFLoaderCoordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode || (BABYLON.GLTFLoaderCoordinateSystemMode = {}));
-    var GLTFFileLoader = (function () {
+    var GLTFFileLoader = /** @class */ (function () {
         function GLTFFileLoader() {
             // V2 options
             this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
@@ -21,6 +21,12 @@ var BABYLON;
                 ".glb": { isBinary: true }
             };
         }
+        GLTFFileLoader.prototype.dispose = function () {
+            if (this._loader) {
+                this._loader.dispose();
+                this._loader = null;
+            }
+        };
         GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
             var loaderData = GLTFFileLoader._parse(data, onError);
             if (!loaderData) {
@@ -29,11 +35,11 @@ var BABYLON;
             if (this.onParsed) {
                 this.onParsed(loaderData);
             }
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
-            loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         };
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) {
             var loaderData = GLTFFileLoader._parse(data, onError);
@@ -43,11 +49,11 @@ var BABYLON;
             if (this.onParsed) {
                 this.onParsed(loaderData);
             }
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
-            return loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            return this._loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         };
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
@@ -163,18 +169,18 @@ var BABYLON;
             // Look for BIN chunk
             var bin = null;
             while (binaryReader.getPosition() < binaryReader.getLength()) {
-                chunkLength = binaryReader.readUint32();
-                chunkFormat = binaryReader.readUint32();
-                switch (chunkFormat) {
+                var chunkLength_1 = binaryReader.readUint32();
+                var chunkFormat_1 = binaryReader.readUint32();
+                switch (chunkFormat_1) {
                     case ChunkFormat.JSON:
                         onError("Unexpected JSON chunk");
                         return null;
                     case ChunkFormat.BIN:
-                        bin = binaryReader.readUint8Array(chunkLength);
+                        bin = binaryReader.readUint8Array(chunkLength_1);
                         break;
                     default:
                         // ignore unrecognized chunkFormat
-                        binaryReader.skipBytes(chunkLength);
+                        binaryReader.skipBytes(chunkLength_1);
                         break;
                 }
             }
@@ -207,7 +213,7 @@ var BABYLON;
         GLTFFileLoader._decodeBufferToText = function (buffer) {
             var result = "";
             var length = buffer.byteLength;
-            for (var i = 0; i < length; ++i) {
+            for (var i = 0; i < length; i++) {
                 result += String.fromCharCode(buffer[i]);
             }
             return result;
@@ -218,7 +224,7 @@ var BABYLON;
         return GLTFFileLoader;
     }());
     BABYLON.GLTFFileLoader = GLTFFileLoader;
-    var BinaryReader = (function () {
+    var BinaryReader = /** @class */ (function () {
         function BinaryReader(arrayBuffer) {
             this._arrayBuffer = arrayBuffer;
             this._dataView = new DataView(arrayBuffer);
@@ -309,7 +315,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        var GLTFLoaderTracker = (function () {
+        var GLTFLoaderTracker = /** @class */ (function () {
             function GLTFLoaderTracker(onComplete) {
                 this._pendingCount = 0;
                 this._callback = onComplete;
@@ -324,10 +330,11 @@ var BABYLON;
             };
             return GLTFLoaderTracker;
         }());
-        var GLTFLoader = (function () {
+        var GLTFLoader = /** @class */ (function () {
             function GLTFLoader(parent) {
-                this._renderReady = false;
                 this._disposed = false;
+                this._renderReady = false;
+                this._requests = new Array();
                 this._renderReadyObservable = new BABYLON.Observable();
                 // Count of pending work that needs to complete before the asset is rendered.
                 this._renderPendingCount = 0;
@@ -350,24 +357,37 @@ var BABYLON;
                     return;
                 }
                 this._disposed = true;
+                // Abort requests that are not complete
+                for (var _i = 0, _a = this._requests; _i < _a.length; _i++) {
+                    var request = _a[_i];
+                    if (request.readyState !== (XMLHttpRequest.DONE || 4)) {
+                        request.abort();
+                    }
+                }
                 // Revoke object urls created during load
                 if (this._gltf.textures) {
-                    this._gltf.textures.forEach(function (texture) {
+                    for (var _b = 0, _c = this._gltf.textures; _b < _c.length; _b++) {
+                        var texture = _c[_b];
                         if (texture.url) {
                             URL.revokeObjectURL(texture.url);
                         }
-                    });
+                    }
                 }
                 this._gltf = undefined;
                 this._babylonScene = undefined;
+                this._parent = undefined;
                 this._rootUrl = undefined;
                 this._defaultMaterial = undefined;
+                this._rootNode = undefined;
                 this._successCallback = undefined;
+                this._progressCallback = undefined;
                 this._errorCallback = undefined;
                 this._renderReady = false;
-                this._renderReadyObservable.clear();
+                this._requests = undefined;
+                this._renderReadyObservable = undefined;
                 this._renderPendingCount = 0;
                 this._loaderPendingCount = 0;
+                this._loaderTrackers = undefined;
             };
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
                 var _this = this;
@@ -435,9 +455,6 @@ var BABYLON;
                 this._startAnimations();
                 this._successCallback();
                 this._renderReadyObservable.notifyObservers(this);
-                if (this._parent.onReady) {
-                    this._parent.onReady();
-                }
             };
             GLTFLoader.prototype._onComplete = function () {
                 if (this._parent.onComplete) {
@@ -465,11 +482,12 @@ var BABYLON;
                 var meshes = [this._rootNode.babylonMesh];
                 var nodes = this._gltf.nodes;
                 if (nodes) {
-                    nodes.forEach(function (node) {
+                    for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                        var node = nodes_1[_i];
                         if (node.babylonMesh) {
                             meshes.push(node.babylonMesh);
                         }
-                    });
+                    }
                 }
                 return meshes;
             };
@@ -477,11 +495,12 @@ var BABYLON;
                 var skeletons = new Array();
                 var skins = this._gltf.skins;
                 if (skins) {
-                    skins.forEach(function (skin) {
+                    for (var _i = 0, skins_1 = skins; _i < skins_1.length; _i++) {
+                        var skin = skins_1[_i];
                         if (skin.babylonSkeleton instanceof BABYLON.Skeleton) {
                             skeletons.push(skin.babylonSkeleton);
                         }
-                    });
+                    }
                 }
                 return skeletons;
             };
@@ -489,15 +508,18 @@ var BABYLON;
                 var targets = new Array();
                 var animations = this._gltf.animations;
                 if (animations) {
-                    animations.forEach(function (animation) {
+                    for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                        var animation = animations_1[_i];
                         targets.push.apply(targets, animation.targets);
-                    });
+                    }
                 }
                 return targets;
             };
             GLTFLoader.prototype._startAnimations = function () {
-                var _this = this;
-                this._getAnimationTargets().forEach(function (target) { return _this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true); });
+                for (var _i = 0, _a = this._getAnimationTargets(); _i < _a.length; _i++) {
+                    var target = _a[_i];
+                    this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
+                }
             };
             GLTFLoader.prototype._loadDefaultScene = function (nodeNames) {
                 var scene = GLTF2.GLTFUtils.GetArrayItem(this._gltf.scenes, this._gltf.scene || 0);
@@ -534,22 +556,23 @@ var BABYLON;
                     if (!(nodeNames instanceof Array)) {
                         nodeNames = [nodeNames];
                     }
-                    var filteredNodeIndices = new Array();
+                    var filteredNodeIndices_1 = new Array();
                     this._traverseNodes(context, nodeIndices, function (node) {
                         if (nodeNames.indexOf(node.name) !== -1) {
-                            filteredNodeIndices.push(node.index);
+                            filteredNodeIndices_1.push(node.index);
                             return false;
                         }
                         return true;
                     }, this._rootNode);
-                    nodeIndices = filteredNodeIndices;
+                    nodeIndices = filteredNodeIndices_1;
                 }
-                for (var i = 0; i < nodeIndices.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, nodeIndices[i]);
+                for (var _i = 0, nodeIndices_1 = nodeIndices; _i < nodeIndices_1.length; _i++) {
+                    var index = nodeIndices_1[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find node " + nodeIndices[i]);
+                        throw new Error(context + ": Failed to find node " + index);
                     }
-                    this._loadNode("#/nodes/" + nodeIndices[i], node);
+                    this._loadNode("#/nodes/" + index, node);
                 }
                 // Disable the root mesh until the asset is ready to render.
                 this._rootNode.babylonMesh.setEnabled(false);
@@ -581,25 +604,26 @@ var BABYLON;
                     // TODO: handle cameras
                 }
                 if (node.children) {
-                    for (var i = 0; i < node.children.length; i++) {
-                        var childNode = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, node.children[i]);
+                    for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
+                        var index = _a[_i];
+                        var childNode = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                         if (!childNode) {
-                            throw new Error(context + ": Failed to find child node " + node.children[i]);
+                            throw new Error(context + ": Failed to find child node " + index);
                         }
-                        this._loadNode("#/nodes/" + node.children[i], childNode);
+                        this._loadNode("#/nodes/" + index, childNode);
                     }
                 }
             };
             GLTFLoader.prototype._loadMesh = function (context, node, mesh) {
                 var _this = this;
                 node.babylonMesh.name = node.babylonMesh.name || mesh.name;
-                if (!mesh.primitives || mesh.primitives.length === 0) {
+                var primitives = mesh.primitives;
+                if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
                 this._createMorphTargets(context, node, mesh);
                 this._loadAllVertexDataAsync(context, mesh, function () {
                     _this._loadMorphTargets(context, node, mesh);
-                    var primitives = mesh.primitives;
                     var vertexData = new BABYLON.VertexData();
                     for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
                         var primitive = primitives_1[_i];
@@ -612,63 +636,68 @@ var BABYLON;
                     var verticesStart = 0;
                     var indicesStart = 0;
                     for (var index = 0; index < primitives.length; index++) {
-                        var vertexData = primitives[index].vertexData;
-                        var verticesCount = vertexData.positions.length;
-                        var indicesCount = vertexData.indices.length;
+                        var vertexData_1 = primitives[index].vertexData;
+                        var verticesCount = vertexData_1.positions.length;
+                        var indicesCount = vertexData_1.indices.length;
                         BABYLON.SubMesh.AddToMesh(index, verticesStart, verticesCount, indicesStart, indicesCount, node.babylonMesh);
                         verticesStart += verticesCount;
                         indicesStart += indicesCount;
                     }
                     ;
-                    var multiMaterial = new BABYLON.MultiMaterial(node.babylonMesh.name, _this._babylonScene);
-                    node.babylonMesh.material = multiMaterial;
-                    var subMaterials = multiMaterial.subMaterials;
-                    for (var index = 0; index < primitives.length; index++) {
-                        var primitive = primitives[index];
-                        if (primitive.material == null) {
-                            subMaterials[index] = _this._getDefaultMaterial();
+                });
+                var multiMaterial = new BABYLON.MultiMaterial(node.babylonMesh.name, this._babylonScene);
+                node.babylonMesh.material = multiMaterial;
+                var subMaterials = multiMaterial.subMaterials;
+                var _loop_1 = function (index) {
+                    var primitive = primitives[index];
+                    if (primitive.material == null) {
+                        subMaterials[index] = this_1._getDefaultMaterial();
+                    }
+                    else {
+                        var material_1 = GLTF2.GLTFUtils.GetArrayItem(this_1._gltf.materials, primitive.material);
+                        if (!material_1) {
+                            throw new Error(context + ": Failed to find material " + primitive.material);
                         }
-                        else {
-                            var material = GLTF2.GLTFUtils.GetArrayItem(_this._gltf.materials, primitive.material);
-                            if (!material) {
-                                throw new Error(context + ": Failed to find material " + primitive.material);
+                        this_1._loadMaterial("#/materials/" + material_1.index, material_1, function (babylonMaterial, isNew) {
+                            if (isNew && _this._parent.onMaterialLoaded) {
+                                _this._parent.onMaterialLoaded(babylonMaterial);
                             }
-                            var capturedIndex = index;
-                            _this._loadMaterial("#/materials/" + material.index, material, function (babylonMaterial, isNew) {
-                                if (isNew && _this._parent.onMaterialLoaded) {
-                                    _this._parent.onMaterialLoaded(babylonMaterial);
-                                }
-                                if (_this._parent.onBeforeMaterialReadyAsync) {
-                                    _this._addLoaderPendingData(material);
-                                    _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, node.babylonMesh, subMaterials[capturedIndex] != null, function () {
-                                        subMaterials[capturedIndex] = babylonMaterial;
-                                        _this._removeLoaderPendingData(material);
+                            if (_this._parent.onBeforeMaterialReadyAsync) {
+                                _this._addLoaderPendingData(material_1);
+                                _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, node.babylonMesh, subMaterials[index] != null, function () {
+                                    _this._tryCatchOnError(function () {
+                                        subMaterials[index] = babylonMaterial;
+                                        _this._removeLoaderPendingData(material_1);
                                     });
-                                }
-                                else {
-                                    subMaterials[capturedIndex] = babylonMaterial;
-                                }
-                            });
-                        }
+                                });
+                            }
+                            else {
+                                subMaterials[index] = babylonMaterial;
+                            }
+                        });
                     }
-                    ;
-                });
+                };
+                var this_1 = this;
+                for (var index = 0; index < primitives.length; index++) {
+                    _loop_1(index);
+                }
+                ;
             };
             GLTFLoader.prototype._loadAllVertexDataAsync = function (context, mesh, onSuccess) {
                 var primitives = mesh.primitives;
                 var numRemainingPrimitives = primitives.length;
-                var _loop_1 = function () {
+                var _loop_2 = function (index) {
                     var primitive = primitives[index];
-                    this_1._loadVertexDataAsync(context + "/primitive/" + index, mesh, primitive, function (vertexData) {
+                    this_2._loadVertexDataAsync(context + "/primitive/" + index, mesh, primitive, function (vertexData) {
                         primitive.vertexData = vertexData;
                         if (--numRemainingPrimitives === 0) {
                             onSuccess();
                         }
                     });
                 };
-                var this_1 = this;
+                var this_2 = this;
                 for (var index = 0; index < primitives.length; index++) {
-                    _loop_1();
+                    _loop_2(index);
                 }
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, mesh, primitive, onSuccess) {
@@ -683,12 +712,12 @@ var BABYLON;
                 }
                 var vertexData = new BABYLON.VertexData();
                 var numRemainingAttributes = Object.keys(attributes).length;
-                var _loop_2 = function (attribute) {
-                    accessor = GLTF2.GLTFUtils.GetArrayItem(this_2._gltf.accessors, attributes[attribute]);
+                var _loop_3 = function (attribute) {
+                    var accessor = GLTF2.GLTFUtils.GetArrayItem(this_3._gltf.accessors, attributes[attribute]);
                     if (!accessor) {
                         throw new Error(context + ": Failed to find attribute '" + attribute + "' accessor " + attributes[attribute]);
                     }
-                    this_2._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
+                    this_3._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
                         switch (attribute) {
                             case "NORMAL":
                                 vertexData.normals = data;
@@ -721,7 +750,9 @@ var BABYLON;
                         if (--numRemainingAttributes === 0) {
                             if (primitive.indices == null) {
                                 vertexData.indices = new Uint32Array(vertexData.positions.length / 3);
-                                vertexData.indices.forEach(function (v, i) { return vertexData.indices[i] = i; });
+                                for (var i = 0; i < vertexData.indices.length; i++) {
+                                    vertexData.indices[i] = i;
+                                }
                                 onSuccess(vertexData);
                             }
                             else {
@@ -737,9 +768,9 @@ var BABYLON;
                         }
                     });
                 };
-                var this_2 = this, accessor;
+                var this_3 = this;
                 for (var attribute in attributes) {
-                    _loop_2(attribute);
+                    _loop_3(attribute);
                 }
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh) {
@@ -783,33 +814,36 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadAllMorphTargetVertexDataAsync = function (context, node, mesh, onSuccess) {
                 var numRemainingTargets = mesh.primitives.length * node.babylonMesh.morphTargetManager.numTargets;
-                for (var _i = 0, _a = mesh.primitives; _i < _a.length; _i++) {
-                    var primitive = _a[_i];
+                var _loop_4 = function (primitive) {
                     var targets = primitive.targets;
                     primitive.targetsVertexData = new Array(targets.length);
-                    var _loop_3 = function (index) {
-                        this_3._loadMorphTargetVertexDataAsync(context + "/targets/" + index, primitive.vertexData, targets[index], function (vertexData) {
+                    var _loop_5 = function (index) {
+                        this_4._loadMorphTargetVertexDataAsync(context + "/targets/" + index, primitive.vertexData, targets[index], function (vertexData) {
                             primitive.targetsVertexData[index] = vertexData;
                             if (--numRemainingTargets === 0) {
                                 onSuccess();
                             }
                         });
                     };
-                    var this_3 = this;
                     for (var index = 0; index < targets.length; index++) {
-                        _loop_3(index);
+                        _loop_5(index);
                     }
+                };
+                var this_4 = this;
+                for (var _i = 0, _a = mesh.primitives; _i < _a.length; _i++) {
+                    var primitive = _a[_i];
+                    _loop_4(primitive);
                 }
             };
             GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, vertexData, attributes, onSuccess) {
                 var targetVertexData = new BABYLON.VertexData();
                 var numRemainingAttributes = Object.keys(attributes).length;
-                var _loop_4 = function (attribute) {
-                    accessor = GLTF2.GLTFUtils.GetArrayItem(this_4._gltf.accessors, attributes[attribute]);
+                var _loop_6 = function (attribute) {
+                    var accessor = GLTF2.GLTFUtils.GetArrayItem(this_5._gltf.accessors, attributes[attribute]);
                     if (!accessor) {
                         throw new Error(context + ": Failed to find attribute '" + attribute + "' accessor " + attributes[attribute]);
                     }
-                    this_4._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
+                    this_5._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
                         // glTF stores morph target information as deltas while babylon.js expects the final data.
                         // As a result we have to add the original data to the delta to calculate the final data.
                         var values = data;
@@ -847,9 +881,9 @@ var BABYLON;
                         }
                     });
                 };
-                var this_4 = this, accessor;
+                var this_5 = this;
                 for (var attribute in attributes) {
-                    _loop_4(attribute);
+                    _loop_6(attribute);
                 }
             };
             GLTFLoader.prototype._loadTransform = function (node) {
@@ -857,8 +891,8 @@ var BABYLON;
                 var rotation = BABYLON.Quaternion.Identity();
                 var scaling = BABYLON.Vector3.One();
                 if (node.matrix) {
-                    var mat = BABYLON.Matrix.FromArray(node.matrix);
-                    mat.decompose(scaling, rotation, position);
+                    var matrix = BABYLON.Matrix.FromArray(node.matrix);
+                    matrix.decompose(scaling, rotation, position);
                 }
                 else {
                     if (node.translation)
@@ -900,10 +934,11 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadBones = function (context, skin, inverseBindMatrixData) {
                 var babylonBones = {};
-                for (var i = 0; i < skin.joints.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, skin.joints[i]);
+                for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) {
+                    var index = _a[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find joint " + skin.joints[i]);
+                        throw new Error(context + ": Failed to find joint " + index);
                     }
                     this._loadBone(node, skin, inverseBindMatrixData, babylonBones);
                 }
@@ -935,10 +970,11 @@ var BABYLON;
             };
             GLTFLoader.prototype._traverseNodes = function (context, indices, action, parentNode) {
                 if (parentNode === void 0) { parentNode = null; }
-                for (var i = 0; i < indices.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, indices[i]);
+                for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
+                    var index = indices_1[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find node " + indices[i]);
+                        throw new Error(context + ": Failed to find node " + index);
                     }
                     this._traverseNode(context, node, action, parentNode);
                 }
@@ -1071,7 +1107,7 @@ var BABYLON;
                     animation.targets = animation.targets || [];
                     if (targetPath === "influence") {
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
-                        for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
+                        var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
                             var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
@@ -1083,14 +1119,17 @@ var BABYLON;
                             }); }));
                             morphTarget.animations.push(babylonAnimation);
                             animation.targets.push(morphTarget);
+                        };
+                        for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
+                            _loop_7(targetIndex);
                         }
                     }
                     else {
                         var animationName = animation.name || "anim" + animation.index;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
-                        for (var i = 0; i < targetNode.babylonAnimationTargets.length; i++) {
-                            var target = targetNode.babylonAnimationTargets[i];
+                        for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
+                            var target = _a[_i];
                             target.animations.push(babylonAnimation.clone());
                             animation.targets.push(target);
                         }
@@ -1137,28 +1176,15 @@ var BABYLON;
                         this._removePendingData(buffer);
                     }
                     else {
-                        if (!GLTF2.GLTFUtils.ValidateUri(buffer.uri)) {
-                            throw new Error(context + ": Uri '" + buffer.uri + "' is invalid");
-                        }
                         buffer.loadedObservable = new BABYLON.Observable();
                         buffer.loadedObservable.add(function (buffer) {
                             onSuccess(buffer.loadedData);
                             _this._removePendingData(buffer);
                         });
-                        BABYLON.Tools.LoadFile(this._rootUrl + buffer.uri, function (data) {
-                            _this._tryCatchOnError(function () {
-                                buffer.loadedData = new Uint8Array(data);
-                                buffer.loadedObservable.notifyObservers(buffer);
-                                buffer.loadedObservable = null;
-                            });
-                        }, function (event) {
-                            _this._tryCatchOnError(function () {
-                                _this._onProgress(event);
-                            });
-                        }, this._babylonScene.database, true, function (request) {
-                            _this._tryCatchOnError(function () {
-                                throw new Error(context + ": Failed to load '" + buffer.uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
-                            });
+                        this._loadUri(context, buffer.uri, function (data) {
+                            buffer.loadedData = data;
+                            buffer.loadedObservable.notifyObservers(buffer);
+                            buffer.loadedObservable = null;
                         });
                     }
                 }
@@ -1173,8 +1199,9 @@ var BABYLON;
                     if (_this._disposed) {
                         return;
                     }
+                    var data;
                     try {
-                        var data = new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        data = new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -1200,27 +1227,32 @@ var BABYLON;
                         throw new Error(context + ": Invalid type (" + accessor.type + ")");
                     }
                     var data;
-                    switch (accessor.componentType) {
-                        case GLTF2.EComponentType.BYTE:
-                            data = _this._buildArrayBuffer(Float32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_BYTE:
-                            data = _this._buildArrayBuffer(Uint8Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.SHORT:
-                            data = _this._buildArrayBuffer(Int16Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_SHORT:
-                            data = _this._buildArrayBuffer(Uint16Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_INT:
-                            data = _this._buildArrayBuffer(Uint32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.FLOAT:
-                            data = _this._buildArrayBuffer(Float32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        default:
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                    try {
+                        switch (accessor.componentType) {
+                            case GLTF2.EComponentType.BYTE:
+                                data = _this._buildArrayBuffer(Float32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_BYTE:
+                                data = _this._buildArrayBuffer(Uint8Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.SHORT:
+                                data = _this._buildArrayBuffer(Int16Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_SHORT:
+                                data = _this._buildArrayBuffer(Uint16Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_INT:
+                                data = _this._buildArrayBuffer(Uint32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.FLOAT:
+                                data = _this._buildArrayBuffer(Float32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            default:
+                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                        }
+                    }
+                    catch (e) {
+                        throw new Error(context + ": " + e);
                     }
                     onSuccess(data);
                 });
@@ -1237,30 +1269,25 @@ var BABYLON;
                 }
                 return 0;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, context, data, byteOffset, count, numComponents, byteStride) {
-                try {
-                    var byteOffset = data.byteOffset + (byteOffset || 0);
-                    var targetLength = count * numComponents;
-                    if (byteStride == null || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                        return new typedArray(data.buffer, byteOffset, targetLength);
-                    }
-                    var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                    var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                    var targetBuffer = new typedArray(targetLength);
-                    var sourceIndex = 0;
-                    var targetIndex = 0;
-                    while (targetIndex < targetLength) {
-                        for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                            targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                            targetIndex++;
-                        }
-                        sourceIndex += elementStride;
+            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
+                byteOffset = data.byteOffset + (byteOffset || 0);
+                var targetLength = count * numComponents;
+                if (byteStride == null || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
+                    return new typedArray(data.buffer, byteOffset, targetLength);
+                }
+                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
+                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
+                var targetBuffer = new typedArray(targetLength);
+                var sourceIndex = 0;
+                var targetIndex = 0;
+                while (targetIndex < targetLength) {
+                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
+                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
+                        targetIndex++;
                     }
-                    return targetBuffer;
-                }
-                catch (e) {
-                    throw new Error(context + ": " + e);
+                    sourceIndex += elementStride;
                 }
+                return targetBuffer;
             };
             GLTFLoader.prototype._addPendingData = function (data) {
                 if (!this._renderReady) {
@@ -1279,10 +1306,16 @@ var BABYLON;
             };
             GLTFLoader.prototype._addLoaderPendingData = function (data) {
                 this._loaderPendingCount++;
-                this._loaderTrackers.forEach(function (tracker) { return tracker._addPendingData(data); });
+                for (var _i = 0, _a = this._loaderTrackers; _i < _a.length; _i++) {
+                    var tracker = _a[_i];
+                    tracker._addPendingData(data);
+                }
             };
             GLTFLoader.prototype._removeLoaderPendingData = function (data) {
-                this._loaderTrackers.forEach(function (tracker) { return tracker._removePendingData(data); });
+                for (var _i = 0, _a = this._loaderTrackers; _i < _a.length; _i++) {
+                    var tracker = _a[_i];
+                    tracker._removePendingData(data);
+                }
                 if (--this._loaderPendingCount === 0) {
                     this._onComplete();
                 }
@@ -1464,12 +1497,12 @@ var BABYLON;
                     texture.dataReadyObservable.add(function (texture) {
                         babylonTexture.updateURL(texture.url);
                     });
-                    var image = GLTF2.GLTFUtils.GetArrayItem(this._gltf.images, texture.source);
-                    if (!image) {
+                    var image_1 = GLTF2.GLTFUtils.GetArrayItem(this._gltf.images, texture.source);
+                    if (!image_1) {
                         throw new Error(context + ": Failed to find source " + texture.source);
                     }
-                    this._loadImage("#/images/" + image.index, image, function (data) {
-                        texture.url = URL.createObjectURL(new Blob([data], { type: image.mimeType }));
+                    this._loadImage("#/images/" + image_1.index, image_1, function (data) {
+                        texture.url = URL.createObjectURL(new Blob([data], { type: image_1.mimeType }));
                         texture.dataReadyObservable.notifyObservers(texture);
                     });
                 }
@@ -1483,28 +1516,12 @@ var BABYLON;
                 return babylonTexture;
             };
             GLTFLoader.prototype._loadImage = function (context, image, onSuccess) {
-                var _this = this;
                 if (image.uri) {
-                    if (!GLTF2.GLTFUtils.ValidateUri(image.uri)) {
-                        throw new Error(context + ": Uri '" + image.uri + "' is invalid");
-                    }
                     if (GLTF2.GLTFUtils.IsBase64(image.uri)) {
                         onSuccess(new Uint8Array(GLTF2.GLTFUtils.DecodeBase64(image.uri)));
                     }
                     else {
-                        BABYLON.Tools.LoadFile(this._rootUrl + image.uri, function (data) {
-                            _this._tryCatchOnError(function () {
-                                onSuccess(data);
-                            });
-                        }, function (event) {
-                            _this._tryCatchOnError(function () {
-                                _this._onProgress(event);
-                            });
-                        }, this._babylonScene.database, true, function (request) {
-                            _this._tryCatchOnError(function () {
-                                throw new Error(context + ": Failed to load '" + image.uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
-                            });
-                        });
+                        this._loadUri(context, image.uri, onSuccess);
                     }
                 }
                 else {
@@ -1515,6 +1532,28 @@ var BABYLON;
                     this._loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView, onSuccess);
                 }
             };
+            GLTFLoader.prototype._loadUri = function (context, uri, onSuccess) {
+                var _this = this;
+                if (!GLTF2.GLTFUtils.ValidateUri(uri)) {
+                    throw new Error(context + ": Uri '" + uri + "' is invalid");
+                }
+                var request = BABYLON.Tools.LoadFile(this._rootUrl + uri, function (data) {
+                    _this._tryCatchOnError(function () {
+                        onSuccess(new Uint8Array(data));
+                    });
+                }, function (event) {
+                    _this._tryCatchOnError(function () {
+                        _this._onProgress(event);
+                    });
+                }, this._babylonScene.database, true, function (request) {
+                    _this._tryCatchOnError(function () {
+                        throw new Error(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
+                    });
+                });
+                if (request) {
+                    this._requests.push(request);
+                }
+            };
             GLTFLoader.prototype._tryCatchOnError = function (handler) {
                 try {
                     handler();
@@ -1541,7 +1580,7 @@ var BABYLON;
         /**
         * Utils functions for GLTF
         */
-        var GLTFUtils = (function () {
+        var GLTFUtils = /** @class */ (function () {
             function GLTFUtils() {
             }
             /**
@@ -1639,7 +1678,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        var GLTFLoaderExtension = (function () {
+        var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension() {
                 this.enabled = true;
             }
@@ -1677,8 +1716,8 @@ var BABYLON;
                 if (!extensions) {
                     return false;
                 }
-                for (var i = 0; i < extensions.length; i++) {
-                    var extension = extensions[i];
+                for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
+                    var extension = extensions_1[_i];
                     if (extension.enabled && action(extension)) {
                         return true;
                     }
@@ -1715,7 +1754,7 @@ var BABYLON;
         var Extensions;
         (function (Extensions) {
             // See https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod for more information about this extension.
-            var MSFTLOD = (function (_super) {
+            var MSFTLOD = /** @class */ (function (_super) {
                 __extends(MSFTLOD, _super);
                 function MSFTLOD() {
                     return _super !== null && _super.apply(this, arguments) || this;
@@ -1765,7 +1804,9 @@ var BABYLON;
                             return;
                         }
                         setTimeout(function () {
-                            _this._loadNodeLOD(loader, context, nodes, index - 1, onComplete);
+                            loader._tryCatchOnError(function () {
+                                _this._loadNodeLOD(loader, context, nodes, index - 1, onComplete);
+                            });
                         }, MSFTLOD.MinimalLODDelay);
                     });
                 };
@@ -1794,7 +1835,9 @@ var BABYLON;
                         loader._executeWhenRenderReady(function () {
                             BABYLON.BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), function () {
                                 setTimeout(function () {
-                                    _this._loadMaterialLOD(loader, context, materials, index - 1, assign, onComplete);
+                                    loader._tryCatchOnError(function () {
+                                        _this._loadMaterialLOD(loader, context, materials, index - 1, assign, onComplete);
+                                    });
                                 }, MSFTLOD.MinimalLODDelay);
                             });
                         });
@@ -1831,7 +1874,7 @@ var BABYLON;
     (function (GLTF2) {
         var Extensions;
         (function (Extensions) {
-            var KHRMaterialsPbrSpecularGlossiness = (function (_super) {
+            var KHRMaterialsPbrSpecularGlossiness = /** @class */ (function (_super) {
                 __extends(KHRMaterialsPbrSpecularGlossiness, _super);
                 function KHRMaterialsPbrSpecularGlossiness() {
                     return _super !== null && _super.apply(this, arguments) || this;

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


+ 11 - 12
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -9,11 +9,11 @@ declare module BABYLON {
         json: Object;
         bin: ArrayBufferView;
     }
-    interface IGLTFLoader {
+    interface IGLTFLoader extends IDisposable {
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
     }
-    class GLTFFileLoader implements ISceneLoaderPluginAsync {
+    class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync {
         static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
         onParsed: (data: IGLTFLoaderData) => void;
@@ -27,19 +27,15 @@ declare module BABYLON {
          */
         onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
         /**
-         * Raised when the visible components (geometry, materials, textures, etc.) are first ready to be rendered.
-         * For assets with LODs, raised when the first LOD is complete.
-         * For assets without LODs, raised when the model is complete just before onComplete.
-         */
-        onReady: () => void;
-        /**
          * Raised when the asset is completely loaded, just before the loader is disposed.
          * For assets with LODs, raised when all of the LODs are complete.
-         * For assets without LODs, raised when the model is complete just after onReady.
+         * For assets without LODs, raised when the model is complete just after onSuccess.
          */
         onComplete: () => void;
+        private _loader;
         name: string;
         extensions: ISceneLoaderPluginExtensions;
+        dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         canDirectLoad(data: string): boolean;
@@ -447,6 +443,7 @@ declare module BABYLON.GLTF1 {
             [name: string]: GLTFLoaderExtension;
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
+        dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): boolean;
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         private _loadShadersAsync(gltfRuntime, onload);
@@ -851,9 +848,10 @@ declare module BABYLON.GLTF2 {
 
 
 declare module BABYLON.GLTF2 {
-    class GLTFLoader implements IGLTFLoader, IDisposable {
+    class GLTFLoader implements IGLTFLoader {
         _gltf: IGLTF;
         _babylonScene: Scene;
+        private _disposed;
         private _parent;
         private _rootUrl;
         private _defaultMaterial;
@@ -862,7 +860,7 @@ declare module BABYLON.GLTF2 {
         private _progressCallback;
         private _errorCallback;
         private _renderReady;
-        private _disposed;
+        private _requests;
         private _renderReadyObservable;
         private _renderPendingCount;
         private _loaderPendingCount;
@@ -910,7 +908,7 @@ declare module BABYLON.GLTF2 {
         private _loadBufferViewAsync(context, bufferView, onSuccess);
         private _loadAccessorAsync(context, accessor, onSuccess);
         private _getNumComponentsOfType(type);
-        private _buildArrayBuffer<T>(typedArray, context, data, byteOffset, count, numComponents, byteStride);
+        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride);
         _addPendingData(data: any): void;
         _removePendingData(data: any): void;
         _addLoaderPendingData(data: any): void;
@@ -924,6 +922,7 @@ declare module BABYLON.GLTF2 {
         _loadMaterialAlphaProperties(context: string, material: IGLTFMaterial, colorFactor: number[]): void;
         _loadTexture(context: string, texture: IGLTFTexture, coordinatesIndex: number): Texture;
         private _loadImage(context, image, onSuccess);
+        _loadUri(context: string, uri: string, onSuccess: (data: ArrayBufferView) => void): void;
         _tryCatchOnError(handler: () => void): void;
     }
 }

+ 253 - 207
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -11,7 +11,7 @@ var BABYLON;
         // Sets the useRightHandedSystem flag on the scene.
         GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 2] = "FORCE_RIGHT_HANDED";
     })(GLTFLoaderCoordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode || (BABYLON.GLTFLoaderCoordinateSystemMode = {}));
-    var GLTFFileLoader = (function () {
+    var GLTFFileLoader = /** @class */ (function () {
         function GLTFFileLoader() {
             // V2 options
             this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
@@ -21,6 +21,12 @@ var BABYLON;
                 ".glb": { isBinary: true }
             };
         }
+        GLTFFileLoader.prototype.dispose = function () {
+            if (this._loader) {
+                this._loader.dispose();
+                this._loader = null;
+            }
+        };
         GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
             var loaderData = GLTFFileLoader._parse(data, onError);
             if (!loaderData) {
@@ -29,11 +35,11 @@ var BABYLON;
             if (this.onParsed) {
                 this.onParsed(loaderData);
             }
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
-            loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         };
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) {
             var loaderData = GLTFFileLoader._parse(data, onError);
@@ -43,11 +49,11 @@ var BABYLON;
             if (this.onParsed) {
                 this.onParsed(loaderData);
             }
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
-            return loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            return this._loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         };
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
@@ -163,18 +169,18 @@ var BABYLON;
             // Look for BIN chunk
             var bin = null;
             while (binaryReader.getPosition() < binaryReader.getLength()) {
-                chunkLength = binaryReader.readUint32();
-                chunkFormat = binaryReader.readUint32();
-                switch (chunkFormat) {
+                var chunkLength_1 = binaryReader.readUint32();
+                var chunkFormat_1 = binaryReader.readUint32();
+                switch (chunkFormat_1) {
                     case ChunkFormat.JSON:
                         onError("Unexpected JSON chunk");
                         return null;
                     case ChunkFormat.BIN:
-                        bin = binaryReader.readUint8Array(chunkLength);
+                        bin = binaryReader.readUint8Array(chunkLength_1);
                         break;
                     default:
                         // ignore unrecognized chunkFormat
-                        binaryReader.skipBytes(chunkLength);
+                        binaryReader.skipBytes(chunkLength_1);
                         break;
                 }
             }
@@ -207,7 +213,7 @@ var BABYLON;
         GLTFFileLoader._decodeBufferToText = function (buffer) {
             var result = "";
             var length = buffer.byteLength;
-            for (var i = 0; i < length; ++i) {
+            for (var i = 0; i < length; i++) {
                 result += String.fromCharCode(buffer[i]);
             }
             return result;
@@ -218,7 +224,7 @@ var BABYLON;
         return GLTFFileLoader;
     }());
     BABYLON.GLTFFileLoader = GLTFFileLoader;
-    var BinaryReader = (function () {
+    var BinaryReader = /** @class */ (function () {
         function BinaryReader(arrayBuffer) {
             this._arrayBuffer = arrayBuffer;
             this._dataView = new DataView(arrayBuffer);
@@ -364,7 +370,7 @@ var BABYLON;
             ETokenType[ETokenType["UNKNOWN"] = 2] = "UNKNOWN";
             ETokenType[ETokenType["END_OF_INPUT"] = 3] = "END_OF_INPUT";
         })(ETokenType || (ETokenType = {}));
-        var Tokenizer = (function () {
+        var Tokenizer = /** @class */ (function () {
             function Tokenizer(toParse) {
                 this._pos = 0;
                 this.isLetterOrDigitPattern = /^[a-zA-Z0-9]+$/;
@@ -1292,7 +1298,7 @@ var BABYLON;
         /**
         * Implementation of the base glTF spec
         */
-        var GLTFLoaderBase = (function () {
+        var GLTFLoaderBase = /** @class */ (function () {
             function GLTFLoaderBase() {
             }
             GLTFLoaderBase.CreateRuntime = function (parsedData, scene, rootUrl) {
@@ -1587,7 +1593,7 @@ var BABYLON;
         /**
         * glTF V1 Loader
         */
-        var GLTFLoader = (function () {
+        var GLTFLoader = /** @class */ (function () {
             function GLTFLoader() {
             }
             GLTFLoader.RegisterExtension = function (extension) {
@@ -1597,6 +1603,9 @@ var BABYLON;
                 }
                 GLTFLoader.Extensions[extension.name] = extension;
             };
+            GLTFLoader.prototype.dispose = function () {
+                // do nothing
+            };
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
                 var _this = this;
                 scene.useRightHandedSystem = true;
@@ -1771,7 +1780,7 @@ var BABYLON;
         /**
         * Utils functions for GLTF
         */
-        var GLTFUtils = (function () {
+        var GLTFUtils = /** @class */ (function () {
             function GLTFUtils() {
             }
             /**
@@ -2021,7 +2030,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF1;
     (function (GLTF1) {
-        var GLTFLoaderExtension = (function () {
+        var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension(name) {
                 this._name = name;
             }
@@ -2175,7 +2184,7 @@ var BABYLON;
         var BinaryExtensionBufferName = "binary_glTF";
         ;
         ;
-        var GLTFBinaryExtension = (function (_super) {
+        var GLTFBinaryExtension = /** @class */ (function (_super) {
             __extends(GLTFBinaryExtension, _super);
             function GLTFBinaryExtension() {
                 return _super.call(this, "KHR_binary_glTF") || this;
@@ -2252,7 +2261,7 @@ var BABYLON;
         ;
         ;
         ;
-        var GLTFMaterialsCommonExtension = (function (_super) {
+        var GLTFMaterialsCommonExtension = /** @class */ (function (_super) {
             __extends(GLTFMaterialsCommonExtension, _super);
             function GLTFMaterialsCommonExtension() {
                 return _super.call(this, "KHR_materials_common") || this;
@@ -2415,7 +2424,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        var GLTFLoaderTracker = (function () {
+        var GLTFLoaderTracker = /** @class */ (function () {
             function GLTFLoaderTracker(onComplete) {
                 this._pendingCount = 0;
                 this._callback = onComplete;
@@ -2430,10 +2439,11 @@ var BABYLON;
             };
             return GLTFLoaderTracker;
         }());
-        var GLTFLoader = (function () {
+        var GLTFLoader = /** @class */ (function () {
             function GLTFLoader(parent) {
-                this._renderReady = false;
                 this._disposed = false;
+                this._renderReady = false;
+                this._requests = new Array();
                 this._renderReadyObservable = new BABYLON.Observable();
                 // Count of pending work that needs to complete before the asset is rendered.
                 this._renderPendingCount = 0;
@@ -2456,24 +2466,37 @@ var BABYLON;
                     return;
                 }
                 this._disposed = true;
+                // Abort requests that are not complete
+                for (var _i = 0, _a = this._requests; _i < _a.length; _i++) {
+                    var request = _a[_i];
+                    if (request.readyState !== (XMLHttpRequest.DONE || 4)) {
+                        request.abort();
+                    }
+                }
                 // Revoke object urls created during load
                 if (this._gltf.textures) {
-                    this._gltf.textures.forEach(function (texture) {
+                    for (var _b = 0, _c = this._gltf.textures; _b < _c.length; _b++) {
+                        var texture = _c[_b];
                         if (texture.url) {
                             URL.revokeObjectURL(texture.url);
                         }
-                    });
+                    }
                 }
                 this._gltf = undefined;
                 this._babylonScene = undefined;
+                this._parent = undefined;
                 this._rootUrl = undefined;
                 this._defaultMaterial = undefined;
+                this._rootNode = undefined;
                 this._successCallback = undefined;
+                this._progressCallback = undefined;
                 this._errorCallback = undefined;
                 this._renderReady = false;
-                this._renderReadyObservable.clear();
+                this._requests = undefined;
+                this._renderReadyObservable = undefined;
                 this._renderPendingCount = 0;
                 this._loaderPendingCount = 0;
+                this._loaderTrackers = undefined;
             };
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
                 var _this = this;
@@ -2541,9 +2564,6 @@ var BABYLON;
                 this._startAnimations();
                 this._successCallback();
                 this._renderReadyObservable.notifyObservers(this);
-                if (this._parent.onReady) {
-                    this._parent.onReady();
-                }
             };
             GLTFLoader.prototype._onComplete = function () {
                 if (this._parent.onComplete) {
@@ -2571,11 +2591,12 @@ var BABYLON;
                 var meshes = [this._rootNode.babylonMesh];
                 var nodes = this._gltf.nodes;
                 if (nodes) {
-                    nodes.forEach(function (node) {
+                    for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                        var node = nodes_1[_i];
                         if (node.babylonMesh) {
                             meshes.push(node.babylonMesh);
                         }
-                    });
+                    }
                 }
                 return meshes;
             };
@@ -2583,11 +2604,12 @@ var BABYLON;
                 var skeletons = new Array();
                 var skins = this._gltf.skins;
                 if (skins) {
-                    skins.forEach(function (skin) {
+                    for (var _i = 0, skins_1 = skins; _i < skins_1.length; _i++) {
+                        var skin = skins_1[_i];
                         if (skin.babylonSkeleton instanceof BABYLON.Skeleton) {
                             skeletons.push(skin.babylonSkeleton);
                         }
-                    });
+                    }
                 }
                 return skeletons;
             };
@@ -2595,15 +2617,18 @@ var BABYLON;
                 var targets = new Array();
                 var animations = this._gltf.animations;
                 if (animations) {
-                    animations.forEach(function (animation) {
+                    for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                        var animation = animations_1[_i];
                         targets.push.apply(targets, animation.targets);
-                    });
+                    }
                 }
                 return targets;
             };
             GLTFLoader.prototype._startAnimations = function () {
-                var _this = this;
-                this._getAnimationTargets().forEach(function (target) { return _this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true); });
+                for (var _i = 0, _a = this._getAnimationTargets(); _i < _a.length; _i++) {
+                    var target = _a[_i];
+                    this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
+                }
             };
             GLTFLoader.prototype._loadDefaultScene = function (nodeNames) {
                 var scene = GLTF2.GLTFUtils.GetArrayItem(this._gltf.scenes, this._gltf.scene || 0);
@@ -2640,22 +2665,23 @@ var BABYLON;
                     if (!(nodeNames instanceof Array)) {
                         nodeNames = [nodeNames];
                     }
-                    var filteredNodeIndices = new Array();
+                    var filteredNodeIndices_1 = new Array();
                     this._traverseNodes(context, nodeIndices, function (node) {
                         if (nodeNames.indexOf(node.name) !== -1) {
-                            filteredNodeIndices.push(node.index);
+                            filteredNodeIndices_1.push(node.index);
                             return false;
                         }
                         return true;
                     }, this._rootNode);
-                    nodeIndices = filteredNodeIndices;
+                    nodeIndices = filteredNodeIndices_1;
                 }
-                for (var i = 0; i < nodeIndices.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, nodeIndices[i]);
+                for (var _i = 0, nodeIndices_1 = nodeIndices; _i < nodeIndices_1.length; _i++) {
+                    var index = nodeIndices_1[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find node " + nodeIndices[i]);
+                        throw new Error(context + ": Failed to find node " + index);
                     }
-                    this._loadNode("#/nodes/" + nodeIndices[i], node);
+                    this._loadNode("#/nodes/" + index, node);
                 }
                 // Disable the root mesh until the asset is ready to render.
                 this._rootNode.babylonMesh.setEnabled(false);
@@ -2687,25 +2713,26 @@ var BABYLON;
                     // TODO: handle cameras
                 }
                 if (node.children) {
-                    for (var i = 0; i < node.children.length; i++) {
-                        var childNode = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, node.children[i]);
+                    for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
+                        var index = _a[_i];
+                        var childNode = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                         if (!childNode) {
-                            throw new Error(context + ": Failed to find child node " + node.children[i]);
+                            throw new Error(context + ": Failed to find child node " + index);
                         }
-                        this._loadNode("#/nodes/" + node.children[i], childNode);
+                        this._loadNode("#/nodes/" + index, childNode);
                     }
                 }
             };
             GLTFLoader.prototype._loadMesh = function (context, node, mesh) {
                 var _this = this;
                 node.babylonMesh.name = node.babylonMesh.name || mesh.name;
-                if (!mesh.primitives || mesh.primitives.length === 0) {
+                var primitives = mesh.primitives;
+                if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
                 this._createMorphTargets(context, node, mesh);
                 this._loadAllVertexDataAsync(context, mesh, function () {
                     _this._loadMorphTargets(context, node, mesh);
-                    var primitives = mesh.primitives;
                     var vertexData = new BABYLON.VertexData();
                     for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
                         var primitive = primitives_1[_i];
@@ -2718,63 +2745,68 @@ var BABYLON;
                     var verticesStart = 0;
                     var indicesStart = 0;
                     for (var index = 0; index < primitives.length; index++) {
-                        var vertexData = primitives[index].vertexData;
-                        var verticesCount = vertexData.positions.length;
-                        var indicesCount = vertexData.indices.length;
+                        var vertexData_1 = primitives[index].vertexData;
+                        var verticesCount = vertexData_1.positions.length;
+                        var indicesCount = vertexData_1.indices.length;
                         BABYLON.SubMesh.AddToMesh(index, verticesStart, verticesCount, indicesStart, indicesCount, node.babylonMesh);
                         verticesStart += verticesCount;
                         indicesStart += indicesCount;
                     }
                     ;
-                    var multiMaterial = new BABYLON.MultiMaterial(node.babylonMesh.name, _this._babylonScene);
-                    node.babylonMesh.material = multiMaterial;
-                    var subMaterials = multiMaterial.subMaterials;
-                    for (var index = 0; index < primitives.length; index++) {
-                        var primitive = primitives[index];
-                        if (primitive.material == null) {
-                            subMaterials[index] = _this._getDefaultMaterial();
+                });
+                var multiMaterial = new BABYLON.MultiMaterial(node.babylonMesh.name, this._babylonScene);
+                node.babylonMesh.material = multiMaterial;
+                var subMaterials = multiMaterial.subMaterials;
+                var _loop_1 = function (index) {
+                    var primitive = primitives[index];
+                    if (primitive.material == null) {
+                        subMaterials[index] = this_1._getDefaultMaterial();
+                    }
+                    else {
+                        var material_1 = GLTF2.GLTFUtils.GetArrayItem(this_1._gltf.materials, primitive.material);
+                        if (!material_1) {
+                            throw new Error(context + ": Failed to find material " + primitive.material);
                         }
-                        else {
-                            var material = GLTF2.GLTFUtils.GetArrayItem(_this._gltf.materials, primitive.material);
-                            if (!material) {
-                                throw new Error(context + ": Failed to find material " + primitive.material);
+                        this_1._loadMaterial("#/materials/" + material_1.index, material_1, function (babylonMaterial, isNew) {
+                            if (isNew && _this._parent.onMaterialLoaded) {
+                                _this._parent.onMaterialLoaded(babylonMaterial);
                             }
-                            var capturedIndex = index;
-                            _this._loadMaterial("#/materials/" + material.index, material, function (babylonMaterial, isNew) {
-                                if (isNew && _this._parent.onMaterialLoaded) {
-                                    _this._parent.onMaterialLoaded(babylonMaterial);
-                                }
-                                if (_this._parent.onBeforeMaterialReadyAsync) {
-                                    _this._addLoaderPendingData(material);
-                                    _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, node.babylonMesh, subMaterials[capturedIndex] != null, function () {
-                                        subMaterials[capturedIndex] = babylonMaterial;
-                                        _this._removeLoaderPendingData(material);
+                            if (_this._parent.onBeforeMaterialReadyAsync) {
+                                _this._addLoaderPendingData(material_1);
+                                _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, node.babylonMesh, subMaterials[index] != null, function () {
+                                    _this._tryCatchOnError(function () {
+                                        subMaterials[index] = babylonMaterial;
+                                        _this._removeLoaderPendingData(material_1);
                                     });
-                                }
-                                else {
-                                    subMaterials[capturedIndex] = babylonMaterial;
-                                }
-                            });
-                        }
+                                });
+                            }
+                            else {
+                                subMaterials[index] = babylonMaterial;
+                            }
+                        });
                     }
-                    ;
-                });
+                };
+                var this_1 = this;
+                for (var index = 0; index < primitives.length; index++) {
+                    _loop_1(index);
+                }
+                ;
             };
             GLTFLoader.prototype._loadAllVertexDataAsync = function (context, mesh, onSuccess) {
                 var primitives = mesh.primitives;
                 var numRemainingPrimitives = primitives.length;
-                var _loop_1 = function () {
+                var _loop_2 = function (index) {
                     var primitive = primitives[index];
-                    this_1._loadVertexDataAsync(context + "/primitive/" + index, mesh, primitive, function (vertexData) {
+                    this_2._loadVertexDataAsync(context + "/primitive/" + index, mesh, primitive, function (vertexData) {
                         primitive.vertexData = vertexData;
                         if (--numRemainingPrimitives === 0) {
                             onSuccess();
                         }
                     });
                 };
-                var this_1 = this;
+                var this_2 = this;
                 for (var index = 0; index < primitives.length; index++) {
-                    _loop_1();
+                    _loop_2(index);
                 }
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, mesh, primitive, onSuccess) {
@@ -2789,12 +2821,12 @@ var BABYLON;
                 }
                 var vertexData = new BABYLON.VertexData();
                 var numRemainingAttributes = Object.keys(attributes).length;
-                var _loop_2 = function (attribute) {
-                    accessor = GLTF2.GLTFUtils.GetArrayItem(this_2._gltf.accessors, attributes[attribute]);
+                var _loop_3 = function (attribute) {
+                    var accessor = GLTF2.GLTFUtils.GetArrayItem(this_3._gltf.accessors, attributes[attribute]);
                     if (!accessor) {
                         throw new Error(context + ": Failed to find attribute '" + attribute + "' accessor " + attributes[attribute]);
                     }
-                    this_2._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
+                    this_3._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
                         switch (attribute) {
                             case "NORMAL":
                                 vertexData.normals = data;
@@ -2827,7 +2859,9 @@ var BABYLON;
                         if (--numRemainingAttributes === 0) {
                             if (primitive.indices == null) {
                                 vertexData.indices = new Uint32Array(vertexData.positions.length / 3);
-                                vertexData.indices.forEach(function (v, i) { return vertexData.indices[i] = i; });
+                                for (var i = 0; i < vertexData.indices.length; i++) {
+                                    vertexData.indices[i] = i;
+                                }
                                 onSuccess(vertexData);
                             }
                             else {
@@ -2843,9 +2877,9 @@ var BABYLON;
                         }
                     });
                 };
-                var this_2 = this, accessor;
+                var this_3 = this;
                 for (var attribute in attributes) {
-                    _loop_2(attribute);
+                    _loop_3(attribute);
                 }
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh) {
@@ -2889,33 +2923,36 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadAllMorphTargetVertexDataAsync = function (context, node, mesh, onSuccess) {
                 var numRemainingTargets = mesh.primitives.length * node.babylonMesh.morphTargetManager.numTargets;
-                for (var _i = 0, _a = mesh.primitives; _i < _a.length; _i++) {
-                    var primitive = _a[_i];
+                var _loop_4 = function (primitive) {
                     var targets = primitive.targets;
                     primitive.targetsVertexData = new Array(targets.length);
-                    var _loop_3 = function (index) {
-                        this_3._loadMorphTargetVertexDataAsync(context + "/targets/" + index, primitive.vertexData, targets[index], function (vertexData) {
+                    var _loop_5 = function (index) {
+                        this_4._loadMorphTargetVertexDataAsync(context + "/targets/" + index, primitive.vertexData, targets[index], function (vertexData) {
                             primitive.targetsVertexData[index] = vertexData;
                             if (--numRemainingTargets === 0) {
                                 onSuccess();
                             }
                         });
                     };
-                    var this_3 = this;
                     for (var index = 0; index < targets.length; index++) {
-                        _loop_3(index);
+                        _loop_5(index);
                     }
+                };
+                var this_4 = this;
+                for (var _i = 0, _a = mesh.primitives; _i < _a.length; _i++) {
+                    var primitive = _a[_i];
+                    _loop_4(primitive);
                 }
             };
             GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, vertexData, attributes, onSuccess) {
                 var targetVertexData = new BABYLON.VertexData();
                 var numRemainingAttributes = Object.keys(attributes).length;
-                var _loop_4 = function (attribute) {
-                    accessor = GLTF2.GLTFUtils.GetArrayItem(this_4._gltf.accessors, attributes[attribute]);
+                var _loop_6 = function (attribute) {
+                    var accessor = GLTF2.GLTFUtils.GetArrayItem(this_5._gltf.accessors, attributes[attribute]);
                     if (!accessor) {
                         throw new Error(context + ": Failed to find attribute '" + attribute + "' accessor " + attributes[attribute]);
                     }
-                    this_4._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
+                    this_5._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
                         // glTF stores morph target information as deltas while babylon.js expects the final data.
                         // As a result we have to add the original data to the delta to calculate the final data.
                         var values = data;
@@ -2953,9 +2990,9 @@ var BABYLON;
                         }
                     });
                 };
-                var this_4 = this, accessor;
+                var this_5 = this;
                 for (var attribute in attributes) {
-                    _loop_4(attribute);
+                    _loop_6(attribute);
                 }
             };
             GLTFLoader.prototype._loadTransform = function (node) {
@@ -2963,8 +3000,8 @@ var BABYLON;
                 var rotation = BABYLON.Quaternion.Identity();
                 var scaling = BABYLON.Vector3.One();
                 if (node.matrix) {
-                    var mat = BABYLON.Matrix.FromArray(node.matrix);
-                    mat.decompose(scaling, rotation, position);
+                    var matrix = BABYLON.Matrix.FromArray(node.matrix);
+                    matrix.decompose(scaling, rotation, position);
                 }
                 else {
                     if (node.translation)
@@ -3006,10 +3043,11 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadBones = function (context, skin, inverseBindMatrixData) {
                 var babylonBones = {};
-                for (var i = 0; i < skin.joints.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, skin.joints[i]);
+                for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) {
+                    var index = _a[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find joint " + skin.joints[i]);
+                        throw new Error(context + ": Failed to find joint " + index);
                     }
                     this._loadBone(node, skin, inverseBindMatrixData, babylonBones);
                 }
@@ -3041,10 +3079,11 @@ var BABYLON;
             };
             GLTFLoader.prototype._traverseNodes = function (context, indices, action, parentNode) {
                 if (parentNode === void 0) { parentNode = null; }
-                for (var i = 0; i < indices.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, indices[i]);
+                for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
+                    var index = indices_1[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find node " + indices[i]);
+                        throw new Error(context + ": Failed to find node " + index);
                     }
                     this._traverseNode(context, node, action, parentNode);
                 }
@@ -3177,7 +3216,7 @@ var BABYLON;
                     animation.targets = animation.targets || [];
                     if (targetPath === "influence") {
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
-                        for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
+                        var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
                             var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
@@ -3189,14 +3228,17 @@ var BABYLON;
                             }); }));
                             morphTarget.animations.push(babylonAnimation);
                             animation.targets.push(morphTarget);
+                        };
+                        for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
+                            _loop_7(targetIndex);
                         }
                     }
                     else {
                         var animationName = animation.name || "anim" + animation.index;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
-                        for (var i = 0; i < targetNode.babylonAnimationTargets.length; i++) {
-                            var target = targetNode.babylonAnimationTargets[i];
+                        for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
+                            var target = _a[_i];
                             target.animations.push(babylonAnimation.clone());
                             animation.targets.push(target);
                         }
@@ -3243,28 +3285,15 @@ var BABYLON;
                         this._removePendingData(buffer);
                     }
                     else {
-                        if (!GLTF2.GLTFUtils.ValidateUri(buffer.uri)) {
-                            throw new Error(context + ": Uri '" + buffer.uri + "' is invalid");
-                        }
                         buffer.loadedObservable = new BABYLON.Observable();
                         buffer.loadedObservable.add(function (buffer) {
                             onSuccess(buffer.loadedData);
                             _this._removePendingData(buffer);
                         });
-                        BABYLON.Tools.LoadFile(this._rootUrl + buffer.uri, function (data) {
-                            _this._tryCatchOnError(function () {
-                                buffer.loadedData = new Uint8Array(data);
-                                buffer.loadedObservable.notifyObservers(buffer);
-                                buffer.loadedObservable = null;
-                            });
-                        }, function (event) {
-                            _this._tryCatchOnError(function () {
-                                _this._onProgress(event);
-                            });
-                        }, this._babylonScene.database, true, function (request) {
-                            _this._tryCatchOnError(function () {
-                                throw new Error(context + ": Failed to load '" + buffer.uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
-                            });
+                        this._loadUri(context, buffer.uri, function (data) {
+                            buffer.loadedData = data;
+                            buffer.loadedObservable.notifyObservers(buffer);
+                            buffer.loadedObservable = null;
                         });
                     }
                 }
@@ -3279,8 +3308,9 @@ var BABYLON;
                     if (_this._disposed) {
                         return;
                     }
+                    var data;
                     try {
-                        var data = new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        data = new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -3306,27 +3336,32 @@ var BABYLON;
                         throw new Error(context + ": Invalid type (" + accessor.type + ")");
                     }
                     var data;
-                    switch (accessor.componentType) {
-                        case GLTF2.EComponentType.BYTE:
-                            data = _this._buildArrayBuffer(Float32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_BYTE:
-                            data = _this._buildArrayBuffer(Uint8Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.SHORT:
-                            data = _this._buildArrayBuffer(Int16Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_SHORT:
-                            data = _this._buildArrayBuffer(Uint16Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_INT:
-                            data = _this._buildArrayBuffer(Uint32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.FLOAT:
-                            data = _this._buildArrayBuffer(Float32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        default:
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                    try {
+                        switch (accessor.componentType) {
+                            case GLTF2.EComponentType.BYTE:
+                                data = _this._buildArrayBuffer(Float32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_BYTE:
+                                data = _this._buildArrayBuffer(Uint8Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.SHORT:
+                                data = _this._buildArrayBuffer(Int16Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_SHORT:
+                                data = _this._buildArrayBuffer(Uint16Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_INT:
+                                data = _this._buildArrayBuffer(Uint32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.FLOAT:
+                                data = _this._buildArrayBuffer(Float32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            default:
+                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                        }
+                    }
+                    catch (e) {
+                        throw new Error(context + ": " + e);
                     }
                     onSuccess(data);
                 });
@@ -3343,30 +3378,25 @@ var BABYLON;
                 }
                 return 0;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, context, data, byteOffset, count, numComponents, byteStride) {
-                try {
-                    var byteOffset = data.byteOffset + (byteOffset || 0);
-                    var targetLength = count * numComponents;
-                    if (byteStride == null || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                        return new typedArray(data.buffer, byteOffset, targetLength);
-                    }
-                    var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                    var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                    var targetBuffer = new typedArray(targetLength);
-                    var sourceIndex = 0;
-                    var targetIndex = 0;
-                    while (targetIndex < targetLength) {
-                        for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                            targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                            targetIndex++;
-                        }
-                        sourceIndex += elementStride;
-                    }
-                    return targetBuffer;
+            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
+                byteOffset = data.byteOffset + (byteOffset || 0);
+                var targetLength = count * numComponents;
+                if (byteStride == null || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
+                    return new typedArray(data.buffer, byteOffset, targetLength);
                 }
-                catch (e) {
-                    throw new Error(context + ": " + e);
+                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
+                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
+                var targetBuffer = new typedArray(targetLength);
+                var sourceIndex = 0;
+                var targetIndex = 0;
+                while (targetIndex < targetLength) {
+                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
+                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
+                        targetIndex++;
+                    }
+                    sourceIndex += elementStride;
                 }
+                return targetBuffer;
             };
             GLTFLoader.prototype._addPendingData = function (data) {
                 if (!this._renderReady) {
@@ -3385,10 +3415,16 @@ var BABYLON;
             };
             GLTFLoader.prototype._addLoaderPendingData = function (data) {
                 this._loaderPendingCount++;
-                this._loaderTrackers.forEach(function (tracker) { return tracker._addPendingData(data); });
+                for (var _i = 0, _a = this._loaderTrackers; _i < _a.length; _i++) {
+                    var tracker = _a[_i];
+                    tracker._addPendingData(data);
+                }
             };
             GLTFLoader.prototype._removeLoaderPendingData = function (data) {
-                this._loaderTrackers.forEach(function (tracker) { return tracker._removePendingData(data); });
+                for (var _i = 0, _a = this._loaderTrackers; _i < _a.length; _i++) {
+                    var tracker = _a[_i];
+                    tracker._removePendingData(data);
+                }
                 if (--this._loaderPendingCount === 0) {
                     this._onComplete();
                 }
@@ -3570,12 +3606,12 @@ var BABYLON;
                     texture.dataReadyObservable.add(function (texture) {
                         babylonTexture.updateURL(texture.url);
                     });
-                    var image = GLTF2.GLTFUtils.GetArrayItem(this._gltf.images, texture.source);
-                    if (!image) {
+                    var image_1 = GLTF2.GLTFUtils.GetArrayItem(this._gltf.images, texture.source);
+                    if (!image_1) {
                         throw new Error(context + ": Failed to find source " + texture.source);
                     }
-                    this._loadImage("#/images/" + image.index, image, function (data) {
-                        texture.url = URL.createObjectURL(new Blob([data], { type: image.mimeType }));
+                    this._loadImage("#/images/" + image_1.index, image_1, function (data) {
+                        texture.url = URL.createObjectURL(new Blob([data], { type: image_1.mimeType }));
                         texture.dataReadyObservable.notifyObservers(texture);
                     });
                 }
@@ -3589,28 +3625,12 @@ var BABYLON;
                 return babylonTexture;
             };
             GLTFLoader.prototype._loadImage = function (context, image, onSuccess) {
-                var _this = this;
                 if (image.uri) {
-                    if (!GLTF2.GLTFUtils.ValidateUri(image.uri)) {
-                        throw new Error(context + ": Uri '" + image.uri + "' is invalid");
-                    }
                     if (GLTF2.GLTFUtils.IsBase64(image.uri)) {
                         onSuccess(new Uint8Array(GLTF2.GLTFUtils.DecodeBase64(image.uri)));
                     }
                     else {
-                        BABYLON.Tools.LoadFile(this._rootUrl + image.uri, function (data) {
-                            _this._tryCatchOnError(function () {
-                                onSuccess(data);
-                            });
-                        }, function (event) {
-                            _this._tryCatchOnError(function () {
-                                _this._onProgress(event);
-                            });
-                        }, this._babylonScene.database, true, function (request) {
-                            _this._tryCatchOnError(function () {
-                                throw new Error(context + ": Failed to load '" + image.uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
-                            });
-                        });
+                        this._loadUri(context, image.uri, onSuccess);
                     }
                 }
                 else {
@@ -3621,6 +3641,28 @@ var BABYLON;
                     this._loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView, onSuccess);
                 }
             };
+            GLTFLoader.prototype._loadUri = function (context, uri, onSuccess) {
+                var _this = this;
+                if (!GLTF2.GLTFUtils.ValidateUri(uri)) {
+                    throw new Error(context + ": Uri '" + uri + "' is invalid");
+                }
+                var request = BABYLON.Tools.LoadFile(this._rootUrl + uri, function (data) {
+                    _this._tryCatchOnError(function () {
+                        onSuccess(new Uint8Array(data));
+                    });
+                }, function (event) {
+                    _this._tryCatchOnError(function () {
+                        _this._onProgress(event);
+                    });
+                }, this._babylonScene.database, true, function (request) {
+                    _this._tryCatchOnError(function () {
+                        throw new Error(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
+                    });
+                });
+                if (request) {
+                    this._requests.push(request);
+                }
+            };
             GLTFLoader.prototype._tryCatchOnError = function (handler) {
                 try {
                     handler();
@@ -3647,7 +3689,7 @@ var BABYLON;
         /**
         * Utils functions for GLTF
         */
-        var GLTFUtils = (function () {
+        var GLTFUtils = /** @class */ (function () {
             function GLTFUtils() {
             }
             /**
@@ -3745,7 +3787,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        var GLTFLoaderExtension = (function () {
+        var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension() {
                 this.enabled = true;
             }
@@ -3783,8 +3825,8 @@ var BABYLON;
                 if (!extensions) {
                     return false;
                 }
-                for (var i = 0; i < extensions.length; i++) {
-                    var extension = extensions[i];
+                for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
+                    var extension = extensions_1[_i];
                     if (extension.enabled && action(extension)) {
                         return true;
                     }
@@ -3821,7 +3863,7 @@ var BABYLON;
         var Extensions;
         (function (Extensions) {
             // See https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod for more information about this extension.
-            var MSFTLOD = (function (_super) {
+            var MSFTLOD = /** @class */ (function (_super) {
                 __extends(MSFTLOD, _super);
                 function MSFTLOD() {
                     return _super !== null && _super.apply(this, arguments) || this;
@@ -3871,7 +3913,9 @@ var BABYLON;
                             return;
                         }
                         setTimeout(function () {
-                            _this._loadNodeLOD(loader, context, nodes, index - 1, onComplete);
+                            loader._tryCatchOnError(function () {
+                                _this._loadNodeLOD(loader, context, nodes, index - 1, onComplete);
+                            });
                         }, MSFTLOD.MinimalLODDelay);
                     });
                 };
@@ -3900,7 +3944,9 @@ var BABYLON;
                         loader._executeWhenRenderReady(function () {
                             BABYLON.BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), function () {
                                 setTimeout(function () {
-                                    _this._loadMaterialLOD(loader, context, materials, index - 1, assign, onComplete);
+                                    loader._tryCatchOnError(function () {
+                                        _this._loadMaterialLOD(loader, context, materials, index - 1, assign, onComplete);
+                                    });
                                 }, MSFTLOD.MinimalLODDelay);
                             });
                         });
@@ -3937,7 +3983,7 @@ var BABYLON;
     (function (GLTF2) {
         var Extensions;
         (function (Extensions) {
-            var KHRMaterialsPbrSpecularGlossiness = (function (_super) {
+            var KHRMaterialsPbrSpecularGlossiness = /** @class */ (function (_super) {
                 __extends(KHRMaterialsPbrSpecularGlossiness, _super);
                 function KHRMaterialsPbrSpecularGlossiness() {
                     return _super !== null && _super.apply(this, arguments) || this;

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


+ 2 - 2
dist/preview release/loaders/babylon.objFileLoader.js

@@ -4,7 +4,7 @@ var BABYLON;
     /**
      * Class reading and parsing the MTL file bundled with the obj file.
      */
-    var MTLFileLoader = (function () {
+    var MTLFileLoader = /** @class */ (function () {
         function MTLFileLoader() {
             // All material loaded from the mtl will be set here
             this.materials = [];
@@ -203,7 +203,7 @@ var BABYLON;
         return MTLFileLoader;
     }());
     BABYLON.MTLFileLoader = MTLFileLoader;
-    var OBJFileLoader = (function () {
+    var OBJFileLoader = /** @class */ (function () {
         function OBJFileLoader() {
             this.name = "obj";
             this.extensions = ".obj";

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


+ 1 - 1
dist/preview release/loaders/babylon.stlFileLoader.js

@@ -1,7 +1,7 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
-    var STLFileLoader = (function () {
+    var STLFileLoader = /** @class */ (function () {
         function STLFileLoader() {
             this.solidPattern = /solid (\S*)([\S\s]*)endsolid[ ]*(\S*)/g;
             this.facetsPattern = /facet([\s\S]*?)endfacet/g;

+ 256 - 210
dist/preview release/loaders/babylonjs.loaders.js

@@ -19,7 +19,7 @@ var __extends = (this && this.__extends) || (function () {
         
 var BABYLON;
 (function (BABYLON) {
-    var STLFileLoader = (function () {
+    var STLFileLoader = /** @class */ (function () {
         function STLFileLoader() {
             this.solidPattern = /solid (\S*)([\S\s]*)endsolid[ ]*(\S*)/g;
             this.facetsPattern = /facet([\s\S]*?)endfacet/g;
@@ -187,7 +187,7 @@ var BABYLON;
     /**
      * Class reading and parsing the MTL file bundled with the obj file.
      */
-    var MTLFileLoader = (function () {
+    var MTLFileLoader = /** @class */ (function () {
         function MTLFileLoader() {
             // All material loaded from the mtl will be set here
             this.materials = [];
@@ -386,7 +386,7 @@ var BABYLON;
         return MTLFileLoader;
     }());
     BABYLON.MTLFileLoader = MTLFileLoader;
-    var OBJFileLoader = (function () {
+    var OBJFileLoader = /** @class */ (function () {
         function OBJFileLoader() {
             this.name = "obj";
             this.extensions = ".obj";
@@ -982,7 +982,7 @@ var BABYLON;
         // Sets the useRightHandedSystem flag on the scene.
         GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 2] = "FORCE_RIGHT_HANDED";
     })(GLTFLoaderCoordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode || (BABYLON.GLTFLoaderCoordinateSystemMode = {}));
-    var GLTFFileLoader = (function () {
+    var GLTFFileLoader = /** @class */ (function () {
         function GLTFFileLoader() {
             // V2 options
             this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
@@ -992,6 +992,12 @@ var BABYLON;
                 ".glb": { isBinary: true }
             };
         }
+        GLTFFileLoader.prototype.dispose = function () {
+            if (this._loader) {
+                this._loader.dispose();
+                this._loader = null;
+            }
+        };
         GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
             var loaderData = GLTFFileLoader._parse(data, onError);
             if (!loaderData) {
@@ -1000,11 +1006,11 @@ var BABYLON;
             if (this.onParsed) {
                 this.onParsed(loaderData);
             }
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
-            loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         };
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) {
             var loaderData = GLTFFileLoader._parse(data, onError);
@@ -1014,11 +1020,11 @@ var BABYLON;
             if (this.onParsed) {
                 this.onParsed(loaderData);
             }
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
-            return loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            return this._loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         };
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
@@ -1134,18 +1140,18 @@ var BABYLON;
             // Look for BIN chunk
             var bin = null;
             while (binaryReader.getPosition() < binaryReader.getLength()) {
-                chunkLength = binaryReader.readUint32();
-                chunkFormat = binaryReader.readUint32();
-                switch (chunkFormat) {
+                var chunkLength_1 = binaryReader.readUint32();
+                var chunkFormat_1 = binaryReader.readUint32();
+                switch (chunkFormat_1) {
                     case ChunkFormat.JSON:
                         onError("Unexpected JSON chunk");
                         return null;
                     case ChunkFormat.BIN:
-                        bin = binaryReader.readUint8Array(chunkLength);
+                        bin = binaryReader.readUint8Array(chunkLength_1);
                         break;
                     default:
                         // ignore unrecognized chunkFormat
-                        binaryReader.skipBytes(chunkLength);
+                        binaryReader.skipBytes(chunkLength_1);
                         break;
                 }
             }
@@ -1178,7 +1184,7 @@ var BABYLON;
         GLTFFileLoader._decodeBufferToText = function (buffer) {
             var result = "";
             var length = buffer.byteLength;
-            for (var i = 0; i < length; ++i) {
+            for (var i = 0; i < length; i++) {
                 result += String.fromCharCode(buffer[i]);
             }
             return result;
@@ -1189,7 +1195,7 @@ var BABYLON;
         return GLTFFileLoader;
     }());
     BABYLON.GLTFFileLoader = GLTFFileLoader;
-    var BinaryReader = (function () {
+    var BinaryReader = /** @class */ (function () {
         function BinaryReader(arrayBuffer) {
             this._arrayBuffer = arrayBuffer;
             this._dataView = new DataView(arrayBuffer);
@@ -1335,7 +1341,7 @@ var BABYLON;
             ETokenType[ETokenType["UNKNOWN"] = 2] = "UNKNOWN";
             ETokenType[ETokenType["END_OF_INPUT"] = 3] = "END_OF_INPUT";
         })(ETokenType || (ETokenType = {}));
-        var Tokenizer = (function () {
+        var Tokenizer = /** @class */ (function () {
             function Tokenizer(toParse) {
                 this._pos = 0;
                 this.isLetterOrDigitPattern = /^[a-zA-Z0-9]+$/;
@@ -2263,7 +2269,7 @@ var BABYLON;
         /**
         * Implementation of the base glTF spec
         */
-        var GLTFLoaderBase = (function () {
+        var GLTFLoaderBase = /** @class */ (function () {
             function GLTFLoaderBase() {
             }
             GLTFLoaderBase.CreateRuntime = function (parsedData, scene, rootUrl) {
@@ -2558,7 +2564,7 @@ var BABYLON;
         /**
         * glTF V1 Loader
         */
-        var GLTFLoader = (function () {
+        var GLTFLoader = /** @class */ (function () {
             function GLTFLoader() {
             }
             GLTFLoader.RegisterExtension = function (extension) {
@@ -2568,6 +2574,9 @@ var BABYLON;
                 }
                 GLTFLoader.Extensions[extension.name] = extension;
             };
+            GLTFLoader.prototype.dispose = function () {
+                // do nothing
+            };
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
                 var _this = this;
                 scene.useRightHandedSystem = true;
@@ -2742,7 +2751,7 @@ var BABYLON;
         /**
         * Utils functions for GLTF
         */
-        var GLTFUtils = (function () {
+        var GLTFUtils = /** @class */ (function () {
             function GLTFUtils() {
             }
             /**
@@ -2992,7 +3001,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF1;
     (function (GLTF1) {
-        var GLTFLoaderExtension = (function () {
+        var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension(name) {
                 this._name = name;
             }
@@ -3137,7 +3146,7 @@ var BABYLON;
         var BinaryExtensionBufferName = "binary_glTF";
         ;
         ;
-        var GLTFBinaryExtension = (function (_super) {
+        var GLTFBinaryExtension = /** @class */ (function (_super) {
             __extends(GLTFBinaryExtension, _super);
             function GLTFBinaryExtension() {
                 return _super.call(this, "KHR_binary_glTF") || this;
@@ -3205,7 +3214,7 @@ var BABYLON;
         ;
         ;
         ;
-        var GLTFMaterialsCommonExtension = (function (_super) {
+        var GLTFMaterialsCommonExtension = /** @class */ (function (_super) {
             __extends(GLTFMaterialsCommonExtension, _super);
             function GLTFMaterialsCommonExtension() {
                 return _super.call(this, "KHR_materials_common") || this;
@@ -3368,7 +3377,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        var GLTFLoaderTracker = (function () {
+        var GLTFLoaderTracker = /** @class */ (function () {
             function GLTFLoaderTracker(onComplete) {
                 this._pendingCount = 0;
                 this._callback = onComplete;
@@ -3383,10 +3392,11 @@ var BABYLON;
             };
             return GLTFLoaderTracker;
         }());
-        var GLTFLoader = (function () {
+        var GLTFLoader = /** @class */ (function () {
             function GLTFLoader(parent) {
-                this._renderReady = false;
                 this._disposed = false;
+                this._renderReady = false;
+                this._requests = new Array();
                 this._renderReadyObservable = new BABYLON.Observable();
                 // Count of pending work that needs to complete before the asset is rendered.
                 this._renderPendingCount = 0;
@@ -3409,24 +3419,37 @@ var BABYLON;
                     return;
                 }
                 this._disposed = true;
+                // Abort requests that are not complete
+                for (var _i = 0, _a = this._requests; _i < _a.length; _i++) {
+                    var request = _a[_i];
+                    if (request.readyState !== (XMLHttpRequest.DONE || 4)) {
+                        request.abort();
+                    }
+                }
                 // Revoke object urls created during load
                 if (this._gltf.textures) {
-                    this._gltf.textures.forEach(function (texture) {
+                    for (var _b = 0, _c = this._gltf.textures; _b < _c.length; _b++) {
+                        var texture = _c[_b];
                         if (texture.url) {
                             URL.revokeObjectURL(texture.url);
                         }
-                    });
+                    }
                 }
                 this._gltf = undefined;
                 this._babylonScene = undefined;
+                this._parent = undefined;
                 this._rootUrl = undefined;
                 this._defaultMaterial = undefined;
+                this._rootNode = undefined;
                 this._successCallback = undefined;
+                this._progressCallback = undefined;
                 this._errorCallback = undefined;
                 this._renderReady = false;
-                this._renderReadyObservable.clear();
+                this._requests = undefined;
+                this._renderReadyObservable = undefined;
                 this._renderPendingCount = 0;
                 this._loaderPendingCount = 0;
+                this._loaderTrackers = undefined;
             };
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
                 var _this = this;
@@ -3494,9 +3517,6 @@ var BABYLON;
                 this._startAnimations();
                 this._successCallback();
                 this._renderReadyObservable.notifyObservers(this);
-                if (this._parent.onReady) {
-                    this._parent.onReady();
-                }
             };
             GLTFLoader.prototype._onComplete = function () {
                 if (this._parent.onComplete) {
@@ -3524,11 +3544,12 @@ var BABYLON;
                 var meshes = [this._rootNode.babylonMesh];
                 var nodes = this._gltf.nodes;
                 if (nodes) {
-                    nodes.forEach(function (node) {
+                    for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                        var node = nodes_1[_i];
                         if (node.babylonMesh) {
                             meshes.push(node.babylonMesh);
                         }
-                    });
+                    }
                 }
                 return meshes;
             };
@@ -3536,11 +3557,12 @@ var BABYLON;
                 var skeletons = new Array();
                 var skins = this._gltf.skins;
                 if (skins) {
-                    skins.forEach(function (skin) {
+                    for (var _i = 0, skins_1 = skins; _i < skins_1.length; _i++) {
+                        var skin = skins_1[_i];
                         if (skin.babylonSkeleton instanceof BABYLON.Skeleton) {
                             skeletons.push(skin.babylonSkeleton);
                         }
-                    });
+                    }
                 }
                 return skeletons;
             };
@@ -3548,15 +3570,18 @@ var BABYLON;
                 var targets = new Array();
                 var animations = this._gltf.animations;
                 if (animations) {
-                    animations.forEach(function (animation) {
+                    for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                        var animation = animations_1[_i];
                         targets.push.apply(targets, animation.targets);
-                    });
+                    }
                 }
                 return targets;
             };
             GLTFLoader.prototype._startAnimations = function () {
-                var _this = this;
-                this._getAnimationTargets().forEach(function (target) { return _this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true); });
+                for (var _i = 0, _a = this._getAnimationTargets(); _i < _a.length; _i++) {
+                    var target = _a[_i];
+                    this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
+                }
             };
             GLTFLoader.prototype._loadDefaultScene = function (nodeNames) {
                 var scene = GLTF2.GLTFUtils.GetArrayItem(this._gltf.scenes, this._gltf.scene || 0);
@@ -3593,22 +3618,23 @@ var BABYLON;
                     if (!(nodeNames instanceof Array)) {
                         nodeNames = [nodeNames];
                     }
-                    var filteredNodeIndices = new Array();
+                    var filteredNodeIndices_1 = new Array();
                     this._traverseNodes(context, nodeIndices, function (node) {
                         if (nodeNames.indexOf(node.name) !== -1) {
-                            filteredNodeIndices.push(node.index);
+                            filteredNodeIndices_1.push(node.index);
                             return false;
                         }
                         return true;
                     }, this._rootNode);
-                    nodeIndices = filteredNodeIndices;
+                    nodeIndices = filteredNodeIndices_1;
                 }
-                for (var i = 0; i < nodeIndices.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, nodeIndices[i]);
+                for (var _i = 0, nodeIndices_1 = nodeIndices; _i < nodeIndices_1.length; _i++) {
+                    var index = nodeIndices_1[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find node " + nodeIndices[i]);
+                        throw new Error(context + ": Failed to find node " + index);
                     }
-                    this._loadNode("#/nodes/" + nodeIndices[i], node);
+                    this._loadNode("#/nodes/" + index, node);
                 }
                 // Disable the root mesh until the asset is ready to render.
                 this._rootNode.babylonMesh.setEnabled(false);
@@ -3640,25 +3666,26 @@ var BABYLON;
                     // TODO: handle cameras
                 }
                 if (node.children) {
-                    for (var i = 0; i < node.children.length; i++) {
-                        var childNode = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, node.children[i]);
+                    for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
+                        var index = _a[_i];
+                        var childNode = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                         if (!childNode) {
-                            throw new Error(context + ": Failed to find child node " + node.children[i]);
+                            throw new Error(context + ": Failed to find child node " + index);
                         }
-                        this._loadNode("#/nodes/" + node.children[i], childNode);
+                        this._loadNode("#/nodes/" + index, childNode);
                     }
                 }
             };
             GLTFLoader.prototype._loadMesh = function (context, node, mesh) {
                 var _this = this;
                 node.babylonMesh.name = node.babylonMesh.name || mesh.name;
-                if (!mesh.primitives || mesh.primitives.length === 0) {
+                var primitives = mesh.primitives;
+                if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
                 }
                 this._createMorphTargets(context, node, mesh);
                 this._loadAllVertexDataAsync(context, mesh, function () {
                     _this._loadMorphTargets(context, node, mesh);
-                    var primitives = mesh.primitives;
                     var vertexData = new BABYLON.VertexData();
                     for (var _i = 0, primitives_1 = primitives; _i < primitives_1.length; _i++) {
                         var primitive = primitives_1[_i];
@@ -3671,63 +3698,68 @@ var BABYLON;
                     var verticesStart = 0;
                     var indicesStart = 0;
                     for (var index = 0; index < primitives.length; index++) {
-                        var vertexData = primitives[index].vertexData;
-                        var verticesCount = vertexData.positions.length;
-                        var indicesCount = vertexData.indices.length;
+                        var vertexData_1 = primitives[index].vertexData;
+                        var verticesCount = vertexData_1.positions.length;
+                        var indicesCount = vertexData_1.indices.length;
                         BABYLON.SubMesh.AddToMesh(index, verticesStart, verticesCount, indicesStart, indicesCount, node.babylonMesh);
                         verticesStart += verticesCount;
                         indicesStart += indicesCount;
                     }
                     ;
-                    var multiMaterial = new BABYLON.MultiMaterial(node.babylonMesh.name, _this._babylonScene);
-                    node.babylonMesh.material = multiMaterial;
-                    var subMaterials = multiMaterial.subMaterials;
-                    for (var index = 0; index < primitives.length; index++) {
-                        var primitive = primitives[index];
-                        if (primitive.material == null) {
-                            subMaterials[index] = _this._getDefaultMaterial();
+                });
+                var multiMaterial = new BABYLON.MultiMaterial(node.babylonMesh.name, this._babylonScene);
+                node.babylonMesh.material = multiMaterial;
+                var subMaterials = multiMaterial.subMaterials;
+                var _loop_1 = function (index) {
+                    var primitive = primitives[index];
+                    if (primitive.material == null) {
+                        subMaterials[index] = this_1._getDefaultMaterial();
+                    }
+                    else {
+                        var material_1 = GLTF2.GLTFUtils.GetArrayItem(this_1._gltf.materials, primitive.material);
+                        if (!material_1) {
+                            throw new Error(context + ": Failed to find material " + primitive.material);
                         }
-                        else {
-                            var material = GLTF2.GLTFUtils.GetArrayItem(_this._gltf.materials, primitive.material);
-                            if (!material) {
-                                throw new Error(context + ": Failed to find material " + primitive.material);
+                        this_1._loadMaterial("#/materials/" + material_1.index, material_1, function (babylonMaterial, isNew) {
+                            if (isNew && _this._parent.onMaterialLoaded) {
+                                _this._parent.onMaterialLoaded(babylonMaterial);
                             }
-                            var capturedIndex = index;
-                            _this._loadMaterial("#/materials/" + material.index, material, function (babylonMaterial, isNew) {
-                                if (isNew && _this._parent.onMaterialLoaded) {
-                                    _this._parent.onMaterialLoaded(babylonMaterial);
-                                }
-                                if (_this._parent.onBeforeMaterialReadyAsync) {
-                                    _this._addLoaderPendingData(material);
-                                    _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, node.babylonMesh, subMaterials[capturedIndex] != null, function () {
-                                        subMaterials[capturedIndex] = babylonMaterial;
-                                        _this._removeLoaderPendingData(material);
+                            if (_this._parent.onBeforeMaterialReadyAsync) {
+                                _this._addLoaderPendingData(material_1);
+                                _this._parent.onBeforeMaterialReadyAsync(babylonMaterial, node.babylonMesh, subMaterials[index] != null, function () {
+                                    _this._tryCatchOnError(function () {
+                                        subMaterials[index] = babylonMaterial;
+                                        _this._removeLoaderPendingData(material_1);
                                     });
-                                }
-                                else {
-                                    subMaterials[capturedIndex] = babylonMaterial;
-                                }
-                            });
-                        }
+                                });
+                            }
+                            else {
+                                subMaterials[index] = babylonMaterial;
+                            }
+                        });
                     }
-                    ;
-                });
+                };
+                var this_1 = this;
+                for (var index = 0; index < primitives.length; index++) {
+                    _loop_1(index);
+                }
+                ;
             };
             GLTFLoader.prototype._loadAllVertexDataAsync = function (context, mesh, onSuccess) {
                 var primitives = mesh.primitives;
                 var numRemainingPrimitives = primitives.length;
-                var _loop_1 = function () {
+                var _loop_2 = function (index) {
                     var primitive = primitives[index];
-                    this_1._loadVertexDataAsync(context + "/primitive/" + index, mesh, primitive, function (vertexData) {
+                    this_2._loadVertexDataAsync(context + "/primitive/" + index, mesh, primitive, function (vertexData) {
                         primitive.vertexData = vertexData;
                         if (--numRemainingPrimitives === 0) {
                             onSuccess();
                         }
                     });
                 };
-                var this_1 = this;
+                var this_2 = this;
                 for (var index = 0; index < primitives.length; index++) {
-                    _loop_1();
+                    _loop_2(index);
                 }
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, mesh, primitive, onSuccess) {
@@ -3742,12 +3774,12 @@ var BABYLON;
                 }
                 var vertexData = new BABYLON.VertexData();
                 var numRemainingAttributes = Object.keys(attributes).length;
-                var _loop_2 = function (attribute) {
-                    accessor = GLTF2.GLTFUtils.GetArrayItem(this_2._gltf.accessors, attributes[attribute]);
+                var _loop_3 = function (attribute) {
+                    var accessor = GLTF2.GLTFUtils.GetArrayItem(this_3._gltf.accessors, attributes[attribute]);
                     if (!accessor) {
                         throw new Error(context + ": Failed to find attribute '" + attribute + "' accessor " + attributes[attribute]);
                     }
-                    this_2._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
+                    this_3._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
                         switch (attribute) {
                             case "NORMAL":
                                 vertexData.normals = data;
@@ -3780,7 +3812,9 @@ var BABYLON;
                         if (--numRemainingAttributes === 0) {
                             if (primitive.indices == null) {
                                 vertexData.indices = new Uint32Array(vertexData.positions.length / 3);
-                                vertexData.indices.forEach(function (v, i) { return vertexData.indices[i] = i; });
+                                for (var i = 0; i < vertexData.indices.length; i++) {
+                                    vertexData.indices[i] = i;
+                                }
                                 onSuccess(vertexData);
                             }
                             else {
@@ -3796,9 +3830,9 @@ var BABYLON;
                         }
                     });
                 };
-                var this_2 = this, accessor;
+                var this_3 = this;
                 for (var attribute in attributes) {
-                    _loop_2(attribute);
+                    _loop_3(attribute);
                 }
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh) {
@@ -3842,33 +3876,36 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadAllMorphTargetVertexDataAsync = function (context, node, mesh, onSuccess) {
                 var numRemainingTargets = mesh.primitives.length * node.babylonMesh.morphTargetManager.numTargets;
-                for (var _i = 0, _a = mesh.primitives; _i < _a.length; _i++) {
-                    var primitive = _a[_i];
+                var _loop_4 = function (primitive) {
                     var targets = primitive.targets;
                     primitive.targetsVertexData = new Array(targets.length);
-                    var _loop_3 = function (index) {
-                        this_3._loadMorphTargetVertexDataAsync(context + "/targets/" + index, primitive.vertexData, targets[index], function (vertexData) {
+                    var _loop_5 = function (index) {
+                        this_4._loadMorphTargetVertexDataAsync(context + "/targets/" + index, primitive.vertexData, targets[index], function (vertexData) {
                             primitive.targetsVertexData[index] = vertexData;
                             if (--numRemainingTargets === 0) {
                                 onSuccess();
                             }
                         });
                     };
-                    var this_3 = this;
                     for (var index = 0; index < targets.length; index++) {
-                        _loop_3(index);
+                        _loop_5(index);
                     }
+                };
+                var this_4 = this;
+                for (var _i = 0, _a = mesh.primitives; _i < _a.length; _i++) {
+                    var primitive = _a[_i];
+                    _loop_4(primitive);
                 }
             };
             GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, vertexData, attributes, onSuccess) {
                 var targetVertexData = new BABYLON.VertexData();
                 var numRemainingAttributes = Object.keys(attributes).length;
-                var _loop_4 = function (attribute) {
-                    accessor = GLTF2.GLTFUtils.GetArrayItem(this_4._gltf.accessors, attributes[attribute]);
+                var _loop_6 = function (attribute) {
+                    var accessor = GLTF2.GLTFUtils.GetArrayItem(this_5._gltf.accessors, attributes[attribute]);
                     if (!accessor) {
                         throw new Error(context + ": Failed to find attribute '" + attribute + "' accessor " + attributes[attribute]);
                     }
-                    this_4._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
+                    this_5._loadAccessorAsync("#/accessors/" + accessor.index, accessor, function (data) {
                         // glTF stores morph target information as deltas while babylon.js expects the final data.
                         // As a result we have to add the original data to the delta to calculate the final data.
                         var values = data;
@@ -3906,9 +3943,9 @@ var BABYLON;
                         }
                     });
                 };
-                var this_4 = this, accessor;
+                var this_5 = this;
                 for (var attribute in attributes) {
-                    _loop_4(attribute);
+                    _loop_6(attribute);
                 }
             };
             GLTFLoader.prototype._loadTransform = function (node) {
@@ -3916,8 +3953,8 @@ var BABYLON;
                 var rotation = BABYLON.Quaternion.Identity();
                 var scaling = BABYLON.Vector3.One();
                 if (node.matrix) {
-                    var mat = BABYLON.Matrix.FromArray(node.matrix);
-                    mat.decompose(scaling, rotation, position);
+                    var matrix = BABYLON.Matrix.FromArray(node.matrix);
+                    matrix.decompose(scaling, rotation, position);
                 }
                 else {
                     if (node.translation)
@@ -3959,10 +3996,11 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadBones = function (context, skin, inverseBindMatrixData) {
                 var babylonBones = {};
-                for (var i = 0; i < skin.joints.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, skin.joints[i]);
+                for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) {
+                    var index = _a[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find joint " + skin.joints[i]);
+                        throw new Error(context + ": Failed to find joint " + index);
                     }
                     this._loadBone(node, skin, inverseBindMatrixData, babylonBones);
                 }
@@ -3994,10 +4032,11 @@ var BABYLON;
             };
             GLTFLoader.prototype._traverseNodes = function (context, indices, action, parentNode) {
                 if (parentNode === void 0) { parentNode = null; }
-                for (var i = 0; i < indices.length; i++) {
-                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, indices[i]);
+                for (var _i = 0, indices_1 = indices; _i < indices_1.length; _i++) {
+                    var index = indices_1[_i];
+                    var node = GLTF2.GLTFUtils.GetArrayItem(this._gltf.nodes, index);
                     if (!node) {
-                        throw new Error(context + ": Failed to find node " + indices[i]);
+                        throw new Error(context + ": Failed to find node " + index);
                     }
                     this._traverseNode(context, node, action, parentNode);
                 }
@@ -4130,7 +4169,7 @@ var BABYLON;
                     animation.targets = animation.targets || [];
                     if (targetPath === "influence") {
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
-                        for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
+                        var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
                             var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
@@ -4142,14 +4181,17 @@ var BABYLON;
                             }); }));
                             morphTarget.animations.push(babylonAnimation);
                             animation.targets.push(morphTarget);
+                        };
+                        for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
+                            _loop_7(targetIndex);
                         }
                     }
                     else {
                         var animationName = animation.name || "anim" + animation.index;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
-                        for (var i = 0; i < targetNode.babylonAnimationTargets.length; i++) {
-                            var target = targetNode.babylonAnimationTargets[i];
+                        for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
+                            var target = _a[_i];
                             target.animations.push(babylonAnimation.clone());
                             animation.targets.push(target);
                         }
@@ -4196,28 +4238,15 @@ var BABYLON;
                         this._removePendingData(buffer);
                     }
                     else {
-                        if (!GLTF2.GLTFUtils.ValidateUri(buffer.uri)) {
-                            throw new Error(context + ": Uri '" + buffer.uri + "' is invalid");
-                        }
                         buffer.loadedObservable = new BABYLON.Observable();
                         buffer.loadedObservable.add(function (buffer) {
                             onSuccess(buffer.loadedData);
                             _this._removePendingData(buffer);
                         });
-                        BABYLON.Tools.LoadFile(this._rootUrl + buffer.uri, function (data) {
-                            _this._tryCatchOnError(function () {
-                                buffer.loadedData = new Uint8Array(data);
-                                buffer.loadedObservable.notifyObservers(buffer);
-                                buffer.loadedObservable = null;
-                            });
-                        }, function (event) {
-                            _this._tryCatchOnError(function () {
-                                _this._onProgress(event);
-                            });
-                        }, this._babylonScene.database, true, function (request) {
-                            _this._tryCatchOnError(function () {
-                                throw new Error(context + ": Failed to load '" + buffer.uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
-                            });
+                        this._loadUri(context, buffer.uri, function (data) {
+                            buffer.loadedData = data;
+                            buffer.loadedObservable.notifyObservers(buffer);
+                            buffer.loadedObservable = null;
                         });
                     }
                 }
@@ -4232,8 +4261,9 @@ var BABYLON;
                     if (_this._disposed) {
                         return;
                     }
+                    var data;
                     try {
-                        var data = new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        data = new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -4259,27 +4289,32 @@ var BABYLON;
                         throw new Error(context + ": Invalid type (" + accessor.type + ")");
                     }
                     var data;
-                    switch (accessor.componentType) {
-                        case GLTF2.EComponentType.BYTE:
-                            data = _this._buildArrayBuffer(Float32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_BYTE:
-                            data = _this._buildArrayBuffer(Uint8Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.SHORT:
-                            data = _this._buildArrayBuffer(Int16Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_SHORT:
-                            data = _this._buildArrayBuffer(Uint16Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.UNSIGNED_INT:
-                            data = _this._buildArrayBuffer(Uint32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        case GLTF2.EComponentType.FLOAT:
-                            data = _this._buildArrayBuffer(Float32Array, context, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
-                            break;
-                        default:
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                    try {
+                        switch (accessor.componentType) {
+                            case GLTF2.EComponentType.BYTE:
+                                data = _this._buildArrayBuffer(Float32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_BYTE:
+                                data = _this._buildArrayBuffer(Uint8Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.SHORT:
+                                data = _this._buildArrayBuffer(Int16Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_SHORT:
+                                data = _this._buildArrayBuffer(Uint16Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.UNSIGNED_INT:
+                                data = _this._buildArrayBuffer(Uint32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            case GLTF2.EComponentType.FLOAT:
+                                data = _this._buildArrayBuffer(Float32Array, bufferViewData, accessor.byteOffset, accessor.count, numComponents, bufferView.byteStride);
+                                break;
+                            default:
+                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                        }
+                    }
+                    catch (e) {
+                        throw new Error(context + ": " + e);
                     }
                     onSuccess(data);
                 });
@@ -4296,30 +4331,25 @@ var BABYLON;
                 }
                 return 0;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, context, data, byteOffset, count, numComponents, byteStride) {
-                try {
-                    var byteOffset = data.byteOffset + (byteOffset || 0);
-                    var targetLength = count * numComponents;
-                    if (byteStride == null || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                        return new typedArray(data.buffer, byteOffset, targetLength);
-                    }
-                    var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                    var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                    var targetBuffer = new typedArray(targetLength);
-                    var sourceIndex = 0;
-                    var targetIndex = 0;
-                    while (targetIndex < targetLength) {
-                        for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                            targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                            targetIndex++;
-                        }
-                        sourceIndex += elementStride;
-                    }
-                    return targetBuffer;
+            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
+                byteOffset = data.byteOffset + (byteOffset || 0);
+                var targetLength = count * numComponents;
+                if (byteStride == null || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
+                    return new typedArray(data.buffer, byteOffset, targetLength);
                 }
-                catch (e) {
-                    throw new Error(context + ": " + e);
+                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
+                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
+                var targetBuffer = new typedArray(targetLength);
+                var sourceIndex = 0;
+                var targetIndex = 0;
+                while (targetIndex < targetLength) {
+                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
+                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
+                        targetIndex++;
+                    }
+                    sourceIndex += elementStride;
                 }
+                return targetBuffer;
             };
             GLTFLoader.prototype._addPendingData = function (data) {
                 if (!this._renderReady) {
@@ -4338,10 +4368,16 @@ var BABYLON;
             };
             GLTFLoader.prototype._addLoaderPendingData = function (data) {
                 this._loaderPendingCount++;
-                this._loaderTrackers.forEach(function (tracker) { return tracker._addPendingData(data); });
+                for (var _i = 0, _a = this._loaderTrackers; _i < _a.length; _i++) {
+                    var tracker = _a[_i];
+                    tracker._addPendingData(data);
+                }
             };
             GLTFLoader.prototype._removeLoaderPendingData = function (data) {
-                this._loaderTrackers.forEach(function (tracker) { return tracker._removePendingData(data); });
+                for (var _i = 0, _a = this._loaderTrackers; _i < _a.length; _i++) {
+                    var tracker = _a[_i];
+                    tracker._removePendingData(data);
+                }
                 if (--this._loaderPendingCount === 0) {
                     this._onComplete();
                 }
@@ -4523,12 +4559,12 @@ var BABYLON;
                     texture.dataReadyObservable.add(function (texture) {
                         babylonTexture.updateURL(texture.url);
                     });
-                    var image = GLTF2.GLTFUtils.GetArrayItem(this._gltf.images, texture.source);
-                    if (!image) {
+                    var image_1 = GLTF2.GLTFUtils.GetArrayItem(this._gltf.images, texture.source);
+                    if (!image_1) {
                         throw new Error(context + ": Failed to find source " + texture.source);
                     }
-                    this._loadImage("#/images/" + image.index, image, function (data) {
-                        texture.url = URL.createObjectURL(new Blob([data], { type: image.mimeType }));
+                    this._loadImage("#/images/" + image_1.index, image_1, function (data) {
+                        texture.url = URL.createObjectURL(new Blob([data], { type: image_1.mimeType }));
                         texture.dataReadyObservable.notifyObservers(texture);
                     });
                 }
@@ -4542,28 +4578,12 @@ var BABYLON;
                 return babylonTexture;
             };
             GLTFLoader.prototype._loadImage = function (context, image, onSuccess) {
-                var _this = this;
                 if (image.uri) {
-                    if (!GLTF2.GLTFUtils.ValidateUri(image.uri)) {
-                        throw new Error(context + ": Uri '" + image.uri + "' is invalid");
-                    }
                     if (GLTF2.GLTFUtils.IsBase64(image.uri)) {
                         onSuccess(new Uint8Array(GLTF2.GLTFUtils.DecodeBase64(image.uri)));
                     }
                     else {
-                        BABYLON.Tools.LoadFile(this._rootUrl + image.uri, function (data) {
-                            _this._tryCatchOnError(function () {
-                                onSuccess(data);
-                            });
-                        }, function (event) {
-                            _this._tryCatchOnError(function () {
-                                _this._onProgress(event);
-                            });
-                        }, this._babylonScene.database, true, function (request) {
-                            _this._tryCatchOnError(function () {
-                                throw new Error(context + ": Failed to load '" + image.uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
-                            });
-                        });
+                        this._loadUri(context, image.uri, onSuccess);
                     }
                 }
                 else {
@@ -4574,6 +4594,28 @@ var BABYLON;
                     this._loadBufferViewAsync("#/bufferViews/" + bufferView.index, bufferView, onSuccess);
                 }
             };
+            GLTFLoader.prototype._loadUri = function (context, uri, onSuccess) {
+                var _this = this;
+                if (!GLTF2.GLTFUtils.ValidateUri(uri)) {
+                    throw new Error(context + ": Uri '" + uri + "' is invalid");
+                }
+                var request = BABYLON.Tools.LoadFile(this._rootUrl + uri, function (data) {
+                    _this._tryCatchOnError(function () {
+                        onSuccess(new Uint8Array(data));
+                    });
+                }, function (event) {
+                    _this._tryCatchOnError(function () {
+                        _this._onProgress(event);
+                    });
+                }, this._babylonScene.database, true, function (request) {
+                    _this._tryCatchOnError(function () {
+                        throw new Error(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""));
+                    });
+                });
+                if (request) {
+                    this._requests.push(request);
+                }
+            };
             GLTFLoader.prototype._tryCatchOnError = function (handler) {
                 try {
                     handler();
@@ -4600,7 +4642,7 @@ var BABYLON;
         /**
         * Utils functions for GLTF
         */
-        var GLTFUtils = (function () {
+        var GLTFUtils = /** @class */ (function () {
             function GLTFUtils() {
             }
             /**
@@ -4698,7 +4740,7 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
-        var GLTFLoaderExtension = (function () {
+        var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension() {
                 this.enabled = true;
             }
@@ -4736,8 +4778,8 @@ var BABYLON;
                 if (!extensions) {
                     return false;
                 }
-                for (var i = 0; i < extensions.length; i++) {
-                    var extension = extensions[i];
+                for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
+                    var extension = extensions_1[_i];
                     if (extension.enabled && action(extension)) {
                         return true;
                     }
@@ -4765,7 +4807,7 @@ var BABYLON;
         var Extensions;
         (function (Extensions) {
             // See https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod for more information about this extension.
-            var MSFTLOD = (function (_super) {
+            var MSFTLOD = /** @class */ (function (_super) {
                 __extends(MSFTLOD, _super);
                 function MSFTLOD() {
                     return _super !== null && _super.apply(this, arguments) || this;
@@ -4815,7 +4857,9 @@ var BABYLON;
                             return;
                         }
                         setTimeout(function () {
-                            _this._loadNodeLOD(loader, context, nodes, index - 1, onComplete);
+                            loader._tryCatchOnError(function () {
+                                _this._loadNodeLOD(loader, context, nodes, index - 1, onComplete);
+                            });
                         }, MSFTLOD.MinimalLODDelay);
                     });
                 };
@@ -4844,7 +4888,9 @@ var BABYLON;
                         loader._executeWhenRenderReady(function () {
                             BABYLON.BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), function () {
                                 setTimeout(function () {
-                                    _this._loadMaterialLOD(loader, context, materials, index - 1, assign, onComplete);
+                                    loader._tryCatchOnError(function () {
+                                        _this._loadMaterialLOD(loader, context, materials, index - 1, assign, onComplete);
+                                    });
                                 }, MSFTLOD.MinimalLODDelay);
                             });
                         });
@@ -4872,7 +4918,7 @@ var BABYLON;
     (function (GLTF2) {
         var Extensions;
         (function (Extensions) {
-            var KHRMaterialsPbrSpecularGlossiness = (function (_super) {
+            var KHRMaterialsPbrSpecularGlossiness = /** @class */ (function (_super) {
                 __extends(KHRMaterialsPbrSpecularGlossiness, _super);
                 function KHRMaterialsPbrSpecularGlossiness() {
                     return _super !== null && _super.apply(this, arguments) || this;

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 11 - 12
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -107,11 +107,11 @@ declare module BABYLON {
         json: Object;
         bin: ArrayBufferView;
     }
-    interface IGLTFLoader {
+    interface IGLTFLoader extends IDisposable {
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
     }
-    class GLTFFileLoader implements ISceneLoaderPluginAsync {
+    class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync {
         static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
         onParsed: (data: IGLTFLoaderData) => void;
@@ -125,19 +125,15 @@ declare module BABYLON {
          */
         onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
         /**
-         * Raised when the visible components (geometry, materials, textures, etc.) are first ready to be rendered.
-         * For assets with LODs, raised when the first LOD is complete.
-         * For assets without LODs, raised when the model is complete just before onComplete.
-         */
-        onReady: () => void;
-        /**
          * Raised when the asset is completely loaded, just before the loader is disposed.
          * For assets with LODs, raised when all of the LODs are complete.
-         * For assets without LODs, raised when the model is complete just after onReady.
+         * For assets without LODs, raised when the model is complete just after onSuccess.
          */
         onComplete: () => void;
+        private _loader;
         name: string;
         extensions: ISceneLoaderPluginExtensions;
+        dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         canDirectLoad(data: string): boolean;
@@ -545,6 +541,7 @@ declare module BABYLON.GLTF1 {
             [name: string]: GLTFLoaderExtension;
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
+        dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): boolean;
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void;
         private _loadShadersAsync(gltfRuntime, onload);
@@ -949,9 +946,10 @@ declare module BABYLON.GLTF2 {
 
 
 declare module BABYLON.GLTF2 {
-    class GLTFLoader implements IGLTFLoader, IDisposable {
+    class GLTFLoader implements IGLTFLoader {
         _gltf: IGLTF;
         _babylonScene: Scene;
+        private _disposed;
         private _parent;
         private _rootUrl;
         private _defaultMaterial;
@@ -960,7 +958,7 @@ declare module BABYLON.GLTF2 {
         private _progressCallback;
         private _errorCallback;
         private _renderReady;
-        private _disposed;
+        private _requests;
         private _renderReadyObservable;
         private _renderPendingCount;
         private _loaderPendingCount;
@@ -1008,7 +1006,7 @@ declare module BABYLON.GLTF2 {
         private _loadBufferViewAsync(context, bufferView, onSuccess);
         private _loadAccessorAsync(context, accessor, onSuccess);
         private _getNumComponentsOfType(type);
-        private _buildArrayBuffer<T>(typedArray, context, data, byteOffset, count, numComponents, byteStride);
+        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride);
         _addPendingData(data: any): void;
         _removePendingData(data: any): void;
         _addLoaderPendingData(data: any): void;
@@ -1022,6 +1020,7 @@ declare module BABYLON.GLTF2 {
         _loadMaterialAlphaProperties(context: string, material: IGLTFMaterial, colorFactor: number[]): void;
         _loadTexture(context: string, texture: IGLTFTexture, coordinatesIndex: number): Texture;
         private _loadImage(context, image, onSuccess);
+        _loadUri(context: string, uri: string, onSuccess: (data: ArrayBufferView) => void): void;
         _tryCatchOnError(handler: () => void): void;
     }
 }

+ 1 - 1
dist/preview release/loaders/readme.md

@@ -36,7 +36,7 @@ Afterwards it can be imported to the project using:
 
 ```
 import * as BABYLON from 'babylonjs';
-import from 'babylonjs-loaders';
+import 'babylonjs-loaders';
 ```
 
 This will extend Babylon's namespace with the loaders available.

+ 2 - 2
dist/preview release/materialsLibrary/babylon.cellMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var CellMaterialDefines = (function (_super) {
+    var CellMaterialDefines = /** @class */ (function (_super) {
         __extends(CellMaterialDefines, _super);
         function CellMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -43,7 +43,7 @@ var BABYLON;
         }
         return CellMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var CellMaterial = (function (_super) {
+    var CellMaterial = /** @class */ (function (_super) {
         __extends(CellMaterial, _super);
         function CellMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 7 - 7
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -18,7 +18,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 var BABYLON;
 (function (BABYLON) {
     // old version of standard material updated every 3 months
-    var StandardMaterialDefines_OldVer = (function (_super) {
+    var StandardMaterialDefines_OldVer = /** @class */ (function (_super) {
         __extends(StandardMaterialDefines_OldVer, _super);
         function StandardMaterialDefines_OldVer() {
             var _this = _super.call(this) || this;
@@ -111,7 +111,7 @@ var BABYLON;
         return StandardMaterialDefines_OldVer;
     }(BABYLON.MaterialDefines));
     BABYLON.StandardMaterialDefines_OldVer = StandardMaterialDefines_OldVer;
-    var StandardMaterial_OldVer = (function (_super) {
+    var StandardMaterial_OldVer = /** @class */ (function (_super) {
         __extends(StandardMaterial_OldVer, _super);
         function StandardMaterial_OldVer(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -1382,19 +1382,19 @@ var BABYLON;
         return StandardMaterial_OldVer;
     }(BABYLON.PushMaterial));
     BABYLON.StandardMaterial_OldVer = StandardMaterial_OldVer;
-    var CustomShaderStructure = (function () {
+    var CustomShaderStructure = /** @class */ (function () {
         function CustomShaderStructure() {
         }
         return CustomShaderStructure;
     }());
     BABYLON.CustomShaderStructure = CustomShaderStructure;
-    var ShaderSpecialParts = (function () {
+    var ShaderSpecialParts = /** @class */ (function () {
         function ShaderSpecialParts() {
         }
         return ShaderSpecialParts;
     }());
     BABYLON.ShaderSpecialParts = ShaderSpecialParts;
-    var ShaderForVer3_0 = (function (_super) {
+    var ShaderForVer3_0 = /** @class */ (function (_super) {
         __extends(ShaderForVer3_0, _super);
         function ShaderForVer3_0() {
             var _this = _super.call(this) || this;
@@ -1895,14 +1895,14 @@ vColor=color;\n\
         return ShaderForVer3_0;
     }(CustomShaderStructure));
     BABYLON.ShaderForVer3_0 = ShaderForVer3_0;
-    var StandardShaderVersions = (function () {
+    var StandardShaderVersions = /** @class */ (function () {
         function StandardShaderVersions() {
         }
         StandardShaderVersions.Ver3_0 = "3.0.0";
         return StandardShaderVersions;
     }());
     BABYLON.StandardShaderVersions = StandardShaderVersions;
-    var CustomMaterial = (function (_super) {
+    var CustomMaterial = /** @class */ (function (_super) {
         __extends(CustomMaterial, _super);
         function CustomMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var FireMaterialDefines = (function (_super) {
+    var FireMaterialDefines = /** @class */ (function (_super) {
         __extends(FireMaterialDefines, _super);
         function FireMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -38,7 +38,7 @@ var BABYLON;
         }
         return FireMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var FireMaterial = (function (_super) {
+    var FireMaterial = /** @class */ (function (_super) {
         __extends(FireMaterial, _super);
         function FireMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var FurMaterialDefines = (function (_super) {
+    var FurMaterialDefines = /** @class */ (function (_super) {
         __extends(FurMaterialDefines, _super);
         function FurMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -42,7 +42,7 @@ var BABYLON;
         }
         return FurMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var FurMaterial = (function (_super) {
+    var FurMaterial = /** @class */ (function (_super) {
         __extends(FurMaterial, _super);
         function FurMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var GradientMaterialDefines = (function (_super) {
+    var GradientMaterialDefines = /** @class */ (function (_super) {
         __extends(GradientMaterialDefines, _super);
         function GradientMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -73,7 +73,7 @@ var BABYLON;
         }
         return GradientMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var GradientMaterial = (function (_super) {
+    var GradientMaterial = /** @class */ (function (_super) {
         __extends(GradientMaterial, _super);
         function GradientMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.gridMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var GridMaterialDefines = (function (_super) {
+    var GridMaterialDefines = /** @class */ (function (_super) {
         __extends(GridMaterialDefines, _super);
         function GridMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -33,7 +33,7 @@ var BABYLON;
      * The grid materials allows you to wrap any shape with a grid.
      * Colors are customizable.
      */
-    var GridMaterial = (function (_super) {
+    var GridMaterial = /** @class */ (function (_super) {
         __extends(GridMaterial, _super);
         /**
          * constructor

+ 2 - 2
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var LavaMaterialDefines = (function (_super) {
+    var LavaMaterialDefines = /** @class */ (function (_super) {
         __extends(LavaMaterialDefines, _super);
         function LavaMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -73,7 +73,7 @@ var BABYLON;
         }
         return LavaMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var LavaMaterial = (function (_super) {
+    var LavaMaterial = /** @class */ (function (_super) {
         __extends(LavaMaterial, _super);
         function LavaMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.legacyPbrMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var LegacyPBRMaterialDefines = (function (_super) {
+    var LegacyPBRMaterialDefines = /** @class */ (function (_super) {
         __extends(LegacyPBRMaterialDefines, _super);
         function LegacyPBRMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -110,7 +110,7 @@ var BABYLON;
      * For more information, please refer to the documentation :
      * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
      */
-    var LegacyPBRMaterial = (function (_super) {
+    var LegacyPBRMaterial = /** @class */ (function (_super) {
         __extends(LegacyPBRMaterial, _super);
         /**
          * Instantiates a new PBRMaterial instance.

+ 2 - 2
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var NormalMaterialDefines = (function (_super) {
+    var NormalMaterialDefines = /** @class */ (function (_super) {
         __extends(NormalMaterialDefines, _super);
         function NormalMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -73,7 +73,7 @@ var BABYLON;
         }
         return NormalMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var NormalMaterial = (function (_super) {
+    var NormalMaterial = /** @class */ (function (_super) {
         __extends(NormalMaterial, _super);
         function NormalMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var ShadowOnlyMaterialDefines = (function (_super) {
+    var ShadowOnlyMaterialDefines = /** @class */ (function (_super) {
         __extends(ShadowOnlyMaterialDefines, _super);
         function ShadowOnlyMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -27,7 +27,7 @@ var BABYLON;
         }
         return ShadowOnlyMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var ShadowOnlyMaterial = (function (_super) {
+    var ShadowOnlyMaterial = /** @class */ (function (_super) {
         __extends(ShadowOnlyMaterial, _super);
         function ShadowOnlyMaterial(name, scene) {
             return _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var SimpleMaterialDefines = (function (_super) {
+    var SimpleMaterialDefines = /** @class */ (function (_super) {
         __extends(SimpleMaterialDefines, _super);
         function SimpleMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -40,7 +40,7 @@ var BABYLON;
         }
         return SimpleMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var SimpleMaterial = (function (_super) {
+    var SimpleMaterial = /** @class */ (function (_super) {
         __extends(SimpleMaterial, _super);
         function SimpleMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.skyMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var SkyMaterialDefines = (function (_super) {
+    var SkyMaterialDefines = /** @class */ (function (_super) {
         __extends(SkyMaterialDefines, _super);
         function SkyMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -31,7 +31,7 @@ var BABYLON;
         }
         return SkyMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var SkyMaterial = (function (_super) {
+    var SkyMaterial = /** @class */ (function (_super) {
         __extends(SkyMaterial, _super);
         function SkyMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var TerrainMaterialDefines = (function (_super) {
+    var TerrainMaterialDefines = /** @class */ (function (_super) {
         __extends(TerrainMaterialDefines, _super);
         function TerrainMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -42,7 +42,7 @@ var BABYLON;
         }
         return TerrainMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var TerrainMaterial = (function (_super) {
+    var TerrainMaterial = /** @class */ (function (_super) {
         __extends(TerrainMaterial, _super);
         function TerrainMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var TriPlanarMaterialDefines = (function (_super) {
+    var TriPlanarMaterialDefines = /** @class */ (function (_super) {
         __extends(TriPlanarMaterialDefines, _super);
         function TriPlanarMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -44,7 +44,7 @@ var BABYLON;
         }
         return TriPlanarMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var TriPlanarMaterial = (function (_super) {
+    var TriPlanarMaterial = /** @class */ (function (_super) {
         __extends(TriPlanarMaterial, _super);
         function TriPlanarMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;

+ 2 - 2
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -17,7 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
 };
 var BABYLON;
 (function (BABYLON) {
-    var WaterMaterialDefines = (function (_super) {
+    var WaterMaterialDefines = /** @class */ (function (_super) {
         __extends(WaterMaterialDefines, _super);
         function WaterMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -46,7 +46,7 @@ var BABYLON;
         }
         return WaterMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var WaterMaterial = (function (_super) {
+    var WaterMaterial = /** @class */ (function (_super) {
         __extends(WaterMaterial, _super);
         /**
         * Constructor

+ 35 - 35
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -20,7 +20,7 @@ var __extends = (this && this.__extends) || (function () {
 
 var BABYLON;
 (function (BABYLON) {
-    var ShadowOnlyMaterialDefines = (function (_super) {
+    var ShadowOnlyMaterialDefines = /** @class */ (function (_super) {
         __extends(ShadowOnlyMaterialDefines, _super);
         function ShadowOnlyMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -36,7 +36,7 @@ var BABYLON;
         }
         return ShadowOnlyMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var ShadowOnlyMaterial = (function (_super) {
+    var ShadowOnlyMaterial = /** @class */ (function (_super) {
         __extends(ShadowOnlyMaterial, _super);
         function ShadowOnlyMaterial(name, scene) {
             return _super.call(this, name, scene) || this;
@@ -221,7 +221,7 @@ BABYLON.Effect.ShadersStore['shadowOnlyPixelShader'] = "precision highp float;\n
 
 var BABYLON;
 (function (BABYLON) {
-    var GradientMaterialDefines = (function (_super) {
+    var GradientMaterialDefines = /** @class */ (function (_super) {
         __extends(GradientMaterialDefines, _super);
         function GradientMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -277,7 +277,7 @@ var BABYLON;
         }
         return GradientMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var GradientMaterial = (function (_super) {
+    var GradientMaterial = /** @class */ (function (_super) {
         __extends(GradientMaterial, _super);
         function GradientMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -496,7 +496,7 @@ BABYLON.Effect.ShadersStore['gradientPixelShader'] = "precision highp float;\n\n
 
 var BABYLON;
 (function (BABYLON) {
-    var NormalMaterialDefines = (function (_super) {
+    var NormalMaterialDefines = /** @class */ (function (_super) {
         __extends(NormalMaterialDefines, _super);
         function NormalMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -552,7 +552,7 @@ var BABYLON;
         }
         return NormalMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var NormalMaterial = (function (_super) {
+    var NormalMaterial = /** @class */ (function (_super) {
         __extends(NormalMaterial, _super);
         function NormalMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -798,7 +798,7 @@ BABYLON.Effect.ShadersStore['normalPixelShader'] = "precision highp float;\n\nun
 
 var BABYLON;
 (function (BABYLON) {
-    var LavaMaterialDefines = (function (_super) {
+    var LavaMaterialDefines = /** @class */ (function (_super) {
         __extends(LavaMaterialDefines, _super);
         function LavaMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -854,7 +854,7 @@ var BABYLON;
         }
         return LavaMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var LavaMaterial = (function (_super) {
+    var LavaMaterial = /** @class */ (function (_super) {
         __extends(LavaMaterial, _super);
         function LavaMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -1146,7 +1146,7 @@ BABYLON.Effect.ShadersStore['lavaPixelShader'] = "precision highp float;\n\nunif
 
 var BABYLON;
 (function (BABYLON) {
-    var SimpleMaterialDefines = (function (_super) {
+    var SimpleMaterialDefines = /** @class */ (function (_super) {
         __extends(SimpleMaterialDefines, _super);
         function SimpleMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -1169,7 +1169,7 @@ var BABYLON;
         }
         return SimpleMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var SimpleMaterial = (function (_super) {
+    var SimpleMaterial = /** @class */ (function (_super) {
         __extends(SimpleMaterial, _super);
         function SimpleMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -1415,7 +1415,7 @@ BABYLON.Effect.ShadersStore['simplePixelShader'] = "precision highp float;\n\nun
 
 var BABYLON;
 (function (BABYLON) {
-    var WaterMaterialDefines = (function (_super) {
+    var WaterMaterialDefines = /** @class */ (function (_super) {
         __extends(WaterMaterialDefines, _super);
         function WaterMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -1444,7 +1444,7 @@ var BABYLON;
         }
         return WaterMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var WaterMaterial = (function (_super) {
+    var WaterMaterial = /** @class */ (function (_super) {
         __extends(WaterMaterial, _super);
         /**
         * Constructor
@@ -2007,7 +2007,7 @@ BABYLON.Effect.ShadersStore['waterPixelShader'] = "#ifdef LOGARITHMICDEPTH\n#ext
 
 var BABYLON;
 (function (BABYLON) {
-    var FireMaterialDefines = (function (_super) {
+    var FireMaterialDefines = /** @class */ (function (_super) {
         __extends(FireMaterialDefines, _super);
         function FireMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -2028,7 +2028,7 @@ var BABYLON;
         }
         return FireMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var FireMaterial = (function (_super) {
+    var FireMaterial = /** @class */ (function (_super) {
         __extends(FireMaterial, _super);
         function FireMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -2322,7 +2322,7 @@ BABYLON.Effect.ShadersStore['firePixelShader'] = "precision highp float;\n\nunif
 
 var BABYLON;
 (function (BABYLON) {
-    var FurMaterialDefines = (function (_super) {
+    var FurMaterialDefines = /** @class */ (function (_super) {
         __extends(FurMaterialDefines, _super);
         function FurMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -2347,7 +2347,7 @@ var BABYLON;
         }
         return FurMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var FurMaterial = (function (_super) {
+    var FurMaterial = /** @class */ (function (_super) {
         __extends(FurMaterial, _super);
         function FurMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -2778,7 +2778,7 @@ BABYLON.Effect.ShadersStore['furPixelShader'] = "precision highp float;\n\nunifo
 
 var BABYLON;
 (function (BABYLON) {
-    var TerrainMaterialDefines = (function (_super) {
+    var TerrainMaterialDefines = /** @class */ (function (_super) {
         __extends(TerrainMaterialDefines, _super);
         function TerrainMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -2803,7 +2803,7 @@ var BABYLON;
         }
         return TerrainMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var TerrainMaterial = (function (_super) {
+    var TerrainMaterial = /** @class */ (function (_super) {
         __extends(TerrainMaterial, _super);
         function TerrainMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -3162,7 +3162,7 @@ BABYLON.Effect.ShadersStore['terrainPixelShader'] = "precision highp float;\n\nu
 
 var BABYLON;
 (function (BABYLON) {
-    var TriPlanarMaterialDefines = (function (_super) {
+    var TriPlanarMaterialDefines = /** @class */ (function (_super) {
         __extends(TriPlanarMaterialDefines, _super);
         function TriPlanarMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -3189,7 +3189,7 @@ var BABYLON;
         }
         return TriPlanarMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var TriPlanarMaterial = (function (_super) {
+    var TriPlanarMaterial = /** @class */ (function (_super) {
         __extends(TriPlanarMaterial, _super);
         function TriPlanarMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -3541,7 +3541,7 @@ BABYLON.Effect.ShadersStore['triplanarPixelShader'] = "precision highp float;\n\
 
 var BABYLON;
 (function (BABYLON) {
-    var SkyMaterialDefines = (function (_super) {
+    var SkyMaterialDefines = /** @class */ (function (_super) {
         __extends(SkyMaterialDefines, _super);
         function SkyMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -3555,7 +3555,7 @@ var BABYLON;
         }
         return SkyMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var SkyMaterial = (function (_super) {
+    var SkyMaterial = /** @class */ (function (_super) {
         __extends(SkyMaterial, _super);
         function SkyMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -3753,7 +3753,7 @@ BABYLON.Effect.ShadersStore['skyPixelShader'] = "precision highp float;\n\nvaryi
 
 var BABYLON;
 (function (BABYLON) {
-    var GridMaterialDefines = (function (_super) {
+    var GridMaterialDefines = /** @class */ (function (_super) {
         __extends(GridMaterialDefines, _super);
         function GridMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -3769,7 +3769,7 @@ var BABYLON;
      * The grid materials allows you to wrap any shape with a grid.
      * Colors are customizable.
      */
-    var GridMaterial = (function (_super) {
+    var GridMaterial = /** @class */ (function (_super) {
         __extends(GridMaterial, _super);
         /**
          * constructor
@@ -3947,7 +3947,7 @@ BABYLON.Effect.ShadersStore['gridPixelShader'] = "#extension GL_OES_standard_der
 var BABYLON;
 (function (BABYLON) {
     // old version of standard material updated every 3 months
-    var StandardMaterialDefines_OldVer = (function (_super) {
+    var StandardMaterialDefines_OldVer = /** @class */ (function (_super) {
         __extends(StandardMaterialDefines_OldVer, _super);
         function StandardMaterialDefines_OldVer() {
             var _this = _super.call(this) || this;
@@ -4040,7 +4040,7 @@ var BABYLON;
         return StandardMaterialDefines_OldVer;
     }(BABYLON.MaterialDefines));
     BABYLON.StandardMaterialDefines_OldVer = StandardMaterialDefines_OldVer;
-    var StandardMaterial_OldVer = (function (_super) {
+    var StandardMaterial_OldVer = /** @class */ (function (_super) {
         __extends(StandardMaterial_OldVer, _super);
         function StandardMaterial_OldVer(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -5311,19 +5311,19 @@ var BABYLON;
         return StandardMaterial_OldVer;
     }(BABYLON.PushMaterial));
     BABYLON.StandardMaterial_OldVer = StandardMaterial_OldVer;
-    var CustomShaderStructure = (function () {
+    var CustomShaderStructure = /** @class */ (function () {
         function CustomShaderStructure() {
         }
         return CustomShaderStructure;
     }());
     BABYLON.CustomShaderStructure = CustomShaderStructure;
-    var ShaderSpecialParts = (function () {
+    var ShaderSpecialParts = /** @class */ (function () {
         function ShaderSpecialParts() {
         }
         return ShaderSpecialParts;
     }());
     BABYLON.ShaderSpecialParts = ShaderSpecialParts;
-    var ShaderForVer3_0 = (function (_super) {
+    var ShaderForVer3_0 = /** @class */ (function (_super) {
         __extends(ShaderForVer3_0, _super);
         function ShaderForVer3_0() {
             var _this = _super.call(this) || this;
@@ -5824,14 +5824,14 @@ vColor=color;\n\
         return ShaderForVer3_0;
     }(CustomShaderStructure));
     BABYLON.ShaderForVer3_0 = ShaderForVer3_0;
-    var StandardShaderVersions = (function () {
+    var StandardShaderVersions = /** @class */ (function () {
         function StandardShaderVersions() {
         }
         StandardShaderVersions.Ver3_0 = "3.0.0";
         return StandardShaderVersions;
     }());
     BABYLON.StandardShaderVersions = StandardShaderVersions;
-    var CustomMaterial = (function (_super) {
+    var CustomMaterial = /** @class */ (function (_super) {
         __extends(CustomMaterial, _super);
         function CustomMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -5991,7 +5991,7 @@ vColor=color;\n\
 
 var BABYLON;
 (function (BABYLON) {
-    var CellMaterialDefines = (function (_super) {
+    var CellMaterialDefines = /** @class */ (function (_super) {
         __extends(CellMaterialDefines, _super);
         function CellMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -6017,7 +6017,7 @@ var BABYLON;
         }
         return CellMaterialDefines;
     }(BABYLON.MaterialDefines));
-    var CellMaterial = (function (_super) {
+    var CellMaterial = /** @class */ (function (_super) {
         __extends(CellMaterial, _super);
         function CellMaterial(name, scene) {
             var _this = _super.call(this, name, scene) || this;
@@ -6269,7 +6269,7 @@ BABYLON.Effect.ShadersStore['cellPixelShader'] = "precision highp float;\n\nunif
 
 var BABYLON;
 (function (BABYLON) {
-    var LegacyPBRMaterialDefines = (function (_super) {
+    var LegacyPBRMaterialDefines = /** @class */ (function (_super) {
         __extends(LegacyPBRMaterialDefines, _super);
         function LegacyPBRMaterialDefines() {
             var _this = _super.call(this) || this;
@@ -6362,7 +6362,7 @@ var BABYLON;
      * For more information, please refer to the documentation :
      * http://doc.babylonjs.com/extensions/Physically_Based_Rendering
      */
-    var LegacyPBRMaterial = (function (_super) {
+    var LegacyPBRMaterial = /** @class */ (function (_super) {
         __extends(LegacyPBRMaterial, _super);
         /**
          * Instantiates a new PBRMaterial instance.

+ 1 - 1
dist/preview release/materialsLibrary/readme.md

@@ -36,7 +36,7 @@ Afterwards it can be imported to the project using:
 
 ```
 import * as BABYLON from 'babylonjs';
-import from 'babylonjs-materials';
+import 'babylonjs-materials';
 ```
 
 This will extend Babylon's namespace with the materials available:

+ 2 - 2
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.js

@@ -23,7 +23,7 @@ var BABYLON;
      * It basically takes care rendering the font front the given font size to a texture.
      * This is used later on in the postprocess.
      */
-    var AsciiArtFontTexture = (function (_super) {
+    var AsciiArtFontTexture = /** @class */ (function (_super) {
         __extends(AsciiArtFontTexture, _super);
         /**
          * Create a new instance of the Ascii Art FontTexture class
@@ -160,7 +160,7 @@ var BABYLON;
      * Simmply add it to your scene and let the nerd that lives in you have fun.
      * Example usage: var pp = new AsciiArtPostProcess("myAscii", "20px Monospace", camera);
      */
-    var AsciiArtPostProcess = (function (_super) {
+    var AsciiArtPostProcess = /** @class */ (function (_super) {
         __extends(AsciiArtPostProcess, _super);
         /**
          * Instantiates a new Ascii Art Post Process.

+ 2 - 2
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.js

@@ -23,7 +23,7 @@ var BABYLON;
      * It basically takes care rendering the font front the given font size to a texture.
      * This is used later on in the postprocess.
      */
-    var DigitalRainFontTexture = (function (_super) {
+    var DigitalRainFontTexture = /** @class */ (function (_super) {
         __extends(DigitalRainFontTexture, _super);
         /**
          * Create a new instance of the Digital Rain FontTexture class
@@ -160,7 +160,7 @@ var BABYLON;
      * Simmply add it to your scene and let the nerd that lives in you have fun.
      * Example usage: var pp = new DigitalRainPostProcess("digitalRain", "20px Monospace", camera);
      */
-    var DigitalRainPostProcess = (function (_super) {
+    var DigitalRainPostProcess = /** @class */ (function (_super) {
         __extends(DigitalRainPostProcess, _super);
         /**
          * Instantiates a new Digital Rain Post Process.

+ 4 - 4
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js

@@ -27,7 +27,7 @@ var BABYLON;
      * It basically takes care rendering the font front the given font size to a texture.
      * This is used later on in the postprocess.
      */
-    var AsciiArtFontTexture = (function (_super) {
+    var AsciiArtFontTexture = /** @class */ (function (_super) {
         __extends(AsciiArtFontTexture, _super);
         /**
          * Create a new instance of the Ascii Art FontTexture class
@@ -164,7 +164,7 @@ var BABYLON;
      * Simmply add it to your scene and let the nerd that lives in you have fun.
      * Example usage: var pp = new AsciiArtPostProcess("myAscii", "20px Monospace", camera);
      */
-    var AsciiArtPostProcess = (function (_super) {
+    var AsciiArtPostProcess = /** @class */ (function (_super) {
         __extends(AsciiArtPostProcess, _super);
         /**
          * Instantiates a new Ascii Art Post Process.
@@ -231,7 +231,7 @@ var BABYLON;
      * It basically takes care rendering the font front the given font size to a texture.
      * This is used later on in the postprocess.
      */
-    var DigitalRainFontTexture = (function (_super) {
+    var DigitalRainFontTexture = /** @class */ (function (_super) {
         __extends(DigitalRainFontTexture, _super);
         /**
          * Create a new instance of the Digital Rain FontTexture class
@@ -368,7 +368,7 @@ var BABYLON;
      * Simmply add it to your scene and let the nerd that lives in you have fun.
      * Example usage: var pp = new DigitalRainPostProcess("digitalRain", "20px Monospace", camera);
      */
-    var DigitalRainPostProcess = (function (_super) {
+    var DigitalRainPostProcess = /** @class */ (function (_super) {
         __extends(DigitalRainPostProcess, _super);
         /**
          * Instantiates a new Digital Rain Post Process.

+ 1 - 1
dist/preview release/postProcessesLibrary/readme.md

@@ -36,7 +36,7 @@ Afterwards it can be imported to the project using:
 
 ```
 import * as BABYLON from 'babylonjs';
-import from 'babylonjs-post-process';
+import 'babylonjs-post-process';
 ```
 
 This will extend Babylon's namespace with the post processes available:

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.brickProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var BrickProceduralTexture = (function (_super) {
+    var BrickProceduralTexture = /** @class */ (function (_super) {
         __extends(BrickProceduralTexture, _super);
         function BrickProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "brickProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.cloudProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var CloudProceduralTexture = (function (_super) {
+    var CloudProceduralTexture = /** @class */ (function (_super) {
         __extends(CloudProceduralTexture, _super);
         function CloudProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "cloudProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.fireProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var FireProceduralTexture = (function (_super) {
+    var FireProceduralTexture = /** @class */ (function (_super) {
         __extends(FireProceduralTexture, _super);
         function FireProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "fireProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.grassProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var GrassProceduralTexture = (function (_super) {
+    var GrassProceduralTexture = /** @class */ (function (_super) {
         __extends(GrassProceduralTexture, _super);
         function GrassProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "grassProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.marbleProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var MarbleProceduralTexture = (function (_super) {
+    var MarbleProceduralTexture = /** @class */ (function (_super) {
         __extends(MarbleProceduralTexture, _super);
         function MarbleProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "marbleProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var NormalMapProceduralTexture = (function (_super) {
+    var NormalMapProceduralTexture = /** @class */ (function (_super) {
         __extends(NormalMapProceduralTexture, _super);
         function NormalMapProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "normalMapProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.perlinNoiseProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var PerlinNoiseProceduralTexture = (function (_super) {
+    var PerlinNoiseProceduralTexture = /** @class */ (function (_super) {
         __extends(PerlinNoiseProceduralTexture, _super);
         function PerlinNoiseProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "perlinNoiseProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.roadProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var RoadProceduralTexture = (function (_super) {
+    var RoadProceduralTexture = /** @class */ (function (_super) {
         __extends(RoadProceduralTexture, _super);
         function RoadProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "roadProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var StarfieldProceduralTexture = (function (_super) {
+    var StarfieldProceduralTexture = /** @class */ (function (_super) {
         __extends(StarfieldProceduralTexture, _super);
         function StarfieldProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "starfieldProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylon.woodProceduralTexture.js

@@ -11,7 +11,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var BABYLON;
 (function (BABYLON) {
-    var WoodProceduralTexture = (function (_super) {
+    var WoodProceduralTexture = /** @class */ (function (_super) {
         __extends(WoodProceduralTexture, _super);
         function WoodProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "woodProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 10 - 10
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js

@@ -20,7 +20,7 @@ var __extends = (this && this.__extends) || (function () {
 
 var BABYLON;
 (function (BABYLON) {
-    var WoodProceduralTexture = (function (_super) {
+    var WoodProceduralTexture = /** @class */ (function (_super) {
         __extends(WoodProceduralTexture, _super);
         function WoodProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "woodProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -68,7 +68,7 @@ BABYLON.Effect.ShadersStore['woodProceduralTexturePixelShader'] = "precision hig
 
 var BABYLON;
 (function (BABYLON) {
-    var FireProceduralTexture = (function (_super) {
+    var FireProceduralTexture = /** @class */ (function (_super) {
         __extends(FireProceduralTexture, _super);
         function FireProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "fireProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -211,7 +211,7 @@ BABYLON.Effect.ShadersStore['fireProceduralTexturePixelShader'] = "precision hig
 
 var BABYLON;
 (function (BABYLON) {
-    var CloudProceduralTexture = (function (_super) {
+    var CloudProceduralTexture = /** @class */ (function (_super) {
         __extends(CloudProceduralTexture, _super);
         function CloudProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "cloudProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -259,7 +259,7 @@ BABYLON.Effect.ShadersStore['cloudProceduralTexturePixelShader'] = "precision hi
 
 var BABYLON;
 (function (BABYLON) {
-    var GrassProceduralTexture = (function (_super) {
+    var GrassProceduralTexture = /** @class */ (function (_super) {
         __extends(GrassProceduralTexture, _super);
         function GrassProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "grassProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -313,7 +313,7 @@ BABYLON.Effect.ShadersStore['grassProceduralTexturePixelShader'] = "precision hi
 
 var BABYLON;
 (function (BABYLON) {
-    var RoadProceduralTexture = (function (_super) {
+    var RoadProceduralTexture = /** @class */ (function (_super) {
         __extends(RoadProceduralTexture, _super);
         function RoadProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "roadProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -348,7 +348,7 @@ BABYLON.Effect.ShadersStore['roadProceduralTexturePixelShader'] = "precision hig
 
 var BABYLON;
 (function (BABYLON) {
-    var BrickProceduralTexture = (function (_super) {
+    var BrickProceduralTexture = /** @class */ (function (_super) {
         __extends(BrickProceduralTexture, _super);
         function BrickProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "brickProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -422,7 +422,7 @@ BABYLON.Effect.ShadersStore['brickProceduralTexturePixelShader'] = "precision hi
 
 var BABYLON;
 (function (BABYLON) {
-    var MarbleProceduralTexture = (function (_super) {
+    var MarbleProceduralTexture = /** @class */ (function (_super) {
         __extends(MarbleProceduralTexture, _super);
         function MarbleProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "marbleProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -496,7 +496,7 @@ BABYLON.Effect.ShadersStore['marbleProceduralTexturePixelShader'] = "precision h
 
 var BABYLON;
 (function (BABYLON) {
-    var StarfieldProceduralTexture = (function (_super) {
+    var StarfieldProceduralTexture = /** @class */ (function (_super) {
         __extends(StarfieldProceduralTexture, _super);
         function StarfieldProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "starfieldProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -661,7 +661,7 @@ BABYLON.Effect.ShadersStore['starfieldProceduralTexturePixelShader'] = "precisio
 
 var BABYLON;
 (function (BABYLON) {
-    var NormalMapProceduralTexture = (function (_super) {
+    var NormalMapProceduralTexture = /** @class */ (function (_super) {
         __extends(NormalMapProceduralTexture, _super);
         function NormalMapProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "normalMapProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;
@@ -704,7 +704,7 @@ BABYLON.Effect.ShadersStore['normalMapProceduralTexturePixelShader'] = "precisio
 
 var BABYLON;
 (function (BABYLON) {
-    var PerlinNoiseProceduralTexture = (function (_super) {
+    var PerlinNoiseProceduralTexture = /** @class */ (function (_super) {
         __extends(PerlinNoiseProceduralTexture, _super);
         function PerlinNoiseProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
             var _this = _super.call(this, name, size, "perlinNoiseProceduralTexture", scene, fallbackTexture, generateMipMaps) || this;

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/readme.md

@@ -36,7 +36,7 @@ Afterwards it can be imported to the project using:
 
 ```
 import * as BABYLON from 'babylonjs';
-import from 'babylonjs-procedural-textures';
+import 'babylonjs-procedural-textures';
 ```
 
 This will extend Babylon's namespace with the procedural textures available:

+ 1 - 1
dist/preview release/serializers/babylon.objSerializer.js

@@ -1,7 +1,7 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
-    var OBJExport = (function () {
+    var OBJExport = /** @class */ (function () {
         function OBJExport() {
         }
         //Exports the geometrys of a Mesh array in .OBJ file format (text)

+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.js

@@ -19,7 +19,7 @@ var __extends = (this && this.__extends) || (function () {
         
 var BABYLON;
 (function (BABYLON) {
-    var OBJExport = (function () {
+    var OBJExport = /** @class */ (function () {
         function OBJExport() {
         }
         //Exports the geometrys of a Mesh array in .OBJ file format (text)

+ 2 - 1
dist/preview release/what's new.md

@@ -16,7 +16,7 @@
 - Added support for `material.separateCullingPass`. [Doc here](http://doc.babylonjs.com/tutorials/transparency_and_how_meshes_are_rendered#things-to-do-and-not-to-do) ([sebavan](https://github.com/sebavan))
 - Added support for Windows Motion Controllers ([Lewis Weaver](https://github.com/leweaver))
 - Added support for Particle animation in ParticleSystem. [Doc here](http://doc.babylonjs.com/tutorials/particles#particle-animation) ([Ibraheem Osama](https://github.com/IbraheemOsama))
-- More robust TypeScript code with *noImplicitAny*, *noImplicitThis* and *noImplicitReturns* compiler options ([deltakosh](https://github.com/deltakosh))
+- More robust TypeScript code with *strictNullChecks*, *noImplicitAny*, *noImplicitThis* and *noImplicitReturns* compiler options ([deltakosh](https://github.com/deltakosh))
 - Introduced `NullEngine` which can be used to use Babylon.js in headless mode. [Doc here](http://doc.babylonjs.com/generals/nullengine) ([deltakosh](https://github.com/deltakosh)) 
 
 ## Updates
@@ -43,3 +43,4 @@
 
 ## Breaking changes
 - `Gamepads` was removed in favor of `scene.gamepadManager`
+- `DynamicFloatArray`, `MapTexture` and `RectPakingMap` were removed because there were not used anymore

+ 0 - 3
inspector/src/properties.ts

@@ -75,9 +75,6 @@ module INSPECTOR {
             ],
             format: (tex: BABYLON.Texture) => { return tex.name }
         },
-        'MapTexture': {
-            type: BABYLON.MapTexture
-        },
         'RenderTargetTexture': {
             type: BABYLON.RenderTargetTexture
         },

+ 1 - 8
inspector/src/tabs/TextureTab.ts

@@ -85,14 +85,7 @@ module INSPECTOR {
                 imgs.push(Helpers.CreateElement('img', 'texture-image', this._imagePanel) as HTMLImageElement);
             }
             
-            if (texture instanceof BABYLON.MapTexture) {
-                // instance of Map texture
-                texture.bindTextureForPosSize(new BABYLON.Vector2(0, 0), new BABYLON.Size(texture.getSize().width, texture.getSize().height), false);
-                BABYLON.Tools.DumpFramebuffer(texture.getSize().width, texture.getSize().height, this._inspector.scene.getEngine(), (data) => img.src = data);
-                texture.unbindTexture();
-
-            }
-            else if (texture instanceof BABYLON.RenderTargetTexture) {
+            if (texture instanceof BABYLON.RenderTargetTexture) {
                 // RenderTarget textures
                 let scene = this._inspector.scene;
                 let engine = scene.getEngine();

+ 4 - 0
loaders/src/glTF/1.0/babylon.glTFLoader.ts

@@ -1512,6 +1512,10 @@ module BABYLON.GLTF1 {
             GLTFLoader.Extensions[extension.name] = extension;
         }
 
+        public dispose(): void {
+            // do nothing
+        }
+
         public importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): boolean {
             scene.useRightHandedSystem = true;
 

+ 3 - 3
loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts

@@ -24,14 +24,14 @@ module BABYLON.GLTF2.Extensions {
         }
 
         private _loadSpecularGlossinessProperties(loader: GLTFLoader, context: string, material: IGLTFMaterial, properties: IKHRMaterialsPbrSpecularGlossiness): void {
-            var babylonMaterial = material.babylonMaterial as PBRMaterial;
+            const babylonMaterial = material.babylonMaterial as PBRMaterial;
 
             babylonMaterial.albedoColor = properties.diffuseFactor ? Color3.FromArray(properties.diffuseFactor) : new Color3(1, 1, 1);
             babylonMaterial.reflectivityColor = properties.specularFactor ? Color3.FromArray(properties.specularFactor) : new Color3(1, 1, 1);
             babylonMaterial.microSurface = properties.glossinessFactor == null ? 1 : properties.glossinessFactor;
 
             if (properties.diffuseTexture) {
-                var texture = GLTFUtils.GetArrayItem(loader._gltf.textures, properties.diffuseTexture.index);
+                const texture = GLTFUtils.GetArrayItem(loader._gltf.textures, properties.diffuseTexture.index);
                 if (!texture) {
                     throw new Error(context + ": Failed to find diffuse texture " + properties.diffuseTexture.index);
                 }
@@ -40,7 +40,7 @@ module BABYLON.GLTF2.Extensions {
             }
 
             if (properties.specularGlossinessTexture) {
-                var texture = GLTFUtils.GetArrayItem(loader._gltf.textures, properties.specularGlossinessTexture.index);
+                const texture = GLTFUtils.GetArrayItem(loader._gltf.textures, properties.specularGlossinessTexture.index);
                 if (!texture) {
                     throw new Error(context + ": Failed to find diffuse texture " + properties.specularGlossinessTexture.index);
                 }

+ 11 - 7
loaders/src/glTF/2.0/Extensions/MSFT_lod.ts

@@ -18,8 +18,8 @@ module BABYLON.GLTF2.Extensions {
 
         protected _traverseNode(loader: GLTFLoader, context: string, node: IGLTFNode, action: (node: IGLTFNode, parentNode: IGLTFNode) => boolean, parentNode: IGLTFNode): boolean {
             return this._loadExtension<IMSFTLOD>(node, (extension, onComplete) => {
-                for (var i = extension.ids.length - 1; i >= 0; i--) {
-                    var lodNode = GLTFUtils.GetArrayItem(loader._gltf.nodes, extension.ids[i]);
+                for (let i = extension.ids.length - 1; i >= 0; i--) {
+                    const lodNode = GLTFUtils.GetArrayItem(loader._gltf.nodes, extension.ids[i]);
                     if (!lodNode) {
                         throw new Error(context + ": Failed to find node " + extension.ids[i]);
                     }
@@ -34,7 +34,7 @@ module BABYLON.GLTF2.Extensions {
 
         protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean {
             return this._loadExtension<IMSFTLOD>(node, (extension, onComplete) => {
-                var nodes = [node.index, ...extension.ids].map(index => loader._gltf.nodes[index]);
+                const nodes = [node.index, ...extension.ids].map(index => loader._gltf.nodes[index]);
 
                 loader._addLoaderPendingData(node);
                 this._loadNodeLOD(loader, context, nodes, nodes.length - 1, () => {
@@ -49,7 +49,7 @@ module BABYLON.GLTF2.Extensions {
                 loader._loadNode(context, nodes[index]);
             }, () => {
                 if (index !== nodes.length - 1) {
-                    var previousNode = nodes[index + 1];
+                    const previousNode = nodes[index + 1];
                     previousNode.babylonMesh.setEnabled(false);
                 }
 
@@ -59,14 +59,16 @@ module BABYLON.GLTF2.Extensions {
                 }
 
                 setTimeout(() => {
-                    this._loadNodeLOD(loader, context, nodes, index - 1, onComplete);
+                    loader._tryCatchOnError(() => {
+                        this._loadNodeLOD(loader, context, nodes, index - 1, onComplete);
+                    });
                 }, MSFTLOD.MinimalLODDelay);
             });
         }
 
         protected _loadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean {
             return this._loadExtension<IMSFTLOD>(material, (extension, onComplete) => {
-                var materials = [material.index, ...extension.ids].map(index => loader._gltf.materials[index]);
+                const materials = [material.index, ...extension.ids].map(index => loader._gltf.materials[index]);
 
                 loader._addLoaderPendingData(material);
                 this._loadMaterialLOD(loader, context, materials, materials.length - 1, assign, () => {
@@ -91,7 +93,9 @@ module BABYLON.GLTF2.Extensions {
                 loader._executeWhenRenderReady(() => {
                     BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), () => {
                         setTimeout(() => {
-                            this._loadMaterialLOD(loader, context, materials, index - 1, assign, onComplete);
+                            loader._tryCatchOnError(() => {
+                                this._loadMaterialLOD(loader, context, materials, index - 1, assign, onComplete);
+                            });
                         }, MSFTLOD.MinimalLODDelay);
                     });
                 });

文件差异内容过多而无法显示
+ 284 - 269
loaders/src/glTF/2.0/babylon.glTFLoader.ts


+ 3 - 4
loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts

@@ -17,7 +17,7 @@ module BABYLON.GLTF2 {
                 return false;
             }
 
-            var extension = property.extensions[this.name] as T;
+            const extension = property.extensions[this.name] as T;
             if (!extension) {
                 return false;
             }
@@ -52,13 +52,12 @@ module BABYLON.GLTF2 {
         }
 
         private static _ApplyExtensions(action: (extension: GLTFLoaderExtension) => boolean) {
-            var extensions = GLTFLoaderExtension._Extensions;
+            const extensions = GLTFLoaderExtension._Extensions;
             if (!extensions) {
                 return false;
             }
 
-            for (var i = 0; i < extensions.length; i++) {
-                var extension = extensions[i];
+            for (const extension of extensions) {
                 if (extension.enabled && action(extension)) {
                     return true;
                 }

+ 5 - 5
loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts

@@ -18,11 +18,11 @@ module BABYLON.GLTF2 {
         * @param uri: the uri to decode
         */
         public static DecodeBase64(uri: string): ArrayBuffer {
-            var decodedString = atob(uri.split(",")[1]);
-            var bufferLength = decodedString.length;
-            var bufferView = new Uint8Array(new ArrayBuffer(bufferLength));
+            const decodedString = atob(uri.split(",")[1]);
+            const bufferLength = decodedString.length;
+            const bufferView = new Uint8Array(new ArrayBuffer(bufferLength));
 
-            for (var i = 0; i < bufferLength; i++) {
+            for (let i = 0; i < bufferLength; i++) {
                 bufferView[i] = decodedString.charCodeAt(i);
             }
 
@@ -35,7 +35,7 @@ module BABYLON.GLTF2 {
 
         public static AssignIndices(array: Array<{index?: number}>): void {
             if (array) {
-                for (var index = 0; index < array.length; index++) {
+                for (let index = 0; index < array.length; index++) {
                     array[index].index = index;
                 }
             }

+ 47 - 45
loaders/src/glTF/babylon.glTFFileLoader.ts

@@ -18,12 +18,12 @@ module BABYLON {
         bin: ArrayBufferView;
     }
 
-    export interface IGLTFLoader {
+    export interface IGLTFLoader extends IDisposable {
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
     }
 
-    export class GLTFFileLoader implements ISceneLoaderPluginAsync {
+    export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync {
         public static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         public static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
 
@@ -45,19 +45,14 @@ module BABYLON {
         public onBeforeMaterialReadyAsync: (material: Material, targetMesh: AbstractMesh, isLOD: boolean, callback: () => void) => void;
 
         /**
-         * Raised when the visible components (geometry, materials, textures, etc.) are first ready to be rendered.
-         * For assets with LODs, raised when the first LOD is complete.
-         * For assets without LODs, raised when the model is complete just before onComplete.
-         */
-        public onReady: () => void;
-
-        /**
          * Raised when the asset is completely loaded, just before the loader is disposed.
          * For assets with LODs, raised when all of the LODs are complete.
-         * For assets without LODs, raised when the model is complete just after onReady.
+         * For assets without LODs, raised when the model is complete just after onSuccess.
          */
         public onComplete: () => void;
 
+        private _loader: IGLTFLoader;
+
         public name = "gltf";
 
         public extensions: ISceneLoaderPluginExtensions = {
@@ -65,8 +60,15 @@ module BABYLON {
             ".glb": { isBinary: true }
         };
 
+        public dispose(): void {
+            if (this._loader) {
+                this._loader.dispose();
+                this._loader = null;
+            }
+        }
+
         public importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void {
-            var loaderData = GLTFFileLoader._parse(data, onError);
+            const loaderData = GLTFFileLoader._parse(data, onError);
             if (!loaderData) {
                 return;
             }
@@ -75,16 +77,16 @@ module BABYLON {
                 this.onParsed(loaderData);
             }
 
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
 
-            loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         }
 
         public loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void): void {
-            var loaderData = GLTFFileLoader._parse(data, onError);
+            const loaderData = GLTFFileLoader._parse(data, onError);
             if (!loaderData) {
                 return;
             }
@@ -93,12 +95,12 @@ module BABYLON {
                 this.onParsed(loaderData);
             }
 
-            var loader = this._getLoader(loaderData, onError);
-            if (!loader) {
+            this._loader = this._getLoader(loaderData, onError);
+            if (!this._loader) {
                 return;
             }
 
-            return loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
+            return this._loader.loadAsync(scene, loaderData, rootUrl, onSuccess, onProgress, onError);
         }
 
         public canDirectLoad(data: string): boolean {
@@ -125,16 +127,16 @@ module BABYLON {
         private _getLoader(loaderData: IGLTFLoaderData, onError: (message: string) => void): IGLTFLoader {
             const loaderVersion = { major: 2, minor: 0 };
 
-            var asset = (<any>loaderData.json).asset || {};
+            const asset = (<any>loaderData.json).asset || {};
 
-            var version = GLTFFileLoader._parseVersion(asset.version);
+            const version = GLTFFileLoader._parseVersion(asset.version);
             if (!version) {
                 onError("Invalid version: " + asset.version);
                 return null;
             }
 
             if (asset.minVersion !== undefined) {
-                var minVersion = GLTFFileLoader._parseVersion(asset.minVersion);
+                const minVersion = GLTFFileLoader._parseVersion(asset.minVersion);
                 if (!minVersion) {
                     onError("Invalid minimum version: " + asset.minVersion);
                     return null;
@@ -146,12 +148,12 @@ module BABYLON {
                 }
             }
 
-            var createLoaders: { [key: number]: (parent: GLTFFileLoader) => IGLTFLoader } = {
+            const createLoaders: { [key: number]: (parent: GLTFFileLoader) => IGLTFLoader } = {
                 1: GLTFFileLoader.CreateGLTFLoaderV1,
                 2: GLTFFileLoader.CreateGLTFLoaderV2
             };
 
-            var createLoader = createLoaders[version.major];
+            const createLoader = createLoaders[version.major];
             if (!createLoader) {
                 onError("Unsupported version: " + asset.version);
                 return null;
@@ -165,15 +167,15 @@ module BABYLON {
                 Magic: 0x46546C67
             };
 
-            var binaryReader = new BinaryReader(data);
+            const binaryReader = new BinaryReader(data);
 
-            var magic = binaryReader.readUint32();
+            const magic = binaryReader.readUint32();
             if (magic !== Binary.Magic) {
                 onError("Unexpected magic: " + magic);
                 return null;
             }
 
-            var version = binaryReader.readUint32();
+            const version = binaryReader.readUint32();
             switch (version) {
                 case 1: return GLTFFileLoader._parseV1(binaryReader, onError);
                 case 2: return GLTFFileLoader._parseV2(binaryReader, onError);
@@ -188,16 +190,16 @@ module BABYLON {
                 JSON: 0
             };
 
-            var length = binaryReader.readUint32();
+            const length = binaryReader.readUint32();
             if (length != binaryReader.getLength()) {
                 onError("Length in header does not match actual data length: " + length + " != " + binaryReader.getLength());
                 return null;
             }
 
-            var contentLength = binaryReader.readUint32();
-            var contentFormat = binaryReader.readUint32();
+            const contentLength = binaryReader.readUint32();
+            const contentFormat = binaryReader.readUint32();
 
-            var content: Object;
+            let content: Object;
             switch (contentFormat) {
                 case ContentFormat.JSON:
                     content = JSON.parse(GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(contentLength)));
@@ -207,8 +209,8 @@ module BABYLON {
                     return null;
             }
 
-            var bytesRemaining = binaryReader.getLength() - binaryReader.getPosition();
-            var body = binaryReader.readUint8Array(bytesRemaining);
+            const bytesRemaining = binaryReader.getLength() - binaryReader.getPosition();
+            const body = binaryReader.readUint8Array(bytesRemaining);
 
             return {
                 json: content,
@@ -222,26 +224,26 @@ module BABYLON {
                 BIN: 0x004E4942
             };
 
-            var length = binaryReader.readUint32();
+            const length = binaryReader.readUint32();
             if (length !== binaryReader.getLength()) {
                 onError("Length in header does not match actual data length: " + length + " != " + binaryReader.getLength());
                 return null;
             }
 
             // JSON chunk
-            var chunkLength = binaryReader.readUint32();
-            var chunkFormat = binaryReader.readUint32();
+            const chunkLength = binaryReader.readUint32();
+            const chunkFormat = binaryReader.readUint32();
             if (chunkFormat !== ChunkFormat.JSON) {
                 onError("First chunk format is not JSON");
                 return null;
             }
-            var json = JSON.parse(GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(chunkLength)));
+            const json = JSON.parse(GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(chunkLength)));
 
             // Look for BIN chunk
-            var bin: Uint8Array = null;
+            let bin: Uint8Array = null;
             while (binaryReader.getPosition() < binaryReader.getLength()) {
-                chunkLength = binaryReader.readUint32();
-                chunkFormat = binaryReader.readUint32();
+                const chunkLength = binaryReader.readUint32();
+                const chunkFormat = binaryReader.readUint32();
                 switch (chunkFormat) {
                     case ChunkFormat.JSON:
                         onError("Unexpected JSON chunk");
@@ -263,7 +265,7 @@ module BABYLON {
         }
 
         private static _parseVersion(version: string): { major: number, minor: number } {
-            var match = (version + "").match(/^(\d+)\.(\d+)$/);
+            const match = (version + "").match(/^(\d+)\.(\d+)$/);
             if (!match) {
                 return null;
             }
@@ -283,10 +285,10 @@ module BABYLON {
         }
 
         private static _decodeBufferToText(buffer: Uint8Array): string {
-            var result = "";
-            var length = buffer.byteLength;
+            let result = "";
+            const length = buffer.byteLength;
 
-            for (var i = 0; i < length; ++i) {
+            for (let i = 0; i < length; i++) {
                 result += String.fromCharCode(buffer[i]);
             }
 
@@ -314,13 +316,13 @@ module BABYLON {
         }
 
         public readUint32(): number {
-            var value = this._dataView.getUint32(this._byteOffset, true);
+            const value = this._dataView.getUint32(this._byteOffset, true);
             this._byteOffset += 4;
             return value;
         }
 
         public readUint8Array(length: number): Uint8Array {
-            var value = new Uint8Array(this._arrayBuffer, this._byteOffset, length);
+            const value = new Uint8Array(this._arrayBuffer, this._byteOffset, length);
             this._byteOffset += length;
             return value;
         }

+ 1 - 1
src/Actions/babylon.actionManager.ts

@@ -434,7 +434,7 @@
             return root;
         }
 
-        public static Parse(parsedActions: any, object: AbstractMesh, scene: Scene) {
+        public static Parse(parsedActions: any, object: Nullable<AbstractMesh>, scene: Scene) {
             var actionManager = new BABYLON.ActionManager(scene);
             if (object === null)
                 scene.actionManager = actionManager;

+ 9 - 7
src/Audio/babylon.analyser.ts

@@ -10,16 +10,16 @@ module BABYLON {
         private _byteTime: Uint8Array;
         private _floatFreqs: Float32Array;
         private _webAudioAnalyser: AnalyserNode;
-        private _debugCanvas: HTMLCanvasElement;
-        private _debugCanvasContext: CanvasRenderingContext2D;
+        private _debugCanvas: Nullable< HTMLCanvasElement>;
+        private _debugCanvasContext: Nullable<CanvasRenderingContext2D>;
         private _scene: Scene;
-        private _registerFunc: () => void
+        private _registerFunc: Nullable<() => void>;
         private _audioEngine: AudioEngine;
 
         constructor(scene: Scene) {
             this._scene = scene;
             this._audioEngine = Engine.audioEngine;
-            if (this._audioEngine.canUseWebAudio) {
+            if (this._audioEngine.canUseWebAudio && this._audioEngine.audioContext) {
                 this._webAudioAnalyser = this._audioEngine.audioContext.createAnalyser();
                 this._webAudioAnalyser.minDecibels = -140;
                 this._webAudioAnalyser.maxDecibels = 0;
@@ -81,7 +81,7 @@ module BABYLON {
                     };
                     this._scene.registerBeforeRender(this._registerFunc);
                 }
-                if (this._registerFunc) {
+                if (this._registerFunc && this._debugCanvasContext) {
                     var workingArray = this.getByteFrequencyData();
 
                     this._debugCanvasContext.fillStyle = 'rgb(0, 0, 0)';
@@ -104,8 +104,10 @@ module BABYLON {
 
         public stopDebugCanvas() {
             if (this._debugCanvas) {
-                this._scene.unregisterBeforeRender(this._registerFunc);
-                this._registerFunc = null;
+                if (this._registerFunc) {
+                    this._scene.unregisterBeforeRender(this._registerFunc);
+                    this._registerFunc = null;
+                }
                 document.body.removeChild(this._debugCanvas);
                 this._debugCanvas = null;
                 this._debugCanvasContext = null;

+ 8 - 5
src/Audio/babylon.audioEngine.ts

@@ -1,11 +1,11 @@
 module BABYLON {
     export class AudioEngine {
-        private _audioContext: AudioContext = null;
+        private _audioContext: Nullable<AudioContext> = null;
         private _audioContextInitialized = false;
         public canUseWebAudio: boolean = false;
         public masterGain: GainNode;
 
-        private _connectedAnalyser: Analyser;
+        private _connectedAnalyser: Nullable<Analyser>;
         public WarnedWebAudioUnsupported: boolean = false;
         public unlocked: boolean = false;
         public onAudioUnlocked: () => any;
@@ -13,7 +13,7 @@
         public isMP3supported: boolean = false;
         public isOGGsupported: boolean = false;
 
-        public get audioContext(): AudioContext {
+        public get audioContext(): Nullable<AudioContext> {
             if (!this._audioContextInitialized) {
                 this._initializeAudioContext();
             }
@@ -56,6 +56,9 @@
 
         private _unlockiOSaudio() {
             var unlockaudio = () => {
+                if (!this.audioContext) {
+                    return;
+                }
                 var buffer = this.audioContext.createBuffer(1, 1, 22050);
                 var source = this.audioContext.createBufferSource();
                 source.buffer = buffer;
@@ -95,7 +98,7 @@
 
         public dispose() {
             if (this.canUseWebAudio && this._audioContextInitialized) {
-                if (this._connectedAnalyser) {
+                if (this._connectedAnalyser && this._audioContext) {
                     this._connectedAnalyser.stopDebugCanvas();
                     this._connectedAnalyser.dispose();
                     this.masterGain.disconnect();
@@ -126,7 +129,7 @@
             if (this._connectedAnalyser) {
                 this._connectedAnalyser.stopDebugCanvas();
             }
-            if (this.canUseWebAudio && this._audioContextInitialized) {
+            if (this.canUseWebAudio && this._audioContextInitialized && this._audioContext) {
                 this._connectedAnalyser = analyser;
                 this.masterGain.disconnect();
                 this._connectedAnalyser.connectAudioNodes(this.masterGain, this._audioContext.destination);

+ 46 - 31
src/Audio/babylon.sound.ts

@@ -24,12 +24,12 @@ module BABYLON {
         public isPlaying: boolean = false;
         public isPaused: boolean = false;
         private _isDirectional: boolean = false;
-        private _readyToPlayCallback: () => any;
-        private _audioBuffer: AudioBuffer;
-        private _soundSource: AudioBufferSourceNode;
+        private _readyToPlayCallback: Nullable<() => any>;
+        private _audioBuffer: Nullable<AudioBuffer>;
+        private _soundSource: Nullable<AudioBufferSourceNode>;
         private _streamingSource: MediaElementAudioSourceNode
-        private _soundPanner: PannerNode;
-        private _soundGain: GainNode;
+        private _soundPanner: Nullable<PannerNode>;
+        private _soundGain: Nullable<GainNode>;
         private _inputAudioNode: AudioNode;
         private _ouputAudioNode: AudioNode;
         // Used if you'd like to create a directional sound.
@@ -38,9 +38,9 @@ module BABYLON {
         private _coneOuterAngle: number = 360;
         private _coneOuterGain: number = 0;
         private _scene: Scene;
-        private _connectedMesh: AbstractMesh;
+        private _connectedMesh: Nullable<AbstractMesh>;
         private _customAttenuationFunction: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number;
-        private _registerFunc: (connectedMesh: AbstractMesh) => any;
+        private _registerFunc: Nullable<(connectedMesh: AbstractMesh) => any>;
         private _isOutputConnected = false;
         private _htmlAudioElement: HTMLAudioElement;
         private _urlType: string = "Unknown";
@@ -52,7 +52,7 @@ module BABYLON {
         * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played
         * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming
         */
-        constructor(name: string, urlOrArrayBuffer: any, scene: Scene, readyToPlayCallback?: () => void, options?: any) {
+        constructor(name: string, urlOrArrayBuffer: any, scene: Scene, readyToPlayCallback: Nullable<() => void> = null, options?: any) {
             this.name = name;
             this._scene = scene;
             this._readyToPlayCallback = readyToPlayCallback;
@@ -82,7 +82,7 @@ module BABYLON {
                 this._streaming = options.streaming || false;
             }
 
-            if (Engine.audioEngine.canUseWebAudio) {
+            if (Engine.audioEngine.canUseWebAudio && Engine.audioEngine.audioContext) {
                 this._soundGain = Engine.audioEngine.audioContext.createGain();
                 this._soundGain.gain.value = this._volume;
                 this._inputAudioNode = this._soundGain;
@@ -130,7 +130,7 @@ module BABYLON {
                                 if (codecSupportedFound) {
                                     // Loading sound using XHR2
                                     if (!this._streaming) {
-                                        Tools.LoadFile(url, (data) => { this._soundLoaded(data); }, null, this._scene.database, true);
+                                        Tools.LoadFile(url, (data) => { this._soundLoaded(data); }, undefined, this._scene.database, true);
                                     }
                                     // Streaming sound using HTML5 Audio tag
                                     else {
@@ -168,7 +168,9 @@ module BABYLON {
                             // Simulating a ready to play event to avoid breaking code path
                             if (this._readyToPlayCallback) {
                                 window.setTimeout(() => {
-                                    this._readyToPlayCallback();
+                                    if (this._readyToPlayCallback) {
+                                        this._readyToPlayCallback();
+                                    }
                                 }, 1000);
                             }
                         }
@@ -185,7 +187,9 @@ module BABYLON {
                 // Simulating a ready to play event to avoid breaking code for non web audio browsers
                 if (this._readyToPlayCallback) {
                     window.setTimeout(() => {
-                        this._readyToPlayCallback();
+                        if (this._readyToPlayCallback) {
+                            this._readyToPlayCallback();
+                        }
                     }, 1000);
                 }
             }
@@ -223,7 +227,7 @@ module BABYLON {
                     document.body.removeChild(this._htmlAudioElement);
                 }
 
-                if (this._connectedMesh) {
+                if (this._connectedMesh && this._registerFunc) {
                     this._connectedMesh.unregisterAfterWorldMatrixUpdate(this._registerFunc);
                     this._connectedMesh = null;
                 }
@@ -236,6 +240,9 @@ module BABYLON {
 
         private _soundLoaded(audioData: ArrayBuffer) {
             this._isLoaded = true;
+            if (!Engine.audioEngine.audioContext) {
+                return;
+            }
             Engine.audioEngine.audioContext.decodeAudioData(audioData, (buffer) => {
                 this._audioBuffer = buffer;
                 this._isReadyToPlay = true;
@@ -266,14 +273,16 @@ module BABYLON {
                         this._htmlAudioElement.playbackRate = this._playbackRate;
                     }
                     else {
-                        this._soundSource.playbackRate.value = this._playbackRate;
+                        if (this._soundSource) {
+                            this._soundSource.playbackRate.value = this._playbackRate;
+                        }
                     }
                 }
             }
         }
 
         private _createSpatialParameters() {
-            if (Engine.audioEngine.canUseWebAudio) {
+            if (Engine.audioEngine.canUseWebAudio && Engine.audioEngine.audioContext) {
                 if (this._scene.headphone) {
                     this._panningModel = "HRTF";
                 }
@@ -285,7 +294,7 @@ module BABYLON {
         }
 
         private _updateSpatialParameters() {
-            if (this.spatialSound) {
+            if (this.spatialSound && this._soundPanner) {
                 if (this.useCustomAttenuation) {
                     // Tricks to disable in a way embedded Web Audio attenuation 
                     this._soundPanner.distanceModel = "linear";
@@ -315,7 +324,7 @@ module BABYLON {
         }
 
         private _switchPanningModel() {
-            if (Engine.audioEngine.canUseWebAudio && this.spatialSound) {
+            if (Engine.audioEngine.canUseWebAudio && this.spatialSound && this._soundPanner) {
                 this._soundPanner.panningModel = this._panningModel as any;
             }
         }
@@ -355,7 +364,7 @@ module BABYLON {
         public setPosition(newPosition: Vector3) {
             this._position = newPosition;
 
-            if (Engine.audioEngine.canUseWebAudio && this.spatialSound) {
+            if (Engine.audioEngine.canUseWebAudio && this.spatialSound && this._soundPanner) {
                 this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
             }
         }
@@ -369,6 +378,10 @@ module BABYLON {
         }
 
         private _updateDirection() {
+            if (!this._connectedMesh || !this._soundPanner) {
+                return;
+            }
+
             var mat = this._connectedMesh.getWorldMatrix();
             var direction = Vector3.TransformNormal(this._localDirection, mat);
             direction.normalize();
@@ -376,7 +389,7 @@ module BABYLON {
         }
 
         public updateDistanceFromListener() {
-            if (Engine.audioEngine.canUseWebAudio && this._connectedMesh && this.useCustomAttenuation) {
+            if (Engine.audioEngine.canUseWebAudio && this._connectedMesh && this.useCustomAttenuation && this._soundGain && this._scene.activeCamera) {
                 var distance = this._connectedMesh.getDistanceToCamera(this._scene.activeCamera);
                 this._soundGain.gain.value = this._customAttenuationFunction(this._volume, distance, this.maxDistance, this.refDistance, this.rolloffFactor);
             }
@@ -392,7 +405,7 @@ module BABYLON {
         * @param offset (optional) Start the sound setting it at a specific time
         */
         public play(time?: number, offset?: number) {
-            if (this._isReadyToPlay && this._scene.audioEnabled) {
+            if (this._isReadyToPlay && this._scene.audioEnabled && Engine.audioEngine.audioContext) {
                 try {
                     if (this._startOffset < 0) {
                         time = -this._startOffset;
@@ -400,7 +413,7 @@ module BABYLON {
                     }
                     var startTime = time ? Engine.audioEngine.audioContext.currentTime + time : Engine.audioEngine.audioContext.currentTime;
                     if (!this._soundSource || !this._streamingSource) {
-                        if (this.spatialSound) {
+                        if (this.spatialSound && this._soundPanner) {
                             this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
                             if (this._isDirectional) {
                                 this._soundPanner.coneInnerAngle = this._coneInnerAngle;
@@ -432,7 +445,9 @@ module BABYLON {
                         this._soundSource.loop = this.loop;
                         this._soundSource.playbackRate.value = this._playbackRate;
                         this._soundSource.onended = () => { this._onended(); };
-                        this._soundSource.start(startTime, this.isPaused ? this._startOffset % this._soundSource.buffer.duration : offset ? offset : 0);
+                        if (this._soundSource.buffer) {
+                            this._soundSource.start(startTime, this.isPaused ? this._startOffset % this._soundSource.buffer.duration : offset ? offset : 0);
+                        }
                     }
                     this._startTime = startTime;
                     this.isPlaying = true;
@@ -464,10 +479,10 @@ module BABYLON {
                         this._htmlAudioElement.currentTime = 0;
                     }
                 }
-                else {
+                else if (Engine.audioEngine.audioContext && this._soundSource) {
                     var stopTime = time ? Engine.audioEngine.audioContext.currentTime + time : Engine.audioEngine.audioContext.currentTime;
                     this._soundSource.stop(stopTime);
-                    this._soundSource.onended = null;
+                    this._soundSource.onended = () => {};
                     if (!this.isPaused) {
                         this._startOffset = 0;
                     }
@@ -482,7 +497,7 @@ module BABYLON {
                 if (this._streaming) {
                     this._htmlAudioElement.pause();
                 }
-                else {
+                else if (Engine.audioEngine.audioContext) {
                     this.stop(0);
                     this._startOffset += Engine.audioEngine.audioContext.currentTime - this._startTime;
                 }
@@ -490,8 +505,8 @@ module BABYLON {
         }
 
         public setVolume(newVolume: number, time?: number) {
-            if (Engine.audioEngine.canUseWebAudio) {
-                if (time) {
+            if (Engine.audioEngine.canUseWebAudio && this._soundGain) {
+                if (time && Engine.audioEngine.audioContext) {
                     this._soundGain.gain.cancelScheduledValues(Engine.audioEngine.audioContext.currentTime);
                     this._soundGain.gain.setValueAtTime(this._soundGain.gain.value, Engine.audioEngine.audioContext.currentTime);
                     this._soundGain.gain.linearRampToValueAtTime(newVolume, Engine.audioEngine.audioContext.currentTime + time);
@@ -509,7 +524,7 @@ module BABYLON {
                 if (this._streaming) {
                     this._htmlAudioElement.playbackRate = this._playbackRate;
                 }
-                else {
+                else if (this._soundSource) {
                     this._soundSource.playbackRate.value = this._playbackRate;
                 }
             }
@@ -520,7 +535,7 @@ module BABYLON {
         }
 
         public attachToMesh(meshToConnectTo: AbstractMesh) {
-            if (this._connectedMesh) {
+            if (this._connectedMesh && this._registerFunc) {
                 this._connectedMesh.unregisterAfterWorldMatrixUpdate(this._registerFunc);
                 this._registerFunc = null;
             }
@@ -539,7 +554,7 @@ module BABYLON {
         }
 
         public detachFromMesh() {
-            if (this._connectedMesh) {
+            if (this._connectedMesh && this._registerFunc) {
                 this._connectedMesh.unregisterAfterWorldMatrixUpdate(this._registerFunc);
                 this._registerFunc = null;
                 this._connectedMesh = null;
@@ -553,7 +568,7 @@ module BABYLON {
             }
         }
 
-        public clone(): Sound {
+        public clone(): Nullable<Sound> {
             if (!this._streaming) {
                 var setBufferAndRun = () => {
                     if (this._isReadyToPlay) {

+ 5 - 5
src/Audio/babylon.soundtrack.ts

@@ -1,6 +1,6 @@
 module BABYLON {
     export class SoundTrack {
-        private _outputAudioNode: GainNode;
+        private _outputAudioNode: Nullable<GainNode>;
         private _scene: Scene;
         public id: number = -1;
         public soundCollection: Array<Sound>;
@@ -21,7 +21,7 @@
         }
 
         private _initializeSoundTrackAudioGraph() {
-            if (Engine.audioEngine.canUseWebAudio) {
+            if (Engine.audioEngine.canUseWebAudio && Engine.audioEngine.audioContext) {
                 this._outputAudioNode = Engine.audioEngine.audioContext.createGain();
                 this._outputAudioNode.connect(Engine.audioEngine.masterGain);
 
@@ -53,7 +53,7 @@
             if (!this._isInitialized) {
                 this._initializeSoundTrackAudioGraph();
             }
-            if (Engine.audioEngine.canUseWebAudio) {
+            if (Engine.audioEngine.canUseWebAudio && this._outputAudioNode) {
                 sound.connectToSoundTrackAudioNode(this._outputAudioNode);
             }
             if (sound.soundTrackId) {
@@ -77,7 +77,7 @@
         }
 
         public setVolume(newVolume: number) {
-            if (Engine.audioEngine.canUseWebAudio) {
+            if (Engine.audioEngine.canUseWebAudio && this._outputAudioNode) {
                 this._outputAudioNode.gain.value = newVolume;
             }
         }
@@ -103,7 +103,7 @@
                 this._connectedAnalyser.stopDebugCanvas();
             }
             this._connectedAnalyser = analyser;
-            if (Engine.audioEngine.canUseWebAudio) {
+            if (Engine.audioEngine.canUseWebAudio && this._outputAudioNode) {
                 this._outputAudioNode.disconnect();
                 this._connectedAnalyser.connectAudioNodes(this._outputAudioNode, Engine.audioEngine.masterGain);
             }

+ 27 - 8
src/Behaviors/Cameras/babylon.autoRotationBehavior.ts

@@ -73,11 +73,11 @@ module BABYLON {
 		}
         
         // Default behavior functions
-        private _onPrePointerObservableObserver: Observer<PointerInfoPre>;
-        private _onAfterCheckInputsObserver: Observer<Camera>;
-        private _attachedCamera: ArcRotateCamera;
+        private _onPrePointerObservableObserver: Nullable<Observer<PointerInfoPre>>;
+        private _onAfterCheckInputsObserver: Nullable<Observer<Camera>>;
+        private _attachedCamera: Nullable<ArcRotateCamera>;
         private _isPointerDown = false;
-        private _lastFrameTime: number = null;
+        private _lastFrameTime: Nullable<number> = null;
 		private _lastInteractionTime = -Infinity;
 		private _cameraRotationSpeed: number = 0;
 
@@ -111,15 +111,23 @@ module BABYLON {
 				let scale = Math.max(Math.min(timeToRotation / (this._idleRotationSpinupTime), 1), 0);
                 this._cameraRotationSpeed = this._idleRotationSpeed * scale;
     
-                // Step camera rotation by rotation speed
-                this._attachedCamera.alpha -= this._cameraRotationSpeed * (dt / 1000);
+				// Step camera rotation by rotation speed
+				if (this._attachedCamera) {
+					this._attachedCamera.alpha -= this._cameraRotationSpeed * (dt / 1000);
+				}
             });
         }
              
         public detach(): void {
+			if (!this._attachedCamera) {
+				return;
+			}
             let scene = this._attachedCamera.getScene();
-            
-            scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
+			
+			if (this._onPrePointerObservableObserver) {
+				scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
+			}
+			
 			this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
 			this._attachedCamera = null;
 		}
@@ -129,11 +137,18 @@ module BABYLON {
 		 * @return true if user is scrolling.
 		 */
 		private _userIsZooming(): boolean {
+			if (!this._attachedCamera) {
+				return false;
+			}			
 			return this._attachedCamera.inertialRadiusOffset !== 0;
 		}   		
 		
 		private _lastFrameRadius = 0;
 		private _shouldAnimationStopForInteraction(): boolean {
+			if (!this._attachedCamera) {
+				return false;
+			}	
+
 			var zoomHasHitLimit = false;
 			if (this._lastFrameRadius === this._attachedCamera.radius && this._attachedCamera.inertialRadiusOffset !== 0) {
 				zoomHasHitLimit = true;
@@ -155,6 +170,10 @@ module BABYLON {
    
         // Tools
         private _userIsMoving(): boolean {
+			if (!this._attachedCamera) {
+				return false;
+			}	
+			
 			return this._attachedCamera.inertialAlphaOffset !== 0 ||
 				this._attachedCamera.inertialBetaOffset !== 0 ||
 				this._attachedCamera.inertialRadiusOffset !== 0 ||

+ 39 - 10
src/Behaviors/Cameras/babylon.bouncingBehavior.ts

@@ -53,6 +53,9 @@ module BABYLON {
 			this._autoTransitionRange = value;
 
 			let camera = this._attachedCamera;
+			if (!camera) {
+				return;
+			}
 
 			if (value) {
 				this._onMeshTargetChangedObserver = camera.onMeshTargetChangedObservable.add((mesh) => {
@@ -72,12 +75,16 @@ module BABYLON {
 		}
         
         // Connection
-        private _attachedCamera: ArcRotateCamera;
-		private _onAfterCheckInputsObserver: Observer<Camera>;	
-		private _onMeshTargetChangedObserver: Observer<AbstractMesh>;
+        private _attachedCamera: Nullable<ArcRotateCamera>;
+		private _onAfterCheckInputsObserver: Nullable<Observer<Camera>>;	
+		private _onMeshTargetChangedObserver: Nullable<Observer<AbstractMesh>>;
         public attach(camera: ArcRotateCamera): void {
             this._attachedCamera = camera;
             this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(() => {
+				if (!this._attachedCamera) {
+					return;
+				}
+
 				// Add the bounce animation to the lower radius limit
 				if (this._isRadiusAtLimit(this._attachedCamera.lowerRadiusLimit)) {
 					this._applyBoundRadiusAnimation(this.lowerRadiusTransitionRange);
@@ -91,7 +98,12 @@ module BABYLON {
         }
         
         public detach(): void {
-			this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
+			if (!this._attachedCamera) {
+				return;
+			}			
+			if (this._onAfterCheckInputsObserver) {
+				this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
+			}
 			if (this._onMeshTargetChangedObserver) {
 				this._attachedCamera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
 			}
@@ -100,7 +112,7 @@ module BABYLON {
 
         // Animations
         private _radiusIsAnimating: boolean = false;
-        private _radiusBounceTransition: Animation = null;
+        private _radiusBounceTransition: Nullable<Animation> = null;
         private _animatables = new Array<BABYLON.Animatable>();
         private _cachedWheelPrecision: number;
 
@@ -109,7 +121,11 @@ module BABYLON {
 		 * @param radiusLimit The limit to check against.
 		 * @return Bool to indicate if at limit.
 		 */
-		private _isRadiusAtLimit(radiusLimit: number): boolean {
+		private _isRadiusAtLimit(radiusLimit: Nullable<number>): boolean {
+			if (!this._attachedCamera) {
+				return false;
+			}
+
 			if (this._attachedCamera.radius === radiusLimit && !this._radiusIsAnimating) {
 				return true;
 			}
@@ -121,6 +137,10 @@ module BABYLON {
 		 * @param radiusDelta The delta by which to animate to. Can be negative.
 		 */
 		private _applyBoundRadiusAnimation(radiusDelta: number): void {
+			if (!this._attachedCamera) {
+				return;
+			}
+
 			if (!this._radiusBounceTransition) {
 				BouncingBehavior.EasingFunction.setEasingMode(BouncingBehavior.EasingMode);
 				this._radiusBounceTransition = Animation.CreateAnimation("radius", Animation.ANIMATIONTYPE_FLOAT, 60, BouncingBehavior.EasingFunction);
@@ -133,8 +153,12 @@ module BABYLON {
 			// Animate to the radius limit
 			this.stopAllAnimations();
 			this._radiusIsAnimating = true;
-            this._animatables.push(Animation.TransitionTo("radius", this._attachedCamera.radius + radiusDelta, this._attachedCamera, this._attachedCamera.getScene(), 60, 
-                                    this._radiusBounceTransition, this.transitionDuration, () => this._clearAnimationLocks()));
+			let animatable = Animation.TransitionTo("radius", this._attachedCamera.radius + radiusDelta, this._attachedCamera, this._attachedCamera.getScene(), 60, 
+			this._radiusBounceTransition, this.transitionDuration, () => this._clearAnimationLocks());
+
+			if (animatable) {
+				this._animatables.push(animatable);
+			}
         }
 
         /**
@@ -142,14 +166,19 @@ module BABYLON {
 		 */
 		protected _clearAnimationLocks(): void {
 			this._radiusIsAnimating = false;
-			this._attachedCamera.wheelPrecision = this._cachedWheelPrecision;
+
+			if (this._attachedCamera) {
+				this._attachedCamera.wheelPrecision = this._cachedWheelPrecision;
+			}			
 		}        
         
 		/**
 		 * Stops and removes all animations that have been applied to the camera
 		 */        
         public stopAllAnimations(): void {
-			this._attachedCamera.animations = [];
+			if (this._attachedCamera) {
+				this._attachedCamera.animations = [];
+			}
 			while (this._animatables.length) {
 				this._animatables[0].onAnimationEnd = null;
 				this._animatables[0].stop();

+ 72 - 28
src/Behaviors/Cameras/babylon.framingBehavior.ts

@@ -140,10 +140,10 @@ module BABYLON {
 		}        
         
         // Default behavior functions
-        private _onPrePointerObservableObserver: Observer<PointerInfoPre>;
-		private _onAfterCheckInputsObserver: Observer<Camera>;
-		private _onMeshTargetChangedObserver: Observer<AbstractMesh>;
-        private _attachedCamera: ArcRotateCamera;
+        private _onPrePointerObservableObserver: Nullable<Observer<PointerInfoPre>>;
+		private _onAfterCheckInputsObserver: Nullable<Observer<Camera>>;
+		private _onMeshTargetChangedObserver: Nullable<Observer<AbstractMesh>>;
+        private _attachedCamera: Nullable<ArcRotateCamera>;
         private _isPointerDown = false;
         private _lastInteractionTime = -Infinity;
 
@@ -181,11 +181,23 @@ module BABYLON {
         }
              
         public detach(): void {
+			if (!this._attachedCamera) {
+				return;
+			}
+
             let scene = this._attachedCamera.getScene();
-            
-            scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
-			this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
-			this._attachedCamera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
+			
+			if (this._onPrePointerObservableObserver) {
+				scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
+			}
+
+			if (this._onAfterCheckInputsObserver) {
+				this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
+			}
+
+			if (this._onMeshTargetChangedObserver) {
+				this._attachedCamera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
+			}
 
 			this._attachedCamera = null;
         }
@@ -205,7 +217,7 @@ module BABYLON {
 		 * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
 		 * @param onAnimationEnd Callback triggered at the end of the framing animation
 		 */
-		public zoomOnMesh(mesh: AbstractMesh, focusOnOriginXZ: boolean = false, onAnimationEnd: () => void = null): void {
+		public zoomOnMesh(mesh: AbstractMesh, focusOnOriginXZ: boolean = false, onAnimationEnd: Nullable<() => void> = null): void {
 			mesh.computeWorldMatrix(true);
 
 			let boundingBox = mesh.getBoundingInfo().boundingBox;
@@ -220,9 +232,13 @@ module BABYLON {
 		 * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
 		 * @param onAnimationEnd Callback triggered at the end of the framing animation
 		 */
-		public zoomOnBoundingInfo(minimumWorld: Vector3, maximumWorld: Vector3, focusOnOriginXZ: boolean = false, onAnimationEnd: () => void = null): void {
+		public zoomOnBoundingInfo(minimumWorld: Vector3, maximumWorld: Vector3, focusOnOriginXZ: boolean = false, onAnimationEnd: Nullable<() => void> = null): void {
 			let zoomTarget: BABYLON.Vector3;
 
+			if (!this._attachedCamera) {
+				return;
+			}
+
 			// Find target by interpolating from bottom of bounding box in world-space to top via framingPositionY
 			let bottom = minimumWorld.y;
 			let top = maximumWorld.y;
@@ -241,8 +257,10 @@ module BABYLON {
 			}			
 
 			this._betaIsAnimating = true;
-			this._animatables.push(Animation.TransitionTo("target", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 
-									60, this._vectorTransition, this._framingTime));
+			let animatable = Animation.TransitionTo("target", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 60, this._vectorTransition, this._framingTime);
+			if (animatable) {
+				this._animatables.push(animatable);
+			}
 
 			// sets the radius and lower radius bounds
 			// Small delta ensures camera is not always at lower zoom limit.
@@ -268,14 +286,20 @@ module BABYLON {
 				this._radiusTransition = Animation.CreateAnimation("radius", Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
 			}
 
-			this._animatables.push(Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 
-				60, this._radiusTransition, this._framingTime, () => {
-					if (onAnimationEnd) {
-						onAnimationEnd();
-					}
+			animatable = Animation.TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 
+			60, this._radiusTransition, this._framingTime, () => {
+				if (onAnimationEnd) {
+					onAnimationEnd();
+				}
 
+				if (this._attachedCamera) {
 					this._attachedCamera.storeState();
-				}));
+				}
+			});
+
+			if (animatable) {
+				this._animatables.push(animatable);
+			}
 		}
 		
 		/**
@@ -301,6 +325,10 @@ module BABYLON {
 			let distance = Math.max(distanceForHorizontalFrustum, distanceForVerticalFrustum);
 			let camera = this._attachedCamera;
 
+			if (!camera) {
+				return 0;
+			}
+
 			if (camera.lowerRadiusLimit && this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
 				// Don't exceed the requested limit
 				distance = distance < camera.lowerRadiusLimit ? camera.lowerRadiusLimit : distance;
@@ -328,7 +356,7 @@ module BABYLON {
 			let limitBeta = Math.PI * 0.5;
 			
 			// Bring the camera back up if below the ground plane
-			if (!this._betaIsAnimating && this._attachedCamera.beta > limitBeta && timeSinceInteraction >= this._elevationReturnWaitTime) {
+			if (this._attachedCamera && !this._betaIsAnimating && this._attachedCamera.beta > limitBeta && timeSinceInteraction >= this._elevationReturnWaitTime) {
                 this._betaIsAnimating = true;
                 
 				//Transition to new position
@@ -336,14 +364,18 @@ module BABYLON {
                 
                 if (!this._betaTransition) {
                     this._betaTransition = Animation.CreateAnimation("beta", Animation.ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
-                }
-
-				this._animatables.push(Animation.TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60,
-                    this._betaTransition, this._elevationReturnTime, 
-                    () => {
-						this._clearAnimationLocks();
-						this.stopAllAnimations();
-					}));
+				}
+				
+				let animatabe = Animation.TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60,
+				this._betaTransition, this._elevationReturnTime, 
+				() => {
+					this._clearAnimationLocks();
+					this.stopAllAnimations();
+				});
+
+				if (animatabe) {
+					this._animatables.push(animatabe);
+				}
 			}
 		}        
 
@@ -355,6 +387,11 @@ module BABYLON {
 			// Calculate the viewport ratio
 			// Aspect Ratio is Height/Width.
 			let camera = this._attachedCamera;
+
+			if (!camera) {
+				return Vector2.Zero();
+			}
+
 			let engine = camera.getScene().getEngine();
 			var aspectRatio = engine.getAspectRatio(camera);
 
@@ -392,7 +429,10 @@ module BABYLON {
 		 * Stops and removes all animations that have been applied to the camera
 		 */        
         public stopAllAnimations(): void {
-			this._attachedCamera.animations = [];
+			if (this._attachedCamera) {
+				this._attachedCamera.animations = [];
+			}
+
 			while (this._animatables.length) {
 				if (this._animatables[0]) {
 					this._animatables[0].onAnimationEnd = null;
@@ -406,6 +446,10 @@ module BABYLON {
 		 * Gets a value indicating if the user is moving the camera
 		 */
         public get isUserIsMoving(): boolean {
+			if (!this._attachedCamera) {
+				return false;
+			}
+			
 			return this._attachedCamera.inertialAlphaOffset !== 0 ||
 				this._attachedCamera.inertialBetaOffset !== 0 ||
 				this._attachedCamera.inertialRadiusOffset !== 0 ||

+ 53 - 62
src/Bones/babylon.bone.ts

@@ -13,7 +13,7 @@ module BABYLON {
 
         // Set this value to map this bone to a different index in the transform matrices.
         // Set this value to -1 to exclude the bone from the transform matrices.
-        public _index: number;
+        public _index: Nullable<number> = null;
 
         private _skeleton: Skeleton;
         private _localMatrix: Matrix;
@@ -22,7 +22,7 @@ module BABYLON {
         private _worldTransform = new Matrix();
         private _absoluteTransform = new Matrix();
         private _invertedAbsoluteTransform = new Matrix();
-        private _parent: Bone;
+        private _parent: Nullable<Bone>;
 
         private _scaleMatrix = Matrix.Identity();
         private _scaleVector = Vector3.One();
@@ -41,7 +41,8 @@ module BABYLON {
             }
         }
 
-        constructor(public name: string, skeleton: Skeleton, parentBone: Bone = null, localMatrix?: Matrix, restPose?: Matrix, baseMatrix?: Matrix, index?: number) {
+        constructor(public name: string, skeleton: Skeleton, parentBone: Nullable<Bone> = null, localMatrix: Nullable<Matrix> = null, 
+                    restPose: Nullable<Matrix> = null, baseMatrix: Nullable<Matrix> = null, index: Nullable<number> = null) {
             super(name, skeleton.getScene());
             this._skeleton = skeleton;
             this._localMatrix = localMatrix ? localMatrix : Matrix.Identity();
@@ -61,11 +62,11 @@ module BABYLON {
             return this._skeleton;
         }
 
-        public getParent(): Bone {
+        public getParent(): Nullable<Bone> {
             return this._parent;
         }
 
-        public setParent(parent: Bone, updateDifferenceMatrix: boolean = true): void {
+        public setParent(parent: Nullable<Bone>, updateDifferenceMatrix: boolean = true): void {
             if (this._parent === parent) {
                 return;
             }
@@ -186,7 +187,7 @@ module BABYLON {
             this._skeleton._markAsDirty();
         }
 
-        public copyAnimationRange(source: Bone, rangeName: string, frameOffset: number, rescaleAsRequired = false, skelDimensionsRatio : Vector3 = null): boolean {
+        public copyAnimationRange(source: Bone, rangeName: string, frameOffset: number, rescaleAsRequired = false, skelDimensionsRatio: Nullable<Vector3> = null): boolean {
             // all animation may be coming from a library skeleton, so may need to create animation
             if (this.animations.length === 0) {
                 this.animations.push(new Animation(this.name, "_matrix", source.animations[0].framePerSecond, Animation.ANIMATIONTYPE_MATRIX, 0));
@@ -207,7 +208,7 @@ module BABYLON {
             var sourceParent = source.getParent();
             var parent = this.getParent();
             var parentScalingReqd = rescaleAsRequired && sourceParent && sourceBoneLength && this.length && sourceBoneLength !== this.length;
-            var parentRatio = parentScalingReqd ? parent.length / sourceParent.length : null;
+            var parentRatio = parentScalingReqd && parent && sourceParent ? parent.length / sourceParent.length : 1;
             
             var dimensionsScalingReqd = rescaleAsRequired && !parent && skelDimensionsRatio && (skelDimensionsRatio.x !== 1 || skelDimensionsRatio.y !== 1 || skelDimensionsRatio.z !== 1);           
             
@@ -230,7 +231,7 @@ module BABYLON {
                             mat.setTranslation(origTranslation.scaleInPlace(parentRatio));
                             
                         // scale based on skeleton dimension ratio when root bone, and value is passed
-                        } else if (dimensionsScalingReqd) {
+                        } else if (dimensionsScalingReqd && skelDimensionsRatio) {
                             origTranslation = mat.getTranslation();
                             mat.setTranslation(origTranslation.multiplyInPlace(skelDimensionsRatio));                            
 
@@ -255,21 +256,17 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.  This is only used in world space.
          */
         public translate(vec: Vector3, space = Space.LOCAL, mesh?: AbstractMesh): void {
-
             var lm = this.getLocalMatrix();
 
             if(space == Space.LOCAL){
-
                 lm.m[12] += vec.x;
                 lm.m[13] += vec.y;
                 lm.m[14] += vec.z;
-
-            }else{
-
-                var wm:Matrix;
+            } else {
+                var wm: Nullable<Matrix> = null;
 
                 //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
-                if(mesh){
+                if (mesh){
                     wm = mesh.getWorldMatrix();
                 }
 
@@ -277,11 +274,13 @@ module BABYLON {
                 var tmat = Bone._tmpMats[0];
                 var tvec = Bone._tmpVecs[0];
 
-                if (mesh) {
-                    tmat.copyFrom(this._parent.getAbsoluteTransform());
-                    tmat.multiplyToRef(wm, tmat);
-                }else {
-                    tmat.copyFrom(this._parent.getAbsoluteTransform());
+                if (this._parent) {
+                    if (mesh && wm) {
+                        tmat.copyFrom(this._parent.getAbsoluteTransform());
+                        tmat.multiplyToRef(wm, tmat);
+                    } else {
+                        tmat.copyFrom(this._parent.getAbsoluteTransform());
+                    }
                 }
 
                 tmat.m[12] = 0;
@@ -311,15 +310,12 @@ module BABYLON {
 
             var lm = this.getLocalMatrix();
 
-            if(space == Space.LOCAL){
-
+            if (space == Space.LOCAL) {
                 lm.m[12] = position.x;
                 lm.m[13] = position.y;
                 lm.m[14] = position.z;
-
-            }else{
-
-                var wm:Matrix;
+            } else {
+                var wm: Nullable<Matrix> = null;
 
                 //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
                 if(mesh){
@@ -331,11 +327,13 @@ module BABYLON {
                 var tmat = Bone._tmpMats[0];
                 var vec = Bone._tmpVecs[0];
 
-                if (mesh) {
-                    tmat.copyFrom(this._parent.getAbsoluteTransform());
-                    tmat.multiplyToRef(wm, tmat);
-                }else {
-                    tmat.copyFrom(this._parent.getAbsoluteTransform());
+                if (this._parent) {
+                    if (mesh && wm) {
+                        tmat.copyFrom(this._parent.getAbsoluteTransform());
+                        tmat.multiplyToRef(wm, tmat);
+                    } else {
+                        tmat.copyFrom(this._parent.getAbsoluteTransform());
+                    }
                 }
 
                 tmat.invert();
@@ -675,14 +673,12 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.  This is only used in world space.
          * @returns The position of the bone
          */
-        public getPosition(space = Space.LOCAL, mesh?: AbstractMesh): Vector3 {
-
+        public getPosition(space = Space.LOCAL, mesh: Nullable<AbstractMesh> = null): Vector3 {
             var pos = Vector3.Zero();
 
             this.getPositionToRef(space, mesh, pos);
 
             return pos;
-
         }
 
         /**
@@ -691,22 +687,19 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.  This is only used in world space.
          * @param result The vector3 to copy the position to.
          */
-        public getPositionToRef(space = Space.LOCAL, mesh: AbstractMesh, result: Vector3): void {
-
-            if(space == Space.LOCAL){
+        public getPositionToRef(space = Space.LOCAL, mesh: Nullable<AbstractMesh>, result: Vector3): void {
 
+            if (space == Space.LOCAL){
                 var lm = this.getLocalMatrix();
 
                 result.x = lm.m[12];
                 result.y = lm.m[13];
                 result.z = lm.m[14];
-
-            }else{
-                
-                var wm;
+            } else {               
+                var wm: Nullable<Matrix> = null;
                 
                 //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
-                if(mesh){
+                if (mesh){
                     wm = mesh.getWorldMatrix();
                 }
                 
@@ -714,7 +707,7 @@ module BABYLON {
                 
                 var tmat = Bone._tmpMats[0];
 
-                if (mesh) {
+                if (mesh && wm) {
                     tmat.copyFrom(this.getAbsoluteTransform());
                     tmat.multiplyToRef(wm, tmat);
                 }else{
@@ -724,9 +717,7 @@ module BABYLON {
                 result.x = tmat.m[12];
                 result.y = tmat.m[13];
                 result.z = tmat.m[14];
-
             }
-
         }
 
         /**
@@ -734,7 +725,7 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.
          * @returns The absolute position of the bone
          */
-        public getAbsolutePosition(mesh?: AbstractMesh): Vector3 {
+        public getAbsolutePosition(mesh: Nullable<AbstractMesh> = null): Vector3 {
 
             var pos = Vector3.Zero();
 
@@ -813,7 +804,7 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.
          * @returns The world direction
          */
-        public getDirection(localAxis: Vector3, mesh?: AbstractMesh): Vector3{
+        public getDirection(localAxis: Vector3, mesh: Nullable<AbstractMesh> = null): Vector3{
 
             var result = Vector3.Zero();
 
@@ -829,9 +820,9 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.
          * @param result The vector3 that the world direction will be copied to.
          */
-        public getDirectionToRef(localAxis: Vector3, mesh: AbstractMesh, result: Vector3): void {
+        public getDirectionToRef(localAxis: Vector3, mesh: Nullable<AbstractMesh> = null, result: Vector3): void {
 
-            var wm:Matrix;
+            var wm: Nullable<Matrix> = null;
 
             //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
             if(mesh){
@@ -844,7 +835,7 @@ module BABYLON {
 
             mat.copyFrom(this.getAbsoluteTransform());
 
-            if(mesh){
+            if (mesh && wm) {
                 mat.multiplyToRef(wm, mat);
             }
 
@@ -860,7 +851,7 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.  This is only used in world space.
          * @returns The euler rotation
          */
-        public getRotation(space = Space.LOCAL, mesh?: AbstractMesh): Vector3 {
+        public getRotation(space = Space.LOCAL, mesh: Nullable<AbstractMesh> = null): Vector3 {
 
             var result = Vector3.Zero();
 
@@ -876,7 +867,7 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.  This is only used in world space.
          * @param result The vector3 that the rotation should be copied to.
          */
-        public getRotationToRef(space = Space.LOCAL, mesh: AbstractMesh, result: Vector3): void {
+        public getRotationToRef(space = Space.LOCAL, mesh: Nullable<AbstractMesh> = null, result: Vector3): void {
 
             var quat = Bone._tmpQuat;
 
@@ -892,7 +883,7 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.  This is only used in world space.
          * @returns The quaternion rotation
          */
-        public getRotationQuaternion(space = Space.LOCAL, mesh?: AbstractMesh): Quaternion {
+        public getRotationQuaternion(space = Space.LOCAL, mesh: Nullable<AbstractMesh> = null): Quaternion {
 
             var result = Quaternion.Identity();
 
@@ -908,7 +899,7 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.  This is only used in world space.
          * @param result The quaternion that the rotation should be copied to.
          */
-        public getRotationQuaternionToRef(space = Space.LOCAL, mesh: AbstractMesh, result: Quaternion): void{
+        public getRotationQuaternionToRef(space = Space.LOCAL, mesh: Nullable<AbstractMesh> = null, result: Quaternion): void{
 
             if(space == Space.LOCAL){
 
@@ -989,7 +980,7 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.
          * @returns The world position
          */
-        public getAbsolutePositionFromLocal(position:Vector3, mesh?:AbstractMesh): Vector3{
+        public getAbsolutePositionFromLocal(position:Vector3, mesh: Nullable<AbstractMesh> = null): Vector3{
 
             var result = Vector3.Zero();
 
@@ -1005,9 +996,9 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.
          * @param result The vector3 that the world position should be copied to.
          */
-        public getAbsolutePositionFromLocalToRef(position:Vector3, mesh:AbstractMesh, result:Vector3): void{
+        public getAbsolutePositionFromLocalToRef(position:Vector3, mesh: Nullable<AbstractMesh> = null, result:Vector3): void{
 
-            var wm:Matrix;
+            var wm: Nullable<Matrix> = null;
 
             //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
             if(mesh){
@@ -1018,7 +1009,7 @@ module BABYLON {
 
             var tmat = Bone._tmpMats[0];
             
-            if (mesh) {
+            if (mesh && wm) {
                 tmat.copyFrom(this.getAbsoluteTransform());
                 tmat.multiplyToRef(wm, tmat);
             }else{
@@ -1035,7 +1026,7 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.
          * @returns The local position
          */
-        public getLocalPositionFromAbsolute(position:Vector3, mesh?:AbstractMesh): Vector3{
+        public getLocalPositionFromAbsolute(position:Vector3, mesh: Nullable<AbstractMesh> = null): Vector3{
 
             var result = Vector3.Zero();
 
@@ -1051,9 +1042,9 @@ module BABYLON {
          * @param mesh The mesh that this bone is attached to.
          * @param result The vector3 that the local position should be copied to.
          */
-        public getLocalPositionFromAbsoluteToRef(position:Vector3, mesh:AbstractMesh, result:Vector3): void{
+        public getLocalPositionFromAbsoluteToRef(position:Vector3, mesh: Nullable<AbstractMesh> = null, result:Vector3): void{
 
-            var wm:Matrix;
+            var wm: Nullable<Matrix> = null;
 
             //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
             if(mesh){
@@ -1066,7 +1057,7 @@ module BABYLON {
 
             tmat.copyFrom(this.getAbsoluteTransform());
             
-            if (mesh) {
+            if (mesh && wm) {
                 tmat.multiplyToRef(wm, tmat);
             }
 

+ 28 - 22
src/Bones/babylon.boneIKController.ts

@@ -7,7 +7,7 @@ module BABYLON {
         
         public targetMesh: AbstractMesh;
         public poleTargetMesh: AbstractMesh;
-        public poleTargetBone: Bone;
+        public poleTargetBone: Nullable<Bone>;
         public targetPosition = Vector3.Zero();
         public poleTargetPosition = Vector3.Zero();
         public poleTargetLocalOffset = Vector3.Zero();
@@ -19,7 +19,7 @@ module BABYLON {
         private _bone1Mat = Matrix.Identity();
         private _bone2Ang = Math.PI;
 
-        private _bone1: Bone;
+        private _bone1: Nullable<Bone>;
         private _bone2: Bone;
         private _bone1Length: number;
         private _bone2Length: number;
@@ -60,6 +60,10 @@ module BABYLON {
 
             this._bone2 = bone;
             this._bone1 = bone.getParent();
+
+            if (!this._bone1) {
+                return;
+            }
             
             this.mesh = mesh;
 
@@ -76,7 +80,7 @@ module BABYLON {
                     this._bendAxis.z = 1;
                 }
             }
-
+            
             if (this._bone1.length) {
 
                 var boneScale1 = this._bone1.getScale();
@@ -95,7 +99,6 @@ module BABYLON {
 
                 this._bone1Length = Vector3.Distance(pos1, pos2);
                 this._bone2Length = Vector3.Distance(pos2, pos3);
-
             }
 
             this._bone1.getRotationMatrixToRef(Space.WORLD, mesh, this._bone1Mat);
@@ -113,14 +116,10 @@ module BABYLON {
                     this.poleTargetMesh = options.poleTargetMesh;
                     this.poleTargetMesh.computeWorldMatrix(true);
 
-                }else if(options.poleTargetBone){
-
+                } else if(options.poleTargetBone){
                     this.poleTargetBone = options.poleTargetBone;
-
-                }else if(this._bone1.getParent()){
-
+                } else if(this._bone1.getParent()){
                     this.poleTargetBone = this._bone1.getParent();
-
                 }
 
                 if(options.poleTargetLocalOffset){
@@ -169,6 +168,11 @@ module BABYLON {
         public update(): void {
 	
             var bone1 = this._bone1;
+
+            if (!bone1) {
+                return;
+            }
+
             var target = this.targetPosition;
             var poleTarget = this.poleTargetPosition;
 
@@ -272,19 +276,21 @@ module BABYLON {
                 mat1.multiplyToRef(mat2, mat1);
             }
 
-            if(this.slerpAmount < 1){
-                if(!this._slerping){
-                    Quaternion.FromRotationMatrixToRef(this._bone1Mat, this._bone1Quat);
+            if (this._bone1) {
+                if(this.slerpAmount < 1){
+                    if(!this._slerping){
+                        Quaternion.FromRotationMatrixToRef(this._bone1Mat, this._bone1Quat);
+                    }
+                    Quaternion.FromRotationMatrixToRef(mat1, _tmpQuat);
+                    Quaternion.SlerpToRef(this._bone1Quat, _tmpQuat, this.slerpAmount, this._bone1Quat);
+                    angC = this._bone2Ang * (1.0 - this.slerpAmount) + angC * this.slerpAmount;
+                    this._bone1.setRotationQuaternion(this._bone1Quat, Space.WORLD, this.mesh);
+                    this._slerping = true;
+                } else {
+                    this._bone1.setRotationMatrix(mat1, Space.WORLD, this.mesh);
+                    this._bone1Mat.copyFrom(mat1);
+                    this._slerping = false;
                 }
-                Quaternion.FromRotationMatrixToRef(mat1, _tmpQuat);
-                Quaternion.SlerpToRef(this._bone1Quat, _tmpQuat, this.slerpAmount, this._bone1Quat);
-                angC = this._bone2Ang * (1.0 - this.slerpAmount) + angC * this.slerpAmount;
-                this._bone1.setRotationQuaternion(this._bone1Quat, Space.WORLD, this.mesh);
-                this._slerping = true;
-            } else {
-                this._bone1.setRotationMatrix(mat1, Space.WORLD, this.mesh);
-                this._bone1Mat.copyFrom(mat1);
-                this._slerping = false;
             }
 
             this._bone2.setAxisAngle(this._bendAxis, angC, Space.LOCAL);

+ 4 - 4
src/Bones/babylon.boneLookController.ts

@@ -277,7 +277,7 @@ module BABYLON {
             var upAxis = BoneLookController._tmpVecs[1];
             upAxis.copyFrom(this.upAxis);
 
-            if(this.upAxisSpace == Space.BONE){
+            if(this.upAxisSpace == Space.BONE && parentBone){
                 if (this._transformYawPitch){
                     Vector3.TransformCoordinatesToRef(upAxis, this._transformYawPitchInv, upAxis);
                 }
@@ -304,7 +304,7 @@ module BABYLON {
                 var spaceMat = BoneLookController._tmpMats[2];
                 var spaceMatInv = BoneLookController._tmpMats[3];
 
-                if(this.upAxisSpace == Space.BONE && upAxis.y == 1){
+                if(this.upAxisSpace == Space.BONE && upAxis.y == 1 && parentBone){
 
                     parentBone.getRotationMatrixToRef(Space.WORLD, this.mesh, spaceMat);
                     
@@ -337,14 +337,14 @@ module BABYLON {
 
                 spaceMat.invertToRef(spaceMatInv);
                 
-                var xzlen:number;
+                var xzlen: Nullable<number> = null;
 
                 if(checkPitch){
                     var localTarget = BoneLookController._tmpVecs[3];
                     target.subtractToRef(bonePos, localTarget);
                     Vector3.TransformCoordinatesToRef(localTarget, spaceMatInv, localTarget);
 
-                    var xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);
+                    xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);
                     var pitch = Math.atan2(localTarget.y, xzlen);
                     var newPitch = pitch;
 

+ 32 - 20
src/Bones/babylon.skeleton.ts

@@ -14,7 +14,7 @@
         private _identity = Matrix.Identity();
         private _synchronizedWithMesh: AbstractMesh;
 
-        private _ranges: { [name: string]: AnimationRange; } = {};
+        private _ranges: { [name: string]: Nullable<AnimationRange> } = {};
 
         private _lastAbsoluteTransformsUpdateId = -1;
 
@@ -108,18 +108,18 @@
                     this.bones[i].animations[0].deleteRange(name, deleteFrames);
                 }
             }
-            this._ranges[name] = undefined; // said much faster than 'delete this._range[name]' 
+            this._ranges[name] = null; // said much faster than 'delete this._range[name]' 
         }
 
-        public getAnimationRange(name: string): AnimationRange {
+        public getAnimationRange(name: string): Nullable<AnimationRange> {
             return this._ranges[name];
         }
 
         /**
          *  Returns as an Array, all AnimationRanges defined on this skeleton
          */
-        public getAnimationRanges(): AnimationRange[] {
-            var animationRanges: AnimationRange[] = [];
+        public getAnimationRanges(): Nullable<AnimationRange>[] {
+            var animationRanges: Nullable<AnimationRange>[] = [];
             var name: string;
             var i: number = 0;
             for (name in this._ranges) {
@@ -167,7 +167,9 @@
             }
             // do not call createAnimationRange(), since it also is done to bones, which was already done
             var range = source.getAnimationRange(name);
-            this._ranges[name] = new AnimationRange(name, range.from + frameOffset, range.to + frameOffset);
+            if (range) {
+                this._ranges[name] = new AnimationRange(name, range.from + frameOffset, range.to + frameOffset);
+            }
             return ret;
         }
 
@@ -190,7 +192,7 @@
             return ret;
         }
 
-        public beginAnimation(name: string, loop?: boolean, speedRatio?: number, onAnimationEnd?: () => void): Animatable {
+        public beginAnimation(name: string, loop?: boolean, speedRatio?: number, onAnimationEnd?: () => void): Nullable<Animatable> {
             var range = this.getAnimationRange(name);
 
             if (!range) {
@@ -216,7 +218,7 @@
             }
         }
 
-        public _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Matrix): void {
+        public _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Nullable<Matrix>): void {
 
             this.onBeforeComputeObservable.notifyObservers(this);
 
@@ -235,7 +237,7 @@
                 }
 
                 if (bone._index !== -1) {
-                    var mappedIndex = bone._index === undefined ? index : bone._index;
+                    var mappedIndex = bone._index === null ? index : bone._index;
                     bone.getInvertedAbsoluteTransform().multiplyToArray(bone.getWorldMatrix(), targetMatrix, mappedIndex * 16);
                 }
             }
@@ -309,8 +311,9 @@
                 var source = this.bones[index];
                 var parentBone = null;
 
-                if (source.getParent()) {
-                    var parentIndex = this.bones.indexOf(source.getParent());
+                let parent = source.getParent();
+                if (parent) {
+                    var parentIndex = this.bones.indexOf(parent);
                     parentBone = result.bones[parentIndex];
                 }
 
@@ -321,7 +324,11 @@
             if (this._ranges) {
                 result._ranges = {};
                 for (var rangeName in this._ranges) {
-                    result._ranges[rangeName] = this._ranges[rangeName].clone();
+                    let range = this._ranges[rangeName];
+
+                    if (range) {
+                        result._ranges[rangeName] = range.clone();
+                    }
                 }
             }
 
@@ -362,9 +369,10 @@
 
             for (var index = 0; index < this.bones.length; index++) {
                 var bone = this.bones[index];
+                let parent = bone.getParent();
 
                 var serializedBone: any = {
-                    parentBoneIndex: bone.getParent() ? this.bones.indexOf(bone.getParent()) : -1,
+                    parentBoneIndex: parent ? this.bones.indexOf(parent) : -1,
                     name: bone.name,
                     matrix: bone.getBaseMatrix().toArray(),
                     rest: bone.getRestPose().toArray()
@@ -382,10 +390,16 @@
 
                 serializationObject.ranges = [];
                 for (var name in this._ranges) {
+                    let source = this._ranges[name];
+
+                    if (!source) {
+                        continue;
+                    }
+
                     var range: any = {};
                     range.name = name;
-                    range.from = this._ranges[name].from;
-                    range.to = this._ranges[name].to;
+                    range.from = source.from;
+                    range.to = source.to;
                     serializationObject.ranges.push(range);
                 }
             }
@@ -408,7 +422,7 @@
                 if (parsedBone.parentBoneIndex > -1) {
                     parentBone = skeleton.bones[parsedBone.parentBoneIndex];
                 }
-                var rest: Matrix = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;
+                var rest: Nullable<Matrix> = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;
                 var bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest);
 
                 if (parsedBone.length) {
@@ -441,16 +455,14 @@
             
         }
 
-        public getPoseMatrix(): Matrix {
-            
-            var poseMatrix: Matrix;
+        public getPoseMatrix(): Nullable<Matrix> {        
+            var poseMatrix: Nullable<Matrix> = null;
             
             if(this._meshesWithPoseMatrix.length > 0){
                 poseMatrix = this._meshesWithPoseMatrix[0].getPoseMatrix();
             }
 
             return poseMatrix;
-
         }
 
         public sortBones(): void {

+ 3 - 3
src/Cameras/Inputs/babylon.arcRotateCameraGamepadInput.ts

@@ -2,9 +2,9 @@ module BABYLON {
     export class ArcRotateCameraGamepadInput implements ICameraInput<ArcRotateCamera> {
         camera: ArcRotateCamera;
 
-        public gamepad: Gamepad;
-        private _onGamepadConnectedObserver : Observer<Gamepad>;
-        private _onGamepadDisconnectedObserver : Observer<Gamepad>;
+        public gamepad: Nullable<Gamepad>;
+        private _onGamepadConnectedObserver : Nullable<Observer<Gamepad>>;
+        private _onGamepadDisconnectedObserver : Nullable<Observer<Gamepad>>;
 
         @serialize()
         public gamepadRotationSensibility = 80;

+ 8 - 4
src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts

@@ -29,8 +29,8 @@ module BABYLON {
 
         private _ctrlPressed: boolean;
         private _altPressed: boolean;
-        private _onCanvasBlurObserver: Observer<Engine>;
-        private _onKeyboardObserver: Observer<KeyboardInfo>;
+        private _onCanvasBlurObserver: Nullable<Observer<Engine>>;
+        private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;
         private _engine: Engine;
         private _scene: Scene;
 
@@ -95,8 +95,12 @@ module BABYLON {
 
         public detachControl(element: HTMLElement) {
             if (this._scene) {
-                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
-                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
+                if (this._onKeyboardObserver) {
+                    this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
+                }
+                if (this._onCanvasBlurObserver) {
+                    this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
+                }
                 this._onKeyboardObserver = null;
                 this._onCanvasBlurObserver = null;
             }

+ 2 - 2
src/Cameras/Inputs/babylon.arcRotateCameraMouseWheelInput.ts

@@ -2,8 +2,8 @@ module BABYLON {
     export class ArcRotateCameraMouseWheelInput implements ICameraInput<ArcRotateCamera> {
         camera: ArcRotateCamera;
 
-        private _wheel: (p: PointerInfo, s: EventState) => void;
-        private _observer: Observer<PointerInfo>;
+        private _wheel: Nullable<(p: PointerInfo, s: EventState) => void>;
+        private _observer: Nullable<Observer<PointerInfo>>;
 
         @serialize()
         public wheelPrecision = 3.0;

+ 43 - 29
src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts

@@ -34,18 +34,19 @@ module BABYLON {
         public pinchInwards = true;
 
         private _pointerInput: (p: PointerInfo, s: EventState) => void;
-        private _observer: Observer<PointerInfo>;
-        private _onMouseMove: (e: MouseEvent) => any;
-        private _onGestureStart: (e: PointerEvent) => void;
-        private _onGesture: (e: MSGestureEvent) => void;
-        private _MSGestureHandler: MSGesture;
-        private _onLostFocus: (e: FocusEvent) => any;
-        private _onContextMenu: (e: PointerEvent) => void;
+        private _observer: Nullable<Observer<PointerInfo>>;
+        private _onMouseMove: Nullable<(e: MouseEvent) => any>;
+        private _onGestureStart: Nullable<(e: PointerEvent) => void>;
+        private _onGesture: Nullable<(e: MSGestureEvent) => void>;
+        private _MSGestureHandler: Nullable<MSGesture>;
+        private _onLostFocus: Nullable<(e: FocusEvent) => any>;
+        private _onContextMenu: Nullable<(e: PointerEvent) => void>;
 
         public attachControl(element: HTMLElement, noPreventDefault?: boolean) {
             var engine = this.camera.getEngine();
-            var cacheSoloPointer: { x: number, y: number, pointerId: number, type: any }; // cache pointer object for better perf on camera rotation
-            var pointA: { x: number, y: number, pointerId: number, type: any }, pointB: { x: number, y: number, pointerId: number, type: any };
+            var cacheSoloPointer: Nullable<{ x: number, y: number, pointerId: number, type: any }>; // cache pointer object for better perf on camera rotation
+            var pointA: Nullable<{ x: number, y: number, pointerId: number, type: any }> = null;
+            var pointB: Nullable<{ x: number, y: number, pointerId: number, type: any }> = null;
             var previousPinchSquaredDistance = 0;
             var initialDistance = 0;
             var twoFingerActivityCount = 0;
@@ -62,7 +63,7 @@ module BABYLON {
                     return;
                 }
 
-                if (p.type === PointerEventTypes.POINTERDOWN) {
+                if (p.type === PointerEventTypes.POINTERDOWN && evt.srcElement) {
                     try {
                         evt.srcElement.setPointerCapture(evt.pointerId);
                     } catch (e) {
@@ -74,10 +75,10 @@ module BABYLON {
 
                     // manage pointers
                     cacheSoloPointer = { x: evt.clientX, y: evt.clientY, pointerId: evt.pointerId, type: evt.pointerType };
-                    if (pointA === undefined) {
+                    if (pointA === null) {
                         pointA = cacheSoloPointer;
                     }
-                    else if (pointB === undefined) {
+                    else if (pointB === null) {
                         pointB = cacheSoloPointer;
                     }
                     if (!noPreventDefault) {
@@ -88,7 +89,7 @@ module BABYLON {
                 else if (p.type === PointerEventTypes.POINTERDOUBLETAP) {
                     this.camera.restoreState();
                 }
-                else if (p.type === PointerEventTypes.POINTERUP) {
+                else if (p.type === PointerEventTypes.POINTERUP && evt.srcElement) {
                     try {
                         evt.srcElement.releasePointerCapture(evt.pointerId);
                     } catch (e) {
@@ -103,7 +104,7 @@ module BABYLON {
                     initialDistance = 0;
 
                     if((<any>p.event).pointerType !== "touch") {
-                        pointB = undefined; // Mouse and pen are mono pointer
+                        pointB = null; // Mouse and pen are mono pointer
                     }
 
                     //would be better to use pointers.remove(evt.pointerId) for multitouch gestures, 
@@ -111,22 +112,22 @@ module BABYLON {
                     //when changing orientation while pinching camera, one pointer stay pressed forever if we don't release all pointers  
                     //will be ok to put back pointers.remove(evt.pointerId); when iPhone bug corrected
                     if (engine.badOS) {
-                        pointA = pointB = undefined;
+                        pointA = pointB = null;
                     }
                     else {
                         //only remove the impacted pointer in case of multitouch allowing on most 
                         //platforms switching from rotate to zoom and pan seamlessly.
                         if (pointB && pointA && pointA.pointerId == evt.pointerId) {
                             pointA = pointB;
-                            pointB = undefined;
+                            pointB = null;
                             cacheSoloPointer = { x: pointA.x, y: pointA.y, pointerId: pointA.pointerId, type: evt.pointerType };
                         }
                         else if (pointA && pointB && pointB.pointerId == evt.pointerId) {
-                            pointB = undefined;
+                            pointB = null;
                             cacheSoloPointer = { x: pointA.x, y: pointA.y, pointerId: pointA.pointerId, type: evt.pointerType };
                         }
                         else {
-                            pointA = pointB = undefined;
+                            pointA = pointB = null;
                         }
                     }
 
@@ -139,7 +140,7 @@ module BABYLON {
                     }
 
                     // One button down
-                    if (pointA && pointB === undefined) {
+                    if (pointA && pointB === null && cacheSoloPointer) {
                         if (this.panningSensibility !== 0 &&
                             ((evt.ctrlKey && this.camera._useCtrlForPanning) || this._isPanClick)) {
                             this.camera.inertialPanningX += -(evt.clientX - cacheSoloPointer.x) / this.panningSensibility;
@@ -214,7 +215,7 @@ module BABYLON {
                                 previousMultiTouchPanPosition.isPinching = true;
                             }
                             else {
-                                if (cacheSoloPointer.pointerId === ed.pointerId && this.panningSensibility !== 0 && this.multiTouchPanning) {
+                                if (cacheSoloPointer && cacheSoloPointer.pointerId === ed.pointerId && this.panningSensibility !== 0 && this.multiTouchPanning) {
                                     if (!previousMultiTouchPanPosition.isPaning) {
                                         previousMultiTouchPanPosition.isPaning = true;
                                         previousMultiTouchPanPosition.isPinching = false;
@@ -228,7 +229,7 @@ module BABYLON {
                                 }
                             }
 
-                            if (cacheSoloPointer.pointerId === evt.pointerId) {
+                            if (cacheSoloPointer && cacheSoloPointer.pointerId === evt.pointerId) {
                                 previousMultiTouchPanPosition.x = ed.x;
                                 previousMultiTouchPanPosition.y = ed.y;
                             }
@@ -251,7 +252,7 @@ module BABYLON {
 
             this._onLostFocus = () => {
                 //this._keys = [];
-                pointA = pointB = undefined;
+                pointA = pointB = null;
                 previousPinchSquaredDistance = 0;
                 previousMultiTouchPanPosition.isPaning = false;
                 previousMultiTouchPanPosition.isPinching = false;
@@ -311,18 +312,31 @@ module BABYLON {
         }
 
         public detachControl(element: HTMLElement) {
-            Tools.UnregisterTopRootEvents([
-                { name: "blur", handler: this._onLostFocus }
-            ]);
+            if (this._onLostFocus) {
+                Tools.UnregisterTopRootEvents([
+                    { name: "blur", handler: this._onLostFocus }
+                ]);
+            }
 
             if (element && this._observer) {
                 this.camera.getScene().onPointerObservable.remove(this._observer);
                 this._observer = null;
 
-                element.removeEventListener("contextmenu", this._onContextMenu);
-                element.removeEventListener("mousemove", this._onMouseMove);
-                element.removeEventListener("MSPointerDown", this._onGestureStart);
-                element.removeEventListener("MSGestureChange", this._onGesture);
+                if (this._onContextMenu) {
+                    element.removeEventListener("contextmenu", this._onContextMenu);
+                }
+
+                if (this._onMouseMove) {
+                    element.removeEventListener("mousemove", this._onMouseMove);
+                }
+
+                if (this._onGestureStart) {
+                    element.removeEventListener("MSPointerDown", this._onGestureStart);
+                }
+
+                if (this._onGesture) {
+                    element.removeEventListener("MSGestureChange", this._onGesture);
+                }
 
                 this._isPanClick = false;
                 this.pinchInwards = true;

+ 11 - 3
src/Cameras/Inputs/babylon.arcRotateCameraVRDeviceOrientationInput.ts

@@ -23,9 +23,17 @@ module BABYLON {
         }
 
         public _onOrientationEvent(evt: DeviceOrientationEvent): void {
-            this._alpha = +evt.alpha | 0;
-            this._beta = +evt.beta | 0;
-            this._gamma = +evt.gamma | 0;
+            if (evt.alpha !== null) {
+                this._alpha = +evt.alpha | 0;
+            }
+
+            if (evt.beta !== null) {
+                this._beta = +evt.beta | 0;
+            }
+
+            if (evt.gamma !== null) {               
+                this._gamma = +evt.gamma | 0;
+            }
             this._dirty = true;
         }
 

+ 3 - 3
src/Cameras/Inputs/babylon.freeCameraDeviceOrientationInput.ts

@@ -42,9 +42,9 @@ module BABYLON {
         }
 
         private _deviceOrientation = (evt: DeviceOrientationEvent) => {
-            this._alpha = evt.alpha;
-            this._beta = evt.beta;
-            this._gamma = evt.gamma;
+            this._alpha = evt.alpha !== null ? evt.alpha : 0;
+            this._beta = evt.beta !== null ? evt.beta : 0;
+            this._gamma = evt.gamma !== null ? evt.gamma : 0;
         }
 
         detachControl(element: HTMLElement) {

+ 3 - 3
src/Cameras/Inputs/babylon.freeCameraGamepadInput.ts

@@ -2,9 +2,9 @@ module BABYLON {
     export class FreeCameraGamepadInput implements ICameraInput<FreeCamera> {
         camera: FreeCamera;
 
-        public gamepad: Gamepad;        
-        private _onGamepadConnectedObserver : Observer<Gamepad>;
-        private _onGamepadDisconnectedObserver : Observer<Gamepad>;
+        public gamepad: Nullable<Gamepad>;        
+        private _onGamepadConnectedObserver : Nullable<Observer<Gamepad>>;
+        private _onGamepadDisconnectedObserver : Nullable<Observer<Gamepad>>;
 
         @serialize()
         public gamepadAngularSensibility = 200;

+ 9 - 4
src/Cameras/Inputs/babylon.freeCameraKeyboardMoveInput.ts

@@ -2,8 +2,8 @@ module BABYLON {
     export class FreeCameraKeyboardMoveInput implements ICameraInput<FreeCamera> {
         camera: FreeCamera;
         private _keys = new Array<number>();
-        private _onCanvasBlurObserver: Observer<Engine>;
-        private _onKeyboardObserver: Observer<KeyboardInfo>;
+        private _onCanvasBlurObserver: Nullable<Observer<Engine>>;
+        private _onKeyboardObserver: Nullable<Observer<KeyboardInfo>>;
         private _engine: Engine;
         private _scene: Scene;        
 
@@ -68,8 +68,13 @@ module BABYLON {
 
         detachControl(element : HTMLElement) {
             if (this._scene) {
-                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
-                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
+                if (this._onKeyboardObserver) {
+                    this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
+                }
+
+                if (this._onCanvasBlurObserver) {
+                    this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
+                }
                 this._onKeyboardObserver = null;
                 this._onCanvasBlurObserver = null;
             }

+ 9 - 6
src/Cameras/Inputs/babylon.freeCameraMouseInput.ts

@@ -9,10 +9,10 @@ module BABYLON {
         public angularSensibility = 2000.0;
 
         private _pointerInput: (p: PointerInfo, s: EventState) => void;
-        private _onMouseMove: (e: MouseEvent) => any;
-        private _observer: Observer<PointerInfo>;
+        private _onMouseMove: Nullable<(e: MouseEvent) => any>;
+        private _observer: Nullable<Observer<PointerInfo>>;
 
-        private previousPosition: { x: number, y: number };
+        private previousPosition: Nullable<{ x: number, y: number }> = null;
 
         constructor(public touchEnabled = true) {
         }           
@@ -36,7 +36,7 @@ module BABYLON {
                         return;
                     }
 
-                    if (p.type === PointerEventTypes.POINTERDOWN) {
+                    if (p.type === PointerEventTypes.POINTERDOWN && evt.srcElement) {
                         try {
                             evt.srcElement.setPointerCapture(evt.pointerId);
                         } catch (e) {
@@ -53,7 +53,7 @@ module BABYLON {
                             element.focus();
                         }
                     }
-                    else if (p.type === PointerEventTypes.POINTERUP) {
+                    else if (p.type === PointerEventTypes.POINTERUP && evt.srcElement) {
                         try {
                             evt.srcElement.releasePointerCapture(evt.pointerId);
                         } catch (e) {
@@ -129,7 +129,10 @@ module BABYLON {
         detachControl(element: HTMLElement) {
             if (this._observer && element) {
                 this.camera.getScene().onPointerObservable.remove(this._observer);
-                element.removeEventListener("mousemove", this._onMouseMove);
+
+                if (this._onMouseMove) {
+                    element.removeEventListener("mousemove", this._onMouseMove);
+                }
 
                 this._observer = null;
                 this._onMouseMove = null;

+ 17 - 12
src/Cameras/Inputs/babylon.freeCameraTouchInput.ts

@@ -2,13 +2,13 @@ module BABYLON {
     export class FreeCameraTouchInput implements ICameraInput<FreeCamera> {
         camera: FreeCamera;
 
-        private _offsetX: number = null;
-        private _offsetY: number = null;
+        private _offsetX: Nullable<number> = null;
+        private _offsetY: Nullable<number> = null;
         private _pointerCount: number = 0;
         private _pointerPressed = new Array<number>();
         private _pointerInput: (p: PointerInfo, s: EventState) => void;
-        private _observer: Observer<PointerInfo>;
-        private _onLostFocus: (e: FocusEvent) => any;
+        private _observer: Nullable<Observer<PointerInfo>>;
+        private _onLostFocus: Nullable<(e: FocusEvent) => any>;
 
         @serialize()
         public touchAngularSensibility: number = 200000.0;
@@ -17,7 +17,7 @@ module BABYLON {
         public touchMoveSensibility: number = 250.0;
 
         attachControl(element: HTMLElement, noPreventDefault?: boolean) {
-            var previousPosition: {x: number, y: number};
+            var previousPosition: Nullable<{x: number, y: number}> = null;
 
             if (this._pointerInput === undefined) {
                 this._onLostFocus = (evt) => {
@@ -93,17 +93,22 @@ module BABYLON {
 
             this._observer = this.camera.getScene().onPointerObservable.add(this._pointerInput, PointerEventTypes.POINTERDOWN | PointerEventTypes.POINTERUP | PointerEventTypes.POINTERMOVE);
 
-            element.addEventListener("blur", this._onLostFocus);
+            if (this._onLostFocus) {
+                element.addEventListener("blur", this._onLostFocus);
+            }
         }
 
         detachControl(element: HTMLElement) {
             if (this._pointerInput && element) {
-                this.camera.getScene().onPointerObservable.remove(this._observer);
-                this._observer = null;
-
-                element.removeEventListener("blur", this._onLostFocus);
+                if (this._observer) {
+                    this.camera.getScene().onPointerObservable.remove(this._observer);
+                    this._observer = null;
+                }
 
-                this._onLostFocus = null;
+                if (this._onLostFocus) {
+                    element.removeEventListener("blur", this._onLostFocus);
+                    this._onLostFocus = null;
+                }
                 this._pointerPressed = [];
                 this._offsetX = null;
                 this._offsetY = null;
@@ -112,7 +117,7 @@ module BABYLON {
         }
 
         checkInputs() {
-            if (this._offsetX) {
+            if (this._offsetX && this._offsetY) {
                 var camera = this.camera;
                 camera.cameraRotation.y += this._offsetX / this.touchAngularSensibility;
 

+ 31 - 17
src/Cameras/VR/babylon.vrExperienceHelper.ts

@@ -16,7 +16,7 @@ module BABYLON {
         // Are we presenting in the fullscreen fallback?
         private _fullscreenVRpresenting = false;
 
-        private _canvas: HTMLCanvasElement;
+        private _canvas: Nullable<HTMLCanvasElement>;
         private _webVRCamera: WebVRFreeCamera;
         private _vrDeviceOrientationCamera: VRDeviceOrientationFreeCamera;
         private _deviceOrientationCamera: DeviceOrientationCamera;
@@ -48,7 +48,9 @@ module BABYLON {
             this._scene.activeCamera = this._deviceOrientationCamera;
             this._position = this._scene.activeCamera.position;
             this._canvas = scene.getEngine().getRenderingCanvas();
-            this._scene.activeCamera.attachControl(this._canvas);
+            if (this._canvas) {
+                this._scene.activeCamera.attachControl(this._canvas);
+            }
 
             this._btnVR = <HTMLButtonElement>document.createElement("BUTTON");
             this._btnVR.className = "babylonVRicon";
@@ -65,20 +67,24 @@ module BABYLON {
             style.appendChild(document.createTextNode(css));
             document.getElementsByTagName('head')[0].appendChild(style);  
 
-            this._btnVR.style.top = this._canvas.offsetTop + this._canvas.offsetHeight - 70 + "px";
-            this._btnVR.style.left = this._canvas.offsetLeft + this._canvas.offsetWidth - 100 + "px";
-            this._btnVR.addEventListener("click", () => {
-                this.enterVR();
-            });
-
-            window.addEventListener("resize", () => {
+            if (this._canvas) {
                 this._btnVR.style.top = this._canvas.offsetTop + this._canvas.offsetHeight - 70 + "px";
                 this._btnVR.style.left = this._canvas.offsetLeft + this._canvas.offsetWidth - 100 + "px";
+                this._btnVR.addEventListener("click", () => {
+                    this.enterVR();
+                });
+
+                window.addEventListener("resize", () => {
+                    if (this._canvas) {
+                        this._btnVR.style.top = this._canvas.offsetTop + this._canvas.offsetHeight - 70 + "px";
+                        this._btnVR.style.left = this._canvas.offsetLeft + this._canvas.offsetWidth - 100 + "px";
+                    }
 
-                if (this._fullscreenVRpresenting && this._webVRready) {
-                    this.exitVR();
-                }
-            });
+                    if (this._fullscreenVRpresenting && this._webVRready) {
+                        this.exitVR();
+                    }
+                });
+            }
 
             document.addEventListener("fullscreenchange", () => { this._onFullscreenChange() }, false);
             document.addEventListener("mozfullscreenchange", () => { this._onFullscreenChange() }, false);
@@ -146,7 +152,7 @@ module BABYLON {
             } else if (document.msIsFullScreen !== undefined) {
                 this._fullscreenVRpresenting = document.msIsFullScreen;
             }
-            if (!this._fullscreenVRpresenting) {
+            if (!this._fullscreenVRpresenting && this._canvas) {
                 this.exitVR();
                 this._btnVR.style.top = this._canvas.offsetTop + this._canvas.offsetHeight - 70 + "px";
                 this._btnVR.style.left = this._canvas.offsetLeft + this._canvas.offsetWidth - 100 + "px";
@@ -221,7 +227,9 @@ module BABYLON {
                 this.updateButtonVisibility();
             }
             
-            this._scene.activeCamera.attachControl(this._canvas);
+            if (this._scene.activeCamera && this._canvas) {
+                this._scene.activeCamera.attachControl(this._canvas);
+            }
         }
 
         /**
@@ -239,7 +247,10 @@ module BABYLON {
             }
             this._deviceOrientationCamera.position = this._position;
             this._scene.activeCamera = this._deviceOrientationCamera;
-            this._scene.activeCamera.attachControl(this._canvas);
+
+            if (this._canvas) {
+                this._scene.activeCamera.attachControl(this._canvas);
+            }
 
             this.updateButtonVisibility();
         }
@@ -250,7 +261,10 @@ module BABYLON {
 
         public set position(value: Vector3) {
             this._position = value;
-            this._scene.activeCamera.position = value;
+
+            if (this._scene.activeCamera) {
+                this._scene.activeCamera.position = value;
+            }
         }
 
         public dispose() {

+ 0 - 0
src/Cameras/VR/babylon.webVRCamera.ts


部分文件因为文件数量过多而无法显示