sebastien 6 tahun lalu
induk
melakukan
7ede423415
98 mengubah file dengan 57091 tambahan dan 39609 penghapusan
  1. 4332 3441
      Playground/babylon.d.txt
  2. 77 73
      Tools/Gulp/config.json
  3. 0 2
      Tools/Gulp/gulpfile.js
  4. 3 3
      Tools/Gulp/tasks/gulpTasks-typedoc.js
  5. 0 6
      Viewer/src/externalModules.d.ts
  6. 2 2
      Viewer/src/loader/plugins/msftLodLoaderPlugin.ts
  7. 3 2
      Viewer/src/model/viewerModel.ts
  8. 2 2
      Viewer/tests/unit/tsconfig.json
  9. 2 2
      Viewer/tsconfig-gulp.json
  10. 2 2
      Viewer/tsconfig.json
  11. 3391 3391
      dist/preview release/babylon.d.ts
  12. 984 45
      dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts
  13. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  14. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js.map
  15. 3192 2944
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  16. 1 0
      dist/preview release/loaders/babylon.glTF1FileLoader.js.map
  17. 3205 1
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  18. 1 0
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js.map
  19. 3934 3691
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  20. 1 0
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  21. 3934 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  22. 1 0
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js.map
  23. 6170 5860
      dist/preview release/loaders/babylon.glTFFileLoader.js
  24. 1 0
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  25. 6209 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  26. 1 0
      dist/preview release/loaders/babylon.glTFFileLoader.min.js.map
  27. 372 885
      dist/preview release/loaders/babylon.objFileLoader.js
  28. 1 0
      dist/preview release/loaders/babylon.objFileLoader.js.map
  29. 373 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  30. 1 0
      dist/preview release/loaders/babylon.objFileLoader.min.js.map
  31. 373 173
      dist/preview release/loaders/babylon.stlFileLoader.js
  32. 1 0
      dist/preview release/loaders/babylon.stlFileLoader.js.map
  33. 373 1
      dist/preview release/loaders/babylon.stlFileLoader.min.js
  34. 1 0
      dist/preview release/loaders/babylon.stlFileLoader.min.js.map
  35. 1617 1851
      dist/preview release/loaders/babylonjs.loaders.d.ts
  36. 7282 6889
      dist/preview release/loaders/babylonjs.loaders.js
  37. 1 0
      dist/preview release/loaders/babylonjs.loaders.js.map
  38. 2 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  39. 1 0
      dist/preview release/loaders/babylonjs.loaders.min.js.map
  40. 3375 1857
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  41. 10 10
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts
  42. 10 10
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.module.d.ts
  43. 2 1
      dist/preview release/viewer/babylon.viewer.d.ts
  44. 125 1
      dist/preview release/viewer/babylon.viewer.js
  45. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  46. 3 2
      dist/preview release/viewer/babylon.viewer.module.d.ts
  47. 4 4
      inspector/src/tabs/GLTFTab.ts
  48. 18 0
      loaders/legacy/legacy-glTF1FileLoader.ts
  49. 18 0
      loaders/legacy/legacy-glTF2FileLoader.ts
  50. 22 0
      loaders/legacy/legacy-glTFFileLoader.ts
  51. 14 0
      loaders/legacy/legacy-objFileLoader.ts
  52. 14 0
      loaders/legacy/legacy-stlFileLoader.ts
  53. 0 984
      loaders/src/OBJ/babylon.objFileLoader.ts
  54. 0 210
      loaders/src/STL/babylon.stlFileLoader.ts
  55. 1 0
      loaders/src/STL/index.ts
  56. 207 0
      loaders/src/STL/stlFileLoader.ts
  57. 0 82
      loaders/src/glTF/1.0/babylon.glTFBinaryExtension.ts
  58. 0 1809
      loaders/src/glTF/1.0/babylon.glTFLoader.ts
  59. 0 158
      loaders/src/glTF/1.0/babylon.glTFLoaderExtension.ts
  60. 0 387
      loaders/src/glTF/1.0/babylon.glTFLoaderInterfaces.ts
  61. 0 233
      loaders/src/glTF/1.0/babylon.glTFLoaderUtils.ts
  62. 0 179
      loaders/src/glTF/1.0/babylon.glTFMaterialsCommonExtension.ts
  63. 87 0
      loaders/src/glTF/1.0/glTFBinaryExtension.ts
  64. 159 0
      loaders/src/glTF/1.0/glTFLoaderExtension.ts
  65. 385 0
      loaders/src/glTF/1.0/glTFLoaderInterfaces.ts
  66. 232 0
      loaders/src/glTF/1.0/glTFLoaderUtils.ts
  67. 1811 0
      loaders/src/glTF/1.0/glTFLoaderV1.ts
  68. 183 0
      loaders/src/glTF/1.0/glTFMaterialsCommonExtension.ts
  69. 6 0
      loaders/src/glTF/1.0/index.ts
  70. 113 111
      loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts
  71. 91 89
      loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts
  72. 95 93
      loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts
  73. 75 74
      loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts
  74. 58 57
      loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts
  75. 56 55
      loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts
  76. 258 257
      loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts
  77. 218 217
      loaders/src/glTF/2.0/Extensions/MSFT_lod.ts
  78. 35 34
      loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts
  79. 35 34
      loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts
  80. 10 0
      loaders/src/glTF/2.0/Extensions/index.ts
  81. 0 2124
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  82. 0 110
      loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts
  83. 0 227
      loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts
  84. 2123 0
      loaders/src/glTF/2.0/glTFLoader.ts
  85. 106 0
      loaders/src/glTF/2.0/glTFLoaderExtension.ts
  86. 228 0
      loaders/src/glTF/2.0/glTFLoaderInterfaces.ts
  87. 4 0
      loaders/src/glTF/2.0/index.ts
  88. 0 874
      loaders/src/glTF/babylon.glTFFileLoader.ts
  89. 879 0
      loaders/src/glTF/glTFFileLoader.ts
  90. 3 0
      loaders/src/glTF/index.ts
  91. 3 0
      loaders/src/index.ts
  92. 19 0
      loaders/src/legacy.ts
  93. 0 15
      loaders/src/tsconfig.json
  94. 41 0
      loaders/tsconfig.json
  95. 68 0
      loaders/webpack.config.js
  96. 7 7
      tests/unit/babylon/babylon.example.tests.ts
  97. 1 1
      tests/unit/babylon/babylonReference.ts
  98. 29 29
      tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts

File diff ditekan karena terlalu besar
+ 4332 - 3441
Playground/babylon.d.txt


+ 77 - 73
Tools/Gulp/config.json

@@ -1886,7 +1886,7 @@
             "processDeclaration": {
                 "filename": "babylonjs.proceduralTextures.module.d.ts",
                 "packageName": "babylonjs-procedural-textures",
-                "moduleName": "BABYLON.PROCEDURALTEXTURES",
+                "moduleName": "BABYLON",
                 "importsToRemove": [],
                 "classMap": {
                     "babylonjs": "BABYLON",
@@ -1899,91 +1899,95 @@
     "loaders": {
         "libraries": [
             {
-                "files": [
-                    "../../loaders/src/STL/babylon.stlFileLoader.ts"
-                ],
-                "output": "babylon.stlFileLoader.js"
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylonjs.loaders.min.js",
+                "webpack": "../../loaders/webpack.config.js",
+                "entry": "./src/legacy.ts",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true,
+                "isMain": true
             },
             {
-                "files": [
-                    "../../loaders/src/OBJ/babylon.objFileLoader.ts"
-                ],
-                "output": "babylon.objFileLoader.js"
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.objFileLoader.min.js",
+                "webpack": "../../loaders/webpack.config.js",
+                "entry": "./legacy/legacy-objFileLoader.ts",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true,
+                "preventLoadLibrary": true
             },
             {
-                "files": [
-                    "../../loaders/src/glTF/babylon.glTFFileLoader.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderInterfaces.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFLoader.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderUtils.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderExtension.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFBinaryExtension.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFMaterialsCommonExtension.ts"
-                ],
-                "doNotIncludeInBundle": true,
-                "output": "babylon.glTF1FileLoader.js"
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.stlFileLoader.min.js",
+                "webpack": "../../loaders/webpack.config.js",
+                "entry": "./legacy/legacy-stlFileLoader.ts",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true,
+                "preventLoadLibrary": true
             },
             {
-                "files": [
-                    "../../loaders/src/glTF/babylon.glTFFileLoader.ts",
-                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
-                    "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
-                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts"
-                ],
-                "doNotIncludeInBundle": true,
-                "output": "babylon.glTF2FileLoader.js"
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.glTF1FileLoader.min.js",
+                "webpack": "../../loaders/webpack.config.js",
+                "entry": "./legacy/legacy-glTF1FileLoader.ts",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true,
+                "preventLoadLibrary": true
             },
             {
-                "files": [
-                    "../../loaders/src/glTF/babylon.glTFFileLoader.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderInterfaces.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFLoader.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderUtils.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderExtension.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFBinaryExtension.ts",
-                    "../../loaders/src/glTF/1.0/babylon.glTFMaterialsCommonExtension.ts",
-                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
-                    "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
-                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts"
-                ],
-                "output": "babylon.glTFFileLoader.js"
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.glTF2FileLoader.min.js",
+                "webpack": "../../loaders/webpack.config.js",
+                "entry": "./legacy/legacy-glTF2FileLoader.ts",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true,
+                "preventLoadLibrary": true
+            },
+            {
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.glTFFileLoader.min.js",
+                "webpack": "../../loaders/webpack.config.js",
+                "entry": "./legacy/legacy-glTFFileLoader.ts",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true,
+                "preventLoadLibrary": true
             }
         ],
         "build": {
-            "srcOutputDirectory": "../../loaders/",
+            "webpack": "../../loaders/webpack.config.js",
+            "srcOutputDirectory": "../../loaders/src/",
             "distOutputDirectory": "/loaders/",
-            "buildAsModule": true,
-            "moduleName": "babylonjs-loaders",
-            "outputFilename": "babylonjs.loaders",
-            "moduleDeclaration": {
-                "name": "Loaders",
-                "module": "babylonjs-loaders"
+            "dtsBundle": {
+                "name": "babylonjs-loaders",
+                "main": "../../dist/preview release/loaders/build/src/index.d.ts",
+                "out": "../babylonjs.loaders.module.d.ts",
+                "baseDir": "../../dist/preview release/loaders/build/",
+                "headerText": "BabylonJS Loaders"
             },
-            "extraTypesDependencies": [
-                "babylonjs",
-                "babylonjs-gltf2interface"
-            ],
-            "extendsRoot": true
+            "processDeclaration": {
+                "filename": "babylonjs.loaders.module.d.ts",
+                "packageName": "babylonjs-loaders",
+                "moduleName": "BABYLON",
+                "importsToRemove": [],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON",
+                    "babylonjs-serializers": "BABYLON",
+                    "babylonjs-gltf2interface": "BABYLON.GLTF2"
+                }
+            }
         }
     },
     "serializers": {

+ 0 - 2
Tools/Gulp/gulpfile.js

@@ -566,8 +566,6 @@ var buildExternalLibrary = function(library, settings, watch) {
 
                 });
             } else {
-                console.log(library.output)
-
                 var wpConfig;
                 if (library.entry) {
                     wpConfig = require(settings.build.webpack);

+ 3 - 3
Tools/Gulp/tasks/gulpTasks-typedoc.js

@@ -16,9 +16,9 @@ gulp.task("typedoc-generate", function() {
         .src([
             "../../dist/preview release/babylon.d.ts",
             "../../dist/preview release/gui/babylon.gui.d.ts",
-            "../../dist/preview release/loaders/babylon.glTF2FileLoader.d.ts",
-            "../../dist/preview release/serializers/babylon.glTF2Serializer.d.ts",
-            "../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts"])
+            "../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts",
+            "../../dist/preview release/loaders/babylonjs.loaders.d.ts",
+            "../../dist/preview release/serializers/babylon.glTF2Serializer.d.ts"])
         .pipe(typedoc({
             // TypeScript options (see typescript docs)
             mode: "modules",

+ 0 - 6
Viewer/src/externalModules.d.ts

@@ -1,6 +0,0 @@
-/// <reference path="../../dist/babylon.glTF2Interface.d.ts"/>
-/// <reference path="../../dist/preview release/loaders/babylonjs.loaders.d.ts"/>
-
-declare module "babylonjs-loaders" {
-    export = BABYLON;
-}

+ 2 - 2
Viewer/src/loader/plugins/msftLodLoaderPlugin.ts

@@ -1,5 +1,5 @@
 import { ISceneLoaderPlugin, ISceneLoaderPluginAsync } from 'babylonjs';
-import { GLTF2, IGLTFLoaderExtension } from 'babylonjs-loaders';
+import { IGLTFLoaderExtension, MSFT_lod } from 'babylonjs-loaders';
 
 import { ViewerModel } from '../../model/viewerModel';
 import { ILoaderPlugin } from './loaderPlugin';
@@ -17,7 +17,7 @@ export class MSFTLodLoaderPlugin implements ILoaderPlugin {
 
     public onExtensionLoaded(extension: IGLTFLoaderExtension) {
         if (extension.name === "MSFT_lod" && this._model.configuration.loaderConfiguration) {
-            const MSFT_lod = extension as GLTF2.Loader.Extensions.MSFT_lod;
+            const MSFT_lod = extension as MSFT_lod;
             MSFT_lod.enabled = !!this._model.configuration.loaderConfiguration.progressiveLoading;
             MSFT_lod.maxLODsToLoad = this._model.configuration.loaderConfiguration.maxLODsToLoad || Number.MAX_VALUE;
         }

+ 3 - 2
Viewer/src/model/viewerModel.ts

@@ -1,5 +1,6 @@
 import { ISceneLoaderPlugin, ISceneLoaderPluginAsync, AnimationGroup, Animatable, AbstractMesh, Tools, Scene, SceneLoader, Observable, SceneLoaderProgressEvent, Tags, IParticleSystem, Skeleton, IDisposable, Nullable, Animation, Quaternion, Material, Vector3, AnimationPropertiesOverride, QuinticEase, SineEase, CircleEase, BackEase, BounceEase, CubicEase, ElasticEase, ExponentialEase, PowerEase, QuadraticEase, QuarticEase, PBRMaterial, MultiMaterial } from "babylonjs";
-import { GLTFFileLoader, GLTF2 } from "babylonjs-loaders";
+import { GLTFFileLoader } from "babylonjs-loaders";
+import { IAsset } from "babylonjs-gltf2interface";
 import { IModelConfiguration } from "../configuration/interfaces/modelConfiguration";
 import { IModelAnimationConfiguration } from "../configuration/interfaces/modelAnimationConfiguration";
 import { IModelAnimation, GroupModelAnimation, AnimationPlayMode, ModelAnimationConfiguration, EasingFunction, AnimationState } from "./modelAnimation";
@@ -90,7 +91,7 @@ export class ViewerModel implements IDisposable {
      */
     public loadId: number;
 
-    public loadInfo: GLTF2.IAsset;
+    public loadInfo: IAsset;
     private _loadedUrl: string;
     private _modelConfiguration: IModelConfiguration;
 

+ 2 - 2
Viewer/tests/unit/tsconfig.json

@@ -26,10 +26,10 @@
                 "../../../../dist/preview release/babylon.d.ts"
             ],
             "babylonjs-loaders": [
-                "../../../src/externalModules.d.ts"
+                "../../../../dist/preview release/loaders/babylonjs.loaders.module.d.ts"
             ],
             "babylonjs-gltf2interface": [
-                "../../../../dist/babylon.glTF2Interface.d.ts"
+                "../../../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts"
             ],
             "babylonjs-viewer-assets": [
                 "../../src/assets/"

+ 2 - 2
Viewer/tsconfig-gulp.json

@@ -26,10 +26,10 @@
                 "../../dist/preview release/babylon.d.ts"
             ],
             "babylonjs-loaders": [
-                "externalModules.d.ts"
+                "../../dist/preview release/loaders/babylonjs.loaders.module.d.ts"
             ],
             "babylonjs-gltf2interface": [
-                "../../dist/babylon.glTF2Interface.d.ts"
+                "../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts"
             ],
             "deepmerge": [
                 "./helper/deepmerge.d.ts"

+ 2 - 2
Viewer/tsconfig.json

@@ -26,10 +26,10 @@
                 "../../dist/preview release/babylon.d.ts"
             ],
             "babylonjs-loaders": [
-                "externalModules.d.ts"
+                "../../dist/preview release/loaders/babylonjs.loaders.module.d.ts"
             ],
             "babylonjs-gltf2interface": [
-                "../../dist/babylon.glTF2Interface.d.ts"
+                "../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts"
             ],
             "deepmerge": [
                 "./helper/deepmerge.d.ts"

File diff ditekan karena terlalu besar
+ 3391 - 3391
dist/preview release/babylon.d.ts


File diff ditekan karena terlalu besar
+ 984 - 45
dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts


File diff ditekan karena terlalu besar
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


File diff ditekan karena terlalu besar
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js.map


File diff ditekan karena terlalu besar
+ 3192 - 2944
dist/preview release/loaders/babylon.glTF1FileLoader.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.glTF1FileLoader.js.map


File diff ditekan karena terlalu besar
+ 3205 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.glTF1FileLoader.min.js.map


File diff ditekan karena terlalu besar
+ 3934 - 3691
dist/preview release/loaders/babylon.glTF2FileLoader.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


File diff ditekan karena terlalu besar
+ 3934 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.min.js.map


File diff ditekan karena terlalu besar
+ 6170 - 5860
dist/preview release/loaders/babylon.glTFFileLoader.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.glTFFileLoader.js.map


File diff ditekan karena terlalu besar
+ 6209 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.glTFFileLoader.min.js.map


File diff ditekan karena terlalu besar
+ 372 - 885
dist/preview release/loaders/babylon.objFileLoader.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.objFileLoader.js.map


File diff ditekan karena terlalu besar
+ 373 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.objFileLoader.min.js.map


+ 373 - 173
dist/preview release/loaders/babylon.stlFileLoader.js

@@ -1,173 +1,373 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-var BABYLON;
-(function (BABYLON) {
-    var STLFileLoader = /** @class */ (function () {
-        function STLFileLoader() {
-            this.solidPattern = /solid (\S*)([\S\s]*)endsolid[ ]*(\S*)/g;
-            this.facetsPattern = /facet([\s\S]*?)endfacet/g;
-            this.normalPattern = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
-            this.vertexPattern = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
-            this.name = "stl";
-            // force data to come in as an ArrayBuffer
-            // we'll convert to string if it looks like it's an ASCII .stl
-            this.extensions = {
-                ".stl": { isBinary: true },
-            };
-        }
-        STLFileLoader.prototype.importMesh = function (meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons) {
-            var matches;
-            if (typeof data !== "string") {
-                if (this.isBinary(data)) {
-                    // binary .stl
-                    var babylonMesh = new BABYLON.Mesh("stlmesh", scene);
-                    this.parseBinary(babylonMesh, data);
-                    if (meshes) {
-                        meshes.push(babylonMesh);
-                    }
-                    return true;
-                }
-                // ASCII .stl
-                // convert to string
-                var array_buffer = new Uint8Array(data);
-                var str = '';
-                for (var i = 0; i < data.byteLength; i++) {
-                    str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian
-                }
-                data = str;
-            }
-            //if arrived here, data is a string, containing the STLA data.
-            while (matches = this.solidPattern.exec(data)) {
-                var meshName = matches[1];
-                var meshNameFromEnd = matches[3];
-                if (meshName != meshNameFromEnd) {
-                    BABYLON.Tools.Error("Error in STL, solid name != endsolid name");
-                    return false;
-                }
-                // check meshesNames
-                if (meshesNames && meshName) {
-                    if (meshesNames instanceof Array) {
-                        if (!meshesNames.indexOf(meshName)) {
-                            continue;
-                        }
-                    }
-                    else {
-                        if (meshName !== meshesNames) {
-                            continue;
-                        }
-                    }
-                }
-                // stl mesh name can be empty as well
-                meshName = meshName || "stlmesh";
-                var babylonMesh = new BABYLON.Mesh(meshName, scene);
-                this.parseASCII(babylonMesh, matches[2]);
-                if (meshes) {
-                    meshes.push(babylonMesh);
-                }
-            }
-            return true;
-        };
-        STLFileLoader.prototype.load = function (scene, data, rootUrl) {
-            var result = this.importMesh(null, scene, data, rootUrl, null, null, null);
-            if (result) {
-                scene.createDefaultCameraOrLight();
-            }
-            return result;
-        };
-        STLFileLoader.prototype.loadAssetContainer = function (scene, data, rootUrl, onError) {
-            var container = new BABYLON.AssetContainer(scene);
-            this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
-            container.removeAllFromScene();
-            return container;
-        };
-        STLFileLoader.prototype.isBinary = function (data) {
-            // check if file size is correct for binary stl
-            var faceSize, nFaces, reader;
-            reader = new DataView(data);
-            faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);
-            nFaces = reader.getUint32(80, true);
-            if (80 + (32 / 8) + (nFaces * faceSize) === reader.byteLength) {
-                return true;
-            }
-            // check characters higher than ASCII to confirm binary
-            var fileLength = reader.byteLength;
-            for (var index = 0; index < fileLength; index++) {
-                if (reader.getUint8(index) > 127) {
-                    return true;
-                }
-            }
-            return false;
-        };
-        STLFileLoader.prototype.parseBinary = function (mesh, data) {
-            var reader = new DataView(data);
-            var faces = reader.getUint32(80, true);
-            var dataOffset = 84;
-            var faceLength = 12 * 4 + 2;
-            var offset = 0;
-            var positions = new Float32Array(faces * 3 * 3);
-            var normals = new Float32Array(faces * 3 * 3);
-            var indices = new Uint32Array(faces * 3);
-            var indicesCount = 0;
-            for (var face = 0; face < faces; face++) {
-                var start = dataOffset + face * faceLength;
-                var normalX = reader.getFloat32(start, true);
-                var normalY = reader.getFloat32(start + 4, true);
-                var normalZ = reader.getFloat32(start + 8, true);
-                for (var i = 1; i <= 3; i++) {
-                    var vertexstart = start + i * 12;
-                    // ordering is intentional to match ascii import
-                    positions[offset] = reader.getFloat32(vertexstart, true);
-                    positions[offset + 2] = reader.getFloat32(vertexstart + 4, true);
-                    positions[offset + 1] = reader.getFloat32(vertexstart + 8, true);
-                    normals[offset] = normalX;
-                    normals[offset + 2] = normalY;
-                    normals[offset + 1] = normalZ;
-                    offset += 3;
-                }
-                indices[indicesCount] = indicesCount++;
-                indices[indicesCount] = indicesCount++;
-                indices[indicesCount] = indicesCount++;
-            }
-            mesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, positions);
-            mesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, normals);
-            mesh.setIndices(indices);
-            mesh.computeWorldMatrix(true);
-        };
-        STLFileLoader.prototype.parseASCII = function (mesh, solidData) {
-            var positions = [];
-            var normals = [];
-            var indices = [];
-            var indicesCount = 0;
-            //load facets, ignoring loop as the standard doesn't define it can contain more than vertices
-            var matches;
-            while (matches = this.facetsPattern.exec(solidData)) {
-                var facet = matches[1];
-                //one normal per face
-                var normalMatches = this.normalPattern.exec(facet);
-                this.normalPattern.lastIndex = 0;
-                if (!normalMatches) {
-                    continue;
-                }
-                var normal = [Number(normalMatches[1]), Number(normalMatches[5]), Number(normalMatches[3])];
-                var vertexMatch;
-                while (vertexMatch = this.vertexPattern.exec(facet)) {
-                    positions.push(Number(vertexMatch[1]), Number(vertexMatch[5]), Number(vertexMatch[3]));
-                    normals.push(normal[0], normal[1], normal[2]);
-                }
-                indices.push(indicesCount++, indicesCount++, indicesCount++);
-                this.vertexPattern.lastIndex = 0;
-            }
-            this.facetsPattern.lastIndex = 0;
-            mesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, positions);
-            mesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, normals);
-            mesh.setIndices(indices);
-            mesh.computeWorldMatrix(true);
-        };
-        return STLFileLoader;
-    }());
-    BABYLON.STLFileLoader = STLFileLoader;
-    if (BABYLON.SceneLoader) {
-        BABYLON.SceneLoader.RegisterPlugin(new STLFileLoader());
-    }
-})(BABYLON || (BABYLON = {}));
-
-//# sourceMappingURL=babylon.stlFileLoader.js.map
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(typeof exports === 'object' && typeof module === 'object')
+		module.exports = factory(require("babylonjs"));
+	else if(typeof define === 'function' && define.amd)
+		define("babylonjs-loaders", ["babylonjs"], factory);
+	else if(typeof exports === 'object')
+		exports["babylonjs-loaders"] = factory(require("babylonjs"));
+	else
+		root["LOADERS"] = factory(root["BABYLON"]);
+})(window, function(__WEBPACK_EXTERNAL_MODULE_babylonjs__) {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// define __esModule on exports
+/******/ 	__webpack_require__.r = function(exports) {
+/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 		}
+/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 	};
+/******/
+/******/ 	// create a fake namespace object
+/******/ 	// mode & 1: value is a module id, require it
+/******/ 	// mode & 2: merge all properties of value into the ns
+/******/ 	// mode & 4: return value when already ns object
+/******/ 	// mode & 8|1: behave like require
+/******/ 	__webpack_require__.t = function(value, mode) {
+/******/ 		if(mode & 1) value = __webpack_require__(value);
+/******/ 		if(mode & 8) return value;
+/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ 		var ns = Object.create(null);
+/******/ 		__webpack_require__.r(ns);
+/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ 		return ns;
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = "./legacy/legacy-stlFileLoader.ts");
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ "../node_modules/webpack/buildin/global.js":
+/*!*************************************************!*\
+  !*** ../node_modules/webpack/buildin/global.js ***!
+  \*************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+var g;
+
+// This works in non-strict mode
+g = (function() {
+	return this;
+})();
+
+try {
+	// This works if eval is allowed (see CSP)
+	g = g || Function("return this")() || (1, eval)("this");
+} catch (e) {
+	// This works if the window reference is available
+	if (typeof window === "object") g = window;
+}
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+module.exports = g;
+
+
+/***/ }),
+
+/***/ "./legacy/legacy-stlFileLoader.ts":
+/*!****************************************!*\
+  !*** ./legacy/legacy-stlFileLoader.ts ***!
+  \****************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(global) {
+function __export(m) {
+    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+var MatLib = __webpack_require__(/*! ../src/STL */ "./src/STL/index.ts");
+/**
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    for (var key in MatLib) {
+        globalObject.BABYLON[key] = MatLib[key];
+    }
+}
+__export(__webpack_require__(/*! ../src/STL */ "./src/STL/index.ts"));
+
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/webpack/buildin/global.js */ "../node_modules/webpack/buildin/global.js")))
+
+/***/ }),
+
+/***/ "./src/STL/index.ts":
+/*!**************************!*\
+  !*** ./src/STL/index.ts ***!
+  \**************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+function __export(m) {
+    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+__export(__webpack_require__(/*! ./stlFileLoader */ "./src/STL/stlFileLoader.ts"));
+
+
+/***/ }),
+
+/***/ "./src/STL/stlFileLoader.ts":
+/*!**********************************!*\
+  !*** ./src/STL/stlFileLoader.ts ***!
+  \**********************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", { value: true });
+var babylonjs_1 = __webpack_require__(/*! babylonjs */ "babylonjs");
+var STLFileLoader = /** @class */ (function () {
+    function STLFileLoader() {
+        this.solidPattern = /solid (\S*)([\S\s]*)endsolid[ ]*(\S*)/g;
+        this.facetsPattern = /facet([\s\S]*?)endfacet/g;
+        this.normalPattern = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
+        this.vertexPattern = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
+        this.name = "stl";
+        // force data to come in as an ArrayBuffer
+        // we'll convert to string if it looks like it's an ASCII .stl
+        this.extensions = {
+            ".stl": { isBinary: true },
+        };
+    }
+    STLFileLoader.prototype.importMesh = function (meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons) {
+        var matches;
+        if (typeof data !== "string") {
+            if (this.isBinary(data)) {
+                // binary .stl
+                var babylonMesh = new babylonjs_1.Mesh("stlmesh", scene);
+                this.parseBinary(babylonMesh, data);
+                if (meshes) {
+                    meshes.push(babylonMesh);
+                }
+                return true;
+            }
+            // ASCII .stl
+            // convert to string
+            var array_buffer = new Uint8Array(data);
+            var str = '';
+            for (var i = 0; i < data.byteLength; i++) {
+                str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian
+            }
+            data = str;
+        }
+        //if arrived here, data is a string, containing the STLA data.
+        while (matches = this.solidPattern.exec(data)) {
+            var meshName = matches[1];
+            var meshNameFromEnd = matches[3];
+            if (meshName != meshNameFromEnd) {
+                babylonjs_1.Tools.Error("Error in STL, solid name != endsolid name");
+                return false;
+            }
+            // check meshesNames
+            if (meshesNames && meshName) {
+                if (meshesNames instanceof Array) {
+                    if (!meshesNames.indexOf(meshName)) {
+                        continue;
+                    }
+                }
+                else {
+                    if (meshName !== meshesNames) {
+                        continue;
+                    }
+                }
+            }
+            // stl mesh name can be empty as well
+            meshName = meshName || "stlmesh";
+            var babylonMesh = new babylonjs_1.Mesh(meshName, scene);
+            this.parseASCII(babylonMesh, matches[2]);
+            if (meshes) {
+                meshes.push(babylonMesh);
+            }
+        }
+        return true;
+    };
+    STLFileLoader.prototype.load = function (scene, data, rootUrl) {
+        var result = this.importMesh(null, scene, data, rootUrl, null, null, null);
+        if (result) {
+            scene.createDefaultCameraOrLight();
+        }
+        return result;
+    };
+    STLFileLoader.prototype.loadAssetContainer = function (scene, data, rootUrl, onError) {
+        var container = new babylonjs_1.AssetContainer(scene);
+        this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
+        container.removeAllFromScene();
+        return container;
+    };
+    STLFileLoader.prototype.isBinary = function (data) {
+        // check if file size is correct for binary stl
+        var faceSize, nFaces, reader;
+        reader = new DataView(data);
+        faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);
+        nFaces = reader.getUint32(80, true);
+        if (80 + (32 / 8) + (nFaces * faceSize) === reader.byteLength) {
+            return true;
+        }
+        // check characters higher than ASCII to confirm binary
+        var fileLength = reader.byteLength;
+        for (var index = 0; index < fileLength; index++) {
+            if (reader.getUint8(index) > 127) {
+                return true;
+            }
+        }
+        return false;
+    };
+    STLFileLoader.prototype.parseBinary = function (mesh, data) {
+        var reader = new DataView(data);
+        var faces = reader.getUint32(80, true);
+        var dataOffset = 84;
+        var faceLength = 12 * 4 + 2;
+        var offset = 0;
+        var positions = new Float32Array(faces * 3 * 3);
+        var normals = new Float32Array(faces * 3 * 3);
+        var indices = new Uint32Array(faces * 3);
+        var indicesCount = 0;
+        for (var face = 0; face < faces; face++) {
+            var start = dataOffset + face * faceLength;
+            var normalX = reader.getFloat32(start, true);
+            var normalY = reader.getFloat32(start + 4, true);
+            var normalZ = reader.getFloat32(start + 8, true);
+            for (var i = 1; i <= 3; i++) {
+                var vertexstart = start + i * 12;
+                // ordering is intentional to match ascii import
+                positions[offset] = reader.getFloat32(vertexstart, true);
+                positions[offset + 2] = reader.getFloat32(vertexstart + 4, true);
+                positions[offset + 1] = reader.getFloat32(vertexstart + 8, true);
+                normals[offset] = normalX;
+                normals[offset + 2] = normalY;
+                normals[offset + 1] = normalZ;
+                offset += 3;
+            }
+            indices[indicesCount] = indicesCount++;
+            indices[indicesCount] = indicesCount++;
+            indices[indicesCount] = indicesCount++;
+        }
+        mesh.setVerticesData(babylonjs_1.VertexBuffer.PositionKind, positions);
+        mesh.setVerticesData(babylonjs_1.VertexBuffer.NormalKind, normals);
+        mesh.setIndices(indices);
+        mesh.computeWorldMatrix(true);
+    };
+    STLFileLoader.prototype.parseASCII = function (mesh, solidData) {
+        var positions = [];
+        var normals = [];
+        var indices = [];
+        var indicesCount = 0;
+        //load facets, ignoring loop as the standard doesn't define it can contain more than vertices
+        var matches;
+        while (matches = this.facetsPattern.exec(solidData)) {
+            var facet = matches[1];
+            //one normal per face
+            var normalMatches = this.normalPattern.exec(facet);
+            this.normalPattern.lastIndex = 0;
+            if (!normalMatches) {
+                continue;
+            }
+            var normal = [Number(normalMatches[1]), Number(normalMatches[5]), Number(normalMatches[3])];
+            var vertexMatch;
+            while (vertexMatch = this.vertexPattern.exec(facet)) {
+                positions.push(Number(vertexMatch[1]), Number(vertexMatch[5]), Number(vertexMatch[3]));
+                normals.push(normal[0], normal[1], normal[2]);
+            }
+            indices.push(indicesCount++, indicesCount++, indicesCount++);
+            this.vertexPattern.lastIndex = 0;
+        }
+        this.facetsPattern.lastIndex = 0;
+        mesh.setVerticesData(babylonjs_1.VertexBuffer.PositionKind, positions);
+        mesh.setVerticesData(babylonjs_1.VertexBuffer.NormalKind, normals);
+        mesh.setIndices(indices);
+        mesh.computeWorldMatrix(true);
+    };
+    return STLFileLoader;
+}());
+exports.STLFileLoader = STLFileLoader;
+if (babylonjs_1.SceneLoader) {
+    babylonjs_1.SceneLoader.RegisterPlugin(new STLFileLoader());
+}
+
+
+/***/ }),
+
+/***/ "babylonjs":
+/*!****************************************************************************************************!*\
+  !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
+  \****************************************************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs__;
+
+/***/ })
+
+/******/ });
+});
+//# sourceMappingURL=babylon.stlFileLoader.js.map

File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.stlFileLoader.js.map


File diff ditekan karena terlalu besar
+ 373 - 1
dist/preview release/loaders/babylon.stlFileLoader.min.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylon.stlFileLoader.min.js.map


File diff ditekan karena terlalu besar
+ 1617 - 1851
dist/preview release/loaders/babylonjs.loaders.d.ts


File diff ditekan karena terlalu besar
+ 7282 - 6889
dist/preview release/loaders/babylonjs.loaders.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylonjs.loaders.js.map


File diff ditekan karena terlalu besar
+ 2 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/preview release/loaders/babylonjs.loaders.min.js.map


File diff ditekan karena terlalu besar
+ 3375 - 1857
dist/preview release/loaders/babylonjs.loaders.module.d.ts


+ 10 - 10
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts

@@ -1,7 +1,7 @@
 /*BabylonJS Procedural Textures*/
 // Dependencies for this module:
 //   ../../../../Tools/Gulp/babylonjs
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class BrickProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -24,7 +24,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): BrickProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class CloudProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -45,7 +45,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): CloudProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class FireProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -74,7 +74,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): FireProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class GrassProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -95,7 +95,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): GrassProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class MarbleProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -118,7 +118,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): MarbleProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class NormalMapProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -140,7 +140,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): NormalMapProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class PerlinNoiseProceduralTexture extends BABYLON.ProceduralTexture {
             time: number;
             timeScale: number;
@@ -164,7 +164,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): PerlinNoiseProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class RoadProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -184,7 +184,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): RoadProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class StarfieldProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -214,7 +214,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): StarfieldProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class WoodProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;

+ 10 - 10
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.module.d.ts

@@ -313,7 +313,7 @@ declare module 'babylonjs-procedural-textures/src/wood/woodProceduralTexture' {
 /*BabylonJS Procedural Textures*/
 // Dependencies for this module:
 //   ../../../../Tools/Gulp/babylonjs
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class BrickProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -336,7 +336,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): BrickProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class CloudProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -357,7 +357,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): CloudProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class FireProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -386,7 +386,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): FireProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class GrassProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -407,7 +407,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): GrassProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class MarbleProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -430,7 +430,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): MarbleProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class NormalMapProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -452,7 +452,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): NormalMapProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class PerlinNoiseProceduralTexture extends BABYLON.ProceduralTexture {
             time: number;
             timeScale: number;
@@ -476,7 +476,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): PerlinNoiseProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class RoadProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -496,7 +496,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): RoadProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class StarfieldProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;
@@ -526,7 +526,7 @@ declare module BABYLON.PROCEDURALTEXTURES {
             static Parse(parsedTexture: any, scene: BABYLON.Scene, rootUrl: string): StarfieldProceduralTexture;
     }
 }
-declare module BABYLON.PROCEDURALTEXTURES {
+declare module BABYLON {
     export class WoodProceduralTexture extends BABYLON.ProceduralTexture {
             constructor(name: string, size: number, scene: BABYLON.Scene, fallbackTexture?: BABYLON.Texture, generateMipMaps?: boolean);
             updateShaderUniforms(): void;

+ 2 - 1
dist/preview release/viewer/babylon.viewer.d.ts

@@ -5,6 +5,7 @@ declare module "babylonjs-loaders"{ export=BABYLON;}
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
 //   ../../../../../Tools/Gulp/babylonjs
+//   ../../../../../Tools/Gulp/babylonjs-gltf2interface
 //   ../../../../../Tools/Gulp/babylonjs-loaders
 declare module BabylonViewer {
     /**
@@ -586,7 +587,7 @@ declare module BabylonViewer {
                 * A loadID provided by the modelLoader, unique to ths (Abstract)Viewer instance.
                 */
             loadId: number;
-            loadInfo: BABYLON.GLTF2.IAsset;
+            loadInfo: IAsset;
             constructor(_observablesManager: ObservablesManager, modelConfiguration: IModelConfiguration, _configurationContainer?: ConfigurationContainer | undefined);
             shadowsRenderedAfterLoad: boolean;
             getViewerId(): string | undefined;

File diff ditekan karena terlalu besar
+ 125 - 1
dist/preview release/viewer/babylon.viewer.js


File diff ditekan karena terlalu besar
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 3 - 2
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -6,6 +6,7 @@ declare module "babylonjs-loaders"{ export=BABYLON;}
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
 //   ../../../../../Tools/Gulp/babylonjs
+//   ../../../../../Tools/Gulp/babylonjs-gltf2interface
 //   ../../../../../Tools/Gulp/babylonjs-loaders
 
 declare module 'babylonjs-viewer' {
@@ -567,7 +568,7 @@ declare module 'babylonjs-viewer/loader/modelLoader' {
 
 declare module 'babylonjs-viewer/model/viewerModel' {
     import { ISceneLoaderPlugin, ISceneLoaderPluginAsync, AnimationGroup, AbstractMesh, Observable, SceneLoaderProgressEvent, IParticleSystem, Skeleton, IDisposable, Nullable, Animation, Material } from "babylonjs";
-    import { GLTF2 } from "babylonjs-loaders";
+    import { IAsset } from "babylonjs-gltf2interface";
     import { IModelConfiguration } from "babylonjs-viewer/configuration/interfaces/modelConfiguration";
     import { IModelAnimation } from "babylonjs-viewer/model/modelAnimation";
     import { ObservablesManager } from "babylonjs-viewer/managers/observablesManager";
@@ -643,7 +644,7 @@ declare module 'babylonjs-viewer/model/viewerModel' {
                 * A loadID provided by the modelLoader, unique to ths (Abstract)Viewer instance.
                 */
             loadId: number;
-            loadInfo: GLTF2.IAsset;
+            loadInfo: IAsset;
             constructor(_observablesManager: ObservablesManager, modelConfiguration: IModelConfiguration, _configurationContainer?: ConfigurationContainer | undefined);
             shadowsRenderedAfterLoad: boolean;
             getViewerId(): string | undefined;

+ 4 - 4
inspector/src/tabs/GLTFTab.ts

@@ -1,5 +1,5 @@
 import { Mesh, Nullable, NullEngine, PBRMaterial, Scene, SceneLoader, StandardMaterial, Texture, TransformNode } from "babylonjs";
-import { GLTF2, GLTFFileLoader } from "babylonjs-loaders";
+import { GLTFLoaderV2, GLTFFileLoader } from "babylonjs-loaders";
 import { GLTF2Export } from "babylonjs-serializers";
 import { DetailPanel } from "../details/DetailPanel";
 import { Property } from "../details/Property";
@@ -11,7 +11,7 @@ import { TabBar } from "./TabBar";
 
 import * as Split from "Split";
 
-import {} from "babylonjs-gltf2interface";
+import { IGLTFValidationResults } from "babylonjs-gltf2interface";
 
 export class GLTFTab extends Tab {
     private static _LoaderDefaults: any = null;
@@ -24,7 +24,7 @@ export class GLTFTab extends Tab {
     private _split: any;
 
     public static get IsSupported(): boolean {
-        return !!(SceneLoader && GLTFFileLoader && GLTF2.GLTFLoader) || !!GLTF2Export;
+        return !!(SceneLoader && GLTFFileLoader && GLTFLoaderV2) || !!GLTF2Export;
     }
 
     /** @hidden */
@@ -55,7 +55,7 @@ export class GLTFTab extends Tab {
             this._closeDetailsPanel();
         });
 
-        if (SceneLoader && GLTFFileLoader && GLTF2.GLTFLoader) {
+        if (SceneLoader && GLTFFileLoader && GLTFLoaderV2) {
             this._addImport();
         }
 

+ 18 - 0
loaders/legacy/legacy-glTF1FileLoader.ts

@@ -0,0 +1,18 @@
+import * as FileLoader from "../src/glTF/glTFFileLoader";
+import * as Loaders from "../src/glTF/1.0";
+
+/**
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    for (var key in FileLoader) {
+        (<any>globalObject).BABYLON[key] = (<any>FileLoader)[key];
+    }
+    for (var key in Loaders) {
+        (<any>globalObject).BABYLON[key] = (<any>FileLoader)[key];
+    }
+}
+
+export * from "../src/glTF/glTFFileLoader";

+ 18 - 0
loaders/legacy/legacy-glTF2FileLoader.ts

@@ -0,0 +1,18 @@
+import * as FileLoader from "../src/glTF/glTFFileLoader";
+import * as Loaders from "../src/glTF/2.0";
+
+/**
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    for (var key in FileLoader) {
+        (<any>globalObject).BABYLON[key] = (<any>FileLoader)[key];
+    }
+    for (var key in Loaders) {
+        (<any>globalObject).BABYLON[key] = (<any>FileLoader)[key];
+    }
+}
+
+export * from "../src/glTF/glTFFileLoader";

+ 22 - 0
loaders/legacy/legacy-glTFFileLoader.ts

@@ -0,0 +1,22 @@
+import * as FileLoader from "../src/glTF/glTFFileLoader";
+import * as LoadersV1 from "../src/glTF/1.0";
+import * as LoadersV2 from "../src/glTF/2.0";
+
+/**
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    for (var key in FileLoader) {
+        (<any>globalObject).BABYLON[key] = (<any>FileLoader)[key];
+    }
+    for (var key in LoadersV1) {
+        (<any>globalObject).BABYLON[key] = (<any>FileLoader)[key];
+    }
+    for (var key in LoadersV2) {
+        (<any>globalObject).BABYLON[key] = (<any>FileLoader)[key];
+    }
+}
+
+export * from "../src/glTF/glTFFileLoader";

+ 14 - 0
loaders/legacy/legacy-objFileLoader.ts

@@ -0,0 +1,14 @@
+import * as MatLib from "../src/STL";
+
+/**
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    for (var key in MatLib) {
+        (<any>globalObject).BABYLON[key] = (<any>MatLib)[key];
+    }
+}
+
+export * from "../src/STL";

+ 14 - 0
loaders/legacy/legacy-stlFileLoader.ts

@@ -0,0 +1,14 @@
+import * as MatLib from "../src/STL";
+
+/**
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    for (var key in MatLib) {
+        (<any>globalObject).BABYLON[key] = (<any>MatLib)[key];
+    }
+}
+
+export * from "../src/STL";

+ 0 - 984
loaders/src/OBJ/babylon.objFileLoader.ts

@@ -1,984 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-
-    /**
-     * Class reading and parsing the MTL file bundled with the obj file.
-     */
-    export class MTLFileLoader {
-
-        // All material loaded from the mtl will be set here
-        public materials: BABYLON.StandardMaterial[] = [];
-
-        /**
-         * This function will read the mtl file and create each material described inside
-         * This function could be improve by adding :
-         * -some component missing (Ni, Tf...)
-         * -including the specific options available
-         *
-         * @param scene
-         * @param data
-         * @param rootUrl
-         */
-        public parseMTL(scene: BABYLON.Scene, data: string | ArrayBuffer, rootUrl: string) {
-            if (data instanceof ArrayBuffer) {
-                return;
-            }
-
-            //Split the lines from the file
-            var lines = data.split('\n');
-            //Space char
-            var delimiter_pattern = /\s+/;
-            //Array with RGB colors
-            var color: number[];
-            //New material
-            var material: Nullable<BABYLON.StandardMaterial> = null;
-
-            //Look at each line
-            for (var i = 0; i < lines.length; i++) {
-                var line = lines[i].trim();
-
-                // Blank line or comment
-                if (line.length === 0 || line.charAt(0) === '#') {
-                    continue;
-                }
-
-                //Get the first parameter (keyword)
-                var pos = line.indexOf(' ');
-                var key = (pos >= 0) ? line.substring(0, pos) : line;
-                key = key.toLowerCase();
-
-                //Get the data following the key
-                var value: string = (pos >= 0) ? line.substring(pos + 1).trim() : "";
-
-                //This mtl keyword will create the new material
-                if (key === "newmtl") {
-                    //Check if it is the first material.
-                    // Materials specifications are described after this keyword.
-                    if (material) {
-                        //Add the previous material in the material array.
-                        this.materials.push(material);
-                    }
-                    //Create a new material.
-                    // value is the name of the material read in the mtl file
-                    material = new BABYLON.StandardMaterial(value, scene);
-                } else if (key === "kd" && material) {
-                    // Diffuse color (color under white light) using RGB values
-
-                    //value  = "r g b"
-                    color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
-                    //color = [r,g,b]
-                    //Set tghe color into the material
-                    material.diffuseColor = BABYLON.Color3.FromArray(color);
-                } else if (key === "ka" && material) {
-                    // Ambient color (color under shadow) using RGB values
-
-                    //value = "r g b"
-                    color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
-                    //color = [r,g,b]
-                    //Set tghe color into the material
-                    material.ambientColor = BABYLON.Color3.FromArray(color);
-                } else if (key === "ks" && material) {
-                    // Specular color (color when light is reflected from shiny surface) using RGB values
-
-                    //value = "r g b"
-                    color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
-                    //color = [r,g,b]
-                    //Set the color into the material
-                    material.specularColor = BABYLON.Color3.FromArray(color);
-                } else if (key === "ke" && material) {
-                    // Emissive color using RGB values
-                    color = value.split(delimiter_pattern, 3).map(parseFloat);
-                    material.emissiveColor = BABYLON.Color3.FromArray(color);
-                } else if (key === "ns" && material) {
-
-                    //value = "Integer"
-                    material.specularPower = parseFloat(value);
-                } else if (key === "d" && material) {
-                    //d is dissolve for current material. It mean alpha for BABYLON
-                    material.alpha = parseFloat(value);
-
-                    //Texture
-                    //This part can be improved by adding the possible options of texture
-                } else if (key === "map_ka" && material) {
-                    // ambient texture map with a loaded image
-                    //We must first get the folder of the image
-                    material.ambientTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-                } else if (key === "map_kd" && material) {
-                    // Diffuse texture map with a loaded image
-                    material.diffuseTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-                } else if (key === "map_ks" && material) {
-                    // Specular texture map with a loaded image
-                    //We must first get the folder of the image
-                    material.specularTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-                } else if (key === "map_ns") {
-                    //Specular
-                    //Specular highlight component
-                    //We must first get the folder of the image
-                    //
-                    //Not supported by BABYLON
-                    //
-                    //    continue;
-                } else if (key === "map_bump" && material) {
-                    //The bump texture
-                    material.bumpTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-                } else if (key === "map_d" && material) {
-                    // The dissolve of the material
-                    material.opacityTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-
-                    //Options for illumination
-                } else if (key === "illum") {
-                    //Illumination
-                    if (value === "0") {
-                        //That mean Kd == Kd
-                    } else if (value === "1") {
-                        //Color on and Ambient on
-                    } else if (value === "2") {
-                        //Highlight on
-                    } else if (value === "3") {
-                        //Reflection on and Ray trace on
-                    } else if (value === "4") {
-                        //Transparency: Glass on, Reflection: Ray trace on
-                    } else if (value === "5") {
-                        //Reflection: Fresnel on and Ray trace on
-                    } else if (value === "6") {
-                        //Transparency: Refraction on, Reflection: Fresnel off and Ray trace on
-                    } else if (value === "7") {
-                        //Transparency: Refraction on, Reflection: Fresnel on and Ray trace on
-                    } else if (value === "8") {
-                        //Reflection on and Ray trace off
-                    } else if (value === "9") {
-                        //Transparency: Glass on, Reflection: Ray trace off
-                    } else if (value === "10") {
-                        //Casts shadows onto invisible surfaces
-                    }
-                } else {
-                    // console.log("Unhandled expression at line : " + i +'\n' + "with value : " + line);
-                }
-            }
-            //At the end of the file, add the last material
-            if (material) {
-                this.materials.push(material);
-            }
-        }
-
-        /**
-         * Gets the texture for the material.
-         *
-         * If the material is imported from input file,
-         * We sanitize the url to ensure it takes the textre from aside the material.
-         *
-         * @param rootUrl The root url to load from
-         * @param value The value stored in the mtl
-         * @return The Texture
-         */
-        private static _getTexture(rootUrl: string, value: string, scene: Scene): Nullable<Texture> {
-            if (!value) {
-                return null;
-            }
-
-            var url = rootUrl;
-            // Load from input file.
-            if (rootUrl === "file:") {
-                var lastDelimiter = value.lastIndexOf("\\");
-                if (lastDelimiter === -1) {
-                    lastDelimiter = value.lastIndexOf("/");
-                }
-
-                if (lastDelimiter > -1) {
-                    url += value.substr(lastDelimiter + 1);
-                }
-                else {
-                    url += value;
-                }
-            }
-            // Not from input file.
-            else {
-                url += value;
-            }
-
-            return new BABYLON.Texture(url, scene);
-        }
-    }
-
-    export class OBJFileLoader implements ISceneLoaderPluginAsync {
-
-        public static OPTIMIZE_WITH_UV = false;
-        public static INVERT_Y = false;
-        public name = "obj";
-        public extensions = ".obj";
-        public obj = /^o/;
-        public group = /^g/;
-        public mtllib = /^mtllib /;
-        public usemtl = /^usemtl /;
-        public smooth = /^s /;
-        public vertexPattern = /v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
-        // vn float float float
-        public normalPattern = /vn( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
-        // vt float float
-        public uvPattern = /vt( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/;
-        // f vertex vertex vertex ...
-        public facePattern1 = /f\s+(([\d]{1,}[\s]?){3,})+/;
-        // f vertex/uvs vertex/uvs vertex/uvs ...
-        public facePattern2 = /f\s+((([\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
-        // f vertex/uvs/normal vertex/uvs/normal vertex/uvs/normal ...
-        public facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
-        // f vertex//normal vertex//normal vertex//normal ...
-        public facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
-        // f -vertex/-uvs/-normal -vertex/-uvs/-normal -vertex/-uvs/-normal ...
-        public facePattern5 = /f\s+(((-[\d]{1,}\/-[\d]{1,}\/-[\d]{1,}[\s]?){3,})+)/;
-
-        /**
-         * Calls synchronously the MTL file attached to this obj.
-         * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.
-         * Without this function materials are not displayed in the first frame (but displayed after).
-         * In consequence it is impossible to get material information in your HTML file
-         *
-         * @param url The URL of the MTL file
-         * @param rootUrl
-         * @param onSuccess Callback function to be called when the MTL file is loaded
-         * @private
-         */
-        private _loadMTL(url: string, rootUrl: string, onSuccess: (response: string | ArrayBuffer, responseUrl?: string) => any) {
-            //The complete path to the mtl file
-            var pathOfFile = BABYLON.Tools.BaseUrl + rootUrl + url;
-
-            // Loads through the babylon tools to allow fileInput search.
-            BABYLON.Tools.LoadFile(pathOfFile,
-                onSuccess,
-                undefined,
-                undefined,
-                false,
-                () => { console.warn("Error - Unable to load " + pathOfFile); });
-        }
-
-        /**
-         * Imports one or more meshes from the loaded glTF data 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 the glTF data to load
-         * @param rootUrl root url to load from
-         * @param onProgress event that fires when loading progress has occured
-         * @param fileName Defines the name of the file to load
-         * @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, fileName?: string): Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
-            //get the meshes from OBJ file
-            return this._parseSolid(meshesNames, scene, data, rootUrl).then((meshes) => {
-                return {
-                    meshes,
-                    particleSystems: [],
-                    skeletons: [],
-                    animationGroups: []
-                };
-            });
-        }
-
-        /**
-         * Imports all objects from the loaded glTF data and adds them to the scene
-         * @param scene the scene the objects should be added to
-         * @param data the glTF data to load
-         * @param rootUrl root url to load from
-         * @param onProgress event that fires when loading progress has occured
-         * @param fileName Defines the name of the file to load
-         * @returns a promise which completes when objects have been loaded to the scene
-         */
-        public loadAsync(scene: Scene, data: string, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string): Promise<void> {
-            //Get the 3D model
-            return this.importMeshAsync(null, scene, data, rootUrl, onProgress).then(() => {
-                // return 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
-         * @param fileName Defines the name of the file to load
-         * @returns The loaded asset container
-         */
-        public loadAssetContainerAsync(scene: Scene, data: string, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string): Promise<AssetContainer> {
-            return this.importMeshAsync(null, scene, data, rootUrl).then((result) => {
-                var container = new AssetContainer(scene);
-                result.meshes.forEach((mesh) => container.meshes.push(mesh));
-                container.removeAllFromScene();
-                return container;
-            });
-        }
-
-        /**
-         * Read the OBJ file and create an Array of meshes.
-         * Each mesh contains all information given by the OBJ and the MTL file.
-         * i.e. vertices positions and indices, optional normals values, optional UV values, optional material
-         *
-         * @param meshesNames
-         * @param scene BABYLON.Scene The scene where are displayed the data
-         * @param data String The content of the obj file
-         * @param rootUrl String The path to the folder
-         * @returns Array<AbstractMesh>
-         * @private
-         */
-        private _parseSolid(meshesNames: any, scene: BABYLON.Scene, data: string, rootUrl: string): Promise<Array<AbstractMesh>> {
-
-            var positions: Array<BABYLON.Vector3> = [];      //values for the positions of vertices
-            var normals: Array<BABYLON.Vector3> = [];      //Values for the normals
-            var uvs: Array<BABYLON.Vector2> = [];      //Values for the textures
-            var meshesFromObj: Array<any> = [];      //[mesh] Contains all the obj meshes
-            var handledMesh: any;      //The current mesh of meshes array
-            var indicesForBabylon: Array<number> = [];      //The list of indices for VertexData
-            var wrappedPositionForBabylon: Array<BABYLON.Vector3> = [];      //The list of position in vectors
-            var wrappedUvsForBabylon: Array<BABYLON.Vector2> = [];      //Array with all value of uvs to match with the indices
-            var wrappedNormalsForBabylon: Array<BABYLON.Vector3> = [];      //Array with all value of normals to match with the indices
-            var tuplePosNorm: Array<{ normals: Array<number>; idx: Array<number>; uv: Array<number> }> = [];      //Create a tuple with indice of Position, Normal, UV  [pos, norm, uvs]
-            var curPositionInIndices = 0;
-            var hasMeshes: Boolean = false;   //Meshes are defined in the file
-            var unwrappedPositionsForBabylon: Array<number> = [];      //Value of positionForBabylon w/o Vector3() [x,y,z]
-            var unwrappedNormalsForBabylon: Array<number> = [];      //Value of normalsForBabylon w/o Vector3()  [x,y,z]
-            var unwrappedUVForBabylon: Array<number> = [];      //Value of uvsForBabylon w/o Vector3()      [x,y,z]
-            var triangles: Array<string> = [];      //Indices from new triangles coming from polygons
-            var materialNameFromObj: string = "";      //The name of the current material
-            var fileToLoad: string = "";      //The name of the mtlFile to load
-            var materialsFromMTLFile: MTLFileLoader = new MTLFileLoader();
-            var objMeshName: string = "";      //The name of the current obj mesh
-            var increment: number = 1;      //Id for meshes created by the multimaterial
-            var isFirstMaterial: boolean = true;
-
-            /**
-             * Search for obj in the given array.
-             * This function is called to check if a couple of data already exists in an array.
-             *
-             * If found, returns the index of the founded tuple index. Returns -1 if not found
-             * @param arr Array<{ normals: Array<number>, idx: Array<number> }>
-             * @param obj Array<number>
-             * @returns {boolean}
-             */
-            var isInArray = (arr: Array<{ normals: Array<number>; idx: Array<number> }>, obj: Array<number>) => {
-                if (!arr[obj[0]]) { arr[obj[0]] = { normals: [], idx: [] }; }
-                var idx = arr[obj[0]].normals.indexOf(obj[1]);
-
-                return idx === -1 ? -1 : arr[obj[0]].idx[idx];
-            };
-            var isInArrayUV = (arr: Array<{ normals: Array<number>; idx: Array<number>; uv: Array<number> }>, obj: Array<number>) => {
-                if (!arr[obj[0]]) { arr[obj[0]] = { normals: [], idx: [], uv: [] }; }
-                var idx = arr[obj[0]].normals.indexOf(obj[1]);
-
-                if (idx != 1 && (obj[2] == arr[obj[0]].uv[idx])) {
-                    return arr[obj[0]].idx[idx];
-                }
-                return -1;
-            };
-
-            /**
-             * This function set the data for each triangle.
-             * Data are position, normals and uvs
-             * If a tuple of (position, normal) is not set, add the data into the corresponding array
-             * If the tuple already exist, add only their indice
-             *
-             * @param indicePositionFromObj Integer The index in positions array
-             * @param indiceUvsFromObj Integer The index in uvs array
-             * @param indiceNormalFromObj Integer The index in normals array
-             * @param positionVectorFromOBJ Vector3 The value of position at index objIndice
-             * @param textureVectorFromOBJ Vector3 The value of uvs
-             * @param normalsVectorFromOBJ Vector3 The value of normals at index objNormale
-             */
-            var setData = (indicePositionFromObj: number, indiceUvsFromObj: number, indiceNormalFromObj: number, positionVectorFromOBJ: BABYLON.Vector3, textureVectorFromOBJ: BABYLON.Vector2, normalsVectorFromOBJ: BABYLON.Vector3) => {
-                //Check if this tuple already exists in the list of tuples
-                var _index: number;
-                if (OBJFileLoader.OPTIMIZE_WITH_UV) {
-                    _index = isInArrayUV(
-                        tuplePosNorm,
-                        [
-                            indicePositionFromObj,
-                            indiceNormalFromObj,
-                            indiceUvsFromObj
-                        ]
-                    );
-                }
-                else {
-                    _index = isInArray(
-                        tuplePosNorm,
-                        [
-                            indicePositionFromObj,
-                            indiceNormalFromObj
-                        ]
-                    );
-                }
-
-                //If it not exists
-                if (_index == -1) {
-                    //Add an new indice.
-                    //The array of indices is only an array with his length equal to the number of triangles - 1.
-                    //We add vertices data in this order
-                    indicesForBabylon.push(wrappedPositionForBabylon.length);
-                    //Push the position of vertice for Babylon
-                    //Each element is a BABYLON.Vector3(x,y,z)
-                    wrappedPositionForBabylon.push(positionVectorFromOBJ);
-                    //Push the uvs for Babylon
-                    //Each element is a BABYLON.Vector3(u,v)
-                    wrappedUvsForBabylon.push(textureVectorFromOBJ);
-                    //Push the normals for Babylon
-                    //Each element is a BABYLON.Vector3(x,y,z)
-                    wrappedNormalsForBabylon.push(normalsVectorFromOBJ);
-                    //Add the tuple in the comparison list
-                    tuplePosNorm[indicePositionFromObj].normals.push(indiceNormalFromObj);
-                    tuplePosNorm[indicePositionFromObj].idx.push(curPositionInIndices++);
-                    if (OBJFileLoader.OPTIMIZE_WITH_UV) { tuplePosNorm[indicePositionFromObj].uv.push(indiceUvsFromObj); }
-                } else {
-                    //The tuple already exists
-                    //Add the index of the already existing tuple
-                    //At this index we can get the value of position, normal and uvs of vertex
-                    indicesForBabylon.push(_index);
-                }
-            };
-
-            /**
-             * Transform BABYLON.Vector() object onto 3 digits in an array
-             */
-            var unwrapData = () => {
-                //Every array has the same length
-                for (var l = 0; l < wrappedPositionForBabylon.length; l++) {
-                    //Push the x, y, z values of each element in the unwrapped array
-                    unwrappedPositionsForBabylon.push(wrappedPositionForBabylon[l].x, wrappedPositionForBabylon[l].y, wrappedPositionForBabylon[l].z);
-                    unwrappedNormalsForBabylon.push(wrappedNormalsForBabylon[l].x, wrappedNormalsForBabylon[l].y, wrappedNormalsForBabylon[l].z);
-                    unwrappedUVForBabylon.push(wrappedUvsForBabylon[l].x, wrappedUvsForBabylon[l].y); //z is an optional value not supported by BABYLON
-                }
-                // Reset arrays for the next new meshes
-                wrappedPositionForBabylon = [];
-                wrappedNormalsForBabylon = [];
-                wrappedUvsForBabylon = [];
-                tuplePosNorm = [];
-                curPositionInIndices = 0;
-            };
-
-            /**
-             * Create triangles from polygons by recursion
-             * The best to understand how it works is to draw it in the same time you get the recursion.
-             * It is important to notice that a triangle is a polygon
-             * We get 5 patterns of face defined in OBJ File :
-             * facePattern1 = ["1","2","3","4","5","6"]
-             * facePattern2 = ["1/1","2/2","3/3","4/4","5/5","6/6"]
-             * facePattern3 = ["1/1/1","2/2/2","3/3/3","4/4/4","5/5/5","6/6/6"]
-             * facePattern4 = ["1//1","2//2","3//3","4//4","5//5","6//6"]
-             * facePattern5 = ["-1/-1/-1","-2/-2/-2","-3/-3/-3","-4/-4/-4","-5/-5/-5","-6/-6/-6"]
-             * Each pattern is divided by the same method
-             * @param face Array[String] The indices of elements
-             * @param v Integer The variable to increment
-             */
-            var getTriangles = (face: Array<string>, v: number) => {
-                //Work for each element of the array
-                if (v + 1 < face.length) {
-                    //Add on the triangle variable the indexes to obtain triangles
-                    triangles.push(face[0], face[v], face[v + 1]);
-                    //Incrementation for recursion
-                    v += 1;
-                    //Recursion
-                    getTriangles(face, v);
-                }
-
-                //Result obtained after 2 iterations:
-                //Pattern1 => triangle = ["1","2","3","1","3","4"];
-                //Pattern2 => triangle = ["1/1","2/2","3/3","1/1","3/3","4/4"];
-                //Pattern3 => triangle = ["1/1/1","2/2/2","3/3/3","1/1/1","3/3/3","4/4/4"];
-                //Pattern4 => triangle = ["1//1","2//2","3//3","1//1","3//3","4//4"];
-                //Pattern5 => triangle = ["-1/-1/-1","-2/-2/-2","-3/-3/-3","-1/-1/-1","-3/-3/-3","-4/-4/-4"];
-            };
-
-            /**
-             * Create triangles and push the data for each polygon for the pattern 1
-             * In this pattern we get vertice positions
-             * @param face
-             * @param v
-             */
-            var setDataForCurrentFaceWithPattern1 = (face: Array<string>, v: number) => {
-                //Get the indices of triangles for each polygon
-                getTriangles(face, v);
-                //For each element in the triangles array.
-                //This var could contains 1 to an infinity of triangles
-                for (var k = 0; k < triangles.length; k++) {
-                    // Set position indice
-                    var indicePositionFromObj = parseInt(triangles[k]) - 1;
-
-                    setData(
-                        indicePositionFromObj,
-                        0, 0,                                           //In the pattern 1, normals and uvs are not defined
-                        positions[indicePositionFromObj],               //Get the vectors data
-                        BABYLON.Vector2.Zero(), BABYLON.Vector3.Up()    //Create default vectors
-                    );
-                }
-                //Reset variable for the next line
-                triangles = [];
-            };
-
-            /**
-             * Create triangles and push the data for each polygon for the pattern 2
-             * In this pattern we get vertice positions and uvsu
-             * @param face
-             * @param v
-             */
-            var setDataForCurrentFaceWithPattern2 = (face: Array<string>, v: number) => {
-                //Get the indices of triangles for each polygon
-                getTriangles(face, v);
-                for (var k = 0; k < triangles.length; k++) {
-                    //triangle[k] = "1/1"
-                    //Split the data for getting position and uv
-                    var point = triangles[k].split("/"); // ["1", "1"]
-                    //Set position indice
-                    var indicePositionFromObj = parseInt(point[0]) - 1;
-                    //Set uv indice
-                    var indiceUvsFromObj = parseInt(point[1]) - 1;
-
-                    setData(
-                        indicePositionFromObj,
-                        indiceUvsFromObj,
-                        0,                                  //Default value for normals
-                        positions[indicePositionFromObj],   //Get the values for each element
-                        uvs[indiceUvsFromObj],
-                        BABYLON.Vector3.Up()                //Default value for normals
-                    );
-                }
-
-                //Reset variable for the next line
-                triangles = [];
-            };
-
-            /**
-             * Create triangles and push the data for each polygon for the pattern 3
-             * In this pattern we get vertice positions, uvs and normals
-             * @param face
-             * @param v
-             */
-            var setDataForCurrentFaceWithPattern3 = (face: Array<string>, v: number) => {
-                //Get the indices of triangles for each polygon
-                getTriangles(face, v);
-
-                for (var k = 0; k < triangles.length; k++) {
-                    //triangle[k] = "1/1/1"
-                    //Split the data for getting position, uv, and normals
-                    var point = triangles[k].split("/"); // ["1", "1", "1"]
-                    // Set position indice
-                    var indicePositionFromObj = parseInt(point[0]) - 1;
-                    // Set uv indice
-                    var indiceUvsFromObj = parseInt(point[1]) - 1;
-                    // Set normal indice
-                    var indiceNormalFromObj = parseInt(point[2]) - 1;
-
-                    setData(
-                        indicePositionFromObj, indiceUvsFromObj, indiceNormalFromObj,
-                        positions[indicePositionFromObj], uvs[indiceUvsFromObj], normals[indiceNormalFromObj] //Set the vector for each component
-                    );
-
-                }
-                //Reset variable for the next line
-                triangles = [];
-            };
-
-            /**
-             * Create triangles and push the data for each polygon for the pattern 4
-             * In this pattern we get vertice positions and normals
-             * @param face
-             * @param v
-             */
-            var setDataForCurrentFaceWithPattern4 = (face: Array<string>, v: number) => {
-                getTriangles(face, v);
-
-                for (var k = 0; k < triangles.length; k++) {
-                    //triangle[k] = "1//1"
-                    //Split the data for getting position and normals
-                    var point = triangles[k].split("//"); // ["1", "1"]
-                    // We check indices, and normals
-                    var indicePositionFromObj = parseInt(point[0]) - 1;
-                    var indiceNormalFromObj = parseInt(point[1]) - 1;
-
-                    setData(
-                        indicePositionFromObj,
-                        1, //Default value for uv
-                        indiceNormalFromObj,
-                        positions[indicePositionFromObj], //Get each vector of data
-                        BABYLON.Vector2.Zero(),
-                        normals[indiceNormalFromObj]
-                    );
-                }
-                //Reset variable for the next line
-                triangles = [];
-            };
-
-            /**
-             * Create triangles and push the data for each polygon for the pattern 3
-             * In this pattern we get vertice positions, uvs and normals
-             * @param face
-             * @param v
-             */
-            var setDataForCurrentFaceWithPattern5 = (face: Array<string>, v: number) => {
-                //Get the indices of triangles for each polygon
-                getTriangles(face, v);
-
-                for (var k = 0; k < triangles.length; k++) {
-                    //triangle[k] = "-1/-1/-1"
-                    //Split the data for getting position, uv, and normals
-                    var point = triangles[k].split("/"); // ["-1", "-1", "-1"]
-                    // Set position indice
-                    var indicePositionFromObj =  positions.length + parseInt(point[0]);
-                    // Set uv indice
-                    var indiceUvsFromObj =  uvs.length + parseInt(point[1]);
-                    // Set normal indice
-                    var indiceNormalFromObj = normals.length + parseInt(point[2]);
-
-                    setData(
-                        indicePositionFromObj, indiceUvsFromObj, indiceNormalFromObj,
-                        positions[indicePositionFromObj], uvs[indiceUvsFromObj], normals[indiceNormalFromObj] //Set the vector for each component
-                    );
-
-                }
-                //Reset variable for the next line
-                triangles = [];
-            };
-
-            var addPreviousObjMesh = () => {
-
-                //Check if it is not the first mesh. Otherwise we don't have data.
-                if (meshesFromObj.length > 0) {
-                    //Get the previous mesh for applying the data about the faces
-                    //=> in obj file, faces definition append after the name of the mesh
-                    handledMesh = meshesFromObj[meshesFromObj.length - 1];
-
-                    //Set the data into Array for the mesh
-                    unwrapData();
-
-                    // Reverse tab. Otherwise face are displayed in the wrong sens
-                    indicesForBabylon.reverse();
-                    //Set the information for the mesh
-                    //Slice the array to avoid rewriting because of the fact this is the same var which be rewrited
-                    handledMesh.indices = indicesForBabylon.slice();
-                    handledMesh.positions = unwrappedPositionsForBabylon.slice();
-                    handledMesh.normals = unwrappedNormalsForBabylon.slice();
-                    handledMesh.uvs = unwrappedUVForBabylon.slice();
-
-                    //Reset the array for the next mesh
-                    indicesForBabylon = [];
-                    unwrappedPositionsForBabylon = [];
-                    unwrappedNormalsForBabylon = [];
-                    unwrappedUVForBabylon = [];
-                }
-            };
-            //Main function
-
-            //Split the file into lines
-            var lines = data.split('\n');
-            //Look at each line
-            for (var i = 0; i < lines.length; i++) {
-                var line = lines[i].trim();
-                var result;
-
-                //Comment or newLine
-                if (line.length === 0 || line.charAt(0) === '#') {
-                    continue;
-
-                    //Get information about one position possible for the vertices
-                } else if ((result = this.vertexPattern.exec(line)) !== null) {
-                    //Create a Vector3 with the position x, y, z
-                    //Value of result:
-                    // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
-                    //Add the Vector in the list of positions
-                    positions.push(new BABYLON.Vector3(
-                        parseFloat(result[1]),
-                        parseFloat(result[2]),
-                        parseFloat(result[3])
-                    ));
-
-                } else if ((result = this.normalPattern.exec(line)) !== null) {
-                    //Create a Vector3 with the normals x, y, z
-                    //Value of result
-                    // ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
-                    //Add the Vector in the list of normals
-                    normals.push(new BABYLON.Vector3(
-                        parseFloat(result[1]),
-                        parseFloat(result[2]),
-                        parseFloat(result[3])
-                    ));
-
-                } else if ((result = this.uvPattern.exec(line)) !== null) {
-                    //Create a Vector2 with the normals u, v
-                    //Value of result
-                    // ["vt 0.1 0.2 0.3", "0.1", "0.2"]
-                    //Add the Vector in the list of uvs
-                    uvs.push(new BABYLON.Vector2(
-                        parseFloat(result[1]),
-                        parseFloat(result[2])
-                    ));
-
-                    //Identify patterns of faces
-                    //Face could be defined in different type of pattern
-                } else if ((result = this.facePattern3.exec(line)) !== null) {
-                    //Value of result:
-                    //["f 1/1/1 2/2/2 3/3/3", "1/1/1 2/2/2 3/3/3"...]
-
-                    //Set the data for this face
-                    setDataForCurrentFaceWithPattern3(
-                        result[1].trim().split(" "), // ["1/1/1", "2/2/2", "3/3/3"]
-                        1
-                    );
-
-                } else if ((result = this.facePattern4.exec(line)) !== null) {
-                    //Value of result:
-                    //["f 1//1 2//2 3//3", "1//1 2//2 3//3"...]
-
-                    //Set the data for this face
-                    setDataForCurrentFaceWithPattern4(
-                        result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
-                        1
-                    );
-
-                } else if ((result = this.facePattern5.exec(line)) !== null) {
-                    //Value of result:
-                    //["f -1/-1/-1 -2/-2/-2 -3/-3/-3", "-1/-1/-1 -2/-2/-2 -3/-3/-3"...]
-
-                    //Set the data for this face
-                    setDataForCurrentFaceWithPattern5(
-                        result[1].trim().split(" "), // ["-1/-1/-1", "-2/-2/-2", "-3/-3/-3"]
-                        1
-                    );
-
-                } else if ((result = this.facePattern2.exec(line)) !== null) {
-                    //Value of result:
-                    //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]
-
-                    //Set the data for this face
-                    setDataForCurrentFaceWithPattern2(
-                        result[1].trim().split(" "), // ["1/1", "2/2", "3/3"]
-                        1
-                    );
-
-                } else if ((result = this.facePattern1.exec(line)) !== null) {
-                    //Value of result
-                    //["f 1 2 3", "1 2 3"...]
-
-                    //Set the data for this face
-                    setDataForCurrentFaceWithPattern1(
-                        result[1].trim().split(" "), // ["1", "2", "3"]
-                        1
-                    );
-
-                    //Define a mesh or an object
-                    //Each time this keyword is analysed, create a new Object with all data for creating a babylonMesh
-                } else if (this.group.test(line) || this.obj.test(line)) {
-                    //Create a new mesh corresponding to the name of the group.
-                    //Definition of the mesh
-                    var objMesh: {
-                        name: string;
-                        indices?: Array<number>;
-                        positions?: Array<number>;
-                        normals?: Array<number>;
-                        uvs?: Array<number>;
-                        materialName: string;
-                    } =
-                    //Set the name of the current obj mesh
-                    {
-                        name: line.substring(2).trim(),
-                        indices: undefined,
-                        positions: undefined,
-                        normals: undefined,
-                        uvs: undefined,
-                        materialName: ""
-                    };
-                    addPreviousObjMesh();
-
-                    //Push the last mesh created with only the name
-                    meshesFromObj.push(objMesh);
-
-                    //Set this variable to indicate that now meshesFromObj has objects defined inside
-                    hasMeshes = true;
-                    isFirstMaterial = true;
-                    increment = 1;
-                    //Keyword for applying a material
-                } else if (this.usemtl.test(line)) {
-                    //Get the name of the material
-                    materialNameFromObj = line.substring(7).trim();
-
-                    //If this new material is in the same mesh
-
-                    if (!isFirstMaterial) {
-                        //Set the data for the previous mesh
-                        addPreviousObjMesh();
-                        //Create a new mesh
-                        var objMesh: {
-                            name: string;
-                            indices?: Array<number>;
-                            positions?: Array<number>;
-                            normals?: Array<number>;
-                            uvs?: Array<number>;
-                            materialName: string;
-                        } =
-                        //Set the name of the current obj mesh
-                        {
-                            name: objMeshName + "_mm" + increment.toString(),
-                            indices: undefined,
-                            positions: undefined,
-                            normals: undefined,
-                            uvs: undefined,
-                            materialName: materialNameFromObj
-                        };
-                        increment++;
-                        //If meshes are already defined
-                        meshesFromObj.push(objMesh);
-                    }
-                    //Set the material name if the previous line define a mesh
-
-                    if (hasMeshes && isFirstMaterial) {
-                        //Set the material name to the previous mesh (1 material per mesh)
-                        meshesFromObj[meshesFromObj.length - 1].materialName = materialNameFromObj;
-                        isFirstMaterial = false;
-                    }
-                    //Keyword for loading the mtl file
-                } else if (this.mtllib.test(line)) {
-                    //Get the name of mtl file
-                    fileToLoad = line.substring(7).trim();
-
-                    //Apply smoothing
-                } else if (this.smooth.test(line)) {
-                    // smooth shading => apply smoothing
-                    //Toda  y I don't know it work with babylon and with obj.
-                    //With the obj file  an integer is set
-                } else {
-                    //If there is another possibility
-                    console.log("Unhandled expression at line : " + line);
-                }
-            }
-
-            //At the end of the file, add the last mesh into the meshesFromObj array
-            if (hasMeshes) {
-                //Set the data for the last mesh
-                handledMesh = meshesFromObj[meshesFromObj.length - 1];
-
-                //Reverse indices for displaying faces in the good sens
-                indicesForBabylon.reverse();
-                //Get the good array
-                unwrapData();
-                //Set array
-                handledMesh.indices = indicesForBabylon;
-                handledMesh.positions = unwrappedPositionsForBabylon;
-                handledMesh.normals = unwrappedNormalsForBabylon;
-                handledMesh.uvs = unwrappedUVForBabylon;
-            }
-
-            //If any o or g keyword found, create a mesj with a random id
-            if (!hasMeshes) {
-                // reverse tab of indices
-                indicesForBabylon.reverse();
-                //Get positions normals uvs
-                unwrapData();
-                //Set data for one mesh
-                meshesFromObj.push({
-                    name: BABYLON.Geometry.RandomId(),
-                    indices: indicesForBabylon,
-                    positions: unwrappedPositionsForBabylon,
-                    normals: unwrappedNormalsForBabylon,
-                    uvs: unwrappedUVForBabylon,
-                    materialName: materialNameFromObj
-                });
-            }
-
-            //Create a BABYLON.Mesh list
-            var babylonMeshesArray: Array<BABYLON.Mesh> = []; //The mesh for babylon
-            var materialToUse = new Array<string>();
-
-            //Set data for each mesh
-            for (var j = 0; j < meshesFromObj.length; j++) {
-
-                //check meshesNames (stlFileLoader)
-                if (meshesNames && meshesFromObj[j].name) {
-                    if (meshesNames instanceof Array) {
-                        if (meshesNames.indexOf(meshesFromObj[j].name) == -1) {
-                            continue;
-                        }
-                    }
-                    else {
-                        if (meshesFromObj[j].name !== meshesNames) {
-                            continue;
-                        }
-                    }
-                }
-
-                //Get the current mesh
-                //Set the data with VertexBuffer for each mesh
-                handledMesh = meshesFromObj[j];
-                //Create a BABYLON.Mesh with the name of the obj mesh
-                var babylonMesh = new BABYLON.Mesh(meshesFromObj[j].name, scene);
-                //Push the name of the material to an array
-                //This is indispensable for the importMesh function
-                materialToUse.push(meshesFromObj[j].materialName);
-
-                var vertexData: VertexData = new BABYLON.VertexData(); //The container for the values
-                //Set the data for the babylonMesh
-                vertexData.positions = handledMesh.positions;
-                vertexData.normals = handledMesh.normals;
-                vertexData.uvs = handledMesh.uvs;
-                vertexData.indices = handledMesh.indices;
-                //Set the data from the VertexBuffer to the current BABYLON.Mesh
-                vertexData.applyToMesh(babylonMesh);
-                if (OBJFileLoader.INVERT_Y) {
-                    babylonMesh.scaling.y *= -1;
-                }
-
-                //Push the mesh into an array
-                babylonMeshesArray.push(babylonMesh);
-            }
-
-            let mtlPromises: Array<Promise<any>> = [];
-            //load the materials
-            //Check if we have a file to load
-            if (fileToLoad !== "") {
-                //Load the file synchronously
-                mtlPromises.push(new Promise((resolve, reject) => {
-                    this._loadMTL(fileToLoad, rootUrl, function(dataLoaded) {
-                        try {
-                            //Create materials thanks MTLLoader function
-                            materialsFromMTLFile.parseMTL(scene, dataLoaded, rootUrl);
-                            //Look at each material loaded in the mtl file
-                            for (var n = 0; n < materialsFromMTLFile.materials.length; n++) {
-                                //Three variables to get all meshes with the same material
-                                var startIndex = 0;
-                                var _indices = [];
-                                var _index;
-
-                                //The material from MTL file is used in the meshes loaded
-                                //Push the indice in an array
-                                //Check if the material is not used for another mesh
-                                while ((_index = materialToUse.indexOf(materialsFromMTLFile.materials[n].name, startIndex)) > -1) {
-                                    _indices.push(_index);
-                                    startIndex = _index + 1;
-                                }
-                                //If the material is not used dispose it
-                                if (_index == -1 && _indices.length == 0) {
-                                    //If the material is not needed, remove it
-                                    materialsFromMTLFile.materials[n].dispose();
-                                } else {
-                                    for (var o = 0; o < _indices.length; o++) {
-                                        //Apply the material to the BABYLON.Mesh for each mesh with the material
-                                        babylonMeshesArray[_indices[o]].material = materialsFromMTLFile.materials[n];
-                                    }
-                                }
-                            }
-                            resolve();
-                        } catch (e) {
-                            reject(e);
-                        }
-
-                    });
-                }));
-
-            }
-            //Return an array with all BABYLON.Mesh
-            return Promise.all(mtlPromises).then(() => {
-                return babylonMeshesArray;
-            });
-        }
-
-    }
-
-    if (BABYLON.SceneLoader) {
-        //Add this loader into the register plugin
-        BABYLON.SceneLoader.RegisterPlugin(new OBJFileLoader());
-    }
-}

+ 0 - 210
loaders/src/STL/babylon.stlFileLoader.ts

@@ -1,210 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON {
-
-    export class STLFileLoader implements ISceneLoaderPlugin {
-
-        public solidPattern = /solid (\S*)([\S\s]*)endsolid[ ]*(\S*)/g;
-        public facetsPattern = /facet([\s\S]*?)endfacet/g;
-        public normalPattern = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
-        public vertexPattern = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
-
-        public name = "stl";
-
-        // force data to come in as an ArrayBuffer
-        // we'll convert to string if it looks like it's an ASCII .stl
-        public extensions: ISceneLoaderPluginExtensions = {
-            ".stl": { isBinary: true },
-        };
-
-        public importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: Nullable<AbstractMesh[]>, particleSystems: Nullable<IParticleSystem[]>, skeletons: Nullable<Skeleton[]>): boolean {
-            var matches;
-
-            if (typeof data !== "string") {
-
-                if (this.isBinary(data)) {
-                    // binary .stl
-                    var babylonMesh = new Mesh("stlmesh", scene);
-                    this.parseBinary(babylonMesh, data);
-                    if (meshes) {
-                        meshes.push(babylonMesh);
-                    }
-                    return true;
-                }
-
-                // ASCII .stl
-
-                // convert to string
-                var array_buffer = new Uint8Array(data);
-                var str = '';
-                for (var i = 0; i < data.byteLength; i++) {
-                    str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian
-                }
-                data = str;
-            }
-
-            //if arrived here, data is a string, containing the STLA data.
-
-            while (matches = this.solidPattern.exec(data)) {
-                var meshName = matches[1];
-                var meshNameFromEnd = matches[3];
-                if (meshName != meshNameFromEnd) {
-                    Tools.Error("Error in STL, solid name != endsolid name");
-                    return false;
-                }
-
-                // check meshesNames
-                if (meshesNames && meshName) {
-                    if (meshesNames instanceof Array) {
-                        if (!meshesNames.indexOf(meshName)) {
-                            continue;
-                        }
-                    } else {
-                        if (meshName !== meshesNames) {
-                            continue;
-                        }
-                    }
-                }
-
-                // stl mesh name can be empty as well
-                meshName = meshName || "stlmesh";
-
-                var babylonMesh = new Mesh(meshName, scene);
-                this.parseASCII(babylonMesh, matches[2]);
-                if (meshes) {
-                    meshes.push(babylonMesh);
-                }
-            }
-
-            return true;
-
-        }
-
-        public load(scene: Scene, data: any, rootUrl: string): boolean {
-            var result = this.importMesh(null, scene, data, rootUrl, null, null, null);
-
-            if (result) {
-                scene.createDefaultCameraOrLight();
-            }
-
-            return result;
-        }
-
-        public loadAssetContainer(scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): AssetContainer {
-            var container = new AssetContainer(scene);
-            this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
-            container.removeAllFromScene();
-            return container;
-        }
-
-        private isBinary(data: any) {
-
-            // check if file size is correct for binary stl
-            var faceSize, nFaces, reader;
-            reader = new DataView(data);
-            faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);
-            nFaces = reader.getUint32(80, true);
-
-            if (80 + (32 / 8) + (nFaces * faceSize) === reader.byteLength) {
-                return true;
-            }
-
-            // check characters higher than ASCII to confirm binary
-            var fileLength = reader.byteLength;
-            for (var index = 0; index < fileLength; index++) {
-                if (reader.getUint8(index) > 127) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        private parseBinary(mesh: Mesh, data: ArrayBuffer) {
-
-            var reader = new DataView(data);
-            var faces = reader.getUint32(80, true);
-
-            var dataOffset = 84;
-            var faceLength = 12 * 4 + 2;
-
-            var offset = 0;
-
-            var positions = new Float32Array(faces * 3 * 3);
-            var normals = new Float32Array(faces * 3 * 3);
-            var indices = new Uint32Array(faces * 3);
-            var indicesCount = 0;
-
-            for (var face = 0; face < faces; face++) {
-
-                var start = dataOffset + face * faceLength;
-                var normalX = reader.getFloat32(start, true);
-                var normalY = reader.getFloat32(start + 4, true);
-                var normalZ = reader.getFloat32(start + 8, true);
-
-                for (var i = 1; i <= 3; i++) {
-
-                    var vertexstart = start + i * 12;
-
-                    // ordering is intentional to match ascii import
-                    positions[offset] = reader.getFloat32(vertexstart, true);
-                    positions[offset + 2] = reader.getFloat32(vertexstart + 4, true);
-                    positions[offset + 1] = reader.getFloat32(vertexstart + 8, true);
-
-                    normals[offset] = normalX;
-                    normals[offset + 2] = normalY;
-                    normals[offset + 1] = normalZ;
-
-                    offset += 3;
-                }
-                indices[indicesCount] = indicesCount++;
-                indices[indicesCount] = indicesCount++;
-                indices[indicesCount] = indicesCount++;
-            }
-
-            mesh.setVerticesData(VertexBuffer.PositionKind, positions);
-            mesh.setVerticesData(VertexBuffer.NormalKind, normals);
-            mesh.setIndices(indices);
-            mesh.computeWorldMatrix(true);
-        }
-
-        private parseASCII(mesh: Mesh, solidData: string) {
-
-            var positions = [];
-            var normals = [];
-            var indices = [];
-            var indicesCount = 0;
-
-            //load facets, ignoring loop as the standard doesn't define it can contain more than vertices
-            var matches;
-            while (matches = this.facetsPattern.exec(solidData)) {
-                var facet = matches[1];
-                //one normal per face
-                var normalMatches = this.normalPattern.exec(facet);
-                this.normalPattern.lastIndex = 0;
-                if (!normalMatches) {
-                    continue;
-                }
-                var normal = [Number(normalMatches[1]), Number(normalMatches[5]), Number(normalMatches[3])];
-
-                var vertexMatch;
-                while (vertexMatch = this.vertexPattern.exec(facet)) {
-                    positions.push(Number(vertexMatch[1]), Number(vertexMatch[5]), Number(vertexMatch[3]));
-                    normals.push(normal[0], normal[1], normal[2]);
-                }
-                indices.push(indicesCount++, indicesCount++, indicesCount++);
-                this.vertexPattern.lastIndex = 0;
-            }
-
-            this.facetsPattern.lastIndex = 0;
-            mesh.setVerticesData(VertexBuffer.PositionKind, positions);
-            mesh.setVerticesData(VertexBuffer.NormalKind, normals);
-            mesh.setIndices(indices);
-            mesh.computeWorldMatrix(true);
-        }
-    }
-
-    if (BABYLON.SceneLoader) {
-        BABYLON.SceneLoader.RegisterPlugin(new STLFileLoader());
-    }
-}

+ 1 - 0
loaders/src/STL/index.ts

@@ -0,0 +1 @@
+export * from "./stlFileLoader";

+ 207 - 0
loaders/src/STL/stlFileLoader.ts

@@ -0,0 +1,207 @@
+import { SceneLoader, ISceneLoaderPlugin, ISceneLoaderPluginExtensions, Scene, Nullable, AbstractMesh, IParticleSystem, Skeleton, Mesh, Tools, AssetContainer, VertexBuffer } from "babylonjs";
+
+export class STLFileLoader implements ISceneLoaderPlugin {
+
+    public solidPattern = /solid (\S*)([\S\s]*)endsolid[ ]*(\S*)/g;
+    public facetsPattern = /facet([\s\S]*?)endfacet/g;
+    public normalPattern = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
+    public vertexPattern = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g;
+
+    public name = "stl";
+
+    // force data to come in as an ArrayBuffer
+    // we'll convert to string if it looks like it's an ASCII .stl
+    public extensions: ISceneLoaderPluginExtensions = {
+        ".stl": { isBinary: true },
+    };
+
+    public importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: Nullable<AbstractMesh[]>, particleSystems: Nullable<IParticleSystem[]>, skeletons: Nullable<Skeleton[]>): boolean {
+        var matches;
+
+        if (typeof data !== "string") {
+
+            if (this.isBinary(data)) {
+                // binary .stl
+                var babylonMesh = new Mesh("stlmesh", scene);
+                this.parseBinary(babylonMesh, data);
+                if (meshes) {
+                    meshes.push(babylonMesh);
+                }
+                return true;
+            }
+
+            // ASCII .stl
+
+            // convert to string
+            var array_buffer = new Uint8Array(data);
+            var str = '';
+            for (var i = 0; i < data.byteLength; i++) {
+                str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian
+            }
+            data = str;
+        }
+
+        //if arrived here, data is a string, containing the STLA data.
+
+        while (matches = this.solidPattern.exec(data)) {
+            var meshName = matches[1];
+            var meshNameFromEnd = matches[3];
+            if (meshName != meshNameFromEnd) {
+                Tools.Error("Error in STL, solid name != endsolid name");
+                return false;
+            }
+
+            // check meshesNames
+            if (meshesNames && meshName) {
+                if (meshesNames instanceof Array) {
+                    if (!meshesNames.indexOf(meshName)) {
+                        continue;
+                    }
+                } else {
+                    if (meshName !== meshesNames) {
+                        continue;
+                    }
+                }
+            }
+
+            // stl mesh name can be empty as well
+            meshName = meshName || "stlmesh";
+
+            var babylonMesh = new Mesh(meshName, scene);
+            this.parseASCII(babylonMesh, matches[2]);
+            if (meshes) {
+                meshes.push(babylonMesh);
+            }
+        }
+
+        return true;
+
+    }
+
+    public load(scene: Scene, data: any, rootUrl: string): boolean {
+        var result = this.importMesh(null, scene, data, rootUrl, null, null, null);
+
+        if (result) {
+            scene.createDefaultCameraOrLight();
+        }
+
+        return result;
+    }
+
+    public loadAssetContainer(scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): AssetContainer {
+        var container = new AssetContainer(scene);
+        this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
+        container.removeAllFromScene();
+        return container;
+    }
+
+    private isBinary(data: any) {
+
+        // check if file size is correct for binary stl
+        var faceSize, nFaces, reader;
+        reader = new DataView(data);
+        faceSize = (32 / 8 * 3) + ((32 / 8 * 3) * 3) + (16 / 8);
+        nFaces = reader.getUint32(80, true);
+
+        if (80 + (32 / 8) + (nFaces * faceSize) === reader.byteLength) {
+            return true;
+        }
+
+        // check characters higher than ASCII to confirm binary
+        var fileLength = reader.byteLength;
+        for (var index = 0; index < fileLength; index++) {
+            if (reader.getUint8(index) > 127) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private parseBinary(mesh: Mesh, data: ArrayBuffer) {
+
+        var reader = new DataView(data);
+        var faces = reader.getUint32(80, true);
+
+        var dataOffset = 84;
+        var faceLength = 12 * 4 + 2;
+
+        var offset = 0;
+
+        var positions = new Float32Array(faces * 3 * 3);
+        var normals = new Float32Array(faces * 3 * 3);
+        var indices = new Uint32Array(faces * 3);
+        var indicesCount = 0;
+
+        for (var face = 0; face < faces; face++) {
+
+            var start = dataOffset + face * faceLength;
+            var normalX = reader.getFloat32(start, true);
+            var normalY = reader.getFloat32(start + 4, true);
+            var normalZ = reader.getFloat32(start + 8, true);
+
+            for (var i = 1; i <= 3; i++) {
+
+                var vertexstart = start + i * 12;
+
+                // ordering is intentional to match ascii import
+                positions[offset] = reader.getFloat32(vertexstart, true);
+                positions[offset + 2] = reader.getFloat32(vertexstart + 4, true);
+                positions[offset + 1] = reader.getFloat32(vertexstart + 8, true);
+
+                normals[offset] = normalX;
+                normals[offset + 2] = normalY;
+                normals[offset + 1] = normalZ;
+
+                offset += 3;
+            }
+            indices[indicesCount] = indicesCount++;
+            indices[indicesCount] = indicesCount++;
+            indices[indicesCount] = indicesCount++;
+        }
+
+        mesh.setVerticesData(VertexBuffer.PositionKind, positions);
+        mesh.setVerticesData(VertexBuffer.NormalKind, normals);
+        mesh.setIndices(indices);
+        mesh.computeWorldMatrix(true);
+    }
+
+    private parseASCII(mesh: Mesh, solidData: string) {
+
+        var positions = [];
+        var normals = [];
+        var indices = [];
+        var indicesCount = 0;
+
+        //load facets, ignoring loop as the standard doesn't define it can contain more than vertices
+        var matches;
+        while (matches = this.facetsPattern.exec(solidData)) {
+            var facet = matches[1];
+            //one normal per face
+            var normalMatches = this.normalPattern.exec(facet);
+            this.normalPattern.lastIndex = 0;
+            if (!normalMatches) {
+                continue;
+            }
+            var normal = [Number(normalMatches[1]), Number(normalMatches[5]), Number(normalMatches[3])];
+
+            var vertexMatch;
+            while (vertexMatch = this.vertexPattern.exec(facet)) {
+                positions.push(Number(vertexMatch[1]), Number(vertexMatch[5]), Number(vertexMatch[3]));
+                normals.push(normal[0], normal[1], normal[2]);
+            }
+            indices.push(indicesCount++, indicesCount++, indicesCount++);
+            this.vertexPattern.lastIndex = 0;
+        }
+
+        this.facetsPattern.lastIndex = 0;
+        mesh.setVerticesData(VertexBuffer.PositionKind, positions);
+        mesh.setVerticesData(VertexBuffer.NormalKind, normals);
+        mesh.setIndices(indices);
+        mesh.computeWorldMatrix(true);
+    }
+}
+
+if (SceneLoader) {
+    SceneLoader.RegisterPlugin(new STLFileLoader());
+}

+ 0 - 82
loaders/src/glTF/1.0/babylon.glTFBinaryExtension.ts

@@ -1,82 +0,0 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF1 {
-    const BinaryExtensionBufferName = "binary_glTF";
-
-    interface IGLTFBinaryExtensionShader {
-        bufferView: string;
-    }
-
-    interface IGLTFBinaryExtensionImage {
-        bufferView: string;
-        mimeType: string;
-        height: number;
-        width: number;
-    }
-
-    export class GLTFBinaryExtension extends GLTFLoaderExtension {
-        private _bin : ArrayBufferView;
-
-        public constructor() {
-            super("KHR_binary_glTF");
-        }
-
-        public loadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (gltfRuntime: IGLTFRuntime) => void, onError: (message: string) => void): boolean {
-            var extensionsUsed = (<any>data.json).extensionsUsed;
-            if (!extensionsUsed || extensionsUsed.indexOf(this.name) === -1 || !data.bin) {
-                return false;
-            }
-
-            this._bin = data.bin;
-            onSuccess(GLTFLoaderBase.CreateRuntime(data.json, scene, rootUrl));
-            return true;
-        }
-
-        public loadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: (message: string) => void): boolean {
-            if (gltfRuntime.extensionsUsed.indexOf(this.name) === -1) {
-                return false;
-            }
-
-            if (id !== BinaryExtensionBufferName) {
-                return false;
-            }
-
-            onSuccess(this._bin);
-            return true;
-        }
-
-        public loadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: (message: string) => void): boolean {
-            var texture: IGLTFTexture = gltfRuntime.textures[id];
-            var source: IGLTFImage = gltfRuntime.images[texture.source];
-            if (!source.extensions || !(this.name in source.extensions)) {
-                return false;
-            }
-
-            var sourceExt: IGLTFBinaryExtensionImage = source.extensions[this.name];
-            var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[sourceExt.bufferView];
-            var buffer = GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, 0, bufferView.byteLength, EComponentType.UNSIGNED_BYTE);
-            onSuccess(buffer);
-            return true;
-        }
-
-        public loadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderString: string) => void, onError: (message: string) => void): boolean {
-            var shader: IGLTFShader = gltfRuntime.shaders[id];
-            if (!shader.extensions || !(this.name in shader.extensions)) {
-                return false;
-            }
-
-            var binaryExtensionShader: IGLTFBinaryExtensionShader = shader.extensions[this.name];
-            var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[binaryExtensionShader.bufferView];
-            var shaderBytes = GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, 0, bufferView.byteLength, EComponentType.UNSIGNED_BYTE);
-
-            setTimeout(() => {
-                var shaderString = GLTFUtils.DecodeBufferToText(shaderBytes);
-                onSuccess(shaderString);
-            });
-
-            return true;
-        }
-    }
-
-    GLTFLoader.RegisterExtension(new GLTFBinaryExtension());
-}

File diff ditekan karena terlalu besar
+ 0 - 1809
loaders/src/glTF/1.0/babylon.glTFLoader.ts


+ 0 - 158
loaders/src/glTF/1.0/babylon.glTFLoaderExtension.ts

@@ -1,158 +0,0 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF1 {
-    export abstract class GLTFLoaderExtension {
-        private _name: string;
-
-        public constructor(name: string) {
-            this._name = name;
-        }
-
-        public get name(): string {
-            return this._name;
-        }
-
-        /**
-        * Defines an override for loading the runtime
-        * Return true to stop further extensions from loading the runtime
-        */
-        public loadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (gltfRuntime: IGLTFRuntime) => void, onError?: (message: string) => void): boolean {
-            return false;
-        }
-
-        /**
-         * Defines an onverride for creating gltf runtime
-         * Return true to stop further extensions from creating the runtime
-         */
-        public loadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError?: (message: string) => void): boolean {
-            return false;
-        }
-
-        /**
-        * Defines an override for loading buffers
-        * Return true to stop further extensions from loading this buffer
-        */
-        public loadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: (message: string) => void, onProgress?: () => void): boolean {
-            return false;
-        }
-
-        /**
-        * Defines an override for loading texture buffers
-        * Return true to stop further extensions from loading this texture data
-        */
-        public loadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: (message: string) => void): boolean {
-            return false;
-        }
-
-        /**
-        * Defines an override for creating textures
-        * Return true to stop further extensions from loading this texture
-        */
-        public createTextureAsync(gltfRuntime: IGLTFRuntime, id: string, buffer: ArrayBufferView, onSuccess: (texture: Texture) => void, onError: (message: string) => void): boolean {
-            return false;
-        }
-
-        /**
-        * Defines an override for loading shader strings
-        * Return true to stop further extensions from loading this shader data
-        */
-        public loadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderString: string) => void, onError: (message: string) => void): boolean {
-            return false;
-        }
-
-        /**
-        * Defines an override for loading materials
-        * Return true to stop further extensions from loading this material
-        */
-        public loadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: (message: string) => void): boolean {
-            return false;
-        }
-
-        // ---------
-        // Utilities
-        // ---------
-
-        public static LoadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (gltfRuntime: IGLTFRuntime) => void, onError?: (message: string) => void): void {
-            GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
-                return loaderExtension.loadRuntimeAsync(scene, data, rootUrl, onSuccess, onError);
-            }, () => {
-                setTimeout(() => {
-                    if (!onSuccess) {
-                        return;
-                    }
-                    onSuccess(GLTFLoaderBase.CreateRuntime(data.json, scene, rootUrl));
-                });
-            });
-        }
-
-        public static LoadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError?: (message: string) => void): void {
-            GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
-                return loaderExtension.loadRuntimeExtensionsAsync(gltfRuntime, onSuccess, onError);
-            }, () => {
-                setTimeout(() => {
-                    onSuccess();
-                });
-            });
-        }
-
-        public static LoadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (bufferView: ArrayBufferView) => void, onError: (message: string) => void, onProgress?: () => void): void {
-            GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
-                return loaderExtension.loadBufferAsync(gltfRuntime, id, onSuccess, onError, onProgress);
-            }, () => {
-                GLTFLoaderBase.LoadBufferAsync(gltfRuntime, id, onSuccess, onError, onProgress);
-            });
-        }
-
-        public static LoadTextureAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (texture: Texture) => void, onError: (message: string) => void): void {
-            GLTFLoaderExtension.LoadTextureBufferAsync(gltfRuntime, id,
-               (buffer) => {
-                    if (buffer) {
-                        GLTFLoaderExtension.CreateTextureAsync(gltfRuntime, id, buffer, onSuccess, onError);
-                    }
-                }, onError);
-        }
-
-        public static LoadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderData: string | ArrayBuffer) => void, onError: (message: string) => void): void {
-            GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
-                return loaderExtension.loadShaderStringAsync(gltfRuntime, id, onSuccess, onError);
-            }, () => {
-                GLTFLoaderBase.LoadShaderStringAsync(gltfRuntime, id, onSuccess, onError);
-            });
-        }
-
-        public static LoadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: (message: string) => void): void {
-            GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
-                return loaderExtension.loadMaterialAsync(gltfRuntime, id, onSuccess, onError);
-            }, () => {
-                GLTFLoaderBase.LoadMaterialAsync(gltfRuntime, id, onSuccess, onError);
-            });
-        }
-
-        private static LoadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: Nullable<ArrayBufferView>) => void, onError: (message: string) => void): void {
-            GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
-                return loaderExtension.loadTextureBufferAsync(gltfRuntime, id, onSuccess, onError);
-            }, () => {
-                GLTFLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, onSuccess, onError);
-            });
-        }
-
-        private static CreateTextureAsync(gltfRuntime: IGLTFRuntime, id: string, buffer: ArrayBufferView, onSuccess: (texture: Texture) => void, onError: (message: string) => void): void {
-            GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
-                return loaderExtension.createTextureAsync(gltfRuntime, id, buffer, onSuccess, onError);
-            }, () => {
-                GLTFLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, onSuccess, onError);
-            });
-        }
-
-        private static ApplyExtensions(func: (loaderExtension: GLTFLoaderExtension) => boolean, defaultFunc: () => void): void {
-            for (var extensionName in GLTFLoader.Extensions) {
-                var loaderExtension = GLTFLoader.Extensions[extensionName];
-                if (func(loaderExtension)) {
-                    return;
-                }
-            }
-
-            defaultFunc();
-        }
-    }
-}

+ 0 - 387
loaders/src/glTF/1.0/babylon.glTFLoaderInterfaces.ts

@@ -1,387 +0,0 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF1 {
-    /**
-    * Enums
-    */
-    export enum EComponentType {
-        BYTE = 5120,
-        UNSIGNED_BYTE = 5121,
-        SHORT = 5122,
-        UNSIGNED_SHORT = 5123,
-        FLOAT = 5126
-    }
-
-    export enum EShaderType {
-        FRAGMENT = 35632,
-        VERTEX = 35633
-    }
-
-    export enum EParameterType {
-        BYTE = 5120,
-        UNSIGNED_BYTE = 5121,
-        SHORT = 5122,
-        UNSIGNED_SHORT = 5123,
-        INT = 5124,
-        UNSIGNED_INT = 5125,
-        FLOAT = 5126,
-        FLOAT_VEC2 = 35664,
-        FLOAT_VEC3 = 35665,
-        FLOAT_VEC4 = 35666,
-        INT_VEC2 = 35667,
-        INT_VEC3 = 35668,
-        INT_VEC4 = 35669,
-        BOOL = 35670,
-        BOOL_VEC2 = 35671,
-        BOOL_VEC3 = 35672,
-        BOOL_VEC4 = 35673,
-        FLOAT_MAT2 = 35674,
-        FLOAT_MAT3 = 35675,
-        FLOAT_MAT4 = 35676,
-        SAMPLER_2D = 35678
-    }
-
-    export enum ETextureWrapMode {
-        CLAMP_TO_EDGE = 33071,
-        MIRRORED_REPEAT = 33648,
-        REPEAT = 10497
-    }
-
-    export enum ETextureFilterType {
-        NEAREST = 9728,
-        LINEAR = 9728,
-        NEAREST_MIPMAP_NEAREST = 9984,
-        LINEAR_MIPMAP_NEAREST = 9985,
-        NEAREST_MIPMAP_LINEAR = 9986,
-        LINEAR_MIPMAP_LINEAR = 9987
-    }
-
-    export enum ETextureFormat {
-        ALPHA = 6406,
-        RGB = 6407,
-        RGBA = 6408,
-        LUMINANCE = 6409,
-        LUMINANCE_ALPHA = 6410
-    }
-
-    export enum ECullingType {
-        FRONT = 1028,
-        BACK = 1029,
-        FRONT_AND_BACK = 1032
-    }
-
-    export enum EBlendingFunction {
-        ZERO = 0,
-        ONE = 1,
-        SRC_COLOR = 768,
-        ONE_MINUS_SRC_COLOR = 769,
-        DST_COLOR = 774,
-        ONE_MINUS_DST_COLOR = 775,
-        SRC_ALPHA = 770,
-        ONE_MINUS_SRC_ALPHA = 771,
-        DST_ALPHA = 772,
-        ONE_MINUS_DST_ALPHA = 773,
-        CONSTANT_COLOR = 32769,
-        ONE_MINUS_CONSTANT_COLOR = 32770,
-        CONSTANT_ALPHA = 32771,
-        ONE_MINUS_CONSTANT_ALPHA = 32772,
-        SRC_ALPHA_SATURATE = 776
-    }
-
-    /**
-    * Interfaces
-    */
-    export interface IGLTFProperty {
-        extensions?: {[key: string]: any};
-        extras?: Object;
-    }
-
-    export interface IGLTFChildRootProperty extends IGLTFProperty {
-        name?: string;
-    }
-
-    export interface IGLTFAccessor extends IGLTFChildRootProperty {
-        bufferView: string;
-        byteOffset: number;
-        byteStride: number;
-        count: number;
-        type: string;
-        componentType: EComponentType;
-
-        max?: number[];
-        min?: number[];
-        name?: string;
-    }
-
-    export interface IGLTFBufferView extends IGLTFChildRootProperty {
-        buffer: string;
-        byteOffset: number;
-        byteLength: number;
-        byteStride: number;
-
-        target?: number;
-    }
-
-    export interface IGLTFBuffer extends IGLTFChildRootProperty {
-        uri: string;
-
-        byteLength?: number;
-        type?: string;
-    }
-
-    export interface IGLTFShader extends IGLTFChildRootProperty {
-        uri: string;
-        type: EShaderType;
-    }
-
-    export interface IGLTFProgram extends IGLTFChildRootProperty {
-        attributes: string[];
-        fragmentShader: string;
-        vertexShader: string;
-    }
-
-    export interface IGLTFTechniqueParameter {
-        type: number;
-
-        count?: number;
-        semantic?: string;
-        node?: string;
-        value?: number | boolean | string | Array<any>;
-        source?: string;
-
-        babylonValue?: any;
-    }
-
-    export interface IGLTFTechniqueCommonProfile {
-        lightingModel: string;
-        texcoordBindings: Object;
-
-        parameters?: Array<any>;
-    }
-
-    export interface IGLTFTechniqueStatesFunctions {
-        blendColor?: number[];
-        blendEquationSeparate?: number[];
-        blendFuncSeparate?: number[];
-        colorMask: boolean[];
-        cullFace: number[];
-    }
-
-    export interface IGLTFTechniqueStates {
-        enable: number[];
-        functions: IGLTFTechniqueStatesFunctions;
-    }
-
-    export interface IGLTFTechnique extends IGLTFChildRootProperty {
-        parameters: {[key: string]: IGLTFTechniqueParameter};
-        program: string;
-
-        attributes: {[key: string]: string};
-        uniforms: {[key: string]: string};
-        states: IGLTFTechniqueStates;
-    }
-
-    export interface IGLTFMaterial extends IGLTFChildRootProperty {
-        technique?: string;
-        values: string[];
-    }
-
-    export interface IGLTFMeshPrimitive extends IGLTFProperty {
-        attributes: {[key: string]: string};
-        indices: string;
-        material: string;
-
-        mode?: number;
-    }
-
-    export interface IGLTFMesh extends IGLTFChildRootProperty {
-        primitives: IGLTFMeshPrimitive[];
-    }
-
-    export interface IGLTFImage extends IGLTFChildRootProperty {
-        uri: string;
-    }
-
-    export interface IGLTFSampler extends IGLTFChildRootProperty {
-        magFilter?: number;
-        minFilter?: number;
-        wrapS?: number;
-        wrapT?: number;
-    }
-
-    export interface IGLTFTexture extends IGLTFChildRootProperty {
-        sampler: string;
-        source: string;
-
-        format?: ETextureFormat;
-        internalFormat?: ETextureFormat;
-        target?: number;
-        type?: number;
-
-        // Babylon.js values (optimize)
-        babylonTexture?: Texture;
-    }
-
-    export interface IGLTFAmbienLight {
-        color?: number[];
-    }
-
-    export interface IGLTFDirectionalLight {
-        color?: number[];
-    }
-
-    export interface IGLTFPointLight {
-        color?: number[];
-        constantAttenuation?: number;
-        linearAttenuation?: number;
-        quadraticAttenuation?: number;
-    }
-
-    export interface IGLTFSpotLight {
-        color?: number[];
-        constantAttenuation?: number;
-        fallOfAngle?: number;
-        fallOffExponent?: number;
-        linearAttenuation?: number;
-        quadraticAttenuation?: number;
-    }
-
-    export interface IGLTFLight extends IGLTFChildRootProperty {
-        type: string;
-    }
-
-    export interface IGLTFCameraOrthographic {
-        xmag: number;
-        ymag: number;
-        zfar: number;
-        znear: number;
-    }
-
-    export interface IGLTFCameraPerspective {
-        aspectRatio: number;
-        yfov: number;
-        zfar: number;
-        znear: number;
-    }
-
-    export interface IGLTFCamera extends IGLTFChildRootProperty {
-        type: string;
-    }
-
-    export interface IGLTFAnimationChannelTarget {
-        id: string;
-        path: string;
-    }
-
-    export interface IGLTFAnimationChannel {
-        sampler: string;
-        target: IGLTFAnimationChannelTarget;
-    }
-
-    export interface IGLTFAnimationSampler {
-        input: string;
-        output: string;
-
-        interpolation?: string;
-    }
-
-    export interface IGLTFAnimation extends IGLTFChildRootProperty {
-        channels?: IGLTFAnimationChannel[];
-        parameters?:  {[key: string]: string};
-        samplers?: {[key: string]: IGLTFAnimationSampler};
-    }
-
-    export interface IGLTFNodeInstanceSkin {
-        skeletons: string[];
-        skin: string;
-        meshes: string[];
-    }
-
-    export interface IGLTFSkins extends IGLTFChildRootProperty {
-        bindShapeMatrix: number[];
-        inverseBindMatrices: string;
-        jointNames: string[];
-
-        babylonSkeleton?: Skeleton;
-    }
-
-    export interface IGLTFNode extends IGLTFChildRootProperty {
-        camera?: string;
-        children: string[];
-        skin?: string;
-        jointName?: string;
-        light?: string;
-        matrix: number[];
-        mesh?: string;
-        meshes?: string[];
-        rotation?: number[];
-        scale?: number[];
-        translation?: number[];
-
-        // Babylon.js values (optimize)
-        babylonNode?: Node;
-    }
-
-    export interface IGLTFScene extends IGLTFChildRootProperty {
-        nodes: string[];
-    }
-
-    /**
-    * Runtime
-    */
-    export interface IGLTFRuntime {
-        extensions: {[key: string]: any};
-        accessors: {[key: string]: IGLTFAccessor};
-        buffers: {[key: string]: IGLTFBuffer};
-        bufferViews: {[key: string]: IGLTFBufferView};
-        meshes: {[key: string]: IGLTFMesh};
-        lights: {[key: string]: IGLTFLight};
-        cameras: {[key: string]: IGLTFCamera};
-        nodes: {[key: string]: IGLTFNode};
-        images: {[key: string]: IGLTFImage};
-        textures: {[key: string]: IGLTFTexture};
-        shaders: {[key: string]: IGLTFShader};
-        programs: {[key: string]: IGLTFProgram};
-        samplers: {[key: string]: IGLTFSampler};
-        techniques: {[key: string]: IGLTFTechnique};
-        materials: {[key: string]: IGLTFMaterial};
-        animations: {[key: string]: IGLTFAnimation};
-        skins: {[key: string]: IGLTFSkins};
-
-        currentScene?: Object;
-        scenes: {[key: string]: IGLTFScene}; // v1.1
-
-        extensionsUsed: string[];
-        extensionsRequired?: string[]; // v1.1
-
-        buffersCount: number;
-        shaderscount: number;
-
-        scene: Scene;
-        rootUrl: string;
-
-        loadedBufferCount: number;
-        loadedBufferViews: { [name: string]: ArrayBufferView };
-
-        loadedShaderCount: number;
-
-        importOnlyMeshes: boolean;
-        importMeshesNames?: string[];
-
-        dummyNodes: Node[];
-    }
-
-    /**
-    * Bones
-    */
-    export interface INodeToRoot {
-        bone: Bone;
-        node: IGLTFNode;
-        id: string;
-    }
-
-    export interface IJointNode {
-        node: IGLTFNode;
-        id: string;
-    }
-}

+ 0 - 233
loaders/src/glTF/1.0/babylon.glTFLoaderUtils.ts

@@ -1,233 +0,0 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF1 {
-    /**
-    * Utils functions for GLTF
-    */
-    export class GLTFUtils {
-        /**
-         * Sets the given "parameter" matrix
-         * @param scene: the Scene object
-         * @param source: the source node where to pick the matrix
-         * @param parameter: the GLTF technique parameter
-         * @param uniformName: the name of the shader's uniform
-         * @param shaderMaterial: the shader material
-         */
-        public static SetMatrix(scene: Scene, source: Node, parameter: IGLTFTechniqueParameter, uniformName: string, shaderMaterial: ShaderMaterial | Effect): void {
-            var mat: Nullable<Matrix> = null;
-
-            if (parameter.semantic === "MODEL") {
-                mat = source.getWorldMatrix();
-            }
-            else if (parameter.semantic === "PROJECTION") {
-                mat = scene.getProjectionMatrix();
-            }
-            else if (parameter.semantic === "VIEW") {
-                mat = scene.getViewMatrix();
-            }
-            else if (parameter.semantic === "MODELVIEWINVERSETRANSPOSE") {
-                mat = Matrix.Transpose(source.getWorldMatrix().multiply(scene.getViewMatrix()).invert());
-            }
-            else if (parameter.semantic === "MODELVIEW") {
-                mat = source.getWorldMatrix().multiply(scene.getViewMatrix());
-            }
-            else if (parameter.semantic === "MODELVIEWPROJECTION") {
-                mat = source.getWorldMatrix().multiply(scene.getTransformMatrix());
-            }
-            else if (parameter.semantic === "MODELINVERSE") {
-                mat = source.getWorldMatrix().invert();
-            }
-            else if (parameter.semantic === "VIEWINVERSE") {
-                mat = scene.getViewMatrix().invert();
-            }
-            else if (parameter.semantic === "PROJECTIONINVERSE") {
-                mat = scene.getProjectionMatrix().invert();
-            }
-            else if (parameter.semantic === "MODELVIEWINVERSE") {
-                mat = source.getWorldMatrix().multiply(scene.getViewMatrix()).invert();
-            }
-            else if (parameter.semantic === "MODELVIEWPROJECTIONINVERSE") {
-                mat = source.getWorldMatrix().multiply(scene.getTransformMatrix()).invert();
-            }
-            else if (parameter.semantic === "MODELINVERSETRANSPOSE") {
-                mat = Matrix.Transpose(source.getWorldMatrix().invert());
-            }
-            else {
-                debugger;
-            }
-
-            if (mat) {
-                switch (parameter.type) {
-                    case EParameterType.FLOAT_MAT2: shaderMaterial.setMatrix2x2(uniformName, Matrix.GetAsMatrix2x2(mat)); break;
-                    case EParameterType.FLOAT_MAT3: shaderMaterial.setMatrix3x3(uniformName, Matrix.GetAsMatrix3x3(mat)); break;
-                    case EParameterType.FLOAT_MAT4: shaderMaterial.setMatrix(uniformName, mat); break;
-                    default: break;
-                }
-            }
-        }
-
-        /**
-         * Sets the given "parameter" matrix
-         * @param shaderMaterial: the shader material
-         * @param uniform: the name of the shader's uniform
-         * @param value: the value of the uniform
-         * @param type: the uniform's type (EParameterType FLOAT, VEC2, VEC3 or VEC4)
-         */
-        public static SetUniform(shaderMaterial: ShaderMaterial | Effect, uniform: string, value: any, type: number): boolean {
-            switch (type) {
-                case EParameterType.FLOAT: shaderMaterial.setFloat(uniform, value); return true;
-                case EParameterType.FLOAT_VEC2: shaderMaterial.setVector2(uniform, Vector2.FromArray(value)); return true;
-                case EParameterType.FLOAT_VEC3: shaderMaterial.setVector3(uniform, Vector3.FromArray(value)); return true;
-                case EParameterType.FLOAT_VEC4: shaderMaterial.setVector4(uniform, Vector4.FromArray(value)); return true;
-                default: return false;
-            }
-        }
-
-        /**
-        * Returns the wrap mode of the texture
-        * @param mode: the mode value
-        */
-        public static GetWrapMode(mode: number): number {
-            switch (mode) {
-                case ETextureWrapMode.CLAMP_TO_EDGE: return Texture.CLAMP_ADDRESSMODE;
-                case ETextureWrapMode.MIRRORED_REPEAT: return Texture.MIRROR_ADDRESSMODE;
-                case ETextureWrapMode.REPEAT: return Texture.WRAP_ADDRESSMODE;
-                default: return Texture.WRAP_ADDRESSMODE;
-            }
-        }
-
-        /**
-         * Returns the byte stride giving an accessor
-         * @param accessor: the GLTF accessor objet
-         */
-        public static GetByteStrideFromType(accessor: IGLTFAccessor): number {
-            // Needs this function since "byteStride" isn't requiered in glTF format
-            var type = accessor.type;
-
-            switch (type) {
-                case "VEC2": return 2;
-                case "VEC3": return 3;
-                case "VEC4": return 4;
-                case "MAT2": return 4;
-                case "MAT3": return 9;
-                case "MAT4": return 16;
-                default: return 1;
-            }
-        }
-
-        /**
-         * Returns the texture filter mode giving a mode value
-         * @param mode: the filter mode value
-         */
-        public static GetTextureFilterMode(mode: number): ETextureFilterType {
-            switch (mode) {
-                case ETextureFilterType.LINEAR:
-                case ETextureFilterType.LINEAR_MIPMAP_NEAREST:
-                case ETextureFilterType.LINEAR_MIPMAP_LINEAR: return Texture.TRILINEAR_SAMPLINGMODE;
-                case ETextureFilterType.NEAREST:
-                case ETextureFilterType.NEAREST_MIPMAP_NEAREST: return Texture.NEAREST_SAMPLINGMODE;
-                default: return Texture.BILINEAR_SAMPLINGMODE;
-            }
-        }
-
-        public static GetBufferFromBufferView(gltfRuntime: IGLTFRuntime, bufferView: IGLTFBufferView, byteOffset: number, byteLength: number, componentType: EComponentType): ArrayBufferView {
-            var byteOffset = bufferView.byteOffset + byteOffset;
-
-            var loadedBufferView = gltfRuntime.loadedBufferViews[bufferView.buffer];
-            if (byteOffset + byteLength > loadedBufferView.byteLength) {
-                throw new Error("Buffer access is out of range");
-            }
-
-            var buffer = loadedBufferView.buffer;
-            byteOffset += loadedBufferView.byteOffset;
-
-            switch (componentType) {
-                case EComponentType.BYTE: return new Int8Array(buffer, byteOffset, byteLength);
-                case EComponentType.UNSIGNED_BYTE: return new Uint8Array(buffer, byteOffset, byteLength);
-                case EComponentType.SHORT: return new Int16Array(buffer, byteOffset, byteLength);
-                case EComponentType.UNSIGNED_SHORT: return new Uint16Array(buffer, byteOffset, byteLength);
-                default: return new Float32Array(buffer, byteOffset, byteLength);
-            }
-        }
-
-        /**
-         * Returns a buffer from its accessor
-         * @param gltfRuntime: the GLTF runtime
-         * @param accessor: the GLTF accessor
-         */
-        public static GetBufferFromAccessor(gltfRuntime: IGLTFRuntime, accessor: IGLTFAccessor): any {
-            var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[accessor.bufferView];
-            var byteLength = accessor.count * GLTFUtils.GetByteStrideFromType(accessor);
-            return GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, accessor.byteOffset, byteLength, accessor.componentType);
-        }
-
-        /**
-         * Decodes a buffer view into a string
-         * @param view: the buffer view
-         */
-        public static DecodeBufferToText(view: ArrayBufferView): string {
-            var result = "";
-            var length = view.byteLength;
-
-            for (var i = 0; i < length; ++i) {
-                result += String.fromCharCode((<any>view)[i]);
-            }
-
-            return result;
-        }
-
-        /**
-         * Returns the default material of gltf. Related to
-         * https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a-default-material
-         * @param scene: the Babylon.js scene
-         */
-        public static GetDefaultMaterial(scene: Scene): ShaderMaterial {
-            if (!GLTFUtils._DefaultMaterial) {
-                Effect.ShadersStore["GLTFDefaultMaterialVertexShader"] = [
-                    "precision highp float;",
-                    "",
-                    "uniform mat4 worldView;",
-                    "uniform mat4 projection;",
-                    "",
-                    "attribute vec3 position;",
-                    "",
-                    "void main(void)",
-                    "{",
-                    "    gl_Position = projection * worldView * vec4(position, 1.0);",
-                    "}"
-                ].join("\n");
-
-                Effect.ShadersStore["GLTFDefaultMaterialPixelShader"] = [
-                    "precision highp float;",
-                    "",
-                    "uniform vec4 u_emission;",
-                    "",
-                    "void main(void)",
-                    "{",
-                    "    gl_FragColor = u_emission;",
-                    "}"
-                ].join("\n");
-
-                var shaderPath = {
-                    vertex: "GLTFDefaultMaterial",
-                    fragment: "GLTFDefaultMaterial"
-                };
-
-                var options = {
-                    attributes: ["position"],
-                    uniforms: ["worldView", "projection", "u_emission"],
-                    samplers: new Array<string>(),
-                    needAlphaBlending: false
-                };
-
-                GLTFUtils._DefaultMaterial = new ShaderMaterial("GLTFDefaultMaterial", scene, shaderPath, options);
-                GLTFUtils._DefaultMaterial.setColor4("u_emission", new Color4(0.5, 0.5, 0.5, 1.0));
-            }
-
-            return GLTFUtils._DefaultMaterial;
-        }
-
-        // The GLTF default material
-        private static _DefaultMaterial: Nullable<ShaderMaterial> = null;
-    }
-}

+ 0 - 179
loaders/src/glTF/1.0/babylon.glTFMaterialsCommonExtension.ts

@@ -1,179 +0,0 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF1 {
-    interface IGLTFMaterialsCommonExtensionValues {
-        ambient?: number[] | string;
-        diffuse?: number[] | string;
-        emission?: number[] | string;
-        specular?: number[] | string;
-        shininess?: number;
-        transparency?: number;
-    }
-
-    interface IGLTFMaterialsCommonExtension {
-        technique: string;
-        transparent?: number;
-        doubleSided?: boolean;
-        values: IGLTFMaterialsCommonExtensionValues;
-    }
-
-    interface IGLTFRuntimeCommonExtension {
-        lights: {[key: string]: IGLTFLightCommonExtension};
-    }
-
-    interface IGLTFLightCommonExtension {
-        name: string;
-        type: string;
-
-        ambient?: IGLTFAmbientLightCommonExtension;
-        point?: IGLTFPointLightCommonExtension;
-        directional?: IGLTFDirectionalLightCommonExtension;
-        spot?: IGLTFSpotLightCommonExtension;
-    }
-
-    interface IGLTFPointLightCommonExtension {
-        color: number[];
-        constantAttenuation: number;
-        linearAttenuation: number;
-        quadraticAttenuation: number;
-    }
-
-    interface IGLTFAmbientLightCommonExtension {
-        color: number[];
-    }
-
-    interface IGLTFDirectionalLightCommonExtension {
-        color: number[];
-    }
-
-    interface IGLTFSpotLightCommonExtension {
-        color: number[];
-        constantAttenuation: number;
-        fallOffAngle: number;
-        fallOffExponent: number;
-        linearAttenuation: number;
-        quadraticAttenuation: number;
-    }
-
-    export class GLTFMaterialsCommonExtension extends GLTFLoaderExtension {
-
-        constructor() {
-            super("KHR_materials_common");
-        }
-
-        public loadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError: (message: string) => void): boolean {
-            if (!gltfRuntime.extensions) { return false; }
-
-            var extension: IGLTFRuntimeCommonExtension = gltfRuntime.extensions[this.name];
-            if (!extension) { return false; }
-
-            // Create lights
-            var lights = extension.lights;
-            if (lights) {
-                for (var thing in lights) {
-                    var light: IGLTFLightCommonExtension = lights[thing];
-
-                    switch (light.type) {
-                        case "ambient":
-                            var ambientLight = new HemisphericLight(light.name, new Vector3(0, 1, 0), gltfRuntime.scene);
-                            var ambient = light.ambient;
-                            if (ambient) {
-                                ambientLight.diffuse = Color3.FromArray(ambient.color || [1, 1, 1]);
-                            }
-                            break;
-                        case "point":
-                            var pointLight = new PointLight(light.name, new Vector3(10, 10, 10), gltfRuntime.scene);
-                            var point = light.point;
-                            if (point) {
-                                pointLight.diffuse = Color3.FromArray(point.color || [1, 1, 1]);
-                            }
-                            break;
-                        case "directional":
-                            var dirLight = new DirectionalLight(light.name, new Vector3(0, -1, 0), gltfRuntime.scene);
-                            var directional = light.directional;
-                            if (directional) {
-                                dirLight.diffuse = Color3.FromArray(directional.color || [1, 1, 1]);
-                            }
-                            break;
-                        case "spot":
-                            var spot = light.spot;
-                            if (spot) {
-                                var spotLight = new SpotLight(light.name, new Vector3(0, 10, 0), new Vector3(0, -1, 0),
-                                                            spot.fallOffAngle || Math.PI,
-                                                            spot.fallOffExponent || 0.0,
-                                                            gltfRuntime.scene);
-                                spotLight.diffuse = Color3.FromArray(spot.color || [1, 1, 1]);
-                            }
-                            break;
-                        default: Tools.Warn("GLTF Material Common extension: light type \"" + light.type + "\” not supported"); break;
-                    }
-                }
-            }
-
-            return false;
-        }
-
-        public loadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: (message: string) => void): boolean {
-            var material: IGLTFMaterial = gltfRuntime.materials[id];
-            if (!material || !material.extensions) { return false; }
-
-            var extension: IGLTFMaterialsCommonExtension = material.extensions[this.name];
-            if (!extension) { return false; }
-
-            var standardMaterial = new StandardMaterial(id, gltfRuntime.scene);
-            standardMaterial.sideOrientation = Material.CounterClockWiseSideOrientation;
-
-            if (extension.technique === "CONSTANT") {
-                standardMaterial.disableLighting = true;
-            }
-
-            standardMaterial.backFaceCulling = extension.doubleSided === undefined ? false : !extension.doubleSided;
-            standardMaterial.alpha = extension.values.transparency === undefined ? 1.0 : extension.values.transparency;
-            standardMaterial.specularPower = extension.values.shininess === undefined ? 0.0 : extension.values.shininess;
-
-            // Ambient
-            if (typeof extension.values.ambient === "string") {
-                this._loadTexture(gltfRuntime, extension.values.ambient, standardMaterial, "ambientTexture", onError);
-            }
-            else {
-                standardMaterial.ambientColor = Color3.FromArray(extension.values.ambient || [0, 0, 0]);
-            }
-
-            // Diffuse
-            if (typeof extension.values.diffuse === "string") {
-                this._loadTexture(gltfRuntime, extension.values.diffuse, standardMaterial, "diffuseTexture", onError);
-            }
-            else {
-                standardMaterial.diffuseColor = Color3.FromArray(extension.values.diffuse || [0, 0, 0]);
-            }
-
-            // Emission
-            if (typeof extension.values.emission === "string") {
-                this._loadTexture(gltfRuntime, extension.values.emission, standardMaterial, "emissiveTexture", onError);
-            }
-            else {
-                standardMaterial.emissiveColor = Color3.FromArray(extension.values.emission || [0, 0, 0]);
-            }
-
-            // Specular
-            if (typeof extension.values.specular === "string") {
-                this._loadTexture(gltfRuntime, extension.values.specular, standardMaterial, "specularTexture", onError);
-            }
-            else {
-                standardMaterial.specularColor = Color3.FromArray(extension.values.specular || [0, 0, 0]);
-            }
-
-            return true;
-        }
-
-        private _loadTexture(gltfRuntime: IGLTFRuntime, id: string, material: StandardMaterial, propertyPath: string, onError: (message: string) => void): void {
-            // Create buffer from texture url
-            GLTFLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, (buffer) => {
-                // Create texture from buffer
-                GLTFLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, (texture) => (<any>material)[propertyPath] = texture, onError);
-            }, onError);
-        }
-    }
-
-    GLTFLoader.RegisterExtension(new GLTFMaterialsCommonExtension());
-}

+ 87 - 0
loaders/src/glTF/1.0/glTFBinaryExtension.ts

@@ -0,0 +1,87 @@
+import { GLTFLoaderExtension } from "./glTFLoaderExtension";
+import { GLTFUtils } from "./glTFLoaderUtils";
+import { GLTFLoaderBase } from "./glTFLoaderV1";
+import { Scene } from "babylonjs";
+import { IGLTFLoaderData } from "../glTFFileLoader";
+import { IGLTFRuntime, IGLTFTexture, IGLTFImage, IGLTFBufferView, EComponentType, IGLTFShader } from "./glTFLoaderInterfaces";
+
+import { GLTFLoaderV1 } from "./glTFLoaderV1";
+
+const BinaryExtensionBufferName = "binary_glTF";
+
+interface IGLTFBinaryExtensionShader {
+    bufferView: string;
+}
+
+interface IGLTFBinaryExtensionImage {
+    bufferView: string;
+    mimeType: string;
+    height: number;
+    width: number;
+}
+
+export class GLTFBinaryExtension extends GLTFLoaderExtension {
+    private _bin : ArrayBufferView;
+
+    public constructor() {
+        super("KHR_binary_glTF");
+    }
+
+    public loadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (gltfRuntime: IGLTFRuntime) => void, onError: (message: string) => void): boolean {
+        var extensionsUsed = (<any>data.json).extensionsUsed;
+        if (!extensionsUsed || extensionsUsed.indexOf(this.name) === -1 || !data.bin) {
+            return false;
+        }
+
+        this._bin = data.bin;
+        onSuccess(GLTFLoaderBase.CreateRuntime(data.json, scene, rootUrl));
+        return true;
+    }
+
+    public loadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: (message: string) => void): boolean {
+        if (gltfRuntime.extensionsUsed.indexOf(this.name) === -1) {
+            return false;
+        }
+
+        if (id !== BinaryExtensionBufferName) {
+            return false;
+        }
+
+        onSuccess(this._bin);
+        return true;
+    }
+
+    public loadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: (message: string) => void): boolean {
+        var texture: IGLTFTexture = gltfRuntime.textures[id];
+        var source: IGLTFImage = gltfRuntime.images[texture.source];
+        if (!source.extensions || !(this.name in source.extensions)) {
+            return false;
+        }
+
+        var sourceExt: IGLTFBinaryExtensionImage = source.extensions[this.name];
+        var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[sourceExt.bufferView];
+        var buffer = GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, 0, bufferView.byteLength, EComponentType.UNSIGNED_BYTE);
+        onSuccess(buffer);
+        return true;
+    }
+
+    public loadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderString: string) => void, onError: (message: string) => void): boolean {
+        var shader: IGLTFShader = gltfRuntime.shaders[id];
+        if (!shader.extensions || !(this.name in shader.extensions)) {
+            return false;
+        }
+
+        var binaryExtensionShader: IGLTFBinaryExtensionShader = shader.extensions[this.name];
+        var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[binaryExtensionShader.bufferView];
+        var shaderBytes = GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, 0, bufferView.byteLength, EComponentType.UNSIGNED_BYTE);
+
+        setTimeout(() => {
+            var shaderString = GLTFUtils.DecodeBufferToText(shaderBytes);
+            onSuccess(shaderString);
+        });
+
+        return true;
+    }
+}
+
+GLTFLoaderV1.RegisterExtension(new GLTFBinaryExtension());

+ 159 - 0
loaders/src/glTF/1.0/glTFLoaderExtension.ts

@@ -0,0 +1,159 @@
+import { Scene, Texture, Material, Nullable } from "babylonjs";
+import { IGLTFLoaderData } from "../glTFFileLoader";
+import { IGLTFRuntime } from "./glTFLoaderInterfaces";
+import { GLTFLoaderV1, GLTFLoaderBase } from "./glTFLoaderV1";
+
+export abstract class GLTFLoaderExtension {
+        private _name: string;
+
+        public constructor(name: string) {
+            this._name = name;
+        }
+
+        public get name(): string {
+            return this._name;
+        }
+
+        /**
+        * Defines an override for loading the runtime
+        * Return true to stop further extensions from loading the runtime
+        */
+    public loadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (gltfRuntime: IGLTFRuntime) => void, onError?: (message: string) => void): boolean {
+        return false;
+    }
+
+    /**
+     * Defines an onverride for creating gltf runtime
+     * Return true to stop further extensions from creating the runtime
+     */
+    public loadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError?: (message: string) => void): boolean {
+        return false;
+    }
+
+    /**
+    * Defines an override for loading buffers
+    * Return true to stop further extensions from loading this buffer
+    */
+    public loadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: (message: string) => void, onProgress?: () => void): boolean {
+        return false;
+    }
+
+    /**
+    * Defines an override for loading texture buffers
+    * Return true to stop further extensions from loading this texture data
+    */
+    public loadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: (message: string) => void): boolean {
+        return false;
+    }
+
+    /**
+    * Defines an override for creating textures
+    * Return true to stop further extensions from loading this texture
+    */
+    public createTextureAsync(gltfRuntime: IGLTFRuntime, id: string, buffer: ArrayBufferView, onSuccess: (texture: Texture) => void, onError: (message: string) => void): boolean {
+        return false;
+    }
+
+    /**
+    * Defines an override for loading shader strings
+    * Return true to stop further extensions from loading this shader data
+    */
+    public loadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderString: string) => void, onError: (message: string) => void): boolean {
+        return false;
+    }
+
+    /**
+    * Defines an override for loading materials
+    * Return true to stop further extensions from loading this material
+    */
+    public loadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: (message: string) => void): boolean {
+        return false;
+    }
+
+    // ---------
+    // Utilities
+    // ---------
+
+    public static LoadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess?: (gltfRuntime: IGLTFRuntime) => void, onError?: (message: string) => void): void {
+        GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
+            return loaderExtension.loadRuntimeAsync(scene, data, rootUrl, onSuccess, onError);
+        }, () => {
+            setTimeout(() => {
+                if (!onSuccess) {
+                    return;
+                }
+                onSuccess(GLTFLoaderBase.CreateRuntime(data.json, scene, rootUrl));
+            });
+        });
+    }
+
+    public static LoadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError?: (message: string) => void): void {
+        GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
+            return loaderExtension.loadRuntimeExtensionsAsync(gltfRuntime, onSuccess, onError);
+        }, () => {
+            setTimeout(() => {
+                onSuccess();
+            });
+        });
+    }
+
+    public static LoadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (bufferView: ArrayBufferView) => void, onError: (message: string) => void, onProgress?: () => void): void {
+        GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
+            return loaderExtension.loadBufferAsync(gltfRuntime, id, onSuccess, onError, onProgress);
+        }, () => {
+            GLTFLoaderBase.LoadBufferAsync(gltfRuntime, id, onSuccess, onError, onProgress);
+        });
+    }
+
+    public static LoadTextureAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (texture: Texture) => void, onError: (message: string) => void): void {
+        GLTFLoaderExtension.LoadTextureBufferAsync(gltfRuntime, id,
+            (buffer) => {
+                if (buffer) {
+                    GLTFLoaderExtension.CreateTextureAsync(gltfRuntime, id, buffer, onSuccess, onError);
+                }
+            }, onError);
+    }
+
+    public static LoadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderData: string | ArrayBuffer) => void, onError: (message: string) => void): void {
+        GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
+            return loaderExtension.loadShaderStringAsync(gltfRuntime, id, onSuccess, onError);
+        }, () => {
+            GLTFLoaderBase.LoadShaderStringAsync(gltfRuntime, id, onSuccess, onError);
+        });
+    }
+
+    public static LoadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: (message: string) => void): void {
+        GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
+            return loaderExtension.loadMaterialAsync(gltfRuntime, id, onSuccess, onError);
+        }, () => {
+            GLTFLoaderBase.LoadMaterialAsync(gltfRuntime, id, onSuccess, onError);
+        });
+    }
+
+    private static LoadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: Nullable<ArrayBufferView>) => void, onError: (message: string) => void): void {
+        GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
+            return loaderExtension.loadTextureBufferAsync(gltfRuntime, id, onSuccess, onError);
+        }, () => {
+            GLTFLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, onSuccess, onError);
+        });
+    }
+
+    private static CreateTextureAsync(gltfRuntime: IGLTFRuntime, id: string, buffer: ArrayBufferView, onSuccess: (texture: Texture) => void, onError: (message: string) => void): void {
+        GLTFLoaderExtension.ApplyExtensions((loaderExtension) => {
+            return loaderExtension.createTextureAsync(gltfRuntime, id, buffer, onSuccess, onError);
+        }, () => {
+            GLTFLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, onSuccess, onError);
+        });
+    }
+
+    private static ApplyExtensions(func: (loaderExtension: GLTFLoaderExtension) => boolean, defaultFunc: () => void): void {
+        for (var extensionName in GLTFLoaderV1.Extensions) {
+            var loaderExtension = GLTFLoaderV1.Extensions[extensionName];
+            if (func(loaderExtension)) {
+                return;
+            }
+        }
+
+        defaultFunc();
+    }
+}

+ 385 - 0
loaders/src/glTF/1.0/glTFLoaderInterfaces.ts

@@ -0,0 +1,385 @@
+import { Texture, Skeleton, Scene, Bone, Node } from "babylonjs";
+
+/**
+* Enums
+*/
+export enum EComponentType {
+    BYTE = 5120,
+    UNSIGNED_BYTE = 5121,
+    SHORT = 5122,
+    UNSIGNED_SHORT = 5123,
+    FLOAT = 5126
+}
+
+export enum EShaderType {
+    FRAGMENT = 35632,
+    VERTEX = 35633
+}
+
+export enum EParameterType {
+    BYTE = 5120,
+    UNSIGNED_BYTE = 5121,
+    SHORT = 5122,
+    UNSIGNED_SHORT = 5123,
+    INT = 5124,
+    UNSIGNED_INT = 5125,
+    FLOAT = 5126,
+    FLOAT_VEC2 = 35664,
+    FLOAT_VEC3 = 35665,
+    FLOAT_VEC4 = 35666,
+    INT_VEC2 = 35667,
+    INT_VEC3 = 35668,
+    INT_VEC4 = 35669,
+    BOOL = 35670,
+    BOOL_VEC2 = 35671,
+    BOOL_VEC3 = 35672,
+    BOOL_VEC4 = 35673,
+    FLOAT_MAT2 = 35674,
+    FLOAT_MAT3 = 35675,
+    FLOAT_MAT4 = 35676,
+    SAMPLER_2D = 35678
+}
+
+export enum ETextureWrapMode {
+    CLAMP_TO_EDGE = 33071,
+    MIRRORED_REPEAT = 33648,
+    REPEAT = 10497
+}
+
+export enum ETextureFilterType {
+    NEAREST = 9728,
+    LINEAR = 9728,
+    NEAREST_MIPMAP_NEAREST = 9984,
+    LINEAR_MIPMAP_NEAREST = 9985,
+    NEAREST_MIPMAP_LINEAR = 9986,
+    LINEAR_MIPMAP_LINEAR = 9987
+}
+
+export enum ETextureFormat {
+    ALPHA = 6406,
+    RGB = 6407,
+    RGBA = 6408,
+    LUMINANCE = 6409,
+    LUMINANCE_ALPHA = 6410
+}
+
+export enum ECullingType {
+    FRONT = 1028,
+    BACK = 1029,
+    FRONT_AND_BACK = 1032
+}
+
+export enum EBlendingFunction {
+    ZERO = 0,
+    ONE = 1,
+    SRC_COLOR = 768,
+    ONE_MINUS_SRC_COLOR = 769,
+    DST_COLOR = 774,
+    ONE_MINUS_DST_COLOR = 775,
+    SRC_ALPHA = 770,
+    ONE_MINUS_SRC_ALPHA = 771,
+    DST_ALPHA = 772,
+    ONE_MINUS_DST_ALPHA = 773,
+    CONSTANT_COLOR = 32769,
+    ONE_MINUS_CONSTANT_COLOR = 32770,
+    CONSTANT_ALPHA = 32771,
+    ONE_MINUS_CONSTANT_ALPHA = 32772,
+    SRC_ALPHA_SATURATE = 776
+}
+
+/**
+* Interfaces
+*/
+export interface IGLTFProperty {
+    extensions?: {[key: string]: any};
+    extras?: Object;
+}
+
+export interface IGLTFChildRootProperty extends IGLTFProperty {
+    name?: string;
+}
+
+export interface IGLTFAccessor extends IGLTFChildRootProperty {
+    bufferView: string;
+    byteOffset: number;
+    byteStride: number;
+    count: number;
+    type: string;
+    componentType: EComponentType;
+
+    max?: number[];
+    min?: number[];
+    name?: string;
+}
+
+export interface IGLTFBufferView extends IGLTFChildRootProperty {
+    buffer: string;
+    byteOffset: number;
+    byteLength: number;
+    byteStride: number;
+
+    target?: number;
+}
+
+export interface IGLTFBuffer extends IGLTFChildRootProperty {
+    uri: string;
+
+    byteLength?: number;
+    type?: string;
+}
+
+export interface IGLTFShader extends IGLTFChildRootProperty {
+    uri: string;
+    type: EShaderType;
+}
+
+export interface IGLTFProgram extends IGLTFChildRootProperty {
+    attributes: string[];
+    fragmentShader: string;
+    vertexShader: string;
+}
+
+export interface IGLTFTechniqueParameter {
+    type: number;
+
+    count?: number;
+    semantic?: string;
+    node?: string;
+    value?: number | boolean | string | Array<any>;
+    source?: string;
+
+    babylonValue?: any;
+}
+
+export interface IGLTFTechniqueCommonProfile {
+    lightingModel: string;
+    texcoordBindings: Object;
+
+    parameters?: Array<any>;
+}
+
+export interface IGLTFTechniqueStatesFunctions {
+    blendColor?: number[];
+    blendEquationSeparate?: number[];
+    blendFuncSeparate?: number[];
+    colorMask: boolean[];
+    cullFace: number[];
+}
+
+export interface IGLTFTechniqueStates {
+    enable: number[];
+    functions: IGLTFTechniqueStatesFunctions;
+}
+
+export interface IGLTFTechnique extends IGLTFChildRootProperty {
+    parameters: {[key: string]: IGLTFTechniqueParameter};
+    program: string;
+
+    attributes: {[key: string]: string};
+    uniforms: {[key: string]: string};
+    states: IGLTFTechniqueStates;
+}
+
+export interface IGLTFMaterial extends IGLTFChildRootProperty {
+    technique?: string;
+    values: string[];
+}
+
+export interface IGLTFMeshPrimitive extends IGLTFProperty {
+    attributes: {[key: string]: string};
+    indices: string;
+    material: string;
+
+    mode?: number;
+}
+
+export interface IGLTFMesh extends IGLTFChildRootProperty {
+    primitives: IGLTFMeshPrimitive[];
+}
+
+export interface IGLTFImage extends IGLTFChildRootProperty {
+    uri: string;
+}
+
+export interface IGLTFSampler extends IGLTFChildRootProperty {
+    magFilter?: number;
+    minFilter?: number;
+    wrapS?: number;
+    wrapT?: number;
+}
+
+export interface IGLTFTexture extends IGLTFChildRootProperty {
+    sampler: string;
+    source: string;
+
+    format?: ETextureFormat;
+    internalFormat?: ETextureFormat;
+    target?: number;
+    type?: number;
+
+    // Babylon.js values (optimize)
+    babylonTexture?: Texture;
+}
+
+export interface IGLTFAmbienLight {
+    color?: number[];
+}
+
+export interface IGLTFDirectionalLight {
+    color?: number[];
+}
+
+export interface IGLTFPointLight {
+    color?: number[];
+    constantAttenuation?: number;
+    linearAttenuation?: number;
+    quadraticAttenuation?: number;
+}
+
+export interface IGLTFSpotLight {
+    color?: number[];
+    constantAttenuation?: number;
+    fallOfAngle?: number;
+    fallOffExponent?: number;
+    linearAttenuation?: number;
+    quadraticAttenuation?: number;
+}
+
+export interface IGLTFLight extends IGLTFChildRootProperty {
+    type: string;
+}
+
+export interface IGLTFCameraOrthographic {
+    xmag: number;
+    ymag: number;
+    zfar: number;
+    znear: number;
+}
+
+export interface IGLTFCameraPerspective {
+    aspectRatio: number;
+    yfov: number;
+    zfar: number;
+    znear: number;
+}
+
+export interface IGLTFCamera extends IGLTFChildRootProperty {
+    type: string;
+}
+
+export interface IGLTFAnimationChannelTarget {
+    id: string;
+    path: string;
+}
+
+export interface IGLTFAnimationChannel {
+    sampler: string;
+    target: IGLTFAnimationChannelTarget;
+}
+
+export interface IGLTFAnimationSampler {
+    input: string;
+    output: string;
+
+    interpolation?: string;
+}
+
+export interface IGLTFAnimation extends IGLTFChildRootProperty {
+    channels?: IGLTFAnimationChannel[];
+    parameters?:  {[key: string]: string};
+    samplers?: {[key: string]: IGLTFAnimationSampler};
+}
+
+export interface IGLTFNodeInstanceSkin {
+    skeletons: string[];
+    skin: string;
+    meshes: string[];
+}
+
+export interface IGLTFSkins extends IGLTFChildRootProperty {
+    bindShapeMatrix: number[];
+    inverseBindMatrices: string;
+    jointNames: string[];
+
+    babylonSkeleton?: Skeleton;
+}
+
+export interface IGLTFNode extends IGLTFChildRootProperty {
+    camera?: string;
+    children: string[];
+    skin?: string;
+    jointName?: string;
+    light?: string;
+    matrix: number[];
+    mesh?: string;
+    meshes?: string[];
+    rotation?: number[];
+    scale?: number[];
+    translation?: number[];
+
+    // Babylon.js values (optimize)
+    babylonNode?: Node;
+}
+
+export interface IGLTFScene extends IGLTFChildRootProperty {
+    nodes: string[];
+}
+
+/**
+* Runtime
+*/
+export interface IGLTFRuntime {
+    extensions: {[key: string]: any};
+    accessors: {[key: string]: IGLTFAccessor};
+    buffers: {[key: string]: IGLTFBuffer};
+    bufferViews: {[key: string]: IGLTFBufferView};
+    meshes: {[key: string]: IGLTFMesh};
+    lights: {[key: string]: IGLTFLight};
+    cameras: {[key: string]: IGLTFCamera};
+    nodes: {[key: string]: IGLTFNode};
+    images: {[key: string]: IGLTFImage};
+    textures: {[key: string]: IGLTFTexture};
+    shaders: {[key: string]: IGLTFShader};
+    programs: {[key: string]: IGLTFProgram};
+    samplers: {[key: string]: IGLTFSampler};
+    techniques: {[key: string]: IGLTFTechnique};
+    materials: {[key: string]: IGLTFMaterial};
+    animations: {[key: string]: IGLTFAnimation};
+    skins: {[key: string]: IGLTFSkins};
+
+    currentScene?: Object;
+    scenes: {[key: string]: IGLTFScene}; // v1.1
+
+    extensionsUsed: string[];
+    extensionsRequired?: string[]; // v1.1
+
+    buffersCount: number;
+    shaderscount: number;
+
+    scene: Scene;
+    rootUrl: string;
+
+    loadedBufferCount: number;
+    loadedBufferViews: { [name: string]: ArrayBufferView };
+
+    loadedShaderCount: number;
+
+    importOnlyMeshes: boolean;
+    importMeshesNames?: string[];
+
+    dummyNodes: Node[];
+}
+
+/**
+* Bones
+*/
+export interface INodeToRoot {
+    bone: Bone;
+    node: IGLTFNode;
+    id: string;
+}
+
+export interface IJointNode {
+    node: IGLTFNode;
+    id: string;
+}

+ 232 - 0
loaders/src/glTF/1.0/glTFLoaderUtils.ts

@@ -0,0 +1,232 @@
+import { Scene, ShaderMaterial, Effect, Nullable, Matrix, Vector2, Vector3, Vector4, Texture, Color4, Node } from "babylonjs";
+import { IGLTFTechniqueParameter, EParameterType, ETextureWrapMode, IGLTFAccessor, ETextureFilterType, IGLTFRuntime, IGLTFBufferView, EComponentType } from "./glTFLoaderInterfaces";
+
+/**
+* Utils functions for GLTF
+*/
+export class GLTFUtils {
+    /**
+     * Sets the given "parameter" matrix
+     * @param scene: the Scene object
+     * @param source: the source node where to pick the matrix
+     * @param parameter: the GLTF technique parameter
+     * @param uniformName: the name of the shader's uniform
+     * @param shaderMaterial: the shader material
+     */
+    public static SetMatrix(scene: Scene, source: Node, parameter: IGLTFTechniqueParameter, uniformName: string, shaderMaterial: ShaderMaterial | Effect): void {
+        var mat: Nullable<Matrix> = null;
+
+        if (parameter.semantic === "MODEL") {
+            mat = source.getWorldMatrix();
+        }
+        else if (parameter.semantic === "PROJECTION") {
+            mat = scene.getProjectionMatrix();
+        }
+        else if (parameter.semantic === "VIEW") {
+            mat = scene.getViewMatrix();
+        }
+        else if (parameter.semantic === "MODELVIEWINVERSETRANSPOSE") {
+            mat = Matrix.Transpose(source.getWorldMatrix().multiply(scene.getViewMatrix()).invert());
+        }
+        else if (parameter.semantic === "MODELVIEW") {
+            mat = source.getWorldMatrix().multiply(scene.getViewMatrix());
+        }
+        else if (parameter.semantic === "MODELVIEWPROJECTION") {
+            mat = source.getWorldMatrix().multiply(scene.getTransformMatrix());
+        }
+        else if (parameter.semantic === "MODELINVERSE") {
+            mat = source.getWorldMatrix().invert();
+        }
+        else if (parameter.semantic === "VIEWINVERSE") {
+            mat = scene.getViewMatrix().invert();
+        }
+        else if (parameter.semantic === "PROJECTIONINVERSE") {
+            mat = scene.getProjectionMatrix().invert();
+        }
+        else if (parameter.semantic === "MODELVIEWINVERSE") {
+            mat = source.getWorldMatrix().multiply(scene.getViewMatrix()).invert();
+        }
+        else if (parameter.semantic === "MODELVIEWPROJECTIONINVERSE") {
+            mat = source.getWorldMatrix().multiply(scene.getTransformMatrix()).invert();
+        }
+        else if (parameter.semantic === "MODELINVERSETRANSPOSE") {
+            mat = Matrix.Transpose(source.getWorldMatrix().invert());
+        }
+        else {
+            debugger;
+        }
+
+        if (mat) {
+            switch (parameter.type) {
+                case EParameterType.FLOAT_MAT2: shaderMaterial.setMatrix2x2(uniformName, Matrix.GetAsMatrix2x2(mat)); break;
+                case EParameterType.FLOAT_MAT3: shaderMaterial.setMatrix3x3(uniformName, Matrix.GetAsMatrix3x3(mat)); break;
+                case EParameterType.FLOAT_MAT4: shaderMaterial.setMatrix(uniformName, mat); break;
+                default: break;
+            }
+        }
+    }
+
+    /**
+     * Sets the given "parameter" matrix
+     * @param shaderMaterial: the shader material
+     * @param uniform: the name of the shader's uniform
+     * @param value: the value of the uniform
+     * @param type: the uniform's type (EParameterType FLOAT, VEC2, VEC3 or VEC4)
+     */
+    public static SetUniform(shaderMaterial: ShaderMaterial | Effect, uniform: string, value: any, type: number): boolean {
+        switch (type) {
+            case EParameterType.FLOAT: shaderMaterial.setFloat(uniform, value); return true;
+            case EParameterType.FLOAT_VEC2: shaderMaterial.setVector2(uniform, Vector2.FromArray(value)); return true;
+            case EParameterType.FLOAT_VEC3: shaderMaterial.setVector3(uniform, Vector3.FromArray(value)); return true;
+            case EParameterType.FLOAT_VEC4: shaderMaterial.setVector4(uniform, Vector4.FromArray(value)); return true;
+            default: return false;
+        }
+    }
+
+    /**
+    * Returns the wrap mode of the texture
+    * @param mode: the mode value
+    */
+    public static GetWrapMode(mode: number): number {
+        switch (mode) {
+            case ETextureWrapMode.CLAMP_TO_EDGE: return Texture.CLAMP_ADDRESSMODE;
+            case ETextureWrapMode.MIRRORED_REPEAT: return Texture.MIRROR_ADDRESSMODE;
+            case ETextureWrapMode.REPEAT: return Texture.WRAP_ADDRESSMODE;
+            default: return Texture.WRAP_ADDRESSMODE;
+        }
+    }
+
+    /**
+     * Returns the byte stride giving an accessor
+     * @param accessor: the GLTF accessor objet
+     */
+    public static GetByteStrideFromType(accessor: IGLTFAccessor): number {
+        // Needs this function since "byteStride" isn't requiered in glTF format
+        var type = accessor.type;
+
+        switch (type) {
+            case "VEC2": return 2;
+            case "VEC3": return 3;
+            case "VEC4": return 4;
+            case "MAT2": return 4;
+            case "MAT3": return 9;
+            case "MAT4": return 16;
+            default: return 1;
+        }
+    }
+
+    /**
+     * Returns the texture filter mode giving a mode value
+     * @param mode: the filter mode value
+     */
+    public static GetTextureFilterMode(mode: number): ETextureFilterType {
+        switch (mode) {
+            case ETextureFilterType.LINEAR:
+            case ETextureFilterType.LINEAR_MIPMAP_NEAREST:
+            case ETextureFilterType.LINEAR_MIPMAP_LINEAR: return Texture.TRILINEAR_SAMPLINGMODE;
+            case ETextureFilterType.NEAREST:
+            case ETextureFilterType.NEAREST_MIPMAP_NEAREST: return Texture.NEAREST_SAMPLINGMODE;
+            default: return Texture.BILINEAR_SAMPLINGMODE;
+        }
+    }
+
+    public static GetBufferFromBufferView(gltfRuntime: IGLTFRuntime, bufferView: IGLTFBufferView, byteOffset: number, byteLength: number, componentType: EComponentType): ArrayBufferView {
+        var byteOffset = bufferView.byteOffset + byteOffset;
+
+        var loadedBufferView = gltfRuntime.loadedBufferViews[bufferView.buffer];
+        if (byteOffset + byteLength > loadedBufferView.byteLength) {
+            throw new Error("Buffer access is out of range");
+        }
+
+        var buffer = loadedBufferView.buffer;
+        byteOffset += loadedBufferView.byteOffset;
+
+        switch (componentType) {
+            case EComponentType.BYTE: return new Int8Array(buffer, byteOffset, byteLength);
+            case EComponentType.UNSIGNED_BYTE: return new Uint8Array(buffer, byteOffset, byteLength);
+            case EComponentType.SHORT: return new Int16Array(buffer, byteOffset, byteLength);
+            case EComponentType.UNSIGNED_SHORT: return new Uint16Array(buffer, byteOffset, byteLength);
+            default: return new Float32Array(buffer, byteOffset, byteLength);
+        }
+    }
+
+    /**
+     * Returns a buffer from its accessor
+     * @param gltfRuntime: the GLTF runtime
+     * @param accessor: the GLTF accessor
+     */
+    public static GetBufferFromAccessor(gltfRuntime: IGLTFRuntime, accessor: IGLTFAccessor): any {
+        var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[accessor.bufferView];
+        var byteLength = accessor.count * GLTFUtils.GetByteStrideFromType(accessor);
+        return GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, accessor.byteOffset, byteLength, accessor.componentType);
+    }
+
+    /**
+     * Decodes a buffer view into a string
+     * @param view: the buffer view
+     */
+    public static DecodeBufferToText(view: ArrayBufferView): string {
+        var result = "";
+        var length = view.byteLength;
+
+        for (var i = 0; i < length; ++i) {
+            result += String.fromCharCode((<any>view)[i]);
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the default material of gltf. Related to
+     * https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a-default-material
+     * @param scene: the Babylon.js scene
+     */
+    public static GetDefaultMaterial(scene: Scene): ShaderMaterial {
+        if (!GLTFUtils._DefaultMaterial) {
+            Effect.ShadersStore["GLTFDefaultMaterialVertexShader"] = [
+                "precision highp float;",
+                "",
+                "uniform mat4 worldView;",
+                "uniform mat4 projection;",
+                "",
+                "attribute vec3 position;",
+                "",
+                "void main(void)",
+                "{",
+                "    gl_Position = projection * worldView * vec4(position, 1.0);",
+                "}"
+            ].join("\n");
+
+            Effect.ShadersStore["GLTFDefaultMaterialPixelShader"] = [
+                "precision highp float;",
+                "",
+                "uniform vec4 u_emission;",
+                "",
+                "void main(void)",
+                "{",
+                "    gl_FragColor = u_emission;",
+                "}"
+            ].join("\n");
+
+            var shaderPath = {
+                vertex: "GLTFDefaultMaterial",
+                fragment: "GLTFDefaultMaterial"
+            };
+
+            var options = {
+                attributes: ["position"],
+                uniforms: ["worldView", "projection", "u_emission"],
+                samplers: new Array<string>(),
+                needAlphaBlending: false
+            };
+
+            GLTFUtils._DefaultMaterial = new ShaderMaterial("GLTFDefaultMaterial", scene, shaderPath, options);
+            GLTFUtils._DefaultMaterial.setColor4("u_emission", new Color4(0.5, 0.5, 0.5, 1.0));
+        }
+
+        return GLTFUtils._DefaultMaterial;
+    }
+
+    // The GLTF default material
+    private static _DefaultMaterial: Nullable<ShaderMaterial> = null;
+}

File diff ditekan karena terlalu besar
+ 1811 - 0
loaders/src/glTF/1.0/glTFLoaderV1.ts


+ 183 - 0
loaders/src/glTF/1.0/glTFMaterialsCommonExtension.ts

@@ -0,0 +1,183 @@
+import { GLTFLoaderExtension, GLTFLoaderBase } from ".";
+
+import { IGLTFRuntime, IGLTFMaterial } from "./glTFLoaderInterfaces";
+
+import { HemisphericLight, Vector3, Color3, PointLight, DirectionalLight, SpotLight, Tools, Material, StandardMaterial } from "babylonjs";
+
+import { GLTFLoaderV1 } from "./glTFLoaderV1";
+
+interface IGLTFMaterialsCommonExtensionValues {
+    ambient?: number[] | string;
+    diffuse?: number[] | string;
+    emission?: number[] | string;
+    specular?: number[] | string;
+    shininess?: number;
+    transparency?: number;
+}
+
+interface IGLTFMaterialsCommonExtension {
+    technique: string;
+    transparent?: number;
+    doubleSided?: boolean;
+    values: IGLTFMaterialsCommonExtensionValues;
+}
+
+interface IGLTFRuntimeCommonExtension {
+    lights: {[key: string]: IGLTFLightCommonExtension};
+}
+
+interface IGLTFLightCommonExtension {
+    name: string;
+    type: string;
+
+    ambient?: IGLTFAmbientLightCommonExtension;
+    point?: IGLTFPointLightCommonExtension;
+    directional?: IGLTFDirectionalLightCommonExtension;
+    spot?: IGLTFSpotLightCommonExtension;
+}
+
+interface IGLTFPointLightCommonExtension {
+    color: number[];
+    constantAttenuation: number;
+    linearAttenuation: number;
+    quadraticAttenuation: number;
+}
+
+interface IGLTFAmbientLightCommonExtension {
+    color: number[];
+}
+
+interface IGLTFDirectionalLightCommonExtension {
+    color: number[];
+}
+
+interface IGLTFSpotLightCommonExtension {
+    color: number[];
+    constantAttenuation: number;
+    fallOffAngle: number;
+    fallOffExponent: number;
+    linearAttenuation: number;
+    quadraticAttenuation: number;
+}
+
+export class GLTFMaterialsCommonExtension extends GLTFLoaderExtension {
+
+    constructor() {
+        super("KHR_materials_common");
+    }
+
+    public loadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError: (message: string) => void): boolean {
+        if (!gltfRuntime.extensions) { return false; }
+
+        var extension: IGLTFRuntimeCommonExtension = gltfRuntime.extensions[this.name];
+        if (!extension) { return false; }
+
+        // Create lights
+        var lights = extension.lights;
+        if (lights) {
+            for (var thing in lights) {
+                var light: IGLTFLightCommonExtension = lights[thing];
+
+                switch (light.type) {
+                    case "ambient":
+                        var ambientLight = new HemisphericLight(light.name, new Vector3(0, 1, 0), gltfRuntime.scene);
+                        var ambient = light.ambient;
+                        if (ambient) {
+                            ambientLight.diffuse = Color3.FromArray(ambient.color || [1, 1, 1]);
+                        }
+                        break;
+                    case "point":
+                        var pointLight = new PointLight(light.name, new Vector3(10, 10, 10), gltfRuntime.scene);
+                        var point = light.point;
+                        if (point) {
+                            pointLight.diffuse = Color3.FromArray(point.color || [1, 1, 1]);
+                        }
+                        break;
+                    case "directional":
+                        var dirLight = new DirectionalLight(light.name, new Vector3(0, -1, 0), gltfRuntime.scene);
+                        var directional = light.directional;
+                        if (directional) {
+                            dirLight.diffuse = Color3.FromArray(directional.color || [1, 1, 1]);
+                        }
+                        break;
+                    case "spot":
+                        var spot = light.spot;
+                        if (spot) {
+                            var spotLight = new SpotLight(light.name, new Vector3(0, 10, 0), new Vector3(0, -1, 0),
+                                                        spot.fallOffAngle || Math.PI,
+                                                        spot.fallOffExponent || 0.0,
+                                                        gltfRuntime.scene);
+                            spotLight.diffuse = Color3.FromArray(spot.color || [1, 1, 1]);
+                        }
+                        break;
+                    default: Tools.Warn("GLTF Material Common extension: light type \"" + light.type + "\” not supported"); break;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public loadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: (message: string) => void): boolean {
+        var material: IGLTFMaterial = gltfRuntime.materials[id];
+        if (!material || !material.extensions) { return false; }
+
+        var extension: IGLTFMaterialsCommonExtension = material.extensions[this.name];
+        if (!extension) { return false; }
+
+        var standardMaterial = new StandardMaterial(id, gltfRuntime.scene);
+        standardMaterial.sideOrientation = Material.CounterClockWiseSideOrientation;
+
+        if (extension.technique === "CONSTANT") {
+            standardMaterial.disableLighting = true;
+        }
+
+        standardMaterial.backFaceCulling = extension.doubleSided === undefined ? false : !extension.doubleSided;
+        standardMaterial.alpha = extension.values.transparency === undefined ? 1.0 : extension.values.transparency;
+        standardMaterial.specularPower = extension.values.shininess === undefined ? 0.0 : extension.values.shininess;
+
+        // Ambient
+        if (typeof extension.values.ambient === "string") {
+            this._loadTexture(gltfRuntime, extension.values.ambient, standardMaterial, "ambientTexture", onError);
+        }
+        else {
+            standardMaterial.ambientColor = Color3.FromArray(extension.values.ambient || [0, 0, 0]);
+        }
+
+        // Diffuse
+        if (typeof extension.values.diffuse === "string") {
+            this._loadTexture(gltfRuntime, extension.values.diffuse, standardMaterial, "diffuseTexture", onError);
+        }
+        else {
+            standardMaterial.diffuseColor = Color3.FromArray(extension.values.diffuse || [0, 0, 0]);
+        }
+
+        // Emission
+        if (typeof extension.values.emission === "string") {
+            this._loadTexture(gltfRuntime, extension.values.emission, standardMaterial, "emissiveTexture", onError);
+        }
+        else {
+            standardMaterial.emissiveColor = Color3.FromArray(extension.values.emission || [0, 0, 0]);
+        }
+
+        // Specular
+        if (typeof extension.values.specular === "string") {
+            this._loadTexture(gltfRuntime, extension.values.specular, standardMaterial, "specularTexture", onError);
+        }
+        else {
+            standardMaterial.specularColor = Color3.FromArray(extension.values.specular || [0, 0, 0]);
+        }
+
+        return true;
+    }
+
+    private _loadTexture(gltfRuntime: IGLTFRuntime, id: string, material: StandardMaterial, propertyPath: string, onError: (message: string) => void): void {
+        // Create buffer from texture url
+        GLTFLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, (buffer) => {
+            // Create texture from buffer
+            GLTFLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, (texture) => (<any>material)[propertyPath] = texture, onError);
+        }, onError);
+    }
+}
+
+GLTFLoaderV1.RegisterExtension(new GLTFMaterialsCommonExtension());

+ 6 - 0
loaders/src/glTF/1.0/index.ts

@@ -0,0 +1,6 @@
+export * from "./glTFBinaryExtension";
+export * from "./glTFLoaderV1";
+export * from "./glTFLoaderExtension";
+//export * from "./glTFLoaderInterfaces";
+export * from "./glTFLoaderUtils";
+export * from "./glTFMaterialsCommonExtension";

+ 113 - 111
loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts

@@ -1,142 +1,144 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "EXT_lights_image_based";
-
-    interface ILightReference {
-        light: number;
+import { BaseTexture, Nullable, RawCubeTexture, Quaternion, Matrix, SphericalHarmonics, SphericalPolynomial, Scalar } from "babylonjs";
+import { IChildRootProperty } from "babylonjs-gltf2interface";
+import { ISceneV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2, ArrayItem } from "../glTFLoader";
+
+const NAME = "EXT_lights_image_based";
+
+interface ILightReference {
+    light: number;
+}
+
+interface ILight extends IChildRootProperty {
+    intensity: number;
+    rotation: number[];
+    specularImageSize: number;
+    specularImages: number[][];
+    irradianceCoefficients: number[][];
+
+    _babylonTexture?: BaseTexture;
+    _loaded?: Promise<void>;
+}
+
+interface ILights {
+    lights: ILight[];
+}
+
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/eb3e32332042e04691a5f35103f8c261e50d8f1e/extensions/2.0/Khronos/EXT_lights_image_based/README.md) (Experimental)
+ */
+export class EXT_lights_image_based implements IGLTFLoaderExtensionV2 {
+    /** The name of this extension. */
+    public readonly name = NAME;
+
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
+
+    private _loader: GLTFLoaderV2;
+    private _lights?: ILight[];
+
+    /** @hidden */
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
     }
 
-    interface ILight extends IChildRootProperty {
-        intensity: number;
-        rotation: number[];
-        specularImageSize: number;
-        specularImages: number[][];
-        irradianceCoefficients: number[][];
-
-        _babylonTexture?: BaseTexture;
-        _loaded?: Promise<void>;
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
+        delete this._lights;
     }
 
-    interface ILights {
-        lights: ILight[];
-    }
-
-    /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/eb3e32332042e04691a5f35103f8c261e50d8f1e/extensions/2.0/Khronos/EXT_lights_image_based/README.md) (Experimental)
-     */
-    export class EXT_lights_image_based implements IGLTFLoaderExtension {
-        /** The name of this extension. */
-        public readonly name = NAME;
-
-        /** Defines whether this extension is enabled. */
-        public enabled = true;
-
-        private _loader: GLTFLoader;
-        private _lights?: ILight[];
-
-        /** @hidden */
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
-        }
-
-        /** @hidden */
-        public dispose() {
-            delete this._loader;
-            delete this._lights;
-        }
-
-        /** @hidden */
-        public onLoading(): void {
-            const extensions = this._loader.gltf.extensions;
-            if (extensions && extensions[this.name]) {
-                const extension = extensions[this.name] as ILights;
-                this._lights = extension.lights;
-            }
+    /** @hidden */
+    public onLoading(): void {
+        const extensions = this._loader.gltf.extensions;
+        if (extensions && extensions[this.name]) {
+            const extension = extensions[this.name] as ILights;
+            this._lights = extension.lights;
         }
+    }
 
-        /** @hidden */
-        public loadSceneAsync(context: string, scene: IScene): Nullable<Promise<void>> {
-            return GLTFLoader.LoadExtensionAsync<ILightReference>(context, scene, this.name, (extensionContext, extension) => {
-                const promises = new Array<Promise<any>>();
+    /** @hidden */
+    public loadSceneAsync(context: string, scene: ISceneV2): Nullable<Promise<void>> {
+        return GLTFLoaderV2.LoadExtensionAsync<ILightReference>(context, scene, this.name, (extensionContext, extension) => {
+            const promises = new Array<Promise<any>>();
 
-                promises.push(this._loader.loadSceneAsync(context, scene));
+            promises.push(this._loader.loadSceneAsync(context, scene));
 
-                this._loader.logOpen(`${extensionContext}`);
+            this._loader.logOpen(`${extensionContext}`);
 
-                const light = ArrayItem.Get(`${extensionContext}/light`, this._lights, extension.light);
-                promises.push(this._loadLightAsync(`#/extensions/${this.name}/lights/${extension.light}`, light).then((texture) => {
-                    this._loader.babylonScene.environmentTexture = texture;
-                }));
+            const light = ArrayItem.Get(`${extensionContext}/light`, this._lights, extension.light);
+            promises.push(this._loadLightAsync(`#/extensions/${this.name}/lights/${extension.light}`, light).then((texture) => {
+                this._loader.babylonScene.environmentTexture = texture;
+            }));
 
-                this._loader.logClose();
+            this._loader.logClose();
 
-                return Promise.all(promises).then(() => {});
-            });
-        }
+            return Promise.all(promises).then(() => {});
+        });
+    }
 
-        private _loadLightAsync(context: string, light: ILight): Promise<BaseTexture> {
-            if (!light._loaded) {
-                const promises = new Array<Promise<any>>();
+    private _loadLightAsync(context: string, light: ILight): Promise<BaseTexture> {
+        if (!light._loaded) {
+            const promises = new Array<Promise<any>>();
 
-                this._loader.logOpen(`${context}`);
+            this._loader.logOpen(`${context}`);
 
-                const imageData = new Array<Array<ArrayBufferView>>(light.specularImages.length);
-                for (let mipmap = 0; mipmap < light.specularImages.length; mipmap++) {
-                    const faces = light.specularImages[mipmap];
-                    imageData[mipmap] = new Array<ArrayBufferView>(faces.length);
-                    for (let face = 0; face < faces.length; face++) {
-                        const specularImageContext = `${context}/specularImages/${mipmap}/${face}`;
-                        this._loader.logOpen(`${specularImageContext}`);
+            const imageData = new Array<Array<ArrayBufferView>>(light.specularImages.length);
+            for (let mipmap = 0; mipmap < light.specularImages.length; mipmap++) {
+                const faces = light.specularImages[mipmap];
+                imageData[mipmap] = new Array<ArrayBufferView>(faces.length);
+                for (let face = 0; face < faces.length; face++) {
+                    const specularImageContext = `${context}/specularImages/${mipmap}/${face}`;
+                    this._loader.logOpen(`${specularImageContext}`);
 
-                        const index = faces[face];
-                        const image = ArrayItem.Get(specularImageContext, this._loader.gltf.images, index);
-                        promises.push(this._loader.loadImageAsync(`#/images/${index}`, image).then((data) => {
-                            imageData[mipmap][face] = data;
-                        }));
+                    const index = faces[face];
+                    const image = ArrayItem.Get(specularImageContext, this._loader.gltf.images, index);
+                    promises.push(this._loader.loadImageAsync(`#/images/${index}`, image).then((data) => {
+                        imageData[mipmap][face] = data;
+                    }));
 
-                        this._loader.logClose();
-                    }
+                    this._loader.logClose();
                 }
+            }
 
-                this._loader.logClose();
-
-                light._loaded = Promise.all(promises).then(() => {
-                    const babylonTexture = new RawCubeTexture(this._loader.babylonScene, null, light.specularImageSize);
-                    light._babylonTexture = babylonTexture;
+            this._loader.logClose();
 
-                    if (light.intensity != undefined) {
-                        babylonTexture.level = light.intensity;
-                    }
+            light._loaded = Promise.all(promises).then(() => {
+                const babylonTexture = new RawCubeTexture(this._loader.babylonScene, null, light.specularImageSize);
+                light._babylonTexture = babylonTexture;
 
-                    if (light.rotation) {
-                        let rotation = Quaternion.FromArray(light.rotation);
+                if (light.intensity != undefined) {
+                    babylonTexture.level = light.intensity;
+                }
 
-                        // Invert the rotation so that positive rotation is counter-clockwise.
-                        if (!this._loader.babylonScene.useRightHandedSystem) {
-                            rotation = Quaternion.Inverse(rotation);
-                        }
+                if (light.rotation) {
+                    let rotation = Quaternion.FromArray(light.rotation);
 
-                        Matrix.FromQuaternionToRef(rotation, babylonTexture.getReflectionTextureMatrix());
+                    // Invert the rotation so that positive rotation is counter-clockwise.
+                    if (!this._loader.babylonScene.useRightHandedSystem) {
+                        rotation = Quaternion.Inverse(rotation);
                     }
 
-                    const sphericalHarmonics = SphericalHarmonics.FromArray(light.irradianceCoefficients);
-                    sphericalHarmonics.scale(light.intensity);
+                    Matrix.FromQuaternionToRef(rotation, babylonTexture.getReflectionTextureMatrix());
+                }
 
-                    sphericalHarmonics.convertIrradianceToLambertianRadiance();
-                    const sphericalPolynomial = SphericalPolynomial.FromHarmonics(sphericalHarmonics);
+                const sphericalHarmonics = SphericalHarmonics.FromArray(light.irradianceCoefficients);
+                sphericalHarmonics.scale(light.intensity);
 
-                    // Compute the lod generation scale to fit exactly to the number of levels available.
-                    const lodGenerationScale = (imageData.length - 1) / Scalar.Log2(light.specularImageSize);
-                    return babylonTexture.updateRGBDAsync(imageData, sphericalPolynomial, lodGenerationScale);
-                });
-            }
+                sphericalHarmonics.convertIrradianceToLambertianRadiance();
+                const sphericalPolynomial = SphericalPolynomial.FromHarmonics(sphericalHarmonics);
 
-            return light._loaded.then(() => {
-                return light._babylonTexture!;
+                // Compute the lod generation scale to fit exactly to the number of levels available.
+                const lodGenerationScale = (imageData.length - 1) / Scalar.Log2(light.specularImageSize);
+                return babylonTexture.updateRGBDAsync(imageData, sphericalPolynomial, lodGenerationScale);
             });
         }
+
+        return light._loaded.then(() => {
+            return light._babylonTexture!;
+        });
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new EXT_lights_image_based(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new EXT_lights_image_based(loader));

+ 91 - 89
loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts

@@ -1,105 +1,107 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "KHR_draco_mesh_compression";
-
-    interface IKHRDracoMeshCompression {
-        bufferView: number;
-        attributes: { [name: string]: number };
+import { Geometry, DracoCompression, Mesh, Nullable, VertexBuffer } from "babylonjs";
+import { MeshPrimitiveMode } from "babylonjs-gltf2interface";
+import { IBufferViewV2, IMeshPrimitiveV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2, ArrayItem } from "../glTFLoader";
+
+const NAME = "KHR_draco_mesh_compression";
+
+interface IKHRDracoMeshCompression {
+    bufferView: number;
+    attributes: { [name: string]: number };
+}
+
+interface IBufferViewDraco extends IBufferViewV2 {
+    _dracoBabylonGeometry?: Promise<Geometry>;
+}
+
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression)
+ */
+export class KHR_draco_mesh_compression implements IGLTFLoaderExtensionV2 {
+    /** The name of this extension. */
+    public readonly name = NAME;
+
+    /** Defines whether this extension is enabled. */
+    public enabled = DracoCompression.DecoderAvailable;
+
+    private _loader: GLTFLoaderV2;
+    private _dracoCompression?: DracoCompression;
+
+    /** @hidden */
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
     }
 
-    interface IBufferViewDraco extends IBufferView {
-        _dracoBabylonGeometry?: Promise<Geometry>;
-    }
-
-    /**
-     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression)
-     */
-    export class KHR_draco_mesh_compression implements IGLTFLoaderExtension {
-        /** The name of this extension. */
-        public readonly name = NAME;
-
-        /** Defines whether this extension is enabled. */
-        public enabled = DracoCompression.DecoderAvailable;
-
-        private _loader: GLTFLoader;
-        private _dracoCompression?: DracoCompression;
-
-        /** @hidden */
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
+    /** @hidden */
+    public dispose(): void {
+        if (this._dracoCompression) {
+            this._dracoCompression.dispose();
+            delete this._dracoCompression;
         }
 
-        /** @hidden */
-        public dispose(): void {
-            if (this._dracoCompression) {
-                this._dracoCompression.dispose();
-                delete this._dracoCompression;
-            }
+        delete this._loader;
+    }
 
-            delete this._loader;
-        }
+    /** @hidden */
+    public _loadVertexDataAsync(context: string, primitive: IMeshPrimitiveV2, babylonMesh: Mesh): Nullable<Promise<Geometry>> {
+        return GLTFLoaderV2.LoadExtensionAsync<IKHRDracoMeshCompression, Geometry>(context, primitive, this.name, (extensionContext, extension) => {
+            if (primitive.mode != undefined) {
+                if (primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP &&
+                    primitive.mode !== MeshPrimitiveMode.TRIANGLES) {
+                    throw new Error(`${context}: Unsupported mode ${primitive.mode}`);
+                }
 
-        /** @hidden */
-        public _loadVertexDataAsync(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>> {
-            return GLTFLoader.LoadExtensionAsync<IKHRDracoMeshCompression, Geometry>(context, primitive, this.name, (extensionContext, extension) => {
-                if (primitive.mode != undefined) {
-                    if (primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP &&
-                        primitive.mode !== MeshPrimitiveMode.TRIANGLES) {
-                        throw new Error(`${context}: Unsupported mode ${primitive.mode}`);
-                    }
+                // TODO: handle triangle strips
+                if (primitive.mode === MeshPrimitiveMode.TRIANGLE_STRIP) {
+                    throw new Error(`${context}: Mode ${primitive.mode} is not currently supported`);
+                }
+            }
 
-                    // TODO: handle triangle strips
-                    if (primitive.mode === MeshPrimitiveMode.TRIANGLE_STRIP) {
-                        throw new Error(`${context}: Mode ${primitive.mode} is not currently supported`);
-                    }
+            const attributes: { [kind: string]: number } = {};
+            const loadAttribute = (name: string, kind: string) => {
+                const uniqueId = extension.attributes[name];
+                if (uniqueId == undefined) {
+                    return;
                 }
 
-                const attributes: { [kind: string]: number } = {};
-                const loadAttribute = (name: string, kind: string) => {
-                    const uniqueId = extension.attributes[name];
-                    if (uniqueId == undefined) {
-                        return;
-                    }
+                babylonMesh._delayInfo = babylonMesh._delayInfo || [];
+                if (babylonMesh._delayInfo.indexOf(kind) === -1) {
+                    babylonMesh._delayInfo.push(kind);
+                }
 
-                    babylonMesh._delayInfo = babylonMesh._delayInfo || [];
-                    if (babylonMesh._delayInfo.indexOf(kind) === -1) {
-                        babylonMesh._delayInfo.push(kind);
+                attributes[kind] = uniqueId;
+            };
+
+            loadAttribute("POSITION", VertexBuffer.PositionKind);
+            loadAttribute("NORMAL", VertexBuffer.NormalKind);
+            loadAttribute("TANGENT", VertexBuffer.TangentKind);
+            loadAttribute("TEXCOORD_0", VertexBuffer.UVKind);
+            loadAttribute("TEXCOORD_1", VertexBuffer.UV2Kind);
+            loadAttribute("JOINTS_0", VertexBuffer.MatricesIndicesKind);
+            loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind);
+            loadAttribute("COLOR_0", VertexBuffer.ColorKind);
+
+            var bufferView = ArrayItem.Get(extensionContext, this._loader.gltf.bufferViews, extension.bufferView) as IBufferViewDraco;
+            if (!bufferView._dracoBabylonGeometry) {
+                bufferView._dracoBabylonGeometry = this._loader.loadBufferViewAsync(`#/bufferViews/${bufferView.index}`, bufferView).then((data) => {
+                    if (!this._dracoCompression) {
+                        this._dracoCompression = new DracoCompression();
                     }
 
-                    attributes[kind] = uniqueId;
-                };
-
-                loadAttribute("POSITION", VertexBuffer.PositionKind);
-                loadAttribute("NORMAL", VertexBuffer.NormalKind);
-                loadAttribute("TANGENT", VertexBuffer.TangentKind);
-                loadAttribute("TEXCOORD_0", VertexBuffer.UVKind);
-                loadAttribute("TEXCOORD_1", VertexBuffer.UV2Kind);
-                loadAttribute("JOINTS_0", VertexBuffer.MatricesIndicesKind);
-                loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind);
-                loadAttribute("COLOR_0", VertexBuffer.ColorKind);
-
-                var bufferView = ArrayItem.Get(extensionContext, this._loader.gltf.bufferViews, extension.bufferView) as IBufferViewDraco;
-                if (!bufferView._dracoBabylonGeometry) {
-                    bufferView._dracoBabylonGeometry = this._loader.loadBufferViewAsync(`#/bufferViews/${bufferView.index}`, bufferView).then((data) => {
-                        if (!this._dracoCompression) {
-                            this._dracoCompression = new DracoCompression();
-                        }
-
-                        return this._dracoCompression.decodeMeshAsync(data, attributes).then((babylonVertexData) => {
-                            const babylonGeometry = new Geometry(babylonMesh.name, this._loader.babylonScene);
-                            babylonVertexData.applyToGeometry(babylonGeometry);
-                            return babylonGeometry;
-                        }).catch((error) => {
-                            throw new Error(`${context}: ${error.message}`);
-                        });
+                    return this._dracoCompression.decodeMeshAsync(data, attributes).then((babylonVertexData) => {
+                        const babylonGeometry = new Geometry(babylonMesh.name, this._loader.babylonScene);
+                        babylonVertexData.applyToGeometry(babylonGeometry);
+                        return babylonGeometry;
+                    }).catch((error) => {
+                        throw new Error(`${context}: ${error.message}`);
                     });
-                }
+                });
+            }
 
-                return bufferView._dracoBabylonGeometry;
-            });
-        }
+            return bufferView._dracoBabylonGeometry;
+        });
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_draco_mesh_compression(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new KHR_draco_mesh_compression(loader));

+ 95 - 93
loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts

@@ -1,107 +1,109 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "KHR_lights_punctual";
-
-    enum LightType {
-        DIRECTIONAL = "directional",
-        POINT = "point",
-        SPOT = "spot"
-    }
-
-    interface ILightReference {
-        light: number;
+import { Mesh, Nullable, Light, DirectionalLight, Vector3, PointLight, SpotLight, Color3 } from "babylonjs";
+import { IChildRootProperty } from "babylonjs-gltf2interface";
+import { INodeV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2, ArrayItem } from "../glTFLoader";
+
+const NAME = "KHR_lights_punctual";
+
+enum LightType {
+    DIRECTIONAL = "directional",
+    POINT = "point",
+    SPOT = "spot"
+}
+
+interface ILightReference {
+    light: number;
+}
+
+interface ILight extends IChildRootProperty {
+    type: LightType;
+    color?: number[];
+    intensity?: number;
+    range?: number;
+    spot?: {
+        innerConeAngle?: number;
+        outerConeAngle?: number;
+    };
+}
+
+interface ILights {
+    lights: ILight[];
+}
+
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/1048d162a44dbcb05aefc1874bfd423cf60135a6/extensions/2.0/Khronos/KHR_lights_punctual/README.md) (Experimental)
+ */
+export class KHR_lights implements IGLTFLoaderExtensionV2 {
+    /** The name of this extension. */
+    public readonly name = NAME;
+
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
+
+    private _loader: GLTFLoaderV2;
+    private _lights?: ILight[];
+
+    /** @hidden */
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
     }
 
-    interface ILight extends IChildRootProperty {
-        type: LightType;
-        color?: number[];
-        intensity?: number;
-        range?: number;
-        spot?: {
-            innerConeAngle?: number;
-            outerConeAngle?: number;
-        };
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
+        delete this._lights;
     }
 
-    interface ILights {
-        lights: ILight[];
-    }
-
-    /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/1048d162a44dbcb05aefc1874bfd423cf60135a6/extensions/2.0/Khronos/KHR_lights_punctual/README.md) (Experimental)
-     */
-    export class KHR_lights implements IGLTFLoaderExtension {
-        /** The name of this extension. */
-        public readonly name = NAME;
-
-        /** Defines whether this extension is enabled. */
-        public enabled = true;
-
-        private _loader: GLTFLoader;
-        private _lights?: ILight[];
-
-        /** @hidden */
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
+    /** @hidden */
+    public onLoading(): void {
+        const extensions = this._loader.gltf.extensions;
+        if (extensions && extensions[this.name]) {
+            const extension = extensions[this.name] as ILights;
+            this._lights = extension.lights;
         }
+    }
 
-        /** @hidden */
-        public dispose() {
-            delete this._loader;
-            delete this._lights;
-        }
+    /** @hidden */
+    public loadNodeAsync(context: string, node: INodeV2, assign: (babylonMesh: Mesh) => void): Nullable<Promise<Mesh>> {
+        return GLTFLoaderV2.LoadExtensionAsync<ILightReference, Mesh>(context, node, this.name, (extensionContext, extension) => {
+            return this._loader.loadNodeAsync(context, node, (babylonMesh) => {
+                let babylonLight: Light;
 
-        /** @hidden */
-        public onLoading(): void {
-            const extensions = this._loader.gltf.extensions;
-            if (extensions && extensions[this.name]) {
-                const extension = extensions[this.name] as ILights;
-                this._lights = extension.lights;
-            }
-        }
+                const light = ArrayItem.Get(extensionContext, this._lights, extension.light);
+                const name = light.name || babylonMesh.name;
 
-        /** @hidden */
-        public loadNodeAsync(context: string, node: INode, assign: (babylonMesh: Mesh) => void): Nullable<Promise<Mesh>> {
-            return GLTFLoader.LoadExtensionAsync<ILightReference, Mesh>(context, node, this.name, (extensionContext, extension) => {
-                return this._loader.loadNodeAsync(context, node, (babylonMesh) => {
-                    let babylonLight: Light;
-
-                    const light = ArrayItem.Get(extensionContext, this._lights, extension.light);
-                    const name = light.name || babylonMesh.name;
-
-                    switch (light.type) {
-                        case LightType.DIRECTIONAL: {
-                            babylonLight = new DirectionalLight(name, Vector3.Backward(), this._loader.babylonScene);
-                            break;
-                        }
-                        case LightType.POINT: {
-                            babylonLight = new PointLight(name, Vector3.Zero(), this._loader.babylonScene);
-                            break;
-                        }
-                        case LightType.SPOT: {
-                            const babylonSpotLight = new SpotLight(name, Vector3.Zero(), Vector3.Backward(), 0, 1, this._loader.babylonScene);
-                            babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2;
-                            babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2;
-                            babylonLight = babylonSpotLight;
-                            break;
-                        }
-                        default: {
-                            throw new Error(`${extensionContext}: Invalid light type (${light.type})`);
-                        }
+                switch (light.type) {
+                    case LightType.DIRECTIONAL: {
+                        babylonLight = new DirectionalLight(name, Vector3.Backward(), this._loader.babylonScene);
+                        break;
                     }
+                    case LightType.POINT: {
+                        babylonLight = new PointLight(name, Vector3.Zero(), this._loader.babylonScene);
+                        break;
+                    }
+                    case LightType.SPOT: {
+                        const babylonSpotLight = new SpotLight(name, Vector3.Zero(), Vector3.Backward(), 0, 1, this._loader.babylonScene);
+                        babylonSpotLight.angle = ((light.spot && light.spot.outerConeAngle) || Math.PI / 4) * 2;
+                        babylonSpotLight.innerAngle = ((light.spot && light.spot.innerConeAngle) || 0) * 2;
+                        babylonLight = babylonSpotLight;
+                        break;
+                    }
+                    default: {
+                        throw new Error(`${extensionContext}: Invalid light type (${light.type})`);
+                    }
+                }
 
-                    babylonLight.falloffType = Light.FALLOFF_GLTF;
-                    babylonLight.diffuse = light.color ? Color3.FromArray(light.color) : Color3.White();
-                    babylonLight.intensity = light.intensity == undefined ? 1 : light.intensity;
-                    babylonLight.range = light.range == undefined ? Number.MAX_VALUE : light.range;
-                    babylonLight.parent = babylonMesh;
+                babylonLight.falloffType = Light.FALLOFF_GLTF;
+                babylonLight.diffuse = light.color ? Color3.FromArray(light.color) : Color3.White();
+                babylonLight.intensity = light.intensity == undefined ? 1 : light.intensity;
+                babylonLight.range = light.range == undefined ? Number.MAX_VALUE : light.range;
+                babylonLight.parent = babylonMesh;
 
-                    assign(babylonMesh);
-                });
+                assign(babylonMesh);
             });
-        }
+        });
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_lights(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new KHR_lights(loader));

+ 75 - 74
loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts

@@ -1,90 +1,91 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "KHR_materials_pbrSpecularGlossiness";
+import { Material, Nullable, PBRMaterial, Color3 } from "babylonjs";
+import { ITextureInfoV2, IMaterialV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2 } from "../glTFLoader";
+
+const NAME = "KHR_materials_pbrSpecularGlossiness";
+
+interface IKHRMaterialsPbrSpecularGlossiness {
+    diffuseFactor: number[];
+    diffuseTexture: ITextureInfoV2;
+    specularFactor: number[];
+    glossinessFactor: number;
+    specularGlossinessTexture: ITextureInfoV2;
+}
+
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness)
+ */
+export class KHR_materials_pbrSpecularGlossiness implements IGLTFLoaderExtensionV2 {
+    /** The name of this extension. */
+    public readonly name = NAME;
+
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
+
+    private _loader: GLTFLoaderV2;
+
+    /** @hidden */
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
+    }
 
-    interface IKHRMaterialsPbrSpecularGlossiness {
-        diffuseFactor: number[];
-        diffuseTexture: ITextureInfo;
-        specularFactor: number[];
-        glossinessFactor: number;
-        specularGlossinessTexture: ITextureInfo;
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
     }
 
-    /**
-     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness)
-     */
-    export class KHR_materials_pbrSpecularGlossiness implements IGLTFLoaderExtension {
-        /** The name of this extension. */
-        public readonly name = NAME;
+    /** @hidden */
+    public loadMaterialPropertiesAsync(context: string, material: IMaterialV2, babylonMaterial: Material): Nullable<Promise<void>> {
+        return GLTFLoaderV2.LoadExtensionAsync<IKHRMaterialsPbrSpecularGlossiness>(context, material, this.name, (extensionContext, extension) => {
+            const promises = new Array<Promise<any>>();
+            promises.push(this._loader.loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
+            promises.push(this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));
+            this._loader.loadMaterialAlphaProperties(context, material, babylonMaterial);
+            return Promise.all(promises).then(() => {});
+        });
+    }
 
-        /** Defines whether this extension is enabled. */
-        public enabled = true;
+    private _loadSpecularGlossinessPropertiesAsync(context: string, material: IMaterialV2, properties: IKHRMaterialsPbrSpecularGlossiness, babylonMaterial: Material): Promise<void> {
+        if (!(babylonMaterial instanceof PBRMaterial)) {
+            throw new Error(`${context}: Material type not supported`);
+        }
 
-        private _loader: GLTFLoader;
+        const promises = new Array<Promise<any>>();
 
-        /** @hidden */
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
-        }
+        babylonMaterial.metallic = null;
+        babylonMaterial.roughness = null;
 
-        /** @hidden */
-        public dispose() {
-            delete this._loader;
+        if (properties.diffuseFactor) {
+            babylonMaterial.albedoColor = Color3.FromArray(properties.diffuseFactor);
+            babylonMaterial.alpha = properties.diffuseFactor[3];
         }
-
-        /** @hidden */
-        public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
-            return GLTFLoader.LoadExtensionAsync<IKHRMaterialsPbrSpecularGlossiness>(context, material, this.name, (extensionContext, extension) => {
-                const promises = new Array<Promise<any>>();
-                promises.push(this._loader.loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
-                promises.push(this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));
-                this._loader.loadMaterialAlphaProperties(context, material, babylonMaterial);
-                return Promise.all(promises).then(() => {});
-            });
+        else {
+            babylonMaterial.albedoColor = Color3.White();
         }
 
-        private _loadSpecularGlossinessPropertiesAsync(context: string, material: IMaterial, properties: IKHRMaterialsPbrSpecularGlossiness, babylonMaterial: Material): Promise<void> {
-            if (!(babylonMaterial instanceof PBRMaterial)) {
-                throw new Error(`${context}: Material type not supported`);
-            }
+        babylonMaterial.reflectivityColor = properties.specularFactor ? Color3.FromArray(properties.specularFactor) : Color3.White();
+        babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
 
-            const promises = new Array<Promise<any>>();
+        if (properties.diffuseTexture) {
+            promises.push(this._loader.loadTextureInfoAsync(`${context}/diffuseTexture`, properties.diffuseTexture, (texture) => {
+                babylonMaterial.albedoTexture = texture;
+                return Promise.resolve();
+            }));
+        }
 
-            babylonMaterial.metallic = null;
-            babylonMaterial.roughness = null;
-
-            if (properties.diffuseFactor) {
-                babylonMaterial.albedoColor = Color3.FromArray(properties.diffuseFactor);
-                babylonMaterial.alpha = properties.diffuseFactor[3];
-            }
-            else {
-                babylonMaterial.albedoColor = Color3.White();
-            }
-
-            babylonMaterial.reflectivityColor = properties.specularFactor ? Color3.FromArray(properties.specularFactor) : Color3.White();
-            babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
-
-            if (properties.diffuseTexture) {
-                promises.push(this._loader.loadTextureInfoAsync(`${context}/diffuseTexture`, properties.diffuseTexture, (texture) => {
-                    babylonMaterial.albedoTexture = texture;
-                    return Promise.resolve();
-                }));
-            }
-
-            if (properties.specularGlossinessTexture) {
-                promises.push(this._loader.loadTextureInfoAsync(`${context}/specularGlossinessTexture`, properties.specularGlossinessTexture, (texture) => {
-                    babylonMaterial.reflectivityTexture = texture;
-                    return Promise.resolve();
-                }));
-
-                babylonMaterial.reflectivityTexture.hasAlpha = true;
-                babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
-            }
+        if (properties.specularGlossinessTexture) {
+            promises.push(this._loader.loadTextureInfoAsync(`${context}/specularGlossinessTexture`, properties.specularGlossinessTexture, (texture) => {
+                babylonMaterial.reflectivityTexture = texture;
+                return Promise.resolve();
+            }));
 
-            return Promise.all(promises).then(() => {});
+            babylonMaterial.reflectivityTexture.hasAlpha = true;
+            babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
         }
+
+        return Promise.all(promises).then(() => {});
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_materials_pbrSpecularGlossiness(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new KHR_materials_pbrSpecularGlossiness(loader));

+ 58 - 57
loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts

@@ -1,74 +1,75 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+import { Material, Nullable, PBRMaterial, Color3 } from "babylonjs";
+import { IMaterialV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2 } from "../glTFLoader";
 
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "KHR_materials_unlit";
+const NAME = "KHR_materials_unlit";
 
-    /**
-     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
-     */
-    export class KHR_materials_unlit implements IGLTFLoaderExtension {
-        /** The name of this extension. */
-        public readonly name = NAME;
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
+ */
+export class KHR_materials_unlit implements IGLTFLoaderExtensionV2 {
+    /** The name of this extension. */
+    public readonly name = NAME;
 
-        /** Defines whether this extension is enabled. */
-        public enabled = true;
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
 
-        private _loader: GLTFLoader;
+    private _loader: GLTFLoaderV2;
 
-        /** @hidden */
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
-        }
+    /** @hidden */
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
+    }
 
-        /** @hidden */
-        public dispose() {
-            delete this._loader;
-        }
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
+    }
 
-        /** @hidden */
-        public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
-            return GLTFLoader.LoadExtensionAsync(context, material, this.name, () => {
-                return this._loadUnlitPropertiesAsync(context, material, babylonMaterial);
-            });
+    /** @hidden */
+    public loadMaterialPropertiesAsync(context: string, material: IMaterialV2, babylonMaterial: Material): Nullable<Promise<void>> {
+        return GLTFLoaderV2.LoadExtensionAsync(context, material, this.name, () => {
+            return this._loadUnlitPropertiesAsync(context, material, babylonMaterial);
+        });
+    }
+
+    private _loadUnlitPropertiesAsync(context: string, material: IMaterialV2, babylonMaterial: Material): Promise<void> {
+        if (!(babylonMaterial instanceof PBRMaterial)) {
+            throw new Error(`${context}: Material type not supported`);
         }
 
-        private _loadUnlitPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Promise<void> {
-            if (!(babylonMaterial instanceof PBRMaterial)) {
-                throw new Error(`${context}: Material type not supported`);
-            }
+        const promises = new Array<Promise<any>>();
 
-            const promises = new Array<Promise<any>>();
-
-            babylonMaterial.unlit = true;
-
-            const properties = material.pbrMetallicRoughness;
-            if (properties) {
-                if (properties.baseColorFactor) {
-                    babylonMaterial.albedoColor = Color3.FromArray(properties.baseColorFactor);
-                    babylonMaterial.alpha = properties.baseColorFactor[3];
-                }
-                else {
-                    babylonMaterial.albedoColor = Color3.White();
-                }
-
-                if (properties.baseColorTexture) {
-                    promises.push(this._loader.loadTextureInfoAsync(`${context}/baseColorTexture`, properties.baseColorTexture, (texture) => {
-                        babylonMaterial.albedoTexture = texture;
-                        return Promise.resolve();
-                    }));
-                }
-            }
+        babylonMaterial.unlit = true;
 
-            if (material.doubleSided) {
-                babylonMaterial.backFaceCulling = false;
-                babylonMaterial.twoSidedLighting = true;
+        const properties = material.pbrMetallicRoughness;
+        if (properties) {
+            if (properties.baseColorFactor) {
+                babylonMaterial.albedoColor = Color3.FromArray(properties.baseColorFactor);
+                babylonMaterial.alpha = properties.baseColorFactor[3];
+            }
+            else {
+                babylonMaterial.albedoColor = Color3.White();
             }
 
-            this._loader.loadMaterialAlphaProperties(context, material, babylonMaterial);
+            if (properties.baseColorTexture) {
+                promises.push(this._loader.loadTextureInfoAsync(`${context}/baseColorTexture`, properties.baseColorTexture, (texture) => {
+                    babylonMaterial.albedoTexture = texture;
+                    return Promise.resolve();
+                }));
+            }
+        }
 
-            return Promise.all(promises).then(() => {});
+        if (material.doubleSided) {
+            babylonMaterial.backFaceCulling = false;
+            babylonMaterial.twoSidedLighting = true;
         }
+
+        this._loader.loadMaterialAlphaProperties(context, material, babylonMaterial);
+
+        return Promise.all(promises).then(() => {});
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_materials_unlit(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new KHR_materials_unlit(loader));

+ 56 - 55
loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts

@@ -1,72 +1,73 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+import { BaseTexture, Nullable, Texture } from "babylonjs";
+import { ITextureInfoV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2 } from "../glTFLoader";
 
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "KHR_texture_transform";
+const NAME = "KHR_texture_transform";
 
-    interface IKHRTextureTransform {
-        offset?: number[];
-        rotation?: number;
-        scale?: number[];
-        texCoord?: number;
-    }
+interface IKHRTextureTransform {
+    offset?: number[];
+    rotation?: number;
+    scale?: number[];
+    texCoord?: number;
+}
 
-    /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
-     */
-    export class KHR_texture_transform implements IGLTFLoaderExtension {
-        /** The name of this extension. */
-        public readonly name = NAME;
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+ */
+export class KHR_texture_transform implements IGLTFLoaderExtensionV2 {
+    /** The name of this extension. */
+    public readonly name = NAME;
 
-        /** Defines whether this extension is enabled. */
-        public enabled = true;
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
 
-        private _loader: GLTFLoader;
+    private _loader: GLTFLoaderV2;
 
-        /** @hidden */
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
-        }
+    /** @hidden */
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
+    }
 
-        /** @hidden */
-        public dispose() {
-            delete this._loader;
-        }
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
+    }
 
-        /** @hidden */
-        public loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>> {
-            return GLTFLoader.LoadExtensionAsync<IKHRTextureTransform, BaseTexture>(context, textureInfo, this.name, (extensionContext, extension) => {
-                return this._loader.loadTextureInfoAsync(context, textureInfo, (babylonTexture) => {
-                    if (!(babylonTexture instanceof Texture)) {
-                        throw new Error(`${extensionContext}: Texture type not supported`);
-                    }
+    /** @hidden */
+    public loadTextureInfoAsync(context: string, textureInfo: ITextureInfoV2, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>> {
+        return GLTFLoaderV2.LoadExtensionAsync<IKHRTextureTransform, BaseTexture>(context, textureInfo, this.name, (extensionContext, extension) => {
+            return this._loader.loadTextureInfoAsync(context, textureInfo, (babylonTexture) => {
+                if (!(babylonTexture instanceof Texture)) {
+                    throw new Error(`${extensionContext}: Texture type not supported`);
+                }
 
-                    if (extension.offset) {
-                        babylonTexture.uOffset = extension.offset[0];
-                        babylonTexture.vOffset = extension.offset[1];
-                    }
+                if (extension.offset) {
+                    babylonTexture.uOffset = extension.offset[0];
+                    babylonTexture.vOffset = extension.offset[1];
+                }
 
-                    // Always rotate around the origin.
-                    babylonTexture.uRotationCenter = 0;
-                    babylonTexture.vRotationCenter = 0;
+                // Always rotate around the origin.
+                babylonTexture.uRotationCenter = 0;
+                babylonTexture.vRotationCenter = 0;
 
-                    if (extension.rotation) {
-                        babylonTexture.wAng = -extension.rotation;
-                    }
+                if (extension.rotation) {
+                    babylonTexture.wAng = -extension.rotation;
+                }
 
-                    if (extension.scale) {
-                        babylonTexture.uScale = extension.scale[0];
-                        babylonTexture.vScale = extension.scale[1];
-                    }
+                if (extension.scale) {
+                    babylonTexture.uScale = extension.scale[0];
+                    babylonTexture.vScale = extension.scale[1];
+                }
 
-                    if (extension.texCoord != undefined) {
-                        babylonTexture.coordinatesIndex = extension.texCoord;
-                    }
+                if (extension.texCoord != undefined) {
+                    babylonTexture.coordinatesIndex = extension.texCoord;
+                }
 
-                    assign(babylonTexture);
-                });
+                assign(babylonTexture);
             });
-        }
+        });
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_texture_transform(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new KHR_texture_transform(loader));

+ 258 - 257
loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts

@@ -1,302 +1,303 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "MSFT_audio_emitter";
-
-    interface IClipReference {
-        clip: number;
-        weight?: number;
-    }
-
-    interface IEmittersReference {
-        emitters: number[];
-    }
-
-    const enum DistanceModel {
-        linear = "linear",
-        inverse = "inverse",
-        exponential = "exponential",
-    }
-
-    interface IEmitter {
-        name?: string;
-        distanceModel?: DistanceModel;
-        refDistance?: number;
-        maxDistance?: number;
-        rolloffFactor?: number;
-        innerAngle?: number;
-        outerAngle?: number;
-        loop?: boolean;
-        volume?: number;
-        clips: IClipReference[];
-    }
-
-    const enum AudioMimeType {
-        WAV = "audio/wav",
+import { WeightedSound, Sound, Nullable, Mesh, Vector3, Tools, AnimationGroup, AnimationEvent } from "babylonjs";
+import { IArrayItemV2, ISceneV2, INodeV2, IAnimationV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2, ArrayItem } from "../glTFLoader";
+
+const NAME = "MSFT_audio_emitter";
+
+interface IClipReference {
+    clip: number;
+    weight?: number;
+}
+
+interface IEmittersReference {
+    emitters: number[];
+}
+
+const enum DistanceModel {
+    linear = "linear",
+    inverse = "inverse",
+    exponential = "exponential",
+}
+
+interface IEmitter {
+    name?: string;
+    distanceModel?: DistanceModel;
+    refDistance?: number;
+    maxDistance?: number;
+    rolloffFactor?: number;
+    innerAngle?: number;
+    outerAngle?: number;
+    loop?: boolean;
+    volume?: number;
+    clips: IClipReference[];
+}
+
+const enum AudioMimeType {
+    WAV = "audio/wav",
+}
+
+interface IClip {
+    uri?: string;
+    bufferView?: number;
+    mimeType?: AudioMimeType;
+}
+
+interface ILoaderClip extends IClip, IArrayItemV2 {
+    _objectURL?: Promise<string>;
+}
+
+interface ILoaderEmitter extends IEmitter, IArrayItemV2 {
+    _babylonData?: {
+        sound?: WeightedSound;
+        loaded: Promise<void>;
+    };
+    _babylonSounds: Sound[];
+}
+
+interface IMSFTAudioEmitter {
+    clips: ILoaderClip[];
+    emitters: ILoaderEmitter[];
+}
+
+const enum AnimationEventAction {
+    play = "play",
+    pause = "pause",
+    stop = "stop",
+}
+
+interface IAnimationEvent {
+    action: AnimationEventAction;
+    emitter: number;
+    time: number;
+    startOffset?: number;
+}
+
+interface ILoaderAnimationEvent extends IAnimationEvent, IArrayItemV2 {
+}
+
+interface ILoaderAnimationEvents {
+    events: ILoaderAnimationEvent[];
+}
+
+/**
+ * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
+ */
+export class MSFT_audio_emitter implements IGLTFLoaderExtensionV2 {
+    /** The name of this extension. */
+    public readonly name = NAME;
+
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
+
+    private _loader: GLTFLoaderV2;
+    private _clips: Array<ILoaderClip>;
+    private _emitters: Array<ILoaderEmitter>;
+
+    /** @hidden */
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
     }
 
-    interface IClip {
-        uri?: string;
-        bufferView?: number;
-        mimeType?: AudioMimeType;
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
+        delete this._clips;
+        delete this._emitters;
     }
 
-    interface ILoaderClip extends IClip, IArrayItem {
-        _objectURL?: Promise<string>;
-    }
-
-    interface ILoaderEmitter extends IEmitter, IArrayItem {
-        _babylonData?: {
-            sound?: WeightedSound;
-            loaded: Promise<void>;
-        };
-        _babylonSounds: Sound[];
-    }
-
-    interface IMSFTAudioEmitter {
-        clips: ILoaderClip[];
-        emitters: ILoaderEmitter[];
-    }
+    /** @hidden */
+    public onLoading(): void {
+        const extensions = this._loader.gltf.extensions;
+        if (extensions && extensions[this.name]) {
+            const extension = extensions[this.name] as IMSFTAudioEmitter;
 
-    const enum AnimationEventAction {
-        play = "play",
-        pause = "pause",
-        stop = "stop",
-    }
-
-    interface IAnimationEvent {
-        action: AnimationEventAction;
-        emitter: number;
-        time: number;
-        startOffset?: number;
-    }
-
-    interface ILoaderAnimationEvent extends IAnimationEvent, IArrayItem {
-    }
+            this._clips = extension.clips;
+            this._emitters = extension.emitters;
 
-    interface ILoaderAnimationEvents {
-        events: ILoaderAnimationEvent[];
-    }
-
-    /**
-     * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
-     */
-    export class MSFT_audio_emitter implements IGLTFLoaderExtension {
-        /** The name of this extension. */
-        public readonly name = NAME;
-
-        /** Defines whether this extension is enabled. */
-        public enabled = true;
-
-        private _loader: GLTFLoader;
-        private _clips: Array<ILoaderClip>;
-        private _emitters: Array<ILoaderEmitter>;
-
-        /** @hidden */
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
+            ArrayItem.Assign(this._clips);
+            ArrayItem.Assign(this._emitters);
         }
+    }
 
-        /** @hidden */
-        public dispose() {
-            delete this._loader;
-            delete this._clips;
-            delete this._emitters;
-        }
+    /** @hidden */
+    public loadSceneAsync(context: string, scene: ISceneV2): Nullable<Promise<void>> {
+        return GLTFLoaderV2.LoadExtensionAsync<IEmittersReference>(context, scene, this.name, (extensionContext, extension) => {
+            const promises = new Array<Promise<any>>();
 
-        /** @hidden */
-        public onLoading(): void {
-            const extensions = this._loader.gltf.extensions;
-            if (extensions && extensions[this.name]) {
-                const extension = extensions[this.name] as IMSFTAudioEmitter;
+            promises.push(this._loader.loadSceneAsync(context, scene));
 
-                this._clips = extension.clips;
-                this._emitters = extension.emitters;
+            for (const emitterIndex of extension.emitters) {
+                const emitter = ArrayItem.Get(`${extensionContext}/emitters`, this._emitters, emitterIndex);
+                if (emitter.refDistance != undefined || emitter.maxDistance != undefined || emitter.rolloffFactor != undefined ||
+                    emitter.distanceModel != undefined || emitter.innerAngle != undefined || emitter.outerAngle != undefined) {
+                    throw new Error(`${extensionContext}: Direction or Distance properties are not allowed on emitters attached to a scene`);
+                }
 
-                ArrayItem.Assign(this._clips);
-                ArrayItem.Assign(this._emitters);
+                promises.push(this._loadEmitterAsync(`${extensionContext}/emitters/${emitter.index}`, emitter));
             }
-        }
 
-        /** @hidden */
-        public loadSceneAsync(context: string, scene: IScene): Nullable<Promise<void>> {
-            return GLTFLoader.LoadExtensionAsync<IEmittersReference>(context, scene, this.name, (extensionContext, extension) => {
-                const promises = new Array<Promise<any>>();
+            return Promise.all(promises).then(() => {});
+        });
+    }
 
-                promises.push(this._loader.loadSceneAsync(context, scene));
+    /** @hidden */
+    public loadNodeAsync(context: string, node: INodeV2, assign: (babylonMesh: Mesh) => void): Nullable<Promise<Mesh>> {
+        return GLTFLoaderV2.LoadExtensionAsync<IEmittersReference, Mesh>(context, node, this.name, (extensionContext, extension) => {
+            const promises = new Array<Promise<any>>();
 
+            return this._loader.loadNodeAsync(extensionContext, node, (babylonMesh) => {
                 for (const emitterIndex of extension.emitters) {
                     const emitter = ArrayItem.Get(`${extensionContext}/emitters`, this._emitters, emitterIndex);
-                    if (emitter.refDistance != undefined || emitter.maxDistance != undefined || emitter.rolloffFactor != undefined ||
-                        emitter.distanceModel != undefined || emitter.innerAngle != undefined || emitter.outerAngle != undefined) {
-                        throw new Error(`${extensionContext}: Direction or Distance properties are not allowed on emitters attached to a scene`);
-                    }
-
-                    promises.push(this._loadEmitterAsync(`${extensionContext}/emitters/${emitter.index}`, emitter));
+                    promises.push(this._loadEmitterAsync(`${extensionContext}/emitters/${emitter.index}`, emitter).then(() => {
+                        for (const sound of emitter._babylonSounds) {
+                            sound.attachToMesh(babylonMesh);
+                            if (emitter.innerAngle != undefined || emitter.outerAngle != undefined) {
+                                sound.setLocalDirectionToMesh(Vector3.Forward());
+                                sound.setDirectionalCone(
+                                    2 * Tools.ToDegrees(emitter.innerAngle == undefined ? Math.PI : emitter.innerAngle),
+                                    2 * Tools.ToDegrees(emitter.outerAngle == undefined ? Math.PI : emitter.outerAngle),
+                                    0);
+                            }
+                        }
+                    }));
                 }
 
-                return Promise.all(promises).then(() => {});
+                assign(babylonMesh);
+            }).then((babylonMesh) => {
+                return Promise.all(promises).then(() => {
+                    return babylonMesh;
+                });
             });
-        }
+        });
+    }
 
-        /** @hidden */
-        public loadNodeAsync(context: string, node: INode, assign: (babylonMesh: Mesh) => void): Nullable<Promise<Mesh>> {
-            return GLTFLoader.LoadExtensionAsync<IEmittersReference, Mesh>(context, node, this.name, (extensionContext, extension) => {
+    /** @hidden */
+    public loadAnimationAsync(context: string, animation: IAnimationV2): Nullable<Promise<AnimationGroup>> {
+        return GLTFLoaderV2.LoadExtensionAsync<ILoaderAnimationEvents, AnimationGroup>(context, animation, this.name, (extensionContext, extension) => {
+            return this._loader.loadAnimationAsync(context, animation).then((babylonAnimationGroup) => {
                 const promises = new Array<Promise<any>>();
 
-                return this._loader.loadNodeAsync(extensionContext, node, (babylonMesh) => {
-                    for (const emitterIndex of extension.emitters) {
-                        const emitter = ArrayItem.Get(`${extensionContext}/emitters`, this._emitters, emitterIndex);
-                        promises.push(this._loadEmitterAsync(`${extensionContext}/emitters/${emitter.index}`, emitter).then(() => {
-                            for (const sound of emitter._babylonSounds) {
-                                sound.attachToMesh(babylonMesh);
-                                if (emitter.innerAngle != undefined || emitter.outerAngle != undefined) {
-                                    sound.setLocalDirectionToMesh(Vector3.Forward());
-                                    sound.setDirectionalCone(
-                                        2 * Tools.ToDegrees(emitter.innerAngle == undefined ? Math.PI : emitter.innerAngle),
-                                        2 * Tools.ToDegrees(emitter.outerAngle == undefined ? Math.PI : emitter.outerAngle),
-                                        0);
-                                }
-                            }
-                        }));
-                    }
-
-                    assign(babylonMesh);
-                }).then((babylonMesh) => {
-                    return Promise.all(promises).then(() => {
-                        return babylonMesh;
-                    });
+                ArrayItem.Assign(extension.events);
+                for (const event of extension.events) {
+                    promises.push(this._loadAnimationEventAsync(`${extensionContext}/events/${event.index}`, context, animation, event, babylonAnimationGroup));
+                }
+
+                return Promise.all(promises).then(() => {
+                    return babylonAnimationGroup;
                 });
             });
-        }
-
-        /** @hidden */
-        public loadAnimationAsync(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>> {
-            return GLTFLoader.LoadExtensionAsync<ILoaderAnimationEvents, AnimationGroup>(context, animation, this.name, (extensionContext, extension) => {
-                return this._loader.loadAnimationAsync(context, animation).then((babylonAnimationGroup) => {
-                    const promises = new Array<Promise<any>>();
+        });
+    }
 
-                    ArrayItem.Assign(extension.events);
-                    for (const event of extension.events) {
-                        promises.push(this._loadAnimationEventAsync(`${extensionContext}/events/${event.index}`, context, animation, event, babylonAnimationGroup));
-                    }
+    private _loadClipAsync(context: string, clip: ILoaderClip): Promise<string> {
+        if (clip._objectURL) {
+            return clip._objectURL;
+        }
 
-                    return Promise.all(promises).then(() => {
-                        return babylonAnimationGroup;
-                    });
-                });
-            });
+        let promise: Promise<ArrayBufferView>;
+        if (clip.uri) {
+            promise = this._loader.loadUriAsync(context, clip.uri);
+        }
+        else {
+            const bufferView = ArrayItem.Get(`${context}/bufferView`, this._loader.gltf.bufferViews, clip.bufferView);
+            promise = this._loader.loadBufferViewAsync(`#/bufferViews/${bufferView.index}`, bufferView);
         }
 
-        private _loadClipAsync(context: string, clip: ILoaderClip): Promise<string> {
-            if (clip._objectURL) {
-                return clip._objectURL;
-            }
+        clip._objectURL = promise.then((data) => {
+            return URL.createObjectURL(new Blob([data], { type: clip.mimeType }));
+        });
 
-            let promise: Promise<ArrayBufferView>;
-            if (clip.uri) {
-                promise = this._loader.loadUriAsync(context, clip.uri);
-            }
-            else {
-                const bufferView = ArrayItem.Get(`${context}/bufferView`, this._loader.gltf.bufferViews, clip.bufferView);
-                promise = this._loader.loadBufferViewAsync(`#/bufferViews/${bufferView.index}`, bufferView);
+        return clip._objectURL;
+    }
+
+    private _loadEmitterAsync(context: string, emitter: ILoaderEmitter): Promise<void> {
+        emitter._babylonSounds = emitter._babylonSounds || [];
+        if (!emitter._babylonData) {
+            const clipPromises = new Array<Promise<any>>();
+            const name = emitter.name || `emitter${emitter.index}`;
+            const options = {
+                loop: false,
+                autoplay: false,
+                volume: emitter.volume == undefined ? 1 : emitter.volume,
+            };
+
+            for (let i = 0; i < emitter.clips.length; i++) {
+                const clipContext = `#/extensions/${this.name}/clips`;
+                const clip = ArrayItem.Get(clipContext, this._clips, emitter.clips[i].clip);
+                clipPromises.push(this._loadClipAsync(`${clipContext}/${emitter.clips[i].clip}`, clip).then((objectURL: string) => {
+                    const sound = emitter._babylonSounds[i] = new Sound(name, objectURL, this._loader.babylonScene, null, options);
+                    sound.refDistance = emitter.refDistance || 1;
+                    sound.maxDistance = emitter.maxDistance || 256;
+                    sound.rolloffFactor = emitter.rolloffFactor || 1;
+                    sound.distanceModel = emitter.distanceModel || 'exponential';
+                    sound._positionInEmitterSpace = true;
+                }));
             }
 
-            clip._objectURL = promise.then((data) => {
-                return URL.createObjectURL(new Blob([data], { type: clip.mimeType }));
+            const promise = Promise.all(clipPromises).then(() => {
+                const weights = emitter.clips.map((clip) => { return clip.weight || 1; });
+                const weightedSound = new WeightedSound(emitter.loop || false, emitter._babylonSounds, weights);
+                if (emitter.innerAngle) { weightedSound.directionalConeInnerAngle = 2 * Tools.ToDegrees(emitter.innerAngle); }
+                if (emitter.outerAngle) { weightedSound.directionalConeOuterAngle = 2 * Tools.ToDegrees(emitter.outerAngle); }
+                if (emitter.volume) { weightedSound.volume = emitter.volume; }
+                emitter._babylonData!.sound = weightedSound;
             });
 
-            return clip._objectURL;
+            emitter._babylonData = {
+                loaded: promise
+            };
         }
 
-        private _loadEmitterAsync(context: string, emitter: ILoaderEmitter): Promise<void> {
-            emitter._babylonSounds = emitter._babylonSounds || [];
-            if (!emitter._babylonData) {
-                const clipPromises = new Array<Promise<any>>();
-                const name = emitter.name || `emitter${emitter.index}`;
-                const options = {
-                    loop: false,
-                    autoplay: false,
-                    volume: emitter.volume == undefined ? 1 : emitter.volume,
-                };
-
-                for (let i = 0; i < emitter.clips.length; i++) {
-                    const clipContext = `#/extensions/${this.name}/clips`;
-                    const clip = ArrayItem.Get(clipContext, this._clips, emitter.clips[i].clip);
-                    clipPromises.push(this._loadClipAsync(`${clipContext}/${emitter.clips[i].clip}`, clip).then((objectURL: string) => {
-                        const sound = emitter._babylonSounds[i] = new Sound(name, objectURL, this._loader.babylonScene, null, options);
-                        sound.refDistance = emitter.refDistance || 1;
-                        sound.maxDistance = emitter.maxDistance || 256;
-                        sound.rolloffFactor = emitter.rolloffFactor || 1;
-                        sound.distanceModel = emitter.distanceModel || 'exponential';
-                        sound._positionInEmitterSpace = true;
-                    }));
-                }
-
-                const promise = Promise.all(clipPromises).then(() => {
-                    const weights = emitter.clips.map((clip) => { return clip.weight || 1; });
-                    const weightedSound = new WeightedSound(emitter.loop || false, emitter._babylonSounds, weights);
-                    if (emitter.innerAngle) { weightedSound.directionalConeInnerAngle = 2 * Tools.ToDegrees(emitter.innerAngle); }
-                    if (emitter.outerAngle) { weightedSound.directionalConeOuterAngle = 2 * Tools.ToDegrees(emitter.outerAngle); }
-                    if (emitter.volume) { weightedSound.volume = emitter.volume; }
-                    emitter._babylonData!.sound = weightedSound;
-                });
+        return emitter._babylonData.loaded;
+    }
 
-                emitter._babylonData = {
-                    loaded: promise
+    private _getEventAction(context: string, sound: WeightedSound, action: AnimationEventAction, time: number, startOffset?: number): (currentFrame: number) => void {
+        switch (action) {
+            case AnimationEventAction.play: {
+                return (currentFrame: number) => {
+                    const frameOffset = (startOffset || 0) + (currentFrame - time);
+                    sound.play(frameOffset);
                 };
             }
-
-            return emitter._babylonData.loaded;
-        }
-
-        private _getEventAction(context: string, sound: WeightedSound, action: AnimationEventAction, time: number, startOffset?: number): (currentFrame: number) => void {
-            switch (action) {
-                case AnimationEventAction.play: {
-                    return (currentFrame: number) => {
-                        const frameOffset = (startOffset || 0) + (currentFrame - time);
-                        sound.play(frameOffset);
-                    };
-                }
-                case AnimationEventAction.stop: {
-                    return (currentFrame: number) => {
-                        sound.stop();
-                    };
-                }
-                case AnimationEventAction.pause: {
-                    return (currentFrame: number) => {
-                        sound.pause();
-                    };
-                }
-                default: {
-                    throw new Error(`${context}: Unsupported action ${action}`);
-                }
+            case AnimationEventAction.stop: {
+                return (currentFrame: number) => {
+                    sound.stop();
+                };
+            }
+            case AnimationEventAction.pause: {
+                return (currentFrame: number) => {
+                    sound.pause();
+                };
+            }
+            default: {
+                throw new Error(`${context}: Unsupported action ${action}`);
             }
         }
+    }
 
-        private _loadAnimationEventAsync(context: string, animationContext: string, animation: IAnimation, event: ILoaderAnimationEvent, babylonAnimationGroup: AnimationGroup): Promise<void> {
-            if (babylonAnimationGroup.targetedAnimations.length == 0) {
-                return Promise.resolve();
-            }
-            const babylonAnimation = babylonAnimationGroup.targetedAnimations[0];
-            const emitterIndex = event.emitter;
-            const emitter = ArrayItem.Get(`#/extensions/${this.name}/emitters`, this._emitters, emitterIndex);
-            return this._loadEmitterAsync(context, emitter).then(() => {
-                const sound = emitter._babylonData!.sound;
-                if (sound) {
-                    var babylonAnimationEvent = new AnimationEvent(event.time, this._getEventAction(context, sound, event.action, event.time, event.startOffset));
-                    babylonAnimation.animation.addEvent(babylonAnimationEvent);
-                    // Make sure all started audio stops when this animation is terminated.
-                    babylonAnimationGroup.onAnimationGroupEndObservable.add(() => {
-                        sound.stop();
-                    });
-                    babylonAnimationGroup.onAnimationGroupPauseObservable.add(() => {
-                        sound.pause();
-                    });
-                }
-            });
+    private _loadAnimationEventAsync(context: string, animationContext: string, animation: IAnimationV2, event: ILoaderAnimationEvent, babylonAnimationGroup: AnimationGroup): Promise<void> {
+        if (babylonAnimationGroup.targetedAnimations.length == 0) {
+            return Promise.resolve();
         }
+        const babylonAnimation = babylonAnimationGroup.targetedAnimations[0];
+        const emitterIndex = event.emitter;
+        const emitter = ArrayItem.Get(`#/extensions/${this.name}/emitters`, this._emitters, emitterIndex);
+        return this._loadEmitterAsync(context, emitter).then(() => {
+            const sound = emitter._babylonData!.sound;
+            if (sound) {
+                var babylonAnimationEvent = new AnimationEvent(event.time, this._getEventAction(context, sound, event.action, event.time, event.startOffset));
+                babylonAnimation.animation.addEvent(babylonAnimationEvent);
+                // Make sure all started audio stops when this animation is terminated.
+                babylonAnimationGroup.onAnimationGroupEndObservable.add(() => {
+                    sound.stop();
+                });
+                babylonAnimationGroup.onAnimationGroupPauseObservable.add(() => {
+                    sound.pause();
+                });
+            }
+        });
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new MSFT_audio_emitter(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new MSFT_audio_emitter(loader));

+ 218 - 217
loaders/src/glTF/2.0/Extensions/MSFT_lod.ts

@@ -1,278 +1,279 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+import { Observable, Nullable, Deferred, Mesh, Material } from "babylonjs";
+import { INodeV2, IMaterialV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2, ArrayItem } from "../glTFLoader";
 
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "MSFT_lod";
+const NAME = "MSFT_lod";
 
-    interface IMSFTLOD {
-        ids: number[];
-    }
+interface IMSFTLOD {
+    ids: number[];
+}
+
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
+ */
+export class MSFT_lod implements IGLTFLoaderExtensionV2 {
+    /** The name of this extension. */
+    public readonly name = NAME;
+
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
 
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
+     * Maximum number of LODs to load, starting from the lowest LOD.
      */
-    export class MSFT_lod implements IGLTFLoaderExtension {
-        /** The name of this extension. */
-        public readonly name = NAME;
-
-        /** Defines whether this extension is enabled. */
-        public enabled = true;
-
-        /**
-         * Maximum number of LODs to load, starting from the lowest LOD.
-         */
-        public maxLODsToLoad = Number.MAX_VALUE;
-
-        /**
-         * Observable raised when all node LODs of one level are loaded.
-         * The event data is the index of the loaded LOD starting from zero.
-         * Dispose the loader to cancel the loading of the next level of LODs.
-         */
-        public onNodeLODsLoadedObservable = new Observable<number>();
-
-        /**
-         * Observable raised when all material LODs of one level are loaded.
-         * The event data is the index of the loaded LOD starting from zero.
-         * Dispose the loader to cancel the loading of the next level of LODs.
-         */
-        public onMaterialLODsLoadedObservable = new Observable<number>();
-
-        private _loader: GLTFLoader;
-
-        private _nodeIndexLOD: Nullable<number> = null;
-        private _nodeSignalLODs = new Array<Deferred<void>>();
-        private _nodePromiseLODs = new Array<Array<Promise<any>>>();
-
-        private _materialIndexLOD: Nullable<number> = null;
-        private _materialSignalLODs = new Array<Deferred<void>>();
-        private _materialPromiseLODs = new Array<Array<Promise<any>>>();
-
-        /** @hidden */
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
-        }
+    public maxLODsToLoad = Number.MAX_VALUE;
 
-        /** @hidden */
-        public dispose() {
-            delete this._loader;
+    /**
+     * Observable raised when all node LODs of one level are loaded.
+     * The event data is the index of the loaded LOD starting from zero.
+     * Dispose the loader to cancel the loading of the next level of LODs.
+     */
+    public onNodeLODsLoadedObservable = new Observable<number>();
 
-            this._nodeIndexLOD = null;
-            this._nodeSignalLODs.length = 0;
-            this._nodePromiseLODs.length = 0;
+    /**
+     * Observable raised when all material LODs of one level are loaded.
+     * The event data is the index of the loaded LOD starting from zero.
+     * Dispose the loader to cancel the loading of the next level of LODs.
+     */
+    public onMaterialLODsLoadedObservable = new Observable<number>();
 
-            this._materialIndexLOD = null;
-            this._materialSignalLODs.length = 0;
-            this._materialPromiseLODs.length = 0;
+    private _loader: GLTFLoaderV2;
 
-            this.onMaterialLODsLoadedObservable.clear();
-            this.onNodeLODsLoadedObservable.clear();
-        }
+    private _nodeIndexLOD: Nullable<number> = null;
+    private _nodeSignalLODs = new Array<Deferred<void>>();
+    private _nodePromiseLODs = new Array<Array<Promise<any>>>();
 
-        /** @hidden */
-        public onReady(): void {
-            for (let indexLOD = 0; indexLOD < this._nodePromiseLODs.length; indexLOD++) {
-                const promise = Promise.all(this._nodePromiseLODs[indexLOD]).then(() => {
-                    if (indexLOD !== 0) {
-                        this._loader.endPerformanceCounter(`Node LOD ${indexLOD}`);
-                    }
+    private _materialIndexLOD: Nullable<number> = null;
+    private _materialSignalLODs = new Array<Deferred<void>>();
+    private _materialPromiseLODs = new Array<Array<Promise<any>>>();
 
-                    this._loader.log(`Loaded node LOD ${indexLOD}`);
-                    this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
+    /** @hidden */
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
+    }
 
-                    if (indexLOD !== this._nodePromiseLODs.length - 1) {
-                        this._loader.startPerformanceCounter(`Node LOD ${indexLOD + 1}`);
-                        if (this._nodeSignalLODs[indexLOD]) {
-                            this._nodeSignalLODs[indexLOD].resolve();
-                        }
-                    }
-                });
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
 
-                this._loader._completePromises.push(promise);
-            }
+        this._nodeIndexLOD = null;
+        this._nodeSignalLODs.length = 0;
+        this._nodePromiseLODs.length = 0;
 
-            for (let indexLOD = 0; indexLOD < this._materialPromiseLODs.length; indexLOD++) {
-                const promise = Promise.all(this._materialPromiseLODs[indexLOD]).then(() => {
-                    if (indexLOD !== 0) {
-                        this._loader.endPerformanceCounter(`Material LOD ${indexLOD}`);
-                    }
+        this._materialIndexLOD = null;
+        this._materialSignalLODs.length = 0;
+        this._materialPromiseLODs.length = 0;
 
-                    this._loader.log(`Loaded material LOD ${indexLOD}`);
-                    this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
+        this.onMaterialLODsLoadedObservable.clear();
+        this.onNodeLODsLoadedObservable.clear();
+    }
 
-                    if (indexLOD !== this._materialPromiseLODs.length - 1) {
-                        this._loader.startPerformanceCounter(`Material LOD ${indexLOD + 1}`);
-                        if (this._materialSignalLODs[indexLOD]) {
-                            this._materialSignalLODs[indexLOD].resolve();
-                        }
+    /** @hidden */
+    public onReady(): void {
+        for (let indexLOD = 0; indexLOD < this._nodePromiseLODs.length; indexLOD++) {
+            const promise = Promise.all(this._nodePromiseLODs[indexLOD]).then(() => {
+                if (indexLOD !== 0) {
+                    this._loader.endPerformanceCounter(`Node LOD ${indexLOD}`);
+                }
+
+                this._loader.log(`Loaded node LOD ${indexLOD}`);
+                this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
+
+                if (indexLOD !== this._nodePromiseLODs.length - 1) {
+                    this._loader.startPerformanceCounter(`Node LOD ${indexLOD + 1}`);
+                    if (this._nodeSignalLODs[indexLOD]) {
+                        this._nodeSignalLODs[indexLOD].resolve();
                     }
-                });
+                }
+            });
 
-                this._loader._completePromises.push(promise);
-            }
+            this._loader._completePromises.push(promise);
         }
 
-        /** @hidden */
-        public loadNodeAsync(context: string, node: INode, assign: (babylonMesh: Mesh) => void): Nullable<Promise<Mesh>> {
-            return GLTFLoader.LoadExtensionAsync<IMSFTLOD, Mesh>(context, node, this.name, (extensionContext, extension) => {
-                let firstPromise: Promise<Mesh>;
-
-                const nodeLODs = this._getLODs(extensionContext, node, this._loader.gltf.nodes, extension.ids);
-                this._loader.logOpen(`${extensionContext}`);
+        for (let indexLOD = 0; indexLOD < this._materialPromiseLODs.length; indexLOD++) {
+            const promise = Promise.all(this._materialPromiseLODs[indexLOD]).then(() => {
+                if (indexLOD !== 0) {
+                    this._loader.endPerformanceCounter(`Material LOD ${indexLOD}`);
+                }
 
-                for (let indexLOD = 0; indexLOD < nodeLODs.length; indexLOD++) {
-                    const nodeLOD = nodeLODs[indexLOD];
+                this._loader.log(`Loaded material LOD ${indexLOD}`);
+                this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
 
-                    if (indexLOD !== 0) {
-                        this._nodeIndexLOD = indexLOD;
-                        this._nodeSignalLODs[indexLOD] = this._nodeSignalLODs[indexLOD] || new Deferred();
+                if (indexLOD !== this._materialPromiseLODs.length - 1) {
+                    this._loader.startPerformanceCounter(`Material LOD ${indexLOD + 1}`);
+                    if (this._materialSignalLODs[indexLOD]) {
+                        this._materialSignalLODs[indexLOD].resolve();
                     }
+                }
+            });
 
-                    const promise = this._loader.loadNodeAsync(`#/nodes/${nodeLOD.index}`, nodeLOD).then((babylonMesh) => {
-                        if (indexLOD !== 0) {
-                            // TODO: should not rely on _babylonMesh
-                            const previousNodeLOD = nodeLODs[indexLOD - 1];
-                            if (previousNodeLOD._babylonMesh) {
-                                previousNodeLOD._babylonMesh.dispose();
-                                delete previousNodeLOD._babylonMesh;
-                                this._disposeUnusedMaterials();
-                            }
-                        }
+            this._loader._completePromises.push(promise);
+        }
+    }
 
-                        return babylonMesh;
-                    });
+    /** @hidden */
+    public loadNodeAsync(context: string, node: INodeV2, assign: (babylonMesh: Mesh) => void): Nullable<Promise<Mesh>> {
+        return GLTFLoaderV2.LoadExtensionAsync<IMSFTLOD, Mesh>(context, node, this.name, (extensionContext, extension) => {
+            let firstPromise: Promise<Mesh>;
 
-                    if (indexLOD === 0) {
-                        firstPromise = promise;
-                    }
-                    else {
-                        this._nodeIndexLOD = null;
-                    }
+            const nodeLODs = this._getLODs(extensionContext, node, this._loader.gltf.nodes, extension.ids);
+            this._loader.logOpen(`${extensionContext}`);
+
+            for (let indexLOD = 0; indexLOD < nodeLODs.length; indexLOD++) {
+                const nodeLOD = nodeLODs[indexLOD];
 
-                    this._nodePromiseLODs[indexLOD] = this._nodePromiseLODs[indexLOD] || [];
-                    this._nodePromiseLODs[indexLOD].push(promise);
+                if (indexLOD !== 0) {
+                    this._nodeIndexLOD = indexLOD;
+                    this._nodeSignalLODs[indexLOD] = this._nodeSignalLODs[indexLOD] || new Deferred();
                 }
 
-                this._loader.logClose();
-                return firstPromise!;
-            });
-        }
+                const promise = this._loader.loadNodeAsync(`#/nodes/${nodeLOD.index}`, nodeLOD).then((babylonMesh) => {
+                    if (indexLOD !== 0) {
+                        // TODO: should not rely on _babylonMesh
+                        const previousNodeLOD = nodeLODs[indexLOD - 1];
+                        if (previousNodeLOD._babylonMesh) {
+                            previousNodeLOD._babylonMesh.dispose();
+                            delete previousNodeLOD._babylonMesh;
+                            this._disposeUnusedMaterials();
+                        }
+                    }
+
+                    return babylonMesh;
+                });
 
-        /** @hidden */
-        public _loadMaterialAsync(context: string, material: IMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<Material>> {
-            // Don't load material LODs if already loading a node LOD.
-            if (this._nodeIndexLOD) {
-                return null;
+                if (indexLOD === 0) {
+                    firstPromise = promise;
+                }
+                else {
+                    this._nodeIndexLOD = null;
+                }
+
+                this._nodePromiseLODs[indexLOD] = this._nodePromiseLODs[indexLOD] || [];
+                this._nodePromiseLODs[indexLOD].push(promise);
             }
 
-            return GLTFLoader.LoadExtensionAsync<IMSFTLOD, Material>(context, material, this.name, (extensionContext, extension) => {
-                let firstPromise: Promise<Material>;
+            this._loader.logClose();
+            return firstPromise!;
+        });
+    }
 
-                const materialLODs = this._getLODs(extensionContext, material, this._loader.gltf.materials, extension.ids);
-                this._loader.logOpen(`${extensionContext}`);
+    /** @hidden */
+    public _loadMaterialAsync(context: string, material: IMaterialV2, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<Material>> {
+        // Don't load material LODs if already loading a node LOD.
+        if (this._nodeIndexLOD) {
+            return null;
+        }
 
-                for (let indexLOD = 0; indexLOD < materialLODs.length; indexLOD++) {
-                    const materialLOD = materialLODs[indexLOD];
+        return GLTFLoaderV2.LoadExtensionAsync<IMSFTLOD, Material>(context, material, this.name, (extensionContext, extension) => {
+            let firstPromise: Promise<Material>;
 
-                    if (indexLOD !== 0) {
-                        this._materialIndexLOD = indexLOD;
-                    }
+            const materialLODs = this._getLODs(extensionContext, material, this._loader.gltf.materials, extension.ids);
+            this._loader.logOpen(`${extensionContext}`);
 
-                    const promise = this._loader._loadMaterialAsync(`#/materials/${materialLOD.index}`, materialLOD, babylonMesh, babylonDrawMode, (babylonMaterial) => {
-                        if (indexLOD === 0) {
-                            assign(babylonMaterial);
-                        }
-                    }).then((babylonMaterial) => {
-                        if (indexLOD !== 0) {
-                            assign(babylonMaterial);
-
-                            // TODO: should not rely on _babylonData
-                            const previousBabylonDataLOD = materialLODs[indexLOD - 1]._babylonData!;
-                            if (previousBabylonDataLOD[babylonDrawMode]) {
-                                previousBabylonDataLOD[babylonDrawMode].material.dispose();
-                                delete previousBabylonDataLOD[babylonDrawMode];
-                            }
-                        }
+            for (let indexLOD = 0; indexLOD < materialLODs.length; indexLOD++) {
+                const materialLOD = materialLODs[indexLOD];
 
-                        return babylonMaterial;
-                    });
+                if (indexLOD !== 0) {
+                    this._materialIndexLOD = indexLOD;
+                }
 
+                const promise = this._loader._loadMaterialAsync(`#/materials/${materialLOD.index}`, materialLOD, babylonMesh, babylonDrawMode, (babylonMaterial) => {
                     if (indexLOD === 0) {
-                        firstPromise = promise;
+                        assign(babylonMaterial);
                     }
-                    else {
-                        this._materialIndexLOD = null;
+                }).then((babylonMaterial) => {
+                    if (indexLOD !== 0) {
+                        assign(babylonMaterial);
+
+                        // TODO: should not rely on _babylonData
+                        const previousBabylonDataLOD = materialLODs[indexLOD - 1]._babylonData!;
+                        if (previousBabylonDataLOD[babylonDrawMode]) {
+                            previousBabylonDataLOD[babylonDrawMode].material.dispose();
+                            delete previousBabylonDataLOD[babylonDrawMode];
+                        }
                     }
 
-                    this._materialPromiseLODs[indexLOD] = this._materialPromiseLODs[indexLOD] || [];
-                    this._materialPromiseLODs[indexLOD].push(promise);
+                    return babylonMaterial;
+                });
+
+                if (indexLOD === 0) {
+                    firstPromise = promise;
+                }
+                else {
+                    this._materialIndexLOD = null;
                 }
 
-                this._loader.logClose();
-                return firstPromise!;
+                this._materialPromiseLODs[indexLOD] = this._materialPromiseLODs[indexLOD] || [];
+                this._materialPromiseLODs[indexLOD].push(promise);
+            }
+
+            this._loader.logClose();
+            return firstPromise!;
+        });
+    }
+
+    /** @hidden */
+    public _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>> {
+        // Defer the loading of uris if loading a material or node LOD.
+        if (this._materialIndexLOD !== null) {
+            this._loader.log(`deferred`);
+            const previousIndexLOD = this._materialIndexLOD - 1;
+            this._materialSignalLODs[previousIndexLOD] = this._materialSignalLODs[previousIndexLOD] || new Deferred<void>();
+            return this._materialSignalLODs[previousIndexLOD].promise.then(() => {
+                return this._loader.loadUriAsync(context, uri);
+            });
+        }
+        else if (this._nodeIndexLOD !== null) {
+            this._loader.log(`deferred`);
+            const previousIndexLOD = this._nodeIndexLOD - 1;
+            this._nodeSignalLODs[previousIndexLOD] = this._nodeSignalLODs[previousIndexLOD] || new Deferred<void>();
+            return this._nodeSignalLODs[this._nodeIndexLOD - 1].promise.then(() => {
+                return this._loader.loadUriAsync(context, uri);
             });
         }
 
-        /** @hidden */
-        public _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>> {
-            // Defer the loading of uris if loading a material or node LOD.
-            if (this._materialIndexLOD !== null) {
-                this._loader.log(`deferred`);
-                const previousIndexLOD = this._materialIndexLOD - 1;
-                this._materialSignalLODs[previousIndexLOD] = this._materialSignalLODs[previousIndexLOD] || new Deferred<void>();
-                return this._materialSignalLODs[previousIndexLOD].promise.then(() => {
-                    return this._loader.loadUriAsync(context, uri);
-                });
-            }
-            else if (this._nodeIndexLOD !== null) {
-                this._loader.log(`deferred`);
-                const previousIndexLOD = this._nodeIndexLOD - 1;
-                this._nodeSignalLODs[previousIndexLOD] = this._nodeSignalLODs[previousIndexLOD] || new Deferred<void>();
-                return this._nodeSignalLODs[this._nodeIndexLOD - 1].promise.then(() => {
-                    return this._loader.loadUriAsync(context, uri);
-                });
-            }
+        return null;
+    }
 
-            return null;
+    /**
+     * Gets an array of LOD properties from lowest to highest.
+     */
+    private _getLODs<T>(context: string, property: T, array: ArrayLike<T> | undefined, ids: number[]): T[] {
+        if (this.maxLODsToLoad <= 0) {
+            throw new Error("maxLODsToLoad must be greater than zero");
         }
 
-        /**
-         * Gets an array of LOD properties from lowest to highest.
-         */
-        private _getLODs<T>(context: string, property: T, array: ArrayLike<T> | undefined, ids: number[]): T[] {
-            if (this.maxLODsToLoad <= 0) {
-                throw new Error("maxLODsToLoad must be greater than zero");
-            }
+        const properties = new Array<T>();
 
-            const properties = new Array<T>();
-
-            for (let i = ids.length - 1; i >= 0; i--) {
-                properties.push(ArrayItem.Get(`${context}/ids/${ids[i]}`, array, ids[i]));
-                if (properties.length === this.maxLODsToLoad) {
-                    return properties;
-                }
+        for (let i = ids.length - 1; i >= 0; i--) {
+            properties.push(ArrayItem.Get(`${context}/ids/${ids[i]}`, array, ids[i]));
+            if (properties.length === this.maxLODsToLoad) {
+                return properties;
             }
-
-            properties.push(property);
-            return properties;
         }
 
-        private _disposeUnusedMaterials(): void {
-            // TODO: should not rely on _babylonData
-            const materials = this._loader.gltf.materials;
-            if (materials) {
-                for (const material of materials) {
-                    if (material._babylonData) {
-                        for (const drawMode in material._babylonData) {
-                            const babylonData = material._babylonData[drawMode];
-                            if (babylonData.meshes.length === 0) {
-                                babylonData.material.dispose(false, true);
-                                delete material._babylonData[drawMode];
-                            }
+        properties.push(property);
+        return properties;
+    }
+
+    private _disposeUnusedMaterials(): void {
+        // TODO: should not rely on _babylonData
+        const materials = this._loader.gltf.materials;
+        if (materials) {
+            for (const material of materials) {
+                if (material._babylonData) {
+                    for (const drawMode in material._babylonData) {
+                        const babylonData = material._babylonData[drawMode];
+                        if (babylonData.meshes.length === 0) {
+                            babylonData.material.dispose(false, true);
+                            delete material._babylonData[drawMode];
                         }
                     }
                 }
             }
         }
     }
-
-    GLTFLoader.RegisterExtension(NAME, (loader) => new MSFT_lod(loader));
 }
+
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new MSFT_lod(loader));

+ 35 - 34
loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts

@@ -1,47 +1,48 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+import { Material, Nullable, PBRMaterial } from "babylonjs";
+import { IMaterialV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2 } from "../glTFLoader";
 
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "MSFT_minecraftMesh";
+const NAME = "MSFT_minecraftMesh";
 
-    /** @hidden */
-    export class MSFT_minecraftMesh implements IGLTFLoaderExtension {
-        public readonly name = NAME;
-        public enabled = true;
+/** @hidden */
+export class MSFT_minecraftMesh implements IGLTFLoaderExtensionV2 {
+    public readonly name = NAME;
+    public enabled = true;
 
-        private _loader: GLTFLoader;
+    private _loader: GLTFLoaderV2;
 
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
-        }
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
+    }
 
-        public dispose() {
-            delete this._loader;
-        }
+    public dispose() {
+        delete this._loader;
+    }
 
-        public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
-            return GLTFLoader.LoadExtraAsync<boolean>(context, material, this.name, (extraContext, extra) => {
-                if (extra) {
-                    if (!(babylonMaterial instanceof PBRMaterial)) {
-                        throw new Error(`${extraContext}: Material type not supported`);
-                    }
+    public loadMaterialPropertiesAsync(context: string, material: IMaterialV2, babylonMaterial: Material): Nullable<Promise<void>> {
+        return GLTFLoaderV2.LoadExtraAsync<boolean>(context, material, this.name, (extraContext, extra) => {
+            if (extra) {
+                if (!(babylonMaterial instanceof PBRMaterial)) {
+                    throw new Error(`${extraContext}: Material type not supported`);
+                }
 
-                    const promise = this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial);
+                const promise = this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial);
 
-                    if (babylonMaterial.needAlphaBlending()) {
-                        babylonMaterial.forceDepthWrite = true;
-                        babylonMaterial.separateCullingPass = true;
-                    }
+                if (babylonMaterial.needAlphaBlending()) {
+                    babylonMaterial.forceDepthWrite = true;
+                    babylonMaterial.separateCullingPass = true;
+                }
 
-                    babylonMaterial.backFaceCulling = babylonMaterial.forceDepthWrite;
-                    babylonMaterial.twoSidedLighting = true;
+                babylonMaterial.backFaceCulling = babylonMaterial.forceDepthWrite;
+                babylonMaterial.twoSidedLighting = true;
 
-                    return promise;
-                }
+                return promise;
+            }
 
-                return null;
-            });
-        }
+            return null;
+        });
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new MSFT_minecraftMesh(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new MSFT_minecraftMesh(loader));

+ 35 - 34
loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts

@@ -1,47 +1,48 @@
-/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+import { Material, Nullable, PBRMaterial } from "babylonjs";
+import { IMaterialV2 } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtensionV2 } from "../glTFLoaderExtension";
+import { GLTFLoaderV2 } from "../glTFLoader";
 
-module BABYLON.GLTF2.Loader.Extensions {
-    const NAME = "MSFT_sRGBFactors";
+const NAME = "MSFT_sRGBFactors";
 
-    /** @hidden */
-    export class MSFT_sRGBFactors implements IGLTFLoaderExtension {
-        public readonly name = NAME;
-        public enabled = true;
+/** @hidden */
+export class MSFT_sRGBFactors implements IGLTFLoaderExtensionV2 {
+    public readonly name = NAME;
+    public enabled = true;
 
-        private _loader: GLTFLoader;
+    private _loader: GLTFLoaderV2;
 
-        constructor(loader: GLTFLoader) {
-            this._loader = loader;
-        }
-
-        public dispose() {
-            delete this._loader;
-        }
+    constructor(loader: GLTFLoaderV2) {
+        this._loader = loader;
+    }
 
-        public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {
-            return GLTFLoader.LoadExtraAsync<boolean>(context, material, this.name, (extraContext, extra) => {
-                if (extra) {
-                    if (!(babylonMaterial instanceof PBRMaterial)) {
-                        throw new Error(`${extraContext}: Material type not supported`);
-                    }
+    public dispose() {
+        delete this._loader;
+    }
 
-                    const promise = this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial);
+    public loadMaterialPropertiesAsync(context: string, material: IMaterialV2, babylonMaterial: Material): Nullable<Promise<void>> {
+        return GLTFLoaderV2.LoadExtraAsync<boolean>(context, material, this.name, (extraContext, extra) => {
+            if (extra) {
+                if (!(babylonMaterial instanceof PBRMaterial)) {
+                    throw new Error(`${extraContext}: Material type not supported`);
+                }
 
-                    if (!babylonMaterial.albedoTexture) {
-                        babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor);
-                    }
+                const promise = this._loader.loadMaterialPropertiesAsync(context, material, babylonMaterial);
 
-                    if (!babylonMaterial.reflectivityTexture) {
-                        babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor);
-                    }
+                if (!babylonMaterial.albedoTexture) {
+                    babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor);
+                }
 
-                    return promise;
+                if (!babylonMaterial.reflectivityTexture) {
+                    babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor);
                 }
 
-                return null;
-            });
-        }
+                return promise;
+            }
+
+            return null;
+        });
     }
+}
 
-    GLTFLoader.RegisterExtension(NAME, (loader) => new MSFT_sRGBFactors(loader));
-}
+GLTFLoaderV2.RegisterExtension(NAME, (loader) => new MSFT_sRGBFactors(loader));

+ 10 - 0
loaders/src/glTF/2.0/Extensions/index.ts

@@ -0,0 +1,10 @@
+export * from "./EXT_lights_image_based";
+export * from "./KHR_draco_mesh_compression";
+export * from "./KHR_lights_punctual";
+export * from "./KHR_materials_pbrSpecularGlossiness";
+export * from "./KHR_materials_unlit";
+export * from "./KHR_texture_transform";
+export * from "./MSFT_audio_emitter";
+export * from "./MSFT_lod";
+export * from "./MSFT_minecraftMesh";
+export * from "./MSFT_sRGBFactors";

File diff ditekan karena terlalu besar
+ 0 - 2124
loaders/src/glTF/2.0/babylon.glTFLoader.ts


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

@@ -1,110 +0,0 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF2 {
-    /**
-     * Interface for a glTF loader extension.
-     */
-    export interface IGLTFLoaderExtension extends BABYLON.IGLTFLoaderExtension, IDisposable {
-        /**
-         * Called after the loader state changes to LOADING.
-         */
-        onLoading?(): void;
-
-        /**
-         * Called after the loader state changes to READY.
-         */
-        onReady?(): void;
-
-        /**
-         * Define this method to modify the default behavior when loading scenes.
-         * @param context The context when loading the asset
-         * @param scene The glTF scene property
-         * @returns A promise that resolves when the load is complete or null if not handled
-         */
-        loadSceneAsync?(context: string, scene: Loader.IScene): Nullable<Promise<void>>;
-
-        /**
-         * Define this method to modify the default behavior when loading nodes.
-         * @param context The context when loading the asset
-         * @param node The glTF node property
-         * @param assign A function called synchronously after parsing the glTF properties
-         * @returns A promise that resolves with the loaded Babylon mesh when the load is complete or null if not handled
-         */
-        loadNodeAsync?(context: string, node: Loader.INode, assign: (babylonMesh: Mesh) => void): Nullable<Promise<Mesh>>;
-
-        /**
-         * Define this method to modify the default behavior when loading cameras.
-         * @param context The context when loading the asset
-         * @param camera The glTF camera property
-         * @param assign A function called synchronously after parsing the glTF properties
-         * @returns A promise that resolves with the loaded Babylon camera when the load is complete or null if not handled
-         */
-        loadCameraAsync?(context: string, camera: Loader.ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
-
-        /**
-         * @hidden Define this method to modify the default behavior when loading vertex data for mesh primitives.
-         * @param context The context when loading the asset
-         * @param primitive The glTF mesh primitive property
-         * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
-         */
-        _loadVertexDataAsync?(context: string, primitive: Loader.IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
-
-        /**
-         * @hidden Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
-         * @param context The context when loading the asset
-         * @param material The glTF material property
-         * @param assign A function called synchronously after parsing the glTF properties
-         * @returns A promise that resolves with the loaded Babylon material when the load is complete or null if not handled
-         */
-        _loadMaterialAsync?(context: string, material: Loader.IMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<Material>>;
-
-        /**
-         * Define this method to modify the default behavior when creating materials.
-         * @param context The context when loading the asset
-         * @param material The glTF material property
-         * @param babylonDrawMode The draw mode for the Babylon material
-         * @returns The Babylon material or null if not handled
-         */
-        createMaterial?(context: string, material: Loader.IMaterial, babylonDrawMode: number): Nullable<Material>;
-
-        /**
-         * Define this method to modify the default behavior when loading material properties.
-         * @param context The context when loading the asset
-         * @param material The glTF material property
-         * @param babylonMaterial The Babylon material
-         * @returns A promise that resolves when the load is complete or null if not handled
-         */
-        loadMaterialPropertiesAsync?(context: string, material: Loader.IMaterial, babylonMaterial: Material): Nullable<Promise<void>>;
-
-        /**
-         * Define this method to modify the default behavior when loading texture infos.
-         * @param context The context when loading the asset
-         * @param textureInfo The glTF texture info property
-         * @param assign A function called synchronously after parsing the glTF properties
-         * @returns A promise that resolves with the loaded Babylon texture when the load is complete or null if not handled
-         */
-        loadTextureInfoAsync?(context: string, textureInfo: Loader.ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
-
-        /**
-         * Define this method to modify the default behavior when loading animations.
-         * @param context The context when loading the asset
-         * @param animation The glTF animation property
-         * @returns A promise that resolves with the loaded Babylon animation group when the load is complete or null if not handled
-         */
-        loadAnimationAsync?(context: string, animation: Loader.IAnimation): Nullable<Promise<AnimationGroup>>;
-
-        /**
-         * Define this method to modify the default behavior when loading uris.
-         * @param context The context when loading the asset
-         * @param uri The uri to load
-         * @returns A promise that resolves with the loaded data when the load is complete or null if not handled
-         */
-        _loadUriAsync?(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
-    }
-}
-
-/**
- * Defines the module for the built-in glTF 2.0 loader extensions.
- */
-module BABYLON.GLTF2.Loader.Extensions {
-}

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

@@ -1,227 +0,0 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GLTF2.Loader {
-    /**
-     * Loader interface with an index field.
-     */
-    export interface IArrayItem {
-        /**
-         * The index of this item in the array.
-         */
-        index: number;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IAccessor extends GLTF2.IAccessor, IArrayItem {
-        /** @hidden */
-        _data?: Promise<ArrayBufferView>;
-
-        /** @hidden */
-        _babylonVertexBuffer?: Promise<VertexBuffer>;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IAnimationChannel extends GLTF2.IAnimationChannel, IArrayItem {
-    }
-
-    /** @hidden */
-    export interface _IAnimationSamplerData {
-        input: Float32Array;
-        interpolation: AnimationSamplerInterpolation;
-        output: Float32Array;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IAnimationSampler extends GLTF2.IAnimationSampler, IArrayItem {
-        /** @hidden */
-        _data?: Promise<_IAnimationSamplerData>;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IAnimation extends GLTF2.IAnimation, IArrayItem {
-        channels: IAnimationChannel[];
-        samplers: IAnimationSampler[];
-
-        /** @hidden */
-        _babylonAnimationGroup?: AnimationGroup;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IBuffer extends GLTF2.IBuffer, IArrayItem {
-        /** @hidden */
-        _data?: Promise<ArrayBufferView>;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IBufferView extends GLTF2.IBufferView, IArrayItem {
-        /** @hidden */
-        _data?: Promise<ArrayBufferView>;
-
-        /** @hidden */
-        _babylonBuffer?: Promise<Buffer>;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface ICamera extends GLTF2.ICamera, IArrayItem {
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IImage extends GLTF2.IImage, IArrayItem {
-        /** @hidden */
-        _data?: Promise<ArrayBufferView>;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IMaterialNormalTextureInfo extends GLTF2.IMaterialNormalTextureInfo, ITextureInfo {
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IMaterialOcclusionTextureInfo extends GLTF2.IMaterialOcclusionTextureInfo, ITextureInfo {
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IMaterialPbrMetallicRoughness extends GLTF2.IMaterialPbrMetallicRoughness {
-        baseColorTexture?: ITextureInfo;
-        metallicRoughnessTexture?: ITextureInfo;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IMaterial extends GLTF2.IMaterial, IArrayItem {
-        pbrMetallicRoughness?: IMaterialPbrMetallicRoughness;
-        normalTexture?: IMaterialNormalTextureInfo;
-        occlusionTexture?: IMaterialOcclusionTextureInfo;
-        emissiveTexture?: ITextureInfo;
-
-        /** @hidden */
-        _babylonData?: {
-            [drawMode: number]: {
-                material: Material;
-                meshes: AbstractMesh[];
-                promise: Promise<void>;
-            }
-        };
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IMesh extends GLTF2.IMesh, IArrayItem {
-        primitives: IMeshPrimitive[];
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IMeshPrimitive extends GLTF2.IMeshPrimitive, IArrayItem {
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface INode extends GLTF2.INode, IArrayItem {
-        /**
-         * The parent glTF node.
-         */
-        parent?: INode;
-
-        /** @hidden */
-        _babylonMesh?: Mesh;
-
-        /** @hidden */
-        _primitiveBabylonMeshes?: Mesh[];
-
-        /** @hidden */
-        _babylonBones?: Bone[];
-
-        /** @hidden */
-        _numMorphTargets?: number;
-    }
-
-    /** @hidden */
-    export interface _ISamplerData {
-        noMipMaps: boolean;
-        samplingMode: number;
-        wrapU: number;
-        wrapV: number;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface ISampler extends GLTF2.ISampler, IArrayItem {
-        /** @hidden */
-        _data?: _ISamplerData;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IScene extends GLTF2.IScene, IArrayItem {
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface ISkin extends GLTF2.ISkin, IArrayItem {
-        /** @hidden */
-        _babylonSkeleton?: Skeleton;
-
-        /** @hidden */
-        _promise?: Promise<void>;
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface ITexture extends GLTF2.ITexture, IArrayItem {
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface ITextureInfo extends GLTF2.ITextureInfo {
-    }
-
-    /**
-     * Loader interface with additional members.
-     */
-    export interface IGLTF extends GLTF2.IGLTF {
-        accessors?: IAccessor[];
-        animations?: IAnimation[];
-        buffers?: IBuffer[];
-        bufferViews?: IBufferView[];
-        cameras?: ICamera[];
-        images?: IImage[];
-        materials?: IMaterial[];
-        meshes?: IMesh[];
-        nodes?: INode[];
-        samplers?: ISampler[];
-        scenes?: IScene[];
-        skins?: ISkin[];
-        textures?: ITexture[];
-    }
-}

File diff ditekan karena terlalu besar
+ 2123 - 0
loaders/src/glTF/2.0/glTFLoader.ts


+ 106 - 0
loaders/src/glTF/2.0/glTFLoaderExtension.ts

@@ -0,0 +1,106 @@
+import { IDisposable, Nullable, Mesh, Camera, Geometry, Material, BaseTexture, AnimationGroup } from "babylonjs";
+import { ISceneV2, INodeV2, ICameraV2, IMeshPrimitiveV2, IMaterialV2, ITextureInfoV2, IAnimationV2 } from "./glTFLoaderInterfaces";
+import { IGLTFLoaderExtension } from "../glTFFileLoader";
+
+export var tata = 0;
+
+/**
+ * Interface for a glTF loader extension.
+ */
+export interface IGLTFLoaderExtensionV2 extends IGLTFLoaderExtension, IDisposable {
+    /**
+     * Called after the loader state changes to LOADING.
+     */
+    onLoading?(): void;
+
+    /**
+     * Called after the loader state changes to READY.
+     */
+    onReady?(): void;
+
+    /**
+     * Define this method to modify the default behavior when loading scenes.
+     * @param context The context when loading the asset
+     * @param scene The glTF scene property
+     * @returns A promise that resolves when the load is complete or null if not handled
+     */
+    loadSceneAsync?(context: string, scene: ISceneV2): Nullable<Promise<void>>;
+
+    /**
+     * Define this method to modify the default behavior when loading nodes.
+     * @param context The context when loading the asset
+     * @param node The glTF node property
+     * @param assign A function called synchronously after parsing the glTF properties
+     * @returns A promise that resolves with the loaded Babylon mesh when the load is complete or null if not handled
+     */
+    loadNodeAsync?(context: string, node: INodeV2, assign: (babylonMesh: Mesh) => void): Nullable<Promise<Mesh>>;
+
+    /**
+     * Define this method to modify the default behavior when loading cameras.
+     * @param context The context when loading the asset
+     * @param camera The glTF camera property
+     * @param assign A function called synchronously after parsing the glTF properties
+     * @returns A promise that resolves with the loaded Babylon camera when the load is complete or null if not handled
+     */
+    loadCameraAsync?(context: string, camera: ICameraV2, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
+
+    /**
+     * @hidden Define this method to modify the default behavior when loading vertex data for mesh primitives.
+     * @param context The context when loading the asset
+     * @param primitive The glTF mesh primitive property
+     * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
+     */
+    _loadVertexDataAsync?(context: string, primitive: IMeshPrimitiveV2, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
+
+    /**
+     * @hidden Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
+     * @param context The context when loading the asset
+     * @param material The glTF material property
+     * @param assign A function called synchronously after parsing the glTF properties
+     * @returns A promise that resolves with the loaded Babylon material when the load is complete or null if not handled
+     */
+    _loadMaterialAsync?(context: string, material: IMaterialV2, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<Material>>;
+
+    /**
+     * Define this method to modify the default behavior when creating materials.
+     * @param context The context when loading the asset
+     * @param material The glTF material property
+     * @param babylonDrawMode The draw mode for the Babylon material
+     * @returns The Babylon material or null if not handled
+     */
+    createMaterial?(context: string, material: IMaterialV2, babylonDrawMode: number): Nullable<Material>;
+
+    /**
+     * Define this method to modify the default behavior when loading material properties.
+     * @param context The context when loading the asset
+     * @param material The glTF material property
+     * @param babylonMaterial The Babylon material
+     * @returns A promise that resolves when the load is complete or null if not handled
+     */
+    loadMaterialPropertiesAsync?(context: string, material: IMaterialV2, babylonMaterial: Material): Nullable<Promise<void>>;
+
+    /**
+     * Define this method to modify the default behavior when loading texture infos.
+     * @param context The context when loading the asset
+     * @param textureInfo The glTF texture info property
+     * @param assign A function called synchronously after parsing the glTF properties
+     * @returns A promise that resolves with the loaded Babylon texture when the load is complete or null if not handled
+     */
+    loadTextureInfoAsync?(context: string, textureInfo: ITextureInfoV2, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+
+    /**
+     * Define this method to modify the default behavior when loading animations.
+     * @param context The context when loading the asset
+     * @param animation The glTF animation property
+     * @returns A promise that resolves with the loaded Babylon animation group when the load is complete or null if not handled
+     */
+    loadAnimationAsync?(context: string, animation: IAnimationV2): Nullable<Promise<AnimationGroup>>;
+
+    /**
+     * Define this method to modify the default behavior when loading uris.
+     * @param context The context when loading the asset
+     * @param uri The uri to load
+     * @returns A promise that resolves with the loaded data when the load is complete or null if not handled
+     */
+    _loadUriAsync?(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+}

+ 228 - 0
loaders/src/glTF/2.0/glTFLoaderInterfaces.ts

@@ -0,0 +1,228 @@
+import { VertexBuffer, Buffer, AnimationGroup, Material, AbstractMesh, Mesh, Bone, Skeleton } from "babylonjs";
+import { AnimationSamplerInterpolation, ITexture, ITextureInfo, IGLTF, ISampler, IScene, ISkin, IMesh, IMeshPrimitive, INode, IAccessor, IAnimationChannel, IAnimationSampler, IAnimation, IBuffer, IBufferView, ICamera, IImage, IMaterialNormalTextureInfo, IMaterialOcclusionTextureInfo, IMaterialPbrMetallicRoughness, IMaterial } from "babylonjs-gltf2interface";
+
+export var toto = 0;
+
+/**
+ * Loader interface with an index field.
+ */
+export interface IArrayItemV2 {
+    /**
+     * The index of this item in the array.
+     */
+    index: number;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IAccessorV2 extends IAccessor, IArrayItemV2 {
+    /** @hidden */
+    _data?: Promise<ArrayBufferView>;
+
+    /** @hidden */
+    _babylonVertexBuffer?: Promise<VertexBuffer>;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IAnimationChannelV2 extends IAnimationChannel, IArrayItemV2 {
+}
+
+/** @hidden */
+export interface _IAnimationSamplerDataV2 {
+    input: Float32Array;
+    interpolation: AnimationSamplerInterpolation;
+    output: Float32Array;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IAnimationSamplerV2 extends IAnimationSampler, IArrayItemV2 {
+    /** @hidden */
+    _data?: Promise<_IAnimationSamplerDataV2>;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IAnimationV2 extends IAnimation, IArrayItemV2 {
+    channels: IAnimationChannelV2[];
+    samplers: IAnimationSamplerV2[];
+
+    /** @hidden */
+    _babylonAnimationGroup?: AnimationGroup;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IBufferV2 extends IBuffer, IArrayItemV2 {
+    /** @hidden */
+    _data?: Promise<ArrayBufferView>;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IBufferViewV2 extends IBufferView, IArrayItemV2 {
+    /** @hidden */
+    _data?: Promise<ArrayBufferView>;
+
+    /** @hidden */
+    _babylonBuffer?: Promise<Buffer>;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface ICameraV2 extends ICamera, IArrayItemV2 {
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IImageV2 extends IImage, IArrayItemV2 {
+    /** @hidden */
+    _data?: Promise<ArrayBufferView>;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IMaterialNormalTextureInfoV2 extends IMaterialNormalTextureInfo, ITextureInfo {
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IMaterialOcclusionTextureInfoV2 extends IMaterialOcclusionTextureInfo, ITextureInfo {
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IMaterialPbrMetallicRoughnessV2 extends IMaterialPbrMetallicRoughness {
+    baseColorTexture?: ITextureInfoV2;
+    metallicRoughnessTexture?: ITextureInfoV2;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IMaterialV2 extends IMaterial, IArrayItemV2 {
+    pbrMetallicRoughness?: IMaterialPbrMetallicRoughnessV2;
+    normalTexture?: IMaterialNormalTextureInfoV2;
+    occlusionTexture?: IMaterialOcclusionTextureInfoV2;
+    emissiveTexture?: ITextureInfoV2;
+
+    /** @hidden */
+    _babylonData?: {
+        [drawMode: number]: {
+            material: Material;
+            meshes: AbstractMesh[];
+            promise: Promise<void>;
+        }
+    };
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IMeshV2 extends IMesh, IArrayItemV2 {
+    primitives: IMeshPrimitiveV2[];
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IMeshPrimitiveV2 extends IMeshPrimitive, IArrayItemV2 {
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface INodeV2 extends INode, IArrayItemV2 {
+    /**
+     * The parent glTF node.
+     */
+    parent?: INodeV2;
+
+    /** @hidden */
+    _babylonMesh?: Mesh;
+
+    /** @hidden */
+    _primitiveBabylonMeshes?: Mesh[];
+
+    /** @hidden */
+    _babylonBones?: Bone[];
+
+    /** @hidden */
+    _numMorphTargets?: number;
+}
+
+/** @hidden */
+export interface _ISamplerDataV2 {
+    noMipMaps: boolean;
+    samplingMode: number;
+    wrapU: number;
+    wrapV: number;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface ISamplerV2 extends ISampler, IArrayItemV2 {
+    /** @hidden */
+    _data?: _ISamplerDataV2;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface ISceneV2 extends IScene, IArrayItemV2 {
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface ISkinV2 extends ISkin, IArrayItemV2 {
+    /** @hidden */
+    _babylonSkeleton?: Skeleton;
+
+    /** @hidden */
+    _promise?: Promise<void>;
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface ITextureV2 extends ITexture, IArrayItemV2 {
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface ITextureInfoV2 extends ITextureInfo {
+}
+
+/**
+ * Loader interface with additional members.
+ */
+export interface IGLTFV2 extends IGLTF {
+    accessors?: IAccessorV2[];
+    animations?: IAnimationV2[];
+    buffers?: IBufferV2[];
+    bufferViews?: IBufferViewV2[];
+    cameras?: ICameraV2[];
+    images?: IImageV2[];
+    materials?: IMaterialV2[];
+    meshes?: IMeshV2[];
+    nodes?: INodeV2[];
+    samplers?: ISamplerV2[];
+    scenes?: ISceneV2[];
+    skins?: ISkinV2[];
+    textures?: ITextureV2[];
+}

+ 4 - 0
loaders/src/glTF/2.0/index.ts

@@ -0,0 +1,4 @@
+export * from "./glTFLoader";
+export * from "./glTFLoaderExtension";
+//export * from "./glTFLoaderInterfaces";
+export * from "./Extensions";

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

@@ -1,874 +0,0 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
-/// <reference path="../../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts"/>
-
-module BABYLON {
-    /**
-     * Mode that determines the coordinate system to use.
-     */
-    export enum GLTFLoaderCoordinateSystemMode {
-        /**
-         * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
-         */
-        AUTO,
-
-        /**
-         * Sets the useRightHandedSystem flag on the scene.
-         */
-        FORCE_RIGHT_HANDED,
-    }
-
-    /**
-     * Mode that determines what animations will start.
-     */
-    export enum GLTFLoaderAnimationStartMode {
-        /**
-         * No animation will start.
-         */
-        NONE,
-
-        /**
-         * The first animation will start.
-         */
-        FIRST,
-
-        /**
-         * All animations will start.
-         */
-        ALL,
-    }
-
-    /**
-     * Interface that contains the data for the glTF asset.
-     */
-    export interface IGLTFLoaderData {
-        /**
-         * Object that represents the glTF JSON.
-         */
-        json: Object;
-
-        /**
-         * The BIN chunk of a binary glTF.
-         */
-        bin: Nullable<ArrayBufferView>;
-    }
-
-    /**
-     * Interface for extending the loader.
-     */
-    export interface IGLTFLoaderExtension {
-        /**
-         * The name of this extension.
-         */
-        readonly name: string;
-
-        /**
-         * Defines whether this extension is enabled.
-         */
-        enabled: boolean;
-    }
-
-    /**
-     * Loader state.
-     */
-    export enum GLTFLoaderState {
-        /**
-         * The asset is loading.
-         */
-        LOADING,
-
-        /**
-         * The asset is ready for rendering.
-         */
-        READY,
-
-        /**
-         * The asset is completely loaded.
-         */
-        COMPLETE
-    }
-
-    /** @hidden */
-    export interface IGLTFLoader extends IDisposable {
-        readonly state: Nullable<GLTFLoaderState>;
-        importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string) => Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }>;
-        loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string) => Promise<void>;
-    }
-
-    /**
-     * File loader for loading glTF files into a scene.
-     */
-    export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
-        /** @hidden */
-        public static _CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
-
-        /** @hidden */
-        public static _CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
-
-        // --------------
-        // Common options
-        // --------------
-
-        /**
-         * Raised when the asset has been parsed
-         */
-        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);
-            }
-            this._onParsedObserver = this.onParsedObservable.add(callback);
-        }
-
-        // ----------
-        // 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.
-         * @hidden
-         */
-        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.
-         * @hidden
-         */
-        public static HomogeneousCoordinates = false;
-
-        // ----------
-        // V2 options
-        // ----------
-
-        /**
-         * The coordinate system mode. Defaults to AUTO.
-         */
-        public coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
-
-        /**
-        * The animation start mode. Defaults to FIRST.
-        */
-        public animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
-
-        /**
-         * Defines if the loader should compile materials before raising the success callback. Defaults to false.
-         */
-        public compileMaterials = false;
-
-        /**
-         * Defines if the loader should also compile materials with clip planes. Defaults to false.
-         */
-        public useClipPlane = false;
-
-        /**
-         * Defines if the loader should compile shadow generators before raising the success callback. Defaults to false.
-         */
-        public compileShadowGenerators = false;
-
-        /**
-         * Defines if the Alpha blended materials are only applied as coverage.
-         * If false, (default) The luminance of each pixel will reduce its opacity to simulate the behaviour of most physical materials.
-         * If true, no extra effects are applied to transparent pixels.
-         */
-        public transparencyAsCoverage = false;
-
-        /**
-         * Function called before loading a url referenced by the asset.
-         */
-        public preprocessUrlAsync = (url: string) => Promise.resolve(url);
-
-        /**
-         * Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
-         */
-        public readonly onMeshLoadedObservable = new Observable<AbstractMesh>();
-
-        private _onMeshLoadedObserver: Nullable<Observer<AbstractMesh>>;
-
-        /**
-         * Callback raised when the loader creates a mesh after parsing the glTF properties of the mesh.
-         */
-        public set onMeshLoaded(callback: (mesh: AbstractMesh) => void) {
-            if (this._onMeshLoadedObserver) {
-                this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver);
-            }
-            this._onMeshLoadedObserver = this.onMeshLoadedObservable.add(callback);
-        }
-
-        /**
-         * Observable raised when the loader creates a texture after parsing the glTF properties of the texture.
-         */
-        public readonly onTextureLoadedObservable = new Observable<BaseTexture>();
-
-        private _onTextureLoadedObserver: Nullable<Observer<BaseTexture>>;
-
-        /**
-         * Callback raised when the loader creates a texture after parsing the glTF properties of the texture.
-         */
-        public set onTextureLoaded(callback: (texture: BaseTexture) => void) {
-            if (this._onTextureLoadedObserver) {
-                this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver);
-            }
-            this._onTextureLoadedObserver = this.onTextureLoadedObservable.add(callback);
-        }
-
-        /**
-         * Observable raised when the loader creates a material after parsing the glTF properties of the material.
-         */
-        public readonly onMaterialLoadedObservable = new Observable<Material>();
-
-        private _onMaterialLoadedObserver: Nullable<Observer<Material>>;
-
-        /**
-         * Callback raised when the loader creates a material after parsing the glTF properties of the material.
-         */
-        public set onMaterialLoaded(callback: (material: Material) => void) {
-            if (this._onMaterialLoadedObserver) {
-                this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver);
-            }
-            this._onMaterialLoadedObserver = this.onMaterialLoadedObservable.add(callback);
-        }
-
-        /**
-         * Observable raised when the loader creates a camera after parsing the glTF properties of the camera.
-         */
-        public readonly onCameraLoadedObservable = new Observable<Camera>();
-
-        private _onCameraLoadedObserver: Nullable<Observer<Camera>>;
-
-        /**
-         * Callback raised when the loader creates a camera after parsing the glTF properties of the camera.
-         */
-        public set onCameraLoaded(callback: (camera: Camera) => void) {
-            if (this._onCameraLoadedObserver) {
-                this.onCameraLoadedObservable.remove(this._onCameraLoadedObserver);
-            }
-            this._onCameraLoadedObserver = this.onCameraLoadedObservable.add(callback);
-        }
-
-        /**
-         * Observable raised when the asset is completely loaded, immediately before the loader is disposed.
-         * For assets with LODs, raised when all of the LODs are complete.
-         * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise.
-         */
-        public readonly onCompleteObservable = new Observable<void>();
-
-        private _onCompleteObserver: Nullable<Observer<void>>;
-
-        /**
-         * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
-         * For assets with LODs, raised when all of the LODs are complete.
-         * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise.
-         */
-        public set onComplete(callback: () => void) {
-            if (this._onCompleteObserver) {
-                this.onCompleteObservable.remove(this._onCompleteObserver);
-            }
-            this._onCompleteObserver = this.onCompleteObservable.add(callback);
-        }
-
-        /**
-         * Observable raised when an error occurs.
-         */
-        public readonly onErrorObservable = new Observable<any>();
-
-        private _onErrorObserver: Nullable<Observer<any>>;
-
-        /**
-         * Callback raised when an error occurs.
-         */
-        public set onError(callback: (reason: any) => void) {
-            if (this._onErrorObserver) {
-                this.onErrorObservable.remove(this._onErrorObserver);
-            }
-            this._onErrorObserver = this.onErrorObservable.add(callback);
-        }
-
-        /**
-         * Observable raised after the loader is disposed.
-         */
-        public readonly onDisposeObservable = new Observable<void>();
-
-        private _onDisposeObserver: Nullable<Observer<void>>;
-
-        /**
-         * Callback raised after the loader is disposed.
-         */
-        public set onDispose(callback: () => void) {
-            if (this._onDisposeObserver) {
-                this.onDisposeObservable.remove(this._onDisposeObserver);
-            }
-            this._onDisposeObserver = this.onDisposeObservable.add(callback);
-        }
-
-        /**
-         * Observable raised after a loader extension is created.
-         * Set additional options for a loader extension in this event.
-         */
-        public readonly onExtensionLoadedObservable = new Observable<IGLTFLoaderExtension>();
-
-        private _onExtensionLoadedObserver: Nullable<Observer<IGLTFLoaderExtension>>;
-
-        /**
-         * Callback raised after a loader extension is created.
-         */
-        public set onExtensionLoaded(callback: (extension: IGLTFLoaderExtension) => void) {
-            if (this._onExtensionLoadedObserver) {
-                this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
-            }
-            this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
-        }
-
-        /**
-         * Defines if the loader logging is enabled.
-         */
-        public get loggingEnabled(): boolean {
-            return this._loggingEnabled;
-        }
-
-        public set loggingEnabled(value: boolean) {
-            if (this._loggingEnabled === value) {
-                return;
-            }
-
-            this._loggingEnabled = value;
-
-            if (this._loggingEnabled) {
-                this._log = this._logEnabled;
-            }
-            else {
-                this._log = this._logDisabled;
-            }
-        }
-
-        /**
-         * Defines if the loader should capture performance counters.
-         */
-        public get capturePerformanceCounters(): boolean {
-            return this._capturePerformanceCounters;
-        }
-
-        public set capturePerformanceCounters(value: boolean) {
-            if (this._capturePerformanceCounters === value) {
-                return;
-            }
-
-            this._capturePerformanceCounters = value;
-
-            if (this._capturePerformanceCounters) {
-                this._startPerformanceCounter = this._startPerformanceCounterEnabled;
-                this._endPerformanceCounter = this._endPerformanceCounterEnabled;
-            }
-            else {
-                this._startPerformanceCounter = this._startPerformanceCounterDisabled;
-                this._endPerformanceCounter = this._endPerformanceCounterDisabled;
-            }
-        }
-
-        /**
-         * Defines if the loader should validate the asset.
-         */
-        public validate = false;
-
-        /**
-         * Observable raised after validation when validate is set to true. The event data is the result of the validation.
-         */
-        public readonly onValidatedObservable = new Observable<IGLTFValidationResults>();
-
-        private _onValidatedObserver: Nullable<Observer<IGLTFValidationResults>>;
-
-        /**
-         * Callback raised after a loader extension is created.
-         */
-        public set onValidated(callback: (results: IGLTFValidationResults) => void) {
-            if (this._onValidatedObserver) {
-                this.onValidatedObservable.remove(this._onValidatedObserver);
-            }
-            this._onValidatedObserver = this.onValidatedObservable.add(callback);
-        }
-
-        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 }
-        };
-
-        /**
-         * Disposes the loader, releases resources during load, and cancels any outstanding requests.
-         */
-        public dispose(): void {
-            if (this._loader) {
-                this._loader.dispose();
-                this._loader = null;
-            }
-
-            this._clear();
-
-            this.onDisposeObservable.notifyObservers(undefined);
-            this.onDisposeObservable.clear();
-        }
-
-        /** @hidden */
-        public _clear(): void {
-            this.preprocessUrlAsync = (url) => Promise.resolve(url);
-
-            this.onMeshLoadedObservable.clear();
-            this.onTextureLoadedObservable.clear();
-            this.onMaterialLoadedObservable.clear();
-            this.onCameraLoadedObservable.clear();
-            this.onCompleteObservable.clear();
-            this.onExtensionLoadedObservable.clear();
-        }
-
-        /**
-         * Imports one or more meshes from the loaded glTF data 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 the glTF data to load
-         * @param rootUrl root url to load from
-         * @param onProgress event that fires when loading progress has occured
-         * @param fileName Defines the name of the file to load
-         * @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, fileName?: string): Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
-            return this._parseAsync(scene, data, rootUrl, fileName).then((loaderData) => {
-                this._log(`Loading ${fileName || ""}`);
-                this._loader = this._getLoader(loaderData);
-                return this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onProgress, fileName);
-            });
-        }
-
-        /**
-         * Imports all objects from the loaded glTF data and adds them to the scene
-         * @param scene the scene the objects should be added to
-         * @param data the glTF data to load
-         * @param rootUrl root url to load from
-         * @param onProgress event that fires when loading progress has occured
-         * @param fileName Defines the name of the file to load
-         * @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, fileName?: string): Promise<void> {
-            return this._parseAsync(scene, data, rootUrl, fileName).then((loaderData) => {
-                this._log(`Loading ${fileName || ""}`);
-                this._loader = this._getLoader(loaderData);
-                return this._loader.loadAsync(scene, loaderData, rootUrl, onProgress, fileName);
-            });
-        }
-
-        /**
-         * 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
-         * @param fileName Defines the name of the file to load
-         * @returns The loaded asset container
-         */
-        public loadAssetContainerAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string): Promise<AssetContainer> {
-            return this._parseAsync(scene, data, rootUrl, fileName).then((loaderData) => {
-                this._log(`Loading ${fileName || ""}`);
-                this._loader = this._getLoader(loaderData);
-                return this._loader.importMeshAsync(null, scene, loaderData, rootUrl, onProgress, fileName).then((result) => {
-                    const container = new AssetContainer(scene);
-                    Array.prototype.push.apply(container.meshes, result.meshes);
-                    Array.prototype.push.apply(container.particleSystems, result.particleSystems);
-                    Array.prototype.push.apply(container.skeletons, result.skeletons);
-                    Array.prototype.push.apply(container.animationGroups, result.animationGroups);
-                    container.removeAllFromScene();
-                    return container;
-                });
-            });
-        }
-
-        /**
-         * 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();
-        }
-
-        /**
-         * The loader state or null if the loader is not active.
-         */
-        public get loaderState(): Nullable<GLTFLoaderState> {
-            return this._loader ? this._loader.state : null;
-        }
-
-        /**
-         * Returns a promise that resolves when the asset is completely loaded.
-         * @returns a promise that resolves when the asset is completely loaded.
-         */
-        public whenCompleteAsync(): Promise<void> {
-            return new Promise((resolve, reject) => {
-                this.onCompleteObservable.addOnce(() => {
-                    resolve();
-                });
-                this.onErrorObservable.addOnce((reason) => {
-                    reject(reason);
-                });
-            });
-        }
-
-        private _parseAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, fileName?: string): Promise<IGLTFLoaderData> {
-            return Promise.resolve().then(() => {
-                const unpacked = (data instanceof ArrayBuffer) ? this._unpackBinary(data) : { json: data, bin: null };
-
-                return this._validateAsync(scene, unpacked.json, rootUrl, fileName).then(() => {
-                    this._startPerformanceCounter("Parse JSON");
-                    this._log(`JSON length: ${unpacked.json.length}`);
-
-                    const loaderData: IGLTFLoaderData = {
-                        json: JSON.parse(unpacked.json),
-                        bin: unpacked.bin
-                    };
-
-                    this._endPerformanceCounter("Parse JSON");
-
-                    this.onParsedObservable.notifyObservers(loaderData);
-                    this.onParsedObservable.clear();
-
-                    return loaderData;
-                });
-            });
-        }
-
-        private _validateAsync(scene: Scene, json: string, rootUrl: string, fileName?: string): Promise<void> {
-            if (!this.validate || typeof GLTFValidator === "undefined") {
-                return Promise.resolve();
-            }
-
-            this._startPerformanceCounter("Validate JSON");
-
-            const options: IGLTFValidationOptions = {
-                externalResourceFunction: (uri) => {
-                    return this.preprocessUrlAsync(rootUrl + uri)
-                        .then((url) => scene._loadFileAsync(url, true, true))
-                        .then((data) => new Uint8Array(data as ArrayBuffer));
-                }
-            };
-
-            if (fileName && fileName.substr(0, 5) !== "data:") {
-                options.uri = (rootUrl === "file:" ? fileName : `${rootUrl}${fileName}`);
-            }
-
-            return GLTFValidator.validateString(json, options).then((result) => {
-                this._endPerformanceCounter("Validate JSON");
-
-                this.onValidatedObservable.notifyObservers(result);
-                this.onValidatedObservable.clear();
-            });
-        }
-
-        private _getLoader(loaderData: IGLTFLoaderData): IGLTFLoader {
-            const asset = (<any>loaderData.json).asset || {};
-
-            this._log(`Asset version: ${asset.version}`);
-            asset.minVersion && this._log(`Asset minimum version: ${asset.minVersion}`);
-            asset.generator && this._log(`Asset generator: ${asset.generator}`);
-
-            const version = GLTFFileLoader._parseVersion(asset.version);
-            if (!version) {
-                throw new Error("Invalid version: " + asset.version);
-            }
-
-            if (asset.minVersion !== undefined) {
-                const minVersion = GLTFFileLoader._parseVersion(asset.minVersion);
-                if (!minVersion) {
-                    throw new Error("Invalid minimum version: " + asset.minVersion);
-                }
-
-                if (GLTFFileLoader._compareVersion(minVersion, { major: 2, minor: 0 }) > 0) {
-                    throw new Error("Incompatible minimum version: " + asset.minVersion);
-                }
-            }
-
-            const createLoaders: { [key: number]: (parent: GLTFFileLoader) => IGLTFLoader } = {
-                1: GLTFFileLoader._CreateGLTFLoaderV1,
-                2: GLTFFileLoader._CreateGLTFLoaderV2
-            };
-
-            const createLoader = createLoaders[version.major];
-            if (!createLoader) {
-                throw new Error("Unsupported version: " + asset.version);
-            }
-
-            return createLoader(this);
-        }
-
-        private _unpackBinary(data: ArrayBuffer): { json: string, bin: Nullable<ArrayBufferView> } {
-            this._startPerformanceCounter("Unpack binary");
-            this._log(`Binary length: ${data.byteLength}`);
-
-            const Binary = {
-                Magic: 0x46546C67
-            };
-
-            const binaryReader = new BinaryReader(data);
-
-            const magic = binaryReader.readUint32();
-            if (magic !== Binary.Magic) {
-                throw new Error("Unexpected magic: " + magic);
-            }
-
-            const version = binaryReader.readUint32();
-
-            if (this.loggingEnabled) {
-                this._log(`Binary version: ${version}`);
-            }
-
-            let unpacked: { json: string, bin: Nullable<ArrayBufferView> };
-            switch (version) {
-                case 1: {
-                    unpacked = this._unpackBinaryV1(binaryReader);
-                    break;
-                }
-                case 2: {
-                    unpacked = this._unpackBinaryV2(binaryReader);
-                    break;
-                }
-                default: {
-                    throw new Error("Unsupported version: " + version);
-                }
-            }
-
-            this._endPerformanceCounter("Unpack binary");
-            return unpacked;
-        }
-
-        private _unpackBinaryV1(binaryReader: BinaryReader): { json: string, bin: Nullable<ArrayBufferView> } {
-            const ContentFormat = {
-                JSON: 0
-            };
-
-            const length = binaryReader.readUint32();
-            if (length != binaryReader.getLength()) {
-                throw new Error("Length in header does not match actual data length: " + length + " != " + binaryReader.getLength());
-            }
-
-            const contentLength = binaryReader.readUint32();
-            const contentFormat = binaryReader.readUint32();
-
-            let content: string;
-            switch (contentFormat) {
-                case ContentFormat.JSON: {
-                    content = GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(contentLength));
-                    break;
-                }
-                default: {
-                    throw new Error("Unexpected content format: " + contentFormat);
-                }
-            }
-
-            const bytesRemaining = binaryReader.getLength() - binaryReader.getPosition();
-            const body = binaryReader.readUint8Array(bytesRemaining);
-
-            return {
-                json: content,
-                bin: body
-            };
-        }
-
-        private _unpackBinaryV2(binaryReader: BinaryReader): { json: string, bin: Nullable<ArrayBufferView> } {
-            const ChunkFormat = {
-                JSON: 0x4E4F534A,
-                BIN: 0x004E4942
-            };
-
-            const length = binaryReader.readUint32();
-            if (length !== binaryReader.getLength()) {
-                throw new Error("Length in header does not match actual data length: " + length + " != " + binaryReader.getLength());
-            }
-
-            // JSON chunk
-            const chunkLength = binaryReader.readUint32();
-            const chunkFormat = binaryReader.readUint32();
-            if (chunkFormat !== ChunkFormat.JSON) {
-                throw new Error("First chunk format is not JSON");
-            }
-            const json = GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(chunkLength));
-
-            // Look for BIN chunk
-            let bin: Nullable<Uint8Array> = null;
-            while (binaryReader.getPosition() < binaryReader.getLength()) {
-                const chunkLength = binaryReader.readUint32();
-                const chunkFormat = binaryReader.readUint32();
-                switch (chunkFormat) {
-                    case ChunkFormat.JSON: {
-                        throw new Error("Unexpected JSON chunk");
-                    }
-                    case ChunkFormat.BIN: {
-                        bin = binaryReader.readUint8Array(chunkLength);
-                        break;
-                    }
-                    default: {
-                        // ignore unrecognized chunkFormat
-                        binaryReader.skipBytes(chunkLength);
-                        break;
-                    }
-                }
-            }
-
-            return {
-                json: json,
-                bin: bin
-            };
-        }
-
-        private static _parseVersion(version: string): Nullable<{ major: number, minor: number }> {
-            if (version === "1.0" || version === "1.0.1") {
-                return {
-                    major: 1,
-                    minor: 0
-                };
-            }
-
-            const match = (version + "").match(/^(\d+)\.(\d+)/);
-            if (!match) {
-                return null;
-            }
-
-            return {
-                major: parseInt(match[1]),
-                minor: parseInt(match[2])
-            };
-        }
-
-        private static _compareVersion(a: { major: number, minor: number }, b: { major: number, minor: number }): number {
-            if (a.major > b.major) { return 1; }
-            if (a.major < b.major) { return -1; }
-            if (a.minor > b.minor) { return 1; }
-            if (a.minor < b.minor) { return -1; }
-            return 0;
-        }
-
-        private static _decodeBufferToText(buffer: Uint8Array): string {
-            let result = "";
-            const length = buffer.byteLength;
-
-            for (let i = 0; i < length; i++) {
-                result += String.fromCharCode(buffer[i]);
-            }
-
-            return result;
-        }
-
-        private static readonly _logSpaces = "                                ";
-        private _logIndentLevel = 0;
-        private _loggingEnabled = false;
-
-        /** @hidden */
-        public _log = this._logDisabled;
-
-        /** @hidden */
-        public _logOpen(message: string): void {
-            this._log(message);
-            this._logIndentLevel++;
-        }
-
-        /** @hidden */
-        public _logClose(): void {
-            --this._logIndentLevel;
-        }
-
-        private _logEnabled(message: string): void {
-            const spaces = GLTFFileLoader._logSpaces.substr(0, this._logIndentLevel * 2);
-            Tools.Log(`${spaces}${message}`);
-        }
-
-        private _logDisabled(message: string): void {
-        }
-
-        private _capturePerformanceCounters = false;
-
-        /** @hidden */
-        public _startPerformanceCounter = this._startPerformanceCounterDisabled;
-
-        /** @hidden */
-        public _endPerformanceCounter = this._endPerformanceCounterDisabled;
-
-        private _startPerformanceCounterEnabled(counterName: string): void {
-            Tools.StartPerformanceCounter(counterName);
-        }
-
-        private _startPerformanceCounterDisabled(counterName: string): void {
-        }
-
-        private _endPerformanceCounterEnabled(counterName: string): void {
-            Tools.EndPerformanceCounter(counterName);
-        }
-
-        private _endPerformanceCounterDisabled(counterName: string): void {
-        }
-    }
-
-    class BinaryReader {
-        private _arrayBuffer: ArrayBuffer;
-        private _dataView: DataView;
-        private _byteOffset: number;
-
-        constructor(arrayBuffer: ArrayBuffer) {
-            this._arrayBuffer = arrayBuffer;
-            this._dataView = new DataView(arrayBuffer);
-            this._byteOffset = 0;
-        }
-
-        public getPosition(): number {
-            return this._byteOffset;
-        }
-
-        public getLength(): number {
-            return this._arrayBuffer.byteLength;
-        }
-
-        public readUint32(): number {
-            const value = this._dataView.getUint32(this._byteOffset, true);
-            this._byteOffset += 4;
-            return value;
-        }
-
-        public readUint8Array(length: number): Uint8Array {
-            const value = new Uint8Array(this._arrayBuffer, this._byteOffset, length);
-            this._byteOffset += length;
-            return value;
-        }
-
-        public skipBytes(length: number): void {
-            this._byteOffset += length;
-        }
-    }
-
-    if (BABYLON.SceneLoader) {
-        BABYLON.SceneLoader.RegisterPlugin(new GLTFFileLoader());
-    }
-}

+ 879 - 0
loaders/src/glTF/glTFFileLoader.ts

@@ -0,0 +1,879 @@
+import { IDisposable, Nullable, Scene, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory, Observable, Observer, SceneLoaderProgressEvent, AbstractMesh, IParticleSystem, Skeleton, AnimationGroup, BaseTexture, Material, Camera, ISceneLoaderPluginExtensions, ISceneLoaderPlugin, AssetContainer, Tools, SceneLoader } from "babylonjs";
+import { IGLTFValidationResults, IGLTFValidationOptions } from "babylonjs-gltf2interface";
+
+/**
+ * glTF validator object
+ */
+declare var GLTFValidator: {
+    validateString: (json: string, options?: IGLTFValidationOptions) => Promise<IGLTFValidationResults>;
+};
+
+/**
+ * Mode that determines the coordinate system to use.
+ */
+export enum GLTFLoaderCoordinateSystemMode {
+    /**
+     * Automatically convert the glTF right-handed data to the appropriate system based on the current coordinate system mode of the scene.
+     */
+    AUTO,
+
+    /**
+     * Sets the useRightHandedSystem flag on the scene.
+     */
+    FORCE_RIGHT_HANDED,
+}
+
+/**
+ * Mode that determines what animations will start.
+ */
+export enum GLTFLoaderAnimationStartMode {
+    /**
+     * No animation will start.
+     */
+    NONE,
+
+    /**
+     * The first animation will start.
+     */
+    FIRST,
+
+    /**
+     * All animations will start.
+     */
+    ALL,
+}
+
+/**
+ * Interface that contains the data for the glTF asset.
+ */
+export interface IGLTFLoaderData {
+    /**
+     * Object that represents the glTF JSON.
+     */
+    json: Object;
+
+    /**
+     * The BIN chunk of a binary glTF.
+     */
+    bin: Nullable<ArrayBufferView>;
+}
+
+/**
+ * Interface for extending the loader.
+ */
+export interface IGLTFLoaderExtension {
+    /**
+     * The name of this extension.
+     */
+    readonly name: string;
+
+    /**
+     * Defines whether this extension is enabled.
+     */
+    enabled: boolean;
+}
+
+/**
+ * Loader state.
+ */
+export enum GLTFLoaderState {
+    /**
+     * The asset is loading.
+     */
+    LOADING,
+
+    /**
+     * The asset is ready for rendering.
+     */
+    READY,
+
+    /**
+     * The asset is completely loaded.
+     */
+    COMPLETE
+}
+
+/** @hidden */
+export interface IGLTFLoader extends IDisposable {
+    readonly state: Nullable<GLTFLoaderState>;
+    importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string) => Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }>;
+    loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string) => Promise<void>;
+}
+
+/**
+ * File loader for loading glTF files into a scene.
+ */
+export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
+    /** @hidden */
+    public static _CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
+
+    /** @hidden */
+    public static _CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
+
+    // --------------
+    // Common options
+    // --------------
+
+    /**
+     * Raised when the asset has been parsed
+     */
+    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);
+        }
+        this._onParsedObserver = this.onParsedObservable.add(callback);
+    }
+
+    // ----------
+    // 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.
+     * @hidden
+     */
+    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.
+     * @hidden
+     */
+    public static HomogeneousCoordinates = false;
+
+    // ----------
+    // V2 options
+    // ----------
+
+    /**
+     * The coordinate system mode. Defaults to AUTO.
+     */
+    public coordinateSystemMode = GLTFLoaderCoordinateSystemMode.AUTO;
+
+    /**
+    * The animation start mode. Defaults to FIRST.
+    */
+    public animationStartMode = GLTFLoaderAnimationStartMode.FIRST;
+
+    /**
+     * Defines if the loader should compile materials before raising the success callback. Defaults to false.
+     */
+    public compileMaterials = false;
+
+    /**
+     * Defines if the loader should also compile materials with clip planes. Defaults to false.
+     */
+    public useClipPlane = false;
+
+    /**
+     * Defines if the loader should compile shadow generators before raising the success callback. Defaults to false.
+     */
+    public compileShadowGenerators = false;
+
+    /**
+     * Defines if the Alpha blended materials are only applied as coverage.
+     * If false, (default) The luminance of each pixel will reduce its opacity to simulate the behaviour of most physical materials.
+     * If true, no extra effects are applied to transparent pixels.
+     */
+    public transparencyAsCoverage = false;
+
+    /**
+     * Function called before loading a url referenced by the asset.
+     */
+    public preprocessUrlAsync = (url: string) => Promise.resolve(url);
+
+    /**
+     * Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
+     */
+    public readonly onMeshLoadedObservable = new Observable<AbstractMesh>();
+
+    private _onMeshLoadedObserver: Nullable<Observer<AbstractMesh>>;
+
+    /**
+     * Callback raised when the loader creates a mesh after parsing the glTF properties of the mesh.
+     */
+    public set onMeshLoaded(callback: (mesh: AbstractMesh) => void) {
+        if (this._onMeshLoadedObserver) {
+            this.onMeshLoadedObservable.remove(this._onMeshLoadedObserver);
+        }
+        this._onMeshLoadedObserver = this.onMeshLoadedObservable.add(callback);
+    }
+
+    /**
+     * Observable raised when the loader creates a texture after parsing the glTF properties of the texture.
+     */
+    public readonly onTextureLoadedObservable = new Observable<BaseTexture>();
+
+    private _onTextureLoadedObserver: Nullable<Observer<BaseTexture>>;
+
+    /**
+     * Callback raised when the loader creates a texture after parsing the glTF properties of the texture.
+     */
+    public set onTextureLoaded(callback: (texture: BaseTexture) => void) {
+        if (this._onTextureLoadedObserver) {
+            this.onTextureLoadedObservable.remove(this._onTextureLoadedObserver);
+        }
+        this._onTextureLoadedObserver = this.onTextureLoadedObservable.add(callback);
+    }
+
+    /**
+     * Observable raised when the loader creates a material after parsing the glTF properties of the material.
+     */
+    public readonly onMaterialLoadedObservable = new Observable<Material>();
+
+    private _onMaterialLoadedObserver: Nullable<Observer<Material>>;
+
+    /**
+     * Callback raised when the loader creates a material after parsing the glTF properties of the material.
+     */
+    public set onMaterialLoaded(callback: (material: Material) => void) {
+        if (this._onMaterialLoadedObserver) {
+            this.onMaterialLoadedObservable.remove(this._onMaterialLoadedObserver);
+        }
+        this._onMaterialLoadedObserver = this.onMaterialLoadedObservable.add(callback);
+    }
+
+    /**
+     * Observable raised when the loader creates a camera after parsing the glTF properties of the camera.
+     */
+    public readonly onCameraLoadedObservable = new Observable<Camera>();
+
+    private _onCameraLoadedObserver: Nullable<Observer<Camera>>;
+
+    /**
+     * Callback raised when the loader creates a camera after parsing the glTF properties of the camera.
+     */
+    public set onCameraLoaded(callback: (camera: Camera) => void) {
+        if (this._onCameraLoadedObserver) {
+            this.onCameraLoadedObservable.remove(this._onCameraLoadedObserver);
+        }
+        this._onCameraLoadedObserver = this.onCameraLoadedObservable.add(callback);
+    }
+
+    /**
+     * Observable raised when the asset is completely loaded, immediately before the loader is disposed.
+     * For assets with LODs, raised when all of the LODs are complete.
+     * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise.
+     */
+    public readonly onCompleteObservable = new Observable<void>();
+
+    private _onCompleteObserver: Nullable<Observer<void>>;
+
+    /**
+     * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
+     * For assets with LODs, raised when all of the LODs are complete.
+     * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise.
+     */
+    public set onComplete(callback: () => void) {
+        if (this._onCompleteObserver) {
+            this.onCompleteObservable.remove(this._onCompleteObserver);
+        }
+        this._onCompleteObserver = this.onCompleteObservable.add(callback);
+    }
+
+    /**
+     * Observable raised when an error occurs.
+     */
+    public readonly onErrorObservable = new Observable<any>();
+
+    private _onErrorObserver: Nullable<Observer<any>>;
+
+    /**
+     * Callback raised when an error occurs.
+     */
+    public set onError(callback: (reason: any) => void) {
+        if (this._onErrorObserver) {
+            this.onErrorObservable.remove(this._onErrorObserver);
+        }
+        this._onErrorObserver = this.onErrorObservable.add(callback);
+    }
+
+    /**
+     * Observable raised after the loader is disposed.
+     */
+    public readonly onDisposeObservable = new Observable<void>();
+
+    private _onDisposeObserver: Nullable<Observer<void>>;
+
+    /**
+     * Callback raised after the loader is disposed.
+     */
+    public set onDispose(callback: () => void) {
+        if (this._onDisposeObserver) {
+            this.onDisposeObservable.remove(this._onDisposeObserver);
+        }
+        this._onDisposeObserver = this.onDisposeObservable.add(callback);
+    }
+
+    /**
+     * Observable raised after a loader extension is created.
+     * Set additional options for a loader extension in this event.
+     */
+    public readonly onExtensionLoadedObservable = new Observable<IGLTFLoaderExtension>();
+
+    private _onExtensionLoadedObserver: Nullable<Observer<IGLTFLoaderExtension>>;
+
+    /**
+     * Callback raised after a loader extension is created.
+     */
+    public set onExtensionLoaded(callback: (extension: IGLTFLoaderExtension) => void) {
+        if (this._onExtensionLoadedObserver) {
+            this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
+        }
+        this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
+    }
+
+    /**
+     * Defines if the loader logging is enabled.
+     */
+    public get loggingEnabled(): boolean {
+        return this._loggingEnabled;
+    }
+
+    public set loggingEnabled(value: boolean) {
+        if (this._loggingEnabled === value) {
+            return;
+        }
+
+        this._loggingEnabled = value;
+
+        if (this._loggingEnabled) {
+            this._log = this._logEnabled;
+        }
+        else {
+            this._log = this._logDisabled;
+        }
+    }
+
+    /**
+     * Defines if the loader should capture performance counters.
+     */
+    public get capturePerformanceCounters(): boolean {
+        return this._capturePerformanceCounters;
+    }
+
+    public set capturePerformanceCounters(value: boolean) {
+        if (this._capturePerformanceCounters === value) {
+            return;
+        }
+
+        this._capturePerformanceCounters = value;
+
+        if (this._capturePerformanceCounters) {
+            this._startPerformanceCounter = this._startPerformanceCounterEnabled;
+            this._endPerformanceCounter = this._endPerformanceCounterEnabled;
+        }
+        else {
+            this._startPerformanceCounter = this._startPerformanceCounterDisabled;
+            this._endPerformanceCounter = this._endPerformanceCounterDisabled;
+        }
+    }
+
+    /**
+     * Defines if the loader should validate the asset.
+     */
+    public validate = false;
+
+    /**
+     * Observable raised after validation when validate is set to true. The event data is the result of the validation.
+     */
+    public readonly onValidatedObservable = new Observable<IGLTFValidationResults>();
+
+    private _onValidatedObserver: Nullable<Observer<IGLTFValidationResults>>;
+
+    /**
+     * Callback raised after a loader extension is created.
+     */
+    public set onValidated(callback: (results: IGLTFValidationResults) => void) {
+        if (this._onValidatedObserver) {
+            this.onValidatedObservable.remove(this._onValidatedObserver);
+        }
+        this._onValidatedObserver = this.onValidatedObservable.add(callback);
+    }
+
+    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 }
+    };
+
+    /**
+     * Disposes the loader, releases resources during load, and cancels any outstanding requests.
+     */
+    public dispose(): void {
+        if (this._loader) {
+            this._loader.dispose();
+            this._loader = null;
+        }
+
+        this._clear();
+
+        this.onDisposeObservable.notifyObservers(undefined);
+        this.onDisposeObservable.clear();
+    }
+
+    /** @hidden */
+    public _clear(): void {
+        this.preprocessUrlAsync = (url) => Promise.resolve(url);
+
+        this.onMeshLoadedObservable.clear();
+        this.onTextureLoadedObservable.clear();
+        this.onMaterialLoadedObservable.clear();
+        this.onCameraLoadedObservable.clear();
+        this.onCompleteObservable.clear();
+        this.onExtensionLoadedObservable.clear();
+    }
+
+    /**
+     * Imports one or more meshes from the loaded glTF data 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 the glTF data to load
+     * @param rootUrl root url to load from
+     * @param onProgress event that fires when loading progress has occured
+     * @param fileName Defines the name of the file to load
+     * @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, fileName?: string): Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
+        return this._parseAsync(scene, data, rootUrl, fileName).then((loaderData) => {
+            this._log(`Loading ${fileName || ""}`);
+            this._loader = this._getLoader(loaderData);
+            return this._loader.importMeshAsync(meshesNames, scene, loaderData, rootUrl, onProgress, fileName);
+        });
+    }
+
+    /**
+     * Imports all objects from the loaded glTF data and adds them to the scene
+     * @param scene the scene the objects should be added to
+     * @param data the glTF data to load
+     * @param rootUrl root url to load from
+     * @param onProgress event that fires when loading progress has occured
+     * @param fileName Defines the name of the file to load
+     * @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, fileName?: string): Promise<void> {
+        return this._parseAsync(scene, data, rootUrl, fileName).then((loaderData) => {
+            this._log(`Loading ${fileName || ""}`);
+            this._loader = this._getLoader(loaderData);
+            return this._loader.loadAsync(scene, loaderData, rootUrl, onProgress, fileName);
+        });
+    }
+
+    /**
+     * 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
+     * @param fileName Defines the name of the file to load
+     * @returns The loaded asset container
+     */
+    public loadAssetContainerAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string): Promise<AssetContainer> {
+        return this._parseAsync(scene, data, rootUrl, fileName).then((loaderData) => {
+            this._log(`Loading ${fileName || ""}`);
+            this._loader = this._getLoader(loaderData);
+            return this._loader.importMeshAsync(null, scene, loaderData, rootUrl, onProgress, fileName).then((result) => {
+                const container = new AssetContainer(scene);
+                Array.prototype.push.apply(container.meshes, result.meshes);
+                Array.prototype.push.apply(container.particleSystems, result.particleSystems);
+                Array.prototype.push.apply(container.skeletons, result.skeletons);
+                Array.prototype.push.apply(container.animationGroups, result.animationGroups);
+                container.removeAllFromScene();
+                return container;
+            });
+        });
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * The loader state or null if the loader is not active.
+     */
+    public get loaderState(): Nullable<GLTFLoaderState> {
+        return this._loader ? this._loader.state : null;
+    }
+
+    /**
+     * Returns a promise that resolves when the asset is completely loaded.
+     * @returns a promise that resolves when the asset is completely loaded.
+     */
+    public whenCompleteAsync(): Promise<void> {
+        return new Promise((resolve, reject) => {
+            this.onCompleteObservable.addOnce(() => {
+                resolve();
+            });
+            this.onErrorObservable.addOnce((reason) => {
+                reject(reason);
+            });
+        });
+    }
+
+    private _parseAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, fileName?: string): Promise<IGLTFLoaderData> {
+        return Promise.resolve().then(() => {
+            const unpacked = (data instanceof ArrayBuffer) ? this._unpackBinary(data) : { json: data, bin: null };
+
+            return this._validateAsync(scene, unpacked.json, rootUrl, fileName).then(() => {
+                this._startPerformanceCounter("Parse JSON");
+                this._log(`JSON length: ${unpacked.json.length}`);
+
+                const loaderData: IGLTFLoaderData = {
+                    json: JSON.parse(unpacked.json),
+                    bin: unpacked.bin
+                };
+
+                this._endPerformanceCounter("Parse JSON");
+
+                this.onParsedObservable.notifyObservers(loaderData);
+                this.onParsedObservable.clear();
+
+                return loaderData;
+            });
+        });
+    }
+
+    private _validateAsync(scene: Scene, json: string, rootUrl: string, fileName?: string): Promise<void> {
+        if (!this.validate || typeof GLTFValidator === "undefined") {
+            return Promise.resolve();
+        }
+
+        this._startPerformanceCounter("Validate JSON");
+
+        const options: IGLTFValidationOptions = {
+            externalResourceFunction: (uri) => {
+                return this.preprocessUrlAsync(rootUrl + uri)
+                    .then((url) => scene._loadFileAsync(url, true, true))
+                    .then((data) => new Uint8Array(data as ArrayBuffer));
+            }
+        };
+
+        if (fileName && fileName.substr(0, 5) !== "data:") {
+            options.uri = (rootUrl === "file:" ? fileName : `${rootUrl}${fileName}`);
+        }
+
+        return GLTFValidator.validateString(json, options).then((result) => {
+            this._endPerformanceCounter("Validate JSON");
+
+            this.onValidatedObservable.notifyObservers(result);
+            this.onValidatedObservable.clear();
+        });
+    }
+
+    private _getLoader(loaderData: IGLTFLoaderData): IGLTFLoader {
+        const asset = (<any>loaderData.json).asset || {};
+
+        this._log(`Asset version: ${asset.version}`);
+        asset.minVersion && this._log(`Asset minimum version: ${asset.minVersion}`);
+        asset.generator && this._log(`Asset generator: ${asset.generator}`);
+
+        const version = GLTFFileLoader._parseVersion(asset.version);
+        if (!version) {
+            throw new Error("Invalid version: " + asset.version);
+        }
+
+        if (asset.minVersion !== undefined) {
+            const minVersion = GLTFFileLoader._parseVersion(asset.minVersion);
+            if (!minVersion) {
+                throw new Error("Invalid minimum version: " + asset.minVersion);
+            }
+
+            if (GLTFFileLoader._compareVersion(minVersion, { major: 2, minor: 0 }) > 0) {
+                throw new Error("Incompatible minimum version: " + asset.minVersion);
+            }
+        }
+
+        const createLoaders: { [key: number]: (parent: GLTFFileLoader) => IGLTFLoader } = {
+            1: GLTFFileLoader._CreateGLTFLoaderV1,
+            2: GLTFFileLoader._CreateGLTFLoaderV2
+        };
+
+        const createLoader = createLoaders[version.major];
+        if (!createLoader) {
+            throw new Error("Unsupported version: " + asset.version);
+        }
+
+        return createLoader(this);
+    }
+
+    private _unpackBinary(data: ArrayBuffer): { json: string, bin: Nullable<ArrayBufferView> } {
+        this._startPerformanceCounter("Unpack binary");
+        this._log(`Binary length: ${data.byteLength}`);
+
+        const Binary = {
+            Magic: 0x46546C67
+        };
+
+        const binaryReader = new BinaryReader(data);
+
+        const magic = binaryReader.readUint32();
+        if (magic !== Binary.Magic) {
+            throw new Error("Unexpected magic: " + magic);
+        }
+
+        const version = binaryReader.readUint32();
+
+        if (this.loggingEnabled) {
+            this._log(`Binary version: ${version}`);
+        }
+
+        let unpacked: { json: string, bin: Nullable<ArrayBufferView> };
+        switch (version) {
+            case 1: {
+                unpacked = this._unpackBinaryV1(binaryReader);
+                break;
+            }
+            case 2: {
+                unpacked = this._unpackBinaryV2(binaryReader);
+                break;
+            }
+            default: {
+                throw new Error("Unsupported version: " + version);
+            }
+        }
+
+        this._endPerformanceCounter("Unpack binary");
+        return unpacked;
+    }
+
+    private _unpackBinaryV1(binaryReader: BinaryReader): { json: string, bin: Nullable<ArrayBufferView> } {
+        const ContentFormat = {
+            JSON: 0
+        };
+
+        const length = binaryReader.readUint32();
+        if (length != binaryReader.getLength()) {
+            throw new Error("Length in header does not match actual data length: " + length + " != " + binaryReader.getLength());
+        }
+
+        const contentLength = binaryReader.readUint32();
+        const contentFormat = binaryReader.readUint32();
+
+        let content: string;
+        switch (contentFormat) {
+            case ContentFormat.JSON: {
+                content = GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(contentLength));
+                break;
+            }
+            default: {
+                throw new Error("Unexpected content format: " + contentFormat);
+            }
+        }
+
+        const bytesRemaining = binaryReader.getLength() - binaryReader.getPosition();
+        const body = binaryReader.readUint8Array(bytesRemaining);
+
+        return {
+            json: content,
+            bin: body
+        };
+    }
+
+    private _unpackBinaryV2(binaryReader: BinaryReader): { json: string, bin: Nullable<ArrayBufferView> } {
+        const ChunkFormat = {
+            JSON: 0x4E4F534A,
+            BIN: 0x004E4942
+        };
+
+        const length = binaryReader.readUint32();
+        if (length !== binaryReader.getLength()) {
+            throw new Error("Length in header does not match actual data length: " + length + " != " + binaryReader.getLength());
+        }
+
+        // JSON chunk
+        const chunkLength = binaryReader.readUint32();
+        const chunkFormat = binaryReader.readUint32();
+        if (chunkFormat !== ChunkFormat.JSON) {
+            throw new Error("First chunk format is not JSON");
+        }
+        const json = GLTFFileLoader._decodeBufferToText(binaryReader.readUint8Array(chunkLength));
+
+        // Look for BIN chunk
+        let bin: Nullable<Uint8Array> = null;
+        while (binaryReader.getPosition() < binaryReader.getLength()) {
+            const chunkLength = binaryReader.readUint32();
+            const chunkFormat = binaryReader.readUint32();
+            switch (chunkFormat) {
+                case ChunkFormat.JSON: {
+                    throw new Error("Unexpected JSON chunk");
+                }
+                case ChunkFormat.BIN: {
+                    bin = binaryReader.readUint8Array(chunkLength);
+                    break;
+                }
+                default: {
+                    // ignore unrecognized chunkFormat
+                    binaryReader.skipBytes(chunkLength);
+                    break;
+                }
+            }
+        }
+
+        return {
+            json: json,
+            bin: bin
+        };
+    }
+
+    private static _parseVersion(version: string): Nullable<{ major: number, minor: number }> {
+        if (version === "1.0" || version === "1.0.1") {
+            return {
+                major: 1,
+                minor: 0
+            };
+        }
+
+        const match = (version + "").match(/^(\d+)\.(\d+)/);
+        if (!match) {
+            return null;
+        }
+
+        return {
+            major: parseInt(match[1]),
+            minor: parseInt(match[2])
+        };
+    }
+
+    private static _compareVersion(a: { major: number, minor: number }, b: { major: number, minor: number }): number {
+        if (a.major > b.major) { return 1; }
+        if (a.major < b.major) { return -1; }
+        if (a.minor > b.minor) { return 1; }
+        if (a.minor < b.minor) { return -1; }
+        return 0;
+    }
+
+    private static _decodeBufferToText(buffer: Uint8Array): string {
+        let result = "";
+        const length = buffer.byteLength;
+
+        for (let i = 0; i < length; i++) {
+            result += String.fromCharCode(buffer[i]);
+        }
+
+        return result;
+    }
+
+    private static readonly _logSpaces = "                                ";
+    private _logIndentLevel = 0;
+    private _loggingEnabled = false;
+
+    /** @hidden */
+    public _log = this._logDisabled;
+
+    /** @hidden */
+    public _logOpen(message: string): void {
+        this._log(message);
+        this._logIndentLevel++;
+    }
+
+    /** @hidden */
+    public _logClose(): void {
+        --this._logIndentLevel;
+    }
+
+    private _logEnabled(message: string): void {
+        const spaces = GLTFFileLoader._logSpaces.substr(0, this._logIndentLevel * 2);
+        Tools.Log(`${spaces}${message}`);
+    }
+
+    private _logDisabled(message: string): void {
+    }
+
+    private _capturePerformanceCounters = false;
+
+    /** @hidden */
+    public _startPerformanceCounter = this._startPerformanceCounterDisabled;
+
+    /** @hidden */
+    public _endPerformanceCounter = this._endPerformanceCounterDisabled;
+
+    private _startPerformanceCounterEnabled(counterName: string): void {
+        Tools.StartPerformanceCounter(counterName);
+    }
+
+    private _startPerformanceCounterDisabled(counterName: string): void {
+    }
+
+    private _endPerformanceCounterEnabled(counterName: string): void {
+        Tools.EndPerformanceCounter(counterName);
+    }
+
+    private _endPerformanceCounterDisabled(counterName: string): void {
+    }
+}
+
+class BinaryReader {
+    private _arrayBuffer: ArrayBuffer;
+    private _dataView: DataView;
+    private _byteOffset: number;
+
+    constructor(arrayBuffer: ArrayBuffer) {
+        this._arrayBuffer = arrayBuffer;
+        this._dataView = new DataView(arrayBuffer);
+        this._byteOffset = 0;
+    }
+
+    public getPosition(): number {
+        return this._byteOffset;
+    }
+
+    public getLength(): number {
+        return this._arrayBuffer.byteLength;
+    }
+
+    public readUint32(): number {
+        const value = this._dataView.getUint32(this._byteOffset, true);
+        this._byteOffset += 4;
+        return value;
+    }
+
+    public readUint8Array(length: number): Uint8Array {
+        const value = new Uint8Array(this._arrayBuffer, this._byteOffset, length);
+        this._byteOffset += length;
+        return value;
+    }
+
+    public skipBytes(length: number): void {
+        this._byteOffset += length;
+    }
+}
+
+if (SceneLoader) {
+    SceneLoader.RegisterPlugin(new GLTFFileLoader());
+}

+ 3 - 0
loaders/src/glTF/index.ts

@@ -0,0 +1,3 @@
+export * from "./glTFFileLoader";
+export * from "./1.0";
+export * from "./2.0";

+ 3 - 0
loaders/src/index.ts

@@ -0,0 +1,3 @@
+export * from "./glTF";
+export * from "./OBJ";
+export * from "./STL";

+ 19 - 0
loaders/src/legacy.ts

@@ -0,0 +1,19 @@
+import * as MatLib from "./index";
+
+/**
+ * Legacy support, defining window.BABYLON.GridMaterial... (global variable).
+ *
+ * This is the entry point for the UMD module.
+ * The entry point for a future ESM package should be index.ts
+ */
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
+if (typeof globalObject !== "undefined") {
+    (<any>globalObject).BABYLON = (<any>globalObject).BABYLON || {};
+    for (var mat in MatLib) {
+        if (MatLib.hasOwnProperty(mat)) {
+            (<any>globalObject).BABYLON[mat] = (<any>MatLib)[mat];
+        }
+    }
+}
+
+export * from "./index";

+ 0 - 15
loaders/src/tsconfig.json

@@ -1,15 +0,0 @@
-{
-  "compileOnSave": true,
-  "compilerOptions": {
-    "experimentalDecorators": true,
-    "module": "commonjs",
-    "target": "es5",
-    "sourceMap": true,
-    "lib": ["dom", "es2015.promise", "es5"],
-    "noImplicitAny": true,
-    "noImplicitReturns": true,
-    "noImplicitThis": true,
-    "noUnusedLocals": true,    
-    "strictNullChecks": true
-  }
-}

+ 41 - 0
loaders/tsconfig.json

@@ -0,0 +1,41 @@
+{
+  "compilerOptions": {
+      "experimentalDecorators": true,
+      "module": "commonjs",
+      "target": "es5",
+      "noImplicitAny": true,
+      "noImplicitReturns": true,
+      "noImplicitThis": true,
+      "noUnusedLocals": true,
+      "strictNullChecks": true,
+      "declaration": true,
+      "sourceMap": true,
+      "lib": [
+          "es5",
+          "dom",
+          "es2015.promise",
+          "es2015.collection",
+          "es2015.iterable"
+      ],
+      "skipDefaultLibCheck": true,
+      "skipLibCheck": true,
+      "baseUrl": "./src/",
+      "rootDir": "./",
+      "paths": {
+          "babylonjs": [
+            "../../dist/preview release/babylon.d.ts",
+          ],
+          "babylonjs-gltf2interface": [
+            "../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts"
+          ],
+      },
+      "outDir": "./build"
+  },
+  "include": [
+      "src/**/*"
+  ],
+  "exclude": [
+      "node_modules",
+      "**/*.spec.ts"
+  ]
+}

+ 68 - 0
loaders/webpack.config.js

@@ -0,0 +1,68 @@
+const path = require('path');
+const webpack = require('webpack');
+const DtsBundleWebpack = require('dts-bundle-webpack');
+const CleanWebpackPlugin = require('clean-webpack-plugin');
+
+module.exports = {
+    context: __dirname,
+    entry: {
+        'babylonjs-loaders': path.resolve(__dirname, './src/legacy.ts'),
+    },
+    output: {
+        path: path.resolve(__dirname, '../dist/preview release/loaders'),
+        filename: 'babylonjs.loaders.min.js',
+        libraryTarget: 'umd',
+        library: {
+            root: ["LOADERS"],
+            amd: "babylonjs-loaders",
+            commonjs: "babylonjs-loaders"
+        },
+        umdNamedDefine: true
+    },
+    resolve: {
+        extensions: [".js", '.ts']
+    },
+    externals: {
+        babylonjs: {
+            root: "BABYLON",
+            commonjs: "babylonjs",
+            commonjs2: "babylonjs",
+            amd: "babylonjs"
+        }
+    },
+    devtool: "source-map",
+    module: {
+        rules: [{
+            test: /\.tsx?$/,
+            exclude: /node_modules/,
+            use: [
+            {
+                loader: 'awesome-typescript-loader',
+                options: {
+                    configFileName: '../../loaders/tsconfig.json',
+                    declarationDir: '../../dist/preview release/loaders/build'
+                }
+            }]
+        }]
+    },
+    mode: "production",
+    devServer: {
+        contentBase: path.join(__dirname, "dist"),
+        compress: false,
+        //open: true,
+        port: 9000
+    },
+    plugins: [
+        new CleanWebpackPlugin([
+            path.resolve(__dirname, './src/**/*.js'),
+            path.resolve(__dirname, './src/**/*.map')
+        ]),
+        new webpack.WatchIgnorePlugin([
+            /\.js$/,
+            /\.d\.ts$/
+        ])
+    ],
+    watchOptions: {
+        ignored: [path.resolve(__dirname, './dist/**/*.*'), 'node_modules']
+    }
+}

+ 7 - 7
tests/unit/babylon/babylon.example.tests.ts

@@ -1,7 +1,7 @@
 /**
  * Describes the test suite.
  */
-describe('Example', function () {
+describe('Example', function() {
     /**
      * Sets the timeout of all the tests to 10 seconds.
      * Note the JavaScript function syntax in the describe callback.
@@ -12,11 +12,11 @@ describe('Example', function () {
     /**
      * Loads the dependencies.
      */
-    before(function (done) {
+    before(function(done) {
         this.timeout(180000);
         (BABYLONDEVTOOLS).Loader
             .useDist()
-            .load(function () {
+            .load(function() {
                 // Force apply promise polyfill for consistent behavior between PhantomJS, IE11, and other browsers.
                 BABYLON.PromisePolyfill.Apply(true);
                 done();
@@ -30,18 +30,18 @@ describe('Example', function () {
     describe('#ExponentOfTwo', () => {
         it('should be expoent of two', () => {
             var result : boolean = BABYLON.Tools.IsExponentOfTwo(2);
-            expect(result).to.be.true; 
+            expect(result).to.be.true;
 
             result = BABYLON.Tools.IsExponentOfTwo(4);
-            result.should.be.true; 
-            
+            result.should.be.true;
+
             result = BABYLON.Tools.IsExponentOfTwo(8);
             assert.isTrue(result);
         });
 
         it('should not be exponent of two', () => {
             var result : boolean = BABYLON.Tools.IsExponentOfTwo(3);
-            expect(result).to.be.false; 
+            expect(result).to.be.false;
 
             result = BABYLON.Tools.IsExponentOfTwo(6);
             result.should.be.false;

+ 1 - 1
tests/unit/babylon/babylonReference.ts

@@ -1,5 +1,5 @@
 /// <reference path="../../../dist/preview release/babylon.d.ts" />
-/// <reference path="../../../dist/preview release/loaders/babylon.glTF2FileLoader.d.ts" />
+/// <reference path="../../../dist/preview release/loaders/babylonjs.loaders.d.ts" />
 /// <reference path="../../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts"/>
 /// <reference path="../../../dist/preview release/serializers/babylon.glTF2Serializer.d.ts" />
 

+ 29 - 29
tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts

@@ -1,7 +1,7 @@
 /**
  * Describes the test suite.
  */
-describe('Babylon Scene Loader', function () {
+describe('Babylon Scene Loader', function() {
     let subject: BABYLON.Engine;
 
     this.timeout(10000);
@@ -9,11 +9,11 @@ describe('Babylon Scene Loader', function () {
     /**
      * Loads the dependencies.
      */
-    before(function (done) {
+    before(function(done) {
         this.timeout(180000);
         (BABYLONDEVTOOLS).Loader
             .useDist()
-            .load(function () {
+            .load(function() {
                 // Force apply promise polyfill for consistent behavior between PhantomJS, IE11, and other browsers.
                 BABYLON.PromisePolyfill.Apply(true);
                 BABYLON.Engine.audioEngine = new BABYLON.AudioEngine();
@@ -24,7 +24,7 @@ describe('Babylon Scene Loader', function () {
     /**
      * Create a new engine subject before each test.
      */
-    beforeEach(function () {
+    beforeEach(function() {
         subject = new BABYLON.NullEngine({
             renderHeight: 256,
             renderWidth: 256,
@@ -43,7 +43,7 @@ describe('Babylon Scene Loader', function () {
     describe('#glTF', () => {
         it('Load BoomBox', () => {
             const scene = new BABYLON.Scene(subject);
-            return BABYLON.SceneLoader.AppendAsync("/Playground/scenes/BoomBox/", "BoomBox.gltf", scene).then(scene => {
+            return BABYLON.SceneLoader.AppendAsync("/Playground/scenes/BoomBox/", "BoomBox.gltf", scene).then((scene) => {
                 expect(scene.meshes.length, "scene.meshes.length").to.equal(2);
                 expect(scene.materials.length, "scene.materials.length").to.equal(1);
             });
@@ -51,7 +51,7 @@ describe('Babylon Scene Loader', function () {
 
         it('Load BoomBox GLB', () => {
             const scene = new BABYLON.Scene(subject);
-            return BABYLON.SceneLoader.AppendAsync("/Playground/scenes/", "BoomBox.glb", scene).then(scene => {
+            return BABYLON.SceneLoader.AppendAsync("/Playground/scenes/", "BoomBox.glb", scene).then((scene) => {
                 expect(scene.meshes.length, "scene.meshes.length").to.equal(2);
                 expect(scene.materials.length, "scene.materials.length").to.equal(1);
             });
@@ -59,7 +59,7 @@ describe('Babylon Scene Loader', function () {
 
         it('Load BoomBox with ImportMesh', () => {
             const scene = new BABYLON.Scene(subject);
-            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/BoomBox/", "BoomBox.gltf", scene).then(result => {
+            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/BoomBox/", "BoomBox.gltf", scene).then((result) => {
                 expect(result.meshes.length, "meshes.length").to.equal(scene.meshes.length);
                 expect(result.particleSystems.length, "particleSystems.length").to.equal(0);
                 expect(result.skeletons.length, "skeletons.length").to.equal(0);
@@ -93,17 +93,17 @@ describe('Babylon Scene Loader', function () {
             const promises = new Array<Promise<void>>();
 
             BABYLON.SceneLoader.OnPluginActivatedObservable.addOnce((loader: BABYLON.GLTFFileLoader) => {
-                loader.onParsed = data => {
+                loader.onParsed = (data) => {
                     parsedCount++;
                 };
 
-                loader.onMeshLoaded = mesh => {
+                loader.onMeshLoaded = (mesh) => {
                     meshCount++;
                 };
-                loader.onMaterialLoaded = material => {
+                loader.onMaterialLoaded = (material) => {
                     materialCount++;
                 };
-                loader.onTextureLoaded = texture => {
+                loader.onTextureLoaded = (texture) => {
                     textureCounts[texture.name] = textureCounts[texture.name] || 0;
                     textureCounts[texture.name]++;
                 };
@@ -173,7 +173,7 @@ describe('Babylon Scene Loader', function () {
                 }
             });
 
-            return BABYLON.SceneLoader.AppendAsync("/Playground/scenes/BoomBox/", "BoomBox.gltf", scene).then(scene => {
+            return BABYLON.SceneLoader.AppendAsync("/Playground/scenes/BoomBox/", "BoomBox.gltf", scene).then((scene) => {
                 subject.stopRenderLoop();
 
                 for (const mesh of scene.meshes) {
@@ -246,7 +246,7 @@ describe('Babylon Scene Loader', function () {
 
         it('Load Alien', () => {
             const scene = new BABYLON.Scene(subject);
-            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/Alien/", "Alien.gltf", scene).then(result => {
+            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/Alien/", "Alien.gltf", scene).then((result) => {
                 const skeletonsMapping = {
                     "AlienHead": "skeleton0",
                     "Collar": "skeleton1",
@@ -275,11 +275,11 @@ describe('Babylon Scene Loader', function () {
                 const animationGroup = result.animationGroups[0];
                 expect(animationGroup.name, "animationGroup.name").to.equal("TwoTargetBlend");
                 expect(animationGroup.targetedAnimations, "animationGroup.targetedAnimations").to.have.lengthOf(7);
-                const influenceAnimations = animationGroup.targetedAnimations.filter(_ => _.animation.targetProperty === "influence");
+                const influenceAnimations = animationGroup.targetedAnimations.filter((_) => _.animation.targetProperty === "influence");
                 expect(influenceAnimations, "influenceAnimations").to.have.lengthOf(2);
-                const rotationAnimations = animationGroup.targetedAnimations.filter(_ => _.animation.targetProperty === "rotationQuaternion");
+                const rotationAnimations = animationGroup.targetedAnimations.filter((_) => _.animation.targetProperty === "rotationQuaternion");
                 expect(rotationAnimations, "rotationAnimations").to.have.lengthOf(4);
-                const positionAnimations = animationGroup.targetedAnimations.filter(_ => _.animation.targetProperty === "position");
+                const positionAnimations = animationGroup.targetedAnimations.filter((_) => _.animation.targetProperty === "position");
                 expect(positionAnimations, "positionAnimations").to.have.lengthOf(1);
             });
         });
@@ -350,10 +350,10 @@ describe('Babylon Scene Loader', function () {
             const promises = new Array<Promise<void>>();
 
             BABYLON.SceneLoader.OnPluginActivatedObservable.addOnce((loader: BABYLON.GLTFFileLoader) => {
-                const observer = loader.onExtensionLoadedObservable.add(extension => {
-                    if (extension instanceof BABYLON.GLTF2.Loader.Extensions.MSFT_lod) {
+                const observer = loader.onExtensionLoadedObservable.add((extension) => {
+                    if (extension instanceof BABYLON.MSFT_lod) {
                         loader.onExtensionLoadedObservable.remove(observer);
-                        extension.onMaterialLODsLoadedObservable.add(indexLOD => {
+                        extension.onMaterialLODsLoadedObservable.add((indexLOD) => {
                             const expectedMaterialName = `LOD${2 - indexLOD}`;
                             expect(scene.getMeshByName("node0").material.name, "Material for node 0").to.equal(expectedMaterialName);
                             expect(scene.getMeshByName("node1").material.name, "Material for node 1").to.equal(expectedMaterialName);
@@ -376,17 +376,17 @@ describe('Babylon Scene Loader', function () {
             const promises = new Array<Promise<void>>();
 
             BABYLON.SceneLoader.OnPluginActivatedObservable.addOnce((loader: BABYLON.GLTFFileLoader) => {
-                const observer = loader.onExtensionLoadedObservable.add(extension => {
-                    if (extension instanceof BABYLON.GLTF2.Loader.Extensions.MSFT_lod) {
+                const observer = loader.onExtensionLoadedObservable.add((extension) => {
+                    if (extension instanceof BABYLON.MSFT_lod) {
                         loader.onExtensionLoadedObservable.remove(observer);
-                        extension.onMaterialLODsLoadedObservable.add(indexLOD => {
+                        extension.onMaterialLODsLoadedObservable.add((indexLOD) => {
                             expect(indexLOD, "indexLOD").to.equal(0);
                             loader.dispose();
                         });
                     }
                 });
 
-                promises.push(new Promise(resolve => {
+                promises.push(new Promise((resolve) => {
                     loader.onDisposeObservable.addOnce(() => {
                         resolve();
                     });
@@ -416,7 +416,7 @@ describe('Babylon Scene Loader', function () {
 
         it('Load MultiPrimitive', () => {
             const scene = new BABYLON.Scene(subject);
-            return BABYLON.SceneLoader.ImportMeshAsync(null, "http://models.babylonjs.com/Tests/MultiPrimitive/", "MultiPrimitive.gltf", scene).then(result => {
+            return BABYLON.SceneLoader.ImportMeshAsync(null, "http://models.babylonjs.com/Tests/MultiPrimitive/", "MultiPrimitive.gltf", scene).then((result) => {
                 expect(result.meshes, "meshes").to.have.lengthOf(4);
 
                 const node = scene.getMeshByName("node");
@@ -439,7 +439,7 @@ describe('Babylon Scene Loader', function () {
 
         it('Load BrainStem', () => {
             const scene = new BABYLON.Scene(subject);
-            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/BrainStem/", "BrainStem.gltf", scene).then(result => {
+            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/BrainStem/", "BrainStem.gltf", scene).then((result) => {
                 expect(result.skeletons, "skeletons").to.have.lengthOf(1);
 
                 const node1 = scene.getMeshByName("node1");
@@ -460,7 +460,7 @@ describe('Babylon Scene Loader', function () {
                 var radianceOverAlpha = false;
 
                 loader.transparencyAsCoverage = true;
-                loader.onMaterialLoaded = material => {
+                loader.onMaterialLoaded = (material) => {
                     specularOverAlpha = specularOverAlpha || (material as BABYLON.PBRMaterial).useSpecularOverAlpha;
                     radianceOverAlpha = radianceOverAlpha || (material as BABYLON.PBRMaterial).useRadianceOverAlpha;
                 };
@@ -484,7 +484,7 @@ describe('Babylon Scene Loader', function () {
                 var radianceOverAlpha = true;
 
                 loader.transparencyAsCoverage = false;
-                loader.onMaterialLoaded = material => {
+                loader.onMaterialLoaded = (material) => {
                     specularOverAlpha = specularOverAlpha && (material as BABYLON.PBRMaterial).useSpecularOverAlpha;
                     radianceOverAlpha = radianceOverAlpha && (material as BABYLON.PBRMaterial).useRadianceOverAlpha;
                 };
@@ -512,7 +512,7 @@ describe('Babylon Scene Loader', function () {
 
         it('Load UFO with MSFT_audio_emitter', () => {
             const scene = new BABYLON.Scene(subject);
-            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/", "ufo.glb", scene).then(result => {
+            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/", "ufo.glb", scene).then((result) => {
                 expect(result.meshes.length, "meshes.length").to.equal(scene.meshes.length);
                 expect(result.particleSystems.length, "particleSystems.length").to.equal(0);
                 expect(result.animationGroups.length, "animationGroups.length").to.equal(3);
@@ -531,7 +531,7 @@ describe('Babylon Scene Loader', function () {
     describe('#AssetContainer', () => {
         it('should be loaded from BoomBox GLTF', () => {
             var scene = new BABYLON.Scene(subject);
-            return BABYLON.SceneLoader.LoadAssetContainerAsync("/Playground/scenes/BoomBox/", "BoomBox.gltf", scene).then(container => {
+            return BABYLON.SceneLoader.LoadAssetContainerAsync("/Playground/scenes/BoomBox/", "BoomBox.gltf", scene).then((container) => {
                 expect(container.meshes.length).to.eq(2);
             });
         });