Explorar el Código

Merge remote-tracking branch 'BabylonJS/master' into viewer-testing

Raanan Weber hace 7 años
padre
commit
3b835302ba
Se han modificado 79 ficheros con 27724 adiciones y 20639 borrados
  1. 14438 12642
      Playground/babylon.d.txt
  2. 3 1
      Tools/Gulp/config.json
  3. 1 1
      Tools/Gulp/gulpfile.js
  4. 2 1
      Tools/Gulp/package.json
  5. 1 1
      dist/gui/readme.md
  6. 4157 3466
      dist/preview release/babylon.d.ts
  7. 42 42
      dist/preview release/babylon.js
  8. 972 348
      dist/preview release/babylon.max.js
  9. 972 348
      dist/preview release/babylon.no-module.max.js
  10. 42 42
      dist/preview release/babylon.worker.js
  11. 972 348
      dist/preview release/es6.js
  12. 4 0
      dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts
  13. 1 1
      dist/preview release/gltf2Interface/package.json
  14. 1 0
      dist/preview release/gui/babylon.gui.d.ts
  15. 10 0
      dist/preview release/gui/babylon.gui.js
  16. 4 4
      dist/preview release/gui/babylon.gui.min.js
  17. 1 0
      dist/preview release/gui/babylon.gui.module.d.ts
  18. 1 1
      dist/preview release/gui/package.json
  19. 11 11
      dist/preview release/inspector/babylon.inspector.css
  20. 1 1
      dist/preview release/inspector/package.json
  21. 168 6
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  22. 106 6
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  23. 341 9
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  24. 248 44
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  25. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  26. 361 9
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  27. 268 44
      dist/preview release/loaders/babylon.glTFFileLoader.js
  28. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  29. 361 9
      dist/preview release/loaders/babylonjs.loaders.d.ts
  30. 268 44
      dist/preview release/loaders/babylonjs.loaders.js
  31. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  32. 361 9
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  33. 2 2
      dist/preview release/loaders/package.json
  34. 1 1
      dist/preview release/materialsLibrary/package.json
  35. 1 1
      dist/preview release/postProcessesLibrary/package.json
  36. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  37. 2 2
      dist/preview release/serializers/package.json
  38. 819 2387
      dist/preview release/typedocValidationBaseline.json
  39. 50 50
      dist/preview release/viewer/babylon.viewer.js
  40. 1244 392
      dist/preview release/viewer/babylon.viewer.max.js
  41. 1 1
      dist/preview release/viewer/package.json
  42. 4 0
      dist/preview release/what's new.md
  43. 2 1
      gui/readme.md
  44. 15 0
      gui/src/advancedDynamicTexture.ts
  45. 1 1
      inspector/sass/defines.scss
  46. 20 0
      loaders/src/glTF/1.0/babylon.glTFLoader.ts
  47. 1 0
      loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts
  48. 173 45
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  49. 3 0
      loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts
  50. 60 0
      loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts
  51. 3 1
      loaders/src/glTF/2.0/babylon.glTFLoaderUtilities.ts
  52. 148 8
      loaders/src/glTF/babylon.glTFFileLoader.ts
  53. 2 2
      package.json
  54. 1 1
      src/Actions/babylon.actionManager.ts
  55. 544 40
      src/Animations/babylon.animation.ts
  56. 121 144
      src/Animations/babylon.runtimeAnimation.ts
  57. 32 19
      src/Bones/babylon.bone.ts
  58. 6 0
      src/Cameras/VR/babylon.vrExperienceHelper.ts
  59. 7 0
      src/Collisions/babylon.collisionCoordinator.ts
  60. 24 5
      src/Culling/babylon.boundingBox.ts
  61. 23 4
      src/Culling/babylon.boundingSphere.ts
  62. 1 1
      src/Engine/babylon.engine.ts
  63. 98 2
      src/Gamepad/babylon.xboxGamepad.ts
  64. 4 23
      src/Helpers/babylon.environmentHelper.ts
  65. 2 1
      src/Lights/babylon.spotLight.ts
  66. 10 33
      src/Materials/Background/babylon.backgroundMaterial.ts
  67. 1 1
      src/Materials/babylon.materialHelper.ts
  68. 18 1
      src/Materials/babylon.standardMaterial.ts
  69. 15 0
      src/Math/babylon.math.ts
  70. 9 4
      src/Mesh/babylon.abstractMesh.ts
  71. 9 1
      src/Mesh/babylon.mesh.ts
  72. 3 2
      src/Mesh/babylon.meshSimplification.ts
  73. 8 4
      src/Physics/babylon.physicsHelper.ts
  74. 21 1
      src/PostProcess/babylon.tonemapPostProcess.ts
  75. 0 3
      src/Shaders/ShadersInclude/lightsFragmentFunctions.fx
  76. 7 0
      src/Shaders/ShadersInclude/pbrLightFunctions.fx
  77. 5 1
      src/Shaders/default.fragment.fx
  78. 44 2
      src/Tools/babylon.virtualJoystick.ts
  79. 34 7
      tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 14438 - 12642
Playground/babylon.d.txt


+ 3 - 1
Tools/Gulp/config.json

@@ -11,7 +11,9 @@
         "intellisenseFile": "babylon.d.txt",
         "intellisenseSources": [
             "../../dist/preview release/babylon.d.ts",
-            "../../dist/preview release/gui/babylon.gui.d.ts"
+            "../../dist/preview release/gui/babylon.gui.d.ts",
+            "../../dist/preview release/loaders/babylon.glTF2FileLoader.d.ts",
+            "../../dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts"
         ],
         "outputCustomConfigurationsDirectory": "../../dist/preview release/customConfigurations",
         "srcOutputDirectory": "../../src/",

+ 1 - 1
Tools/Gulp/gulpfile.js

@@ -884,7 +884,7 @@ gulp.task("modules", ["prepare-dependency-tree"], function () {
  */
 gulp.task("typedoc-generate", function () {
     return gulp
-        .src(["../../dist/preview release/babylon.d.ts"])
+        .src(["../../dist/preview release/babylon.d.ts", "../../dist/preview release/loaders/babylon.glTF2FileLoader.d.ts", "../../dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts"])
         .pipe(typedoc({
             // TypeScript options (see typescript docs)
             mode: "modules",

+ 2 - 1
Tools/Gulp/package.json

@@ -65,6 +65,7 @@
     },
     "dependencies": {
         "dts-bundle": "^0.7.3",
-        "gulp-clean": "^0.4.0"
+        "gulp-clean": "^0.4.0",
+        "npm": "^5.8.0"
     }
 }

+ 1 - 1
dist/gui/readme.md

@@ -1,7 +1,7 @@
 Babylon.js GUI module
 =====================
 
-For usage documentation please visit http://doc.babylonjs.com/overviews/gui
+For usage documentation please visit http://doc.babylonjs.com/how_to/gui
 
 # Installation instructions
 

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 4157 - 3466
dist/preview release/babylon.d.ts


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 42 - 42
dist/preview release/babylon.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 972 - 348
dist/preview release/babylon.max.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 972 - 348
dist/preview release/babylon.no-module.max.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 42 - 42
dist/preview release/babylon.worker.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 972 - 348
dist/preview release/es6.js


+ 4 - 0
dist/preview release/gltf2Interface/babylon.glTF2Interface.d.ts

@@ -1,3 +1,7 @@
+/**
+ * @ignoreChildren
+ * @ignore
+ */
 declare module BABYLON.GLTF2 {
     const enum AccessorComponentType {
         BYTE = 5120,

+ 1 - 1
dist/preview release/gltf2Interface/package.json

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 0
dist/preview release/gui/babylon.gui.d.ts

@@ -55,6 +55,7 @@ declare module BABYLON.GUI {
         dispose(): void;
         private _onResize();
         _getGlobalViewport(scene: Scene): Viewport;
+        getProjectedPosition(position: Vector3, worldMatrix: Matrix): Vector2;
         private _checkUpdate(camera);
         private _render();
         private _doPicking(x, y, type, pointerId, buttonIndex);

+ 10 - 0
dist/preview release/gui/babylon.gui.js

@@ -303,6 +303,16 @@ var BABYLON;
                 var engine = scene.getEngine();
                 return this._fullscreenViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
             };
+            AdvancedDynamicTexture.prototype.getProjectedPosition = function (position, worldMatrix) {
+                var scene = this.getScene();
+                if (!scene) {
+                    return BABYLON.Vector2.Zero();
+                }
+                var globalViewport = this._getGlobalViewport(scene);
+                var projectedPosition = BABYLON.Vector3.Project(position, worldMatrix, scene.getTransformMatrix(), globalViewport);
+                projectedPosition.scaleInPlace(this.renderScale);
+                return new BABYLON.Vector2(projectedPosition.x, projectedPosition.y);
+            };
             AdvancedDynamicTexture.prototype._checkUpdate = function (camera) {
                 if (this._layerToDispose) {
                     if ((camera.layerMask & this._layerToDispose.layerMask) === 0) {

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 4 - 4
dist/preview release/gui/babylon.gui.min.js


+ 1 - 0
dist/preview release/gui/babylon.gui.module.d.ts

@@ -60,6 +60,7 @@ declare module BABYLON.GUI {
         dispose(): void;
         private _onResize();
         _getGlobalViewport(scene: Scene): Viewport;
+        getProjectedPosition(position: Vector3, worldMatrix: Matrix): Vector2;
         private _checkUpdate(camera);
         private _render();
         private _doPicking(x, y, type, pointerId, buttonIndex);

+ 1 - 1
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 11 - 11
dist/preview release/inspector/babylon.inspector.css

@@ -44,11 +44,11 @@
       font-size: 1em; }
       .insp-wrapper .insp-right-panel .top-panel .tab-panel-content {
         width: 100%;
-        height: calc(100% - 32px); }
+        height: calc(100% - 40px); }
       .insp-wrapper .insp-right-panel .top-panel .more-tabs-panel {
         position: absolute;
         z-index: 10;
-        top: 32px;
+        top: 40px;
         right: 0;
         width: 100px;
         display: none;
@@ -70,7 +70,7 @@
             background-color: #454545; }
   .insp-wrapper .tooltip {
     position: absolute;
-    top: 32px;
+    top: 40px;
     right: 0;
     color: #f29766;
     display: none;
@@ -249,7 +249,7 @@
   .insp-wrapper .insp-tree {
     overflow-y: auto;
     overflow-x: hidden;
-    height: calc(50% - 32px - 30px); }
+    height: calc(50% - 40px - 30px); }
     .insp-wrapper .insp-tree .line {
       padding: 3px;
       cursor: pointer; }
@@ -368,7 +368,7 @@
           max-width: 110px;
           max-height: 110px; }
   .insp-wrapper .tabbar {
-    height: 32px;
+    height: 40px;
     display: flex;
     align-items: center;
     border-bottom: 1px solid #383838;
@@ -377,11 +377,11 @@
     overflow-y: hidden;
     box-sizing: border-box; }
     .insp-wrapper .tabbar .tab {
-      height: calc(32px - 2px);
+      height: calc(40px - 2px);
       width: auto;
       padding: 0 10px 0 10px;
       color: #ccc;
-      line-height: 32px;
+      line-height: 40px;
       text-align: center;
       cursor: pointer;
       margin: 0 5px 0 5px;
@@ -394,8 +394,8 @@
       .insp-wrapper .tabbar .tab.active {
         border-bottom: 1px solid #f29766; }
     .insp-wrapper .tabbar .more-tabs {
-      width: 32px;
-      height: 32px;
+      width: 40px;
+      height: 40px;
       display: flex;
       justify-content: center;
       align-items: center;
@@ -412,8 +412,8 @@
   .insp-wrapper .toolbar {
     display: flex; }
     .insp-wrapper .toolbar .tool {
-      width: 32px;
-      height: 32px;
+      width: 40px;
+      height: 40px;
       display: flex;
       justify-content: center;
       align-items: center;

+ 1 - 1
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -1,5 +1,8 @@
 
 declare module BABYLON {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     enum GLTFLoaderCoordinateSystemMode {
         /**
          * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
@@ -10,6 +13,9 @@ declare module BABYLON {
          */
         FORCE_RIGHT_HANDED = 1,
     }
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     enum GLTFLoaderAnimationStartMode {
         /**
          * No animation will start.
@@ -24,10 +30,22 @@ declare module BABYLON {
          */
         ALL = 2,
     }
+    /**
+    * Loaded gltf data
+    */
     interface IGLTFLoaderData {
+        /**
+        * Loaded json string converted to an object
+        */
         json: Object;
+        /**
+        * Loaded ArrayBufferView
+        */
         bin: Nullable<ArrayBufferView>;
     }
+    /**
+    * Gltf extension interface
+    */
     interface IGLTFLoaderExtension {
         /**
          * The name of this extension.
@@ -38,6 +56,9 @@ declare module BABYLON {
          */
         enabled: boolean;
     }
+    /**
+    * Loading state
+    */
     enum GLTFLoaderState {
         /**
          * The asset is loading.
@@ -52,29 +73,77 @@ declare module BABYLON {
          */
         COMPLETE = 2,
     }
+    /**
+    * GLTF loader interface
+    */
     interface IGLTFLoader extends IDisposable {
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+       * Observable that fires each time a material is loaded
+       */
         onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires when the load has completed
+        */
         onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fire when an extension is loaded
+        */
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Loader state
+        */
         state: Nullable<GLTFLoaderState>;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        */
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        */
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<void>;
     }
+    /** File loader to load gltf files into a babylon scene */
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
+        /** Creates a gltf 1.0 file loader */
         static CreateGLTFLoaderV1: () => IGLTFLoader;
+        /** Creates a gltf 2.0 file loader */
         static CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed.
@@ -83,27 +152,39 @@ declare module BABYLON {
          */
         onParsedObservable: Observable<IGLTFLoaderData>;
         private _onParsedObserver;
+        /** Raised when the asset has been parsed. */
         onParsed: (loaderData: IGLTFLoaderData) => void;
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         static IncrementalLoading: boolean;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         static HomogeneousCoordinates: boolean;
         /**
-         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+         * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+         * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
          */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         /**
-         * The animation start mode (NONE, FIRST, ALL).
-         */
+        * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+        * - NONE - No animation will start.
+        * - FIRST - The first animation will start.
+        * - ALL - All animations will start.
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
         /**
-         * Set to true to compile materials before raising the success callback.
+         * Set to true to compile materials before raising the success callback. Defaults to false.
          */
         compileMaterials: boolean;
         /**
-         * Set to true to also compile materials with clip planes.
+         * Set to true to also compile materials with clip planes. Defaults to false.
          */
         useClipPlane: boolean;
         /**
-         * Set to true to compile shadow generators before raising the success callback.
+         * Set to true to compile shadow generators before raising the success callback. Defaults to false.
          */
         compileShadowGenerators: boolean;
         /**
@@ -111,18 +192,27 @@ declare module BABYLON {
          */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         private _onMeshLoadedObserver;
+        /**
+         * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+         */
         onMeshLoaded: (mesh: AbstractMesh) => void;
         /**
          * Raised when the loader creates a texture after parsing the glTF properties of the texture.
          */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         private _onTextureLoadedObserver;
+        /**
+         * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+         */
         onTextureLoaded: (texture: BaseTexture) => void;
         /**
          * Raised when the loader creates a material after parsing the glTF properties of the material.
          */
         readonly onMaterialLoadedObservable: Observable<Material>;
         private _onMaterialLoadedObserver;
+        /**
+         * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+         */
         onMaterialLoaded: (material: Material) => void;
         /**
          * Raised when the asset is completely loaded, immediately before the loader is disposed.
@@ -131,12 +221,18 @@ declare module BABYLON {
          */
         readonly onCompleteObservable: Observable<GLTFFileLoader>;
         private _onCompleteObserver;
+        /**
+         * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+         */
         onComplete: () => void;
         /**
         * Raised after the loader is disposed.
         */
         readonly onDisposeObservable: Observable<GLTFFileLoader>;
         private _onDisposeObserver;
+        /**
+         * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+         */
         onDispose: () => void;
         /**
          * Raised after a loader extension is created.
@@ -144,6 +240,9 @@ declare module BABYLON {
          */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         private _onExtensionLoadedObserver;
+        /**
+         * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+         */
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
          * Returns a promise that resolves when the asset is completely loaded.
@@ -155,22 +254,65 @@ declare module BABYLON {
          */
         readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
+        /**
+         * Name of the loader ("gltf")
+         */
         name: string;
+        /**
+         * Supported file extensions of the loader (.gltf, .glb)
+         */
         extensions: ISceneLoaderPluginExtensions;
         /**
          * Disposes the loader, releases resources during load, and cancels any outstanding requests.
          */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         loadAssetContainerAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<AssetContainer>;
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         canDirectLoad(data: string): boolean;
+        /**
+         * Rewrites a url by combining a root url and response url
+         */
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
         private _parse(data);
         private _getLoader(loaderData);
@@ -587,9 +729,21 @@ declare module BABYLON.GLTF1 {
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * State of the loader
+        */
         state: Nullable<GLTFLoaderState>;
         dispose(): void;
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress?, onError?);
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
@@ -597,6 +751,14 @@ declare module BABYLON.GLTF1 {
             animationGroups: AnimationGroup[];
         }>;
         private _loadAsync(scene, data, rootUrl, onSuccess, onProgress?, onError?);
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
         private _loadShadersAsync(gltfRuntime, onload);
         private _loadBuffersAsync(gltfRuntime, onLoad, onProgress?);

+ 106 - 6
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -1,6 +1,9 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     var GLTFLoaderCoordinateSystemMode;
     (function (GLTFLoaderCoordinateSystemMode) {
         /**
@@ -12,6 +15,9 @@ var BABYLON;
          */
         GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 1] = "FORCE_RIGHT_HANDED";
     })(GLTFLoaderCoordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode || (BABYLON.GLTFLoaderCoordinateSystemMode = {}));
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     var GLTFLoaderAnimationStartMode;
     (function (GLTFLoaderAnimationStartMode) {
         /**
@@ -27,6 +33,9 @@ var BABYLON;
          */
         GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["ALL"] = 2] = "ALL";
     })(GLTFLoaderAnimationStartMode = BABYLON.GLTFLoaderAnimationStartMode || (BABYLON.GLTFLoaderAnimationStartMode = {}));
+    /**
+    * Loading state
+    */
     var GLTFLoaderState;
     (function (GLTFLoaderState) {
         /**
@@ -42,6 +51,7 @@ var BABYLON;
          */
         GLTFLoaderState[GLTFLoaderState["COMPLETE"] = 2] = "COMPLETE";
     })(GLTFLoaderState = BABYLON.GLTFLoaderState || (BABYLON.GLTFLoaderState = {}));
+    /** File loader to load gltf files into a babylon scene */
     var GLTFFileLoader = /** @class */ (function () {
         function GLTFFileLoader() {
             // #region Common options
@@ -54,23 +64,28 @@ var BABYLON;
             // #endregion
             // #region V2 options
             /**
-             * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+             * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+             * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+             * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
              */
             this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
             /**
-             * The animation start mode (NONE, FIRST, ALL).
-             */
+            * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+            * - NONE - No animation will start.
+            * - FIRST - The first animation will start.
+            * - ALL - All animations will start.
+            */
             this.animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
             /**
-             * Set to true to compile materials before raising the success callback.
+             * Set to true to compile materials before raising the success callback. Defaults to false.
              */
             this.compileMaterials = false;
             /**
-             * Set to true to also compile materials with clip planes.
+             * Set to true to also compile materials with clip planes. Defaults to false.
              */
             this.useClipPlane = false;
             /**
-             * Set to true to compile shadow generators before raising the success callback.
+             * Set to true to compile shadow generators before raising the success callback. Defaults to false.
              */
             this.compileShadowGenerators = false;
             /**
@@ -102,13 +117,20 @@ var BABYLON;
             this.onExtensionLoadedObservable = new BABYLON.Observable();
             // #endregion
             this._loader = null;
+            /**
+             * Name of the loader ("gltf")
+             */
             this.name = "gltf";
+            /**
+             * Supported file extensions of the loader (.gltf, .glb)
+             */
             this.extensions = {
                 ".gltf": { isBinary: false },
                 ".glb": { isBinary: true }
             };
         }
         Object.defineProperty(GLTFFileLoader.prototype, "onParsed", {
+            /** Raised when the asset has been parsed. */
             set: function (callback) {
                 if (this._onParsedObserver) {
                     this.onParsedObservable.remove(this._onParsedObserver);
@@ -119,6 +141,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
+            /**
+             * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onMeshLoadedObserver) {
                     this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver);
@@ -129,6 +154,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", {
+            /**
+             * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onTextureLoadedObserver) {
                     this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver);
@@ -139,6 +167,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", {
+            /**
+             * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onMaterialLoadedObserver) {
                     this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver);
@@ -149,6 +180,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
+            /**
+             * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onCompleteObserver) {
                     this.onCompleteObservable.remove(this._onCompleteObserver);
@@ -159,6 +193,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
+            /**
+             * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onDisposeObserver) {
                     this.onDisposeObservable.remove(this._onDisposeObserver);
@@ -169,6 +206,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
+            /**
+             * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onExtensionLoadedObserver) {
                     this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
@@ -214,6 +254,15 @@ var BABYLON;
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
         };
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -222,6 +271,14 @@ var BABYLON;
                 return _this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onProgress);
             });
         };
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -230,6 +287,14 @@ var BABYLON;
                 return _this._loader.loadAsync(scene, loaderData, rootUrl, onProgress);
             });
         };
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         GLTFFileLoader.prototype.loadAssetContainerAsync = function (scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -246,9 +311,18 @@ var BABYLON;
                 });
             });
         };
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         };
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         GLTFFileLoader.prototype.createPlugin = function () {
             return new GLTFFileLoader();
         };
@@ -432,7 +506,13 @@ var BABYLON;
         };
         // #endregion
         // #region V1 options
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         GLTFFileLoader.IncrementalLoading = true;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         GLTFFileLoader.HomogeneousCoordinates = false;
         return GLTFFileLoader;
     }());
@@ -1869,6 +1949,9 @@ var BABYLON;
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onExtensionLoadedObservable = new BABYLON.Observable();
+                /**
+                * State of the loader
+                */
                 this.state = null;
             }
             GLTFLoader.RegisterExtension = function (extension) {
@@ -1931,6 +2014,15 @@ var BABYLON;
                 }, onError);
                 return true;
             };
+            /**
+            * Imports one or more meshes from a loaded gltf file and adds them to the scene
+            * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+            * @param scene the scene the meshes should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise containg the loaded meshes, particles, skeletons and animations
+            */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return new Promise(function (resolve, reject) {
@@ -1970,6 +2062,14 @@ var BABYLON;
                     }, onError);
                 }, onError);
             };
+            /**
+            * Imports all objects from a loaded gltf file and adds them to the scene
+            * @param scene the scene the objects should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise which completes when objects have been loaded to the scene
+            */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return new Promise(function (resolve, reject) {

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

@@ -1,5 +1,8 @@
 
 declare module BABYLON {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     enum GLTFLoaderCoordinateSystemMode {
         /**
          * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
@@ -10,6 +13,9 @@ declare module BABYLON {
          */
         FORCE_RIGHT_HANDED = 1,
     }
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     enum GLTFLoaderAnimationStartMode {
         /**
          * No animation will start.
@@ -24,10 +30,22 @@ declare module BABYLON {
          */
         ALL = 2,
     }
+    /**
+    * Loaded gltf data
+    */
     interface IGLTFLoaderData {
+        /**
+        * Loaded json string converted to an object
+        */
         json: Object;
+        /**
+        * Loaded ArrayBufferView
+        */
         bin: Nullable<ArrayBufferView>;
     }
+    /**
+    * Gltf extension interface
+    */
     interface IGLTFLoaderExtension {
         /**
          * The name of this extension.
@@ -38,6 +56,9 @@ declare module BABYLON {
          */
         enabled: boolean;
     }
+    /**
+    * Loading state
+    */
     enum GLTFLoaderState {
         /**
          * The asset is loading.
@@ -52,29 +73,77 @@ declare module BABYLON {
          */
         COMPLETE = 2,
     }
+    /**
+    * GLTF loader interface
+    */
     interface IGLTFLoader extends IDisposable {
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+       * Observable that fires each time a material is loaded
+       */
         onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires when the load has completed
+        */
         onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fire when an extension is loaded
+        */
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Loader state
+        */
         state: Nullable<GLTFLoaderState>;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        */
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        */
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<void>;
     }
+    /** File loader to load gltf files into a babylon scene */
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
+        /** Creates a gltf 1.0 file loader */
         static CreateGLTFLoaderV1: () => IGLTFLoader;
+        /** Creates a gltf 2.0 file loader */
         static CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed.
@@ -83,27 +152,39 @@ declare module BABYLON {
          */
         onParsedObservable: Observable<IGLTFLoaderData>;
         private _onParsedObserver;
+        /** Raised when the asset has been parsed. */
         onParsed: (loaderData: IGLTFLoaderData) => void;
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         static IncrementalLoading: boolean;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         static HomogeneousCoordinates: boolean;
         /**
-         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+         * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+         * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
          */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         /**
-         * The animation start mode (NONE, FIRST, ALL).
-         */
+        * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+        * - NONE - No animation will start.
+        * - FIRST - The first animation will start.
+        * - ALL - All animations will start.
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
         /**
-         * Set to true to compile materials before raising the success callback.
+         * Set to true to compile materials before raising the success callback. Defaults to false.
          */
         compileMaterials: boolean;
         /**
-         * Set to true to also compile materials with clip planes.
+         * Set to true to also compile materials with clip planes. Defaults to false.
          */
         useClipPlane: boolean;
         /**
-         * Set to true to compile shadow generators before raising the success callback.
+         * Set to true to compile shadow generators before raising the success callback. Defaults to false.
          */
         compileShadowGenerators: boolean;
         /**
@@ -111,18 +192,27 @@ declare module BABYLON {
          */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         private _onMeshLoadedObserver;
+        /**
+         * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+         */
         onMeshLoaded: (mesh: AbstractMesh) => void;
         /**
          * Raised when the loader creates a texture after parsing the glTF properties of the texture.
          */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         private _onTextureLoadedObserver;
+        /**
+         * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+         */
         onTextureLoaded: (texture: BaseTexture) => void;
         /**
          * Raised when the loader creates a material after parsing the glTF properties of the material.
          */
         readonly onMaterialLoadedObservable: Observable<Material>;
         private _onMaterialLoadedObserver;
+        /**
+         * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+         */
         onMaterialLoaded: (material: Material) => void;
         /**
          * Raised when the asset is completely loaded, immediately before the loader is disposed.
@@ -131,12 +221,18 @@ declare module BABYLON {
          */
         readonly onCompleteObservable: Observable<GLTFFileLoader>;
         private _onCompleteObserver;
+        /**
+         * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+         */
         onComplete: () => void;
         /**
         * Raised after the loader is disposed.
         */
         readonly onDisposeObservable: Observable<GLTFFileLoader>;
         private _onDisposeObserver;
+        /**
+         * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+         */
         onDispose: () => void;
         /**
          * Raised after a loader extension is created.
@@ -144,6 +240,9 @@ declare module BABYLON {
          */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         private _onExtensionLoadedObserver;
+        /**
+         * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+         */
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
          * Returns a promise that resolves when the asset is completely loaded.
@@ -155,22 +254,65 @@ declare module BABYLON {
          */
         readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
+        /**
+         * Name of the loader ("gltf")
+         */
         name: string;
+        /**
+         * Supported file extensions of the loader (.gltf, .glb)
+         */
         extensions: ISceneLoaderPluginExtensions;
         /**
          * Disposes the loader, releases resources during load, and cancels any outstanding requests.
          */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         loadAssetContainerAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<AssetContainer>;
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         canDirectLoad(data: string): boolean;
+        /**
+         * Rewrites a url by combining a root url and response url
+         */
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
         private _parse(data);
         private _getLoader(loaderData);
@@ -185,48 +327,84 @@ declare module BABYLON {
 
 
 declare module BABYLON.GLTF2 {
+    /** Array item which contains it's index in an array */
     interface IArrayItem {
         _index: number;
     }
+    /** Array item helper methods */
     class ArrayItem {
+        /** Sets the index of each array element to its index in the array */
         static Assign(values?: IArrayItem[]): void;
     }
 }
 
 
 
+/**
+ * GLTF2 module for babylon
+ */
 declare module BABYLON.GLTF2 {
+    /**
+     * Interface to access data and vertex buffer associated with a file
+     */
     interface ILoaderAccessor extends IAccessor, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
+    /**
+     * Loader's animation channel
+     */
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
+    /**
+     * Container for animation keyframe data
+     */
     interface ILoaderAnimationSamplerData {
         input: Float32Array;
         interpolation: AnimationSamplerInterpolation;
         output: Float32Array;
     }
+    /**
+     * Keyframe data
+     */
     interface ILoaderAnimationSampler extends IAnimationSampler, IArrayItem {
         _data: Promise<ILoaderAnimationSamplerData>;
     }
+    /**
+     * Loader animation
+     */
     interface ILoaderAnimation extends IAnimation, IArrayItem {
         channels: ILoaderAnimationChannel[];
         samplers: ILoaderAnimationSampler[];
         _babylonAnimationGroup?: AnimationGroup;
     }
+    /**
+     * Loader buffer
+     */
     interface ILoaderBuffer extends IBuffer, IArrayItem {
         _data?: Promise<ArrayBufferView>;
     }
+    /**
+     * Loader's buffer data
+     */
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonBuffer?: Promise<Buffer>;
     }
+    /**
+     * Loader's loaded camera data
+     */
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
+    /**
+     * Loaded image specified by url
+     */
     interface ILoaderImage extends IImage, IArrayItem {
         _objectURL?: Promise<string>;
     }
+    /**
+     * Loaded material data
+     */
     interface ILoaderMaterial extends IMaterial, IArrayItem {
         _babylonData?: {
             [drawMode: number]: {
@@ -236,11 +414,20 @@ declare module BABYLON.GLTF2 {
             };
         };
     }
+    /**
+     * Loader mesh data
+     */
     interface ILoaderMesh extends IMesh, IArrayItem {
         primitives: ILoaderMeshPrimitive[];
     }
+    /**
+     * Loader mesh data
+     */
     interface ILoaderMeshPrimitive extends IMeshPrimitive, IArrayItem {
     }
+    /**
+     * Node for traversing loader data
+     */
     interface ILoaderNode extends INode, IArrayItem {
         _parent: ILoaderNode;
         _babylonMesh?: Mesh;
@@ -248,23 +435,41 @@ declare module BABYLON.GLTF2 {
         _babylonAnimationTargets?: Node[];
         _numMorphTargets?: number;
     }
+    /**
+     * Sampler data
+     */
     interface ILoaderSamplerData {
         noMipMaps: boolean;
         samplingMode: number;
         wrapU: number;
         wrapV: number;
     }
+    /**
+     * Sampler data
+     */
     interface ILoaderSampler extends ISampler, IArrayItem {
         _data?: ILoaderSamplerData;
     }
+    /**
+     * Loader's scene
+     */
     interface ILoaderScene extends IScene, IArrayItem {
     }
+    /**
+     * Loader's skeleton data
+     */
     interface ILoaderSkin extends ISkin, IArrayItem {
         _babylonSkeleton?: Skeleton;
         _loaded?: Promise<void>;
     }
+    /**
+     * Loader's texture
+     */
     interface ILoaderTexture extends ITexture, IArrayItem {
     }
+    /**
+     * Loaded GLTF data
+     */
     interface ILoaderGLTF extends IGLTF {
         accessors?: ILoaderAccessor[];
         animations?: ILoaderAnimation[];
@@ -283,14 +488,40 @@ declare module BABYLON.GLTF2 {
 }
 
 
+/**
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
+*/
 declare module BABYLON.GLTF2 {
+    /**
+    * Interface for a meterial with a constructor
+    */
     interface MaterialConstructor<T extends Material> {
+        /**
+        * The material class
+        */
         readonly prototype: T;
+        /**
+        * Instatiates a material
+        * @param name name of the material
+        * @param scene the scene the material will be added to
+        */
         new (name: string, scene: Scene): T;
     }
+    /**
+    * Used to load from a GLTF2 file
+    */
     class GLTFLoader implements IGLTFLoader {
+        /**
+        * @ignore
+        */
         _gltf: ILoaderGLTF;
+        /**
+        * @ignore
+        */
         _babylonScene: Scene;
+        /**
+        * @ignore
+        */
         _completePromises: Promise<void>[];
         private _disposed;
         private _state;
@@ -303,26 +534,87 @@ declare module BABYLON.GLTF2 {
         private _requests;
         private static _Names;
         private static _Factories;
+        /**
+        * @ignore, registers the loader
+        * @param name name of the loader
+        * @param factory function that converts a loader to a loader extension
+        */
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         readonly onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+        * Observable that fires each time a material is loaded
+        */
         readonly onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires each time an extension is loaded
+        */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Observable that fires when the load has completed
+        */
         readonly onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * The current state of the loader
+        */
         readonly state: Nullable<GLTFLoaderState>;
+        /**
+        * Disposes of the loader
+        */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
         private _loadAsync(nodes, scene, data, rootUrl, onProgress?);
         private _loadExtensions();
@@ -331,12 +623,18 @@ declare module BABYLON.GLTF2 {
         private _checkExtensions();
         private _createRootNode();
         private _loadNodesAsync(nodes);
+        /**
+        * @ignore
+        */
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
         private _forEachPrimitive(node, callback);
         private _getMeshes();
         private _getSkeletons();
         private _getAnimationGroups();
         private _startAnimations();
+        /**
+        * @ignore
+        */
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
         private _loadMeshAsync(context, node, mesh, babylonMesh);
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
@@ -346,31 +644,58 @@ declare module BABYLON.GLTF2 {
         private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
+        private _loadBones(context, skin);
+        private _loadBone(node, skin, babylonBones);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
-        private _createBone(node, skin, parent, localMatrix, baseMatrix, index);
-        private _loadBones(context, skin, inverseBindMatricesData);
-        private _loadBone(node, skin, inverseBindMatricesData, babylonBones);
+        private _updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
         private _getNodeMatrix(node);
         private _loadAnimationsAsync();
         private _loadAnimationAsync(context, animation);
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadBufferAsync(context, buffer);
+        /**
+        * @ignore
+        */
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
+        /**
+        * @ignore
+        */
         _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
         private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
+        /**
+        * @ignore
+        */
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
+        /**
+        * @ignore
+        */
         _createMaterial<T extends Material>(type: MaterialConstructor<T>, name: string, drawMode: number): T;
+        /**
+        * @ignore
+        */
         _loadMaterialBasePropertiesAsync(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void>;
+        /**
+        * @ignore
+        */
         _loadMaterialAlphaProperties(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): void;
+        /**
+        * @ignore
+        */
         _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Promise<void>;
         private _loadSampler(context, sampler);
         private _loadImageAsync(context, image);
+        /**
+        * @ignore
+        */
         _loadUriAsync(context: string, uri: string): Promise<ArrayBufferView>;
         private _onProgress();
+        /**
+        * @ignore
+        */
         static _GetProperty<T>(context: string, array: ArrayLike<T> | undefined, index: number | undefined): T;
         private static _GetTextureWrapMode(context, mode);
         private static _GetTextureSamplingMode(context, magFilter?, minFilter?);
@@ -380,12 +705,18 @@ declare module BABYLON.GLTF2 {
         private _compileMaterialsAsync();
         private _compileShadowGeneratorsAsync();
         private _clear();
+        /**
+        * @ignore
+        */
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
     }
 }
 
 
 declare module BABYLON.GLTF2 {
+    /**
+     * Abstract class that can be implemented to extend existing gltf loader behavior.
+     */
     abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
         enabled: boolean;
         readonly abstract name: string;
@@ -440,6 +771,7 @@ declare module BABYLON.GLTF2.Extensions {
 }
 
 
+/** Module defining extensions to gltf */
 declare module BABYLON.GLTF2.Extensions {
     class KHR_draco_mesh_compression extends GLTFLoaderExtension {
         readonly name: string;

+ 248 - 44
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -1,6 +1,9 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     var GLTFLoaderCoordinateSystemMode;
     (function (GLTFLoaderCoordinateSystemMode) {
         /**
@@ -12,6 +15,9 @@ var BABYLON;
          */
         GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 1] = "FORCE_RIGHT_HANDED";
     })(GLTFLoaderCoordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode || (BABYLON.GLTFLoaderCoordinateSystemMode = {}));
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     var GLTFLoaderAnimationStartMode;
     (function (GLTFLoaderAnimationStartMode) {
         /**
@@ -27,6 +33,9 @@ var BABYLON;
          */
         GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["ALL"] = 2] = "ALL";
     })(GLTFLoaderAnimationStartMode = BABYLON.GLTFLoaderAnimationStartMode || (BABYLON.GLTFLoaderAnimationStartMode = {}));
+    /**
+    * Loading state
+    */
     var GLTFLoaderState;
     (function (GLTFLoaderState) {
         /**
@@ -42,6 +51,7 @@ var BABYLON;
          */
         GLTFLoaderState[GLTFLoaderState["COMPLETE"] = 2] = "COMPLETE";
     })(GLTFLoaderState = BABYLON.GLTFLoaderState || (BABYLON.GLTFLoaderState = {}));
+    /** File loader to load gltf files into a babylon scene */
     var GLTFFileLoader = /** @class */ (function () {
         function GLTFFileLoader() {
             // #region Common options
@@ -54,23 +64,28 @@ var BABYLON;
             // #endregion
             // #region V2 options
             /**
-             * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+             * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+             * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+             * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
              */
             this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
             /**
-             * The animation start mode (NONE, FIRST, ALL).
-             */
+            * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+            * - NONE - No animation will start.
+            * - FIRST - The first animation will start.
+            * - ALL - All animations will start.
+            */
             this.animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
             /**
-             * Set to true to compile materials before raising the success callback.
+             * Set to true to compile materials before raising the success callback. Defaults to false.
              */
             this.compileMaterials = false;
             /**
-             * Set to true to also compile materials with clip planes.
+             * Set to true to also compile materials with clip planes. Defaults to false.
              */
             this.useClipPlane = false;
             /**
-             * Set to true to compile shadow generators before raising the success callback.
+             * Set to true to compile shadow generators before raising the success callback. Defaults to false.
              */
             this.compileShadowGenerators = false;
             /**
@@ -102,13 +117,20 @@ var BABYLON;
             this.onExtensionLoadedObservable = new BABYLON.Observable();
             // #endregion
             this._loader = null;
+            /**
+             * Name of the loader ("gltf")
+             */
             this.name = "gltf";
+            /**
+             * Supported file extensions of the loader (.gltf, .glb)
+             */
             this.extensions = {
                 ".gltf": { isBinary: false },
                 ".glb": { isBinary: true }
             };
         }
         Object.defineProperty(GLTFFileLoader.prototype, "onParsed", {
+            /** Raised when the asset has been parsed. */
             set: function (callback) {
                 if (this._onParsedObserver) {
                     this.onParsedObservable.remove(this._onParsedObserver);
@@ -119,6 +141,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
+            /**
+             * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onMeshLoadedObserver) {
                     this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver);
@@ -129,6 +154,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", {
+            /**
+             * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onTextureLoadedObserver) {
                     this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver);
@@ -139,6 +167,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", {
+            /**
+             * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onMaterialLoadedObserver) {
                     this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver);
@@ -149,6 +180,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
+            /**
+             * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onCompleteObserver) {
                     this.onCompleteObservable.remove(this._onCompleteObserver);
@@ -159,6 +193,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
+            /**
+             * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onDisposeObserver) {
                     this.onDisposeObservable.remove(this._onDisposeObserver);
@@ -169,6 +206,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
+            /**
+             * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onExtensionLoadedObserver) {
                     this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
@@ -214,6 +254,15 @@ var BABYLON;
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
         };
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -222,6 +271,14 @@ var BABYLON;
                 return _this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onProgress);
             });
         };
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -230,6 +287,14 @@ var BABYLON;
                 return _this._loader.loadAsync(scene, loaderData, rootUrl, onProgress);
             });
         };
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         GLTFFileLoader.prototype.loadAssetContainerAsync = function (scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -246,9 +311,18 @@ var BABYLON;
                 });
             });
         };
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         };
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         GLTFFileLoader.prototype.createPlugin = function () {
             return new GLTFFileLoader();
         };
@@ -432,7 +506,13 @@ var BABYLON;
         };
         // #endregion
         // #region V1 options
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         GLTFFileLoader.IncrementalLoading = true;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         GLTFFileLoader.HomogeneousCoordinates = false;
         return GLTFFileLoader;
     }());
@@ -476,9 +556,11 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /** Array item helper methods */
         var ArrayItem = /** @class */ (function () {
             function ArrayItem() {
             }
+            /** Sets the index of each array element to its index in the array */
             ArrayItem.Assign = function (values) {
                 if (values) {
                     for (var index = 0; index < values.length; index++) {
@@ -500,12 +582,21 @@ var BABYLON;
 //# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
 
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+/**
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
+*/
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /**
+        * Used to load from a GLTF2 file
+        */
         var GLTFLoader = /** @class */ (function () {
             function GLTFLoader() {
+                /**
+                * @ignore
+                */
                 this._completePromises = new Array();
                 this._disposed = false;
                 this._state = null;
@@ -513,18 +604,56 @@ var BABYLON;
                 this._defaultSampler = {};
                 this._defaultBabylonMaterials = {};
                 this._requests = new Array();
+                /**
+                * Coordinate system that will be used when loading from the gltf file
+                */
                 this.coordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode.AUTO;
+                /**
+                * Animation mode that determines which animations should be started when a file is loaded
+                */
                 this.animationStartMode = BABYLON.GLTFLoaderAnimationStartMode.FIRST;
+                /**
+                * If the materials in the file should automatically be compiled
+                */
                 this.compileMaterials = false;
+                /**
+                * If a clip plane should be usede when loading meshes in the file
+                */
                 this.useClipPlane = false;
+                /**
+                * If shadow generators should automatically be compiled
+                */
                 this.compileShadowGenerators = false;
+                /**
+                * Observable that fires when the loader is disposed
+                */
                 this.onDisposeObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a mesh is loaded
+                */
                 this.onMeshLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a texture is loaded
+                */
                 this.onTextureLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a material is loaded
+                */
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time an extension is loaded
+                */
                 this.onExtensionLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires when the load has completed
+                */
                 this.onCompleteObservable = new BABYLON.Observable();
             }
+            /**
+            * @ignore, registers the loader
+            * @param name name of the loader
+            * @param factory function that converts a loader to a loader extension
+            */
             GLTFLoader._Register = function (name, factory) {
                 if (GLTFLoader._Factories[name]) {
                     BABYLON.Tools.Error("Extension with the name '" + name + "' already exists");
@@ -535,12 +664,18 @@ var BABYLON;
                 GLTFLoader._Names.push(name);
             };
             Object.defineProperty(GLTFLoader.prototype, "state", {
+                /**
+                * The current state of the loader
+                */
                 get: function () {
                     return this._state;
                 },
                 enumerable: true,
                 configurable: true
             });
+            /**
+            * Disposes of the loader
+            */
             GLTFLoader.prototype.dispose = function () {
                 if (this._disposed) {
                     return;
@@ -550,6 +685,15 @@ var BABYLON;
                 this.onDisposeObservable.clear();
                 this._clear();
             };
+            /**
+            * Imports one or more meshes from a loaded gltf file and adds them to the scene
+            * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+            * @param scene the scene the meshes should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise containg the loaded meshes, particles, skeletons and animations
+            */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return Promise.resolve().then(function () {
@@ -583,6 +727,14 @@ var BABYLON;
                     });
                 });
             };
+            /**
+            * Imports all objects from a loaded gltf file and adds them to the scene
+            * @param scene the scene the objects should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise which completes when objects have been loaded to the scene
+            */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
                 return this._loadAsync(null, scene, data, rootUrl, onProgress);
             };
@@ -740,6 +892,9 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadSceneAsync = function (context, scene) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadSceneAsync(this, context, scene);
                 if (promise) {
@@ -839,6 +994,9 @@ var BABYLON;
                     }
                 }
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadNodeAsync = function (context, node) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadNodeAsync(this, context, node);
                 if (promise) {
@@ -868,7 +1026,6 @@ var BABYLON;
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
-                // TODO: instancing
                 var _this = this;
                 var promises = new Array();
                 var primitives = mesh.primitives;
@@ -1070,9 +1227,9 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadSkinAsync = function (context, node, mesh, skin) {
                 var _this = this;
-                var assignSkeleton = function () {
+                var assignSkeleton = function (skeleton) {
                     _this._forEachPrimitive(node, function (babylonMesh) {
-                        babylonMesh.skeleton = skin._babylonSkeleton;
+                        babylonMesh.skeleton = skeleton;
                     });
                     // Ignore the TRS of skinned nodes.
                     // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
@@ -1083,61 +1240,68 @@ var BABYLON;
                 };
                 if (skin._loaded) {
                     return skin._loaded.then(function () {
-                        assignSkeleton();
+                        assignSkeleton(skin._babylonSkeleton);
                     });
                 }
-                // TODO: split into two parts so that bones are created before inverseBindMatricesData is loaded (for compiling materials).
+                var skeletonId = "skeleton" + skin._index;
+                var babylonSkeleton = new BABYLON.Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
+                skin._babylonSkeleton = babylonSkeleton;
+                this._loadBones(context, skin);
+                assignSkeleton(babylonSkeleton);
                 return (skin._loaded = this._loadSkinInverseBindMatricesDataAsync(context, skin).then(function (inverseBindMatricesData) {
-                    var skeletonId = "skeleton" + skin._index;
-                    var babylonSkeleton = new BABYLON.Skeleton(skin.name || skeletonId, skeletonId, _this._babylonScene);
-                    skin._babylonSkeleton = babylonSkeleton;
-                    _this._loadBones(context, skin, inverseBindMatricesData);
-                    assignSkeleton();
+                    _this._updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
                 }));
             };
-            GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) {
-                if (skin.inverseBindMatrices == undefined) {
-                    return Promise.resolve(null);
-                }
-                var accessor = GLTFLoader._GetProperty(context + "/inverseBindMatrices", this._gltf.accessors, skin.inverseBindMatrices);
-                return this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                    return data;
-                });
-            };
-            GLTFLoader.prototype._createBone = function (node, skin, parent, localMatrix, baseMatrix, index) {
-                var babylonBone = new BABYLON.Bone(node.name || "joint" + node._index, skin._babylonSkeleton, parent, localMatrix, null, baseMatrix, index);
-                node._babylonAnimationTargets = node._babylonAnimationTargets || [];
-                node._babylonAnimationTargets.push(babylonBone);
-                return babylonBone;
-            };
-            GLTFLoader.prototype._loadBones = function (context, skin, inverseBindMatricesData) {
+            GLTFLoader.prototype._loadBones = function (context, skin) {
                 var babylonBones = {};
                 for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) {
                     var index = _a[_i];
                     var node = GLTFLoader._GetProperty(context + "/joints/" + index, this._gltf.nodes, index);
-                    this._loadBone(node, skin, inverseBindMatricesData, babylonBones);
+                    this._loadBone(node, skin, babylonBones);
                 }
             };
-            GLTFLoader.prototype._loadBone = function (node, skin, inverseBindMatricesData, babylonBones) {
+            GLTFLoader.prototype._loadBone = function (node, skin, babylonBones) {
                 var babylonBone = babylonBones[node._index];
                 if (babylonBone) {
                     return babylonBone;
                 }
-                var boneIndex = skin.joints.indexOf(node._index);
-                var baseMatrix = BABYLON.Matrix.Identity();
-                if (inverseBindMatricesData && boneIndex !== -1) {
-                    baseMatrix = BABYLON.Matrix.FromArray(inverseBindMatricesData, boneIndex * 16);
-                    baseMatrix.invertToRef(baseMatrix);
-                }
                 var babylonParentBone = null;
                 if (node._parent._babylonMesh !== this._rootBabylonMesh) {
-                    babylonParentBone = this._loadBone(node._parent, skin, inverseBindMatricesData, babylonBones);
-                    baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
+                    babylonParentBone = this._loadBone(node._parent, skin, babylonBones);
                 }
-                babylonBone = this._createBone(node, skin, babylonParentBone, this._getNodeMatrix(node), baseMatrix, boneIndex);
+                var boneIndex = skin.joints.indexOf(node._index);
+                babylonBone = new BABYLON.Bone(node.name || "joint" + node._index, skin._babylonSkeleton, babylonParentBone, this._getNodeMatrix(node), null, null, boneIndex);
                 babylonBones[node._index] = babylonBone;
+                node._babylonAnimationTargets = node._babylonAnimationTargets || [];
+                node._babylonAnimationTargets.push(babylonBone);
                 return babylonBone;
             };
+            GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) {
+                if (skin.inverseBindMatrices == undefined) {
+                    return Promise.resolve(null);
+                }
+                var accessor = GLTFLoader._GetProperty(context + "/inverseBindMatrices", this._gltf.accessors, skin.inverseBindMatrices);
+                return this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                    return data;
+                });
+            };
+            GLTFLoader.prototype._updateBoneMatrices = function (babylonSkeleton, inverseBindMatricesData) {
+                for (var _i = 0, _a = babylonSkeleton.bones; _i < _a.length; _i++) {
+                    var babylonBone = _a[_i];
+                    var baseMatrix = BABYLON.Matrix.Identity();
+                    var boneIndex = babylonBone._index;
+                    if (inverseBindMatricesData && boneIndex !== -1) {
+                        BABYLON.Matrix.FromArrayToRef(inverseBindMatricesData, boneIndex * 16, baseMatrix);
+                        baseMatrix.invertToRef(baseMatrix);
+                    }
+                    var babylonParentBone = babylonBone.getParent();
+                    if (babylonParentBone) {
+                        baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
+                    }
+                    babylonBone.updateMatrix(baseMatrix, false, false);
+                    babylonBone._updateDifferenceMatrix(undefined, false);
+                }
+            };
             GLTFLoader.prototype._getNodeMatrix = function (node) {
                 return node.matrix ?
                     BABYLON.Matrix.FromArray(node.matrix) :
@@ -1290,7 +1454,9 @@ var BABYLON;
                             }); }));
                             var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
+                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
+                                morphTarget.animations.push(babylonAnimation);
+                                morphTargets.push(morphTarget);
                             });
                             babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
@@ -1303,6 +1469,10 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
+                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
+                                var babylonAnimationTarget = _a[_i];
+                                babylonAnimationTarget.animations.push(babylonAnimation);
+                            }
                             babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
@@ -1353,6 +1523,9 @@ var BABYLON;
                 buffer._data = this._loadUriAsync(context, buffer.uri);
                 return buffer._data;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadBufferViewAsync = function (context, bufferView) {
                 if (bufferView._data) {
                     return bufferView._data;
@@ -1411,6 +1584,9 @@ var BABYLON;
                 });
                 return accessor._data;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
                 var _this = this;
                 if (bufferView._babylonBuffer) {
@@ -1480,6 +1656,9 @@ var BABYLON;
                 this._loadMaterialAlphaProperties(context, material, babylonMaterial);
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
                 if (promise) {
@@ -1505,12 +1684,18 @@ var BABYLON;
                 assign(babylonData.material);
                 return babylonData.loaded;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._createMaterial = function (type, name, drawMode) {
                 var babylonMaterial = new type(name, this._babylonScene);
                 babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? BABYLON.Material.CounterClockWiseSideOrientation : BABYLON.Material.ClockWiseSideOrientation;
                 babylonMaterial.fillMode = drawMode;
                 return babylonMaterial;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialBasePropertiesAsync = function (context, material, babylonMaterial) {
                 var promises = new Array();
                 babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
@@ -1544,6 +1729,9 @@ var BABYLON;
                 }
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialAlphaProperties = function (context, material, babylonMaterial) {
                 var alphaMode = material.alphaMode || "OPAQUE" /* OPAQUE */;
                 switch (alphaMode) {
@@ -1572,6 +1760,9 @@ var BABYLON;
                     }
                 }
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
                 var _this = this;
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
@@ -1631,6 +1822,9 @@ var BABYLON;
                 });
                 return image._objectURL;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadUriAsync = function (context, uri) {
                 var _this = this;
                 var promise = GLTF2.GLTFLoaderExtension._LoadUriAsync(this, context, uri);
@@ -1688,6 +1882,9 @@ var BABYLON;
                 }
                 this._progressCallback(new BABYLON.SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
             };
+            /**
+            * @ignore
+            */
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !array[index]) {
                     throw new Error(context + ": Failed to find index (" + index + ")");
@@ -1836,6 +2033,9 @@ var BABYLON;
                 this.onTextureLoadedObservable.clear();
                 this.onMaterialLoadedObservable.clear();
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._applyExtensions = function (actionAsync) {
                 for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
                     var name_5 = _a[_i];
@@ -1865,6 +2065,9 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /**
+         * Abstract class that can be implemented to extend existing gltf loader behavior.
+         */
         var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension(loader) {
                 this.enabled = true;
@@ -2114,6 +2317,7 @@ var __extends = (this && this.__extends) || (function () {
         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
     };
 })();
+/** Module defining extensions to gltf */
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


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

@@ -1,5 +1,8 @@
 
 declare module BABYLON {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     enum GLTFLoaderCoordinateSystemMode {
         /**
          * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
@@ -10,6 +13,9 @@ declare module BABYLON {
          */
         FORCE_RIGHT_HANDED = 1,
     }
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     enum GLTFLoaderAnimationStartMode {
         /**
          * No animation will start.
@@ -24,10 +30,22 @@ declare module BABYLON {
          */
         ALL = 2,
     }
+    /**
+    * Loaded gltf data
+    */
     interface IGLTFLoaderData {
+        /**
+        * Loaded json string converted to an object
+        */
         json: Object;
+        /**
+        * Loaded ArrayBufferView
+        */
         bin: Nullable<ArrayBufferView>;
     }
+    /**
+    * Gltf extension interface
+    */
     interface IGLTFLoaderExtension {
         /**
          * The name of this extension.
@@ -38,6 +56,9 @@ declare module BABYLON {
          */
         enabled: boolean;
     }
+    /**
+    * Loading state
+    */
     enum GLTFLoaderState {
         /**
          * The asset is loading.
@@ -52,29 +73,77 @@ declare module BABYLON {
          */
         COMPLETE = 2,
     }
+    /**
+    * GLTF loader interface
+    */
     interface IGLTFLoader extends IDisposable {
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+       * Observable that fires each time a material is loaded
+       */
         onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires when the load has completed
+        */
         onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fire when an extension is loaded
+        */
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Loader state
+        */
         state: Nullable<GLTFLoaderState>;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        */
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        */
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<void>;
     }
+    /** File loader to load gltf files into a babylon scene */
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
+        /** Creates a gltf 1.0 file loader */
         static CreateGLTFLoaderV1: () => IGLTFLoader;
+        /** Creates a gltf 2.0 file loader */
         static CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed.
@@ -83,27 +152,39 @@ declare module BABYLON {
          */
         onParsedObservable: Observable<IGLTFLoaderData>;
         private _onParsedObserver;
+        /** Raised when the asset has been parsed. */
         onParsed: (loaderData: IGLTFLoaderData) => void;
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         static IncrementalLoading: boolean;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         static HomogeneousCoordinates: boolean;
         /**
-         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+         * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+         * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
          */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         /**
-         * The animation start mode (NONE, FIRST, ALL).
-         */
+        * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+        * - NONE - No animation will start.
+        * - FIRST - The first animation will start.
+        * - ALL - All animations will start.
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
         /**
-         * Set to true to compile materials before raising the success callback.
+         * Set to true to compile materials before raising the success callback. Defaults to false.
          */
         compileMaterials: boolean;
         /**
-         * Set to true to also compile materials with clip planes.
+         * Set to true to also compile materials with clip planes. Defaults to false.
          */
         useClipPlane: boolean;
         /**
-         * Set to true to compile shadow generators before raising the success callback.
+         * Set to true to compile shadow generators before raising the success callback. Defaults to false.
          */
         compileShadowGenerators: boolean;
         /**
@@ -111,18 +192,27 @@ declare module BABYLON {
          */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         private _onMeshLoadedObserver;
+        /**
+         * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+         */
         onMeshLoaded: (mesh: AbstractMesh) => void;
         /**
          * Raised when the loader creates a texture after parsing the glTF properties of the texture.
          */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         private _onTextureLoadedObserver;
+        /**
+         * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+         */
         onTextureLoaded: (texture: BaseTexture) => void;
         /**
          * Raised when the loader creates a material after parsing the glTF properties of the material.
          */
         readonly onMaterialLoadedObservable: Observable<Material>;
         private _onMaterialLoadedObserver;
+        /**
+         * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+         */
         onMaterialLoaded: (material: Material) => void;
         /**
          * Raised when the asset is completely loaded, immediately before the loader is disposed.
@@ -131,12 +221,18 @@ declare module BABYLON {
          */
         readonly onCompleteObservable: Observable<GLTFFileLoader>;
         private _onCompleteObserver;
+        /**
+         * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+         */
         onComplete: () => void;
         /**
         * Raised after the loader is disposed.
         */
         readonly onDisposeObservable: Observable<GLTFFileLoader>;
         private _onDisposeObserver;
+        /**
+         * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+         */
         onDispose: () => void;
         /**
          * Raised after a loader extension is created.
@@ -144,6 +240,9 @@ declare module BABYLON {
          */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         private _onExtensionLoadedObserver;
+        /**
+         * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+         */
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
          * Returns a promise that resolves when the asset is completely loaded.
@@ -155,22 +254,65 @@ declare module BABYLON {
          */
         readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
+        /**
+         * Name of the loader ("gltf")
+         */
         name: string;
+        /**
+         * Supported file extensions of the loader (.gltf, .glb)
+         */
         extensions: ISceneLoaderPluginExtensions;
         /**
          * Disposes the loader, releases resources during load, and cancels any outstanding requests.
          */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         loadAssetContainerAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<AssetContainer>;
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         canDirectLoad(data: string): boolean;
+        /**
+         * Rewrites a url by combining a root url and response url
+         */
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
         private _parse(data);
         private _getLoader(loaderData);
@@ -587,9 +729,21 @@ declare module BABYLON.GLTF1 {
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * State of the loader
+        */
         state: Nullable<GLTFLoaderState>;
         dispose(): void;
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress?, onError?);
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
@@ -597,6 +751,14 @@ declare module BABYLON.GLTF1 {
             animationGroups: AnimationGroup[];
         }>;
         private _loadAsync(scene, data, rootUrl, onSuccess, onProgress?, onError?);
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
         private _loadShadersAsync(gltfRuntime, onload);
         private _loadBuffersAsync(gltfRuntime, onLoad, onProgress?);
@@ -741,48 +903,84 @@ declare module BABYLON.GLTF1 {
 
 
 declare module BABYLON.GLTF2 {
+    /** Array item which contains it's index in an array */
     interface IArrayItem {
         _index: number;
     }
+    /** Array item helper methods */
     class ArrayItem {
+        /** Sets the index of each array element to its index in the array */
         static Assign(values?: IArrayItem[]): void;
     }
 }
 
 
 
+/**
+ * GLTF2 module for babylon
+ */
 declare module BABYLON.GLTF2 {
+    /**
+     * Interface to access data and vertex buffer associated with a file
+     */
     interface ILoaderAccessor extends IAccessor, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
+    /**
+     * Loader's animation channel
+     */
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
+    /**
+     * Container for animation keyframe data
+     */
     interface ILoaderAnimationSamplerData {
         input: Float32Array;
         interpolation: AnimationSamplerInterpolation;
         output: Float32Array;
     }
+    /**
+     * Keyframe data
+     */
     interface ILoaderAnimationSampler extends IAnimationSampler, IArrayItem {
         _data: Promise<ILoaderAnimationSamplerData>;
     }
+    /**
+     * Loader animation
+     */
     interface ILoaderAnimation extends IAnimation, IArrayItem {
         channels: ILoaderAnimationChannel[];
         samplers: ILoaderAnimationSampler[];
         _babylonAnimationGroup?: AnimationGroup;
     }
+    /**
+     * Loader buffer
+     */
     interface ILoaderBuffer extends IBuffer, IArrayItem {
         _data?: Promise<ArrayBufferView>;
     }
+    /**
+     * Loader's buffer data
+     */
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonBuffer?: Promise<Buffer>;
     }
+    /**
+     * Loader's loaded camera data
+     */
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
+    /**
+     * Loaded image specified by url
+     */
     interface ILoaderImage extends IImage, IArrayItem {
         _objectURL?: Promise<string>;
     }
+    /**
+     * Loaded material data
+     */
     interface ILoaderMaterial extends IMaterial, IArrayItem {
         _babylonData?: {
             [drawMode: number]: {
@@ -792,11 +990,20 @@ declare module BABYLON.GLTF2 {
             };
         };
     }
+    /**
+     * Loader mesh data
+     */
     interface ILoaderMesh extends IMesh, IArrayItem {
         primitives: ILoaderMeshPrimitive[];
     }
+    /**
+     * Loader mesh data
+     */
     interface ILoaderMeshPrimitive extends IMeshPrimitive, IArrayItem {
     }
+    /**
+     * Node for traversing loader data
+     */
     interface ILoaderNode extends INode, IArrayItem {
         _parent: ILoaderNode;
         _babylonMesh?: Mesh;
@@ -804,23 +1011,41 @@ declare module BABYLON.GLTF2 {
         _babylonAnimationTargets?: Node[];
         _numMorphTargets?: number;
     }
+    /**
+     * Sampler data
+     */
     interface ILoaderSamplerData {
         noMipMaps: boolean;
         samplingMode: number;
         wrapU: number;
         wrapV: number;
     }
+    /**
+     * Sampler data
+     */
     interface ILoaderSampler extends ISampler, IArrayItem {
         _data?: ILoaderSamplerData;
     }
+    /**
+     * Loader's scene
+     */
     interface ILoaderScene extends IScene, IArrayItem {
     }
+    /**
+     * Loader's skeleton data
+     */
     interface ILoaderSkin extends ISkin, IArrayItem {
         _babylonSkeleton?: Skeleton;
         _loaded?: Promise<void>;
     }
+    /**
+     * Loader's texture
+     */
     interface ILoaderTexture extends ITexture, IArrayItem {
     }
+    /**
+     * Loaded GLTF data
+     */
     interface ILoaderGLTF extends IGLTF {
         accessors?: ILoaderAccessor[];
         animations?: ILoaderAnimation[];
@@ -839,14 +1064,40 @@ declare module BABYLON.GLTF2 {
 }
 
 
+/**
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
+*/
 declare module BABYLON.GLTF2 {
+    /**
+    * Interface for a meterial with a constructor
+    */
     interface MaterialConstructor<T extends Material> {
+        /**
+        * The material class
+        */
         readonly prototype: T;
+        /**
+        * Instatiates a material
+        * @param name name of the material
+        * @param scene the scene the material will be added to
+        */
         new (name: string, scene: Scene): T;
     }
+    /**
+    * Used to load from a GLTF2 file
+    */
     class GLTFLoader implements IGLTFLoader {
+        /**
+        * @ignore
+        */
         _gltf: ILoaderGLTF;
+        /**
+        * @ignore
+        */
         _babylonScene: Scene;
+        /**
+        * @ignore
+        */
         _completePromises: Promise<void>[];
         private _disposed;
         private _state;
@@ -859,26 +1110,87 @@ declare module BABYLON.GLTF2 {
         private _requests;
         private static _Names;
         private static _Factories;
+        /**
+        * @ignore, registers the loader
+        * @param name name of the loader
+        * @param factory function that converts a loader to a loader extension
+        */
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         readonly onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+        * Observable that fires each time a material is loaded
+        */
         readonly onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires each time an extension is loaded
+        */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Observable that fires when the load has completed
+        */
         readonly onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * The current state of the loader
+        */
         readonly state: Nullable<GLTFLoaderState>;
+        /**
+        * Disposes of the loader
+        */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
         private _loadAsync(nodes, scene, data, rootUrl, onProgress?);
         private _loadExtensions();
@@ -887,12 +1199,18 @@ declare module BABYLON.GLTF2 {
         private _checkExtensions();
         private _createRootNode();
         private _loadNodesAsync(nodes);
+        /**
+        * @ignore
+        */
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
         private _forEachPrimitive(node, callback);
         private _getMeshes();
         private _getSkeletons();
         private _getAnimationGroups();
         private _startAnimations();
+        /**
+        * @ignore
+        */
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
         private _loadMeshAsync(context, node, mesh, babylonMesh);
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
@@ -902,31 +1220,58 @@ declare module BABYLON.GLTF2 {
         private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
+        private _loadBones(context, skin);
+        private _loadBone(node, skin, babylonBones);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
-        private _createBone(node, skin, parent, localMatrix, baseMatrix, index);
-        private _loadBones(context, skin, inverseBindMatricesData);
-        private _loadBone(node, skin, inverseBindMatricesData, babylonBones);
+        private _updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
         private _getNodeMatrix(node);
         private _loadAnimationsAsync();
         private _loadAnimationAsync(context, animation);
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadBufferAsync(context, buffer);
+        /**
+        * @ignore
+        */
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
+        /**
+        * @ignore
+        */
         _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
         private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
+        /**
+        * @ignore
+        */
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
+        /**
+        * @ignore
+        */
         _createMaterial<T extends Material>(type: MaterialConstructor<T>, name: string, drawMode: number): T;
+        /**
+        * @ignore
+        */
         _loadMaterialBasePropertiesAsync(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void>;
+        /**
+        * @ignore
+        */
         _loadMaterialAlphaProperties(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): void;
+        /**
+        * @ignore
+        */
         _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Promise<void>;
         private _loadSampler(context, sampler);
         private _loadImageAsync(context, image);
+        /**
+        * @ignore
+        */
         _loadUriAsync(context: string, uri: string): Promise<ArrayBufferView>;
         private _onProgress();
+        /**
+        * @ignore
+        */
         static _GetProperty<T>(context: string, array: ArrayLike<T> | undefined, index: number | undefined): T;
         private static _GetTextureWrapMode(context, mode);
         private static _GetTextureSamplingMode(context, magFilter?, minFilter?);
@@ -936,12 +1281,18 @@ declare module BABYLON.GLTF2 {
         private _compileMaterialsAsync();
         private _compileShadowGeneratorsAsync();
         private _clear();
+        /**
+        * @ignore
+        */
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
     }
 }
 
 
 declare module BABYLON.GLTF2 {
+    /**
+     * Abstract class that can be implemented to extend existing gltf loader behavior.
+     */
     abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
         enabled: boolean;
         readonly abstract name: string;
@@ -996,6 +1347,7 @@ declare module BABYLON.GLTF2.Extensions {
 }
 
 
+/** Module defining extensions to gltf */
 declare module BABYLON.GLTF2.Extensions {
     class KHR_draco_mesh_compression extends GLTFLoaderExtension {
         readonly name: string;

+ 268 - 44
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -1,6 +1,9 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     var GLTFLoaderCoordinateSystemMode;
     (function (GLTFLoaderCoordinateSystemMode) {
         /**
@@ -12,6 +15,9 @@ var BABYLON;
          */
         GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 1] = "FORCE_RIGHT_HANDED";
     })(GLTFLoaderCoordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode || (BABYLON.GLTFLoaderCoordinateSystemMode = {}));
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     var GLTFLoaderAnimationStartMode;
     (function (GLTFLoaderAnimationStartMode) {
         /**
@@ -27,6 +33,9 @@ var BABYLON;
          */
         GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["ALL"] = 2] = "ALL";
     })(GLTFLoaderAnimationStartMode = BABYLON.GLTFLoaderAnimationStartMode || (BABYLON.GLTFLoaderAnimationStartMode = {}));
+    /**
+    * Loading state
+    */
     var GLTFLoaderState;
     (function (GLTFLoaderState) {
         /**
@@ -42,6 +51,7 @@ var BABYLON;
          */
         GLTFLoaderState[GLTFLoaderState["COMPLETE"] = 2] = "COMPLETE";
     })(GLTFLoaderState = BABYLON.GLTFLoaderState || (BABYLON.GLTFLoaderState = {}));
+    /** File loader to load gltf files into a babylon scene */
     var GLTFFileLoader = /** @class */ (function () {
         function GLTFFileLoader() {
             // #region Common options
@@ -54,23 +64,28 @@ var BABYLON;
             // #endregion
             // #region V2 options
             /**
-             * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+             * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+             * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+             * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
              */
             this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
             /**
-             * The animation start mode (NONE, FIRST, ALL).
-             */
+            * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+            * - NONE - No animation will start.
+            * - FIRST - The first animation will start.
+            * - ALL - All animations will start.
+            */
             this.animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
             /**
-             * Set to true to compile materials before raising the success callback.
+             * Set to true to compile materials before raising the success callback. Defaults to false.
              */
             this.compileMaterials = false;
             /**
-             * Set to true to also compile materials with clip planes.
+             * Set to true to also compile materials with clip planes. Defaults to false.
              */
             this.useClipPlane = false;
             /**
-             * Set to true to compile shadow generators before raising the success callback.
+             * Set to true to compile shadow generators before raising the success callback. Defaults to false.
              */
             this.compileShadowGenerators = false;
             /**
@@ -102,13 +117,20 @@ var BABYLON;
             this.onExtensionLoadedObservable = new BABYLON.Observable();
             // #endregion
             this._loader = null;
+            /**
+             * Name of the loader ("gltf")
+             */
             this.name = "gltf";
+            /**
+             * Supported file extensions of the loader (.gltf, .glb)
+             */
             this.extensions = {
                 ".gltf": { isBinary: false },
                 ".glb": { isBinary: true }
             };
         }
         Object.defineProperty(GLTFFileLoader.prototype, "onParsed", {
+            /** Raised when the asset has been parsed. */
             set: function (callback) {
                 if (this._onParsedObserver) {
                     this.onParsedObservable.remove(this._onParsedObserver);
@@ -119,6 +141,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
+            /**
+             * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onMeshLoadedObserver) {
                     this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver);
@@ -129,6 +154,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", {
+            /**
+             * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onTextureLoadedObserver) {
                     this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver);
@@ -139,6 +167,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", {
+            /**
+             * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onMaterialLoadedObserver) {
                     this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver);
@@ -149,6 +180,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
+            /**
+             * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onCompleteObserver) {
                     this.onCompleteObservable.remove(this._onCompleteObserver);
@@ -159,6 +193,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
+            /**
+             * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onDisposeObserver) {
                     this.onDisposeObservable.remove(this._onDisposeObserver);
@@ -169,6 +206,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
+            /**
+             * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onExtensionLoadedObserver) {
                     this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
@@ -214,6 +254,15 @@ var BABYLON;
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
         };
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -222,6 +271,14 @@ var BABYLON;
                 return _this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onProgress);
             });
         };
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -230,6 +287,14 @@ var BABYLON;
                 return _this._loader.loadAsync(scene, loaderData, rootUrl, onProgress);
             });
         };
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         GLTFFileLoader.prototype.loadAssetContainerAsync = function (scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -246,9 +311,18 @@ var BABYLON;
                 });
             });
         };
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         };
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         GLTFFileLoader.prototype.createPlugin = function () {
             return new GLTFFileLoader();
         };
@@ -432,7 +506,13 @@ var BABYLON;
         };
         // #endregion
         // #region V1 options
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         GLTFFileLoader.IncrementalLoading = true;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         GLTFFileLoader.HomogeneousCoordinates = false;
         return GLTFFileLoader;
     }());
@@ -1869,6 +1949,9 @@ var BABYLON;
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onExtensionLoadedObservable = new BABYLON.Observable();
+                /**
+                * State of the loader
+                */
                 this.state = null;
             }
             GLTFLoader.RegisterExtension = function (extension) {
@@ -1931,6 +2014,15 @@ var BABYLON;
                 }, onError);
                 return true;
             };
+            /**
+            * Imports one or more meshes from a loaded gltf file and adds them to the scene
+            * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+            * @param scene the scene the meshes should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise containg the loaded meshes, particles, skeletons and animations
+            */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return new Promise(function (resolve, reject) {
@@ -1970,6 +2062,14 @@ var BABYLON;
                     }, onError);
                 }, onError);
             };
+            /**
+            * Imports all objects from a loaded gltf file and adds them to the scene
+            * @param scene the scene the objects should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise which completes when objects have been loaded to the scene
+            */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return new Promise(function (resolve, reject) {
@@ -2671,9 +2771,11 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /** Array item helper methods */
         var ArrayItem = /** @class */ (function () {
             function ArrayItem() {
             }
+            /** Sets the index of each array element to its index in the array */
             ArrayItem.Assign = function (values) {
                 if (values) {
                     for (var index = 0; index < values.length; index++) {
@@ -2695,12 +2797,21 @@ var BABYLON;
 //# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
 
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+/**
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
+*/
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /**
+        * Used to load from a GLTF2 file
+        */
         var GLTFLoader = /** @class */ (function () {
             function GLTFLoader() {
+                /**
+                * @ignore
+                */
                 this._completePromises = new Array();
                 this._disposed = false;
                 this._state = null;
@@ -2708,18 +2819,56 @@ var BABYLON;
                 this._defaultSampler = {};
                 this._defaultBabylonMaterials = {};
                 this._requests = new Array();
+                /**
+                * Coordinate system that will be used when loading from the gltf file
+                */
                 this.coordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode.AUTO;
+                /**
+                * Animation mode that determines which animations should be started when a file is loaded
+                */
                 this.animationStartMode = BABYLON.GLTFLoaderAnimationStartMode.FIRST;
+                /**
+                * If the materials in the file should automatically be compiled
+                */
                 this.compileMaterials = false;
+                /**
+                * If a clip plane should be usede when loading meshes in the file
+                */
                 this.useClipPlane = false;
+                /**
+                * If shadow generators should automatically be compiled
+                */
                 this.compileShadowGenerators = false;
+                /**
+                * Observable that fires when the loader is disposed
+                */
                 this.onDisposeObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a mesh is loaded
+                */
                 this.onMeshLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a texture is loaded
+                */
                 this.onTextureLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a material is loaded
+                */
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time an extension is loaded
+                */
                 this.onExtensionLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires when the load has completed
+                */
                 this.onCompleteObservable = new BABYLON.Observable();
             }
+            /**
+            * @ignore, registers the loader
+            * @param name name of the loader
+            * @param factory function that converts a loader to a loader extension
+            */
             GLTFLoader._Register = function (name, factory) {
                 if (GLTFLoader._Factories[name]) {
                     BABYLON.Tools.Error("Extension with the name '" + name + "' already exists");
@@ -2730,12 +2879,18 @@ var BABYLON;
                 GLTFLoader._Names.push(name);
             };
             Object.defineProperty(GLTFLoader.prototype, "state", {
+                /**
+                * The current state of the loader
+                */
                 get: function () {
                     return this._state;
                 },
                 enumerable: true,
                 configurable: true
             });
+            /**
+            * Disposes of the loader
+            */
             GLTFLoader.prototype.dispose = function () {
                 if (this._disposed) {
                     return;
@@ -2745,6 +2900,15 @@ var BABYLON;
                 this.onDisposeObservable.clear();
                 this._clear();
             };
+            /**
+            * Imports one or more meshes from a loaded gltf file and adds them to the scene
+            * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+            * @param scene the scene the meshes should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise containg the loaded meshes, particles, skeletons and animations
+            */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return Promise.resolve().then(function () {
@@ -2778,6 +2942,14 @@ var BABYLON;
                     });
                 });
             };
+            /**
+            * Imports all objects from a loaded gltf file and adds them to the scene
+            * @param scene the scene the objects should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise which completes when objects have been loaded to the scene
+            */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
                 return this._loadAsync(null, scene, data, rootUrl, onProgress);
             };
@@ -2935,6 +3107,9 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadSceneAsync = function (context, scene) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadSceneAsync(this, context, scene);
                 if (promise) {
@@ -3034,6 +3209,9 @@ var BABYLON;
                     }
                 }
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadNodeAsync = function (context, node) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadNodeAsync(this, context, node);
                 if (promise) {
@@ -3063,7 +3241,6 @@ var BABYLON;
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
-                // TODO: instancing
                 var _this = this;
                 var promises = new Array();
                 var primitives = mesh.primitives;
@@ -3265,9 +3442,9 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadSkinAsync = function (context, node, mesh, skin) {
                 var _this = this;
-                var assignSkeleton = function () {
+                var assignSkeleton = function (skeleton) {
                     _this._forEachPrimitive(node, function (babylonMesh) {
-                        babylonMesh.skeleton = skin._babylonSkeleton;
+                        babylonMesh.skeleton = skeleton;
                     });
                     // Ignore the TRS of skinned nodes.
                     // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
@@ -3278,61 +3455,68 @@ var BABYLON;
                 };
                 if (skin._loaded) {
                     return skin._loaded.then(function () {
-                        assignSkeleton();
+                        assignSkeleton(skin._babylonSkeleton);
                     });
                 }
-                // TODO: split into two parts so that bones are created before inverseBindMatricesData is loaded (for compiling materials).
+                var skeletonId = "skeleton" + skin._index;
+                var babylonSkeleton = new BABYLON.Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
+                skin._babylonSkeleton = babylonSkeleton;
+                this._loadBones(context, skin);
+                assignSkeleton(babylonSkeleton);
                 return (skin._loaded = this._loadSkinInverseBindMatricesDataAsync(context, skin).then(function (inverseBindMatricesData) {
-                    var skeletonId = "skeleton" + skin._index;
-                    var babylonSkeleton = new BABYLON.Skeleton(skin.name || skeletonId, skeletonId, _this._babylonScene);
-                    skin._babylonSkeleton = babylonSkeleton;
-                    _this._loadBones(context, skin, inverseBindMatricesData);
-                    assignSkeleton();
+                    _this._updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
                 }));
             };
-            GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) {
-                if (skin.inverseBindMatrices == undefined) {
-                    return Promise.resolve(null);
-                }
-                var accessor = GLTFLoader._GetProperty(context + "/inverseBindMatrices", this._gltf.accessors, skin.inverseBindMatrices);
-                return this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                    return data;
-                });
-            };
-            GLTFLoader.prototype._createBone = function (node, skin, parent, localMatrix, baseMatrix, index) {
-                var babylonBone = new BABYLON.Bone(node.name || "joint" + node._index, skin._babylonSkeleton, parent, localMatrix, null, baseMatrix, index);
-                node._babylonAnimationTargets = node._babylonAnimationTargets || [];
-                node._babylonAnimationTargets.push(babylonBone);
-                return babylonBone;
-            };
-            GLTFLoader.prototype._loadBones = function (context, skin, inverseBindMatricesData) {
+            GLTFLoader.prototype._loadBones = function (context, skin) {
                 var babylonBones = {};
                 for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) {
                     var index = _a[_i];
                     var node = GLTFLoader._GetProperty(context + "/joints/" + index, this._gltf.nodes, index);
-                    this._loadBone(node, skin, inverseBindMatricesData, babylonBones);
+                    this._loadBone(node, skin, babylonBones);
                 }
             };
-            GLTFLoader.prototype._loadBone = function (node, skin, inverseBindMatricesData, babylonBones) {
+            GLTFLoader.prototype._loadBone = function (node, skin, babylonBones) {
                 var babylonBone = babylonBones[node._index];
                 if (babylonBone) {
                     return babylonBone;
                 }
-                var boneIndex = skin.joints.indexOf(node._index);
-                var baseMatrix = BABYLON.Matrix.Identity();
-                if (inverseBindMatricesData && boneIndex !== -1) {
-                    baseMatrix = BABYLON.Matrix.FromArray(inverseBindMatricesData, boneIndex * 16);
-                    baseMatrix.invertToRef(baseMatrix);
-                }
                 var babylonParentBone = null;
                 if (node._parent._babylonMesh !== this._rootBabylonMesh) {
-                    babylonParentBone = this._loadBone(node._parent, skin, inverseBindMatricesData, babylonBones);
-                    baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
+                    babylonParentBone = this._loadBone(node._parent, skin, babylonBones);
                 }
-                babylonBone = this._createBone(node, skin, babylonParentBone, this._getNodeMatrix(node), baseMatrix, boneIndex);
+                var boneIndex = skin.joints.indexOf(node._index);
+                babylonBone = new BABYLON.Bone(node.name || "joint" + node._index, skin._babylonSkeleton, babylonParentBone, this._getNodeMatrix(node), null, null, boneIndex);
                 babylonBones[node._index] = babylonBone;
+                node._babylonAnimationTargets = node._babylonAnimationTargets || [];
+                node._babylonAnimationTargets.push(babylonBone);
                 return babylonBone;
             };
+            GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) {
+                if (skin.inverseBindMatrices == undefined) {
+                    return Promise.resolve(null);
+                }
+                var accessor = GLTFLoader._GetProperty(context + "/inverseBindMatrices", this._gltf.accessors, skin.inverseBindMatrices);
+                return this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                    return data;
+                });
+            };
+            GLTFLoader.prototype._updateBoneMatrices = function (babylonSkeleton, inverseBindMatricesData) {
+                for (var _i = 0, _a = babylonSkeleton.bones; _i < _a.length; _i++) {
+                    var babylonBone = _a[_i];
+                    var baseMatrix = BABYLON.Matrix.Identity();
+                    var boneIndex = babylonBone._index;
+                    if (inverseBindMatricesData && boneIndex !== -1) {
+                        BABYLON.Matrix.FromArrayToRef(inverseBindMatricesData, boneIndex * 16, baseMatrix);
+                        baseMatrix.invertToRef(baseMatrix);
+                    }
+                    var babylonParentBone = babylonBone.getParent();
+                    if (babylonParentBone) {
+                        baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
+                    }
+                    babylonBone.updateMatrix(baseMatrix, false, false);
+                    babylonBone._updateDifferenceMatrix(undefined, false);
+                }
+            };
             GLTFLoader.prototype._getNodeMatrix = function (node) {
                 return node.matrix ?
                     BABYLON.Matrix.FromArray(node.matrix) :
@@ -3485,7 +3669,9 @@ var BABYLON;
                             }); }));
                             var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
+                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
+                                morphTarget.animations.push(babylonAnimation);
+                                morphTargets.push(morphTarget);
                             });
                             babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
@@ -3498,6 +3684,10 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
+                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
+                                var babylonAnimationTarget = _a[_i];
+                                babylonAnimationTarget.animations.push(babylonAnimation);
+                            }
                             babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
@@ -3548,6 +3738,9 @@ var BABYLON;
                 buffer._data = this._loadUriAsync(context, buffer.uri);
                 return buffer._data;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadBufferViewAsync = function (context, bufferView) {
                 if (bufferView._data) {
                     return bufferView._data;
@@ -3606,6 +3799,9 @@ var BABYLON;
                 });
                 return accessor._data;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
                 var _this = this;
                 if (bufferView._babylonBuffer) {
@@ -3675,6 +3871,9 @@ var BABYLON;
                 this._loadMaterialAlphaProperties(context, material, babylonMaterial);
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
                 if (promise) {
@@ -3700,12 +3899,18 @@ var BABYLON;
                 assign(babylonData.material);
                 return babylonData.loaded;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._createMaterial = function (type, name, drawMode) {
                 var babylonMaterial = new type(name, this._babylonScene);
                 babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? BABYLON.Material.CounterClockWiseSideOrientation : BABYLON.Material.ClockWiseSideOrientation;
                 babylonMaterial.fillMode = drawMode;
                 return babylonMaterial;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialBasePropertiesAsync = function (context, material, babylonMaterial) {
                 var promises = new Array();
                 babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
@@ -3739,6 +3944,9 @@ var BABYLON;
                 }
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialAlphaProperties = function (context, material, babylonMaterial) {
                 var alphaMode = material.alphaMode || "OPAQUE" /* OPAQUE */;
                 switch (alphaMode) {
@@ -3767,6 +3975,9 @@ var BABYLON;
                     }
                 }
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
                 var _this = this;
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
@@ -3826,6 +4037,9 @@ var BABYLON;
                 });
                 return image._objectURL;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadUriAsync = function (context, uri) {
                 var _this = this;
                 var promise = GLTF2.GLTFLoaderExtension._LoadUriAsync(this, context, uri);
@@ -3883,6 +4097,9 @@ var BABYLON;
                 }
                 this._progressCallback(new BABYLON.SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
             };
+            /**
+            * @ignore
+            */
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !array[index]) {
                     throw new Error(context + ": Failed to find index (" + index + ")");
@@ -4031,6 +4248,9 @@ var BABYLON;
                 this.onTextureLoadedObservable.clear();
                 this.onMaterialLoadedObservable.clear();
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._applyExtensions = function (actionAsync) {
                 for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
                     var name_5 = _a[_i];
@@ -4060,6 +4280,9 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /**
+         * Abstract class that can be implemented to extend existing gltf loader behavior.
+         */
         var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension(loader) {
                 this.enabled = true;
@@ -4309,6 +4532,7 @@ var __extends = (this && this.__extends) || (function () {
         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
     };
 })();
+/** Module defining extensions to gltf */
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 361 - 9
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -96,6 +96,9 @@ declare module BABYLON {
 
 
 declare module BABYLON {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     enum GLTFLoaderCoordinateSystemMode {
         /**
          * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
@@ -106,6 +109,9 @@ declare module BABYLON {
          */
         FORCE_RIGHT_HANDED = 1,
     }
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     enum GLTFLoaderAnimationStartMode {
         /**
          * No animation will start.
@@ -120,10 +126,22 @@ declare module BABYLON {
          */
         ALL = 2,
     }
+    /**
+    * Loaded gltf data
+    */
     interface IGLTFLoaderData {
+        /**
+        * Loaded json string converted to an object
+        */
         json: Object;
+        /**
+        * Loaded ArrayBufferView
+        */
         bin: Nullable<ArrayBufferView>;
     }
+    /**
+    * Gltf extension interface
+    */
     interface IGLTFLoaderExtension {
         /**
          * The name of this extension.
@@ -134,6 +152,9 @@ declare module BABYLON {
          */
         enabled: boolean;
     }
+    /**
+    * Loading state
+    */
     enum GLTFLoaderState {
         /**
          * The asset is loading.
@@ -148,29 +169,77 @@ declare module BABYLON {
          */
         COMPLETE = 2,
     }
+    /**
+    * GLTF loader interface
+    */
     interface IGLTFLoader extends IDisposable {
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+       * Observable that fires each time a material is loaded
+       */
         onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires when the load has completed
+        */
         onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fire when an extension is loaded
+        */
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Loader state
+        */
         state: Nullable<GLTFLoaderState>;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        */
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        */
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<void>;
     }
+    /** File loader to load gltf files into a babylon scene */
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
+        /** Creates a gltf 1.0 file loader */
         static CreateGLTFLoaderV1: () => IGLTFLoader;
+        /** Creates a gltf 2.0 file loader */
         static CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed.
@@ -179,27 +248,39 @@ declare module BABYLON {
          */
         onParsedObservable: Observable<IGLTFLoaderData>;
         private _onParsedObserver;
+        /** Raised when the asset has been parsed. */
         onParsed: (loaderData: IGLTFLoaderData) => void;
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         static IncrementalLoading: boolean;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         static HomogeneousCoordinates: boolean;
         /**
-         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+         * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+         * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
          */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         /**
-         * The animation start mode (NONE, FIRST, ALL).
-         */
+        * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+        * - NONE - No animation will start.
+        * - FIRST - The first animation will start.
+        * - ALL - All animations will start.
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
         /**
-         * Set to true to compile materials before raising the success callback.
+         * Set to true to compile materials before raising the success callback. Defaults to false.
          */
         compileMaterials: boolean;
         /**
-         * Set to true to also compile materials with clip planes.
+         * Set to true to also compile materials with clip planes. Defaults to false.
          */
         useClipPlane: boolean;
         /**
-         * Set to true to compile shadow generators before raising the success callback.
+         * Set to true to compile shadow generators before raising the success callback. Defaults to false.
          */
         compileShadowGenerators: boolean;
         /**
@@ -207,18 +288,27 @@ declare module BABYLON {
          */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         private _onMeshLoadedObserver;
+        /**
+         * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+         */
         onMeshLoaded: (mesh: AbstractMesh) => void;
         /**
          * Raised when the loader creates a texture after parsing the glTF properties of the texture.
          */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         private _onTextureLoadedObserver;
+        /**
+         * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+         */
         onTextureLoaded: (texture: BaseTexture) => void;
         /**
          * Raised when the loader creates a material after parsing the glTF properties of the material.
          */
         readonly onMaterialLoadedObservable: Observable<Material>;
         private _onMaterialLoadedObserver;
+        /**
+         * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+         */
         onMaterialLoaded: (material: Material) => void;
         /**
          * Raised when the asset is completely loaded, immediately before the loader is disposed.
@@ -227,12 +317,18 @@ declare module BABYLON {
          */
         readonly onCompleteObservable: Observable<GLTFFileLoader>;
         private _onCompleteObserver;
+        /**
+         * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+         */
         onComplete: () => void;
         /**
         * Raised after the loader is disposed.
         */
         readonly onDisposeObservable: Observable<GLTFFileLoader>;
         private _onDisposeObserver;
+        /**
+         * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+         */
         onDispose: () => void;
         /**
          * Raised after a loader extension is created.
@@ -240,6 +336,9 @@ declare module BABYLON {
          */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         private _onExtensionLoadedObserver;
+        /**
+         * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+         */
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
          * Returns a promise that resolves when the asset is completely loaded.
@@ -251,22 +350,65 @@ declare module BABYLON {
          */
         readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
+        /**
+         * Name of the loader ("gltf")
+         */
         name: string;
+        /**
+         * Supported file extensions of the loader (.gltf, .glb)
+         */
         extensions: ISceneLoaderPluginExtensions;
         /**
          * Disposes the loader, releases resources during load, and cancels any outstanding requests.
          */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         loadAssetContainerAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<AssetContainer>;
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         canDirectLoad(data: string): boolean;
+        /**
+         * Rewrites a url by combining a root url and response url
+         */
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
         private _parse(data);
         private _getLoader(loaderData);
@@ -683,9 +825,21 @@ declare module BABYLON.GLTF1 {
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * State of the loader
+        */
         state: Nullable<GLTFLoaderState>;
         dispose(): void;
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress?, onError?);
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
@@ -693,6 +847,14 @@ declare module BABYLON.GLTF1 {
             animationGroups: AnimationGroup[];
         }>;
         private _loadAsync(scene, data, rootUrl, onSuccess, onProgress?, onError?);
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
         private _loadShadersAsync(gltfRuntime, onload);
         private _loadBuffersAsync(gltfRuntime, onLoad, onProgress?);
@@ -837,48 +999,84 @@ declare module BABYLON.GLTF1 {
 
 
 declare module BABYLON.GLTF2 {
+    /** Array item which contains it's index in an array */
     interface IArrayItem {
         _index: number;
     }
+    /** Array item helper methods */
     class ArrayItem {
+        /** Sets the index of each array element to its index in the array */
         static Assign(values?: IArrayItem[]): void;
     }
 }
 
 
 
+/**
+ * GLTF2 module for babylon
+ */
 declare module BABYLON.GLTF2 {
+    /**
+     * Interface to access data and vertex buffer associated with a file
+     */
     interface ILoaderAccessor extends IAccessor, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
+    /**
+     * Loader's animation channel
+     */
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
+    /**
+     * Container for animation keyframe data
+     */
     interface ILoaderAnimationSamplerData {
         input: Float32Array;
         interpolation: AnimationSamplerInterpolation;
         output: Float32Array;
     }
+    /**
+     * Keyframe data
+     */
     interface ILoaderAnimationSampler extends IAnimationSampler, IArrayItem {
         _data: Promise<ILoaderAnimationSamplerData>;
     }
+    /**
+     * Loader animation
+     */
     interface ILoaderAnimation extends IAnimation, IArrayItem {
         channels: ILoaderAnimationChannel[];
         samplers: ILoaderAnimationSampler[];
         _babylonAnimationGroup?: AnimationGroup;
     }
+    /**
+     * Loader buffer
+     */
     interface ILoaderBuffer extends IBuffer, IArrayItem {
         _data?: Promise<ArrayBufferView>;
     }
+    /**
+     * Loader's buffer data
+     */
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonBuffer?: Promise<Buffer>;
     }
+    /**
+     * Loader's loaded camera data
+     */
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
+    /**
+     * Loaded image specified by url
+     */
     interface ILoaderImage extends IImage, IArrayItem {
         _objectURL?: Promise<string>;
     }
+    /**
+     * Loaded material data
+     */
     interface ILoaderMaterial extends IMaterial, IArrayItem {
         _babylonData?: {
             [drawMode: number]: {
@@ -888,11 +1086,20 @@ declare module BABYLON.GLTF2 {
             };
         };
     }
+    /**
+     * Loader mesh data
+     */
     interface ILoaderMesh extends IMesh, IArrayItem {
         primitives: ILoaderMeshPrimitive[];
     }
+    /**
+     * Loader mesh data
+     */
     interface ILoaderMeshPrimitive extends IMeshPrimitive, IArrayItem {
     }
+    /**
+     * Node for traversing loader data
+     */
     interface ILoaderNode extends INode, IArrayItem {
         _parent: ILoaderNode;
         _babylonMesh?: Mesh;
@@ -900,23 +1107,41 @@ declare module BABYLON.GLTF2 {
         _babylonAnimationTargets?: Node[];
         _numMorphTargets?: number;
     }
+    /**
+     * Sampler data
+     */
     interface ILoaderSamplerData {
         noMipMaps: boolean;
         samplingMode: number;
         wrapU: number;
         wrapV: number;
     }
+    /**
+     * Sampler data
+     */
     interface ILoaderSampler extends ISampler, IArrayItem {
         _data?: ILoaderSamplerData;
     }
+    /**
+     * Loader's scene
+     */
     interface ILoaderScene extends IScene, IArrayItem {
     }
+    /**
+     * Loader's skeleton data
+     */
     interface ILoaderSkin extends ISkin, IArrayItem {
         _babylonSkeleton?: Skeleton;
         _loaded?: Promise<void>;
     }
+    /**
+     * Loader's texture
+     */
     interface ILoaderTexture extends ITexture, IArrayItem {
     }
+    /**
+     * Loaded GLTF data
+     */
     interface ILoaderGLTF extends IGLTF {
         accessors?: ILoaderAccessor[];
         animations?: ILoaderAnimation[];
@@ -935,14 +1160,40 @@ declare module BABYLON.GLTF2 {
 }
 
 
+/**
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
+*/
 declare module BABYLON.GLTF2 {
+    /**
+    * Interface for a meterial with a constructor
+    */
     interface MaterialConstructor<T extends Material> {
+        /**
+        * The material class
+        */
         readonly prototype: T;
+        /**
+        * Instatiates a material
+        * @param name name of the material
+        * @param scene the scene the material will be added to
+        */
         new (name: string, scene: Scene): T;
     }
+    /**
+    * Used to load from a GLTF2 file
+    */
     class GLTFLoader implements IGLTFLoader {
+        /**
+        * @ignore
+        */
         _gltf: ILoaderGLTF;
+        /**
+        * @ignore
+        */
         _babylonScene: Scene;
+        /**
+        * @ignore
+        */
         _completePromises: Promise<void>[];
         private _disposed;
         private _state;
@@ -955,26 +1206,87 @@ declare module BABYLON.GLTF2 {
         private _requests;
         private static _Names;
         private static _Factories;
+        /**
+        * @ignore, registers the loader
+        * @param name name of the loader
+        * @param factory function that converts a loader to a loader extension
+        */
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         readonly onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+        * Observable that fires each time a material is loaded
+        */
         readonly onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires each time an extension is loaded
+        */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Observable that fires when the load has completed
+        */
         readonly onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * The current state of the loader
+        */
         readonly state: Nullable<GLTFLoaderState>;
+        /**
+        * Disposes of the loader
+        */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
         private _loadAsync(nodes, scene, data, rootUrl, onProgress?);
         private _loadExtensions();
@@ -983,12 +1295,18 @@ declare module BABYLON.GLTF2 {
         private _checkExtensions();
         private _createRootNode();
         private _loadNodesAsync(nodes);
+        /**
+        * @ignore
+        */
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
         private _forEachPrimitive(node, callback);
         private _getMeshes();
         private _getSkeletons();
         private _getAnimationGroups();
         private _startAnimations();
+        /**
+        * @ignore
+        */
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
         private _loadMeshAsync(context, node, mesh, babylonMesh);
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
@@ -998,31 +1316,58 @@ declare module BABYLON.GLTF2 {
         private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
+        private _loadBones(context, skin);
+        private _loadBone(node, skin, babylonBones);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
-        private _createBone(node, skin, parent, localMatrix, baseMatrix, index);
-        private _loadBones(context, skin, inverseBindMatricesData);
-        private _loadBone(node, skin, inverseBindMatricesData, babylonBones);
+        private _updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
         private _getNodeMatrix(node);
         private _loadAnimationsAsync();
         private _loadAnimationAsync(context, animation);
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadBufferAsync(context, buffer);
+        /**
+        * @ignore
+        */
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
+        /**
+        * @ignore
+        */
         _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
         private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
+        /**
+        * @ignore
+        */
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
+        /**
+        * @ignore
+        */
         _createMaterial<T extends Material>(type: MaterialConstructor<T>, name: string, drawMode: number): T;
+        /**
+        * @ignore
+        */
         _loadMaterialBasePropertiesAsync(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void>;
+        /**
+        * @ignore
+        */
         _loadMaterialAlphaProperties(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): void;
+        /**
+        * @ignore
+        */
         _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Promise<void>;
         private _loadSampler(context, sampler);
         private _loadImageAsync(context, image);
+        /**
+        * @ignore
+        */
         _loadUriAsync(context: string, uri: string): Promise<ArrayBufferView>;
         private _onProgress();
+        /**
+        * @ignore
+        */
         static _GetProperty<T>(context: string, array: ArrayLike<T> | undefined, index: number | undefined): T;
         private static _GetTextureWrapMode(context, mode);
         private static _GetTextureSamplingMode(context, magFilter?, minFilter?);
@@ -1032,12 +1377,18 @@ declare module BABYLON.GLTF2 {
         private _compileMaterialsAsync();
         private _compileShadowGeneratorsAsync();
         private _clear();
+        /**
+        * @ignore
+        */
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
     }
 }
 
 
 declare module BABYLON.GLTF2 {
+    /**
+     * Abstract class that can be implemented to extend existing gltf loader behavior.
+     */
     abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
         enabled: boolean;
         readonly abstract name: string;
@@ -1092,6 +1443,7 @@ declare module BABYLON.GLTF2.Extensions {
 }
 
 
+/** Module defining extensions to gltf */
 declare module BABYLON.GLTF2.Extensions {
     class KHR_draco_mesh_compression extends GLTFLoaderExtension {
         readonly name: string;

+ 268 - 44
dist/preview release/loaders/babylonjs.loaders.js

@@ -1001,6 +1001,9 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     var GLTFLoaderCoordinateSystemMode;
     (function (GLTFLoaderCoordinateSystemMode) {
         /**
@@ -1012,6 +1015,9 @@ var BABYLON;
          */
         GLTFLoaderCoordinateSystemMode[GLTFLoaderCoordinateSystemMode["FORCE_RIGHT_HANDED"] = 1] = "FORCE_RIGHT_HANDED";
     })(GLTFLoaderCoordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode || (BABYLON.GLTFLoaderCoordinateSystemMode = {}));
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     var GLTFLoaderAnimationStartMode;
     (function (GLTFLoaderAnimationStartMode) {
         /**
@@ -1027,6 +1033,9 @@ var BABYLON;
          */
         GLTFLoaderAnimationStartMode[GLTFLoaderAnimationStartMode["ALL"] = 2] = "ALL";
     })(GLTFLoaderAnimationStartMode = BABYLON.GLTFLoaderAnimationStartMode || (BABYLON.GLTFLoaderAnimationStartMode = {}));
+    /**
+    * Loading state
+    */
     var GLTFLoaderState;
     (function (GLTFLoaderState) {
         /**
@@ -1042,6 +1051,7 @@ var BABYLON;
          */
         GLTFLoaderState[GLTFLoaderState["COMPLETE"] = 2] = "COMPLETE";
     })(GLTFLoaderState = BABYLON.GLTFLoaderState || (BABYLON.GLTFLoaderState = {}));
+    /** File loader to load gltf files into a babylon scene */
     var GLTFFileLoader = /** @class */ (function () {
         function GLTFFileLoader() {
             // #region Common options
@@ -1054,23 +1064,28 @@ var BABYLON;
             // #endregion
             // #region V2 options
             /**
-             * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+             * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+             * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+             * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
              */
             this.coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
             /**
-             * The animation start mode (NONE, FIRST, ALL).
-             */
+            * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+            * - NONE - No animation will start.
+            * - FIRST - The first animation will start.
+            * - ALL - All animations will start.
+            */
             this.animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
             /**
-             * Set to true to compile materials before raising the success callback.
+             * Set to true to compile materials before raising the success callback. Defaults to false.
              */
             this.compileMaterials = false;
             /**
-             * Set to true to also compile materials with clip planes.
+             * Set to true to also compile materials with clip planes. Defaults to false.
              */
             this.useClipPlane = false;
             /**
-             * Set to true to compile shadow generators before raising the success callback.
+             * Set to true to compile shadow generators before raising the success callback. Defaults to false.
              */
             this.compileShadowGenerators = false;
             /**
@@ -1102,13 +1117,20 @@ var BABYLON;
             this.onExtensionLoadedObservable = new BABYLON.Observable();
             // #endregion
             this._loader = null;
+            /**
+             * Name of the loader ("gltf")
+             */
             this.name = "gltf";
+            /**
+             * Supported file extensions of the loader (.gltf, .glb)
+             */
             this.extensions = {
                 ".gltf": { isBinary: false },
                 ".glb": { isBinary: true }
             };
         }
         Object.defineProperty(GLTFFileLoader.prototype, "onParsed", {
+            /** Raised when the asset has been parsed. */
             set: function (callback) {
                 if (this._onParsedObserver) {
                     this.onParsedObservable.remove(this._onParsedObserver);
@@ -1119,6 +1141,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
+            /**
+             * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onMeshLoadedObserver) {
                     this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver);
@@ -1129,6 +1154,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", {
+            /**
+             * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onTextureLoadedObserver) {
                     this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver);
@@ -1139,6 +1167,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", {
+            /**
+             * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onMaterialLoadedObserver) {
                     this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver);
@@ -1149,6 +1180,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
+            /**
+             * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onCompleteObserver) {
                     this.onCompleteObservable.remove(this._onCompleteObserver);
@@ -1159,6 +1193,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
+            /**
+             * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onDisposeObserver) {
                     this.onDisposeObservable.remove(this._onDisposeObserver);
@@ -1169,6 +1206,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
+            /**
+             * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+             */
             set: function (callback) {
                 if (this._onExtensionLoadedObserver) {
                     this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
@@ -1214,6 +1254,15 @@ var BABYLON;
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
         };
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         GLTFFileLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -1222,6 +1271,14 @@ var BABYLON;
                 return _this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onProgress);
             });
         };
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         GLTFFileLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -1230,6 +1287,14 @@ var BABYLON;
                 return _this._loader.loadAsync(scene, loaderData, rootUrl, onProgress);
             });
         };
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         GLTFFileLoader.prototype.loadAssetContainerAsync = function (scene, data, rootUrl, onProgress) {
             var _this = this;
             return Promise.resolve().then(function () {
@@ -1246,9 +1311,18 @@ var BABYLON;
                 });
             });
         };
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         };
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         GLTFFileLoader.prototype.createPlugin = function () {
             return new GLTFFileLoader();
         };
@@ -1432,7 +1506,13 @@ var BABYLON;
         };
         // #endregion
         // #region V1 options
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         GLTFFileLoader.IncrementalLoading = true;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         GLTFFileLoader.HomogeneousCoordinates = false;
         return GLTFFileLoader;
     }());
@@ -2869,6 +2949,9 @@ var BABYLON;
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onExtensionLoadedObservable = new BABYLON.Observable();
+                /**
+                * State of the loader
+                */
                 this.state = null;
             }
             GLTFLoader.RegisterExtension = function (extension) {
@@ -2931,6 +3014,15 @@ var BABYLON;
                 }, onError);
                 return true;
             };
+            /**
+            * Imports one or more meshes from a loaded gltf file and adds them to the scene
+            * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+            * @param scene the scene the meshes should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise containg the loaded meshes, particles, skeletons and animations
+            */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return new Promise(function (resolve, reject) {
@@ -2970,6 +3062,14 @@ var BABYLON;
                     }, onError);
                 }, onError);
             };
+            /**
+            * Imports all objects from a loaded gltf file and adds them to the scene
+            * @param scene the scene the objects should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise which completes when objects have been loaded to the scene
+            */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return new Promise(function (resolve, reject) {
@@ -3653,9 +3753,11 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /** Array item helper methods */
         var ArrayItem = /** @class */ (function () {
             function ArrayItem() {
             }
+            /** Sets the index of each array element to its index in the array */
             ArrayItem.Assign = function (values) {
                 if (values) {
                     for (var index = 0; index < values.length; index++) {
@@ -3677,12 +3779,21 @@ var BABYLON;
 //# sourceMappingURL=babylon.glTFLoaderInterfaces.js.map
 
 
+/**
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
+*/
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /**
+        * Used to load from a GLTF2 file
+        */
         var GLTFLoader = /** @class */ (function () {
             function GLTFLoader() {
+                /**
+                * @ignore
+                */
                 this._completePromises = new Array();
                 this._disposed = false;
                 this._state = null;
@@ -3690,18 +3801,56 @@ var BABYLON;
                 this._defaultSampler = {};
                 this._defaultBabylonMaterials = {};
                 this._requests = new Array();
+                /**
+                * Coordinate system that will be used when loading from the gltf file
+                */
                 this.coordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode.AUTO;
+                /**
+                * Animation mode that determines which animations should be started when a file is loaded
+                */
                 this.animationStartMode = BABYLON.GLTFLoaderAnimationStartMode.FIRST;
+                /**
+                * If the materials in the file should automatically be compiled
+                */
                 this.compileMaterials = false;
+                /**
+                * If a clip plane should be usede when loading meshes in the file
+                */
                 this.useClipPlane = false;
+                /**
+                * If shadow generators should automatically be compiled
+                */
                 this.compileShadowGenerators = false;
+                /**
+                * Observable that fires when the loader is disposed
+                */
                 this.onDisposeObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a mesh is loaded
+                */
                 this.onMeshLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a texture is loaded
+                */
                 this.onTextureLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time a material is loaded
+                */
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires each time an extension is loaded
+                */
                 this.onExtensionLoadedObservable = new BABYLON.Observable();
+                /**
+                * Observable that fires when the load has completed
+                */
                 this.onCompleteObservable = new BABYLON.Observable();
             }
+            /**
+            * @ignore, registers the loader
+            * @param name name of the loader
+            * @param factory function that converts a loader to a loader extension
+            */
             GLTFLoader._Register = function (name, factory) {
                 if (GLTFLoader._Factories[name]) {
                     BABYLON.Tools.Error("Extension with the name '" + name + "' already exists");
@@ -3712,12 +3861,18 @@ var BABYLON;
                 GLTFLoader._Names.push(name);
             };
             Object.defineProperty(GLTFLoader.prototype, "state", {
+                /**
+                * The current state of the loader
+                */
                 get: function () {
                     return this._state;
                 },
                 enumerable: true,
                 configurable: true
             });
+            /**
+            * Disposes of the loader
+            */
             GLTFLoader.prototype.dispose = function () {
                 if (this._disposed) {
                     return;
@@ -3727,6 +3882,15 @@ var BABYLON;
                 this.onDisposeObservable.clear();
                 this._clear();
             };
+            /**
+            * Imports one or more meshes from a loaded gltf file and adds them to the scene
+            * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+            * @param scene the scene the meshes should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise containg the loaded meshes, particles, skeletons and animations
+            */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return Promise.resolve().then(function () {
@@ -3760,6 +3924,14 @@ var BABYLON;
                     });
                 });
             };
+            /**
+            * Imports all objects from a loaded gltf file and adds them to the scene
+            * @param scene the scene the objects should be added to
+            * @param data gltf data containing information of the meshes in a loaded file
+            * @param rootUrl root url to load from
+            * @param onProgress event that fires when loading progress has occured
+            * @returns a promise which completes when objects have been loaded to the scene
+            */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
                 return this._loadAsync(null, scene, data, rootUrl, onProgress);
             };
@@ -3917,6 +4089,9 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadSceneAsync = function (context, scene) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadSceneAsync(this, context, scene);
                 if (promise) {
@@ -4016,6 +4191,9 @@ var BABYLON;
                     }
                 }
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadNodeAsync = function (context, node) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadNodeAsync(this, context, node);
                 if (promise) {
@@ -4045,7 +4223,6 @@ var BABYLON;
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
-                // TODO: instancing
                 var _this = this;
                 var promises = new Array();
                 var primitives = mesh.primitives;
@@ -4247,9 +4424,9 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadSkinAsync = function (context, node, mesh, skin) {
                 var _this = this;
-                var assignSkeleton = function () {
+                var assignSkeleton = function (skeleton) {
                     _this._forEachPrimitive(node, function (babylonMesh) {
-                        babylonMesh.skeleton = skin._babylonSkeleton;
+                        babylonMesh.skeleton = skeleton;
                     });
                     // Ignore the TRS of skinned nodes.
                     // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
@@ -4260,61 +4437,68 @@ var BABYLON;
                 };
                 if (skin._loaded) {
                     return skin._loaded.then(function () {
-                        assignSkeleton();
+                        assignSkeleton(skin._babylonSkeleton);
                     });
                 }
-                // TODO: split into two parts so that bones are created before inverseBindMatricesData is loaded (for compiling materials).
+                var skeletonId = "skeleton" + skin._index;
+                var babylonSkeleton = new BABYLON.Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
+                skin._babylonSkeleton = babylonSkeleton;
+                this._loadBones(context, skin);
+                assignSkeleton(babylonSkeleton);
                 return (skin._loaded = this._loadSkinInverseBindMatricesDataAsync(context, skin).then(function (inverseBindMatricesData) {
-                    var skeletonId = "skeleton" + skin._index;
-                    var babylonSkeleton = new BABYLON.Skeleton(skin.name || skeletonId, skeletonId, _this._babylonScene);
-                    skin._babylonSkeleton = babylonSkeleton;
-                    _this._loadBones(context, skin, inverseBindMatricesData);
-                    assignSkeleton();
+                    _this._updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
                 }));
             };
-            GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) {
-                if (skin.inverseBindMatrices == undefined) {
-                    return Promise.resolve(null);
-                }
-                var accessor = GLTFLoader._GetProperty(context + "/inverseBindMatrices", this._gltf.accessors, skin.inverseBindMatrices);
-                return this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                    return data;
-                });
-            };
-            GLTFLoader.prototype._createBone = function (node, skin, parent, localMatrix, baseMatrix, index) {
-                var babylonBone = new BABYLON.Bone(node.name || "joint" + node._index, skin._babylonSkeleton, parent, localMatrix, null, baseMatrix, index);
-                node._babylonAnimationTargets = node._babylonAnimationTargets || [];
-                node._babylonAnimationTargets.push(babylonBone);
-                return babylonBone;
-            };
-            GLTFLoader.prototype._loadBones = function (context, skin, inverseBindMatricesData) {
+            GLTFLoader.prototype._loadBones = function (context, skin) {
                 var babylonBones = {};
                 for (var _i = 0, _a = skin.joints; _i < _a.length; _i++) {
                     var index = _a[_i];
                     var node = GLTFLoader._GetProperty(context + "/joints/" + index, this._gltf.nodes, index);
-                    this._loadBone(node, skin, inverseBindMatricesData, babylonBones);
+                    this._loadBone(node, skin, babylonBones);
                 }
             };
-            GLTFLoader.prototype._loadBone = function (node, skin, inverseBindMatricesData, babylonBones) {
+            GLTFLoader.prototype._loadBone = function (node, skin, babylonBones) {
                 var babylonBone = babylonBones[node._index];
                 if (babylonBone) {
                     return babylonBone;
                 }
-                var boneIndex = skin.joints.indexOf(node._index);
-                var baseMatrix = BABYLON.Matrix.Identity();
-                if (inverseBindMatricesData && boneIndex !== -1) {
-                    baseMatrix = BABYLON.Matrix.FromArray(inverseBindMatricesData, boneIndex * 16);
-                    baseMatrix.invertToRef(baseMatrix);
-                }
                 var babylonParentBone = null;
                 if (node._parent._babylonMesh !== this._rootBabylonMesh) {
-                    babylonParentBone = this._loadBone(node._parent, skin, inverseBindMatricesData, babylonBones);
-                    baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
+                    babylonParentBone = this._loadBone(node._parent, skin, babylonBones);
                 }
-                babylonBone = this._createBone(node, skin, babylonParentBone, this._getNodeMatrix(node), baseMatrix, boneIndex);
+                var boneIndex = skin.joints.indexOf(node._index);
+                babylonBone = new BABYLON.Bone(node.name || "joint" + node._index, skin._babylonSkeleton, babylonParentBone, this._getNodeMatrix(node), null, null, boneIndex);
                 babylonBones[node._index] = babylonBone;
+                node._babylonAnimationTargets = node._babylonAnimationTargets || [];
+                node._babylonAnimationTargets.push(babylonBone);
                 return babylonBone;
             };
+            GLTFLoader.prototype._loadSkinInverseBindMatricesDataAsync = function (context, skin) {
+                if (skin.inverseBindMatrices == undefined) {
+                    return Promise.resolve(null);
+                }
+                var accessor = GLTFLoader._GetProperty(context + "/inverseBindMatrices", this._gltf.accessors, skin.inverseBindMatrices);
+                return this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                    return data;
+                });
+            };
+            GLTFLoader.prototype._updateBoneMatrices = function (babylonSkeleton, inverseBindMatricesData) {
+                for (var _i = 0, _a = babylonSkeleton.bones; _i < _a.length; _i++) {
+                    var babylonBone = _a[_i];
+                    var baseMatrix = BABYLON.Matrix.Identity();
+                    var boneIndex = babylonBone._index;
+                    if (inverseBindMatricesData && boneIndex !== -1) {
+                        BABYLON.Matrix.FromArrayToRef(inverseBindMatricesData, boneIndex * 16, baseMatrix);
+                        baseMatrix.invertToRef(baseMatrix);
+                    }
+                    var babylonParentBone = babylonBone.getParent();
+                    if (babylonParentBone) {
+                        baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
+                    }
+                    babylonBone.updateMatrix(baseMatrix, false, false);
+                    babylonBone._updateDifferenceMatrix(undefined, false);
+                }
+            };
             GLTFLoader.prototype._getNodeMatrix = function (node) {
                 return node.matrix ?
                     BABYLON.Matrix.FromArray(node.matrix) :
@@ -4467,7 +4651,9 @@ var BABYLON;
                             }); }));
                             var morphTargets = new Array();
                             _this._forEachPrimitive(targetNode, function (babylonMesh) {
-                                morphTargets.push(babylonMesh.morphTargetManager.getTarget(targetIndex));
+                                var morphTarget = babylonMesh.morphTargetManager.getTarget(targetIndex);
+                                morphTarget.animations.push(babylonAnimation);
+                                morphTargets.push(morphTarget);
                             });
                             babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                         };
@@ -4480,6 +4666,10 @@ var BABYLON;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode._babylonAnimationTargets) {
+                            for (var _i = 0, _a = targetNode._babylonAnimationTargets; _i < _a.length; _i++) {
+                                var babylonAnimationTarget = _a[_i];
+                                babylonAnimationTarget.animations.push(babylonAnimation);
+                            }
                             babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                         }
                     }
@@ -4530,6 +4720,9 @@ var BABYLON;
                 buffer._data = this._loadUriAsync(context, buffer.uri);
                 return buffer._data;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadBufferViewAsync = function (context, bufferView) {
                 if (bufferView._data) {
                     return bufferView._data;
@@ -4588,6 +4781,9 @@ var BABYLON;
                 });
                 return accessor._data;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
                 var _this = this;
                 if (bufferView._babylonBuffer) {
@@ -4657,6 +4853,9 @@ var BABYLON;
                 this._loadMaterialAlphaProperties(context, material, babylonMaterial);
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
                 if (promise) {
@@ -4682,12 +4881,18 @@ var BABYLON;
                 assign(babylonData.material);
                 return babylonData.loaded;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._createMaterial = function (type, name, drawMode) {
                 var babylonMaterial = new type(name, this._babylonScene);
                 babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? BABYLON.Material.CounterClockWiseSideOrientation : BABYLON.Material.ClockWiseSideOrientation;
                 babylonMaterial.fillMode = drawMode;
                 return babylonMaterial;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialBasePropertiesAsync = function (context, material, babylonMaterial) {
                 var promises = new Array();
                 babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
@@ -4721,6 +4926,9 @@ var BABYLON;
                 }
                 return Promise.all(promises).then(function () { });
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadMaterialAlphaProperties = function (context, material, babylonMaterial) {
                 var alphaMode = material.alphaMode || "OPAQUE" /* OPAQUE */;
                 switch (alphaMode) {
@@ -4749,6 +4957,9 @@ var BABYLON;
                     }
                 }
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
                 var _this = this;
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
@@ -4808,6 +5019,9 @@ var BABYLON;
                 });
                 return image._objectURL;
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._loadUriAsync = function (context, uri) {
                 var _this = this;
                 var promise = GLTF2.GLTFLoaderExtension._LoadUriAsync(this, context, uri);
@@ -4865,6 +5079,9 @@ var BABYLON;
                 }
                 this._progressCallback(new BABYLON.SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
             };
+            /**
+            * @ignore
+            */
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !array[index]) {
                     throw new Error(context + ": Failed to find index (" + index + ")");
@@ -5013,6 +5230,9 @@ var BABYLON;
                 this.onTextureLoadedObservable.clear();
                 this.onMaterialLoadedObservable.clear();
             };
+            /**
+            * @ignore
+            */
             GLTFLoader.prototype._applyExtensions = function (actionAsync) {
                 for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
                     var name_5 = _a[_i];
@@ -5042,6 +5262,9 @@ var BABYLON;
 (function (BABYLON) {
     var GLTF2;
     (function (GLTF2) {
+        /**
+         * Abstract class that can be implemented to extend existing gltf loader behavior.
+         */
         var GLTFLoaderExtension = /** @class */ (function () {
             function GLTFLoaderExtension(loader) {
                 this.enabled = true;
@@ -5273,6 +5496,7 @@ var BABYLON;
 
 
 
+/** Module defining extensions to gltf */
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


+ 361 - 9
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -103,6 +103,9 @@ declare module BABYLON {
 
 
 declare module BABYLON {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     enum GLTFLoaderCoordinateSystemMode {
         /**
          * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
@@ -113,6 +116,9 @@ declare module BABYLON {
          */
         FORCE_RIGHT_HANDED = 1,
     }
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     enum GLTFLoaderAnimationStartMode {
         /**
          * No animation will start.
@@ -127,10 +133,22 @@ declare module BABYLON {
          */
         ALL = 2,
     }
+    /**
+    * Loaded gltf data
+    */
     interface IGLTFLoaderData {
+        /**
+        * Loaded json string converted to an object
+        */
         json: Object;
+        /**
+        * Loaded ArrayBufferView
+        */
         bin: Nullable<ArrayBufferView>;
     }
+    /**
+    * Gltf extension interface
+    */
     interface IGLTFLoaderExtension {
         /**
          * The name of this extension.
@@ -141,6 +159,9 @@ declare module BABYLON {
          */
         enabled: boolean;
     }
+    /**
+    * Loading state
+    */
     enum GLTFLoaderState {
         /**
          * The asset is loading.
@@ -155,29 +176,77 @@ declare module BABYLON {
          */
         COMPLETE = 2,
     }
+    /**
+    * GLTF loader interface
+    */
     interface IGLTFLoader extends IDisposable {
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+       * Observable that fires each time a material is loaded
+       */
         onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires when the load has completed
+        */
         onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fire when an extension is loaded
+        */
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Loader state
+        */
         state: Nullable<GLTFLoaderState>;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        */
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        */
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<void>;
     }
+    /** File loader to load gltf files into a babylon scene */
     class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
+        /** Creates a gltf 1.0 file loader */
         static CreateGLTFLoaderV1: () => IGLTFLoader;
+        /** Creates a gltf 2.0 file loader */
         static CreateGLTFLoaderV2: () => IGLTFLoader;
         /**
          * Raised when the asset has been parsed.
@@ -186,27 +255,39 @@ declare module BABYLON {
          */
         onParsedObservable: Observable<IGLTFLoaderData>;
         private _onParsedObserver;
+        /** Raised when the asset has been parsed. */
         onParsed: (loaderData: IGLTFLoaderData) => void;
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         static IncrementalLoading: boolean;
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         static HomogeneousCoordinates: boolean;
         /**
-         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+         * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+         * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
          */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         /**
-         * The animation start mode (NONE, FIRST, ALL).
-         */
+        * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+        * - NONE - No animation will start.
+        * - FIRST - The first animation will start.
+        * - ALL - All animations will start.
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
         /**
-         * Set to true to compile materials before raising the success callback.
+         * Set to true to compile materials before raising the success callback. Defaults to false.
          */
         compileMaterials: boolean;
         /**
-         * Set to true to also compile materials with clip planes.
+         * Set to true to also compile materials with clip planes. Defaults to false.
          */
         useClipPlane: boolean;
         /**
-         * Set to true to compile shadow generators before raising the success callback.
+         * Set to true to compile shadow generators before raising the success callback. Defaults to false.
          */
         compileShadowGenerators: boolean;
         /**
@@ -214,18 +295,27 @@ declare module BABYLON {
          */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         private _onMeshLoadedObserver;
+        /**
+         * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+         */
         onMeshLoaded: (mesh: AbstractMesh) => void;
         /**
          * Raised when the loader creates a texture after parsing the glTF properties of the texture.
          */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         private _onTextureLoadedObserver;
+        /**
+         * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+         */
         onTextureLoaded: (texture: BaseTexture) => void;
         /**
          * Raised when the loader creates a material after parsing the glTF properties of the material.
          */
         readonly onMaterialLoadedObservable: Observable<Material>;
         private _onMaterialLoadedObserver;
+        /**
+         * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+         */
         onMaterialLoaded: (material: Material) => void;
         /**
          * Raised when the asset is completely loaded, immediately before the loader is disposed.
@@ -234,12 +324,18 @@ declare module BABYLON {
          */
         readonly onCompleteObservable: Observable<GLTFFileLoader>;
         private _onCompleteObserver;
+        /**
+         * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+         */
         onComplete: () => void;
         /**
         * Raised after the loader is disposed.
         */
         readonly onDisposeObservable: Observable<GLTFFileLoader>;
         private _onDisposeObserver;
+        /**
+         * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+         */
         onDispose: () => void;
         /**
          * Raised after a loader extension is created.
@@ -247,6 +343,9 @@ declare module BABYLON {
          */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         private _onExtensionLoadedObserver;
+        /**
+         * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+         */
         onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
          * Returns a promise that resolves when the asset is completely loaded.
@@ -258,22 +357,65 @@ declare module BABYLON {
          */
         readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
+        /**
+         * Name of the loader ("gltf")
+         */
         name: string;
+        /**
+         * Supported file extensions of the loader (.gltf, .glb)
+         */
         extensions: ISceneLoaderPluginExtensions;
         /**
          * Disposes the loader, releases resources during load, and cancels any outstanding requests.
          */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         loadAssetContainerAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<AssetContainer>;
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         canDirectLoad(data: string): boolean;
+        /**
+         * Rewrites a url by combining a root url and response url
+         */
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
         private _parse(data);
         private _getLoader(loaderData);
@@ -690,9 +832,21 @@ declare module BABYLON.GLTF1 {
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * State of the loader
+        */
         state: Nullable<GLTFLoaderState>;
         dispose(): void;
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress?, onError?);
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
@@ -700,6 +854,14 @@ declare module BABYLON.GLTF1 {
             animationGroups: AnimationGroup[];
         }>;
         private _loadAsync(scene, data, rootUrl, onSuccess, onProgress?, onError?);
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
         private _loadShadersAsync(gltfRuntime, onload);
         private _loadBuffersAsync(gltfRuntime, onLoad, onProgress?);
@@ -844,48 +1006,84 @@ declare module BABYLON.GLTF1 {
 
 
 declare module BABYLON.GLTF2 {
+    /** Array item which contains it's index in an array */
     interface IArrayItem {
         _index: number;
     }
+    /** Array item helper methods */
     class ArrayItem {
+        /** Sets the index of each array element to its index in the array */
         static Assign(values?: IArrayItem[]): void;
     }
 }
 
 
 
+/**
+ * GLTF2 module for babylon
+ */
 declare module BABYLON.GLTF2 {
+    /**
+     * Interface to access data and vertex buffer associated with a file
+     */
     interface ILoaderAccessor extends IAccessor, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
+    /**
+     * Loader's animation channel
+     */
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
+    /**
+     * Container for animation keyframe data
+     */
     interface ILoaderAnimationSamplerData {
         input: Float32Array;
         interpolation: AnimationSamplerInterpolation;
         output: Float32Array;
     }
+    /**
+     * Keyframe data
+     */
     interface ILoaderAnimationSampler extends IAnimationSampler, IArrayItem {
         _data: Promise<ILoaderAnimationSamplerData>;
     }
+    /**
+     * Loader animation
+     */
     interface ILoaderAnimation extends IAnimation, IArrayItem {
         channels: ILoaderAnimationChannel[];
         samplers: ILoaderAnimationSampler[];
         _babylonAnimationGroup?: AnimationGroup;
     }
+    /**
+     * Loader buffer
+     */
     interface ILoaderBuffer extends IBuffer, IArrayItem {
         _data?: Promise<ArrayBufferView>;
     }
+    /**
+     * Loader's buffer data
+     */
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonBuffer?: Promise<Buffer>;
     }
+    /**
+     * Loader's loaded camera data
+     */
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
+    /**
+     * Loaded image specified by url
+     */
     interface ILoaderImage extends IImage, IArrayItem {
         _objectURL?: Promise<string>;
     }
+    /**
+     * Loaded material data
+     */
     interface ILoaderMaterial extends IMaterial, IArrayItem {
         _babylonData?: {
             [drawMode: number]: {
@@ -895,11 +1093,20 @@ declare module BABYLON.GLTF2 {
             };
         };
     }
+    /**
+     * Loader mesh data
+     */
     interface ILoaderMesh extends IMesh, IArrayItem {
         primitives: ILoaderMeshPrimitive[];
     }
+    /**
+     * Loader mesh data
+     */
     interface ILoaderMeshPrimitive extends IMeshPrimitive, IArrayItem {
     }
+    /**
+     * Node for traversing loader data
+     */
     interface ILoaderNode extends INode, IArrayItem {
         _parent: ILoaderNode;
         _babylonMesh?: Mesh;
@@ -907,23 +1114,41 @@ declare module BABYLON.GLTF2 {
         _babylonAnimationTargets?: Node[];
         _numMorphTargets?: number;
     }
+    /**
+     * Sampler data
+     */
     interface ILoaderSamplerData {
         noMipMaps: boolean;
         samplingMode: number;
         wrapU: number;
         wrapV: number;
     }
+    /**
+     * Sampler data
+     */
     interface ILoaderSampler extends ISampler, IArrayItem {
         _data?: ILoaderSamplerData;
     }
+    /**
+     * Loader's scene
+     */
     interface ILoaderScene extends IScene, IArrayItem {
     }
+    /**
+     * Loader's skeleton data
+     */
     interface ILoaderSkin extends ISkin, IArrayItem {
         _babylonSkeleton?: Skeleton;
         _loaded?: Promise<void>;
     }
+    /**
+     * Loader's texture
+     */
     interface ILoaderTexture extends ITexture, IArrayItem {
     }
+    /**
+     * Loaded GLTF data
+     */
     interface ILoaderGLTF extends IGLTF {
         accessors?: ILoaderAccessor[];
         animations?: ILoaderAnimation[];
@@ -942,14 +1167,40 @@ declare module BABYLON.GLTF2 {
 }
 
 
+/**
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
+*/
 declare module BABYLON.GLTF2 {
+    /**
+    * Interface for a meterial with a constructor
+    */
     interface MaterialConstructor<T extends Material> {
+        /**
+        * The material class
+        */
         readonly prototype: T;
+        /**
+        * Instatiates a material
+        * @param name name of the material
+        * @param scene the scene the material will be added to
+        */
         new (name: string, scene: Scene): T;
     }
+    /**
+    * Used to load from a GLTF2 file
+    */
     class GLTFLoader implements IGLTFLoader {
+        /**
+        * @ignore
+        */
         _gltf: ILoaderGLTF;
+        /**
+        * @ignore
+        */
         _babylonScene: Scene;
+        /**
+        * @ignore
+        */
         _completePromises: Promise<void>[];
         private _disposed;
         private _state;
@@ -962,26 +1213,87 @@ declare module BABYLON.GLTF2 {
         private _requests;
         private static _Names;
         private static _Factories;
+        /**
+        * @ignore, registers the loader
+        * @param name name of the loader
+        * @param factory function that converts a loader to a loader extension
+        */
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         readonly onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
+        /**
+        * Observable that fires each time a material is loaded
+        */
         readonly onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires each time an extension is loaded
+        */
         readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        /**
+        * Observable that fires when the load has completed
+        */
         readonly onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * The current state of the loader
+        */
         readonly state: Nullable<GLTFLoaderState>;
+        /**
+        * Disposes of the loader
+        */
         dispose(): void;
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             skeletons: Skeleton[];
             animationGroups: AnimationGroup[];
         }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void>;
         private _loadAsync(nodes, scene, data, rootUrl, onProgress?);
         private _loadExtensions();
@@ -990,12 +1302,18 @@ declare module BABYLON.GLTF2 {
         private _checkExtensions();
         private _createRootNode();
         private _loadNodesAsync(nodes);
+        /**
+        * @ignore
+        */
         _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void>;
         private _forEachPrimitive(node, callback);
         private _getMeshes();
         private _getSkeletons();
         private _getAnimationGroups();
         private _startAnimations();
+        /**
+        * @ignore
+        */
         _loadNodeAsync(context: string, node: ILoaderNode): Promise<void>;
         private _loadMeshAsync(context, node, mesh, babylonMesh);
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
@@ -1005,31 +1323,58 @@ declare module BABYLON.GLTF2 {
         private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
+        private _loadBones(context, skin);
+        private _loadBone(node, skin, babylonBones);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
-        private _createBone(node, skin, parent, localMatrix, baseMatrix, index);
-        private _loadBones(context, skin, inverseBindMatricesData);
-        private _loadBone(node, skin, inverseBindMatricesData, babylonBones);
+        private _updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
         private _getNodeMatrix(node);
         private _loadAnimationsAsync();
         private _loadAnimationAsync(context, animation);
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadBufferAsync(context, buffer);
+        /**
+        * @ignore
+        */
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
+        /**
+        * @ignore
+        */
         _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
         private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
+        /**
+        * @ignore
+        */
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
+        /**
+        * @ignore
+        */
         _createMaterial<T extends Material>(type: MaterialConstructor<T>, name: string, drawMode: number): T;
+        /**
+        * @ignore
+        */
         _loadMaterialBasePropertiesAsync(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void>;
+        /**
+        * @ignore
+        */
         _loadMaterialAlphaProperties(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): void;
+        /**
+        * @ignore
+        */
         _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Promise<void>;
         private _loadSampler(context, sampler);
         private _loadImageAsync(context, image);
+        /**
+        * @ignore
+        */
         _loadUriAsync(context: string, uri: string): Promise<ArrayBufferView>;
         private _onProgress();
+        /**
+        * @ignore
+        */
         static _GetProperty<T>(context: string, array: ArrayLike<T> | undefined, index: number | undefined): T;
         private static _GetTextureWrapMode(context, mode);
         private static _GetTextureSamplingMode(context, magFilter?, minFilter?);
@@ -1039,12 +1384,18 @@ declare module BABYLON.GLTF2 {
         private _compileMaterialsAsync();
         private _compileShadowGeneratorsAsync();
         private _clear();
+        /**
+        * @ignore
+        */
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
     }
 }
 
 
 declare module BABYLON.GLTF2 {
+    /**
+     * Abstract class that can be implemented to extend existing gltf loader behavior.
+     */
     abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
         enabled: boolean;
         readonly abstract name: string;
@@ -1099,6 +1450,7 @@ declare module BABYLON.GLTF2.Extensions {
 }
 
 
+/** Module defining extensions to gltf */
 declare module BABYLON.GLTF2.Extensions {
     class KHR_draco_mesh_compression extends GLTFLoaderExtension {
         readonly name: string;

+ 2 - 2
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "3.2.0-beta.4"
+        "babylonjs-gltf2interface": "3.2.0-beta.5"
     },
     "peerDependencies": {
         "babylonjs": ">=3.2.0-alpha"

+ 1 - 1
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 2
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "3.2.0-beta.4"
+        "babylonjs-gltf2interface": "3.2.0-beta.5"
     },
     "peerDependencies": {
         "babylonjs": ">=3.2.0-alpha"

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 819 - 2387
dist/preview release/typedocValidationBaseline.json


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 50 - 50
dist/preview release/viewer/babylon.viewer.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1244 - 392
dist/preview release/viewer/babylon.viewer.max.js


+ 1 - 1
dist/preview release/viewer/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-viewer",
     "description": "A simple-to-use viewer based on BabylonJS to display 3D elements natively",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 4 - 0
dist/preview release/what's new.md

@@ -114,6 +114,7 @@
 - Added unlit material extension support to glTF 2.0 loader. ([bghgary](https://github.com/bghgary))
 - (Viewer) Viewer's declaration file automatically generated ([RaananW](https://github.com/RaananW))
 - New serialize and parse functions for effect layers (Highlight and Glow layers) ([julien-moreau](https://github.com/julien-moreau))
+- Added alphaCutOff support for StandardMaterial ([deltakosh](https://github.com/deltakosh))
 
 ## Bug fixes
 
@@ -146,3 +147,6 @@
 - Engine's onCanvasPointerOutObservable will now return a PointerEvent instead of the Engine. ([trevordev](https://github.com/trevordev))
 - Removed public references to default rendering pipeline's internal post process ([trevordev](https://github.com/trevordev))
 - `Bone.setScale` does not support scaleChildren property anymore. You can use `Bone.scale` to achieve the same effect ([deltakosh](https://github.com/deltakosh))
+- Vector3 &amp; Vector4:
+    - `MinimizeInPlace` has been renamed to `minimizeInPlace`
+    - `MaximizeInPlace` has been renamed to `maximizeInPlace`

+ 2 - 1
gui/readme.md

@@ -2,4 +2,5 @@
 The Babylon.js GUI library is an extension you can use to generate interactive user interface.
 It is build on top of the DynamicTexture.
 
-Documentation: http://doc.babylonjs.com/overviews/gui
+Documentation: http://doc.babylonjs.com/how_to/gui
+API: http://doc.babylonjs.com/api/modules/babylon.gui

+ 15 - 0
gui/src/advancedDynamicTexture.ts

@@ -309,6 +309,21 @@ module BABYLON.GUI {
             return this._fullscreenViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
         }
 
+        public getProjectedPosition(position: Vector3, worldMatrix: Matrix): Vector2 {
+            var scene = this.getScene();
+
+            if (!scene) {
+                return Vector2.Zero();
+            }
+
+            var globalViewport = this._getGlobalViewport(scene);
+            var projectedPosition = Vector3.Project(position, worldMatrix, scene.getTransformMatrix(), globalViewport);
+
+            projectedPosition.scaleInPlace(this.renderScale);
+            
+            return new Vector2(projectedPosition.x, projectedPosition.y);
+        }
+
         private _checkUpdate(camera: Camera): void {
             if (this._layerToDispose) {
                 if ((camera.layerMask & this._layerToDispose.layerMask) === 0) {

+ 1 - 1
inspector/sass/defines.scss

@@ -20,5 +20,5 @@ $background-lighter2: lighten($color: $background-lighter, $amount : 5%);
 $background-lighter3: lighten($color: $background-lighter2, $amount: 5%);
 
 $resizebar-width    : 10px;
-$tabbar-height      : 32px;
+$tabbar-height      : 40px;
 $searchbar-height   : 30px;

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

@@ -1576,6 +1576,9 @@ module BABYLON.GLTF1 {
         public onCompleteObservable = new Observable<IGLTFLoader>();
         public onExtensionLoadedObservable = new Observable<IGLTFLoaderExtension>();
 
+        /**
+        * State of the loader
+        */
         public state: Nullable<GLTFLoaderState> = null;
 
         public dispose(): void {}
@@ -1644,6 +1647,15 @@ module BABYLON.GLTF1 {
             return true;
         }
 
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         public importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{ meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
             return new Promise((resolve, reject) => {
                 this._importMeshAsync(meshesNames, scene, data, rootUrl, (meshes, skeletons) => {
@@ -1687,6 +1699,14 @@ module BABYLON.GLTF1 {
             }, onError);
         }
 
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         public loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void> {
             return new Promise((resolve, reject) => {
                 this._loadAsync(scene, data, rootUrl, () => {

+ 1 - 0
loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts

@@ -1,5 +1,6 @@
 /// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
 
+/** Module defining extensions to gltf */
 module BABYLON.GLTF2.Extensions {
     // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
 

+ 173 - 45
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -1,5 +1,8 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
+/**
+* Defines the GLTF2 module used to import/export GLTF 2.0 files
+*/
 module BABYLON.GLTF2 {
     interface IFileRequestInfo extends IFileRequest {
         _lengthComputable?: boolean;
@@ -7,14 +10,37 @@ module BABYLON.GLTF2 {
         _total?: number;
     }
 
+    /**
+    * Interface for a meterial with a constructor
+    */
     export interface MaterialConstructor<T extends Material> {
+        /**
+        * The material class
+        */
         readonly prototype: T;
+        /**
+        * Instatiates a material
+        * @param name name of the material
+        * @param scene the scene the material will be added to
+        */
         new(name: string, scene: Scene): T;
     }
 
+    /**
+    * Used to load from a GLTF2 file
+    */
     export class GLTFLoader implements IGLTFLoader {
+        /**
+        * @ignore
+        */
         public _gltf: ILoaderGLTF;
+        /**
+        * @ignore
+        */
         public _babylonScene: Scene;
+        /**
+        * @ignore
+        */
         public _completePromises = new Array<Promise<void>>();
 
         private _disposed = false;
@@ -29,6 +55,11 @@ module BABYLON.GLTF2 {
 
         private static _Names = new Array<string>();
         private static _Factories: { [name: string]: (loader: GLTFLoader) => GLTFLoaderExtension } = {};
+        /**
+        * @ignore, registers the loader
+        * @param name name of the loader
+        * @param factory function that converts a loader to a loader extension
+        */
         public static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void {
             if (GLTFLoader._Factories[name]) {
                 Tools.Error(`Extension with the name '${name}' already exists`);
@@ -41,23 +72,62 @@ module BABYLON.GLTF2 {
             GLTFLoader._Names.push(name);
         }
 
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         public coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         public animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         public compileMaterials = false;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         public useClipPlane = false;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         public compileShadowGenerators = false;
 
+        /**
+        * Observable that fires when the loader is disposed
+        */
         public readonly onDisposeObservable = new Observable<IGLTFLoader>();
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         public readonly onMeshLoadedObservable = new Observable<AbstractMesh>();
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         public readonly onTextureLoadedObservable = new Observable<BaseTexture>();
+        /**
+        * Observable that fires each time a material is loaded
+        */
         public readonly onMaterialLoadedObservable = new Observable<Material>();
+        /**
+        * Observable that fires each time an extension is loaded
+        */
         public readonly onExtensionLoadedObservable = new Observable<IGLTFLoaderExtension>();
+        /**
+        * Observable that fires when the load has completed
+        */
         public readonly onCompleteObservable = new Observable<IGLTFLoader>();
 
+        /**
+        * The current state of the loader
+        */
         public get state(): Nullable<GLTFLoaderState> {
             return this._state;
         }
 
+        /**
+        * Disposes of the loader
+        */
         public dispose(): void {
             if (this._disposed) {
                 return;
@@ -71,6 +141,15 @@ module BABYLON.GLTF2 {
             this._clear();
         }
 
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         public importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{ meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
             return Promise.resolve().then(() => {
                 let nodes: Nullable<Array<ILoaderNode>> = null;
@@ -107,6 +186,14 @@ module BABYLON.GLTF2 {
             });
         }
 
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         public loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void> {
             return this._loadAsync(null, scene, data, rootUrl, onProgress);
         }
@@ -286,6 +373,9 @@ module BABYLON.GLTF2 {
             return Promise.all(promises).then(() => {});
         }
 
+        /**
+        * @ignore
+        */
         public _loadSceneAsync(context: string, scene: ILoaderScene): Promise<void> {
             const promise = GLTFLoaderExtension._LoadSceneAsync(this, context, scene);
             if (promise) {
@@ -396,6 +486,9 @@ module BABYLON.GLTF2 {
             }
         }
 
+        /**
+        * @ignore
+        */
         public _loadNodeAsync(context: string, node: ILoaderNode): Promise<void> {
             const promise = GLTFLoaderExtension._LoadNodeAsync(this, context, node);
             if (promise) {
@@ -434,8 +527,6 @@ module BABYLON.GLTF2 {
         }
 
         private _loadMeshAsync(context: string, node: ILoaderNode, mesh: ILoaderMesh, babylonMesh: Mesh): Promise<void> {
-            // TODO: instancing
-
             const promises = new Array<Promise<void>>();
 
             const primitives = mesh.primitives;
@@ -669,9 +760,9 @@ module BABYLON.GLTF2 {
         }
 
         private _loadSkinAsync(context: string, node: ILoaderNode, mesh: ILoaderMesh, skin: ILoaderSkin): Promise<void> {
-            const assignSkeleton = () => {
+            const assignSkeleton = (skeleton: Skeleton) => {
                 this._forEachPrimitive(node, babylonMesh => {
-                    babylonMesh.skeleton = skin._babylonSkeleton!;
+                    babylonMesh.skeleton = skeleton;
                 });
 
                 // Ignore the TRS of skinned nodes.
@@ -684,74 +775,81 @@ module BABYLON.GLTF2 {
 
             if (skin._loaded) {
                 return skin._loaded.then(() => {
-                    assignSkeleton();
+                    assignSkeleton(skin._babylonSkeleton!);
                 });
             }
 
-            // TODO: split into two parts so that bones are created before inverseBindMatricesData is loaded (for compiling materials).
+            const skeletonId = `skeleton${skin._index}`;
+            const babylonSkeleton = new Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
+            skin._babylonSkeleton = babylonSkeleton;
+            this._loadBones(context, skin);
+            assignSkeleton(babylonSkeleton);
 
             return (skin._loaded = this._loadSkinInverseBindMatricesDataAsync(context, skin).then(inverseBindMatricesData => {
-                const skeletonId = `skeleton${skin._index}`;
-                const babylonSkeleton = new Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
-                skin._babylonSkeleton = babylonSkeleton;
-                this._loadBones(context, skin, inverseBindMatricesData);
-                assignSkeleton();
+                this._updateBoneMatrices(babylonSkeleton, inverseBindMatricesData);
             }));
         }
 
-        private _loadSkinInverseBindMatricesDataAsync(context: string, skin: ILoaderSkin): Promise<Nullable<Float32Array>> {
-            if (skin.inverseBindMatrices == undefined) {
-                return Promise.resolve(null);
-            }
-
-            const accessor = GLTFLoader._GetProperty(`${context}/inverseBindMatrices`, this._gltf.accessors, skin.inverseBindMatrices);
-            return this._loadAccessorAsync(`#/accessors/${accessor._index}`, accessor).then(data => {
-                return data as Float32Array;
-            });
-        }
-
-        private _createBone(node: ILoaderNode, skin: ILoaderSkin, parent: Nullable<Bone>, localMatrix: Matrix, baseMatrix: Matrix, index: number): Bone {
-            const babylonBone = new Bone(node.name || `joint${node._index}`, skin._babylonSkeleton!, parent, localMatrix, null, baseMatrix, index);
-
-            node._babylonAnimationTargets = node._babylonAnimationTargets || [];
-            node._babylonAnimationTargets.push(babylonBone);
-
-            return babylonBone;
-        }
-
-        private _loadBones(context: string, skin: ILoaderSkin, inverseBindMatricesData: Nullable<Float32Array>): void {
+        private _loadBones(context: string, skin: ILoaderSkin): void {
             const babylonBones: { [index: number]: Bone } = {};
             for (const index of skin.joints) {
                 const node = GLTFLoader._GetProperty(`${context}/joints/${index}`, this._gltf.nodes, index);
-                this._loadBone(node, skin, inverseBindMatricesData, babylonBones);
+                this._loadBone(node, skin, babylonBones);
             }
         }
 
-        private _loadBone(node: ILoaderNode, skin: ILoaderSkin, inverseBindMatricesData: Nullable<Float32Array>, babylonBones: { [index: number]: Bone }): Bone {
+        private _loadBone(node: ILoaderNode, skin: ILoaderSkin, babylonBones: { [index: number]: Bone }): Bone {
             let babylonBone = babylonBones[node._index];
             if (babylonBone) {
                 return babylonBone;
             }
 
-            const boneIndex = skin.joints.indexOf(node._index);
-
-            let baseMatrix = Matrix.Identity();
-            if (inverseBindMatricesData && boneIndex !== -1) {
-                baseMatrix = Matrix.FromArray(inverseBindMatricesData, boneIndex * 16);
-                baseMatrix.invertToRef(baseMatrix);
-            }
-
             let babylonParentBone: Nullable<Bone> = null;
             if (node._parent._babylonMesh !== this._rootBabylonMesh) {
-                babylonParentBone = this._loadBone(node._parent, skin, inverseBindMatricesData, babylonBones);
-                baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
+                babylonParentBone = this._loadBone(node._parent, skin, babylonBones);
             }
 
-            babylonBone = this._createBone(node, skin, babylonParentBone, this._getNodeMatrix(node), baseMatrix, boneIndex);
+            const boneIndex = skin.joints.indexOf(node._index);
+
+            babylonBone = new Bone(node.name || `joint${node._index}`, skin._babylonSkeleton!, babylonParentBone, this._getNodeMatrix(node), null, null, boneIndex);
             babylonBones[node._index] = babylonBone;
+
+            node._babylonAnimationTargets = node._babylonAnimationTargets || [];
+            node._babylonAnimationTargets.push(babylonBone);
+
             return babylonBone;
         }
 
+        private _loadSkinInverseBindMatricesDataAsync(context: string, skin: ILoaderSkin): Promise<Nullable<Float32Array>> {
+            if (skin.inverseBindMatrices == undefined) {
+                return Promise.resolve(null);
+            }
+
+            const accessor = GLTFLoader._GetProperty(`${context}/inverseBindMatrices`, this._gltf.accessors, skin.inverseBindMatrices);
+            return this._loadAccessorAsync(`#/accessors/${accessor._index}`, accessor).then(data => {
+                return data as Float32Array;
+            });
+        }
+
+        private _updateBoneMatrices(babylonSkeleton: Skeleton, inverseBindMatricesData: Nullable<Float32Array>): void {
+            for (const babylonBone of babylonSkeleton.bones) {
+                let baseMatrix = Matrix.Identity();
+                const boneIndex = babylonBone._index!;
+                if (inverseBindMatricesData && boneIndex !== -1) {
+                    Matrix.FromArrayToRef(inverseBindMatricesData, boneIndex * 16, baseMatrix);
+                    baseMatrix.invertToRef(baseMatrix);
+                }
+
+                const babylonParentBone = babylonBone.getParent();
+                if (babylonParentBone) {
+                    baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
+                }
+
+                babylonBone.updateMatrix(baseMatrix, false, false);
+                babylonBone._updateDifferenceMatrix(undefined, false);
+            }
+        }
+
         private _getNodeMatrix(node: ILoaderNode): Matrix {
             return node.matrix ?
                 Matrix.FromArray(node.matrix) :
@@ -1001,6 +1099,9 @@ module BABYLON.GLTF2 {
             return buffer._data;
         }
 
+        /**
+        * @ignore
+        */
         public _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView> {
             if (bufferView._data) {
                 return bufferView._data;
@@ -1067,6 +1168,9 @@ module BABYLON.GLTF2 {
             return accessor._data;
         }
 
+        /**
+        * @ignore
+        */
         public _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer> {
             if (bufferView._babylonBuffer) {
                 return bufferView._babylonBuffer;
@@ -1153,6 +1257,9 @@ module BABYLON.GLTF2 {
             return Promise.all(promises).then(() => {});
         }
 
+        /**
+        * @ignore
+        */
         public _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void> {
             const promise = GLTFLoaderExtension._LoadMaterialAsync(this, context, material, babylonMesh, babylonDrawMode, assign);
             if (promise) {
@@ -1187,6 +1294,9 @@ module BABYLON.GLTF2 {
             return babylonData.loaded;
         }
 
+        /**
+        * @ignore
+        */
         public _createMaterial<T extends Material>(type: MaterialConstructor<T>, name: string, drawMode: number): T {
             const babylonMaterial = new type(name, this._babylonScene);
             babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
@@ -1194,6 +1304,9 @@ module BABYLON.GLTF2 {
             return babylonMaterial;
         }
 
+        /**
+        * @ignore
+        */
         public _loadMaterialBasePropertiesAsync(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void> {
             const promises = new Array<Promise<void>>();
 
@@ -1235,6 +1348,9 @@ module BABYLON.GLTF2 {
             return Promise.all(promises).then(() => {});
         }
 
+        /**
+        * @ignore
+        */
         public _loadMaterialAlphaProperties(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): void {
             const alphaMode = material.alphaMode || MaterialAlphaMode.OPAQUE;
             switch (alphaMode) {
@@ -1264,6 +1380,9 @@ module BABYLON.GLTF2 {
             }
         }
 
+        /**
+        * @ignore
+        */
         public _loadTextureAsync(context: string, textureInfo: ITextureInfo, assign: (texture: Texture) => void): Promise<void> {
             const texture = GLTFLoader._GetProperty(`${context}/index`, this._gltf.textures, textureInfo.index);
             context = `#/textures/${textureInfo.index}`;
@@ -1335,6 +1454,9 @@ module BABYLON.GLTF2 {
             return image._objectURL;
         }
 
+        /**
+        * @ignore
+        */
         public _loadUriAsync(context: string, uri: string): Promise<ArrayBufferView> {
             const promise = GLTFLoaderExtension._LoadUriAsync(this, context, uri);
             if (promise) {
@@ -1399,6 +1521,9 @@ module BABYLON.GLTF2 {
             this._progressCallback(new SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
         }
 
+        /**
+        * @ignore
+        */
         public static _GetProperty<T>(context: string, array: ArrayLike<T> | undefined, index: number | undefined): T {
             if (!array || index == undefined || !array[index]) {
                 throw new Error(`${context}: Failed to find index (${index})`);
@@ -1571,6 +1696,9 @@ module BABYLON.GLTF2 {
             this.onMaterialLoadedObservable.clear();
         }
 
+        /**
+        * @ignore
+        */
         public _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>) {
             for (const name of GLTFLoader._Names) {
                 const extension = this._extensions[name];

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

@@ -1,6 +1,9 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GLTF2 {
+    /**
+     * Abstract class that can be implemented to extend existing gltf loader behavior.
+     */
     export abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable {
         public enabled = true;
         public abstract readonly name: string;

+ 60 - 0
loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts

@@ -1,25 +1,43 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 /// <reference path="../../../../dist/babylon.glTF2Interface.d.ts"/>
 
+/**
+ * GLTF2 module for babylon
+ */
 module BABYLON.GLTF2 {
+    /**
+     * Interface to access data and vertex buffer associated with a file
+     */
     export interface ILoaderAccessor extends IAccessor, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
 
+    /**
+     * Loader's animation channel
+     */
     export interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
 
+    /**
+     * Container for animation keyframe data
+     */
     export interface ILoaderAnimationSamplerData {
         input: Float32Array;
         interpolation: AnimationSamplerInterpolation;
         output: Float32Array;
     }
 
+    /**
+     * Keyframe data
+     */
     export interface ILoaderAnimationSampler extends IAnimationSampler, IArrayItem {
         _data: Promise<ILoaderAnimationSamplerData>;
     }
 
+    /**
+     * Loader animation
+     */
     export interface ILoaderAnimation extends IAnimation, IArrayItem {
         channels: ILoaderAnimationChannel[];
         samplers: ILoaderAnimationSampler[];
@@ -27,22 +45,37 @@ module BABYLON.GLTF2 {
         _babylonAnimationGroup?: AnimationGroup;
     }
 
+    /**
+     * Loader buffer
+     */
     export interface ILoaderBuffer extends IBuffer, IArrayItem {
         _data?: Promise<ArrayBufferView>;
     }
 
+    /**
+     * Loader's buffer data
+     */
     export interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
         _babylonBuffer?: Promise<Buffer>;
     }
 
+    /**
+     * Loader's loaded camera data
+     */
     export interface ILoaderCamera extends ICamera, IArrayItem {
     }
 
+    /**
+     * Loaded image specified by url
+     */
     export interface ILoaderImage extends IImage, IArrayItem {
         _objectURL?: Promise<string>;
     }
 
+    /**
+     * Loaded material data
+     */
     export interface ILoaderMaterial extends IMaterial, IArrayItem {
         _babylonData?: {
             [drawMode: number]: {
@@ -53,13 +86,22 @@ module BABYLON.GLTF2 {
         };
     }
 
+    /**
+     * Loader mesh data
+     */
     export interface ILoaderMesh extends IMesh, IArrayItem {
         primitives: ILoaderMeshPrimitive[];
     }
 
+    /**
+     * Loader mesh data
+     */
     export interface ILoaderMeshPrimitive extends IMeshPrimitive, IArrayItem {
     }
 
+    /**
+     * Node for traversing loader data
+     */
     export interface ILoaderNode extends INode, IArrayItem {
         _parent: ILoaderNode;
         _babylonMesh?: Mesh;
@@ -68,6 +110,9 @@ module BABYLON.GLTF2 {
         _numMorphTargets?: number;
     }
 
+    /**
+     * Sampler data
+     */
     export interface ILoaderSamplerData {
         noMipMaps: boolean;
         samplingMode: number;
@@ -75,21 +120,36 @@ module BABYLON.GLTF2 {
         wrapV: number;
     }
 
+    /**
+     * Sampler data
+     */
     export interface ILoaderSampler extends ISampler, IArrayItem {
         _data?: ILoaderSamplerData;
     }
 
+    /**
+     * Loader's scene
+     */
     export interface ILoaderScene extends IScene, IArrayItem {
     }
 
+    /**
+     * Loader's skeleton data
+     */
     export interface ILoaderSkin extends ISkin, IArrayItem {
         _babylonSkeleton?: Skeleton;
         _loaded?: Promise<void>;
     }
 
+    /**
+     * Loader's texture
+     */
     export interface ILoaderTexture extends ITexture, IArrayItem {
     }
 
+    /**
+     * Loaded GLTF data
+     */
     export interface ILoaderGLTF extends IGLTF {
         accessors?: ILoaderAccessor[];
         animations?: ILoaderAnimation[];

+ 3 - 1
loaders/src/glTF/2.0/babylon.glTFLoaderUtilities.ts

@@ -1,11 +1,13 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GLTF2 {
+    /** Array item which contains it's index in an array */
     export interface IArrayItem {
         _index: number;
     }
-
+    /** Array item helper methods */
     export class ArrayItem {
+        /** Sets the index of each array element to its index in the array */
         public static Assign(values?: IArrayItem[]): void {
             if (values) {
                 for (let index = 0; index < values.length; index++) {

+ 148 - 8
loaders/src/glTF/babylon.glTFFileLoader.ts

@@ -1,6 +1,9 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON {
+    /**
+    * Coordinate system mode that will be used when loading from the gltf file
+    */
     export enum GLTFLoaderCoordinateSystemMode {
         /**
          * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
@@ -13,6 +16,9 @@ module BABYLON {
         FORCE_RIGHT_HANDED,
     }
 
+    /**
+    * Animation mode that determines which animations should be started when a file is loaded
+    */
     export enum GLTFLoaderAnimationStartMode {
         /**
          * No animation will start.
@@ -30,11 +36,23 @@ module BABYLON {
         ALL,
     }
 
+    /**
+    * Loaded gltf data
+    */
     export interface IGLTFLoaderData {
+        /**
+        * Loaded json string converted to an object
+        */
         json: Object;
+        /**
+        * Loaded ArrayBufferView
+        */
         bin: Nullable<ArrayBufferView>;
     }
 
+    /**
+    * Gltf extension interface
+    */
     export interface IGLTFLoaderExtension {
         /**
          * The name of this extension.
@@ -47,6 +65,9 @@ module BABYLON {
         enabled: boolean;
     }
 
+    /**
+    * Loading state
+    */
     export enum GLTFLoaderState {
         /**
          * The asset is loading.
@@ -64,28 +85,75 @@ module BABYLON {
         COMPLETE
     }
 
+    /**
+    * GLTF loader interface
+    */
     export interface IGLTFLoader extends IDisposable {
+        /**
+        * Coordinate system that will be used when loading from the gltf file
+        */
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
+        /**
+        * Animation mode that determines which animations should be started when a file is loaded
+        */
         animationStartMode: GLTFLoaderAnimationStartMode;
+        /**
+        * If the materials in the file should automatically be compiled
+        */
         compileMaterials: boolean;
+        /**
+        * If a clip plane should be usede when loading meshes in the file
+        */
         useClipPlane: boolean;
+        /**
+        * If shadow generators should automatically be compiled
+        */
         compileShadowGenerators: boolean;
 
+        /**
+        * Observable that fires each time a mesh is loaded
+        */
         onMeshLoadedObservable: Observable<AbstractMesh>;
+        /**
+        * Observable that fires each time a texture is loaded
+        */
         onTextureLoadedObservable: Observable<BaseTexture>;
+         /**
+        * Observable that fires each time a material is loaded
+        */
         onMaterialLoadedObservable: Observable<Material>;
+        /**
+        * Observable that fires when the load has completed
+        */
         onCompleteObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fires when the loader is disposed
+        */
         onDisposeObservable: Observable<IGLTFLoader>;
+        /**
+        * Observable that fire when an extension is loaded
+        */
         onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
 
+        /**
+        * Loader state
+        */
         state: Nullable<GLTFLoaderState>;
 
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        */
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{ meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }>;
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        */
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<void>;
     }
-
+    /** File loader to load gltf files into a babylon scene */
     export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
+        /** Creates a gltf 1.0 file loader */
         public static CreateGLTFLoaderV1: () => IGLTFLoader;
+        /** Creates a gltf 2.0 file loader */
         public static CreateGLTFLoaderV2: () => IGLTFLoader;
 
         // #region Common options
@@ -98,6 +166,7 @@ module BABYLON {
         public onParsedObservable = new Observable<IGLTFLoaderData>();
 
         private _onParsedObserver: Nullable<Observer<IGLTFLoaderData>>;
+        /** Raised when the asset has been parsed. */
         public set onParsed(callback: (loaderData: IGLTFLoaderData) => void) {
             if (this._onParsedObserver) {
                 this.onParsedObservable.remove(this._onParsedObserver);
@@ -108,9 +177,14 @@ module BABYLON {
         // #endregion
 
         // #region V1 options
-
+        /**
+         * Set this property to false to disable incremental loading which delays the loader from calling the success callback until after loading the meshes and shaders. Textures always loads asynchronously. For example, the success callback can compute the bounding information of the loaded meshes when incremental loading is disabled. Defaults to true.
+         */
         public static IncrementalLoading = true;
 
+        /**
+         * Set this property to true in order to work with homogeneous coordinates, available with some converters and exporters. Defaults to false. See https://en.wikipedia.org/wiki/Homogeneous_coordinates
+         */
         public static HomogeneousCoordinates = false;
 
         // #endregion
@@ -118,27 +192,32 @@ module BABYLON {
         // #region V2 options
 
         /**
-         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED).
+         * The coordinate system mode (AUTO, FORCE_RIGHT_HANDED). Defaults to AUTO.
+         * - AUTO - Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+         * - FORCE_RIGHT_HANDED - Sets the useRightHandedSystem flag on the scene.
          */
         public coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
 
         /**
-         * The animation start mode (NONE, FIRST, ALL).
-         */
+        * The animation start mode (NONE, FIRST, ALL). Defaults to FIRST.
+        * - NONE - No animation will start.
+        * - FIRST - The first animation will start.
+        * - ALL - All animations will start.
+        */
         public animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
 
         /**
-         * Set to true to compile materials before raising the success callback.
+         * Set to true to compile materials before raising the success callback. Defaults to false.
          */
         public compileMaterials = false;
 
         /**
-         * Set to true to also compile materials with clip planes.
+         * Set to true to also compile materials with clip planes. Defaults to false.
          */
         public useClipPlane = false;
 
         /**
-         * Set to true to compile shadow generators before raising the success callback.
+         * Set to true to compile shadow generators before raising the success callback. Defaults to false.
          */
         public compileShadowGenerators = false;
 
@@ -148,6 +227,9 @@ module BABYLON {
         public readonly onMeshLoadedObservable = new Observable<AbstractMesh>();
 
         private _onMeshLoadedObserver: Nullable<Observer<AbstractMesh>>;
+        /**
+         * Raised when the loader creates a mesh after parsing the glTF properties of the mesh. (onMeshLoadedObservable is likely desired instead.)
+         */
         public set onMeshLoaded(callback: (mesh: AbstractMesh) => void) {
             if (this._onMeshLoadedObserver) {
                 this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver);
@@ -161,6 +243,9 @@ module BABYLON {
         public readonly onTextureLoadedObservable = new Observable<BaseTexture>();
 
         private _onTextureLoadedObserver: Nullable<Observer<BaseTexture>>;
+        /**
+         * Method called when a texture has been loaded (onTextureLoadedObservable is likely desired instead.)
+         */
         public set onTextureLoaded(callback: (texture: BaseTexture) => void) {
             if (this._onTextureLoadedObserver) {
                 this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver);
@@ -174,6 +259,9 @@ module BABYLON {
         public readonly onMaterialLoadedObservable = new Observable<Material>();
 
         private _onMaterialLoadedObserver: Nullable<Observer<Material>>;
+        /**
+         * Method when the loader creates a material after parsing the glTF properties of the material. (onMaterialLoadedObservable is likely desired instead.)
+         */
         public set onMaterialLoaded(callback: (material: Material) => void) {
             if (this._onMaterialLoadedObserver) {
                 this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver);
@@ -189,6 +277,9 @@ module BABYLON {
         public readonly onCompleteObservable = new Observable<GLTFFileLoader>();
 
         private _onCompleteObserver: Nullable<Observer<GLTFFileLoader>>;
+        /**
+         * Raised when the asset is completely loaded, immediately before the loader is disposed. (onCompleteObservable is likely desired instead.)
+         */
         public set onComplete(callback: () => void) {
             if (this._onCompleteObserver) {
                 this.onCompleteObservable.remove(this._onCompleteObserver);
@@ -202,6 +293,9 @@ module BABYLON {
         public readonly onDisposeObservable = new Observable<GLTFFileLoader>();
 
         private _onDisposeObserver: Nullable<Observer<GLTFFileLoader>>;
+        /**
+         * Raised after the loader is disposed. (onDisposeObservable is likely desired instead.)
+         */
         public set onDispose(callback: () => void) {
             if (this._onDisposeObserver) {
                 this.onDisposeObservable.remove(this._onDisposeObserver);
@@ -216,6 +310,9 @@ module BABYLON {
         public readonly onExtensionLoadedObservable = new Observable<IGLTFLoaderExtension>();
 
         private _onExtensionLoadedObserver: Nullable<Observer<IGLTFLoaderExtension>>;
+        /**
+         * Raised after a loader extension is created. (onExtensionLoadedObservable is likely desired instead.)
+         */
         public set onExtensionLoaded(callback: (extension: IGLTFLoaderExtension) => void) {
             if (this._onExtensionLoadedObserver) {
                 this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
@@ -246,8 +343,14 @@ module BABYLON {
 
         private _loader: Nullable<IGLTFLoader> = null;
 
+        /**
+         * Name of the loader ("gltf")
+         */
         public name = "gltf";
 
+        /**
+         * Supported file extensions of the loader (.gltf, .glb)
+         */
         public extensions: ISceneLoaderPluginExtensions = {
             ".gltf": { isBinary: false },
             ".glb": { isBinary: true }
@@ -270,6 +373,15 @@ module BABYLON {
             this.onDisposeObservable.clear();
         }
 
+        /**
+        * Imports one or more meshes from a loaded gltf file and adds them to the scene
+        * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
+        * @param scene the scene the meshes should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise containg the loaded meshes, particles, skeletons and animations
+        */
         public importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{ meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
             return Promise.resolve().then(() => {
                 const loaderData = this._parse(data);
@@ -278,6 +390,14 @@ module BABYLON {
             });
         }
 
+        /**
+        * Imports all objects from a loaded gltf file and adds them to the scene
+        * @param scene the scene the objects should be added to
+        * @param data gltf data containing information of the meshes in a loaded file
+        * @param rootUrl root url to load from
+        * @param onProgress event that fires when loading progress has occured
+        * @returns a promise which completes when objects have been loaded to the scene
+        */
         public loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void> {
             return Promise.resolve().then(() => {
                 const loaderData = this._parse(data);
@@ -286,6 +406,14 @@ module BABYLON {
             });
         }
 
+        /**
+         * Load into an asset container.
+         * @param scene The scene to load into
+         * @param data The data to import
+         * @param rootUrl The root url for scene and resources
+         * @param onProgress The callback when the load progresses
+         * @returns The loaded asset container
+         */
         public loadAssetContainerAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<AssetContainer> {
             return Promise.resolve().then(() => {
                 const loaderData = this._parse(data);
@@ -302,12 +430,24 @@ module BABYLON {
             });
         }
 
+        /**
+         * If the data string can be loaded directly
+         * @param data string contianing the file data
+         * @returns if the data can be loaded directly
+         */
         public canDirectLoad(data: string): boolean {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         }
 
+        /**
+         * Rewrites a url by combining a root url and response url
+         */
         public rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
 
+        /**
+         * Instantiates a gltf file loader plugin
+         * @returns the created plugin
+         */
         public createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync {
             return new GLTFFileLoader();
         }

+ 2 - 2
package.json

@@ -9,7 +9,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "3.2.0-beta.4",
+    "version": "3.2.0-beta.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -42,4 +42,4 @@
     "devDependencies": {
         "typescript": "^2.8.1"
     }
-}
+}

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

@@ -152,7 +152,7 @@
         private _scene: Scene;
 
         constructor(scene: Scene) {
-            this._scene = scene;
+            this._scene = scene || Engine.LastCreatedScene;
 
             scene._actionManagers.push(this);
         }

+ 544 - 40
src/Animations/babylon.animation.ts

@@ -1,8 +1,27 @@
 module BABYLON {
+    /**
+     * Represents the range of an animation
+     */
     export class AnimationRange {
-        constructor(public name: string, public from: number, public to: number) {
+        /**
+         * Initializes the range of an animation
+         * @param name The name of the animation range
+         * @param from The starting frame of the animation
+         * @param to The ending frame of the animation
+         */
+        constructor(
+            /**The name of the animation range**/
+            public name: string, 
+            /**The starting frame of the animation */
+            public from: number, 
+            /**The ending frame of the animation*/
+            public to: number) {
         }
 
+        /**
+         * Makes a copy of the animation range
+         * @returns A copy of the animation range
+         */
         public clone(): AnimationRange {
             return new AnimationRange(this.name, this.from, this.to);
         }
@@ -12,37 +31,90 @@
      * Composed of a frame, and an action function
      */
     export class AnimationEvent {
+        /**
+         * Specifies if the animation event is done
+         */
         public isDone: boolean = false;
-        constructor(public frame: number, public action: () => void, public onlyOnce?: boolean) {
+
+        /**
+         * Initializes the animation event
+         * @param frame The frame for which the event is triggered
+         * @param action The event to perform when triggered
+         * @param onlyOnce Specifies if the event should be triggered only once
+         */
+        constructor(
+            /** The frame for which the event is triggered **/
+            public frame: number,
+            /** The event to perform when triggered **/
+            public action: () => void , 
+            /** Specifies if the event should be triggered only once**/
+            public onlyOnce?: boolean ) {
         }
     }
 
+    /**
+     * A cursor which tracks a point on a path
+     */
     export class PathCursor {
+        /**
+         * Stores path cursor callbacks for when an onchange event is triggered
+         */
         private _onchange = new Array<(cursor: PathCursor) => void>();
 
+        /**
+         * The value of the path cursor
+         */
         value: number = 0;
+
+        /**
+         * The animation array of the path cursor
+         */
         animations = new Array<Animation>();
 
+        /**
+         * Initializes the path cursor
+         * @param path The path to track
+         */
         constructor(private path: Path2) {
         }
 
+        /**
+         * Gets the cursor point on the path
+         * @returns A point on the path cursor at the cursor location
+         */
         public getPoint(): Vector3 {
             var point = this.path.getPointAtLengthPosition(this.value);
             return new Vector3(point.x, 0, point.y);
         }
 
+        /**
+         * Moves the cursor ahead by the step amount
+         * @param step The amount to move the cursor forward
+         * @returns This path cursor
+         */
         public moveAhead(step: number = 0.002): PathCursor {
             this.move(step);
 
             return this;
         }
 
+        /**
+         * Moves the cursor behind by the step amount
+         * @param step The amount to move the cursor back
+         * @returns This path cursor
+         */
         public moveBack(step: number = 0.002): PathCursor {
             this.move(-step);
 
             return this;
         }
 
+        /**
+         * Moves the cursor by the step amount
+         * If the step amount is greater than one, an exception is thrown
+         * @param step The amount to move the cursor
+         * @returns This path cursor
+         */
         public move(step: number): PathCursor {
 
             if (Math.abs(step) > 1) {
@@ -56,6 +128,10 @@
             return this;
         }
 
+        /**
+         * Ensures that the value is limited between zero and one
+         * @returns This path cursor
+         */
         private ensureLimits(): PathCursor {
             while (this.value > 1) {
                 this.value -= 1;
@@ -67,13 +143,21 @@
             return this;
         }
 
-        // used by animation engine
+        /**
+         * Runs onchange callbacks on change (used by the animation engine)
+         * @returns This path cursor
+         */
         private raiseOnChange(): PathCursor {
             this._onchange.forEach(f => f(this));
 
             return this;
         }
 
+        /**
+         * Executes a function on change
+         * @param f A path cursor onchange callback
+         * @returns This path cursor
+         */
         public onchange(f: (cursor: PathCursor) => void): PathCursor {
             this._onchange.push(f);
 
@@ -81,17 +165,38 @@
         }
     }
 
+    /**
+     * Defines an interface which represents an animation key frame
+     */
     export interface IAnimationKey {
+        /**
+         * Frame of the key frame
+         */
         frame: number;
+        /**
+         * Value at the specifies key frame
+         */
         value: any;
+        /**
+         * The input tangent for the cubic hermite spline
+         */
         inTangent?: any;
+        /**
+         * The output tangent for the cubic hermite spline
+         */
         outTangent?: any;
+        /**
+         * The animation interpolation type
+         */
         interpolation?: AnimationKeyInterpolation;
     }
 
+    /**
+     * Enum for the animation key frame interpolation type
+     */
     export enum AnimationKeyInterpolation {
         /**
-         * Do not interpolate between keys and use the start key value only. Tangents are ignored.
+         * Do not interpolate between keys and use the start key value only. Tangents are ignored
          */
         STEP = 1
     }
@@ -110,21 +215,45 @@
          */
         public static AllowMatrixDecomposeForInterpolation = true;
 
+        /**
+         * Stores the key frames of the animation
+         */
         private _keys: Array<IAnimationKey>;
+
+        /**
+         * Stores the easing function of the animation
+         */
         private _easingFunction: IEasingFunction;
 
+        /**
+         * @ignore Internal use only
+         */
         public _runtimeAnimations = new Array<RuntimeAnimation>();
 
-        // The set of event that will be linked to this animation
+        /**
+         * The set of event that will be linked to this animation
+         */
         private _events = new Array<AnimationEvent>();
 
+        /**
+         * Stores an array of target property paths
+         */
         public targetPropertyPath: string[];
 
+        /**
+         * Stores the blending speed of the animation
+         */
         public blendingSpeed = 0.01;
 
+        /**
+         * Stores the animation ranges for the animation
+         */
         private _ranges: { [name: string]: Nullable<AnimationRange> } = {};
 
-        static _PrepareAnimation(name: string, targetProperty: string, framePerSecond: number, totalFrame: number,
+        /**
+         * @ignore Internal use
+         */
+        public static _PrepareAnimation(name: string, targetProperty: string, framePerSecond: number, totalFrame: number,
             from: any, to: any, loopMode?: number, easingFunction?: EasingFunction): Nullable<Animation> {
             var dataType = undefined;
 
@@ -159,10 +288,11 @@
         }
 
         /**
-		 * Sets up an animation.
-		 * @param property the property to animate
-		 * @param animationType the animation type to apply
-		 * @param easingFunction the easing function used in the animation
+		 * Sets up an animation
+		 * @param property The property to animate
+		 * @param animationType The animation type to apply
+         * @param framePerSecond The frames per second of the animation
+		 * @param easingFunction The easing function used in the animation
 		 * @returns The created animation
 		 */
         public static CreateAnimation(property: string, animationType: number, framePerSecond: number, easingFunction: EasingFunction): Animation {
@@ -179,15 +309,15 @@
 
         /**
          * Create and start an animation on a node
-         * @param {string} name defines the name of the global animation that will be run on all nodes
-         * @param {BABYLON.Node} node defines the root node where the animation will take place
-         * @param {string} targetProperty defines property to animate
-         * @param {number} framePerSecond defines the number of frame per second yo use
-         * @param {number} totalFrame defines the number of frames in total
-         * @param {any} from defines the initial value
-         * @param {any} to defines the final value
-         * @param {number} loopMode defines which loop mode you want to use (off by default)
-         * @param {BABYLON.EasingFunction} easingFunction defines the easing function to use (linear by default)
+         * @param name defines the name of the global animation that will be run on all nodes
+         * @param node defines the root node where the animation will take place
+         * @param targetProperty defines property to animate
+         * @param framePerSecond defines the number of frame per second yo use
+         * @param totalFrame defines the number of frames in total
+         * @param from defines the initial value
+         * @param to defines the final value
+         * @param loopMode defines which loop mode you want to use (off by default)
+         * @param easingFunction defines the easing function to use (linear by default)
          * @param onAnimationEnd defines the callback to call when animation end
          * @returns the animatable created for this animation
          */
@@ -206,16 +336,16 @@
 
         /**
          * Create and start an animation on a node and its descendants
-         * @param {string} name defines the name of the global animation that will be run on all nodes
-         * @param {BABYLON.Node} node defines the root node where the animation will take place
-         * @param {boolean} directDescendantsOnly if true only direct descendants will be used, if false direct and also indirect (children of children, an so on in a recursive manner) descendants will be used.
-         * @param {string} targetProperty defines property to animate
-         * @param {number} framePerSecond defines the number of frame per second yo use
-         * @param {number} totalFrame defines the number of frames in total
-         * @param {any} from defines the initial value
-         * @param {any} to defines the final value
-         * @param {number} loopMode defines which loop mode you want to use (off by default)
-         * @param {BABYLON.EasingFunction} easingFunction defines the easing function to use (linear by default)
+         * @param name defines the name of the global animation that will be run on all nodes
+         * @param node defines the root node where the animation will take place
+         * @param directDescendantsOnly if true only direct descendants will be used, if false direct and also indirect (children of children, an so on in a recursive manner) descendants will be used
+         * @param targetProperty defines property to animate
+         * @param framePerSecond defines the number of frame per second to use
+         * @param totalFrame defines the number of frames in total
+         * @param from defines the initial value
+         * @param to defines the final value
+         * @param loopMode defines which loop mode you want to use (off by default)
+         * @param easingFunction defines the easing function to use (linear by default)
          * @param onAnimationEnd defines the callback to call when an animation ends (will be called once per node)
          * @returns the list of animatables created for all nodes
          * @example https://www.babylonjs-playground.com/#MH0VLI
@@ -234,6 +364,20 @@
             return scene.beginDirectHierarchyAnimation(node, directDescendantsOnly, [animation], 0, totalFrame, (animation.loopMode === 1), 1.0, onAnimationEnd);
         }
 
+        /**
+         * Creates a new animation, merges it with the existing animations and starts it
+         * @param name Name of the animation
+         * @param node Node which contains the scene that begins the animations
+         * @param targetProperty Specifies which property to animate
+         * @param framePerSecond The frames per second of the animation
+         * @param totalFrame The total number of frames
+         * @param from The frame at the beginning of the animation
+         * @param to The frame at the end of the animation
+         * @param loopMode Specifies the loop mode of the animation
+         * @param easingFunction (Optional) The easing function of the animation, which allow custom mathematical formulas for animations
+         * @param onAnimationEnd Callback to run once the animation is complete
+         * @returns Nullable animation
+         */
         public static CreateMergeAndStartAnimation(name: string, node: Node, targetProperty: string,
             framePerSecond: number, totalFrame: number,
             from: any, to: any, loopMode?: number, easingFunction?: EasingFunction, onAnimationEnd?: () => void): Nullable<Animatable> {
@@ -250,7 +394,7 @@
         }
 
         /**
-		 * Transition property of the Camera to the target Value.
+		 * Transition property of the Camera to the target Value
 		 * @param property The property to transition
 		 * @param targetValue The target Value of the property
          * @param host The object where the property to animate belongs
@@ -258,10 +402,10 @@
          * @param frameRate Framerate (in frame/s) to use
 		 * @param transition The transition type we want to use
 		 * @param duration The duration of the animation, in milliseconds
-		 * @param onAnimationEnd Call back trigger at the end of the animation.
+		 * @param onAnimationEnd Callback trigger at the end of the animation
+         * @returns Nullable animation
 		 */
         public static TransitionTo(property: string, targetValue: any, host: any, scene: Scene, frameRate: number, transition: Animation, duration: number, onAnimationEnd: Nullable<() => void> = null): Nullable<Animatable> {
-
             if (duration <= 0) {
                 host[property] = targetValue;
                 if (onAnimationEnd) {
@@ -299,6 +443,9 @@
             return this._runtimeAnimations;
         }
 
+        /**
+         * Specifies if any of the runtime animations are currently running
+         */
         public get hasRunningRuntimeAnimations(): boolean {
             for (var runtimeAnimation of this._runtimeAnimations) {
                 if (!runtimeAnimation.isStopped) {
@@ -309,7 +456,28 @@
             return false;
         }
 
-        constructor(public name: string, public targetProperty: string, public framePerSecond: number, public dataType: number, public loopMode?: number, public enableBlending?: boolean) {
+        /**
+         * Initializes the animation
+         * @param name Name of the animation
+         * @param targetProperty Property to animate
+         * @param framePerSecond The frames per second of the animation
+         * @param dataType The data type of the animation
+         * @param loopMode The loop mode of the animation
+         * @param enableBlendings Specifies if blending should be enabled
+         */
+        constructor(
+            /**Name of the animation */
+            public name: string, 
+            /**Property to animate */
+            public targetProperty: string, 
+            /**The frames per second of the animation */
+            public framePerSecond: number, 
+            /**The data type of the animation */
+            public dataType: number,
+            /**The loop mode of the animation */ 
+            public loopMode?: number, 
+            /**Specifies if blending should be enabled */
+            public enableBlending?: boolean) {
             this.targetPropertyPath = targetProperty.split(".");
             this.dataType = dataType;
             this.loopMode = loopMode === undefined ? Animation.ANIMATIONLOOPMODE_CYCLE : loopMode;
@@ -317,7 +485,9 @@
 
         // Methods
         /**
-         * @param {boolean} fullDetails - support for multiple levels of logging within scene loading
+         * Converts the animation to a string
+         * @param fullDetails support for multiple levels of logging within scene loading
+         * @returns String form of the animation
          */
         public toString(fullDetails?: boolean): string {
             var ret = "Name: " + this.name + ", property: " + this.targetProperty;
@@ -340,7 +510,8 @@
         }
 
         /**
-         * Add an event to this animation.
+         * Add an event to this animation
+         * @param event Event to add
          */
         public addEvent(event: AnimationEvent): void {
             this._events.push(event);
@@ -348,7 +519,7 @@
 
         /**
          * Remove all events found at the given frame
-         * @param frame
+         * @param frame The frame to remove events from
          */
         public removeEvents(frame: number): void {
             for (var index = 0; index < this._events.length; index++) {
@@ -359,10 +530,20 @@
             }
         }
 
+        /**
+         * Retrieves all the events from the animation
+         * @returns Events from the animation
+         */
         public getEvents(): AnimationEvent[] {
             return this._events;
         }
 
+        /**
+         * Creates an animation range
+         * @param name Name of the animation range
+         * @param from Starting frame of the animation range
+         * @param to Ending frame of the animation
+         */
         public createRange(name: string, from: number, to: number): void {
             // check name not already in use; could happen for bones after serialized
             if (!this._ranges[name]) {
@@ -370,6 +551,11 @@
             }
         }
 
+        /**
+         * Deletes an animation range by name
+         * @param name Name of the animation range to delete
+         * @param deleteFrames Specifies if the key frames for the range should also be deleted (true) or not (false)
+         */
         public deleteRange(name: string, deleteFrames = true): void {
             let range = this._ranges[name];
             if (!range) {
@@ -391,15 +577,27 @@
 
         }
 
+        /**
+         * Gets the animation range by name, or null if not defined
+         * @param name Name of the animation range
+         * @returns Nullable animation range
+         */
         public getRange(name: string): Nullable<AnimationRange> {
             return this._ranges[name];
         }
 
-
+        /**
+         * Gets the key frames from the animation
+         * @returns The key frames of the animation
+         */
         public getKeys(): Array<IAnimationKey> {
             return this._keys;
         }
 
+        /**
+         * Gets the highest frame rate of the animation
+         * @returns Highest frame rate of the animation
+         */
         public getHighestFrame(): number {
             var ret = 0;
 
@@ -411,55 +609,279 @@
             return ret;
         }
 
-        public getEasingFunction() {
+        /**
+         * Gets the easing function of the animation
+         * @returns Easing function of the animation
+         */
+        public getEasingFunction(): IEasingFunction {
             return this._easingFunction;
         }
 
-        public setEasingFunction(easingFunction: EasingFunction) {
+        /**
+         * Sets the easing function of the animation
+         * @param easingFunction A custom mathematical formula for animation
+         */
+        public setEasingFunction(easingFunction: EasingFunction): void {
             this._easingFunction = easingFunction;
         }
 
+        /**
+         * Interpolates a scalar linearly
+         * @param startValue Start value of the animation curve
+         * @param endValue End value of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated scalar value
+         */
         public floatInterpolateFunction(startValue: number, endValue: number, gradient: number): number {
             return Scalar.Lerp(startValue, endValue, gradient);
         }
 
+        /**
+         * Interpolates a scalar cubically
+         * @param startValue Start value of the animation curve
+         * @param outTangent End tangent of the animation
+         * @param endValue End value of the animation curve
+         * @param inTangent Start tangent of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated scalar value
+         */
         public floatInterpolateFunctionWithTangents(startValue: number, outTangent: number, endValue: number, inTangent: number, gradient: number): number {
             return Scalar.Hermite(startValue, outTangent, endValue, inTangent, gradient);
         }
 
+        /**
+         * Interpolates a quaternion using a spherical linear interpolation
+         * @param startValue Start value of the animation curve
+         * @param endValue End value of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated quaternion value
+         */
         public quaternionInterpolateFunction(startValue: Quaternion, endValue: Quaternion, gradient: number): Quaternion {
             return Quaternion.Slerp(startValue, endValue, gradient);
         }
 
+        /**
+         * Interpolates a quaternion cubically
+         * @param startValue Start value of the animation curve
+         * @param outTangent End tangent of the animation curve
+         * @param endValue End value of the animation curve
+         * @param inTangent Start tangent of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated quaternion value
+         */
         public quaternionInterpolateFunctionWithTangents(startValue: Quaternion, outTangent: Quaternion, endValue: Quaternion, inTangent: Quaternion, gradient: number): Quaternion {
             return Quaternion.Hermite(startValue, outTangent, endValue, inTangent, gradient).normalize();
         }
 
+        /**
+         * Interpolates a Vector3 linearl
+         * @param startValue Start value of the animation curve
+         * @param endValue End value of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated scalar value
+         */
         public vector3InterpolateFunction(startValue: Vector3, endValue: Vector3, gradient: number): Vector3 {
             return Vector3.Lerp(startValue, endValue, gradient);
         }
 
+        /**
+         * Interpolates a Vector3 cubically
+         * @param startValue Start value of the animation curve
+         * @param outTangent End tangent of the animation
+         * @param endValue End value of the animation curve
+         * @param inTangent Start tangent of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns InterpolatedVector3 value
+         */
         public vector3InterpolateFunctionWithTangents(startValue: Vector3, outTangent: Vector3, endValue: Vector3, inTangent: Vector3, gradient: number): Vector3 {
             return Vector3.Hermite(startValue, outTangent, endValue, inTangent, gradient);
         }
 
+        /**
+         * Interpolates a Vector2 linearly
+         * @param startValue Start value of the animation curve
+         * @param endValue End value of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated Vector2 value
+         */
         public vector2InterpolateFunction(startValue: Vector2, endValue: Vector2, gradient: number): Vector2 {
             return Vector2.Lerp(startValue, endValue, gradient);
         }
 
+        /**
+         * Interpolates a Vector2 cubically
+         * @param startValue Start value of the animation curve
+         * @param outTangent End tangent of the animation
+         * @param endValue End value of the animation curve
+         * @param inTangent Start tangent of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated Vector2 value
+         */
         public vector2InterpolateFunctionWithTangents(startValue: Vector2, outTangent: Vector2, endValue: Vector2, inTangent: Vector2, gradient: number): Vector2 {
             return Vector2.Hermite(startValue, outTangent, endValue, inTangent, gradient);
         }
 
+        /**
+         * Interpolates a size linearly
+         * @param startValue Start value of the animation curve
+         * @param endValue End value of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated Size value
+         */
         public sizeInterpolateFunction(startValue: Size, endValue: Size, gradient: number): Size {
             return Size.Lerp(startValue, endValue, gradient);
         }
 
+        /**
+         * Interpolates a Color3 linearly
+         * @param startValue Start value of the animation curve
+         * @param endValue End value of the animation curve
+         * @param gradient Scalar amount to interpolate
+         * @returns Interpolated Color3 value
+         */
         public color3InterpolateFunction(startValue: Color3, endValue: Color3, gradient: number): Color3 {
             return Color3.Lerp(startValue, endValue, gradient);
         }
 
         /**
+         * @ignore Internal use only
+         */
+        public _getKeyValue(value: any): any {
+            if (typeof value === "function") {
+                return value();
+            }
+
+            return value;
+        } 
+
+        /**
+         * @ignore Internal use only
+         */
+        public _interpolate(currentFrame: number, repeatCount: number, workValue?: any, loopMode?: number, offsetValue?: any, highLimitValue?: any): any {
+            if (loopMode === Animation.ANIMATIONLOOPMODE_CONSTANT && repeatCount > 0) {
+                return highLimitValue.clone ? highLimitValue.clone() : highLimitValue;
+            }
+
+            let keys = this.getKeys();
+
+            // Try to get a hash to find the right key
+            var startKeyIndex = Math.max(0, Math.min(keys.length - 1, Math.floor(keys.length * (currentFrame - keys[0].frame) / (keys[keys.length - 1].frame - keys[0].frame)) - 1));
+
+            if (keys[startKeyIndex].frame >= currentFrame) {
+                while (startKeyIndex - 1 >= 0 && keys[startKeyIndex].frame >= currentFrame) {
+                    startKeyIndex--;
+                }
+            }
+
+            for (var key = startKeyIndex; key < keys.length; key++) {
+                var endKey = keys[key + 1];
+
+                if (endKey.frame >= currentFrame) {
+
+                    var startKey = keys[key];
+                    var startValue = this._getKeyValue(startKey.value);
+                    if (startKey.interpolation === AnimationKeyInterpolation.STEP) {
+                        return startValue;
+                    }
+
+                    var endValue = this._getKeyValue(endKey.value);
+
+                    var useTangent = startKey.outTangent !== undefined && endKey.inTangent !== undefined;
+                    var frameDelta = endKey.frame - startKey.frame;
+
+                    // gradient : percent of currentFrame between the frame inf and the frame sup
+                    var gradient = (currentFrame - startKey.frame) / frameDelta;
+
+                    // check for easingFunction and correction of gradient
+                    let easingFunction = this.getEasingFunction();
+                    if (easingFunction != null) {
+                        gradient = easingFunction.ease(gradient);
+                    }
+
+                    switch (this.dataType) {
+                        // Float
+                        case Animation.ANIMATIONTYPE_FLOAT:
+                            var floatValue = useTangent ? this.floatInterpolateFunctionWithTangents(startValue, startKey.outTangent * frameDelta, endValue, endKey.inTangent * frameDelta, gradient) : this.floatInterpolateFunction(startValue, endValue, gradient);
+                            switch (loopMode) {
+                                case Animation.ANIMATIONLOOPMODE_CYCLE:
+                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
+                                    return floatValue;
+                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
+                                    return offsetValue * repeatCount + floatValue;
+                            }
+                            break;
+                        // Quaternion
+                        case Animation.ANIMATIONTYPE_QUATERNION:
+                            var quatValue = useTangent ? this.quaternionInterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.quaternionInterpolateFunction(startValue, endValue, gradient);
+                            switch (loopMode) {
+                                case Animation.ANIMATIONLOOPMODE_CYCLE:
+                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
+                                    return quatValue;
+                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
+                                    return quatValue.addInPlace(offsetValue.scale(repeatCount));
+                            }
+
+                            return quatValue;
+                        // Vector3
+                        case Animation.ANIMATIONTYPE_VECTOR3:
+                            var vec3Value = useTangent ? this.vector3InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.vector3InterpolateFunction(startValue, endValue, gradient);
+                            switch (loopMode) {
+                                case Animation.ANIMATIONLOOPMODE_CYCLE:
+                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
+                                    return vec3Value;
+                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
+                                    return vec3Value.add(offsetValue.scale(repeatCount));
+                            }
+                        // Vector2
+                        case Animation.ANIMATIONTYPE_VECTOR2:
+                            var vec2Value = useTangent ? this.vector2InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.vector2InterpolateFunction(startValue, endValue, gradient);
+                            switch (loopMode) {
+                                case Animation.ANIMATIONLOOPMODE_CYCLE:
+                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
+                                    return vec2Value;
+                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
+                                    return vec2Value.add(offsetValue.scale(repeatCount));
+                            }
+                        // Size
+                        case Animation.ANIMATIONTYPE_SIZE:
+                            switch (loopMode) {
+                                case Animation.ANIMATIONLOOPMODE_CYCLE:
+                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
+                                    return this.sizeInterpolateFunction(startValue, endValue, gradient);
+                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
+                                    return this.sizeInterpolateFunction(startValue, endValue, gradient).add(offsetValue.scale(repeatCount));
+                            }
+                        // Color3
+                        case Animation.ANIMATIONTYPE_COLOR3:
+                            switch (loopMode) {
+                                case Animation.ANIMATIONLOOPMODE_CYCLE:
+                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
+                                    return this.color3InterpolateFunction(startValue, endValue, gradient);
+                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
+                                    return this.color3InterpolateFunction(startValue, endValue, gradient).add(offsetValue.scale(repeatCount));
+                            }
+                        // Matrix
+                        case Animation.ANIMATIONTYPE_MATRIX:
+                            switch (loopMode) {
+                                case Animation.ANIMATIONLOOPMODE_CYCLE:
+                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
+                                    if (Animation.AllowMatricesInterpolation) {
+                                        workValue = this.matrixInterpolateFunction(startValue, endValue, gradient, workValue);
+                                        return workValue;
+                                    }
+                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
+                                    return startValue;
+                            }
+                        default:
+                            break;
+                    }
+                    break;
+                }
+            }
+            return this._getKeyValue(keys[keys.length - 1].value);
+        }
+
+        /**
          * Defines the function to use to interpolate matrices
          * @param startValue defines the start matrix
          * @param endValue defines the end matrix
@@ -483,6 +905,10 @@
             return Matrix.Lerp(startValue, endValue, gradient);
         }
 
+        /**
+         * Makes a copy of the animation
+         * @returns Cloned animation
+         */
         public clone(): Animation {
             var clone = new Animation(this.name, this.targetPropertyPath.join("."), this.framePerSecond, this.dataType, this.loopMode);
 
@@ -507,10 +933,18 @@
             return clone;
         }
 
+        /**
+         * Sets the key frames of the animation
+         * @param values The animation key frames to set
+         */
         public setKeys(values: Array<IAnimationKey>): void {
             this._keys = values.slice(0);
         }
 
+        /**
+         * Serializes the animation to an object
+         * @returns Serialized object
+         */
         public serialize(): any {
             var serializationObject: any = {};
 
@@ -564,57 +998,122 @@
         }
 
         // Statics
+        /**
+         * Float animation type
+         */
         private static _ANIMATIONTYPE_FLOAT = 0;
+        /**
+         * Vector3 animation type
+         */
         private static _ANIMATIONTYPE_VECTOR3 = 1;
+        /**
+         * Quaternion animation type
+         */
         private static _ANIMATIONTYPE_QUATERNION = 2;
+        /**
+         * Matrix animation type
+         */
         private static _ANIMATIONTYPE_MATRIX = 3;
+        /**
+         * Color3 animation type
+         */
         private static _ANIMATIONTYPE_COLOR3 = 4;
+        /**
+         * Vector2 animation type
+         */
         private static _ANIMATIONTYPE_VECTOR2 = 5;
+        /**
+         * Size animation type
+         */
         private static _ANIMATIONTYPE_SIZE = 6;
+        /**
+         * Relative Loop Mode
+         */
         private static _ANIMATIONLOOPMODE_RELATIVE = 0;
+        /**
+         * Cycle Loop Mode
+         */
         private static _ANIMATIONLOOPMODE_CYCLE = 1;
+        /**
+         * Constant Loop Mode
+         */
         private static _ANIMATIONLOOPMODE_CONSTANT = 2;
 
+        /**
+         * Get the float animation type
+         */
         public static get ANIMATIONTYPE_FLOAT(): number {
             return Animation._ANIMATIONTYPE_FLOAT;
         }
 
+        /**
+         * Get the Vector3 animation type
+         */
         public static get ANIMATIONTYPE_VECTOR3(): number {
             return Animation._ANIMATIONTYPE_VECTOR3;
         }
 
+        /**
+         * Get the Vectpr2 animation type
+         */
         public static get ANIMATIONTYPE_VECTOR2(): number {
             return Animation._ANIMATIONTYPE_VECTOR2;
         }
 
+        /**
+         * Get the Size animation type
+         */
         public static get ANIMATIONTYPE_SIZE(): number {
             return Animation._ANIMATIONTYPE_SIZE;
         }
 
+        /**
+         * Get the Quaternion animation type
+         */
         public static get ANIMATIONTYPE_QUATERNION(): number {
             return Animation._ANIMATIONTYPE_QUATERNION;
         }
 
+        /**
+         * Get the Matrix animation type
+         */
         public static get ANIMATIONTYPE_MATRIX(): number {
             return Animation._ANIMATIONTYPE_MATRIX;
         }
 
+        /**
+         * Get the Color3 animation type
+         */
         public static get ANIMATIONTYPE_COLOR3(): number {
             return Animation._ANIMATIONTYPE_COLOR3;
         }
 
+        /**
+         * Get the Relative Loop Mode
+         */
         public static get ANIMATIONLOOPMODE_RELATIVE(): number {
             return Animation._ANIMATIONLOOPMODE_RELATIVE;
         }
 
+        /**
+         * Get the Cycle Loop Mode
+         */
         public static get ANIMATIONLOOPMODE_CYCLE(): number {
             return Animation._ANIMATIONLOOPMODE_CYCLE;
         }
 
+        /**
+         * Get the Constant Loop Mode
+         */
         public static get ANIMATIONLOOPMODE_CONSTANT(): number {
             return Animation._ANIMATIONLOOPMODE_CONSTANT;
         }
 
+        /**
+         * Parses an animation object and creates an animation
+         * @param parsedAnimation Parsed animation object
+         * @returns Animation object
+         */
         public static Parse(parsedAnimation: any): Animation {
             var animation = new Animation(parsedAnimation.name, parsedAnimation.property, parsedAnimation.framePerSecond, parsedAnimation.dataType, parsedAnimation.loopBehavior);
 
@@ -698,7 +1197,12 @@
             return animation;
         }
 
-        public static AppendSerializedAnimations(source: IAnimatable, destination: any): any {
+        /**
+         * Appends the serialized animations from the source animations
+         * @param source Source containing the animations
+         * @param destination Target to store the animations
+         */
+        public static AppendSerializedAnimations(source: IAnimatable, destination: any): void {
             if (source.animations) {
                 destination.animations = [];
                 for (var animationIndex = 0; animationIndex < source.animations.length; animationIndex++) {

+ 121 - 144
src/Animations/babylon.runtimeAnimation.ts

@@ -1,28 +1,104 @@
 module BABYLON {
 
+    /**
+     * Defines a runtime animation
+     */
     export class RuntimeAnimation {
+        /**
+         * The current frame of the runtime animation
+         */
         private _currentFrame: number = 0;
+
+        /**
+         * The animation used by the runtime animation
+         */
         private _animation: Animation;
+        
+        /**
+         * The target of the runtime animation
+         */
         private _target: any;
-        private _host: Animatable;
 
+        /**
+         * The initiating animatable
+         */
+        private _host: Animatable;
+        
+        /**
+         * The original value of the runtime animation
+         */
         private _originalValue: any;
+        
+        /**
+         * The original blend value of the runtime animation
+         */
         private _originalBlendValue: any;
+        
+        /**
+         * The offsets cache of the runtime animation
+         */
         private _offsetsCache: {[key: string]: any} = {};
+        
+        /**
+         * The high limits cache of the runtime animation
+         */
         private _highLimitsCache: {[key: string]: any} = {};
+        
+        /**
+         * Specifies if the runtime animation has been stopped
+         */
         private _stopped = false;
+        
+        /**
+         * The blending factor of the runtime animation
+         */
         private _blendingFactor = 0;
+        
+        /**
+         * The BabylonJS scene
+         */
         private _scene: Scene;
 
+        /**
+         * The current value of the runtime animation
+         */
         private _currentValue: any;
+        
         /** @ignore */
         public _workValue: any;
+        
+        /**
+         * The active target of the runtime animation
+         */
         private _activeTarget: any;
+        
+        /**
+         * The target path of the runtime animation
+         */
         private _targetPath: string = "";
+        
+        /**
+         * The weight of the runtime animation
+         */
         private _weight = 1.0;
 
         /**
-         * Gets the current frame
+         * The ratio offset of the runtime animation
+         */
+        private _ratioOffset = 0;
+
+        /**
+         * The previous delay of the runtime animation
+         */
+        private _previousDelay: number = 0;
+        
+        /**
+         * The previous ratio of the runtime animation
+         */
+        private _previousRatio: number = 0;
+
+        /**
+         * Gets the current frame of the runtime animation
          */
         public get currentFrame(): number {
             return this._currentFrame;
@@ -50,7 +126,7 @@
         }
 
         /**
-         * Gets the path where to store the animated value in the target
+         * Gets the target path of the runtime animation
          */
         public get targetPath(): string {
             return this._targetPath;
@@ -66,7 +142,7 @@
         /**
          * Create a new RuntimeAnimation object
          * @param target defines the target of the animation
-         * @param animation defines the source {BABYLON.Animation} object
+         * @param animation defines the source animation object
          * @param scene defines the hosting scene
          * @param host defines the initiating Animatable
          */
@@ -79,10 +155,16 @@
             animation._runtimeAnimations.push(this);
         }
 
+        /**
+         * Gets the animation from the runtime animation
+         */
         public get animation(): Animation {
             return this._animation;
         }
 
+        /**
+         * Resets the runtime animation to the beginning
+         */
         public reset(): void {
             this._offsetsCache = {};
             this._highLimitsCache = {};
@@ -91,10 +173,17 @@
             this._originalValue = null;
         }
 
+        /**
+         * Specifies if the runtime animation is stopped
+         * @returns Boolean specifying if the runtime animation is stopped
+         */
         public isStopped(): boolean {
             return this._stopped;
         }        
 
+        /**
+         * Disposes of the runtime animation
+         */
         public dispose(): void {
             let index = this._animation.runtimeAnimations.indexOf(this);
 
@@ -102,139 +191,19 @@
                 this._animation.runtimeAnimations.splice(index, 1);
             }
         }
-
-        private _getKeyValue(value: any): any {
-            if (typeof value === "function") {
-                return value();
-            }
-
-            return value;
-        }      
         
-        private _interpolate(currentFrame: number, repeatCount: number, loopMode?: number, offsetValue?: any, highLimitValue?: any) {
-            if (loopMode === Animation.ANIMATIONLOOPMODE_CONSTANT && repeatCount > 0) {
-                return highLimitValue.clone ? highLimitValue.clone() : highLimitValue;
-            }
-
+        /**
+         * Interpolates the animation from the current frame
+         * @param currentFrame The frame to interpolate the animation to
+         * @param repeatCount The number of times that the animation should loop
+         * @param loopMode The type of looping mode to use
+         * @param offsetValue Animation offset value
+         * @param highLimitValue The high limit value
+         * @returns The interpolated value
+         */
+        private _interpolate(currentFrame: number, repeatCount: number, loopMode?: number, offsetValue?: any, highLimitValue?: any): any {
             this._currentFrame = currentFrame;
-
-            let keys = this._animation.getKeys();
-
-            // Try to get a hash to find the right key
-            var startKeyIndex = Math.max(0, Math.min(keys.length - 1, Math.floor(keys.length * (currentFrame - keys[0].frame) / (keys[keys.length - 1].frame - keys[0].frame)) - 1));
-
-            if (keys[startKeyIndex].frame >= currentFrame) {
-                while (startKeyIndex - 1 >= 0 && keys[startKeyIndex].frame >= currentFrame) {
-                    startKeyIndex--;
-                }
-            }
-
-            for (var key = startKeyIndex; key < keys.length; key++) {
-                var endKey = keys[key + 1];
-
-                if (endKey.frame >= currentFrame) {
-
-                    var startKey = keys[key];
-                    var startValue = this._getKeyValue(startKey.value);
-                    if (startKey.interpolation === AnimationKeyInterpolation.STEP) {
-                        return startValue;
-                    }
-
-                    var endValue = this._getKeyValue(endKey.value);
-
-                    var useTangent = startKey.outTangent !== undefined && endKey.inTangent !== undefined;
-                    var frameDelta = endKey.frame - startKey.frame;
-
-                    // gradient : percent of currentFrame between the frame inf and the frame sup
-                    var gradient = (currentFrame - startKey.frame) / frameDelta;
-
-                    // check for easingFunction and correction of gradient
-                    let easingFunction = this._animation.getEasingFunction();
-                    if (easingFunction != null) {
-                        gradient = easingFunction.ease(gradient);
-                    }
-
-                    switch (this._animation.dataType) {
-                        // Float
-                        case Animation.ANIMATIONTYPE_FLOAT:
-                            var floatValue = useTangent ? this._animation.floatInterpolateFunctionWithTangents(startValue, startKey.outTangent * frameDelta, endValue, endKey.inTangent * frameDelta, gradient) : this._animation.floatInterpolateFunction(startValue, endValue, gradient);
-                            switch (loopMode) {
-                                case Animation.ANIMATIONLOOPMODE_CYCLE:
-                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    return floatValue;
-                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return offsetValue * repeatCount + floatValue;
-                            }
-                            break;
-                        // Quaternion
-                        case Animation.ANIMATIONTYPE_QUATERNION:
-                            var quatValue = useTangent ? this._animation.quaternionInterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this._animation.quaternionInterpolateFunction(startValue, endValue, gradient);
-                            switch (loopMode) {
-                                case Animation.ANIMATIONLOOPMODE_CYCLE:
-                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    return quatValue;
-                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return quatValue.addInPlace(offsetValue.scale(repeatCount));
-                            }
-
-                            return quatValue;
-                        // Vector3
-                        case Animation.ANIMATIONTYPE_VECTOR3:
-                            var vec3Value = useTangent ? this._animation.vector3InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this._animation.vector3InterpolateFunction(startValue, endValue, gradient);
-                            switch (loopMode) {
-                                case Animation.ANIMATIONLOOPMODE_CYCLE:
-                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    return vec3Value;
-                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return vec3Value.add(offsetValue.scale(repeatCount));
-                            }
-                        // Vector2
-                        case Animation.ANIMATIONTYPE_VECTOR2:
-                            var vec2Value = useTangent ? this._animation.vector2InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this._animation.vector2InterpolateFunction(startValue, endValue, gradient);
-                            switch (loopMode) {
-                                case Animation.ANIMATIONLOOPMODE_CYCLE:
-                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    return vec2Value;
-                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return vec2Value.add(offsetValue.scale(repeatCount));
-                            }
-                        // Size
-                        case Animation.ANIMATIONTYPE_SIZE:
-                            switch (loopMode) {
-                                case Animation.ANIMATIONLOOPMODE_CYCLE:
-                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    return this._animation.sizeInterpolateFunction(startValue, endValue, gradient);
-                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return this._animation.sizeInterpolateFunction(startValue, endValue, gradient).add(offsetValue.scale(repeatCount));
-                            }
-                        // Color3
-                        case Animation.ANIMATIONTYPE_COLOR3:
-                            switch (loopMode) {
-                                case Animation.ANIMATIONLOOPMODE_CYCLE:
-                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    return this._animation.color3InterpolateFunction(startValue, endValue, gradient);
-                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return this._animation.color3InterpolateFunction(startValue, endValue, gradient).add(offsetValue.scale(repeatCount));
-                            }
-                        // Matrix
-                        case Animation.ANIMATIONTYPE_MATRIX:
-                            switch (loopMode) {
-                                case Animation.ANIMATIONLOOPMODE_CYCLE:
-                                case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    if (Animation.AllowMatricesInterpolation) {
-                                        this._workValue = this._animation.matrixInterpolateFunction(startValue, endValue, gradient, this._workValue);
-                                        return this._workValue;
-                                    }
-                                case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return startValue;
-                            }
-                        default:
-                            break;
-                    }
-                    break;
-                }
-            }
-            return this._getKeyValue(keys[keys.length - 1].value);
+            return this._animation._interpolate(currentFrame, repeatCount, this._workValue, loopMode, offsetValue, highLimitValue);
         }
 
         /**
@@ -253,6 +222,12 @@
             }
         }
 
+        /**
+         * Sets the value of the runtime animation
+         * @param target The target property of the runtime animation
+         * @param currentValue The current value to use for the runtime animation
+         * @param weight The weight to use for the runtime animation (Defaults to 1.0)
+         */
         private _setValue(target: any, currentValue: any, weight = 1.0): void {
             // Set value
             var path: any;
@@ -327,18 +302,17 @@
                             this._currentValue = Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
                         }
                     }
-                } else if (this._originalBlendValue.constructor) { // Complex value
+                } else { 
                     let constructor = this._originalBlendValue.constructor;
                     if (constructor.Lerp) { // Lerp supported
                         this._currentValue = constructor.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
                     } else if (constructor.Slerp) { // Slerp supported
                         this._currentValue = constructor.Slerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                    } else if (this._originalBlendValue.toFixed) { // Number
+                        this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                     } else { // Blending not supported
                         this._currentValue = currentValue;
                     }
-
-                } else  { // Direct value
-                    this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                 }
                 this._blendingFactor += blendingSpeed;
             } else {
@@ -356,6 +330,10 @@
             }
         }
 
+        /**
+         * Gets the loop pmode of the runtime animation
+         * @returns Loop Mode
+         */
         private _getCorrectLoopMode(): number | undefined {
             if ( this._target && this._target.animationPropertiesOverride) {
                 return this._target.animationPropertiesOverride.loopMode;
@@ -382,16 +360,15 @@
             this.setValue(currentValue, -1);
         }
 
+        /**
+         * @ignore Internal use only
+         */
         public _prepareForSpeedRatioChange(newSpeedRatio: number): void {
             let newRatio = this._previousDelay * (this._animation.framePerSecond * newSpeedRatio) / 1000.0;
 
             this._ratioOffset = this._previousRatio - newRatio;
         }
 
-        private _ratioOffset = 0;
-        private _previousDelay: number = 0;
-        private _previousRatio: number = 0;
-
         /**
          * Execute the current animation
          * @param delay defines the delay to add to the current frame
@@ -446,7 +423,7 @@
 
             if (((to > from && ratio > range) || (from > to && ratio < range)) && !loop) { // If we are out of range and not looping get back to caller
                 returnValue = false;
-                highLimitValue = this._getKeyValue(keys[keys.length - 1].value);
+                highLimitValue = this._animation._getKeyValue(keys[keys.length - 1].value);
             } else {
                 // Get max value if required
 

+ 32 - 19
src/Bones/babylon.bone.ts

@@ -38,7 +38,7 @@
         private _parent: Nullable<Bone>;
         private _scalingDeterminant = 1;
         private _worldTransform = new Matrix();
-        
+
         private _localScaling: Vector3;
         private _localRotation: Quaternion;
         private _localPosition: Vector3;
@@ -84,7 +84,9 @@
 
             this.setParent(parentBone, false);
 
-            this._updateDifferenceMatrix();
+            if (baseMatrix || localMatrix) {
+                this._updateDifferenceMatrix();
+            }
         }
 
         // Members
@@ -202,7 +204,7 @@
         public set position(newPosition: Vector3) {
             this._decompose();
             this._localPosition.copyFrom(newPosition);
-            
+
             this._markAsDirtyAndCompose();
         }
 
@@ -267,23 +269,29 @@
         }
 
         /**
-         * Update the local matrix
-         * @param matrix defines the new local matrix
+         * Update the base and local matrices
+         * @param matrix defines the new base or local matrix
          * @param updateDifferenceMatrix defines if the difference matrix must be updated
+         * @param updateLocalMatrix defines if the local matrix should be updated
          */
-        public updateMatrix(matrix: Matrix, updateDifferenceMatrix = true): void {
+        public updateMatrix(matrix: Matrix, updateDifferenceMatrix = true, updateLocalMatrix = true): void {
             this._baseMatrix.copyFrom(matrix);
-            this._localMatrix.copyFrom(matrix);
 
             if (updateDifferenceMatrix) {
                 this._updateDifferenceMatrix();
             }
 
-            this._markAsDirtyAndDecompose();
+            if (updateLocalMatrix) {
+                this._localMatrix.copyFrom(matrix);
+                this._markAsDirtyAndDecompose();
+            }
+            else {
+                this.markAsDirty();
+            }
         }
 
         /** @ignore */
-        public _updateDifferenceMatrix(rootMatrix?: Matrix): void {
+        public _updateDifferenceMatrix(rootMatrix?: Matrix, updateChildren = true): void {
             if (!rootMatrix) {
                 rootMatrix = this._baseMatrix;
             }
@@ -296,8 +304,10 @@
 
             this._absoluteTransform.invertToRef(this._invertedAbsoluteTransform);
 
-            for (var index = 0; index < this.children.length; index++) {
-                this.children[index]._updateDifferenceMatrix();
+            if (updateChildren) {
+                for (var index = 0; index < this.children.length; index++) {
+                    this.children[index]._updateDifferenceMatrix();
+                }
             }
 
             this._scalingDeterminant = (this._absoluteTransform.determinant() < 0 ? -1 : 1);
@@ -318,7 +328,7 @@
         }
 
         private _markAsDirtyAndDecompose() {
-            this.markAsDirty();            
+            this.markAsDirty();
             this._needToDecompose = true;
         }
 
@@ -520,6 +530,9 @@
             for (var child of this.children) {
                 var cm = child.getLocalMatrix();
                 cm.multiplyToRef(scaleMat, cm);
+                cm.m[12] *= x;
+                cm.m[13] *= y;
+                cm.m[14] *= z;
 
                 child._markAsDirtyAndDecompose();
             }
@@ -537,12 +550,12 @@
          * Set the bone scaling in local space
          * @param scale defines the scaling vector
          */
-        public setScale(scale: Vector3): void {          
+        public setScale(scale: Vector3): void {
             this._decompose();
             this._localScaling.copyFrom(scale);
             this._markAsDirtyAndCompose();
-        }    
-        
+        }
+
         /**
          * Gets the current scaling in local space
          * @returns the current scaling vector
@@ -559,7 +572,7 @@
         public getScaleToRef(result: Vector3) {
             this._decompose();
             result.copyFrom(this._localScaling);
-        }        
+        }
 
         /**
          * Set the yaw, pitch, and roll of the bone in local or world space
@@ -572,7 +585,7 @@
         public setYawPitchRoll(yaw: number, pitch: number, roll: number, space = Space.LOCAL, mesh?: AbstractMesh): void {
             if (space === Space.LOCAL) {
                 var quat = Bone._tmpQuat;
-                Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, quat);                
+                Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, quat);
                 this.setRotationQuaternion(quat, space, mesh);
                 return;
             }
@@ -619,7 +632,7 @@
             if (space === Space.LOCAL) {
                 var quat = Bone._tmpQuat;
                 Quaternion.RotationAxisToRef(axis, angle, quat);
-    
+
                 this.setRotationQuaternion(quat, space, mesh);
                 return;
             }
@@ -658,7 +671,7 @@
                 this._localRotation.copyFrom(quat);
 
                 this._markAsDirtyAndCompose();
-    
+
                 return;
             }
 

+ 6 - 0
src/Cameras/VR/babylon.vrExperienceHelper.ts

@@ -799,6 +799,9 @@ module BABYLON {
             }
             else if (this._vrDeviceOrientationCamera) {
                 this._vrDeviceOrientationCamera.position = this._position;
+                if(this._scene.activeCamera){
+                    this._vrDeviceOrientationCamera.minZ = this._scene.activeCamera.minZ
+                }
                 this._scene.activeCamera = this._vrDeviceOrientationCamera;
                 this._scene.getEngine().switchFullscreen(true);
                 this.updateButtonVisibility();
@@ -849,6 +852,9 @@ module BABYLON {
             if (this._interactionsEnabled) {
                 this._scene.unregisterBeforeRender(this.beforeRender);
             }
+
+            // resize to update width and height when exiting vr exits fullscreen
+            this._scene.getEngine().resize();
         }
 
         /**

+ 7 - 0
src/Collisions/babylon.collisionCoordinator.ts

@@ -77,9 +77,13 @@ module BABYLON {
         radius: Array<number>;
     }
 
+    /** Defines supported task for worker process */
     export enum WorkerTaskType {
+        /** Initialization */
         INIT,
+        /** Update of geometry */
         UPDATE,
+        /** Evaluate collision */
         COLLIDE
     }
 
@@ -113,8 +117,11 @@ module BABYLON {
         removedGeometries: Array<string>;
     }
 
+    /** Defines kind of replies returned by worker */
     export enum WorkerReplyType {
+        /** Success */
         SUCCESS,
+        /** Unkown error */
         UNKNOWN_ERROR
     }
 

+ 24 - 5
src/Culling/babylon.boundingBox.ts

@@ -1,6 +1,6 @@
 module BABYLON {
     export class BoundingBox implements ICullable {
-        public vectors: Vector3[] = new Array<Vector3>();
+        public vectors: Vector3[];
         public center: Vector3;
         public centerWorld: Vector3;
         public extendSize: Vector3;
@@ -9,12 +9,32 @@
         public vectorsWorld: Vector3[] = new Array<Vector3>();
         public minimumWorld: Vector3;
         public maximumWorld: Vector3;
-
+        public minimum: Vector3;
+        public maximum: Vector3;
 
         private _worldMatrix: Matrix;
 
-        constructor(public minimum: Vector3, public maximum: Vector3) {
+        /**
+         * Creates a new bounding box
+         * @param min defines the minimum vector (in local space)
+         * @param max defines the maximum vector (in local space)
+         */
+        constructor(min: Vector3, max: Vector3) {
+            this.reConstruct(min, max);
+        }
+
+        // Methods
+
+        /**
+         * Recreates the entire bounding box from scratch
+         * @param min defines the new minimum vector (in local space)
+         * @param max defines the new maximum vector (in local space) 
+         */
+        public reConstruct(min: Vector3, max: Vector3) {
+            this.minimum = min.clone();
+            this.maximum = max.clone()
             // Bounding vectors
+            this.vectors= new Array<Vector3>();
             this.vectors.push(this.minimum.clone());
             this.vectors.push(this.maximum.clone());
 
@@ -50,10 +70,9 @@
             this.centerWorld = Vector3.Zero();
             this.extendSizeWorld = Vector3.Zero();
 
-            this._update(Matrix.Identity());
+            this._update(this._worldMatrix || Matrix.Identity());
         }
 
-        // Methods
         public getWorldMatrix(): Matrix {
             return this._worldMatrix;
         }

+ 23 - 4
src/Culling/babylon.boundingSphere.ts

@@ -4,17 +4,36 @@
         public radius: number;
         public centerWorld: Vector3;
         public radiusWorld: number;
+        public minimum: Vector3;
+        public maximum: Vector3;
 
         private _tempRadiusVector = Vector3.Zero();
 
-        constructor(public minimum: Vector3, public maximum: Vector3) {
-            var distance = Vector3.Distance(minimum, maximum);
+        /**
+         * Creates a new bounding sphere
+         * @param min defines the minimum vector (in local space)
+         * @param max defines the maximum vector (in local space)
+         */
+        constructor(min: Vector3, max: Vector3) {
+            this.reConstruct(min, max);
+        }
+
+        /**
+         * Recreates the entire bounding sphere from scratch
+         * @param min defines the new minimum vector (in local space)
+         * @param max defines the new maximum vector (in local space) 
+         */
+        public reConstruct(min: Vector3, max: Vector3) {
+            this.minimum = min.clone();
+            this.maximum = max.clone()
+
+            var distance = Vector3.Distance(min, max);
 
-            this.center = Vector3.Lerp(minimum, maximum, 0.5);
+            this.center = Vector3.Lerp(min, max, 0.5);
             this.radius = distance * 0.5;
 
             this.centerWorld = Vector3.Zero();
-            this._update(Matrix.Identity());
+            this._update(Matrix.Identity());            
         }
 
         // Methods

+ 1 - 1
src/Engine/babylon.engine.ts

@@ -726,7 +726,7 @@
          * Returns the current version of the framework
          */
         public static get Version(): string {
-            return "3.2.0-beta.4";
+            return "3.2.0-beta.5";
         }
 
         // Updatable statics so stick with vars here

+ 98 - 2
src/Gamepad/babylon.xboxGamepad.ts

@@ -1,25 +1,46 @@
 module BABYLON {
 
+    /**
+     * Defines supported buttons for XBox360 compatible gamepads
+     */
     export enum Xbox360Button {
+        /** A */
         A,
+        /** B */
         B,
+        /** X */
         X,
+        /** Y */
         Y,
+        /** Start */
         Start,
+        /** Back */
         Back,
+        /** Left button */
         LB,
+        /** Right button */
         RB,
+        /** Left stick */
         LeftStick,
+        /** Right stick */
         RightStick
     }
 
+    /** Defines values for XBox360 DPad  */
     export enum Xbox360Dpad {
+        /** Up */
         Up,
+        /** Down */
         Down,
+        /** Left */
         Left,
+        /** Right */
         Right
     }
 
+    /**
+     * Defines a XBox360 gamepad
+     */
     export class Xbox360Pad extends Gamepad {
         private _leftTrigger: number = 0;
         private _rightTrigger: number = 0;
@@ -32,9 +53,13 @@
         private _ondpaddown: (dPadPressed: Xbox360Dpad) => void;
         private _ondpadup: (dPadReleased: Xbox360Dpad) => void;
 
+        /** Observable raised when a button is pressed */
         public onButtonDownObservable = new Observable<Xbox360Button>();
+        /** Observable raised when a button is released */
         public onButtonUpObservable = new Observable<Xbox360Button>();        
+        /** Observable raised when a pad is pressed */
         public onPadDownObservable = new Observable<Xbox360Dpad>();
+        /** Observable raised when a pad is released */
         public onPadUpObservable = new Observable<Xbox360Dpad>();        
 
         private _buttonA: number = 0;
@@ -55,20 +80,38 @@
 
         private _isXboxOnePad: boolean = false;
 
+        /**
+         * Creates a new XBox360 gamepad object
+         * @param id defines the id of this gamepad
+         * @param index defines its index
+         * @param gamepad defines the internal HTML gamepad object
+         * @param xboxOne defines if it is a XBox One gamepad
+         */
         constructor(id: string, index: number, gamepad: any, xboxOne: boolean = false) {
             super(id, index, gamepad, 0, 1, 2, 3);
             this.type = Gamepad.XBOX;
             this._isXboxOnePad = xboxOne;
         }
 
+        /**
+         * Defines the callback to call when left trigger is pressed
+         * @param callback defines the callback to use
+         */
         public onlefttriggerchanged(callback: (value: number) => void) {
             this._onlefttriggerchanged = callback;
         }
 
+        /**
+         * Defines the callback to call when right trigger is pressed
+         * @param callback defines the callback to use
+         */        
         public onrighttriggerchanged(callback: (value: number) => void) {
             this._onrighttriggerchanged = callback;
         }
-
+ 
+        /**
+         * Gets or sets left trigger value
+         */
         public get leftTrigger(): number {
             return this._leftTrigger;
         }
@@ -79,6 +122,9 @@
             this._leftTrigger = newValue;
         }
 
+        /**
+         * Gets or sets right trigger value
+         */        
         public get rightTrigger(): number {
             return this._rightTrigger;
         }
@@ -89,15 +135,34 @@
             this._rightTrigger = newValue;
         }
 
+        /**
+         * Defines the callback to call when a button is pressed
+         * @param callback defines the callback to use
+         */
         public onbuttondown(callback: (buttonPressed: Xbox360Button) => void) {
             this._onbuttondown = callback;
         }
+
+        /**
+         * Defines the callback to call when a button is released
+         * @param callback defines the callback to use
+         */        
         public onbuttonup(callback: (buttonReleased: Xbox360Button) => void) {
             this._onbuttonup = callback;
         }
+
+        /**
+         * Defines the callback to call when a pad is pressed
+         * @param callback defines the callback to use
+         */             
         public ondpaddown(callback: (dPadPressed: Xbox360Dpad) => void) {
             this._ondpaddown = callback;
         }
+
+        /**
+         * Defines the callback to call when a pad is released
+         * @param callback defines the callback to use
+         */             
         public ondpadup(callback: (dPadReleased: Xbox360Dpad) => void) {
             this._ondpadup = callback;
         }
@@ -143,90 +208,121 @@
             return newValue;
         }
 
+        /** Gets or sets value of A button */
         public get buttonA(): number {
             return this._buttonA;
         }
         public set buttonA(value) {
             this._buttonA = this._setButtonValue(value, this._buttonA, Xbox360Button.A);
         }
+
+        /** Gets or sets value of B button */
         public get buttonB(): number {
             return this._buttonB;
         }
         public set buttonB(value) {
             this._buttonB = this._setButtonValue(value, this._buttonB, Xbox360Button.B);
         }
+
+        /** Gets or sets value of X button */       
         public get buttonX(): number {
             return this._buttonX;
         }
         public set buttonX(value) {
             this._buttonX = this._setButtonValue(value, this._buttonX, Xbox360Button.X);
         }
+
+        /** Gets or sets value of Y button */        
         public get buttonY(): number {
             return this._buttonY;
         }
         public set buttonY(value) {
             this._buttonY = this._setButtonValue(value, this._buttonY, Xbox360Button.Y);
-        }
+        }        
+        
+        /** Gets or sets value of Start button  */
         public get buttonStart(): number {
             return this._buttonStart;
         }
         public set buttonStart(value) {
             this._buttonStart = this._setButtonValue(value, this._buttonStart, Xbox360Button.Start);
         }
+
+        /** Gets or sets value of Back button  */        
         public get buttonBack(): number {
             return this._buttonBack;
         }
         public set buttonBack(value) {
             this._buttonBack = this._setButtonValue(value, this._buttonBack, Xbox360Button.Back);
         }
+
+        /** Gets or sets value of Left button  */        
         public get buttonLB(): number {
             return this._buttonLB;
         }
         public set buttonLB(value) {
             this._buttonLB = this._setButtonValue(value, this._buttonLB, Xbox360Button.LB);
         }
+
+        /** Gets or sets value of Right button  */        
         public get buttonRB(): number {
             return this._buttonRB;
         }
         public set buttonRB(value) {
             this._buttonRB = this._setButtonValue(value, this._buttonRB, Xbox360Button.RB);
         }
+
+        /** Gets or sets value of left stick */  
         public get buttonLeftStick(): number {
             return this._buttonLeftStick;
         }
         public set buttonLeftStick(value) {
             this._buttonLeftStick = this._setButtonValue(value, this._buttonLeftStick, Xbox360Button.LeftStick);
         }
+
+        /** Gets or sets value of right stick */  
         public get buttonRightStick(): number {
             return this._buttonRightStick;
         }
         public set buttonRightStick(value) {
             this._buttonRightStick = this._setButtonValue(value, this._buttonRightStick, Xbox360Button.RightStick);
         }
+
+        /** Gets or sets value of DPad up */  
         public get dPadUp(): number {
             return this._dPadUp;
         }
         public set dPadUp(value) {
             this._dPadUp = this._setDPadValue(value, this._dPadUp, Xbox360Dpad.Up);
         }
+
+        /** Gets or sets value of DPad down */  
         public get dPadDown(): number {
             return this._dPadDown;
         }
         public set dPadDown(value) {
             this._dPadDown = this._setDPadValue(value, this._dPadDown, Xbox360Dpad.Down);
         }
+
+        /** Gets or sets value of DPad left */  
         public get dPadLeft(): number {
             return this._dPadLeft;
         }
         public set dPadLeft(value) {
             this._dPadLeft = this._setDPadValue(value, this._dPadLeft, Xbox360Dpad.Left);
         }
+
+        /** Gets or sets value of DPad right */  
         public get dPadRight(): number {
             return this._dPadRight;
         }
         public set dPadRight(value) {
             this._dPadRight = this._setDPadValue(value, this._dPadRight, Xbox360Dpad.Right);
         }
+
+        /**
+         * Force the gamepad to synchronize with device values
+         */
         public update() {
             super.update();
             if (this._isXboxOnePad) {

+ 4 - 23
src/Helpers/babylon.environmentHelper.ts

@@ -396,37 +396,18 @@ module BABYLON {
         /**
          * Sets the primary color of all the available elements.
          * @param color the main color to affect to the ground and the background
-         * @param perceptual Specifies wether the chosen color has been set as intented to be seen e.g. in gamma space not accounting for exposure and tone mapping
          */
-        public setMainColor(color: Color3, perceptual = false): void {
+        public setMainColor(color: Color3): void {
             if (this.groundMaterial) {
-                if (perceptual) {
-                    this.groundMaterial.perceptualColor = color;
-                }
-                else {
-                    this.groundMaterial.primaryColor = color;
-                }
+                this.groundMaterial.primaryColor = color;
             }
 
             if (this.skyboxMaterial) {
-                if (perceptual) {
-                    this.skyboxMaterial.perceptualColor = color;
-                }
-                else {
-                    this.skyboxMaterial.primaryColor = color;
-                }
+                this.skyboxMaterial.primaryColor = color;
             }
 
             if (this.groundMirror) {
-                if (perceptual && this.groundMaterial) {
-                    this.groundMirror.clearColor = new Color4(this.groundMaterial.primaryColor.r, 
-                        this.groundMaterial.primaryColor.g, 
-                        this.groundMaterial.primaryColor.b, 
-                        1.0);
-                }
-                else {
-                    this.groundMirror.clearColor = new Color4(color.r, color.g, color.b, 1.0);
-                }
+                this.groundMirror.clearColor = new Color4(color.r, color.g, color.b, 1.0);
             }
         }
 

+ 2 - 1
src/Lights/babylon.spotLight.ts

@@ -116,7 +116,8 @@
         }
 
         @serializeAsTexture("projectedLightTexture")
-        private _projectionTexture: Nullable<BaseTexture>;;
+        private _projectionTexture: Nullable<BaseTexture>;
+        
         /** 
          * Gets the projection texture of the light.
         */

+ 10 - 33
src/Materials/Background/babylon.backgroundMaterial.ts

@@ -155,8 +155,10 @@
         public primaryColor = Color3.White();
         
         @serializeAsColor3()
-        protected _perceptualColor: Nullable<Color3>;
+        protected __perceptualColor: Nullable<Color3>;
         /**
+         * Experimental Internal Use Only.
+         * 
          * Key light Color in "perceptual value" meaning the color you would like to see on screen.
          * This acts as a helper to set the primary color to a more "human friendly" value.
          * Conversion to linear space as well as exposure and tone mapping correction will be applied to keep the
@@ -164,11 +166,11 @@
          * (This does not account for contrast color grading and color curves as they are considered post effect and not directly
          * part of lighting setup.)
          */
-        public get perceptualColor(): Nullable<Color3> {
-            return this._perceptualColor;
+        public get _perceptualColor(): Nullable<Color3> {
+            return this.__perceptualColor;
         }
-        public set perceptualColor(value: Nullable<Color3>) {
-            this._perceptualColor = value;
+        public set _perceptualColor(value: Nullable<Color3>) {
+            this.__perceptualColor = value;
             this._computePrimaryColorFromPerceptualColor();
             this._markAllSubMeshesAsLightsDirty();
         }
@@ -711,6 +713,7 @@
                         }
                     } else {
                         defines.REFLECTION = false;
+                        defines.REFLECTIONFRESNEL = false;
                         defines.REFLECTIONFALLOFF = false;
                         defines.REFLECTIONBLUR = false;
                         defines.REFLECTIONMAP_3D = false;
@@ -865,44 +868,20 @@
         }
 
         /**
-         * Tone Mapping calibration (should match image processing tone mapping calibration value).
-         */
-        private static readonly _tonemappingCalibration = 1.590579;
-
-        /**
          * Compute the primary color according to the chosen perceptual color.
          */
         private _computePrimaryColorFromPerceptualColor(): void {
-            if (!this._perceptualColor) {
+            if (!this.__perceptualColor) {
                 return;
             }
 
-            this._primaryColor.copyFrom(this._perceptualColor);
+            this._primaryColor.copyFrom(this.__perceptualColor);
 
             // Revert gamma space.
             this._primaryColor.toLinearSpaceToRef(this._primaryColor);
 
             // Revert image processing configuration.
             if (this._imageProcessingConfiguration) {
-                // Revert tone mapping.
-                if (this._imageProcessingConfiguration.toneMappingEnabled) {
-                    // shader reference.
-                    // tonemapped.rgb = 1.0 - exp2(-tonemappingCalibration * color.rgb);
-                    // providing
-                    // log2(1.0 - tonemapped.rgb) / -tonemappingCalibration = color.rgb;
-
-                    // 1.0 - tonemapped.rgb
-                    this._white.subtractToRef(this._primaryColor, this._primaryColor);
-
-                    // log2(1.0 - tonemapped.rgb)
-                    this._primaryColor.r = Scalar.Log2(this._primaryColor.r);
-                    this._primaryColor.g = Scalar.Log2(this._primaryColor.g);
-                    this._primaryColor.b = Scalar.Log2(this._primaryColor.b);
-                    
-                    // log2(1.0 - tonemapped.rgb) / -tonemappingCalibration
-                    this._primaryColor.scaleToRef(-1 / BackgroundMaterial._tonemappingCalibration, this._primaryColor);
-                }
-
                 // Revert Exposure.
                 this._primaryColor.scaleToRef(1 / this._imageProcessingConfiguration.exposure, this._primaryColor);
             }
@@ -921,13 +900,11 @@
             // Find the highlight color based on the configuration.
             this._primaryColor.scaleToRef(this._primaryColorShadowLevel, this._primaryShadowColor);
             this._primaryColor.subtractToRef(this._primaryShadowColor, this._primaryShadowColor);
-            this._primaryShadowColor.clampToRef(0, 1, this._primaryShadowColor);
 
             // Find the shadow color based on the configuration.
             this._white.subtractToRef(this._primaryColor, this._primaryHighlightColor);
             this._primaryHighlightColor.scaleToRef(this._primaryColorHighlightLevel, this._primaryHighlightColor);
             this._primaryColor.addToRef(this._primaryHighlightColor, this._primaryHighlightColor);
-            this._primaryHighlightColor.clampToRef(0, 1, this._primaryHighlightColor);
         }
 
         /**

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

@@ -220,7 +220,7 @@ module BABYLON {
                     if (light.getTypeID() === Light.LIGHTTYPEID_SPOTLIGHT) {
                         type = "SPOTLIGHT" + lightIndex;
                         let spotLight = light as SpotLight;
-                        defines["PROJECTEDLIGHTTEXTURE" + lightIndex] = spotLight.projectionTexture ? spotLight.projectionTexture.isReady() : false;
+                        defines["PROJECTEDLIGHTTEXTURE" + lightIndex] = spotLight.projectionTexture ? true : false;
                     } else if (light.getTypeID() === Light.LIGHTTYPEID_HEMISPHERICLIGHT) {
                         type = "HEMILIGHT" + lightIndex;
                     } else if (light.getTypeID() === Light.LIGHTTYPEID_POINTLIGHT) {

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

@@ -241,6 +241,12 @@ module BABYLON {
         @serialize()
         public invertRefractionY = true;
 
+        /**
+         * Defines the alpha limits in alpha test mode
+         */
+        @serialize()
+        public alphaCutOff = 0.4;        
+
         @serialize("useLightmapAsShadowmap")
         private _useLightmapAsShadowmap = false;
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")
@@ -876,7 +882,7 @@ module BABYLON {
                     "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "normalMatrix", "lightmapMatrix", "refractionMatrix",
                     "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
                     "vReflectionPosition", "vReflectionSize",
-                    "logarithmicDepthConstant", "vTangentSpaceParams"
+                    "logarithmicDepthConstant", "vTangentSpaceParams", "alphaCutOff"
                 ];
 
                 var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler", "refractionCubeSampler", "refraction2DSampler"]
@@ -968,12 +974,19 @@ module BABYLON {
 
         public unbind(): void {
             if (this._activeEffect) {
+                let needFlag = false;
                 if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
                     this._activeEffect.setTexture("reflection2DSampler", null);
+                    needFlag = true;
                 }
 
                 if (this._refractionTexture && this._refractionTexture.isRenderTarget) {
                     this._activeEffect.setTexture("refraction2DSampler", null);
+                    needFlag = true;
+                }
+
+                if (needFlag) {
+                    this._markAllSubMeshesAsTexturesDirty();
                 }
             }
 
@@ -1047,6 +1060,10 @@ module BABYLON {
                         if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                             this._uniformBuffer.updateFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                             MaterialHelper.BindTextureMatrix(this._diffuseTexture, this._uniformBuffer, "diffuse");
+
+                            if (this._diffuseTexture.hasAlpha) {
+                                effect.setFloat("alphaCutOff", this.alphaCutOff);
+                            }
                         }
 
                         if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {

+ 15 - 0
src/Math/babylon.math.ts

@@ -5840,15 +5840,23 @@
         }
     }
 
+    /** Defines supported spaces */
     export enum Space {
+        /** Local (object) space */
         LOCAL = 0,
+        /** World space */
         WORLD = 1,
+        /** Bone space */
         BONE = 2
     }
 
+    /** Defines the 3 main axes */
     export class Axis {
+        /** X axis */
         public static X: Vector3 = new Vector3(1.0, 0.0, 0.0);
+        /** Y axis */
         public static Y: Vector3 = new Vector3(0.0, 1.0, 0.0);
+        /** Z axis */
         public static Z: Vector3 = new Vector3(0.0, 0.0, 1.0);
     };
 
@@ -5882,8 +5890,15 @@
         }
     }
 
+    /**
+     * Defines potential orientation for back face culling
+     */
     export enum Orientation {
+        /**
+         * Clockwise
+         */
         CW = 0,
+        /** Counter clockwise */
         CCW = 1
     }
 

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

@@ -248,12 +248,10 @@
                 return;
             }
 
-            for (var subMesh of this.subMeshes) {
-                subMesh.setEffect(null);
-            }
+            this._unBindEffect();
         }
 
-        private _receiveShadows = false;
+       private _receiveShadows = false;
         public get receiveShadows(): boolean {
             return this._receiveShadows;
         }
@@ -538,6 +536,13 @@
             this._markSubMeshesAsLightDirty();
         }
 
+        /** @ignore */
+        public _unBindEffect() {
+            for (var subMesh of this.subMeshes) {
+                subMesh.setEffect(null);
+            }
+        }        
+
         public _removeLightSource(light: Light): void {
             var index = this._lightSources.indexOf(light);
 

+ 9 - 1
src/Mesh/babylon.mesh.ts

@@ -87,7 +87,7 @@
                 this.onBeforeDrawObservable.remove(this._onBeforeDrawObserver);
             }
             this._onBeforeDrawObserver = this.onBeforeDrawObservable.add(callback);
-        }
+        }     
 
         // Members
         public delayLoadState = Engine.DELAYLOADSTATE_NONE;
@@ -288,6 +288,14 @@
             return ret;
         }
 
+        public _unBindEffect() {
+            super._unBindEffect();
+
+            for (var instance of this.instances) {
+                instance._unBindEffect();
+            }
+        }           
+
         /**
          * True if the mesh has some Levels Of Details (LOD).  
          * Returns a boolean. 

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

@@ -114,10 +114,11 @@
     }
 
     /**
-     * The implemented types of simplification.
-     * At the moment only Quadratic Error Decimation is implemented.
+     * The implemented types of simplification
+     * At the moment only Quadratic Error Decimation is implemented
      */
     export enum SimplificationType {
+        /** Quadratic error decimation */
         QUADRATIC
     }
 

+ 8 - 4
src/Physics/babylon.physicsHelper.ts

@@ -634,16 +634,20 @@ module BABYLON {
     * The strenght of the force in correspondence to the distance of the affected object
     */
     export enum PhysicsRadialImpulseFalloff {
-        Constant, // impulse is constant in strength across it's whole radius
-        Linear // impulse gets weaker if it's further from the origin
+        /** Defines that impulse is constant in strength across it's whole radius */
+        Constant,
+        /** DEfines that impulse gets weaker if it's further from the origin */
+        Linear 
     }
 
     /**
      * The strenght of the force in correspondence to the distance of the affected object
      */
     export enum PhysicsUpdraftMode {
-        Center, // the upstream forces will pull towards the top center of the cylinder
-        Perpendicular // once a impostor is inside the cylinder, it will shoot out perpendicular from the ground of the cylinder
+        /** Defines that the upstream forces will pull towards the top center of the cylinder */
+        Center,
+        /** Defines that once a impostor is inside the cylinder, it will shoot out perpendicular from the ground of the cylinder */
+        Perpendicular
     }
 
 

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

@@ -1,14 +1,34 @@
 module BABYLON {
+    /** Defines operator used for tonemapping */
     export enum TonemappingOperator {
+        /** Hable */
         Hable = 0,
+        /** Reinhard */
         Reinhard = 1,
+        /** HejiDawson */
         HejiDawson = 2,
+        /** Photographic */
         Photographic = 3,
     };
 
+    /**
+     * Defines a post process to apply tone mapping
+     */
     export class TonemapPostProcess extends PostProcess {
 
-        constructor(name: string, private _operator: TonemappingOperator, public exposureAdjustment: number, camera: Camera, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, textureFormat = Engine.TEXTURETYPE_UNSIGNED_INT) {
+        /**
+         * Creates a new TonemapPostProcess
+         * @param name defines the name of the postprocess
+         * @param _operator defines the operator to use
+         * @param exposureAdjustment defines the required exposure adjustement
+         * @param camera defines the camera to use (can be null)
+         * @param samplingMode defines the required sampling mode (BABYLON.Texture.BILINEAR_SAMPLINGMODE by default)
+         * @param engine defines the hosting engine (can be ignore if camera is set)
+         * @param textureFormat defines the texture format to use (BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT by default)
+         */
+        constructor(name: string, private _operator: TonemappingOperator, 
+            /** Defines the required exposure adjustement */
+            public exposureAdjustment: number, camera: Camera, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, textureFormat = Engine.TEXTURETYPE_UNSIGNED_INT) {
             super(name, "tonemap", ["_ExposureAdjustment"], null, 1.0, camera, samplingMode, engine, true, null, textureFormat);
 
             var defines = "#define ";

+ 0 - 3
src/Shaders/ShadersInclude/lightsFragmentFunctions.fx

@@ -113,8 +113,5 @@ vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler, m
 	vec4 strq = textureProjectionMatrix * vec4(vPositionW, 1.0);
 	strq /= strq.w;
 	vec3 textureColor = texture2D(projectionLightSampler, strq.xy).rgb;
-#ifdef PBR
-	textureColor = toLinearSpace(textureColor);
-#endif
 	return textureColor;
 }

+ 7 - 0
src/Shaders/ShadersInclude/pbrLightFunctions.fx

@@ -153,4 +153,11 @@ lightingInfo computeHemisphericLighting(vec3 viewDirectionW, vec3 vNormal, vec4
     #endif
 
     return result;
+}
+
+vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler, mat4 textureProjectionMatrix){
+	vec4 strq = textureProjectionMatrix * vec4(vPositionW, 1.0);
+	strq /= strq.w;
+	vec3 textureColor = texture2D(projectionLightSampler, strq.xy).rgb;
+	return toLinearSpace(textureColor);
 }

+ 5 - 1
src/Shaders/default.fragment.fx

@@ -121,6 +121,10 @@ uniform sampler2D refraction2DSampler;
 	uniform sampler2D specularSampler;
 #endif
 
+#ifdef ALPHATEST
+	uniform float alphaCutOff;
+#endif
+
 // Fresnel
 #include<fresnelFunction>
 
@@ -192,7 +196,7 @@ void main(void) {
 	baseColor = texture2D(diffuseSampler, vDiffuseUV + uvOffset);
 
 	#ifdef ALPHATEST
-		if (baseColor.a < 0.4)
+		if (baseColor.a < alphaCutOff)
 			discard;
 	#endif
 

+ 44 - 2
src/Tools/babylon.virtualJoystick.ts

@@ -3,16 +3,37 @@
 // & on Seb Lee-Delisle original work: http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/ 
 
 module BABYLON {
+    /**
+     * Defines the potential axis of a Joystick
+     */
     export enum JoystickAxis {
+        /** X axis */
         X,
+        /** Y axis */
         Y,
+        /** Z axis */
         Z
     }
 
+    /**
+     * Class used to define virtual joystick (used in touch mode)
+     */
     export class VirtualJoystick {
+        /**
+         * Gets or sets a boolean indicating that left and right values must be inverted
+         */
         public reverseLeftRight: boolean;
+        /**
+         * Gets or sets a boolean indicating that up and down values must be inverted
+         */
         public reverseUpDown: boolean;
+        /**
+         * Gets the offset value for the position (ie. the change of the position value)
+         */
         public deltaPosition: Vector3;
+        /**
+         * Gets a boolean indicating if the virtual joystick was pressed
+         */
         public pressed: boolean;
 
         // Used to draw the virtual joystick inside a 2D canvas on top of the WebGL rendering canvas
@@ -43,6 +64,10 @@ module BABYLON {
         private _onPointerUpHandlerRef: (e: PointerEvent) => any;
         private _onResize: (e: any) => any;
 
+        /**
+         * Creates a new virtual joystick
+         * @param leftJoystick defines that the joystick is for left hand (false by default)
+         */
         constructor(leftJoystick?: boolean) {
             if (leftJoystick) {
                 this._leftJoystick = true;
@@ -140,6 +165,10 @@ module BABYLON {
             requestAnimationFrame(() => { this._drawVirtualJoystick(); });
         }
 
+        /**
+         * Defines joystick sensibility (ie. the ratio beteen a physical move and virtual joystick position change)
+         * @param newJoystickSensibility defines the new sensibility
+         */
         public setJoystickSensibility(newJoystickSensibility: number) {
             this._joystickSensibility = newJoystickSensibility;
             this._inversedSensibility = 1 / (this._joystickSensibility / 1000);
@@ -249,11 +278,18 @@ module BABYLON {
             this._joystickColor = newColor;
         }
 
+        /**
+         * Defines a callback to call when the joystick is touched
+         * @param action defines the callback
+         */
         public setActionOnTouch(action: () => any) {
             this._action = action;
         }
 
-        // Define which axis you'd like to control for left & right 
+        /**
+         * Defines which axis you'd like to control for left & right 
+         * @param axis defines the axis to use
+         */
         public setAxisForLeftRight(axis: JoystickAxis) {
             switch (axis) {
                 case JoystickAxis.X:
@@ -267,7 +303,10 @@ module BABYLON {
             }
         }
 
-        // Define which axis you'd like to control for up & down 
+        /**
+         * Defines which axis you'd like to control for up & down 
+         * @param axis defines the axis to use
+         */
         public setAxisForUpDown(axis: JoystickAxis) {
             switch (axis) {
                 case JoystickAxis.X:
@@ -324,6 +363,9 @@ module BABYLON {
             requestAnimationFrame(() => { this._drawVirtualJoystick(); });
         }
 
+        /**
+         * Release internal HTML canvas
+         */
         public releaseCanvas() {
             if (VirtualJoystick.vjCanvas) {
                 VirtualJoystick.vjCanvas.removeEventListener('pointerdown', this._onPointerDownHandlerRef);

+ 34 - 7
tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts

@@ -170,7 +170,7 @@ describe('Babylon Scene Loader', function () {
             });
         });
 
-        it('Load CompileMaterialsTest', () => {
+        it('Load CompileMaterialsTest with compileMaterials', () => {
             const scene = new BABYLON.Scene(subject);
             const promises = new Array<Promise<void>>();
             let createShaderProgramSpy: sinon.SinonSpy;
@@ -187,12 +187,9 @@ describe('Babylon Scene Loader', function () {
                 loader.compileMaterials = true;
 
                 promises.push(loader.whenCompleteAsync().then(() => {
-                    try {
-                        expect(createShaderProgramSpy.called, "createShaderProgramSpy.called").to.be.false;
-                    }
-                    finally {
-                        createShaderProgramSpy.restore();
-                    }
+                    const called = createShaderProgramSpy.called;
+                    createShaderProgramSpy.restore();
+                    expect(called, "createShaderProgramCalled").to.be.false;
                 }));
             }, undefined, undefined, undefined, true);
 
@@ -203,6 +200,36 @@ describe('Babylon Scene Loader', function () {
             return Promise.all(promises);
         });
 
+        it('Load BrainStem with compileMaterials', () => {
+            const scene = new BABYLON.Scene(subject);
+            const promises = new Array<Promise<void>>();
+            let createShaderProgramSpy: sinon.SinonSpy;
+
+            subject.runRenderLoop(() => {
+                for (const mesh of scene.meshes) {
+                    if (mesh.material && mesh.isEnabled()) {
+                        expect(mesh.material.isReady(mesh), "mesh material is ready").to.be.true;
+                    }
+                }
+            });
+
+            BABYLON.SceneLoader.OnPluginActivatedObservable.add((loader: BABYLON.GLTFFileLoader) => {
+                loader.compileMaterials = true;
+
+                promises.push(loader.whenCompleteAsync().then(() => {
+                    const called = createShaderProgramSpy.called;
+                    createShaderProgramSpy.restore();
+                    expect(called, "createShaderProgramCalled").to.be.false;
+                }));
+            }, undefined, undefined, undefined, true);
+
+            promises.push(BABYLON.SceneLoader.AppendAsync("/Playground/scenes/BrainStem/", "BrainStem.gltf", scene).then(() => {
+                createShaderProgramSpy = sinon.spy(subject, "createShaderProgram");
+            }));
+
+            return Promise.all(promises);
+        });
+
         it('Load Alien', () => {
             const scene = new BABYLON.Scene(subject);
             return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/Alien/", "Alien.gltf", scene).then(result => {