Pārlūkot izejas kodu

Merge branch 'master' into dev_support_webgl2_textures

Nicolas 7 gadi atpakaļ
vecāks
revīzija
189a3dba88
100 mainītis faili ar 36556 papildinājumiem un 151942 dzēšanām
  1. 6 0
      .gitignore
  2. 2 2
      .travis.yml
  3. 1 1
      .vscode/tasks.json
  4. 4877 4788
      Playground/babylon.d.txt
  5. 79 0
      Playground/css/color_ts.css
  6. 422 419
      Playground/debug.html
  7. 92 93
      Playground/frame.html
  8. 7 6
      Playground/full.html
  9. 3 2
      Playground/index-local.html
  10. 13 11
      Playground/index.html
  11. 23 7
      Playground/js/index.js
  12. BIN
      Playground/scenes/ufo.glb
  13. 29 4
      Playground/ts.html
  14. 0 1
      Playground/zipContent/index.html
  15. 32 25
      Tools/DevLoader/BabylonLoader.js
  16. 113 154
      Tools/Gulp/config.json
  17. 160 107
      Tools/Gulp/gulpfile.js
  18. 10 9
      Tools/Gulp/package.json
  19. 51 19
      Tools/Gulp/processViewerDeclaration.js
  20. 8 4
      Tools/Publisher/index.js
  21. 139 0
      Tools/WebpackShaderLoader/index.js
  22. 4 4
      Viewer/assets/templates/default/navbar.html
  23. 25 0
      Viewer/dist/printExample.html
  24. 6 4
      Viewer/package.json
  25. 2 2
      Viewer/src/configuration/configurationCompatibility.ts
  26. 4 2
      Viewer/src/configuration/types/default.ts
  27. 2 2
      Viewer/src/model/viewerModel.ts
  28. 62 0
      Viewer/src/templating/plugins/printButton.ts
  29. 25 11
      Viewer/src/viewer/defaultViewer.ts
  30. 48 30
      Viewer/src/viewer/viewer.ts
  31. 2 1
      Viewer/tests/unit/tsconfig.json
  32. 4 2
      Viewer/tests/unit/webpack.config.js
  33. 1 1
      Viewer/tests/validation/karma.conf.js
  34. 1 1
      Viewer/tsconfig-gulp.json
  35. 2 2
      Viewer/tsconfig.json
  36. 4 2
      Viewer/webpack.assets.config.js
  37. 4 3
      Viewer/webpack.config.js
  38. 9 10
      Viewer/webpack.gulp.config.js
  39. 10560 10128
      dist/preview release/babylon.d.ts
  40. 63 61
      dist/preview release/babylon.js
  41. 1860 848
      dist/preview release/babylon.max.js
  42. 1860 848
      dist/preview release/babylon.no-module.max.js
  43. 64 62
      dist/preview release/babylon.worker.js
  44. 1862 850
      dist/preview release/es6.js
  45. 1 1
      dist/preview release/glTF2Interface/package.json
  46. 2356 2665
      dist/preview release/gui/babylon.gui.d.ts
  47. 2 5
      dist/preview release/gui/babylon.gui.min.js
  48. 1 0
      dist/preview release/gui/babylon.gui.min.js.map
  49. 4917 2669
      dist/preview release/gui/babylon.gui.module.d.ts
  50. 2 3
      dist/preview release/gui/package.json
  51. 2 5
      dist/preview release/inspector/babylon.inspector.bundle.js
  52. 1 0
      dist/preview release/inspector/babylon.inspector.bundle.js.map
  53. 1040 1385
      dist/preview release/inspector/babylon.inspector.d.ts
  54. 2371 0
      dist/preview release/inspector/babylon.inspector.module.d.ts
  55. 4 1
      dist/preview release/inspector/package.json
  56. 11 0
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  57. 23 1
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  58. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  59. 66 9
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  60. 391 94
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  61. 3 3
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  62. 66 9
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  63. 391 96
      dist/preview release/loaders/babylon.glTFFileLoader.js
  64. 4 4
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  65. 1 0
      dist/preview release/loaders/babylon.objFileLoader.d.ts
  66. 37 1
      dist/preview release/loaders/babylon.objFileLoader.js
  67. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  68. 67 9
      dist/preview release/loaders/babylonjs.loaders.d.ts
  69. 419 97
      dist/preview release/loaders/babylonjs.loaders.js
  70. 4 4
      dist/preview release/loaders/babylonjs.loaders.min.js
  71. 67 9
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  72. 2 2
      dist/preview release/loaders/package.json
  73. 1 0
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.d.ts
  74. 6 3
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  75. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  76. 1 0
      dist/preview release/materialsLibrary/babylonjs.materials.d.ts
  77. 6 3
      dist/preview release/materialsLibrary/babylonjs.materials.js
  78. 2 2
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  79. 1 0
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  80. 1 1
      dist/preview release/materialsLibrary/package.json
  81. 1 1
      dist/preview release/postProcessesLibrary/package.json
  82. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  83. 7 0
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  84. 113 91
      dist/preview release/serializers/babylon.glTF2Serializer.js
  85. 2 2
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  86. 7 0
      dist/preview release/serializers/babylonjs.serializers.d.ts
  87. 113 91
      dist/preview release/serializers/babylonjs.serializers.js
  88. 2 2
      dist/preview release/serializers/babylonjs.serializers.min.js
  89. 7 0
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  90. 2 2
      dist/preview release/serializers/package.json
  91. 2 99
      dist/preview release/typedocValidationBaseline.json
  92. 109 240
      dist/preview release/viewer/babylon.viewer.d.ts
  93. 55 75
      dist/preview release/viewer/babylon.viewer.js
  94. 560 125057
      dist/preview release/viewer/babylon.viewer.max.js
  95. 112 76
      dist/preview release/viewer/babylon.viewer.module.d.ts
  96. 18 2
      dist/preview release/what's new.md
  97. 41 0
      gui/package.json
  98. 3 3
      gui/readme.md
  99. 589 589
      gui/src/2D/advancedDynamicTexture.ts
  100. 0 0
      gui/src/2D/controls/button.ts

+ 6 - 0
.gitignore

@@ -13,6 +13,7 @@ TestResults
 *.user
 *.user
 *.sln.docstates
 *.sln.docstates
 *.map
 *.map
+!dist/**/*.map
 
 
 # javascript files
 # javascript files
 src/**/*.js
 src/**/*.js
@@ -161,8 +162,12 @@ node_modules
 *.js.fx
 *.js.fx
 *.d.ts
 *.d.ts
 !dist/**/*.d.ts
 !dist/**/*.d.ts
+!dist/**/*.js.map
 !lib.d.ts
 !lib.d.ts
 
 
+# Split declaration file
+!ISplit.d.ts
+
 # local dev
 # local dev
 localDev/src/*
 localDev/src/*
 /dist/preview release/babylon.custom.js
 /dist/preview release/babylon.custom.js
@@ -183,3 +188,4 @@ Viewer/tests/unit/src/**/*.js
 Viewer/tests/Lib/**/*.js
 Viewer/tests/Lib/**/*.js
 Viewer/tests/commons/**/*.js
 Viewer/tests/commons/**/*.js
 .sass-cache/
 .sass-cache/
+gui/dist/

+ 2 - 2
.travis.yml

@@ -31,8 +31,8 @@ jobs:
     - set -e
     - set -e
     - gulp typescript-all
     - gulp typescript-all
     - gulp tests-unit
     - gulp tests-unit
-#    - travis_retry gulp tests-validation-virtualscreen
-#    - travis_retry gulp tests-validation-browserstack
+    - travis_retry gulp tests-validation-virtualscreen
+    - travis_retry gulp tests-validation-browserstack
     - travis_retry gulp tests-viewer-validation-virtualscreen
     - travis_retry gulp tests-viewer-validation-virtualscreen
     - travis_retry gulp tests-viewer-validation-browserstack
     - travis_retry gulp tests-viewer-validation-browserstack
 notifications:
 notifications:

+ 1 - 1
.vscode/tasks.json

@@ -66,7 +66,7 @@
                     "background": {
                     "background": {
                         "activeOnStart": true,
                         "activeOnStart": true,
                         "beginsPattern": "Project is running at",
                         "beginsPattern": "Project is running at",
-                        "endsPattern": "webpack: Compiled successfully."
+                        "endsPattern": "Compiled successfully."
                     }
                     }
                 }
                 }
             ],
             ],

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 4877 - 4788
Playground/babylon.d.txt


+ 79 - 0
Playground/css/color_ts.css

@@ -0,0 +1,79 @@
+@import url("https://fonts.googleapis.com/css?family=Montserrat:300,400");
+@import url("https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css");
+#waitTitle {
+    color: rgb(208, 23, 211);
+}
+#exampleList #exampleBanner h1 {
+    color: #ae00ef;
+}
+#exampleList .horizontalSeparator {
+    border-top: 1px solid #ae00ef;
+}
+#exampleList .categoryContainer .itemLine .itemContent .itemLineDocLink {
+    color: #ae00ef;
+}
+#exampleList .categoryContainer .itemLine .itemContent .itemLinePGLink {
+    color: #ae00ef;
+}
+
+#fpsLabel {
+    background-color: #9147c9;
+}
+.navbar .title {
+    color: #bb47c9;
+}
+.navbar .version {
+    color: #9147c9;
+}
+
+.button {
+    background-color: #9147c9;
+}
+.button:hover {
+    background-color: #bb47c9;
+}
+.navbar .button.run {
+    background-color: #bb47c9;
+}
+.navbar .select .toDisplay {
+    border: 1px solid #9147c9;
+}
+.navbar .select .subSelect .toDisplaySub {
+    border: 1px solid #9147c9;
+}
+
+.navbar .select .toDisplay .option {
+    font-size: 0.9em;
+    height: 35px;
+    line-height: 35px;
+    padding: 0px 5px 0px 5px;
+    text-align: center;
+    border-bottom : 1px solid rgba(0,0,0,0.1);
+}
+
+.navbar .select .toDisplay .option.light:hover {
+    cursor: pointer;
+    background-color: #d9d9d9;
+}
+
+
+.navbar .select .toDisplay .option.dark {
+    background-color: #333;
+    color: white;
+}
+.navbar .select .toDisplay .option.light {
+    background-color: white;
+    color: #9147c9;
+}
+.navbar .select .toDisplayBig {
+    border: 1px solid #9147c9;
+}
+
+.navbar .select .toDisplayBig.light {    
+    color: #bb47c9;
+}
+.navbar .select .toDisplayBig a.light {
+    color: #9147c9;
+}
+
+

+ 422 - 419
Playground/debug.html

@@ -1,510 +1,513 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html>
 <html>
 
 
-<head>
-    <title>Babylon.js Playground</title>
-    <meta charset='utf-8' />
-    <meta name="viewport" content="width=device-width, user-scalable=no">
-    <link rel="shortcut icon" href="https://www.babylonjs.com/img/favicon/favicon.ico">
-    <link rel="apple-touch-icon" sizes="57x57" href="https://www.babylonjs.com/img/favicon/apple-icon-57x57.png">
-    <link rel="apple-touch-icon" sizes="60x60" href="https://www.babylonjs.com/img/favicon/apple-icon-60x60.png">
-    <link rel="apple-touch-icon" sizes="72x72" href="https://www.babylonjs.com/img/favicon/apple-icon-72x72.png">
-    <link rel="apple-touch-icon" sizes="76x76" href="https://www.babylonjs.com/img/favicon/apple-icon-76x76.png">
-    <link rel="apple-touch-icon" sizes="114x114" href="https://www.babylonjs.com/img/favicon/apple-icon-114x114.png">
-    <link rel="apple-touch-icon" sizes="120x120" href="https://www.babylonjs.com/img/favicon/apple-icon-120x120.png">
-    <link rel="apple-touch-icon" sizes="144x144" href="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png">
-    <link rel="apple-touch-icon" sizes="152x152" href="https://www.babylonjs.com/img/favicon/apple-icon-152x152.png">
-    <link rel="apple-touch-icon" sizes="180x180" href="https://www.babylonjs.com/img/favicon/apple-icon-180x180.png">
-    <link rel="icon" type="image/png" sizes="192x192" href="https://www.babylonjs.com/img/favicon/android-icon-192x192.png">
-    <link rel="icon" type="image/png" sizes="32x32" href="https://www.babylonjs.com/img/favicon/favicon-32x32.png">
-    <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
-    <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
-    <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
-    <meta name="msapplication-TileColor" content="#ffffff">
-    <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
-    <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
-    <meta name="theme-color" content="#ffffff">
-
-    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
-    <!--For canvas/code separator-->
-    <script src="js/libs/split.js"></script>
-
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
-    <!-- jszip -->
-    <script src="js/libs/jszip.min.js"></script>
-    <script src="js/libs/fileSaver.js"></script>
-    <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
-    <!-- Babylon.js -->
-    <script src="https://preview.babylonjs.com/cannon.js"></script>
-    <script src="https://preview.babylonjs.com/Oimo.js"></script>
-    <script src="https://preview.babylonjs.com/babylon.max.js"></script>
-    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
-
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.fireMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.waterMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.lavaMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.normalMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.skyMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.triPlanarMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.terrainMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gradientMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.furMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gridMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.shadowOnlyMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.customMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.cellMaterial.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.brickProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.cloudProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.fireProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.grassProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.marbleProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.roadProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.woodProceduralTexture.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.asciiArtPostProcess.min.js"></script>
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.digitalRainPostProcess.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylon.objFileLoader.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylon.stlFileLoader.js"></script>
-
-    <script src="https://preview.babylonjs.com/gui/babylon.gui.js"></script>
-
-    <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
-
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
-    <link href="css/index.css" rel="stylesheet" />
-
-</head>
-
-<body>
-    <div class="navbar navBar1600">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-            v3.0-alpha
-        </div>
-
-        <div class="category">
-            <div class="button run" id="runButton1600">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
+    <head>
+        <title>Babylon.js Playground</title>
+        <meta charset='utf-8' />
+        <meta name="viewport" content="width=device-width, user-scalable=no">
+        <link rel="shortcut icon" href="https://www.babylonjs.com/img/favicon/favicon.ico">
+        <link rel="apple-touch-icon" sizes="57x57" href="https://www.babylonjs.com/img/favicon/apple-icon-57x57.png">
+        <link rel="apple-touch-icon" sizes="60x60" href="https://www.babylonjs.com/img/favicon/apple-icon-60x60.png">
+        <link rel="apple-touch-icon" sizes="72x72" href="https://www.babylonjs.com/img/favicon/apple-icon-72x72.png">
+        <link rel="apple-touch-icon" sizes="76x76" href="https://www.babylonjs.com/img/favicon/apple-icon-76x76.png">
+        <link rel="apple-touch-icon" sizes="114x114" href="https://www.babylonjs.com/img/favicon/apple-icon-114x114.png">
+        <link rel="apple-touch-icon" sizes="120x120" href="https://www.babylonjs.com/img/favicon/apple-icon-120x120.png">
+        <link rel="apple-touch-icon" sizes="144x144" href="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png">
+        <link rel="apple-touch-icon" sizes="152x152" href="https://www.babylonjs.com/img/favicon/apple-icon-152x152.png">
+        <link rel="apple-touch-icon" sizes="180x180" href="https://www.babylonjs.com/img/favicon/apple-icon-180x180.png">
+        <link rel="icon" type="image/png" sizes="192x192" href="https://www.babylonjs.com/img/favicon/android-icon-192x192.png">
+        <link rel="icon" type="image/png" sizes="32x32" href="https://www.babylonjs.com/img/favicon/favicon-32x32.png">
+        <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
+        <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
+        <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
+        <meta name="msapplication-TileColor" content="#ffffff">
+        <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
+        <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
+        <meta name="theme-color" content="#ffffff">
+
+        <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+        <!--For canvas/code separator-->
+        <script src="js/libs/split.js"></script>
+
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
+        <!-- jszip -->
+        <script src="js/libs/jszip.min.js"></script>
+        <script src="js/libs/fileSaver.js"></script>
+
+        <!-- Babylon.js -->
+        <script src="https://preview.babylonjs.com/cannon.js"></script>
+        <script src="https://preview.babylonjs.com/Oimo.js"></script>
+        <script src="https://preview.babylonjs.com/babylon.max.js"></script>
+        <script src="https://preview.babylonjs.com/gui/babylon.gui.js"></script>
+        <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
+
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.fireMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.waterMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.lavaMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.normalMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.skyMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.triPlanarMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.terrainMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gradientMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.furMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gridMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.shadowOnlyMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.customMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.cellMaterial.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.brickProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.cloudProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.fireProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.grassProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.marbleProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.roadProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.woodProceduralTexture.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.asciiArtPostProcess.min.js"></script>
+        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.digitalRainPostProcess.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
+        <script src="https://preview.babylonjs.com/loaders/babylon.objFileLoader.js"></script>
+        <script src="https://preview.babylonjs.com/loaders/babylon.stlFileLoader.js"></script>
+
+
+
+        <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
+
+        <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
+        <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
+        <link href="css/index.css" rel="stylesheet" />
+
+        <!-- Monaco -->
+        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
+    </head>
+
+    <body>
+        <div class="navbar navBar1600">
+            <div class="title">
+                Babylon.js Playground
+            </div>
+            <div class="version" id="mainTitle">
+                v3.0-alpha
+            </div>
+
+            <div class="category">
+                <div class="button run" id="runButton1600">Run
+                    <i class="fa fa-play" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
 
 
-        <div class="category">
-            <div class="button" id="newButton1600">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1600">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="newButton1600">New
+                    <i class="fa fa-file" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="clearButton1600">Clear
+                    <i class="fa fa-trash" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button" id="saveButton1600">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1600">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="saveButton1600">Save
+                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="zipButton1600">Zip
+                    <i class="fa fa-download" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme1600">Dark</div>
-                            <div class="option" id="lightTheme1600">Light</div>
+            <div class="category">
+                <div class="button select">Settings
+                    <div class="toDisplay">
+                        <div class="option subSelect">Theme
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" id="darkTheme1600">Dark</div>
+                                <div class="option" id="lightTheme1600">Light</div>
+                            </div>
                         </div>
                         </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize1600">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
+                        <div class="option subSelect">
+                            <span id="currentFontSize1600">Font: 14</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setFontSize(12);">12</div>
+                                <div class="option" onclick="setFontSize(14);">14</div>
+                                <div class="option" onclick="setFontSize(16);">16</div>
+                                <div class="option" onclick="setFontSize(18);">18</div>
+                                <div class="option" onclick="setFontSize(20);">20</div>
+                                <div class="option" onclick="setFontSize(22);">22</div>
+                            </div>
+                        </div>
+                        <div class="option" id="safemodeToggle1600">Safe mode
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option checked" id="editorButton1600">Editor
+                            <i class="fa fa-check-square" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="fullscreenButton1600">Fullscreen</div>
+                        <div class="option" id="editorFullscreenButton1600">Editor Fullscreen</div>
+                        <div class="option" id="formatButton1600">Format code</div>
+                        <div class="option" id="minimapToggle1600">Minimap
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1600">Safe mode
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1600">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1600">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1600">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1600">Format code</div>
-                    <div class="option" id="minimapToggle1600">Minimap
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
                     </div>
                     </div>
                 </div>
                 </div>
-            </div>
 
 
-            <div class="button uncheck" id="debugButton1600">Inspector
-                <i class="fa fa-square-o" aria-hidden="true"></i>
+                <div class="button uncheck" id="debugButton1600">Inspector
+                    <i class="fa fa-square-o" aria-hidden="true"></i>
+                </div>
+                <div class="button" id="metadataButton1600">Metadata</div>
             </div>
             </div>
-            <div class="button" id="metadataButton1600">Metadata</div>
-        </div>
 
 
 
 
 
 
-        <div class="category right">
-            <div class="button select">
-                <span id="currentVersion1600">Version: Latest</span>
-                <div class="toDisplay">
-                    <div class="option" onclick="setVersion('latest');">Latest</div>
-                    <div class="option" onclick="setVersion('2.5');">2.5</div>
+            <div class="category right">
+                <div class="button select">
+                    <span id="currentVersion1600">Version: Latest</span>
+                    <div class="toDisplay">
+                        <div class="option" onclick="setVersion('latest');">Latest</div>
+                        <div class="option" onclick="setVersion('2.5');">2.5</div>
+                    </div>
+                </div>
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
                 </div>
                 </div>
-            </div>
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
             </div>
             </div>
         </div>
         </div>
-    </div>
 
 
-    <div class="navbar navBar1475">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-            v3.0-alpha
-        </div>
+        <div class="navbar navBar1475">
+            <div class="title">
+                Babylon.js Playground
+            </div>
+            <div class="version" id="mainTitle">
+                v3.0-alpha
+            </div>
 
 
-        <div class="category">
-            <div class="button run" id="runButton1475">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button run" id="runButton1475">Run
+                    <i class="fa fa-play" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
 
 
-        <div class="category">
-            <div class="button" id="newButton1475">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1475">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="newButton1475">New
+                    <i class="fa fa-file" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="clearButton1475">Clear
+                    <i class="fa fa-trash" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button" id="saveButton1475">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1475">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="saveButton1475">Save
+                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="zipButton1475">Zip
+                    <i class="fa fa-download" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme1475">Dark</div>
-                            <div class="option" id="lightTheme1475">Light</div>
+            <div class="category">
+                <div class="button select">Settings
+                    <div class="toDisplay">
+                        <div class="option subSelect">Theme
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" id="darkTheme1475">Dark</div>
+                                <div class="option" id="lightTheme1475">Light</div>
+                            </div>
                         </div>
                         </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize1475">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
+                        <div class="option subSelect">
+                            <span id="currentFontSize1475">Font: 14</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setFontSize(12);">12</div>
+                                <div class="option" onclick="setFontSize(14);">14</div>
+                                <div class="option" onclick="setFontSize(16);">16</div>
+                                <div class="option" onclick="setFontSize(18);">18</div>
+                                <div class="option" onclick="setFontSize(20);">20</div>
+                                <div class="option" onclick="setFontSize(22);">22</div>
+                            </div>
                         </div>
                         </div>
-                    </div>
-                    <div class="option" id='safemodeToggle1475'>Safe mode
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1475">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1475">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1475">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1475">Format code</div>
-                    <div class="option" id="minimapToggle1475">Minimap
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1475">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="metadataButton1475">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion1475">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('2.5');">2.5</div>
+                        <div class="option" id='safemodeToggle1475'>Safe mode
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option checked" id="editorButton1475">Editor
+                            <i class="fa fa-check-square" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="fullscreenButton1475">Fullscreen</div>
+                        <div class="option" id="editorFullscreenButton1475">Editor Fullscreen</div>
+                        <div class="option" id="formatButton1475">Format code</div>
+                        <div class="option" id="minimapToggle1475">Minimap
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton1475">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="metadataButton1475">Metadata</div>
+                        <div class="option subSelect">
+                            <span id="currentVersion1475">Vers. : Latest</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setVersion('latest');">Latest</div>
+                                <div class="option" onclick="setVersion('2.5');">2.5</div>
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
             </div>
         </div>
         </div>
-    </div>
 
 
-    <div class="navbar navBar1030">
-        <div class="category">
-            <div class="button run" id="runButton1030">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
+        <div class="navbar navBar1030">
+            <div class="category">
+                <div class="button run" id="runButton1030">Run
+                    <i class="fa fa-play" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
 
 
-        <div class="category">
-            <div class="button" id="newButton1030">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1030">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="newButton1030">New
+                    <i class="fa fa-file" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="clearButton1030">Clear
+                    <i class="fa fa-trash" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button" id="saveButton1030">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1030">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button" id="saveButton1030">Save
+                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                </div>
+                <div class="button removeOnPhone" id="zipButton1030">Zip
+                    <i class="fa fa-download" aria-hidden="true"></i>
+                </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme1030">Dark</div>
-                            <div class="option" id="lightTheme1030">Light</div>
+            <div class="category">
+                <div class="button select">Settings
+                    <div class="toDisplay">
+                        <div class="option subSelect">Theme
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" id="darkTheme1030">Dark</div>
+                                <div class="option" id="lightTheme1030">Light</div>
+                            </div>
                         </div>
                         </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize1030">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
+                        <div class="option subSelect">
+                            <span id="currentFontSize1030">Font: 14</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setFontSize(12);">12</div>
+                                <div class="option" onclick="setFontSize(14);">14</div>
+                                <div class="option" onclick="setFontSize(16);">16</div>
+                                <div class="option" onclick="setFontSize(18);">18</div>
+                                <div class="option" onclick="setFontSize(20);">20</div>
+                                <div class="option" onclick="setFontSize(22);">22</div>
+                            </div>
                         </div>
                         </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1030">Safe mode
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1030">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1030">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1030">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1030">Format code</div>
-                    <div class="option" id="minimapToggle1030">Minimap
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1030">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="metadataButton1030">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion1030">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('2.5');">2.5</div>
+                        <div class="option" id="safemodeToggle1030">Safe mode
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option checked" id="editorButton1030">Editor
+                            <i class="fa fa-check-square" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="fullscreenButton1030">Fullscreen</div>
+                        <div class="option" id="editorFullscreenButton1030">Editor Fullscreen</div>
+                        <div class="option" id="formatButton1030">Format code</div>
+                        <div class="option" id="minimapToggle1030">Minimap
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton1030">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="metadataButton1030">Metadata</div>
+                        <div class="option subSelect">
+                            <span id="currentVersion1030">Vers. : Latest</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setVersion('latest');">Latest</div>
+                                <div class="option" onclick="setVersion('2.5');">2.5</div>
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
             </div>
         </div>
         </div>
-    </div>
-
-    <div class="navbar navBar750">
-        <div class="category">
-            <div class="button select">File
-                <div class="toDisplay">
-                    <div class="option" id="runButton750">Run
-                        <i class="fa fa-play" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="newButton750">New
-                        <i class="fa fa-file" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="clearButton750">Clear
-                        <i class="fa fa-trash" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="saveButton750">Save
-                        <i class="fa fa-floppy-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="zipButton750">Zip
-                        <i class="fa fa-download" aria-hidden="true"></i>
+
+        <div class="navbar navBar750">
+            <div class="category">
+                <div class="button select">File
+                    <div class="toDisplay">
+                        <div class="option" id="runButton750">Run
+                            <i class="fa fa-play" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="newButton750">New
+                            <i class="fa fa-file" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="clearButton750">Clear
+                            <i class="fa fa-trash" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="saveButton750">Save
+                            <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="zipButton750">Zip
+                            <i class="fa fa-download" aria-hidden="true"></i>
+                        </div>
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme750">Dark</div>
-                            <div class="option" id="lightTheme750">Light</div>
+            <div class="category">
+                <div class="button select">Settings
+                    <div class="toDisplay">
+                        <div class="option subSelect">Theme
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" id="darkTheme750">Dark</div>
+                                <div class="option" id="lightTheme750">Light</div>
+                            </div>
                         </div>
                         </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize750">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
+                        <div class="option subSelect">
+                            <span id="currentFontSize750">Font: 14</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setFontSize(12);">12</div>
+                                <div class="option" onclick="setFontSize(14);">14</div>
+                                <div class="option" onclick="setFontSize(16);">16</div>
+                                <div class="option" onclick="setFontSize(18);">18</div>
+                                <div class="option" onclick="setFontSize(20);">20</div>
+                                <div class="option" onclick="setFontSize(22);">22</div>
+                            </div>
                         </div>
                         </div>
-                    </div>
-                    <div class="option" id="safemodeToggle750">Safe mode
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div style="display:none;" class="option checked" id="editorButton750">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton750">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton750">Editor Fullscreen</div>
-                    <div class="option" id="formatButton750">Format code</div>
-                    <div class="option" id="minimapToggle750">Minimap
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton750">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="metadataButton750">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion750">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('2.5');">2.5</div>
+                        <div class="option" id="safemodeToggle750">Safe mode
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div style="display:none;" class="option checked" id="editorButton750">Editor
+                            <i class="fa fa-check-square" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="fullscreenButton750">Fullscreen</div>
+                        <div class="option" id="editorFullscreenButton750">Editor Fullscreen</div>
+                        <div class="option" id="formatButton750">Format code</div>
+                        <div class="option" id="minimapToggle750">Minimap
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton750">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="metadataButton750">Metadata</div>
+                        <div class="option subSelect">
+                            <span id="currentVersion750">Vers. : Latest</span>
+                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                            <div class="toDisplaySub">
+                                <div class="option" onclick="setVersion('latest');">Latest</div>
+                                <div class="option" onclick="setVersion('2.5');">2.5</div>
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
             </div>
         </div>
         </div>
-    </div>
 
 
-    <div class="wrapper">
-        <div id="jsEditor"></div>
-        <div id="canvasZone">
-            <canvas touch-action="none" id="renderCanvas"></canvas>
+        <div class="wrapper">
+            <div id="jsEditor"></div>
+            <div id="canvasZone">
+                <canvas touch-action="none" id="renderCanvas"></canvas>
+            </div>
         </div>
         </div>
-    </div>
-    <div id="exampleList">
-        <div id="exampleBanner">
-            <h1>Examples</h1>
+        <div id="exampleList">
+            <div id="exampleBanner">
+                <h1>Examples</h1>
+            </div>
+            <div class="horizontalSeparator"></div>
+            <input id="filterBar" type="text" placeholder="Filter examples...">
+            <img id="filterBarClear" src="https://d33wubrfki0l68.cloudfront.net/17ca450bae302631f4857cd8c3992234ec5dd9a7/057f9/img/ui/clear_button.png">
         </div>
         </div>
-        <div class="horizontalSeparator"></div>
-        <input id="filterBar" type="text" placeholder="Filter examples...">
-        <img id="filterBarClear" src="https://d33wubrfki0l68.cloudfront.net/17ca450bae302631f4857cd8c3992234ec5dd9a7/057f9/img/ui/clear_button.png">
-    </div>
 
 
-    <span class="label" id="fpsLabel">FPS</span>
+        <span class="label" id="fpsLabel">FPS</span>
 
 
-    <div id="errorZone">
-    </div>
+        <div id="errorZone">
+        </div>
 
 
-    <div class="navbarBottom">
-        <div id="statusBar"></div>
-        <div class="links">
-            <div class='link'>
-                <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://doc.babylonjs.com">Documentation</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://doc.babylonjs.com/playground">Search</a>
+        <div class="navbarBottom">
+            <div id="statusBar"></div>
+            <div class="links">
+                <div class='link'>
+                    <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
+                </div>
+                <div class='link'>
+                    <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
+                </div>
+                <div class='link'>
+                    <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
+                </div>
+                <div class='link'>
+                    <a target='_new' href="https://doc.babylonjs.com">Documentation</a>
+                </div>
+                <div class='link'>
+                    <a target='_new' href="https://doc.babylonjs.com/playground">Search</a>
+                </div>
             </div>
             </div>
         </div>
         </div>
-    </div>
 
 
-    <div id="saveLayer" class="save-layer">
-        <div class="save-form">
-            <label for="saveFormTitle">TITLE</label>
-            <div class="separator"></div>
-            <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
+        <div id="saveLayer" class="save-layer">
+            <div class="save-form">
+                <label for="saveFormTitle">TITLE</label>
+                <div class="separator"></div>
+                <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
 
 
-            <label for="saveFormDescription">DESCRIPTION</label>
-            <div class="separator"></div>
-            <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
+                <label for="saveFormDescription">DESCRIPTION</label>
+                <div class="separator"></div>
+                <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
 
 
-            <label for="saveFormTags">TAGS (separated by comma)</label>
-            <div class="separator"></div>
-            <textarea id="saveFormTags" rows="4" cols="10"></textarea>
+                <label for="saveFormTags">TAGS (separated by comma)</label>
+                <div class="separator"></div>
+                <textarea id="saveFormTags" rows="4" cols="10"></textarea>
 
 
-            <div class="save-form-buttons" id="saveFormButtons">
+                <div class="save-form-buttons" id="saveFormButtons">
 
 
-                <div id="saveFormButtonOk" class="button">OK</div>
-                <div id="saveFormButtonCancel" class="button">Cancel</div>
+                    <div id="saveFormButtonOk" class="button">OK</div>
+                    <div id="saveFormButtonCancel" class="button">Cancel</div>
+                </div>
             </div>
             </div>
         </div>
         </div>
-    </div>
 
 
-    <script src="https://code.jquery.com/jquery.js"></script>
+        <script src="https://code.jquery.com/jquery.js"></script>
 
 
-    <script src="js/actions.js"></script>
-    <script src="js/pbt.js"></script>
-    <script src="js/index.js"></script>
+        <script src="js/actions.js"></script>
+        <script src="js/pbt.js"></script>
+        <script src="js/index.js"></script>
 
 
-    <!-- Global site tag (gtag.js) - Google Analytics -->
-    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
-    <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
+        <!-- Global site tag (gtag.js) - Google Analytics -->
+        <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
+        <script>
+            window.dataLayer = window.dataLayer || [];
+            function gtag() { dataLayer.push(arguments); }
+            gtag('js', new Date());
 
 
-    gtag('config', 'UA-41767310-2');
-    </script>    
-</body>
+            gtag('config', 'UA-41767310-2');
+        </script>
+    </body>
 
 
 </html>
 </html>

+ 92 - 93
Playground/frame.html

@@ -1,98 +1,97 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html>
 <html>
 
 
-<head>
-    <title>Babylon.js Playground</title>
-    <link rel="shortcut icon" href="https://www.babylonjs.com/img/favicon/favicon.ico">
-    <link rel="apple-touch-icon" sizes="57x57" href="https://www.babylonjs.com/img/favicon/apple-icon-57x57.png">
-    <link rel="apple-touch-icon" sizes="60x60" href="https://www.babylonjs.com/img/favicon/apple-icon-60x60.png">
-    <link rel="apple-touch-icon" sizes="72x72" href="https://www.babylonjs.com/img/favicon/apple-icon-72x72.png">
-    <link rel="apple-touch-icon" sizes="76x76" href="https://www.babylonjs.com/img/favicon/apple-icon-76x76.png">
-    <link rel="apple-touch-icon" sizes="114x114" href="https://www.babylonjs.com/img/favicon/apple-icon-114x114.png">
-    <link rel="apple-touch-icon" sizes="120x120" href="https://www.babylonjs.com/img/favicon/apple-icon-120x120.png">
-    <link rel="apple-touch-icon" sizes="144x144" href="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png">
-    <link rel="apple-touch-icon" sizes="152x152" href="https://www.babylonjs.com/img/favicon/apple-icon-152x152.png">
-    <link rel="apple-touch-icon" sizes="180x180" href="https://www.babylonjs.com/img/favicon/apple-icon-180x180.png">
-    <link rel="icon" type="image/png" sizes="192x192" href="https://www.babylonjs.com/img/favicon/android-icon-192x192.png">
-    <link rel="icon" type="image/png" sizes="32x32" href="https://www.babylonjs.com/img/favicon/favicon-32x32.png">
-    <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
-    <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
-    <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
-    <meta name="msapplication-TileColor" content="#ffffff">
-    <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
-    <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
-    <meta name="theme-color" content="#ffffff">
-    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
-
-    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
-    
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
-    <!-- Babylon.js -->
-    <script src="https://preview.babylonjs.com/cannon.js"></script>
-    <script src="https://preview.babylonjs.com/Oimo.js"></script>
-    <script src="https://preview.babylonjs.com/earcut.min.js"></script>
-    <script src="https://preview.babylonjs.com/babylon.js"></script>
-    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
-
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.fireMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.waterMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.lavaMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.normalMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.skyMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.triPlanarMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.terrainMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gradientMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.furMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gridMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.shadowOnlyMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.customMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.cellMaterial.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.brickProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.cloudProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.fireProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.grassProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.marbleProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.roadProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.woodProceduralTexture.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.asciiArtPostProcess.min.js"></script>
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.digitalRainPostProcess.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylon.objFileLoader.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylon.stlFileLoader.js"></script>
-
-    <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
-
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
-    <link href="frame.css" rel="stylesheet" />
-</head>
-
-<body>
-    <canvas touch-action="none" id="renderCanvas" tabindex="1"></canvas>
-
-    <span class="label" id="fpsLabel">FPS</span>
-
-    <a class="link" id="refresh" href="#">Reload</a>
-    <a class="link" id="link" href="#" target="_blank">Edit</a>
-
-    <script src="https://code.jquery.com/jquery.js"></script>
-    <script src="js/frame.js"></script>
-
-    <!-- Global site tag (gtag.js) - Google Analytics -->
-    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
-    <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
-
-    gtag('config', 'UA-41767310-2');
-    </script>    
-</body>
+    <head>
+        <title>Babylon.js Playground</title>
+        <link rel="shortcut icon" href="https://www.babylonjs.com/img/favicon/favicon.ico">
+        <link rel="apple-touch-icon" sizes="57x57" href="https://www.babylonjs.com/img/favicon/apple-icon-57x57.png">
+        <link rel="apple-touch-icon" sizes="60x60" href="https://www.babylonjs.com/img/favicon/apple-icon-60x60.png">
+        <link rel="apple-touch-icon" sizes="72x72" href="https://www.babylonjs.com/img/favicon/apple-icon-72x72.png">
+        <link rel="apple-touch-icon" sizes="76x76" href="https://www.babylonjs.com/img/favicon/apple-icon-76x76.png">
+        <link rel="apple-touch-icon" sizes="114x114" href="https://www.babylonjs.com/img/favicon/apple-icon-114x114.png">
+        <link rel="apple-touch-icon" sizes="120x120" href="https://www.babylonjs.com/img/favicon/apple-icon-120x120.png">
+        <link rel="apple-touch-icon" sizes="144x144" href="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png">
+        <link rel="apple-touch-icon" sizes="152x152" href="https://www.babylonjs.com/img/favicon/apple-icon-152x152.png">
+        <link rel="apple-touch-icon" sizes="180x180" href="https://www.babylonjs.com/img/favicon/apple-icon-180x180.png">
+        <link rel="icon" type="image/png" sizes="192x192" href="https://www.babylonjs.com/img/favicon/android-icon-192x192.png">
+        <link rel="icon" type="image/png" sizes="32x32" href="https://www.babylonjs.com/img/favicon/favicon-32x32.png">
+        <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
+        <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
+        <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
+        <meta name="msapplication-TileColor" content="#ffffff">
+        <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
+        <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
+        <meta name="theme-color" content="#ffffff">
+        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
+
+        <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
+        <!-- Babylon.js -->
+        <script src="https://preview.babylonjs.com/cannon.js"></script>
+        <script src="https://preview.babylonjs.com/Oimo.js"></script>
+        <script src="https://preview.babylonjs.com/earcut.min.js"></script>
+        <script src="https://preview.babylonjs.com/babylon.js"></script>
+        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
+        <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
+
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.fireMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.waterMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.lavaMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.normalMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.skyMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.triPlanarMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.terrainMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gradientMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.furMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gridMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.shadowOnlyMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.customMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.cellMaterial.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.brickProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.cloudProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.fireProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.grassProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.marbleProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.roadProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.woodProceduralTexture.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.asciiArtPostProcess.min.js"></script>
+        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.digitalRainPostProcess.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
+        <script src="https://preview.babylonjs.com/loaders/babylon.objFileLoader.js"></script>
+        <script src="https://preview.babylonjs.com/loaders/babylon.stlFileLoader.js"></script>
+
+        <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
+
+        <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
+        <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
+        <link href="frame.css" rel="stylesheet" />
+    </head>
+
+    <body>
+        <canvas touch-action="none" id="renderCanvas" tabindex="1"></canvas>
+
+        <span class="label" id="fpsLabel">FPS</span>
+
+        <a class="link" id="refresh" href="#">Reload</a>
+        <a class="link" id="link" href="#" target="_blank">Edit</a>
+
+        <script src="https://code.jquery.com/jquery.js"></script>
+        <script src="js/frame.js"></script>
+
+        <!-- Global site tag (gtag.js) - Google Analytics -->
+        <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
+        <script>
+            window.dataLayer = window.dataLayer || [];
+            function gtag() { dataLayer.push(arguments); }
+            gtag('js', new Date());
+
+            gtag('config', 'UA-41767310-2');
+        </script>
+    </body>
 
 
 </html>
 </html>

+ 7 - 6
Playground/full.html

@@ -29,6 +29,7 @@
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
+        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
 
 
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
@@ -39,7 +40,7 @@
 
 
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
 
 
-        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
+
 
 
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
@@ -54,12 +55,12 @@
         <!-- Global site tag (gtag.js) - Google Analytics -->
         <!-- Global site tag (gtag.js) - Google Analytics -->
         <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
         <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
         <script>
         <script>
-        window.dataLayer = window.dataLayer || [];
-        function gtag(){dataLayer.push(arguments);}
-        gtag('js', new Date());
+            window.dataLayer = window.dataLayer || [];
+            function gtag() { dataLayer.push(arguments); }
+            gtag('js', new Date());
 
 
-        gtag('config', 'UA-41767310-2');
-        </script>        
+            gtag('config', 'UA-41767310-2');
+        </script>
     </body>
     </body>
 
 
 </html>
 </html>

+ 3 - 2
Playground/index-local.html

@@ -18,7 +18,7 @@
         <script src="../dist/preview%20release/Oimo.js"></script>
         <script src="../dist/preview%20release/Oimo.js"></script>
         <script src="../dist/preview%20release/earcut.min.js"></script>
         <script src="../dist/preview%20release/earcut.min.js"></script>
         <!-- Monaco -->
         <!-- Monaco -->
-        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
         <!-- Babylon.js -->
         <!-- Babylon.js -->
         <script src="../tools/DevLoader/BabylonLoader.js"></script>
         <script src="../tools/DevLoader/BabylonLoader.js"></script>
 
 
@@ -447,6 +447,7 @@
         <script src="js/pbt.js"></script>
         <script src="js/pbt.js"></script>
         <script>
         <script>
             BABYLONDEVTOOLS.Loader
             BABYLONDEVTOOLS.Loader
+                .require('node_modules/monaco-editor/min/vs/loader.js')
                 .require('js/index.js')
                 .require('js/index.js')
                 .load(function () {
                 .load(function () {
                     BABYLON.DracoCompression.Configuration.decoder = {
                     BABYLON.DracoCompression.Configuration.decoder = {
@@ -458,4 +459,4 @@
         </script>
         </script>
     </body>
     </body>
 
 
-</html>
+</html>

+ 13 - 11
Playground/index.html

@@ -37,24 +37,26 @@
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
-        <!-- Monaco -->
-        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
         <!-- Babylon.js -->
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
+        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
         <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
         <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
-        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
+
+        <!-- Monaco -->
+        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
 
 
         <!-- Extensions -->
         <!-- Extensions -->
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js" async></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js" async></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.navmesh.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.navmesh.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
-                               
+
         <link href="css/index.css" rel="stylesheet" />
         <link href="css/index.css" rel="stylesheet" />
     </head>
     </head>
 
 
@@ -408,7 +410,7 @@
                 <canvas touch-action="none" id="renderCanvas"></canvas>
                 <canvas touch-action="none" id="renderCanvas"></canvas>
             </div>
             </div>
         </div>
         </div>
-        <div id="exampleList">
+        <div id="exampleList" class="javascript">
             <div id="exampleBanner">
             <div id="exampleBanner">
                 <h1>Examples</h1>
                 <h1>Examples</h1>
             </div>
             </div>
@@ -479,16 +481,16 @@
         <script src="js/actions.js"></script>
         <script src="js/actions.js"></script>
         <script src="js/pbt.js"></script>
         <script src="js/pbt.js"></script>
         <script src="js/index.js"></script>
         <script src="js/index.js"></script>
-        
+
         <!-- Global site tag (gtag.js) - Google Analytics -->
         <!-- Global site tag (gtag.js) - Google Analytics -->
         <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
         <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
         <script>
         <script>
-        window.dataLayer = window.dataLayer || [];
-        function gtag(){dataLayer.push(arguments);}
-        gtag('js', new Date());
+            window.dataLayer = window.dataLayer || [];
+            function gtag() { dataLayer.push(arguments); }
+            gtag('js', new Date());
 
 
-        gtag('config', 'UA-41767310-2');
-        </script>        
+            gtag('config', 'UA-41767310-2');
+        </script>
     </body>
     </body>
 
 
 </html>
 </html>

+ 23 - 7
Playground/js/index.js

@@ -241,9 +241,17 @@ function showError(errorMessage, errorEvent) {
         };
         };
 
 
         var loadScriptsList = function () {
         var loadScriptsList = function () {
-            var xhr = new XMLHttpRequest();
 
 
-            xhr.open('GET', 'https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list.json', true);
+            var exampleList = document.getElementById("exampleList");
+           
+            var xhr = new XMLHttpRequest();
+            //Open Typescript or Javascript examples
+            if(exampleList.className != 'typescript') {
+                xhr.open('GET', 'https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list.json', true);
+            }
+            else {
+                xhr.open('GET', 'https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list_ts.json', true);
+            }
 
 
             xhr.onreadystatechange = function () {
             xhr.onreadystatechange = function () {
                 if (xhr.readyState === 4) {
                 if (xhr.readyState === 4) {
@@ -257,7 +265,7 @@ function showError(errorMessage, errorEvent) {
                         }
                         }
                         scripts.sort(sortScriptsList);
                         scripts.sort(sortScriptsList);
 
 
-                        var exampleList = document.getElementById("exampleList");
+                                                
 
 
                         if (exampleList) {
                         if (exampleList) {
                             for (var i = 0; i < scripts.length; i++) {
                             for (var i = 0; i < scripts.length; i++) {
@@ -550,7 +558,8 @@ function showError(errorMessage, errorEvent) {
                     }
                     }
     
     
                     var scene;
                     var scene;
-    
+                    var defaultEngineZip = "new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true })";
+
                     if (code.indexOf("createEngine") !== -1) {
                     if (code.indexOf("createEngine") !== -1) {
                         createEngineFunction = "createEngine";
                         createEngineFunction = "createEngine";
                     }
                     }
@@ -573,7 +582,7 @@ function showError(errorMessage, errorEvent) {
                         eval("runScript = function(scene, canvas) {" + code + "}");
                         eval("runScript = function(scene, canvas) {" + code + "}");
                         runScript(scene, canvas);
                         runScript(scene, canvas);
     
     
-                        zipCode = "var scene = new BABYLON.Scene(engine);\r\n\r\n" + code;
+                        zipCode = "var engine = " + defaultEngineZip + ";\r\nvar scene = new BABYLON.Scene(engine);\r\n\r\n" + code;
                     } else {
                     } else {
                         //execute the code
                         //execute the code
                         eval(code);
                         eval(code);
@@ -592,8 +601,15 @@ function showError(errorMessage, errorEvent) {
                             return;
                             return;
                         }
                         }
     
     
-                        // update the scene code for the zip file
-                        zipCode = code + "\r\n\r\nvar scene = " + createSceneFunction + "()";
+                        var createEngineZip = (createEngineFunction === "createEngine")
+                            ? "createEngine()"
+                            : defaultEngineZip
+
+                        zipCode = 
+                            code + "\r\n\r\n" +
+                            "var engine = " + createEngineZip + ";\r\n" +
+                            "var scene = " + createSceneFunction + "();"
+
                     }
                     }
     
     
                     engine.runRenderLoop(function () {
                     engine.runRenderLoop(function () {

BIN
Playground/scenes/ufo.glb


+ 29 - 4
Playground/ts.html

@@ -37,17 +37,18 @@
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
-        <!-- Monaco -->
-        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
         <!-- Babylon.js -->
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
+        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
         <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
         <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
-        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
+
+        <!-- Monaco -->
+        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
 
 
         <!-- Extensions -->
         <!-- Extensions -->
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>
@@ -56,6 +57,7 @@
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
                                
                                
         <link href="css/index.css" rel="stylesheet" />
         <link href="css/index.css" rel="stylesheet" />
+        <link href="css/color_ts.css" rel="stylesheet" />
     </head>
     </head>
 
 
     <body>
     <body>
@@ -144,6 +146,9 @@
                         <div class="option" onclick="setVersion('stable');">Stable</div>
                         <div class="option" onclick="setVersion('stable');">Stable</div>
                     </div>
                     </div>
                 </div>
                 </div>
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
             </div>
         </div>
         </div>
 
 
@@ -228,6 +233,12 @@
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
+
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
+            </div>
         </div>
         </div>
 
 
         <div class="navbar navBar1030">
         <div class="navbar navBar1030">
@@ -305,6 +316,12 @@
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
+
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
+            </div>
         </div>
         </div>
 
 
         <div class="navbar navBar750">
         <div class="navbar navBar750">
@@ -387,6 +404,14 @@
                 <canvas touch-action="none" id="renderCanvas"></canvas>
                 <canvas touch-action="none" id="renderCanvas"></canvas>
             </div>
             </div>
         </div>
         </div>
+        <div id="exampleList" class = "typescript">
+            <div id="exampleBanner">
+                <h1>Examples</h1>
+            </div>
+            <div class="horizontalSeparator"></div>
+            <input id="filterBar" type="text" placeholder="Filter examples...">
+            <img id="filterBarClear" src="https://d33wubrfki0l68.cloudfront.net/17ca450bae302631f4857cd8c3992234ec5dd9a7/057f9/img/ui/clear_button.png">
+        </div>
 
 
         <span class="label" id="fpsLabel">FPS</span>
         <span class="label" id="fpsLabel">FPS</span>
 
 
@@ -464,4 +489,4 @@
         </script>        
         </script>        
     </body>
     </body>
 
 
-</html>
+</html>

+ 0 - 1
Playground/zipContent/index.html

@@ -40,7 +40,6 @@
     <canvas id="renderCanvas"></canvas>
     <canvas id="renderCanvas"></canvas>
     <script>
     <script>
         var canvas = document.getElementById("renderCanvas");
         var canvas = document.getElementById("renderCanvas");
-        var engine = new BABYLON.Engine(canvas, true);
 
 
 ####INJECT####
 ####INJECT####
 
 

+ 32 - 25
Tools/DevLoader/BabylonLoader.js

@@ -130,7 +130,7 @@ var BABYLONDEVTOOLS;
             var style = document.createElement('link');
             var style = document.createElement('link');
             style.href = url;
             style.href = url;
             style.rel = "stylesheet";
             style.rel = "stylesheet";
-            style.type = "text/css"
+            style.type = "text/css";
             document.head.appendChild(style);
             document.head.appendChild(style);
         }
         }
 
 
@@ -141,36 +141,44 @@ var BABYLONDEVTOOLS;
         }
         }
 
 
         Loader.prototype.loadLibrary = function (library, module) {
         Loader.prototype.loadLibrary = function (library, module) {
+            if (library.preventLoadLibrary) {
+                return;
+            }
+
             if (!useDist) {
             if (!useDist) {
-                var i = 0;
-                for (; i < library.files.length; i++) {
-                    var file = library.files[i];
-                    if (file.indexOf('lib.d.ts') > 0) {
-                        continue;
-                    }
+                if (library.useOutputForDebugging) {
+                    this.loadScript(babylonJSPath + '/.temp' + module.build.distOutputDirectory + library.output);
+                } else {
+                    var i = 0;
+                    for (; i < library.files.length; i++) {
+                        var file = library.files[i];
+                        if (file.indexOf('lib.d.ts') > 0) {
+                            continue;
+                        }
 
 
-                    file = file.replace('.ts', '.js');
-                    file = file.replace('../', '');
-                    file = babylonJSPath + '/' + file;
-                    this.loadScript(file);
-                }
+                        file = file.replace('.ts', '.js');
+                        file = file.replace('../', '');
+                        file = babylonJSPath + '/' + file;
+                        this.loadScript(file);
+                    }
 
 
-                if (library.shaderFiles && library.shaderFiles.length > 0) {
-                    var shaderFile = library.shaderFiles[0];
-                    var endDirectoryIndex = shaderFile.lastIndexOf('/');
-                    shaderFile = shaderFile.substring(0, endDirectoryIndex + 1);
-                    shaderFile += library.output.replace('.js', '.js.fx');
-                    this.loadScript(shaderFile);
-                    if (library.shadersIncludeFiles) {
-                        var includeShaderFile = shaderFile.replace('.js.fx', '.js.include.fx');
-                        this.loadScript(includeShaderFile);
+                    if (library.shaderFiles && library.shaderFiles.length > 0) {
+                        var shaderFile = library.shaderFiles[0];
+                        var endDirectoryIndex = shaderFile.lastIndexOf('/');
+                        shaderFile = shaderFile.substring(0, endDirectoryIndex + 1);
+                        shaderFile += library.output.replace('.js', '.js.fx');
+                        this.loadScript(shaderFile);
+                        if (library.shadersIncludeFiles) {
+                            var includeShaderFile = shaderFile.replace('.js.fx', '.js.include.fx');
+                            this.loadScript(includeShaderFile);
+                        }
                     }
                     }
                 }
                 }
             }
             }
             else if (min) {
             else if (min) {
                 if (library.webpack) {
                 if (library.webpack) {
                     if (module.build.distOutputDirectory)
                     if (module.build.distOutputDirectory)
-                        this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output.replace('.js', '.bundle.js'));
+                        this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
                 }
                 }
                 else {
                 else {
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output.replace('.js', '.min.js'));
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output.replace('.js', '.min.js'));
@@ -181,6 +189,7 @@ var BABYLONDEVTOOLS;
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
             }
             }
 
 
+            // Currently not being used
             if (!min && library.sassFiles && library.sassFiles.length > 0) {
             if (!min && library.sassFiles && library.sassFiles.length > 0) {
                 var cssFile = library.output.replace('.js', '.css');
                 var cssFile = library.output.replace('.js', '.css');
                 cssFile = babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + cssFile;
                 cssFile = babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + cssFile;
@@ -242,10 +251,8 @@ var BABYLONDEVTOOLS;
 
 
             // Modules
             // Modules
             if (loadModules) {
             if (loadModules) {
+
                 for (var i = 0; i < settings.modules.length; i++) {
                 for (var i = 0; i < settings.modules.length; i++) {
-                    if (settings.modules[i] === "viewer") {
-                        continue;
-                    }
                     this.loadModule(settings[settings.modules[i]]);
                     this.loadModule(settings[settings.modules[i]]);
                 }
                 }
             }
             }

+ 113 - 154
Tools/Gulp/config.json

@@ -8,6 +8,7 @@
         "declarationModuleFilename": "babylon.module.d.ts",
         "declarationModuleFilename": "babylon.module.d.ts",
         "outputDirectory": "../../dist/preview release",
         "outputDirectory": "../../dist/preview release",
         "playgroundDirectory": "../../Playground/",
         "playgroundDirectory": "../../Playground/",
+        "tempDirectory": "../../.temp/",
         "intellisenseFile": "babylon.d.txt",
         "intellisenseFile": "babylon.d.txt",
         "intellisenseSources": [
         "intellisenseSources": [
             "../../dist/preview release/babylon.d.ts",
             "../../dist/preview release/babylon.d.ts",
@@ -123,7 +124,8 @@
             "imageProcessing",
             "imageProcessing",
             "occlusionQuery",
             "occlusionQuery",
             "transformFeedback",
             "transformFeedback",
-            "noise"
+            "noise",
+            "videoRecorder"
         ],
         ],
         "minimal": [
         "minimal": [
             "meshBuilder",
             "meshBuilder",
@@ -136,7 +138,7 @@
             "picking",
             "picking",
             "backgroundMaterial",
             "backgroundMaterial",
             "videoDome"
             "videoDome"
-        ]      
+        ]
     },
     },
     "workloads": {
     "workloads": {
         "core": {
         "core": {
@@ -227,7 +229,7 @@
                 "fresnelFunction",
                 "fresnelFunction",
                 "reflectionFunction",
                 "reflectionFunction",
                 "imageProcessingDeclaration",
                 "imageProcessingDeclaration",
-                "imageProcessingFunctions",                
+                "imageProcessingFunctions",
                 "bumpFragmentFunctions",
                 "bumpFragmentFunctions",
                 "clipPlaneFragmentDeclaration",
                 "clipPlaneFragmentDeclaration",
                 "fogFragmentDeclaration",
                 "fogFragmentDeclaration",
@@ -246,7 +248,7 @@
                 "core",
                 "core",
                 "debug"
                 "debug"
             ]
             ]
-        },          
+        },
         "occlusionQuery": {
         "occlusionQuery": {
             "files": [
             "files": [
                 "../../src/Engine/Extensions/babylon.engine.occlusionQuery.js"
                 "../../src/Engine/Extensions/babylon.engine.occlusionQuery.js"
@@ -255,7 +257,7 @@
                 "core",
                 "core",
                 "debug"
                 "debug"
             ]
             ]
-        },          
+        },
         "behaviors": {
         "behaviors": {
             "files": [
             "files": [
                 "../../src/Behaviors/babylon.behavior.js"
                 "../../src/Behaviors/babylon.behavior.js"
@@ -263,7 +265,7 @@
             "dependUpon": [
             "dependUpon": [
                 "core"
                 "core"
             ]
             ]
-        },   
+        },
         "imageProcessing": {
         "imageProcessing": {
             "files": [
             "files": [
                 "../../src/Materials/babylon.imageProcessingConfiguration.js",
                 "../../src/Materials/babylon.imageProcessingConfiguration.js",
@@ -273,8 +275,8 @@
             "dependUpon": [
             "dependUpon": [
                 "core"
                 "core"
             ]
             ]
-        },  
-        "noise" : {
+        },
+        "noise": {
             "files": [
             "files": [
                 "../../src/Materials/Textures/Procedurals/babylon.noiseProceduralTexture.js"
                 "../../src/Materials/Textures/Procedurals/babylon.noiseProceduralTexture.js"
             ],
             ],
@@ -285,14 +287,17 @@
             "shaders": [
             "shaders": [
                 "noise.fragment"
                 "noise.fragment"
             ]
             ]
-        },      
+        },
         "particles": {
         "particles": {
             "files": [
             "files": [
                 "../../src/Particles/babylon.particle.js",
                 "../../src/Particles/babylon.particle.js",
+                "../../src/Particles/babylon.baseParticleSystem.js",
                 "../../src/Particles/babylon.particleSystem.js",
                 "../../src/Particles/babylon.particleSystem.js",
                 "../../src/Particles/EmitterTypes/babylon.boxParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.boxParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.coneParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.coneParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.sphereParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.sphereParticleEmitter.js",
+                "../../src/Particles/EmitterTypes/babylon.hemisphericParticleEmitter.js",
+                "../../src/Particles/EmitterTypes/babylon.pointParticleEmitter.js",
                 "../../src/Particles/babylon.particleSystemComponent.js"
                 "../../src/Particles/babylon.particleSystemComponent.js"
             ],
             ],
             "dependUpon": [
             "dependUpon": [
@@ -571,7 +576,8 @@
                 "../../src/Audio/babylon.audioEngine.js",
                 "../../src/Audio/babylon.audioEngine.js",
                 "../../src/Audio/babylon.sound.js",
                 "../../src/Audio/babylon.sound.js",
                 "../../src/Audio/babylon.soundtrack.js",
                 "../../src/Audio/babylon.soundtrack.js",
-                "../../src/Audio/babylon.analyser.js"
+                "../../src/Audio/babylon.analyser.js",
+                "../../src/Audio/babylon.weightedsound.js"
             ],
             ],
             "dependUpon": [
             "dependUpon": [
                 "core"
                 "core"
@@ -1083,7 +1089,7 @@
             ]
             ]
         },
         },
         "textureFormats": {
         "textureFormats": {
-            "files": [ ],
+            "files": [],
             "dependUpon": [
             "dependUpon": [
                 "dds",
                 "dds",
                 "tga",
                 "tga",
@@ -1208,7 +1214,7 @@
             "shaders": [
             "shaders": [
                 "anaglyph.fragment"
                 "anaglyph.fragment"
             ]
             ]
-        },       
+        },
         "stereoscopic": {
         "stereoscopic": {
             "files": [
             "files": [
                 "../../src/PostProcess/babylon.stereoscopicInterlacePostProcess.js",
                 "../../src/PostProcess/babylon.stereoscopicInterlacePostProcess.js",
@@ -1226,7 +1232,7 @@
             "shaders": [
             "shaders": [
                 "stereoscopicInterlace.fragment"
                 "stereoscopicInterlace.fragment"
             ]
             ]
-        },           
+        },
         "vr": {
         "vr": {
             "files": [
             "files": [
                 "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
                 "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
@@ -1386,7 +1392,16 @@
                 "meshBuilder",
                 "meshBuilder",
                 "additionalTextures"
                 "additionalTextures"
             ]
             ]
+        },
+        "videoRecorder": {
+            "files": [
+                "../../src/Tools/babylon.videoRecorder.js"
+            ],
+            "dependUpon": [
+                "core"
+            ]
         }
         }
+
     },
     },
     "typescript": [
     "typescript": [
         "../../src/**/*.ts",
         "../../src/**/*.ts",
@@ -1409,8 +1424,8 @@
         "proceduralTexturesLibrary",
         "proceduralTexturesLibrary",
         "loaders",
         "loaders",
         "serializers",
         "serializers",
-        "inspector",
         "gui",
         "gui",
+        "inspector",
         "viewer",
         "viewer",
         "viewer-assets"
         "viewer-assets"
     ],
     ],
@@ -1749,6 +1764,7 @@
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.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_minecraftMesh.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts",
@@ -1774,6 +1790,7 @@
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.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_minecraftMesh.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts",
@@ -1844,146 +1861,72 @@
     "gui": {
     "gui": {
         "libraries": [
         "libraries": [
             {
             {
-                "files": [
-                    "../../gui/src/2D/style.ts",
-                    "../../gui/src/2D/valueAndUnit.ts",
-                    "../../gui/src/2D/advancedDynamicTexture.ts",
-                    "../../gui/src/2D/measure.ts",
-                    "../../gui/src/2D/math2D.ts",
-                    "../../gui/src/2D/multiLinePoint.ts",
-                    "../../gui/src/2D/controls/control.ts",
-                    "../../gui/src/2D/controls/container.ts",
-                    "../../gui/src/2D/controls/stackPanel.ts",
-                    "../../gui/src/2D/controls/rectangle.ts",
-                    "../../gui/src/2D/controls/ellipse.ts",
-                    "../../gui/src/2D/controls/line.ts",
-                    "../../gui/src/2D/controls/slider.ts",
-                    "../../gui/src/2D/controls/checkbox.ts",
-                    "../../gui/src/2D/controls/radioButton.ts",
-                    "../../gui/src/2D/controls/textBlock.ts",
-                    "../../gui/src/2D/controls/image.ts",
-                    "../../gui/src/2D/controls/button.ts",
-                    "../../gui/src/2D/controls/colorpicker.ts",
-                    "../../gui/src/2D/controls/inputText.ts",
-                    "../../gui/src/2D/controls/inputPassword.ts",
-                    "../../gui/src/2D/controls/virtualKeyboard.ts",
-                    "../../gui/src/2D/controls/multiLine.ts",
-                    "../../gui/src/2D/controls/grid.ts",                    
-                    "../../gui/src/3D/gui3DManager.ts",
-                    "../../gui/src/3D/materials/fluentMaterial.ts",
-                    "../../gui/src/3D/vector3WithInfo.ts",
-                    "../../gui/src/3D/controls/control3D.ts",
-                    "../../gui/src/3D/controls/container3D.ts",
-                    "../../gui/src/3D/controls/abstractButton3D.ts",
-                    "../../gui/src/3D/controls/button3D.ts",
-                    "../../gui/src/3D/controls/meshButton3D.ts",
-                    "../../gui/src/3D/controls/holographicButton.ts",
-                    "../../gui/src/3D/controls/stackPanel3D.ts",
-                    "../../gui/src/3D/controls/volumeBasedPanel.ts",
-                    "../../gui/src/3D/controls/spherePanel.ts",
-                    "../../gui/src/3D/controls/planePanel.ts",
-                    "../../gui/src/3D/controls/scatterPanel.ts",
-                    "../../gui/src/3D/controls/cylinderPanel.ts"
-                ],
-                "shaderFiles": [
-                    "../../gui/src/3D/materials/shaders/fluent.vertex.fx",
-                    "../../gui/src/3D/materials/shaders/fluent.fragment.fx"
-                ],
-                "output": "babylon.gui.js",
-                "buildAsModule": true,
-                "moduleName": "babylonjs-gui",
-                "moduleDeclaration": {
-                    "name": "GUI",
-                    "module": "babylonjs-gui"
-                }
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.gui.min.js",
+                "webpack": "../../gui/webpack.config.js",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true
             }
             }
         ],
         ],
         "build": {
         "build": {
-            "srcOutputDirectory": "../../gui/",
-            "distOutputDirectory": "/gui/"
+            "srcOutputDirectory": "../../gui/src/",
+            "distOutputDirectory": "/gui/",
+            "dtsBundle": {
+                "name": "babylonjs-gui",
+                "main": "../../dist/preview release/gui/build/index.d.ts",
+                "out": "../babylon.gui.module.d.ts",
+                "baseDir": "../../dist/preview release/gui/build/",
+                "headerText": "BabylonJS GUI"
+            },
+            "processDeclaration": {
+                "filename": "babylon.gui.module.d.ts",
+                "packageName": "babylonjs-gui",
+                "moduleName": "BABYLON.GUI",
+                "importsToRemove": [],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON",
+                    "babylonjs-serializers": "BABYLON"
+                }
+            }
         }
         }
     },
     },
     "inspector": {
     "inspector": {
         "libraries": [
         "libraries": [
             {
             {
-                "files": [
-                    "../../inspector/src/Inspector.ts",
-                    "../../inspector/src/properties.ts",
-                    "../../inspector/src/properties_gui.ts",
-                    "../../inspector/src/gui/BasicElement.ts",
-                    "../../inspector/src/adapters/Adapter.ts",
-                    "../../inspector/src/adapters/CameraAdapter.ts",
-                    "../../inspector/src/adapters/PhysicsImpostorAdapter.ts",
-                    "../../inspector/src/adapters/GUIAdapter.ts",
-                    "../../inspector/src/adapters/SoundAdapter.ts",
-                    "../../inspector/src/adapters/TextureAdapter.ts",
-                    "../../inspector/src/adapters/LightAdapter.ts",
-                    "../../inspector/src/adapters/MaterialAdapter.ts",
-                    "../../inspector/src/adapters/MeshAdapter.ts",
-                    "../../inspector/src/adapters/PhysicsImpostorAdapter.ts",
-                    "../../inspector/src/details/DetailPanel.ts",
-                    "../../inspector/src/details/Property.ts",
-                    "../../inspector/src/details/PropertyLine.ts",
-                    "../../inspector/src/gui/ColorElement.ts",
-                    "../../inspector/src/gui/ColorPickerElement.ts",
-                    "../../inspector/src/gui/CubeTextureElement.ts",
-                    "../../inspector/src/gui/HDRCubeTextureElement.ts",
-                    "../../inspector/src/gui/SearchBar.ts",
-                    "../../inspector/src/gui/TextureElement.ts",
-                    "../../inspector/src/gui/Tooltip.ts",
-                    "../../inspector/src/helpers/Helpers.ts",
-                    "../../inspector/src/scheduler/Scheduler.ts",
-                    "../../inspector/src/tabs/Tab.ts",
-                    "../../inspector/src/tabs/PropertyTab.ts",
-                    "../../inspector/src/tabs/CameraTab.ts",
-                    "../../inspector/src/tabs/GUITab.ts",
-                    "../../inspector/src/tabs/PhysicsTab.ts",
-                    "../../inspector/src/tabs/SoundTab.ts",
-                    "../../inspector/src/tabs/TextureTab.ts",
-                    "../../inspector/src/tabs/LightTab.ts",
-                    "../../inspector/src/tabs/MaterialTab.ts",
-                    "../../inspector/src/tabs/MeshTab.ts",
-                    "../../inspector/src/tabs/SceneTab.ts",
-                    "../../inspector/src/tabs/ConsoleTab.ts",
-                    "../../inspector/src/tabs/StatsTab.ts",
-                    "../../inspector/src/tabs/GLTFTab.ts",
-                    "../../inspector/src/tabs/ToolsTab.ts",
-                    "../../inspector/src/tabs/TabBar.ts",
-                    "../../inspector/src/tools/AbstractTool.ts",
-                    "../../inspector/src/tools/PauseScheduleTool.ts",
-                    "../../inspector/src/tools/PickTool.ts",
-                    "../../inspector/src/tools/PopupTool.ts",
-                    "../../inspector/src/tools/RefreshTool.ts",
-                    "../../inspector/src/tools/LabelTool.ts",
-                    "../../inspector/src/tools/Toolbar.ts",
-                    "../../inspector/src/tools/DisposeTool.ts",
-                    "../../inspector/src/tools/FullscreenTool.ts",
-                    "../../inspector/src/tree/TreeItem.ts",
-                    "../../inspector/src/treetools/AbstractTreeTool.ts",
-                    "../../inspector/src/treetools/BoundingBox.ts",
-                    "../../inspector/src/treetools/CameraPOV.ts",
-                    "../../inspector/src/treetools/SoundInteractions.ts",
-                    "../../inspector/src/treetools/Checkbox.ts",
-                    "../../inspector/src/treetools/DebugArea.ts",
-                    "../../inspector/src/treetools/Info.ts",
-                    "../../inspector/src/lib.d.ts"
-                ],
-                "sassFiles": [
-                    "../../inspector/sass/**/*.scss"
-                ],
-                "output": "babylon.inspector.js",
+                "files": [],
+                "sassFiles": [],
+                "output": "babylon.inspector.bundle.js",
                 "webpack": "../../inspector/webpack.config.js",
                 "webpack": "../../inspector/webpack.config.js",
                 "bundle": "true",
                 "bundle": "true",
-                "moduleDeclaration": {
-                    "name": "INSPECTOR",
-                    "module": "babylonjs-inspector"
-                },
-                "extendsRoot": true
+                "extendsRoot": true,
+                "useOutputForDebugging": true
             }
             }
         ],
         ],
         "build": {
         "build": {
-            "srcOutputDirectory": "../../inspector/",
-            "distOutputDirectory": "/inspector/"
+            "srcOutputDirectory": "../../inspector/src/",
+            "distOutputDirectory": "/inspector/",
+            "dtsBundle": {
+                "name": "babylonjs-inspector",
+                "main": "../../dist/preview release/inspector/build/index.d.ts",
+                "out": "../babylon.inspector.module.d.ts",
+                "baseDir": "../../dist/preview release/inspector/build/",
+                "headerText": "BabylonJS Inspector"
+            },
+            "processDeclaration": {
+                "filename": "babylon.inspector.module.d.ts",
+                "packageName": "babylonjs-inspector",
+                "moduleName": "INSPECTOR",
+                "importsToRemove": [],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON",
+                    "babylonjs-serializers": "BABYLON",
+                    "babylonjs-gui": "BABYLON.GUI"
+                }
+            }
         }
         }
     },
     },
     "viewer": {
     "viewer": {
@@ -1998,21 +1941,35 @@
                     "name": "BabylonViewer",
                     "name": "BabylonViewer",
                     "module": "babylonjs-viewer"
                     "module": "babylonjs-viewer"
                 },
                 },
-                "babylonIncluded": true
+                "babylonIncluded": true,
+                "noWatch": true,
+                "preventLoadLibrary": true
             }
             }
         ],
         ],
         "build": {
         "build": {
             "srcOutputDirectory": "../../Viewer/",
             "srcOutputDirectory": "../../Viewer/",
+            "distOutputDirectory": "/viewer/",
             "dtsBundle": {
             "dtsBundle": {
                 "name": "babylonjs-viewer",
                 "name": "babylonjs-viewer",
-                "main": "../../Viewer/dist/build/src/index.d.ts",
-                "out": "../../../../dist/preview release/viewer/babylon.viewer.module.d.ts",
-                "legacyDeclaration": true,
+                "main": "../../dist/preview release/viewer/build/src/index.d.ts",
+                "out": "../../babylon.viewer.module.d.ts",
                 "prependText": "/// <reference path=\"./babylon.d.ts\"/>\n/// <reference path=\"./babylon.glTF2Interface.d.ts\"/>\n/// <reference path=\"./babylonjs.loaders.d.ts\"/>\ndeclare module \"babylonjs-loaders\"{ export=BABYLON;}\n"
                 "prependText": "/// <reference path=\"./babylon.d.ts\"/>\n/// <reference path=\"./babylon.glTF2Interface.d.ts\"/>\n/// <reference path=\"./babylonjs.loaders.d.ts\"/>\ndeclare module \"babylonjs-loaders\"{ export=BABYLON;}\n"
             },
             },
+            "processDeclaration": {
+                "packageName": "babylonjs-viewer",
+                "moduleName": "BabylonViewer",
+                "importsToRemove": [
+                    "pep",
+                    "babylonjs-loaders"
+                ],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON"
+                }
+            },
             "outputs": [
             "outputs": [
                 {
                 {
-                    "destination": [
+                    "destinations": [
                         {
                         {
                             "filename": "viewer.js",
                             "filename": "viewer.js",
                             "outputDirectory": "/../../Viewer/dist/"
                             "outputDirectory": "/../../Viewer/dist/"
@@ -2030,7 +1987,7 @@
                     "minified": true
                     "minified": true
                 },
                 },
                 {
                 {
-                    "destination": [
+                    "destinations": [
                         {
                         {
                             "filename": "viewer.max.js",
                             "filename": "viewer.max.js",
                             "outputDirectory": "/../../Viewer/dist/"
                             "outputDirectory": "/../../Viewer/dist/"
@@ -2056,23 +2013,25 @@
                     "name": "BabylonViewerAssets",
                     "name": "BabylonViewerAssets",
                     "module": "babylonjs-viewer-assets"
                     "module": "babylonjs-viewer-assets"
                 },
                 },
-                "babylonIncluded": true
+                "babylonIncluded": true,
+                "noWatch": true,
+                "preventLoadLibrary": true
             }
             }
         ],
         ],
         "build": {
         "build": {
             "srcOutputDirectory": "../../Viewer/",
             "srcOutputDirectory": "../../Viewer/",
+            "distOutputDirectory": "/viewer/",
             "dtsBundle": {
             "dtsBundle": {
                 "name": "babylonjs-viewer-assets",
                 "name": "babylonjs-viewer-assets",
-                "baseDir": "../../Viewer/dist/build/src/assets/",
-                "main": "../../Viewer/dist/build/src/assets/index.d.ts",
-                "out": "../../../build/assets/babylon.viewer.assets.module.d.ts"
+                "main": "../../dist/preview release/viewer/build/src/assets/index.d.ts",
+                "out": "../../../../../../Viewer/build/assets/babylon.viewer.assets.module.d.ts"
             },
             },
             "outputs": [
             "outputs": [
                 {
                 {
-                    "destination": [
+                    "destinations": [
                         {
                         {
                             "filename": "babylon.viewer.assets.js",
                             "filename": "babylon.viewer.assets.js",
-                            "outputDirectory": "/../../Viewer/dist/build/assets/"
+                            "outputDirectory": "/../../Viewer/build/assets/"
                         }
                         }
                     ],
                     ],
                     "minified": true
                     "minified": true
@@ -2080,4 +2039,4 @@
             ]
             ]
         }
         }
     }
     }
-}
+}

+ 160 - 107
Tools/Gulp/gulpfile.js

@@ -16,7 +16,6 @@ var merge2 = require("merge2");
 var concat = require("gulp-concat");
 var concat = require("gulp-concat");
 var rename = require("gulp-rename");
 var rename = require("gulp-rename");
 var cleants = require("gulp-clean-ts-extends");
 var cleants = require("gulp-clean-ts-extends");
-var changedInPlace = require("gulp-changed-in-place");
 var runSequence = require("run-sequence");
 var runSequence = require("run-sequence");
 var replace = require("gulp-replace");
 var replace = require("gulp-replace");
 var uncommentShader = require("./gulp-removeShaderComments");
 var uncommentShader = require("./gulp-removeShaderComments");
@@ -25,17 +24,17 @@ var optimisejs = require("gulp-optimize-js");
 var webserver = require("gulp-webserver");
 var webserver = require("gulp-webserver");
 var path = require("path");
 var path = require("path");
 var sass = require("gulp-sass");
 var sass = require("gulp-sass");
-var webpack = require("webpack-stream");
+const webpack = require('webpack');
+var webpackStream = require("webpack-stream");
 var typedoc = require("gulp-typedoc");
 var typedoc = require("gulp-typedoc");
 var validateTypedoc = require("./gulp-validateTypedoc");
 var validateTypedoc = require("./gulp-validateTypedoc");
-var request = require('request');
 var fs = require("fs");
 var fs = require("fs");
 var dtsBundle = require('dts-bundle');
 var dtsBundle = require('dts-bundle');
 const through = require('through2');
 const through = require('through2');
 var karmaServer = require('karma').Server;
 var karmaServer = require('karma').Server;
 
 
 //viewer declaration
 //viewer declaration
-var processViewerDeclaration = require('./processViewerDeclaration');
+var processDeclaration = require('./processViewerDeclaration');
 
 
 var config = require("./config.json");
 var config = require("./config.json");
 
 
@@ -448,107 +447,135 @@ var buildExternalLibrary = function (library, settings, watch) {
 
 
         if (library.webpack) {
         if (library.webpack) {
             let sequence = [waitAll];
             let sequence = [waitAll];
-            let wpBuild = webpack(require(library.webpack));
-            if (settings.build.outputs) {
-                //shoud dtsBundle create the declaration?
-                if (settings.build.dtsBundle) {
-                    let event = wpBuild
-                        .pipe(through.obj(function (file, enc, cb) {
-                            // only declaration files
-                            const isdts = /\.d\.ts$/.test(file.path);
-                            if (isdts) this.push(file);
-                            cb();
-                        }))
-                        .pipe(gulp.dest('.'));
-                    // dts-bundle does NOT support (gulp) streams, so files have to be saved and reloaded, 
-                    // until I fix it
-                    event.on("end", function () {
-                        // create the file
-                        dtsBundle.bundle(settings.build.dtsBundle);
-                        // prepend the needed reference
-                        let fileLocation = path.join(path.dirname(settings.build.dtsBundle.main), settings.build.dtsBundle.out);
-                        fs.readFile(fileLocation, function (err, data) {
-                            if (err) throw err;
-                            data = (settings.build.dtsBundle.prependText || "") + '\n' + data.toString();
-                            fs.writeFile(fileLocation, data);
-                            if (settings.build.dtsBundle.legacyDeclaration) {
-                                var newData = processViewerDeclaration(data);
-                                fs.writeFile(fileLocation.replace('.module', ''), newData);
-                            }
-                        });
-                    });
-                }
 
 
-                let build = wpBuild
-                    .pipe(through.obj(function (file, enc, cb) {
-                        // only pipe js files
-                        const isJs = /\.js$/.test(file.path);
-                        if (isJs) this.push(file);
-                        cb();
-                    }))
-                    .pipe(addModuleExports(library.moduleDeclaration, { subModule: false, extendsRoot: false, externalUsingBabylon: true, noBabylonInit: library.babylonIncluded }));
+            if (settings.build.outputs) {
 
 
-                let unminifiedOutpus = [];
-                let minifiedOutputs = [];
                 settings.build.outputs.forEach(out => {
                 settings.build.outputs.forEach(out => {
-                    if (out.minified) {
-                        out.destination.forEach(dest => {
-                            minifiedOutputs.push(dest);
-                        });
-                    } else {
-                        out.destination.forEach(dest => {
-                            unminifiedOutpus.push(dest);
+                    let wpConfig = require(library.webpack);
+                    if (!out.minified) {
+                        wpConfig.mode = "development";
+                    }
+                    let wpBuild = webpackStream(wpConfig, webpack);
+
+                    //shoud dtsBundle create the declaration?
+                    if (settings.build.dtsBundle) {
+                        let event = wpBuild
+                            .pipe(through.obj(function (file, enc, cb) {
+                                // only declaration files
+                                const isdts = /\.d\.ts$/.test(file.path);
+                                if (isdts) this.push(file);
+                                cb();
+                            }))
+                            .pipe(gulp.dest(outputDirectory));
+                        // dts-bundle does NOT support (gulp) streams, so files have to be saved and reloaded, 
+                        // until I fix it
+                        event.on("end", function () {
+                            // create the file
+                            dtsBundle.bundle(settings.build.dtsBundle);
+                            // prepend the needed reference
+                            let fileLocation = path.join(path.dirname(settings.build.dtsBundle.main), settings.build.dtsBundle.out);
+                            fs.readFile(fileLocation, function (err, data) {
+                                if (err) throw err;
+                                data = (settings.build.dtsBundle.prependText || "") + '\n' + data.toString();
+                                fs.writeFile(fileLocation, data);
+                                if (settings.build.processDeclaration) {
+                                    var newData = processDeclaration(data, settings.build.processDeclaration);
+                                    fs.writeFile(fileLocation.replace('.module', ''), newData);
+                                }
+                            });
                         });
                         });
                     }
                     }
-                });
-
-                function processDestination(dest) {
-                    var outputDirectory = config.build.outputDirectory + dest.outputDirectory;
-                    build = build
-                        .pipe(rename(dest.filename.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
-                        .pipe(gulp.dest(outputDirectory));
 
 
-                    if (library.babylonIncluded && dest.addBabylonDeclaration) {
-                        // include the babylon declaration
-                        if (dest.addBabylonDeclaration === true) {
-                            dest.addBabylonDeclaration = [config.build.declarationFilename];
+                    let build = wpBuild
+                        .pipe(through.obj(function (file, enc, cb) {
+                            // only pipe js files
+                            const isJs = /\.js$/.test(file.path);
+                            if (isJs) this.push(file);
+                            cb();
+                        }))
+                        .pipe(addModuleExports(library.moduleDeclaration, { subModule: false, extendsRoot: false, externalUsingBabylon: true, noBabylonInit: library.babylonIncluded }));
+
+                    function processDestination(dest) {
+                        var outputDirectory = config.build.outputDirectory + dest.outputDirectory;
+                        build = build
+                            .pipe(rename(dest.filename.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
+                            .pipe(gulp.dest(outputDirectory));
+
+                        if (library.babylonIncluded && dest.addBabylonDeclaration) {
+                            // include the babylon declaration
+                            if (dest.addBabylonDeclaration === true) {
+                                dest.addBabylonDeclaration = [config.build.declarationFilename];
+                            }
+                            var decsToAdd = dest.addBabylonDeclaration.map(function (dec) {
+                                return config.build.outputDirectory + '/' + dec;
+                            });
+                            sequence.unshift(gulp.src(decsToAdd)
+                                .pipe(rename(function (path) {
+                                    path.dirname = '';
+                                }))
+                                .pipe(gulp.dest(outputDirectory)))
                         }
                         }
-                        var decsToAdd = dest.addBabylonDeclaration.map(function (dec) {
-                            return config.build.outputDirectory + '/' + dec;
-                        });
-                        sequence.unshift(gulp.src(decsToAdd)
-                            .pipe(rename(function (path) {
-                                path.dirname = '';
-                            }))
-                            .pipe(gulp.dest(outputDirectory)))
                     }
                     }
-                }
 
 
-                unminifiedOutpus.forEach(dest => {
-                    processDestination(dest);
-                });
+                    out.destinations.forEach(dest => {
+                        processDestination(dest);
+                    });
 
 
-                if (minifiedOutputs.length) {
-                    build = build
-                        .pipe(uglify())
-                        .pipe(optimisejs())
-                }
+                    sequence.push(build);
 
 
-                minifiedOutputs.forEach(dest => {
-                    processDestination(dest);
                 });
                 });
 
 
-                sequence.push(build);
+
 
 
             } else {
             } else {
+
+                let wpBuild = webpackStream(require(library.webpack), webpack);
+
+                let buildEvent = wpBuild
+                    .pipe(gulp.dest(outputDirectory))
+                    //back-compat
+                    .pipe(through.obj(function (file, enc, cb) {
+                        // only js files
+                        const isjs = /\.js$/.test(file.path);
+                        if (isjs) this.push(file);
+                        cb();
+                    }))
+                    .pipe(rename(library.output.replace(".js", ".max.js")))
+                    .pipe(rename(library.output.replace(".min.max.", ".")))
+                    .pipe(rename(library.output.replace(".bundle.max.", ".")))
+                    .pipe(gulp.dest(outputDirectory));
                 sequence.push(
                 sequence.push(
-                    wpBuild
-                        .pipe(rename(library.output.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
-                        .pipe(addModuleExports(library.moduleDeclaration, { subModule: false, extendsRoot: library.extendsRoot, externalUsingBabylon: true }))
-                        .pipe(uglify())
-                        .pipe(optimisejs())
-                        .pipe(gulp.dest(outputDirectory))
-                )
+                    buildEvent
+                );
+                if (settings.build.dtsBundle || settings.build.processDeclaration) {
+                    buildEvent.on("end", function () {
+                        if (settings.build.dtsBundle) {
+                            dtsBundle.bundle(settings.build.dtsBundle);
+                        } if (settings.build.processDeclaration) {
+                            let fileLocation = path.join(outputDirectory, settings.build.processDeclaration.filename);
+                            fs.readFile(fileLocation, function (err, data) {
+                                if (err) throw err;
+                                var newData = processDeclaration(data, settings.build.processDeclaration);
+                                fs.writeFile(fileLocation.replace('.module', ''), newData);
+                                //legacy module support
+                                fs.writeFile(fileLocation, data + "\n" + newData);
+                            });
+                        }
+                    });
+                }
+                /*if (settings.build.processDeclaration) {
+                    sequence.push(
+                        wpBuild
+                            .pipe(through.obj(function (file, enc, cb) {
+                                // only js files
+                                const isDts = /\.d.ts$/.test(file.path);
+                                file.contents = new Buffer(processDeclaration(file.contents, settings.build.processDeclaration));
+                                if (isDts) this.push(file);
+                                cb();
+                            }))
+                            .pipe(gulp.dest(outputDirectory))
+                    )
+                }*/
             }
             }
 
 
             return merge2(sequence);
             return merge2(sequence);
@@ -600,7 +627,7 @@ gulp.task("build-custom", function (cb) {
  * Do it all.
  * Do it all.
  */
  */
 gulp.task("typescript-all", function (cb) {
 gulp.task("typescript-all", function (cb) {
-    runSequence("typescript", "typescript-libraries", cb);
+    runSequence("typescript", "typescript-libraries", "netlify-cleanup", cb);
 });
 });
 
 
 /**
 /**
@@ -623,22 +650,35 @@ gulp.task("watch", ["srcTscWatch"], function () {
     var tasks = [];
     var tasks = [];
 
 
     config.modules.map(function (module) {
     config.modules.map(function (module) {
+
         config[module].libraries.map(function (library) {
         config[module].libraries.map(function (library) {
-            tasks.push(gulp.watch(library.files, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug());
-            }));
-            tasks.push(gulp.watch(library.shaderFiles, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug())
-            }));
-            tasks.push(gulp.watch(library.sassFiles, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug())
-            }));
+            if (library.webpack) {
+                if (library.noWatch) return;
+                var outputDirectory = config.build.tempDirectory + config[module].build.distOutputDirectory;
+                let wpconfig = require(library.webpack);
+                wpconfig.watch = true;
+                // dev mode and absolute path sourcemaps for debugging
+                wpconfig.mode = "development";
+                wpconfig.output.devtoolModuleFilenameTemplate = "[absolute-resource-path]";
+                //config.stats = "minimal";
+                tasks.push(webpackStream(wpconfig, webpack).pipe(gulp.dest(outputDirectory)))
+            } else {
+                tasks.push(gulp.watch(library.files, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug());
+                }));
+                tasks.push(gulp.watch(library.shaderFiles, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug())
+                }));
+                tasks.push(gulp.watch(library.sassFiles, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug())
+                }));
+            }
         });
         });
     });
     });
 
 
@@ -696,6 +736,19 @@ gulp.task("clean-JS-MAP", function () {
     ], { force: true });
     ], { force: true });
 });
 });
 
 
+gulp.task("netlify-cleanup", function () {
+    //set by netlify
+    if (process.env.REPOSITORY_URL) {
+        return del([
+            "../../inspector/node_modules/**/*", "../../gui/node_modules/**/*",
+            "../../Viewer/node_modules/**/*"
+        ], { force: true });
+    }
+    else {
+        return true;
+    }
+})
+
 // this is needed for the modules for the declaration files.
 // this is needed for the modules for the declaration files.
 gulp.task("modules-compile", function () {
 gulp.task("modules-compile", function () {
     var tsResult = gulp.src(config.typescript)
     var tsResult = gulp.src(config.typescript)
@@ -1131,7 +1184,7 @@ gulp.task("tests-viewer-validation-browserstack", ["tests-viewer-validation-tran
  */
  */
 gulp.task("tests-viewer-validation-transpile", function (done) {
 gulp.task("tests-viewer-validation-transpile", function (done) {
 
 
-    let wpBuild = webpack(require('../../Viewer//webpack.gulp.config.js'));
+    let wpBuild = webpackStream(require('../../Viewer/webpack.gulp.config.js'), webpack);
 
 
     // clean the built directory
     // clean the built directory
     rmDir("../../Viewer/tests/build/");
     rmDir("../../Viewer/tests/build/");
@@ -1150,7 +1203,7 @@ gulp.task("tests-viewer-validation-transpile", function (done) {
  */
  */
 gulp.task("tests-viewer-transpile", function (done) {
 gulp.task("tests-viewer-transpile", function (done) {
 
 
-    let wpBuild = webpack(require('../../Viewer/tests/unit/webpack.config.js'));
+    let wpBuild = webpackStream(require('../../Viewer/tests/unit/webpack.config.js'), webpack);
 
 
     // clean the built directory
     // clean the built directory
     rmDir("../../Viewer/tests/build/");
     rmDir("../../Viewer/tests/build/");

+ 10 - 9
Tools/Gulp/package.json

@@ -9,13 +9,13 @@
     "readme": "https://github.com/BabylonJS/Babylon.js/edit/master/readme.md",
     "readme": "https://github.com/BabylonJS/Babylon.js/edit/master/readme.md",
     "license": "(Apache-2.0)",
     "license": "(Apache-2.0)",
     "devDependencies": {
     "devDependencies": {
-        "@types/node": "^8.9.4",
+        "@types/node": "^8.10.21",
         "base64-font-loader": "0.0.4",
         "base64-font-loader": "0.0.4",
         "base64-image-loader": "^1.2.1",
         "base64-image-loader": "^1.2.1",
         "chai": "^4.1.2",
         "chai": "^4.1.2",
         "color-support": "^1.1.3",
         "color-support": "^1.1.3",
         "css-loader": "^0.25.0",
         "css-loader": "^0.25.0",
-        "deepmerge": "^2.0.1",
+        "deepmerge": "^2.1.1",
         "del": "2.2.2",
         "del": "2.2.2",
         "es6-promise": "^4.2.4",
         "es6-promise": "^4.2.4",
         "exports-loader": "^0.6.4",
         "exports-loader": "^0.6.4",
@@ -27,7 +27,7 @@
         "gulp-debug": "^3.2.0",
         "gulp-debug": "^3.2.0",
         "gulp-expect-file": "^0.0.7",
         "gulp-expect-file": "^0.0.7",
         "gulp-optimize-js": "^1.0.2",
         "gulp-optimize-js": "^1.0.2",
-        "gulp-rename": "~1.2.2",
+        "gulp-rename": "^1.2.3",
         "gulp-replace": "~0.5.3",
         "gulp-replace": "~0.5.3",
         "gulp-sass": "3.1.0",
         "gulp-sass": "3.1.0",
         "gulp-sourcemaps": "~1.9.1",
         "gulp-sourcemaps": "~1.9.1",
@@ -40,7 +40,7 @@
         "html-loader": "^0.5.5",
         "html-loader": "^0.5.5",
         "imports-loader": "^0.7.1",
         "imports-loader": "^0.7.1",
         "json-loader": "^0.5.7",
         "json-loader": "^0.5.7",
-        "karma": "^2.0.0",
+        "karma": "^2.0.4",
         "karma-browserstack-launcher": "^1.3.0",
         "karma-browserstack-launcher": "^1.3.0",
         "karma-chai": "^0.1.0",
         "karma-chai": "^0.1.0",
         "karma-chrome-launcher": "^2.2.0",
         "karma-chrome-launcher": "^2.2.0",
@@ -53,20 +53,21 @@
         "mocha": "^4.0.1",
         "mocha": "^4.0.1",
         "phantomjs": "^2.1.7",
         "phantomjs": "^2.1.7",
         "run-sequence": "~1.1.0",
         "run-sequence": "~1.1.0",
-        "sinon": "^4.3.0",
+        "sinon": "^4.5.0",
         "style-loader": "^0.13.2",
         "style-loader": "^0.13.2",
         "through2": "~0.6.5",
         "through2": "~0.6.5",
         "ts-loader": "^2.3.7",
         "ts-loader": "^2.3.7",
         "typedoc": "^0.9.0",
         "typedoc": "^0.9.0",
-        "typescript": "~2.8.1",
-        "webpack-stream": "^4.0.1"
+        "typescript": "^2.8.4",
+        "webpack": "^4.16.1",
+        "webpack-stream": "^4.0.3"
     },
     },
     "scripts": {
     "scripts": {
-        "install": "npm --prefix ../../Playground/ install ../../Playground/ && npm --prefix ../../tests/unit/ install ../../tests/unit/ && npm --prefix ../../Viewer/tests/ install ../../Viewer/tests/ && cd ../../Viewer && npm install && cd ../Tools/Gulp/ && gulp deployLocalDev"
+        "install": "cd ../../gui && npm install && cd ../Tools/Gulp/ &&  cd ../../inspector && npm install && cd ../Tools/Gulp/ && npm --prefix ../../Playground/ install ../../Playground/ && npm --prefix ../../tests/unit/ install ../../tests/unit/ && npm --prefix ../../Viewer/tests/ install ../../Viewer/tests/ && cd ../../Viewer && npm install && cd ../Tools/Gulp/ && gulp deployLocalDev"
     },
     },
     "dependencies": {
     "dependencies": {
         "dts-bundle": "^0.7.3",
         "dts-bundle": "^0.7.3",
         "gulp-clean": "^0.4.0",
         "gulp-clean": "^0.4.0",
-        "npm": "^5.8.0"
+        "npm": "^5.10.0"
     }
     }
 }
 }

+ 51 - 19
Tools/Gulp/processViewerDeclaration.js

@@ -1,4 +1,13 @@
-module.exports = function (data) {
+module.exports = function (data, options) {
+
+    /*
+    {
+        packageName: string,
+        moduleName: string,
+        importsToRemove: Array<string>,
+        classMap
+    }
+    */
 
 
     var str = "" + data;
     var str = "" + data;
 
 
@@ -6,35 +15,58 @@ module.exports = function (data) {
     // str = str.replace(/declare module 'babylonjs-viewer\/' {((?!(declare))(.|\n))*\n}/g, '');
     // str = str.replace(/declare module 'babylonjs-viewer\/' {((?!(declare))(.|\n))*\n}/g, '');
 
 
     let lines = str.split('\n');
     let lines = str.split('\n');
-    var firstIndex = lines.findIndex((line => { return line.indexOf("'babylonjs-viewer/'") !== -1 }));
+    var firstIndex = lines.findIndex((line => { return line.indexOf(`'${options.packageName}/'`) !== -1 }));
     var lastIndex = lines.findIndex(((line, idx) => { return line.trim() === '}' && idx > firstIndex }));
     var lastIndex = lines.findIndex(((line, idx) => { return line.trim() === '}' && idx > firstIndex }));
     lines.splice(firstIndex, lastIndex - firstIndex + 1);
     lines.splice(firstIndex, lastIndex - firstIndex + 1);
     str = lines.join('\n');
     str = lines.join('\n');
 
 
-    str = str.replace(/declare module (.*) {/g, 'declare module BabylonViewer {').replace("import * as BABYLON from 'babylonjs';", "");
-    str = str.replace(/import {(.*)} from ['"]babylonjs-viewer(.*)['"];/g, '').replace(/import 'babylonjs-loaders';/, '').replace(/import 'pep';/, '');
+    str = str.replace(/declare module (.*) {/g, `declare module ${options.moduleName} {`);
+
+    str = str.replace("import * as BABYLON from 'babylonjs';", "");
+    let regexp = new RegExp(`import {(.*)} from ['"]${options.packageName}(.*)['"];`, 'g');
+    str = str.replace(regexp, '');
+
+    if (options.importsToRemove) {
+        while (options.importsToRemove.length) {
+            let remove = options.importsToRemove.pop();
+            str = str.replace(new RegExp(`import '${remove}';`), '');
+        }
+    }
 
 
     //find all used BABYLON and BABYLON-Loaders classes:
     //find all used BABYLON and BABYLON-Loaders classes:
 
 
-    var babylonRegex = /import {(.*)} from ['"](babylonjs|babylonjs-loaders)['"];/g
+    if ((options.classMap)) {
+        Object.keys(options.classMap).forEach(package => {
+            var babylonRegex = new RegExp(`import {(.*)} from ['"](${package})['"];`, "g");
 
 
-    var match = babylonRegex.exec(str);
-    let classes = new Set();
-    while (match != null) {
-        if (match[1]) {
-            match[1].split(",").forEach(element => {
-                classes.add(element.trim());
+            var match = babylonRegex.exec(str);
+            let classes = new Set();
+            while (match != null) {
+                if (match[1]) {
+                    match[1].split(",").forEach(element => {
+                        classes.add(element.trim());
+                    });
+                }
+                match = babylonRegex.exec(str);
+            }
+            str = str.replace(babylonRegex, '');
+            classes.forEach(cls => {
+                let rg = new RegExp(`([ <])(${cls})([^\\w])`, "g")
+                str = str.replace(rg, `$1${options.classMap[package]}.$2$3`);
             });
             });
-        }
-        match = babylonRegex.exec(str);
+        })
     }
     }
-    str = str.replace(babylonRegex, '');
-    classes.forEach(cls => {
-        let rg = new RegExp(`([ <])(${cls})([^\\w])`, "g")
-        str = str.replace(rg, "$1BABYLON.$2$3");
-    });
 
 
-    str = str.replace(/export {(.*)};/g, '')
+    str = str.replace(/export {(.*)};/g, '');
+
+    str = str.replace(/import (.*);/g, "");
+
+    str = str.split("\n").filter(line => line.trim()).filter(line => line.indexOf("export * from") === -1).join("\n");
+
+    //empty declare regex
+    let emptyDeclareRegexp = new RegExp("declare module " + options.moduleName + " {\n}", "g");
+
+    str = str.replace(emptyDeclareRegexp, "");
 
 
     return str;
     return str;
 }
 }

+ 8 - 4
Tools/Publisher/index.js

@@ -51,12 +51,13 @@ let packages = [
         required: [
         required: [
             basePath + '/viewer/readme.md',
             basePath + '/viewer/readme.md',
             basePath + '/viewer/package.json',
             basePath + '/viewer/package.json',
-            basePath + '/viewer/babylon.viewer.js'
+            basePath + '/viewer/babylon.viewer.js',
+            basePath + '/viewer/babylon.viewer.max.js'
         ]
         ]
     },
     },
     {
     {
         name: 'viewer-assets',
         name: 'viewer-assets',
-        path: basePath + '/../../Viewer/dist/build/assets/',
+        path: basePath + '/../../Viewer/build/assets/',
         required: [
         required: [
             basePath + '/../../Viewer/assets/readme.md',
             basePath + '/../../Viewer/assets/readme.md',
             basePath + '/../../Viewer/assets/package.json',
             basePath + '/../../Viewer/assets/package.json',
@@ -215,7 +216,7 @@ function processCore(package, version) {
 
 
 function processViewer(package, version) {
 function processViewer(package, version) {
 
 
-    let buildPath = package.path + "dist/build/src/";
+    let buildPath = package.path + "build/src/";
     let projectPath = '../../Viewer';
     let projectPath = '../../Viewer';
 
 
     if (package.required) {
     if (package.required) {
@@ -257,7 +258,10 @@ function publish(version, packageName, basePath) {
 
 
     //publish the respected package
     //publish the respected package
     console.log("executing " + 'npm publish \"' + basePath + "\"" + ' ' + tagDef);
     console.log("executing " + 'npm publish \"' + basePath + "\"" + ' ' + tagDef);
-    shelljs.exec('npm publish \"' + basePath + "\"" + ' ' + tagDef);
+    if (process.argv.indexOf('--no-publish') === -1) {
+        shelljs.exec('npm publish \"' + basePath + "\"" + ' ' + tagDef);
+    }
+
 }
 }
 
 
 function getFiles(dir, files_) {
 function getFiles(dir, files_) {

+ 139 - 0
Tools/WebpackShaderLoader/index.js

@@ -0,0 +1,139 @@
+//modified https://github.com/grieve/webpack-glsl-loader/blob/master/index.js
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+
+
+function parse(loader, source, context, cb) {
+    var imports = [];
+    var importPattern = /@import ([.\/\w_-]+);/gi;
+    var match = importPattern.exec(source);
+
+    while (match != null) {
+        imports.push({
+            key: match[1],
+            target: match[0],
+            content: ''
+        });
+        match = importPattern.exec(source);
+    }
+
+    source = uncomment(source);
+
+    processImports(loader, source, context, imports, cb);
+}
+
+var singleComment = 1;
+var multiComment = 2;
+
+function uncomment(str) {
+
+    var currentChar;
+    var nextChar;
+    var insideString = false;
+    var insideComment = 0;
+    var offset = 0;
+    var ret = '';
+
+    str = str.replace(/\r\n/g, '\n');
+    str = str.replace(/[ \f\t\v]+/g, ' ');
+    str = str.replace(/^\s*\n/gm, '');
+    str = str.replace(/ \+ /g, '+');
+    str = str.replace(/ \- /g, '-');
+    str = str.replace(/ \/ /g, '/');
+    str = str.replace(/ \* /g, '*');
+    str = str.replace(/ > /g, '>');
+    str = str.replace(/ < /g, '<');
+    str = str.replace(/ >= /g, '>=');
+    str = str.replace(/ <= /g, '<=');
+    str = str.replace(/ \+= /g, '+=');
+    str = str.replace(/ \-= /g, '-=');
+    str = str.replace(/ \/= /g, '/=');
+    str = str.replace(/ \*= /g, '*=');
+    str = str.replace(/ = /g, '=');
+    str = str.replace(/, /g, ',');
+    str = str.replace(/\n\n/g, '\n');
+    str = str.replace(/\n /g, '\n');
+
+    for (var i = 0; i < str.length; i++) {
+        currentChar = str[i];
+        nextChar = str[i + 1];
+
+        if (!insideComment && currentChar === '"') {
+            var escaped = str[i - 1] === '\\' && str[i - 2] !== '\\';
+            if (!escaped) {
+                insideString = !insideString;
+            }
+        }
+
+        if (insideString) {
+            continue;
+        }
+
+        if (!insideComment && currentChar + nextChar === '//') {
+            ret += str.slice(offset, i);
+            offset = i;
+            insideComment = singleComment;
+            i++;
+        } else if (insideComment === singleComment && currentChar === '\n') {
+            insideComment = 0;
+            offset = i;
+        } else if (!insideComment && currentChar + nextChar === '/*') {
+            ret += str.slice(offset, i);
+            offset = i;
+            insideComment = multiComment;
+            i++;
+            continue;
+        } else if (insideComment === multiComment && currentChar + nextChar === '*/') {
+            i++;
+            insideComment = 0;
+            offset = i + 1;
+            continue;
+        }
+    }
+
+    return ret + (insideComment ? '' : str.substr(offset));
+}
+
+function processImports(loader, source, context, imports, cb) {
+    if (imports.length === 0) {
+        return cb(null, source);
+    }
+
+    var imp = imports.pop();
+
+    loader.resolve(context, imp.key + '.fx', function (err, resolved) {
+        if (err) {
+            return cb(err);
+        }
+
+        loader.addDependency(resolved);
+        fs.readFile(resolved, 'utf-8', function (err, src) {
+            if (err) {
+                return cb(err);
+            }
+
+            parse(loader, src, path.dirname(resolved), function (err, bld) {
+                if (err) {
+                    return cb(err);
+                }
+
+                source = source.replace(imp.target, bld);
+                processImports(loader, source, context, imports, cb);
+            });
+        });
+    });
+}
+
+module.exports = function (source) {
+    this.cacheable();
+    var cb = this.async();
+    parse(this, source, this.context, function (err, bld) {
+        if (err) {
+            return cb(err);
+        }
+
+        cb(null, 'module.exports = ' + JSON.stringify(bld));
+    });
+};

+ 4 - 4
Viewer/assets/templates/default/navbar.html

@@ -457,7 +457,7 @@
             </button>
             </button>
             <div class="menu-options">
             <div class="menu-options">
                 {{#each animations}} {{#unless (eq ../selectedAnimation (add @index 1))}}
                 {{#each animations}} {{#unless (eq ../selectedAnimation (add @index 1))}}
-                <button class="flex-container label-option-button animation-buttons" data-value="{{this.value}}">
+                <button class="flex-container label-option-button animation-buttons" data-value="{{this.value}} ">
                     <!-- <div> -->
                     <!-- <div> -->
                     <span class="icon types-icon"></span>
                     <span class="icon types-icon"></span>
                     <span class="control-text animation-label">{{this.label}}</span>
                     <span class="control-text animation-label">{{this.label}}</span>
@@ -494,15 +494,15 @@
     {{/unless}}
     {{/unless}}
     <div class="default-control">
     <div class="default-control">
         {{#unless hideVr}}
         {{#unless hideVr}}
-        <button class="vr vr-button" title="{{text.vrButton}}">
+        <button class="vr vr-button" title="{{text.vrButton}} ">
             <span class="icon vr-icon"></span>
             <span class="icon vr-icon"></span>
         </button>
         </button>
         {{/unless}}{{#unless hideHelp}}
         {{/unless}}{{#unless hideHelp}}
-        <button class="help help-button" title="{{text.helpButton}}">
+        <button class="help help-button" title="{{text.helpButton}} ">
             <span class="icon help-icon"></span>
             <span class="icon help-icon"></span>
         </button>
         </button>
         {{/unless}} {{#unless hideFullscreen}}
         {{/unless}} {{#unless hideFullscreen}}
-        <button class="fullscreen fullscreen-button" title="{{text.fullscreenButton}}">
+        <button class="fullscreen fullscreen-button" title="{{text.fullscreenButton}} ">
             <span class="icon fullscreen-icon"></span>
             <span class="icon fullscreen-icon"></span>
         </button>
         </button>
         {{/unless}}
         {{/unless}}

+ 25 - 0
Viewer/dist/printExample.html

@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en">
+
+    <head>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <meta http-equiv="X-UA-Compatible" content="ie=edge">
+        <title>BabylonJS Viewer - 3D Print usage</title>
+        <style>
+            babylon {
+                width: 800px;
+                height: 500px;
+            }
+        </style>
+    </head>
+
+    <body>
+        <babylon templates.nav-bar.params.hide-print="false">
+            <model url="https://playground.babylonjs.com/scenes/BoomBox.glb">
+            </model>
+        </babylon>
+        <script src="viewer.js"></script>
+    </body>
+
+</html>

+ 6 - 4
Viewer/package.json

@@ -27,15 +27,17 @@
         "@types/node": "^8.9.4",
         "@types/node": "^8.9.4",
         "base64-font-loader": "0.0.4",
         "base64-font-loader": "0.0.4",
         "base64-image-loader": "^1.2.1",
         "base64-image-loader": "^1.2.1",
+        "base64-inline-loader": "^1.1.1",
         "deepmerge": "^2.1.1",
         "deepmerge": "^2.1.1",
         "handlebars": "^4.0.11",
         "handlebars": "^4.0.11",
         "html-loader": "^0.5.5",
         "html-loader": "^0.5.5",
         "json-loader": "^0.5.7",
         "json-loader": "^0.5.7",
-        "ts-loader": "^2.3.7",
-        "typescript": "^2.7.2",
+        "ts-loader": "^4.4.0",
+        "typescript": "^2.9.2",
         "uglifyjs-webpack-plugin": "^1.2.2",
         "uglifyjs-webpack-plugin": "^1.2.2",
-        "webpack": "^3.11.0",
-        "webpack-dev-server": "^2.11.2"
+        "webpack": "^4.16.0",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
     },
     },
     "dependencies": {
     "dependencies": {
         "pepjs": "^0.4.3"
         "pepjs": "^0.4.3"

+ 2 - 2
Viewer/src/configuration/configurationCompatibility.ts

@@ -43,7 +43,7 @@ export function processConfigurationCompatibility(configuration: ViewerConfigura
 
 
     if (configuration.lab) {
     if (configuration.lab) {
         if (configuration.lab.assetsRootURL) {
         if (configuration.lab.assetsRootURL) {
-            setKeyInObject(configuration, "scene.assetsRootURL", configuration.lab.assetsRootURL);
+            setKeyInObject(configuration, "scene.assetsRootURL", configuration.lab.assetsRootURL, true);
         }
         }
         if (configuration.lab.environmentMap) {
         if (configuration.lab.environmentMap) {
             setKeyInObject(configuration, "environmentMap", configuration.lab.environmentMap, true);
             setKeyInObject(configuration, "environmentMap", configuration.lab.environmentMap, true);
@@ -63,4 +63,4 @@ function setKeyInObject(object: any, keys: string, value: any, shouldOverwrite?:
     });
     });
     if (curObj[lastKey] !== undefined && !shouldOverwrite) return;
     if (curObj[lastKey] !== undefined && !shouldOverwrite) return;
     curObj[lastKey] = value;
     curObj[lastKey] = value;
-}
+}

+ 4 - 2
Viewer/src/configuration/types/default.ts

@@ -51,12 +51,14 @@ export let defaultConfiguration: ViewerConfiguration = {
                 hideHelp: true,
                 hideHelp: true,
                 hideHd: true,
                 hideHd: true,
                 hideVr: true,
                 hideVr: true,
+                hidePrint: true,
                 disableOnFullscreen: false,
                 disableOnFullscreen: false,
                 text: {
                 text: {
                     hdButton: "Toggle HD",
                     hdButton: "Toggle HD",
-                    fullscreenButton: "Fullscreen",
+                    fullscreenButton: "Toggle Fullscreen",
                     helpButton: "Help",
                     helpButton: "Help",
-                    vrButton: "Toggle VR"
+                    vrButton: "Toggle VR",
+                    printButton: "3D Print Object"
                 }
                 }
             },
             },
             events: {
             events: {

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

@@ -354,7 +354,7 @@ export class ViewerModel implements IDisposable {
      */
      */
     protected _getAnimationByName(name: string): Nullable<IModelAnimation> {
     protected _getAnimationByName(name: string): Nullable<IModelAnimation> {
         // can't use .find, noe available on IE
         // can't use .find, noe available on IE
-        let filtered = this._animations.filter(a => a.name === name);
+        let filtered = this._animations.filter(a => a.name === name.trim());
         // what the next line means - if two animations have the same name, they will not be returned!
         // what the next line means - if two animations have the same name, they will not be returned!
         if (filtered.length === 1) {
         if (filtered.length === 1) {
             return filtered[0];
             return filtered[0];
@@ -377,7 +377,7 @@ export class ViewerModel implements IDisposable {
     }
     }
 
 
     public setCurrentAnimationByName(name: string) {
     public setCurrentAnimationByName(name: string) {
-        let animation = this._getAnimationByName(name);
+        let animation = this._getAnimationByName(name.trim());
         if (animation) {
         if (animation) {
             if (this.currentAnimation && this.currentAnimation.state !== AnimationState.STOPPED) {
             if (this.currentAnimation && this.currentAnimation.state !== AnimationState.STOPPED) {
                 this.currentAnimation.stop();
                 this.currentAnimation.stop();

+ 62 - 0
Viewer/src/templating/plugins/printButton.ts

@@ -0,0 +1,62 @@
+import { AbstractViewerNavbarButton } from "../viewerTemplatePlugin";
+import { DefaultViewer } from "../../viewer/defaultViewer";
+import { EventCallback } from "../templateManager";
+import { Tools } from "babylonjs";
+
+export class PrintButtonPlugin extends AbstractViewerNavbarButton {
+
+    private _currentModelUrl: string;
+
+    constructor(private _viewer: DefaultViewer) {
+        super("print", "print-button", PrintButtonPlugin.HtmlTemplate);
+
+        this._viewer.onModelLoadedObservable.add((model) => {
+            this._currentModelUrl = "";
+            if (model.configuration.url) {
+                let filename = Tools.GetFilename(model.configuration.url) || model.configuration.url;
+                let baseUrl = model.configuration.root || Tools.GetFolderPath(model.configuration.url);
+
+                //gltf, obj, stl
+                let extension = model.configuration.loader || filename.split(".").pop() || "";
+                let printable = false;
+                // not using .some sue to IE11
+                ["gltf", "glb", "obj", "stl"].forEach(ext => {
+                    if (extension.indexOf(ext) !== -1) {
+                        printable = true;
+                    }
+                })
+                if (printable) {
+                    this._currentModelUrl = baseUrl + filename;
+                }
+            }
+        })
+    }
+
+    onEvent(event: EventCallback): void {
+        if (this._currentModelUrl) {
+            let printUrl = this._currentModelUrl.replace(/https?:\/\//, "com.microsoft.builder3d://");
+            window.open(printUrl, "_self");
+        }
+    }
+
+    protected static HtmlTemplate: string = `
+{{#unless hidePrint}}
+<style>
+
+/* Show only if it's a windows 10 printer  */
+.print-icon.not-win-10 {
+    display: none;
+}
+
+.print-icon:after {
+    font-size: 16px;
+    content: "\\E914";
+}
+
+</style>
+<button class="print-button ${window.navigator.userAgent.indexOf("Windows NT 10.0") === -1 ? "no-win-10" : ""}" title="{{text.printButton}}">
+     <span class="icon print-icon"></span>
+ </button>
+ {{/unless}}
+`;
+}

+ 25 - 11
Viewer/src/viewer/defaultViewer.ts

@@ -8,6 +8,7 @@ import { ViewerModel } from '../model/viewerModel';
 import { IModelAnimation, AnimationState } from '../model/modelAnimation';
 import { IModelAnimation, AnimationState } from '../model/modelAnimation';
 import { IViewerTemplatePlugin } from '../templating/viewerTemplatePlugin';
 import { IViewerTemplatePlugin } from '../templating/viewerTemplatePlugin';
 import { HDButtonPlugin } from '../templating/plugins/hdButtonPlugin';
 import { HDButtonPlugin } from '../templating/plugins/hdButtonPlugin';
+import { PrintButtonPlugin } from '../templating/plugins/printButton';
 
 
 /**
 /**
  * The Default viewer is the default implementation of the AbstractViewer.
  * The Default viewer is the default implementation of the AbstractViewer.
@@ -148,6 +149,7 @@ export class DefaultViewer extends AbstractViewer {
             }
             }
 
 
             this.registerTemplatePlugin(new HDButtonPlugin(this));
             this.registerTemplatePlugin(new HDButtonPlugin(this));
+            this.registerTemplatePlugin(new PrintButtonPlugin(this));
         }
         }
     }
     }
 
 
@@ -196,7 +198,7 @@ export class DefaultViewer extends AbstractViewer {
                 var value = element.dataset["value"];
                 var value = element.dataset["value"];
                 var label = element.querySelector("span.animation-label");
                 var label = element.querySelector("span.animation-label");
                 if (label && value) {
                 if (label && value) {
-                    this._updateAnimationType({ value, label: label.innerHTML });
+                    this._updateAnimationType({ value: value.trim(), label: label.innerHTML });
                 }
                 }
                 break;
                 break;
             case "speed-option-button":
             case "speed-option-button":
@@ -326,19 +328,31 @@ export class DefaultViewer extends AbstractViewer {
         this._updateAnimationSpeed("1.0", paramsObject);
         this._updateAnimationSpeed("1.0", paramsObject);
     }
     }
 
 
-    public toggleVR() {
-        super.toggleVR();
+    protected _initVR() {
+        this.engine.onVRDisplayChangedObservable.add(() => {
+            let viewerTemplate = this.templateManager.getTemplate('viewer');
+            let viewerElement = viewerTemplate && viewerTemplate.parent;
 
 
-        let viewerTemplate = this.templateManager.getTemplate('viewer');
-        let viewerElement = viewerTemplate && viewerTemplate.parent;
-
-        if (viewerElement) {
-            if (this._vrToggled) {
-                viewerElement.classList.add("in-vr");
-            } else {
-                viewerElement.classList.remove("in-vr");
+            if (viewerElement) {
+                if (this.sceneManager.vrHelper!.isInVRMode) {
+                    viewerElement.classList.add("in-vr");
+                } else {
+                    viewerElement.classList.remove("in-vr");
+                }
             }
             }
+        });
+        if (this.sceneManager.vrHelper) {
+            // due to the way the experience helper is exisintg VR, this must be added.
+            this.sceneManager.vrHelper.onExitingVR.add(() => {
+                let viewerTemplate = this.templateManager.getTemplate('viewer');
+                let viewerElement = viewerTemplate && viewerTemplate.parent;
+
+                if (viewerElement) {
+                    viewerElement.classList.remove("in-vr");
+                }
+            });
         }
         }
+        super._initVR();
     }
     }
 
 
     /**
     /**

+ 48 - 30
Viewer/src/viewer/viewer.ts

@@ -262,10 +262,14 @@ export abstract class AbstractViewer {
     private _vrModelRepositioning: number = 0;
     private _vrModelRepositioning: number = 0;
     protected _vrScale: number = 1;
     protected _vrScale: number = 1;
 
 
+    protected _vrInit: boolean = false;
+
     public toggleVR() {
     public toggleVR() {
-        this._vrToggled = !this._vrToggled;
+        if (!this._vrInit) {
+            this._initVR();
+        }
 
 
-        if (this._vrToggled && this.sceneManager.vrHelper) {
+        if (this.sceneManager.vrHelper && !this.sceneManager.vrHelper.isInVRMode) {
             // make sure the floor is set
             // make sure the floor is set
             if (this.sceneManager.environmentHelper && this.sceneManager.environmentHelper.ground) {
             if (this.sceneManager.environmentHelper && this.sceneManager.environmentHelper.ground) {
                 this.sceneManager.vrHelper.addFloorMesh(this.sceneManager.environmentHelper.ground);
                 this.sceneManager.vrHelper.addFloorMesh(this.sceneManager.environmentHelper.ground);
@@ -274,7 +278,7 @@ export abstract class AbstractViewer {
             this.sceneManager.vrHelper.enterVR();
             this.sceneManager.vrHelper.enterVR();
 
 
             // position the vr camera to be in front of the object or wherever the user has configured it to be
             // position the vr camera to be in front of the object or wherever the user has configured it to be
-            if (this.sceneManager.vrHelper.currentVRCamera) {
+            if (this.sceneManager.vrHelper.currentVRCamera && this.sceneManager.vrHelper.currentVRCamera !== this.sceneManager.camera) {
                 if (this.configuration.vr && this.configuration.vr.cameraPosition !== undefined) {
                 if (this.configuration.vr && this.configuration.vr.cameraPosition !== undefined) {
                     this.sceneManager.vrHelper.currentVRCamera.position.copyFrom(this.configuration.vr.cameraPosition as Vector3);
                     this.sceneManager.vrHelper.currentVRCamera.position.copyFrom(this.configuration.vr.cameraPosition as Vector3);
                 } else {
                 } else {
@@ -291,42 +295,49 @@ export abstract class AbstractViewer {
                         this._vrModelRepositioning = 0;
                         this._vrModelRepositioning = 0;
                     }
                     }
                 }
                 }
-            } else {
-                this._vrModelRepositioning = 0;
-            }
 
 
-            // scale the model
-            if (this.sceneManager.models.length) {
-                let boundingVectors = this.sceneManager.models[0].rootMesh.getHierarchyBoundingVectors();
-                let sizeVec = boundingVectors.max.subtract(boundingVectors.min);
-                let maxDimension = Math.max(sizeVec.x, sizeVec.y, sizeVec.z);
-                this._vrScale = (1 / maxDimension);
-                if (this.configuration.vr && this.configuration.vr.objectScaleFactor) {
-                    this._vrScale *= this.configuration.vr.objectScaleFactor;
-                }
+                // scale the model
+                if (this.sceneManager.models.length) {
+                    let boundingVectors = this.sceneManager.models[0].rootMesh.getHierarchyBoundingVectors();
+                    let sizeVec = boundingVectors.max.subtract(boundingVectors.min);
+                    let maxDimension = Math.max(sizeVec.x, sizeVec.y, sizeVec.z);
+                    this._vrScale = (1 / maxDimension);
+                    if (this.configuration.vr && this.configuration.vr.objectScaleFactor) {
+                        this._vrScale *= this.configuration.vr.objectScaleFactor;
+                    }
 
 
-                this.sceneManager.models[0].rootMesh.scaling.scaleInPlace(this._vrScale);
+                    this.sceneManager.models[0].rootMesh.scaling.scaleInPlace(this._vrScale);
 
 
-                // reposition the object to "float" in front of the user
-                this.sceneManager.models[0].rootMesh.position.y += this._vrModelRepositioning;
-                this.sceneManager.models[0].rootMesh.rotationQuaternion = null;
-            }
+                    // reposition the object to "float" in front of the user
+                    this.sceneManager.models[0].rootMesh.position.y += this._vrModelRepositioning;
+                    this.sceneManager.models[0].rootMesh.rotationQuaternion = null;
+                }
 
 
-            // scale the environment to match the model
-            if (this.sceneManager.environmentHelper) {
-                this.sceneManager.environmentHelper.ground && this.sceneManager.environmentHelper.ground.scaling.scaleInPlace(this._vrScale);
-                this.sceneManager.environmentHelper.skybox && this.sceneManager.environmentHelper.skybox.scaling.scaleInPlace(this._vrScale);
-            }
+                // scale the environment to match the model
+                if (this.sceneManager.environmentHelper) {
+                    this.sceneManager.environmentHelper.ground && this.sceneManager.environmentHelper.ground.scaling.scaleInPlace(this._vrScale);
+                    this.sceneManager.environmentHelper.skybox && this.sceneManager.environmentHelper.skybox.scaling.scaleInPlace(this._vrScale);
+                }
 
 
-            // post processing
-            if (this.sceneManager.defaultRenderingPipelineEnabled && this.sceneManager.defaultRenderingPipeline) {
-                this.sceneManager.defaultRenderingPipeline.imageProcessingEnabled = false;
-                this.sceneManager.defaultRenderingPipeline.prepare();
+                // post processing
+                if (this.sceneManager.defaultRenderingPipelineEnabled && this.sceneManager.defaultRenderingPipeline) {
+                    this.sceneManager.defaultRenderingPipeline.imageProcessingEnabled = false;
+                    this.sceneManager.defaultRenderingPipeline.prepare();
+                }
+            } else {
+                this._vrModelRepositioning = 0;
             }
             }
         } else {
         } else {
             if (this.sceneManager.vrHelper) {
             if (this.sceneManager.vrHelper) {
                 this.sceneManager.vrHelper.exitVR();
                 this.sceneManager.vrHelper.exitVR();
+            }
+        }
+    }
+
+    protected _initVR() {
 
 
+        if (this.sceneManager.vrHelper) {
+            this.sceneManager.vrHelper.onExitingVR.add(() => {
                 // undo the scaling of the model
                 // undo the scaling of the model
                 if (this.sceneManager.models.length) {
                 if (this.sceneManager.models.length) {
                     this.sceneManager.models[0].rootMesh.scaling.scaleInPlace(1 / this._vrScale);
                     this.sceneManager.models[0].rootMesh.scaling.scaleInPlace(1 / this._vrScale);
@@ -344,8 +355,15 @@ export abstract class AbstractViewer {
                     this.sceneManager.defaultRenderingPipeline.imageProcessingEnabled = true;
                     this.sceneManager.defaultRenderingPipeline.imageProcessingEnabled = true;
                     this.sceneManager.defaultRenderingPipeline.prepare();
                     this.sceneManager.defaultRenderingPipeline.prepare();
                 }
                 }
-            }
+
+                // clear set height and eidth
+                this.canvas.removeAttribute("height");
+                this.canvas.removeAttribute("width");
+                this.engine.resize();
+            })
         }
         }
+
+        this._vrInit = true;
     }
     }
 
 
     /**
     /**

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

@@ -20,7 +20,7 @@
         "skipDefaultLibCheck": true,
         "skipDefaultLibCheck": true,
         "skipLibCheck": true,
         "skipLibCheck": true,
         "baseUrl": "./src/",
         "baseUrl": "./src/",
-        "rootDir": "./",
+        "rootDir": "../../",
         "paths": {
         "paths": {
             "babylonjs": [
             "babylonjs": [
                 "../../../../dist/preview release/babylon.d.ts"
                 "../../../../dist/preview release/babylon.d.ts"
@@ -35,6 +35,7 @@
                 "../../src/assets/"
                 "../../src/assets/"
             ]
             ]
         },
         },
+        "outDir": "./build"
     },
     },
     "include": [
     "include": [
         "./src/**/*.ts"
         "./src/**/*.ts"

+ 4 - 2
Viewer/tests/unit/webpack.config.js

@@ -1,6 +1,7 @@
 const path = require('path');
 const path = require('path');
 
 
 module.exports = {
 module.exports = {
+    context: __dirname,
     entry: {
     entry: {
         'test': __dirname + '/src/index.ts'
         'test': __dirname + '/src/index.ts'
     },
     },
@@ -24,9 +25,10 @@ module.exports = {
         oimo: 'OIMO',
         oimo: 'OIMO',
         "earcut": true
         "earcut": true
     },
     },
+    mode: "development",
     devtool: 'source-map',
     devtool: 'source-map',
     module: {
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
             test: /\.tsx?$/,
             loader: 'ts-loader',
             loader: 'ts-loader',
             exclude: /node_modules/
             exclude: /node_modules/
@@ -46,7 +48,7 @@ module.exports = {
         },
         },
         {
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
         }]
     },
     },
     devServer: {
     devServer: {

+ 1 - 1
Viewer/tests/validation/karma.conf.js

@@ -22,7 +22,7 @@ module.exports = function (config) {
         ],
         ],
         proxies: {
         proxies: {
             '/tests/': '/base/tests/',
             '/tests/': '/base/tests/',
-            '/dist/assets/': '/base//dist/assets/'
+            '/dist/assets/': '/base/dist/assets/'
         },
         },
 
 
         port: 3000,
         port: 3000,

+ 1 - 1
Viewer/tsconfig-gulp.json

@@ -41,7 +41,7 @@
                 "./assets/"
                 "./assets/"
             ]
             ]
         },
         },
-        "outDir": "./dist/build"
+        "outDir": "./build"
     },
     },
     "exclude": [
     "exclude": [
         "node_modules",
         "node_modules",

+ 2 - 2
Viewer/tsconfig.json

@@ -1,6 +1,6 @@
 {
 {
     "compilerOptions": {
     "compilerOptions": {
-        "target": "es2015",
+        "target": "es5",
         "module": "commonjs",
         "module": "commonjs",
         "declaration": true,
         "declaration": true,
         "experimentalDecorators": true,
         "experimentalDecorators": true,
@@ -44,6 +44,6 @@
                 "./assets/*"
                 "./assets/*"
             ]
             ]
         },
         },
-        "outDir": "./dist/build"
+        "outDir": "./build"
     }
     }
 }
 }

+ 4 - 2
Viewer/webpack.assets.config.js

@@ -1,4 +1,5 @@
 module.exports = {
 module.exports = {
+    context: __dirname,
     entry: [
     entry: [
         __dirname + '/src/assets/index.ts'
         __dirname + '/src/assets/index.ts'
     ],
     ],
@@ -10,8 +11,9 @@ module.exports = {
     resolve: {
     resolve: {
         extensions: ['.ts']
         extensions: ['.ts']
     },
     },
+    mode: "production",
     module: {
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
             test: /\.tsx?$/,
             use: {
             use: {
                 loader: 'ts-loader',
                 loader: 'ts-loader',
@@ -36,7 +38,7 @@ module.exports = {
         },
         },
         {
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
         }]
     }
     }
 }
 }

+ 4 - 3
Viewer/webpack.config.js

@@ -54,7 +54,7 @@ module.exports = /*[
             libraryTarget: 'umd',
             libraryTarget: 'umd',
             library: 'BabylonViewer',
             library: 'BabylonViewer',
             umdNamedDefine: true,
             umdNamedDefine: true,
-            devtoolModuleFilenameTemplate: '[relative-resource-path]'
+            devtoolModuleFilenameTemplate: '[absolute-resource-path]'
         },
         },
         resolve: {
         resolve: {
             extensions: ['.ts', '.js'],
             extensions: ['.ts', '.js'],
@@ -71,6 +71,7 @@ module.exports = /*[
             oimo: 'OIMO',
             oimo: 'OIMO',
             earcut: true
             earcut: true
         },
         },
+        mode: "development",
         devtool: 'source-map',
         devtool: 'source-map',
         plugins: [
         plugins: [
             new webpack.WatchIgnorePlugin([
             new webpack.WatchIgnorePlugin([
@@ -78,7 +79,7 @@ module.exports = /*[
             ])
             ])
         ],
         ],
         module: {
         module: {
-            loaders: [{
+            rules: [{
                 test: /\.tsx?$/,
                 test: /\.tsx?$/,
                 loader: 'ts-loader',
                 loader: 'ts-loader',
                 exclude: /node_modules/
                 exclude: /node_modules/
@@ -98,7 +99,7 @@ module.exports = /*[
             },
             },
             {
             {
                 test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                 test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-                loader: 'base64-font-loader'
+                loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
             }]
             }]
         },
         },
         devServer: {
         devServer: {

+ 9 - 10
Viewer/webpack.gulp.config.js

@@ -1,7 +1,10 @@
+const path = require('path');
+const webpack = require('webpack');
+
 module.exports = {
 module.exports = {
-    //context: __dirname,
+    context: __dirname,
     entry: [
     entry: [
-        __dirname + '/src/index.ts'
+        path.resolve(__dirname, './src/index.ts')
     ],
     ],
     output: {
     output: {
         libraryTarget: 'var',
         libraryTarget: 'var',
@@ -22,15 +25,11 @@ module.exports = {
             "babylonjs-viewer-assets": __dirname + '/src/assets/index.ts'
             "babylonjs-viewer-assets": __dirname + '/src/assets/index.ts'
         }
         }
     },
     },
+    mode: "production",
     module: {
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
             test: /\.tsx?$/,
-            use: {
-                loader: 'ts-loader',
-                options: {
-                    configFile: 'tsconfig-gulp.json'
-                }
-            },
+            loader: 'ts-loader',
             exclude: /node_modules/
             exclude: /node_modules/
         },
         },
         {
         {
@@ -48,7 +47,7 @@ module.exports = {
         },
         },
         {
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
         }]
     }
     }
 }
 }

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


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


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


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


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


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


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

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

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


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


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


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


+ 2 - 3
dist/preview release/gui/package.json

@@ -4,16 +4,15 @@
     },
     },
     "name": "babylonjs-gui",
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.3.0-alpha.12",
+    "version": "3.3.0-alpha.13",
     "repository": {
     "repository": {
         "type": "git",
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
         "url": "https://github.com/BabylonJS/Babylon.js.git"
     },
     },
     "main": "babylon.gui.min.js",
     "main": "babylon.gui.min.js",
     "files": [
     "files": [
-        "babylon.gui.js",
         "babylon.gui.min.js",
         "babylon.gui.min.js",
-        "babylon.gui.d.ts",
+        "babylon.gui.min.js.map",
         "babylon.gui.module.d.ts",
         "babylon.gui.module.d.ts",
         "readme.md",
         "readme.md",
         "package.json"
         "package.json"

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


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


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


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


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

@@ -4,7 +4,7 @@
     },
     },
     "name": "babylonjs-inspector",
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
     "description": "The Babylon.js inspector.",
-    "version": "3.3.0-alpha.12",
+    "version": "3.3.0-alpha.13",
     "repository": {
     "repository": {
         "type": "git",
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -12,9 +12,12 @@
     "main": "babylon.inspector.bundle.js",
     "main": "babylon.inspector.bundle.js",
     "files": [
     "files": [
         "babylon.inspector.bundle.js",
         "babylon.inspector.bundle.js",
+        "babylon.inspector.bundle.js.map",
+        "babylon.inspector.module.d.ts",
         "readme.md",
         "readme.md",
         "package.json"
         "package.json"
     ],
     ],
+    "typings": "babylon.inspector.module.d.ts",
     "keywords": [
     "keywords": [
         "3D",
         "3D",
         "javascript",
         "javascript",

+ 11 - 0
dist/preview release/loaders/babylon.glTF1FileLoader.d.ts

@@ -191,9 +191,20 @@ declare module BABYLON {
         private _onCompleteObserver;
         private _onCompleteObserver;
         /**
         /**
          * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
          * 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.
          */
          */
         onComplete: () => void;
         onComplete: () => void;
         /**
         /**
+         * Observable raised when an error occurs.
+         */
+        readonly onErrorObservable: Observable<any>;
+        private _onErrorObserver;
+        /**
+         * Callback raised when an error occurs.
+         */
+        onError: (reason: any) => void;
+        /**
          * Observable raised after the loader is disposed.
          * Observable raised after the loader is disposed.
          */
          */
         readonly onDisposeObservable: Observable<void>;
         readonly onDisposeObservable: Observable<void>;

+ 23 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -118,6 +118,10 @@ var BABYLON;
              */
              */
             this.onCompleteObservable = new BABYLON.Observable();
             this.onCompleteObservable = new BABYLON.Observable();
             /**
             /**
+             * Observable raised when an error occurs.
+             */
+            this.onErrorObservable = new BABYLON.Observable();
+            /**
              * Observable raised after the loader is disposed.
              * Observable raised after the loader is disposed.
              */
              */
             this.onDisposeObservable = new BABYLON.Observable();
             this.onDisposeObservable = new BABYLON.Observable();
@@ -217,6 +221,8 @@ var BABYLON;
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
             /**
             /**
              * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
              * 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.
              */
              */
             set: function (callback) {
             set: function (callback) {
                 if (this._onCompleteObserver) {
                 if (this._onCompleteObserver) {
@@ -227,6 +233,19 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(GLTFFileLoader.prototype, "onError", {
+            /**
+             * Callback raised when an error occurs.
+             */
+            set: function (callback) {
+                if (this._onErrorObserver) {
+                    this.onErrorObservable.remove(this._onErrorObserver);
+                }
+                this._onErrorObserver = this.onErrorObservable.add(callback);
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
             /**
             /**
              * Callback raised after the loader is disposed.
              * Callback raised after the loader is disposed.
@@ -259,10 +278,13 @@ var BABYLON;
          */
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
             var _this = this;
             var _this = this;
-            return new Promise(function (resolve) {
+            return new Promise(function (resolve, reject) {
                 _this.onCompleteObservable.addOnce(function () {
                 _this.onCompleteObservable.addOnce(function () {
                     resolve();
                     resolve();
                 });
                 });
+                _this.onErrorObservable.addOnce(function (reason) {
+                    reject(reason);
+                });
             });
             });
         };
         };
         Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
         Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {

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


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

@@ -191,9 +191,20 @@ declare module BABYLON {
         private _onCompleteObserver;
         private _onCompleteObserver;
         /**
         /**
          * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
          * 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.
          */
          */
         onComplete: () => void;
         onComplete: () => void;
         /**
         /**
+         * Observable raised when an error occurs.
+         */
+        readonly onErrorObservable: Observable<any>;
+        private _onErrorObserver;
+        /**
+         * Callback raised when an error occurs.
+         */
+        onError: (reason: any) => void;
+        /**
          * Observable raised after the loader is disposed.
          * Observable raised after the loader is disposed.
          */
          */
         readonly onDisposeObservable: Observable<void>;
         readonly onDisposeObservable: Observable<void>;
@@ -449,7 +460,6 @@ declare module BABYLON.GLTF2 {
         _parent: GLTFFileLoader;
         _parent: GLTFFileLoader;
         _gltf: _ILoaderGLTF;
         _gltf: _ILoaderGLTF;
         _babylonScene: Scene;
         _babylonScene: Scene;
-        _readyPromise: Promise<void>;
         _completePromises: Promise<void>[];
         _completePromises: Promise<void>[];
         private _disposed;
         private _disposed;
         private _state;
         private _state;
@@ -463,9 +473,6 @@ declare module BABYLON.GLTF2 {
         private static _ExtensionNames;
         private static _ExtensionNames;
         private static _ExtensionFactories;
         private static _ExtensionFactories;
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
-        /**
-         * Loader state or null if the loader is not active.
-         */
         readonly state: Nullable<GLTFLoaderState>;
         readonly state: Nullable<GLTFLoaderState>;
         constructor(parent: GLTFFileLoader);
         constructor(parent: GLTFFileLoader);
         dispose(): void;
         dispose(): void;
@@ -481,6 +488,7 @@ declare module BABYLON.GLTF2 {
         private _setupData();
         private _setupData();
         private _loadExtensions();
         private _loadExtensions();
         private _checkExtensions();
         private _checkExtensions();
+        private _setState(state);
         private _createRootNode();
         private _createRootNode();
         _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void>;
         _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void>;
         private _forEachPrimitive(node, callback);
         private _forEachPrimitive(node, callback);
@@ -504,7 +512,7 @@ declare module BABYLON.GLTF2 {
         private _getNodeMatrix(node);
         private _getNodeMatrix(node);
         private _loadCamera(context, camera, babylonMesh);
         private _loadCamera(context, camera, babylonMesh);
         private _loadAnimationsAsync();
         private _loadAnimationsAsync();
-        private _loadAnimationAsync(context, animation);
+        _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Promise<void>;
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadBufferAsync(context, buffer);
         private _loadBufferAsync(context, buffer);
@@ -536,6 +544,7 @@ declare module BABYLON.GLTF2 {
         private _compileMaterialsAsync();
         private _compileMaterialsAsync();
         private _compileShadowGeneratorsAsync();
         private _compileShadowGeneratorsAsync();
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
+        _forEachExtensions(action: (extension: GLTFLoaderExtension) => void): void;
     }
     }
 }
 }
 
 
@@ -564,6 +573,14 @@ declare module BABYLON.GLTF2 {
          */
          */
         dispose(): void;
         dispose(): void;
         /**
         /**
+         * Override this method to do work after the state changes to LOADING.
+         */
+        protected _onLoading(): void;
+        /**
+         * Override this method to do work after the state changes to READY.
+         */
+        protected _onReady(): void;
+        /**
          * Override this method to modify the default behavior for loading scenes.
          * Override this method to modify the default behavior for loading scenes.
          * @hidden
          * @hidden
          */
          */
@@ -603,6 +620,8 @@ declare module BABYLON.GLTF2 {
          * @hidden
          * @hidden
          */
          */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+        /** Override this method to modify the default behavior for loading animations. */
+        protected _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
         /**
         /**
          * Helper method called by a loader extension to load an glTF extension.
          * Helper method called by a loader extension to load an glTF extension.
          * @hidden
          * @hidden
@@ -614,6 +633,16 @@ declare module BABYLON.GLTF2 {
          */
          */
         protected _loadExtrasValueAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, value: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
         protected _loadExtrasValueAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, value: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
         /**
         /**
+         * Helper method called by the loader after the state changes to LOADING.
+         * @hidden
+         */
+        static _OnLoading(loader: GLTFLoader): void;
+        /**
+         * Helper method called by the loader after the state changes to READY.
+         * @hidden
+         */
+        static _OnReady(loader: GLTFLoader): void;
+        /**
          * Helper method called by the loader to allow extensions to override loading scenes.
          * Helper method called by the loader to allow extensions to override loading scenes.
          * @hidden
          * @hidden
          */
          */
@@ -653,6 +682,11 @@ declare module BABYLON.GLTF2 {
          * @hidden
          * @hidden
          */
          */
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading animations.
+         * @hidden
+         */
+        static _LoadAnimationAsync(loader: GLTFLoader, context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
     }
     }
 }
 }
 /**
 /**
@@ -664,6 +698,26 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
     /**
     /**
+     * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
+     */
+    class MSFT_audio_emitter extends GLTFLoaderExtension {
+        readonly name: string;
+        private _loadClipAsync(context, clip);
+        private _loadEmitterAsync(context, emitter);
+        protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
+        protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
+        protected _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
+        private _getEventAction(context, sound, action, time, startOffset?);
+        private _loadAnimationEventAsync(context, animationContext, animation, event, babylonAnimationGroup);
+        private readonly _extension;
+        private readonly _clips;
+        private readonly _emitters;
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
      */
      */
     class MSFT_lod extends GLTFLoaderExtension {
     class MSFT_lod extends GLTFLoaderExtension {
@@ -690,8 +744,8 @@ declare module BABYLON.GLTF2.Extensions {
         private _materialIndexLOD;
         private _materialIndexLOD;
         private _materialSignalLODs;
         private _materialSignalLODs;
         private _materialPromiseLODs;
         private _materialPromiseLODs;
-        constructor(loader: GLTFLoader);
         dispose(): void;
         dispose(): void;
+        protected _onReady(): void;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
@@ -717,7 +771,8 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     /** @hidden */
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        protected _loadMaterialPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: Material): Nullable<Promise<void>>;
+        private _convertColorsToLinear(babylonMaterial);
     }
     }
 }
 }
 
 
@@ -766,9 +821,10 @@ declare module BABYLON.GLTF2.Extensions {
      */
      */
     class KHR_lights extends GLTFLoaderExtension {
     class KHR_lights extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
+        private _lights?;
+        protected _onLoading(): void;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        private readonly _lights;
     }
     }
 }
 }
 
 
@@ -790,8 +846,9 @@ declare module BABYLON.GLTF2.Extensions {
      */
      */
     class EXT_lights_imageBased extends GLTFLoaderExtension {
     class EXT_lights_imageBased extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
+        private _lights?;
+        protected _onLoading(): void;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         private _loadLightAsync(context, light);
         private _loadLightAsync(context, light);
-        private readonly _lights;
     }
     }
 }
 }

+ 391 - 94
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -118,6 +118,10 @@ var BABYLON;
              */
              */
             this.onCompleteObservable = new BABYLON.Observable();
             this.onCompleteObservable = new BABYLON.Observable();
             /**
             /**
+             * Observable raised when an error occurs.
+             */
+            this.onErrorObservable = new BABYLON.Observable();
+            /**
              * Observable raised after the loader is disposed.
              * Observable raised after the loader is disposed.
              */
              */
             this.onDisposeObservable = new BABYLON.Observable();
             this.onDisposeObservable = new BABYLON.Observable();
@@ -217,6 +221,8 @@ var BABYLON;
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
             /**
             /**
              * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
              * 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.
              */
              */
             set: function (callback) {
             set: function (callback) {
                 if (this._onCompleteObserver) {
                 if (this._onCompleteObserver) {
@@ -227,6 +233,19 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(GLTFFileLoader.prototype, "onError", {
+            /**
+             * Callback raised when an error occurs.
+             */
+            set: function (callback) {
+                if (this._onErrorObserver) {
+                    this.onErrorObservable.remove(this._onErrorObserver);
+                }
+                this._onErrorObserver = this.onErrorObservable.add(callback);
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
             /**
             /**
              * Callback raised after the loader is disposed.
              * Callback raised after the loader is disposed.
@@ -259,10 +278,13 @@ var BABYLON;
          */
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
             var _this = this;
             var _this = this;
-            return new Promise(function (resolve) {
+            return new Promise(function (resolve, reject) {
                 _this.onCompleteObservable.addOnce(function () {
                 _this.onCompleteObservable.addOnce(function () {
                     resolve();
                     resolve();
                 });
                 });
+                _this.onErrorObservable.addOnce(function (reason) {
+                    reject(reason);
+                });
             });
             });
         };
         };
         Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
         Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
@@ -713,9 +735,6 @@ var BABYLON;
                 GLTFLoader._ExtensionNames.push(name);
                 GLTFLoader._ExtensionNames.push(name);
             };
             };
             Object.defineProperty(GLTFLoader.prototype, "state", {
             Object.defineProperty(GLTFLoader.prototype, "state", {
-                /**
-                 * Loader state or null if the loader is not active.
-                 */
                 get: function () {
                 get: function () {
                     return this._state;
                     return this._state;
                 },
                 },
@@ -734,7 +753,6 @@ var BABYLON;
                 this._requests.length = 0;
                 this._requests.length = 0;
                 delete this._gltf;
                 delete this._gltf;
                 delete this._babylonScene;
                 delete this._babylonScene;
-                delete this._readyPromise;
                 this._completePromises.length = 0;
                 this._completePromises.length = 0;
                 for (var name_1 in this._extensions) {
                 for (var name_1 in this._extensions) {
                     this._extensions[name_1].dispose();
                     this._extensions[name_1].dispose();
@@ -794,14 +812,14 @@ var BABYLON;
             GLTFLoader.prototype._loadAsync = function (nodes) {
             GLTFLoader.prototype._loadAsync = function (nodes) {
                 var _this = this;
                 var _this = this;
                 return Promise.resolve().then(function () {
                 return Promise.resolve().then(function () {
-                    _this._parent._startPerformanceCounter("Loading => Ready");
-                    _this._parent._startPerformanceCounter("Loading => Complete");
-                    _this._state = BABYLON.GLTFLoaderState.LOADING;
-                    _this._parent._log("Loading");
-                    var readyDeferred = new BABYLON.Deferred();
-                    _this._readyPromise = readyDeferred.promise;
                     _this._loadExtensions();
                     _this._loadExtensions();
                     _this._checkExtensions();
                     _this._checkExtensions();
+                    var loadingToReadyCounterName = BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.LOADING] + " => " + BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.READY];
+                    var loadingToCompleteCounterName = BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.LOADING] + " => " + BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.COMPLETE];
+                    _this._parent._startPerformanceCounter(loadingToReadyCounterName);
+                    _this._parent._startPerformanceCounter(loadingToCompleteCounterName);
+                    _this._setState(BABYLON.GLTFLoaderState.LOADING);
+                    GLTF2.GLTFLoaderExtension._OnLoading(_this);
                     var promises = new Array();
                     var promises = new Array();
                     if (nodes) {
                     if (nodes) {
                         promises.push(_this._loadSceneAsync("#/nodes", { nodes: nodes, _index: -1 }));
                         promises.push(_this._loadSceneAsync("#/nodes", { nodes: nodes, _index: -1 }));
@@ -817,33 +835,33 @@ var BABYLON;
                         promises.push(_this._compileShadowGeneratorsAsync());
                         promises.push(_this._compileShadowGeneratorsAsync());
                     }
                     }
                     var resultPromise = Promise.all(promises).then(function () {
                     var resultPromise = Promise.all(promises).then(function () {
-                        _this._state = BABYLON.GLTFLoaderState.READY;
-                        _this._parent._log("Ready");
-                        readyDeferred.resolve();
+                        _this._setState(BABYLON.GLTFLoaderState.READY);
+                        GLTF2.GLTFLoaderExtension._OnReady(_this);
                         _this._startAnimations();
                         _this._startAnimations();
                     });
                     });
                     resultPromise.then(function () {
                     resultPromise.then(function () {
-                        _this._parent._endPerformanceCounter("Loading => Ready");
+                        _this._parent._endPerformanceCounter(loadingToReadyCounterName);
                         BABYLON.Tools.SetImmediate(function () {
                         BABYLON.Tools.SetImmediate(function () {
                             if (!_this._disposed) {
                             if (!_this._disposed) {
                                 Promise.all(_this._completePromises).then(function () {
                                 Promise.all(_this._completePromises).then(function () {
-                                    _this._parent._endPerformanceCounter("Loading => Complete");
-                                    _this._state = BABYLON.GLTFLoaderState.COMPLETE;
-                                    _this._parent._log("Complete");
+                                    _this._parent._endPerformanceCounter(loadingToCompleteCounterName);
+                                    _this._setState(BABYLON.GLTFLoaderState.COMPLETE);
                                     _this._parent.onCompleteObservable.notifyObservers(undefined);
                                     _this._parent.onCompleteObservable.notifyObservers(undefined);
                                     _this._parent.onCompleteObservable.clear();
                                     _this._parent.onCompleteObservable.clear();
                                     _this.dispose();
                                     _this.dispose();
-                                }).catch(function (error) {
-                                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                                }, function (error) {
+                                    _this._parent.onErrorObservable.notifyObservers(error);
+                                    _this._parent.onErrorObservable.clear();
                                     _this.dispose();
                                     _this.dispose();
                                 });
                                 });
                             }
                             }
                         });
                         });
                     });
                     });
                     return resultPromise;
                     return resultPromise;
-                }).catch(function (error) {
+                }, function (error) {
                     if (!_this._disposed) {
                     if (!_this._disposed) {
-                        BABYLON.Tools.Error("glTF Loader: " + error.message);
+                        _this._parent.onErrorObservable.notifyObservers(error);
+                        _this._parent.onErrorObservable.clear();
                         _this.dispose();
                         _this.dispose();
                         throw error;
                         throw error;
                     }
                     }
@@ -919,6 +937,10 @@ var BABYLON;
                     }
                     }
                 }
                 }
             };
             };
+            GLTFLoader.prototype._setState = function (state) {
+                this._state = state;
+                this._parent._log(BABYLON.GLTFLoaderState[this._state]);
+            };
             GLTFLoader.prototype._createRootNode = function () {
             GLTFLoader.prototype._createRootNode = function () {
                 this._rootBabylonMesh = new BABYLON.Mesh("__root__", this._babylonScene);
                 this._rootBabylonMesh = new BABYLON.Mesh("__root__", this._babylonScene);
                 var rootNode = { _babylonMesh: this._rootBabylonMesh };
                 var rootNode = { _babylonMesh: this._rootBabylonMesh };
@@ -1409,6 +1431,10 @@ var BABYLON;
             };
             };
             GLTFLoader.prototype._loadAnimationAsync = function (context, animation) {
             GLTFLoader.prototype._loadAnimationAsync = function (context, animation) {
                 var _this = this;
                 var _this = this;
+                var promise = GLTF2.GLTFLoaderExtension._LoadAnimationAsync(this, context, animation);
+                if (promise) {
+                    return promise;
+                }
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 var promises = new Array();
                 var promises = new Array();
@@ -2173,6 +2199,15 @@ var BABYLON;
                 }
                 }
                 return null;
                 return null;
             };
             };
+            GLTFLoader.prototype._forEachExtensions = function (action) {
+                for (var _i = 0, _a = GLTFLoader._ExtensionNames; _i < _a.length; _i++) {
+                    var name_6 = _a[_i];
+                    var extension = this._extensions[name_6];
+                    if (extension.enabled) {
+                        action(extension);
+                    }
+                }
+            };
             GLTFLoader._ExtensionNames = new Array();
             GLTFLoader._ExtensionNames = new Array();
             GLTFLoader._ExtensionFactories = {};
             GLTFLoader._ExtensionFactories = {};
             return GLTFLoader;
             return GLTFLoader;
@@ -2212,6 +2247,14 @@ var BABYLON;
             };
             };
             // #region Overridable Methods
             // #region Overridable Methods
             /**
             /**
+             * Override this method to do work after the state changes to LOADING.
+             */
+            GLTFLoaderExtension.prototype._onLoading = function () { };
+            /**
+             * Override this method to do work after the state changes to READY.
+             */
+            GLTFLoaderExtension.prototype._onReady = function () { };
+            /**
              * Override this method to modify the default behavior for loading scenes.
              * Override this method to modify the default behavior for loading scenes.
              * @hidden
              * @hidden
              */
              */
@@ -2251,6 +2294,8 @@ var BABYLON;
              * @hidden
              * @hidden
              */
              */
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
+            /** Override this method to modify the default behavior for loading animations. */
+            GLTFLoaderExtension.prototype._loadAnimationAsync = function (context, animation) { return null; };
             // #endregion
             // #endregion
             /**
             /**
              * Helper method called by a loader extension to load an glTF extension.
              * Helper method called by a loader extension to load an glTF extension.
@@ -2299,6 +2344,20 @@ var BABYLON;
                 }
                 }
             };
             };
             /**
             /**
+             * Helper method called by the loader after the state changes to LOADING.
+             * @hidden
+             */
+            GLTFLoaderExtension._OnLoading = function (loader) {
+                loader._forEachExtensions(function (extension) { return extension._onLoading(); });
+            };
+            /**
+             * Helper method called by the loader after the state changes to READY.
+             * @hidden
+             */
+            GLTFLoaderExtension._OnReady = function (loader) {
+                loader._forEachExtensions(function (extension) { return extension._onReady(); });
+            };
+            /**
              * Helper method called by the loader to allow extensions to override loading scenes.
              * Helper method called by the loader to allow extensions to override loading scenes.
              * @hidden
              * @hidden
              */
              */
@@ -2354,6 +2413,13 @@ var BABYLON;
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
             };
             };
+            /**
+             * Helper method called by the loader to allow extensions to override loading animations.
+             * @hidden
+             */
+            GLTFLoaderExtension._LoadAnimationAsync = function (loader, context, animation) {
+                return loader._applyExtensions(function (extension) { return extension._loadAnimationAsync(context, animation); });
+            };
             return GLTFLoaderExtension;
             return GLTFLoaderExtension;
         }());
         }());
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
@@ -2379,14 +2445,246 @@ var BABYLON;
     (function (GLTF2) {
     (function (GLTF2) {
         var Extensions;
         var Extensions;
         (function (Extensions) {
         (function (Extensions) {
+            var NAME = "MSFT_audio_emitter";
+            /**
+             * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
+             */
+            var MSFT_audio_emitter = /** @class */ (function (_super) {
+                __extends(MSFT_audio_emitter, _super);
+                function MSFT_audio_emitter() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
+                }
+                MSFT_audio_emitter.prototype._loadClipAsync = function (context, clip) {
+                    if (clip._objectURL) {
+                        return clip._objectURL;
+                    }
+                    var promise;
+                    if (clip.uri) {
+                        promise = this._loader._loadUriAsync(context, clip.uri);
+                    }
+                    else {
+                        var bufferView = GLTF2.GLTFLoader._GetProperty(context + "/bufferView", this._loader._gltf.bufferViews, clip.bufferView);
+                        promise = this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView);
+                    }
+                    clip._objectURL = promise.then(function (data) {
+                        return URL.createObjectURL(new Blob([data], { type: clip.mimeType }));
+                    });
+                    return clip._objectURL;
+                };
+                MSFT_audio_emitter.prototype._loadEmitterAsync = function (context, emitter) {
+                    var _this = this;
+                    emitter._babylonSounds = emitter._babylonSounds || [];
+                    if (!emitter._babylonData) {
+                        var clipPromises = new Array();
+                        var name_1 = emitter.name || "emitter" + emitter._index;
+                        var options_1 = {
+                            loop: false,
+                            autoplay: false,
+                            volume: emitter.volume == undefined ? 1 : emitter.volume,
+                        };
+                        GLTF2._ArrayItem.Assign(this._clips);
+                        var _loop_1 = function (i) {
+                            var clipContext = "#/extensions/" + NAME + "/clips";
+                            var clip = GLTF2.GLTFLoader._GetProperty(clipContext, this_1._clips, emitter.clips[i].clip);
+                            clipPromises.push(this_1._loadClipAsync(clipContext + "/" + emitter.clips[i].clip, clip).then(function (objectURL) {
+                                var sound = emitter._babylonSounds[i] = new BABYLON.Sound(name_1, objectURL, _this._loader._babylonScene, null, options_1);
+                                sound.refDistance = emitter.refDistance || 1;
+                                sound.maxDistance = emitter.maxDistance || 256;
+                                sound.rolloffFactor = emitter.rolloffFactor || 1;
+                                sound.distanceModel = emitter.distanceModel || 'exponential';
+                                sound._positionInEmitterSpace = true;
+                            }));
+                        };
+                        var this_1 = this;
+                        for (var i = 0; i < emitter.clips.length; i++) {
+                            _loop_1(i);
+                        }
+                        var promise = Promise.all(clipPromises).then(function () {
+                            var weights = emitter.clips.map(function (clip) { return clip.weight || 1; });
+                            var weightedSound = new BABYLON.WeightedSound(emitter.loop || false, emitter._babylonSounds, weights);
+                            if (emitter.innerAngle)
+                                weightedSound.directionalConeInnerAngle = 2 * BABYLON.Tools.ToDegrees(emitter.innerAngle);
+                            if (emitter.outerAngle)
+                                weightedSound.directionalConeOuterAngle = 2 * BABYLON.Tools.ToDegrees(emitter.outerAngle);
+                            if (emitter.volume)
+                                weightedSound.volume = emitter.volume;
+                            emitter._babylonData.sound = weightedSound;
+                        });
+                        emitter._babylonData = {
+                            loaded: promise
+                        };
+                    }
+                    return emitter._babylonData.loaded;
+                };
+                MSFT_audio_emitter.prototype._loadSceneAsync = function (context, scene) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
+                        return _this._loader._loadSceneAsync(context, scene).then(function () {
+                            var promises = new Array();
+                            GLTF2._ArrayItem.Assign(_this._emitters);
+                            for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) {
+                                var emitterIndex = _a[_i];
+                                var emitter = GLTF2.GLTFLoader._GetProperty(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));
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._loadNodeAsync = function (context, node) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
+                        return _this._loader._loadNodeAsync(extensionContext, node).then(function () {
+                            var promises = new Array();
+                            GLTF2._ArrayItem.Assign(_this._emitters);
+                            var _loop_2 = function (emitterIndex) {
+                                var emitter = GLTF2.GLTFLoader._GetProperty(extensionContext + "/emitters", _this._emitters, emitterIndex);
+                                promises.push(_this._loadEmitterAsync(extensionContext + "/emitters/" + emitter._index, emitter).then(function () {
+                                    if (node._babylonMesh) {
+                                        for (var _i = 0, _a = emitter._babylonSounds; _i < _a.length; _i++) {
+                                            var sound = _a[_i];
+                                            sound.attachToMesh(node._babylonMesh);
+                                            if (emitter.innerAngle != undefined || emitter.outerAngle != undefined) {
+                                                sound.setLocalDirectionToMesh(new BABYLON.Vector3(0, 0, 1));
+                                                sound.setDirectionalCone(2 * BABYLON.Tools.ToDegrees(emitter.innerAngle == undefined ? Math.PI : emitter.innerAngle), 2 * BABYLON.Tools.ToDegrees(emitter.outerAngle == undefined ? Math.PI : emitter.outerAngle), 0);
+                                            }
+                                        }
+                                    }
+                                }));
+                            };
+                            for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) {
+                                var emitterIndex = _a[_i];
+                                _loop_2(emitterIndex);
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._loadAnimationAsync = function (context, animation) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, animation, function (extensionContext, extension) {
+                        return _this._loader._loadAnimationAsync(extensionContext, animation).then(function () {
+                            var promises = new Array();
+                            var babylonAnimationGroup = animation._babylonAnimationGroup;
+                            GLTF2._ArrayItem.Assign(extension.events);
+                            for (var _i = 0, _a = extension.events; _i < _a.length; _i++) {
+                                var event_1 = _a[_i];
+                                promises.push(_this._loadAnimationEventAsync(extensionContext + "/events/" + event_1._index, context, animation, event_1, babylonAnimationGroup));
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._getEventAction = function (context, sound, action, time, startOffset) {
+                    if (action == "play" /* play */) {
+                        return function (currentFrame) {
+                            var frameOffset = (startOffset || 0) + (currentFrame - time);
+                            sound.play(frameOffset);
+                        };
+                    }
+                    else if (action == "stop" /* stop */) {
+                        return function (currentFrame) {
+                            sound.stop();
+                        };
+                    }
+                    else if (action == "pause" /* pause */) {
+                        return function (currentFrame) {
+                            sound.pause();
+                        };
+                    }
+                    else {
+                        throw new Error(context + ": Unsupported action " + action);
+                    }
+                };
+                MSFT_audio_emitter.prototype._loadAnimationEventAsync = function (context, animationContext, animation, event, babylonAnimationGroup) {
+                    var _this = this;
+                    if (babylonAnimationGroup.targetedAnimations.length == 0) {
+                        return Promise.resolve();
+                    }
+                    var babylonAnimation = babylonAnimationGroup.targetedAnimations[0];
+                    var emitterIndex = event.emitter;
+                    var emitter = GLTF2.GLTFLoader._GetProperty("#/extensions/" + NAME + "/emitters", this._emitters, emitterIndex);
+                    return this._loadEmitterAsync(context, emitter).then(function () {
+                        var sound = emitter._babylonData.sound;
+                        if (sound) {
+                            var babylonAnimationEvent = new BABYLON.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(function () {
+                                sound.stop();
+                            });
+                            babylonAnimationGroup.onAnimationGroupPauseObservable.add(function () {
+                                sound.pause();
+                            });
+                        }
+                    });
+                };
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_extension", {
+                    get: function () {
+                        var extensions = this._loader._gltf.extensions;
+                        if (!extensions || !extensions[this.name]) {
+                            throw new Error("#/extensions: '" + this.name + "' not found");
+                        }
+                        return extensions[this.name];
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_clips", {
+                    get: function () {
+                        return this._extension.clips;
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_emitters", {
+                    get: function () {
+                        return this._extension.emitters;
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                return MSFT_audio_emitter;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.MSFT_audio_emitter = MSFT_audio_emitter;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFT_audio_emitter(loader); });
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=MSFT_audio_emitter.js.map
+
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
             var NAME = "MSFT_lod";
             var NAME = "MSFT_lod";
             /**
             /**
              * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
              * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
              */
              */
             var MSFT_lod = /** @class */ (function (_super) {
             var MSFT_lod = /** @class */ (function (_super) {
                 __extends(MSFT_lod, _super);
                 __extends(MSFT_lod, _super);
-                function MSFT_lod(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_lod() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
                     _this.name = NAME;
                     /**
                     /**
                      * Maximum number of LODs to load, starting from the lowest LOD.
                      * Maximum number of LODs to load, starting from the lowest LOD.
@@ -2410,42 +2708,6 @@ var BABYLON;
                     _this._materialIndexLOD = null;
                     _this._materialIndexLOD = null;
                     _this._materialSignalLODs = new Array();
                     _this._materialSignalLODs = new Array();
                     _this._materialPromiseLODs = new Array();
                     _this._materialPromiseLODs = new Array();
-                    _this._loader._readyPromise.then(function () {
-                        var _loop_1 = function (indexLOD) {
-                            var promise = Promise.all(_this._nodePromiseLODs[indexLOD]).then(function () {
-                                if (indexLOD !== 0) {
-                                    _this._loader._parent._endPerformanceCounter("Node LOD " + indexLOD);
-                                }
-                                _this._loader._parent._log("Loaded node LOD " + indexLOD);
-                                _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
-                                if (indexLOD !== _this._nodePromiseLODs.length - 1) {
-                                    _this._loader._parent._startPerformanceCounter("Node LOD " + (indexLOD + 1));
-                                    _this._nodeSignalLODs[indexLOD].resolve();
-                                }
-                            });
-                            _this._loader._completePromises.push(promise);
-                        };
-                        for (var indexLOD = 0; indexLOD < _this._nodePromiseLODs.length; indexLOD++) {
-                            _loop_1(indexLOD);
-                        }
-                        var _loop_2 = function (indexLOD) {
-                            var promise = Promise.all(_this._materialPromiseLODs[indexLOD]).then(function () {
-                                if (indexLOD !== 0) {
-                                    _this._loader._parent._endPerformanceCounter("Material LOD " + indexLOD);
-                                }
-                                _this._loader._parent._log("Loaded material LOD " + indexLOD);
-                                _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
-                                if (indexLOD !== _this._materialPromiseLODs.length - 1) {
-                                    _this._loader._parent._startPerformanceCounter("Material LOD " + (indexLOD + 1));
-                                    _this._materialSignalLODs[indexLOD].resolve();
-                                }
-                            });
-                            _this._loader._completePromises.push(promise);
-                        };
-                        for (var indexLOD = 0; indexLOD < _this._materialPromiseLODs.length; indexLOD++) {
-                            _loop_2(indexLOD);
-                        }
-                    });
                     return _this;
                     return _this;
                 }
                 }
                 MSFT_lod.prototype.dispose = function () {
                 MSFT_lod.prototype.dispose = function () {
@@ -2459,6 +2721,49 @@ var BABYLON;
                     this.onMaterialLODsLoadedObservable.clear();
                     this.onMaterialLODsLoadedObservable.clear();
                     this.onNodeLODsLoadedObservable.clear();
                     this.onNodeLODsLoadedObservable.clear();
                 };
                 };
+                MSFT_lod.prototype._onReady = function () {
+                    var _this = this;
+                    var _loop_1 = function (indexLOD) {
+                        var promise = Promise.all(this_1._nodePromiseLODs[indexLOD]).then(function () {
+                            if (indexLOD !== 0) {
+                                _this._loader._parent._endPerformanceCounter("Node LOD " + indexLOD);
+                            }
+                            _this._loader._parent._log("Loaded node LOD " + indexLOD);
+                            _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
+                            if (indexLOD !== _this._nodePromiseLODs.length - 1) {
+                                _this._loader._parent._startPerformanceCounter("Node LOD " + (indexLOD + 1));
+                                if (_this._nodeSignalLODs[indexLOD]) {
+                                    _this._nodeSignalLODs[indexLOD].resolve();
+                                }
+                            }
+                        });
+                        this_1._loader._completePromises.push(promise);
+                    };
+                    var this_1 = this;
+                    for (var indexLOD = 0; indexLOD < this._nodePromiseLODs.length; indexLOD++) {
+                        _loop_1(indexLOD);
+                    }
+                    var _loop_2 = function (indexLOD) {
+                        var promise = Promise.all(this_2._materialPromiseLODs[indexLOD]).then(function () {
+                            if (indexLOD !== 0) {
+                                _this._loader._parent._endPerformanceCounter("Material LOD " + indexLOD);
+                            }
+                            _this._loader._parent._log("Loaded material LOD " + indexLOD);
+                            _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
+                            if (indexLOD !== _this._materialPromiseLODs.length - 1) {
+                                _this._loader._parent._startPerformanceCounter("Material LOD " + (indexLOD + 1));
+                                if (_this._materialSignalLODs[indexLOD]) {
+                                    _this._materialSignalLODs[indexLOD].resolve();
+                                }
+                            }
+                        });
+                        this_2._loader._completePromises.push(promise);
+                    };
+                    var this_2 = this;
+                    for (var indexLOD = 0; indexLOD < this._materialPromiseLODs.length; indexLOD++) {
+                        _loop_2(indexLOD);
+                    }
+                };
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
@@ -2683,23 +2988,25 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
-                MSFT_sRGBFactors.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                MSFT_sRGBFactors.prototype._loadMaterialPropertiesAsync = function (context, material, babylonMaterial) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtrasValueAsync(context, material, function (extensionContext, value) {
                     return this._loadExtrasValueAsync(context, material, function (extensionContext, value) {
                         if (value) {
                         if (value) {
-                            return _this._loader._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
-                                if (!babylonMaterial.albedoTexture) {
-                                    babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor);
-                                }
-                                if (!babylonMaterial.reflectivityTexture) {
-                                    babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor);
-                                }
-                                assign(babylonMaterial);
-                            });
+                            var promise = _this._loader._loadMaterialPropertiesAsync(context, material, babylonMaterial);
+                            _this._convertColorsToLinear(babylonMaterial);
+                            return promise;
                         }
                         }
                         return null;
                         return null;
                     });
                     });
                 };
                 };
+                MSFT_sRGBFactors.prototype._convertColorsToLinear = function (babylonMaterial) {
+                    if (!babylonMaterial.albedoTexture) {
+                        babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor);
+                    }
+                    if (!babylonMaterial.reflectivityTexture) {
+                        babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor);
+                    }
+                };
                 return MSFT_sRGBFactors;
                 return MSFT_sRGBFactors;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
@@ -2990,6 +3297,13 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
+                KHR_lights.prototype._onLoading = function () {
+                    var extensions = this._loader._gltf.extensions;
+                    if (extensions && extensions[this.name]) {
+                        var extension = extensions[this.name];
+                        this._lights = extension.lights;
+                    }
+                };
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
@@ -3038,18 +3352,6 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                Object.defineProperty(KHR_lights.prototype, "_lights", {
-                    get: function () {
-                        var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: '" + this.name + "' not found");
-                        }
-                        var extension = extensions[this.name];
-                        return extension.lights;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
                 return KHR_lights;
                 return KHR_lights;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.KHR_lights = KHR_lights;
             Extensions.KHR_lights = KHR_lights;
@@ -3151,6 +3453,13 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
+                EXT_lights_imageBased.prototype._onLoading = function () {
+                    var extensions = this._loader._gltf.extensions;
+                    if (extensions && extensions[this.name]) {
+                        var extension = extensions[this.name];
+                        this._lights = extension.lights;
+                    }
+                };
                 EXT_lights_imageBased.prototype._loadSceneAsync = function (context, scene) {
                 EXT_lights_imageBased.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
@@ -3220,18 +3529,6 @@ var BABYLON;
                         return light._babylonTexture;
                         return light._babylonTexture;
                     });
                     });
                 };
                 };
-                Object.defineProperty(EXT_lights_imageBased.prototype, "_lights", {
-                    get: function () {
-                        var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: '" + this.name + "' not found");
-                        }
-                        var extension = extensions[this.name];
-                        return extension.lights;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
                 return EXT_lights_imageBased;
                 return EXT_lights_imageBased;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.EXT_lights_imageBased = EXT_lights_imageBased;
             Extensions.EXT_lights_imageBased = EXT_lights_imageBased;

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


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

@@ -191,9 +191,20 @@ declare module BABYLON {
         private _onCompleteObserver;
         private _onCompleteObserver;
         /**
         /**
          * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
          * 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.
          */
          */
         onComplete: () => void;
         onComplete: () => void;
         /**
         /**
+         * Observable raised when an error occurs.
+         */
+        readonly onErrorObservable: Observable<any>;
+        private _onErrorObserver;
+        /**
+         * Callback raised when an error occurs.
+         */
+        onError: (reason: any) => void;
+        /**
          * Observable raised after the loader is disposed.
          * Observable raised after the loader is disposed.
          */
          */
         readonly onDisposeObservable: Observable<void>;
         readonly onDisposeObservable: Observable<void>;
@@ -1011,7 +1022,6 @@ declare module BABYLON.GLTF2 {
         _parent: GLTFFileLoader;
         _parent: GLTFFileLoader;
         _gltf: _ILoaderGLTF;
         _gltf: _ILoaderGLTF;
         _babylonScene: Scene;
         _babylonScene: Scene;
-        _readyPromise: Promise<void>;
         _completePromises: Promise<void>[];
         _completePromises: Promise<void>[];
         private _disposed;
         private _disposed;
         private _state;
         private _state;
@@ -1025,9 +1035,6 @@ declare module BABYLON.GLTF2 {
         private static _ExtensionNames;
         private static _ExtensionNames;
         private static _ExtensionFactories;
         private static _ExtensionFactories;
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
-        /**
-         * Loader state or null if the loader is not active.
-         */
         readonly state: Nullable<GLTFLoaderState>;
         readonly state: Nullable<GLTFLoaderState>;
         constructor(parent: GLTFFileLoader);
         constructor(parent: GLTFFileLoader);
         dispose(): void;
         dispose(): void;
@@ -1043,6 +1050,7 @@ declare module BABYLON.GLTF2 {
         private _setupData();
         private _setupData();
         private _loadExtensions();
         private _loadExtensions();
         private _checkExtensions();
         private _checkExtensions();
+        private _setState(state);
         private _createRootNode();
         private _createRootNode();
         _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void>;
         _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void>;
         private _forEachPrimitive(node, callback);
         private _forEachPrimitive(node, callback);
@@ -1066,7 +1074,7 @@ declare module BABYLON.GLTF2 {
         private _getNodeMatrix(node);
         private _getNodeMatrix(node);
         private _loadCamera(context, camera, babylonMesh);
         private _loadCamera(context, camera, babylonMesh);
         private _loadAnimationsAsync();
         private _loadAnimationsAsync();
-        private _loadAnimationAsync(context, animation);
+        _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Promise<void>;
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadBufferAsync(context, buffer);
         private _loadBufferAsync(context, buffer);
@@ -1098,6 +1106,7 @@ declare module BABYLON.GLTF2 {
         private _compileMaterialsAsync();
         private _compileMaterialsAsync();
         private _compileShadowGeneratorsAsync();
         private _compileShadowGeneratorsAsync();
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
+        _forEachExtensions(action: (extension: GLTFLoaderExtension) => void): void;
     }
     }
 }
 }
 
 
@@ -1126,6 +1135,14 @@ declare module BABYLON.GLTF2 {
          */
          */
         dispose(): void;
         dispose(): void;
         /**
         /**
+         * Override this method to do work after the state changes to LOADING.
+         */
+        protected _onLoading(): void;
+        /**
+         * Override this method to do work after the state changes to READY.
+         */
+        protected _onReady(): void;
+        /**
          * Override this method to modify the default behavior for loading scenes.
          * Override this method to modify the default behavior for loading scenes.
          * @hidden
          * @hidden
          */
          */
@@ -1165,6 +1182,8 @@ declare module BABYLON.GLTF2 {
          * @hidden
          * @hidden
          */
          */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+        /** Override this method to modify the default behavior for loading animations. */
+        protected _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
         /**
         /**
          * Helper method called by a loader extension to load an glTF extension.
          * Helper method called by a loader extension to load an glTF extension.
          * @hidden
          * @hidden
@@ -1176,6 +1195,16 @@ declare module BABYLON.GLTF2 {
          */
          */
         protected _loadExtrasValueAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, value: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
         protected _loadExtrasValueAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, value: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
         /**
         /**
+         * Helper method called by the loader after the state changes to LOADING.
+         * @hidden
+         */
+        static _OnLoading(loader: GLTFLoader): void;
+        /**
+         * Helper method called by the loader after the state changes to READY.
+         * @hidden
+         */
+        static _OnReady(loader: GLTFLoader): void;
+        /**
          * Helper method called by the loader to allow extensions to override loading scenes.
          * Helper method called by the loader to allow extensions to override loading scenes.
          * @hidden
          * @hidden
          */
          */
@@ -1215,6 +1244,11 @@ declare module BABYLON.GLTF2 {
          * @hidden
          * @hidden
          */
          */
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading animations.
+         * @hidden
+         */
+        static _LoadAnimationAsync(loader: GLTFLoader, context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
     }
     }
 }
 }
 /**
 /**
@@ -1226,6 +1260,26 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
     /**
     /**
+     * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
+     */
+    class MSFT_audio_emitter extends GLTFLoaderExtension {
+        readonly name: string;
+        private _loadClipAsync(context, clip);
+        private _loadEmitterAsync(context, emitter);
+        protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
+        protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
+        protected _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
+        private _getEventAction(context, sound, action, time, startOffset?);
+        private _loadAnimationEventAsync(context, animationContext, animation, event, babylonAnimationGroup);
+        private readonly _extension;
+        private readonly _clips;
+        private readonly _emitters;
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
      */
      */
     class MSFT_lod extends GLTFLoaderExtension {
     class MSFT_lod extends GLTFLoaderExtension {
@@ -1252,8 +1306,8 @@ declare module BABYLON.GLTF2.Extensions {
         private _materialIndexLOD;
         private _materialIndexLOD;
         private _materialSignalLODs;
         private _materialSignalLODs;
         private _materialPromiseLODs;
         private _materialPromiseLODs;
-        constructor(loader: GLTFLoader);
         dispose(): void;
         dispose(): void;
+        protected _onReady(): void;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
@@ -1279,7 +1333,8 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     /** @hidden */
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        protected _loadMaterialPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: Material): Nullable<Promise<void>>;
+        private _convertColorsToLinear(babylonMaterial);
     }
     }
 }
 }
 
 
@@ -1328,9 +1383,10 @@ declare module BABYLON.GLTF2.Extensions {
      */
      */
     class KHR_lights extends GLTFLoaderExtension {
     class KHR_lights extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
+        private _lights?;
+        protected _onLoading(): void;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        private readonly _lights;
     }
     }
 }
 }
 
 
@@ -1352,8 +1408,9 @@ declare module BABYLON.GLTF2.Extensions {
      */
      */
     class EXT_lights_imageBased extends GLTFLoaderExtension {
     class EXT_lights_imageBased extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
+        private _lights?;
+        protected _onLoading(): void;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         private _loadLightAsync(context, light);
         private _loadLightAsync(context, light);
-        private readonly _lights;
     }
     }
 }
 }

+ 391 - 96
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -118,6 +118,10 @@ var BABYLON;
              */
              */
             this.onCompleteObservable = new BABYLON.Observable();
             this.onCompleteObservable = new BABYLON.Observable();
             /**
             /**
+             * Observable raised when an error occurs.
+             */
+            this.onErrorObservable = new BABYLON.Observable();
+            /**
              * Observable raised after the loader is disposed.
              * Observable raised after the loader is disposed.
              */
              */
             this.onDisposeObservable = new BABYLON.Observable();
             this.onDisposeObservable = new BABYLON.Observable();
@@ -217,6 +221,8 @@ var BABYLON;
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
             /**
             /**
              * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
              * 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.
              */
              */
             set: function (callback) {
             set: function (callback) {
                 if (this._onCompleteObserver) {
                 if (this._onCompleteObserver) {
@@ -227,6 +233,19 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(GLTFFileLoader.prototype, "onError", {
+            /**
+             * Callback raised when an error occurs.
+             */
+            set: function (callback) {
+                if (this._onErrorObserver) {
+                    this.onErrorObservable.remove(this._onErrorObserver);
+                }
+                this._onErrorObserver = this.onErrorObservable.add(callback);
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
             /**
             /**
              * Callback raised after the loader is disposed.
              * Callback raised after the loader is disposed.
@@ -259,10 +278,13 @@ var BABYLON;
          */
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
             var _this = this;
             var _this = this;
-            return new Promise(function (resolve) {
+            return new Promise(function (resolve, reject) {
                 _this.onCompleteObservable.addOnce(function () {
                 _this.onCompleteObservable.addOnce(function () {
                     resolve();
                     resolve();
                 });
                 });
+                _this.onErrorObservable.addOnce(function (reason) {
+                    reject(reason);
+                });
             });
             });
         };
         };
         Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
         Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
@@ -2914,9 +2936,6 @@ var BABYLON;
                 GLTFLoader._ExtensionNames.push(name);
                 GLTFLoader._ExtensionNames.push(name);
             };
             };
             Object.defineProperty(GLTFLoader.prototype, "state", {
             Object.defineProperty(GLTFLoader.prototype, "state", {
-                /**
-                 * Loader state or null if the loader is not active.
-                 */
                 get: function () {
                 get: function () {
                     return this._state;
                     return this._state;
                 },
                 },
@@ -2935,7 +2954,6 @@ var BABYLON;
                 this._requests.length = 0;
                 this._requests.length = 0;
                 delete this._gltf;
                 delete this._gltf;
                 delete this._babylonScene;
                 delete this._babylonScene;
-                delete this._readyPromise;
                 this._completePromises.length = 0;
                 this._completePromises.length = 0;
                 for (var name_1 in this._extensions) {
                 for (var name_1 in this._extensions) {
                     this._extensions[name_1].dispose();
                     this._extensions[name_1].dispose();
@@ -2995,14 +3013,14 @@ var BABYLON;
             GLTFLoader.prototype._loadAsync = function (nodes) {
             GLTFLoader.prototype._loadAsync = function (nodes) {
                 var _this = this;
                 var _this = this;
                 return Promise.resolve().then(function () {
                 return Promise.resolve().then(function () {
-                    _this._parent._startPerformanceCounter("Loading => Ready");
-                    _this._parent._startPerformanceCounter("Loading => Complete");
-                    _this._state = BABYLON.GLTFLoaderState.LOADING;
-                    _this._parent._log("Loading");
-                    var readyDeferred = new BABYLON.Deferred();
-                    _this._readyPromise = readyDeferred.promise;
                     _this._loadExtensions();
                     _this._loadExtensions();
                     _this._checkExtensions();
                     _this._checkExtensions();
+                    var loadingToReadyCounterName = BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.LOADING] + " => " + BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.READY];
+                    var loadingToCompleteCounterName = BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.LOADING] + " => " + BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.COMPLETE];
+                    _this._parent._startPerformanceCounter(loadingToReadyCounterName);
+                    _this._parent._startPerformanceCounter(loadingToCompleteCounterName);
+                    _this._setState(BABYLON.GLTFLoaderState.LOADING);
+                    GLTF2.GLTFLoaderExtension._OnLoading(_this);
                     var promises = new Array();
                     var promises = new Array();
                     if (nodes) {
                     if (nodes) {
                         promises.push(_this._loadSceneAsync("#/nodes", { nodes: nodes, _index: -1 }));
                         promises.push(_this._loadSceneAsync("#/nodes", { nodes: nodes, _index: -1 }));
@@ -3018,33 +3036,33 @@ var BABYLON;
                         promises.push(_this._compileShadowGeneratorsAsync());
                         promises.push(_this._compileShadowGeneratorsAsync());
                     }
                     }
                     var resultPromise = Promise.all(promises).then(function () {
                     var resultPromise = Promise.all(promises).then(function () {
-                        _this._state = BABYLON.GLTFLoaderState.READY;
-                        _this._parent._log("Ready");
-                        readyDeferred.resolve();
+                        _this._setState(BABYLON.GLTFLoaderState.READY);
+                        GLTF2.GLTFLoaderExtension._OnReady(_this);
                         _this._startAnimations();
                         _this._startAnimations();
                     });
                     });
                     resultPromise.then(function () {
                     resultPromise.then(function () {
-                        _this._parent._endPerformanceCounter("Loading => Ready");
+                        _this._parent._endPerformanceCounter(loadingToReadyCounterName);
                         BABYLON.Tools.SetImmediate(function () {
                         BABYLON.Tools.SetImmediate(function () {
                             if (!_this._disposed) {
                             if (!_this._disposed) {
                                 Promise.all(_this._completePromises).then(function () {
                                 Promise.all(_this._completePromises).then(function () {
-                                    _this._parent._endPerformanceCounter("Loading => Complete");
-                                    _this._state = BABYLON.GLTFLoaderState.COMPLETE;
-                                    _this._parent._log("Complete");
+                                    _this._parent._endPerformanceCounter(loadingToCompleteCounterName);
+                                    _this._setState(BABYLON.GLTFLoaderState.COMPLETE);
                                     _this._parent.onCompleteObservable.notifyObservers(undefined);
                                     _this._parent.onCompleteObservable.notifyObservers(undefined);
                                     _this._parent.onCompleteObservable.clear();
                                     _this._parent.onCompleteObservable.clear();
                                     _this.dispose();
                                     _this.dispose();
-                                }).catch(function (error) {
-                                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                                }, function (error) {
+                                    _this._parent.onErrorObservable.notifyObservers(error);
+                                    _this._parent.onErrorObservable.clear();
                                     _this.dispose();
                                     _this.dispose();
                                 });
                                 });
                             }
                             }
                         });
                         });
                     });
                     });
                     return resultPromise;
                     return resultPromise;
-                }).catch(function (error) {
+                }, function (error) {
                     if (!_this._disposed) {
                     if (!_this._disposed) {
-                        BABYLON.Tools.Error("glTF Loader: " + error.message);
+                        _this._parent.onErrorObservable.notifyObservers(error);
+                        _this._parent.onErrorObservable.clear();
                         _this.dispose();
                         _this.dispose();
                         throw error;
                         throw error;
                     }
                     }
@@ -3120,6 +3138,10 @@ var BABYLON;
                     }
                     }
                 }
                 }
             };
             };
+            GLTFLoader.prototype._setState = function (state) {
+                this._state = state;
+                this._parent._log(BABYLON.GLTFLoaderState[this._state]);
+            };
             GLTFLoader.prototype._createRootNode = function () {
             GLTFLoader.prototype._createRootNode = function () {
                 this._rootBabylonMesh = new BABYLON.Mesh("__root__", this._babylonScene);
                 this._rootBabylonMesh = new BABYLON.Mesh("__root__", this._babylonScene);
                 var rootNode = { _babylonMesh: this._rootBabylonMesh };
                 var rootNode = { _babylonMesh: this._rootBabylonMesh };
@@ -3610,6 +3632,10 @@ var BABYLON;
             };
             };
             GLTFLoader.prototype._loadAnimationAsync = function (context, animation) {
             GLTFLoader.prototype._loadAnimationAsync = function (context, animation) {
                 var _this = this;
                 var _this = this;
+                var promise = GLTF2.GLTFLoaderExtension._LoadAnimationAsync(this, context, animation);
+                if (promise) {
+                    return promise;
+                }
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 var promises = new Array();
                 var promises = new Array();
@@ -4374,6 +4400,15 @@ var BABYLON;
                 }
                 }
                 return null;
                 return null;
             };
             };
+            GLTFLoader.prototype._forEachExtensions = function (action) {
+                for (var _i = 0, _a = GLTFLoader._ExtensionNames; _i < _a.length; _i++) {
+                    var name_6 = _a[_i];
+                    var extension = this._extensions[name_6];
+                    if (extension.enabled) {
+                        action(extension);
+                    }
+                }
+            };
             GLTFLoader._ExtensionNames = new Array();
             GLTFLoader._ExtensionNames = new Array();
             GLTFLoader._ExtensionFactories = {};
             GLTFLoader._ExtensionFactories = {};
             return GLTFLoader;
             return GLTFLoader;
@@ -4413,6 +4448,14 @@ var BABYLON;
             };
             };
             // #region Overridable Methods
             // #region Overridable Methods
             /**
             /**
+             * Override this method to do work after the state changes to LOADING.
+             */
+            GLTFLoaderExtension.prototype._onLoading = function () { };
+            /**
+             * Override this method to do work after the state changes to READY.
+             */
+            GLTFLoaderExtension.prototype._onReady = function () { };
+            /**
              * Override this method to modify the default behavior for loading scenes.
              * Override this method to modify the default behavior for loading scenes.
              * @hidden
              * @hidden
              */
              */
@@ -4452,6 +4495,8 @@ var BABYLON;
              * @hidden
              * @hidden
              */
              */
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
+            /** Override this method to modify the default behavior for loading animations. */
+            GLTFLoaderExtension.prototype._loadAnimationAsync = function (context, animation) { return null; };
             // #endregion
             // #endregion
             /**
             /**
              * Helper method called by a loader extension to load an glTF extension.
              * Helper method called by a loader extension to load an glTF extension.
@@ -4500,6 +4545,20 @@ var BABYLON;
                 }
                 }
             };
             };
             /**
             /**
+             * Helper method called by the loader after the state changes to LOADING.
+             * @hidden
+             */
+            GLTFLoaderExtension._OnLoading = function (loader) {
+                loader._forEachExtensions(function (extension) { return extension._onLoading(); });
+            };
+            /**
+             * Helper method called by the loader after the state changes to READY.
+             * @hidden
+             */
+            GLTFLoaderExtension._OnReady = function (loader) {
+                loader._forEachExtensions(function (extension) { return extension._onReady(); });
+            };
+            /**
              * Helper method called by the loader to allow extensions to override loading scenes.
              * Helper method called by the loader to allow extensions to override loading scenes.
              * @hidden
              * @hidden
              */
              */
@@ -4555,6 +4614,13 @@ var BABYLON;
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
             };
             };
+            /**
+             * Helper method called by the loader to allow extensions to override loading animations.
+             * @hidden
+             */
+            GLTFLoaderExtension._LoadAnimationAsync = function (loader, context, animation) {
+                return loader._applyExtensions(function (extension) { return extension._loadAnimationAsync(context, animation); });
+            };
             return GLTFLoaderExtension;
             return GLTFLoaderExtension;
         }());
         }());
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
@@ -4580,14 +4646,246 @@ var BABYLON;
     (function (GLTF2) {
     (function (GLTF2) {
         var Extensions;
         var Extensions;
         (function (Extensions) {
         (function (Extensions) {
+            var NAME = "MSFT_audio_emitter";
+            /**
+             * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
+             */
+            var MSFT_audio_emitter = /** @class */ (function (_super) {
+                __extends(MSFT_audio_emitter, _super);
+                function MSFT_audio_emitter() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
+                }
+                MSFT_audio_emitter.prototype._loadClipAsync = function (context, clip) {
+                    if (clip._objectURL) {
+                        return clip._objectURL;
+                    }
+                    var promise;
+                    if (clip.uri) {
+                        promise = this._loader._loadUriAsync(context, clip.uri);
+                    }
+                    else {
+                        var bufferView = GLTF2.GLTFLoader._GetProperty(context + "/bufferView", this._loader._gltf.bufferViews, clip.bufferView);
+                        promise = this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView);
+                    }
+                    clip._objectURL = promise.then(function (data) {
+                        return URL.createObjectURL(new Blob([data], { type: clip.mimeType }));
+                    });
+                    return clip._objectURL;
+                };
+                MSFT_audio_emitter.prototype._loadEmitterAsync = function (context, emitter) {
+                    var _this = this;
+                    emitter._babylonSounds = emitter._babylonSounds || [];
+                    if (!emitter._babylonData) {
+                        var clipPromises = new Array();
+                        var name_1 = emitter.name || "emitter" + emitter._index;
+                        var options_1 = {
+                            loop: false,
+                            autoplay: false,
+                            volume: emitter.volume == undefined ? 1 : emitter.volume,
+                        };
+                        GLTF2._ArrayItem.Assign(this._clips);
+                        var _loop_1 = function (i) {
+                            var clipContext = "#/extensions/" + NAME + "/clips";
+                            var clip = GLTF2.GLTFLoader._GetProperty(clipContext, this_1._clips, emitter.clips[i].clip);
+                            clipPromises.push(this_1._loadClipAsync(clipContext + "/" + emitter.clips[i].clip, clip).then(function (objectURL) {
+                                var sound = emitter._babylonSounds[i] = new BABYLON.Sound(name_1, objectURL, _this._loader._babylonScene, null, options_1);
+                                sound.refDistance = emitter.refDistance || 1;
+                                sound.maxDistance = emitter.maxDistance || 256;
+                                sound.rolloffFactor = emitter.rolloffFactor || 1;
+                                sound.distanceModel = emitter.distanceModel || 'exponential';
+                                sound._positionInEmitterSpace = true;
+                            }));
+                        };
+                        var this_1 = this;
+                        for (var i = 0; i < emitter.clips.length; i++) {
+                            _loop_1(i);
+                        }
+                        var promise = Promise.all(clipPromises).then(function () {
+                            var weights = emitter.clips.map(function (clip) { return clip.weight || 1; });
+                            var weightedSound = new BABYLON.WeightedSound(emitter.loop || false, emitter._babylonSounds, weights);
+                            if (emitter.innerAngle)
+                                weightedSound.directionalConeInnerAngle = 2 * BABYLON.Tools.ToDegrees(emitter.innerAngle);
+                            if (emitter.outerAngle)
+                                weightedSound.directionalConeOuterAngle = 2 * BABYLON.Tools.ToDegrees(emitter.outerAngle);
+                            if (emitter.volume)
+                                weightedSound.volume = emitter.volume;
+                            emitter._babylonData.sound = weightedSound;
+                        });
+                        emitter._babylonData = {
+                            loaded: promise
+                        };
+                    }
+                    return emitter._babylonData.loaded;
+                };
+                MSFT_audio_emitter.prototype._loadSceneAsync = function (context, scene) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
+                        return _this._loader._loadSceneAsync(context, scene).then(function () {
+                            var promises = new Array();
+                            GLTF2._ArrayItem.Assign(_this._emitters);
+                            for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) {
+                                var emitterIndex = _a[_i];
+                                var emitter = GLTF2.GLTFLoader._GetProperty(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));
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._loadNodeAsync = function (context, node) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
+                        return _this._loader._loadNodeAsync(extensionContext, node).then(function () {
+                            var promises = new Array();
+                            GLTF2._ArrayItem.Assign(_this._emitters);
+                            var _loop_2 = function (emitterIndex) {
+                                var emitter = GLTF2.GLTFLoader._GetProperty(extensionContext + "/emitters", _this._emitters, emitterIndex);
+                                promises.push(_this._loadEmitterAsync(extensionContext + "/emitters/" + emitter._index, emitter).then(function () {
+                                    if (node._babylonMesh) {
+                                        for (var _i = 0, _a = emitter._babylonSounds; _i < _a.length; _i++) {
+                                            var sound = _a[_i];
+                                            sound.attachToMesh(node._babylonMesh);
+                                            if (emitter.innerAngle != undefined || emitter.outerAngle != undefined) {
+                                                sound.setLocalDirectionToMesh(new BABYLON.Vector3(0, 0, 1));
+                                                sound.setDirectionalCone(2 * BABYLON.Tools.ToDegrees(emitter.innerAngle == undefined ? Math.PI : emitter.innerAngle), 2 * BABYLON.Tools.ToDegrees(emitter.outerAngle == undefined ? Math.PI : emitter.outerAngle), 0);
+                                            }
+                                        }
+                                    }
+                                }));
+                            };
+                            for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) {
+                                var emitterIndex = _a[_i];
+                                _loop_2(emitterIndex);
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._loadAnimationAsync = function (context, animation) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, animation, function (extensionContext, extension) {
+                        return _this._loader._loadAnimationAsync(extensionContext, animation).then(function () {
+                            var promises = new Array();
+                            var babylonAnimationGroup = animation._babylonAnimationGroup;
+                            GLTF2._ArrayItem.Assign(extension.events);
+                            for (var _i = 0, _a = extension.events; _i < _a.length; _i++) {
+                                var event_1 = _a[_i];
+                                promises.push(_this._loadAnimationEventAsync(extensionContext + "/events/" + event_1._index, context, animation, event_1, babylonAnimationGroup));
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._getEventAction = function (context, sound, action, time, startOffset) {
+                    if (action == "play" /* play */) {
+                        return function (currentFrame) {
+                            var frameOffset = (startOffset || 0) + (currentFrame - time);
+                            sound.play(frameOffset);
+                        };
+                    }
+                    else if (action == "stop" /* stop */) {
+                        return function (currentFrame) {
+                            sound.stop();
+                        };
+                    }
+                    else if (action == "pause" /* pause */) {
+                        return function (currentFrame) {
+                            sound.pause();
+                        };
+                    }
+                    else {
+                        throw new Error(context + ": Unsupported action " + action);
+                    }
+                };
+                MSFT_audio_emitter.prototype._loadAnimationEventAsync = function (context, animationContext, animation, event, babylonAnimationGroup) {
+                    var _this = this;
+                    if (babylonAnimationGroup.targetedAnimations.length == 0) {
+                        return Promise.resolve();
+                    }
+                    var babylonAnimation = babylonAnimationGroup.targetedAnimations[0];
+                    var emitterIndex = event.emitter;
+                    var emitter = GLTF2.GLTFLoader._GetProperty("#/extensions/" + NAME + "/emitters", this._emitters, emitterIndex);
+                    return this._loadEmitterAsync(context, emitter).then(function () {
+                        var sound = emitter._babylonData.sound;
+                        if (sound) {
+                            var babylonAnimationEvent = new BABYLON.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(function () {
+                                sound.stop();
+                            });
+                            babylonAnimationGroup.onAnimationGroupPauseObservable.add(function () {
+                                sound.pause();
+                            });
+                        }
+                    });
+                };
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_extension", {
+                    get: function () {
+                        var extensions = this._loader._gltf.extensions;
+                        if (!extensions || !extensions[this.name]) {
+                            throw new Error("#/extensions: '" + this.name + "' not found");
+                        }
+                        return extensions[this.name];
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_clips", {
+                    get: function () {
+                        return this._extension.clips;
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_emitters", {
+                    get: function () {
+                        return this._extension.emitters;
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                return MSFT_audio_emitter;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.MSFT_audio_emitter = MSFT_audio_emitter;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFT_audio_emitter(loader); });
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=MSFT_audio_emitter.js.map
+
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
             var NAME = "MSFT_lod";
             var NAME = "MSFT_lod";
             /**
             /**
              * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
              * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
              */
              */
             var MSFT_lod = /** @class */ (function (_super) {
             var MSFT_lod = /** @class */ (function (_super) {
                 __extends(MSFT_lod, _super);
                 __extends(MSFT_lod, _super);
-                function MSFT_lod(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_lod() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
                     _this.name = NAME;
                     /**
                     /**
                      * Maximum number of LODs to load, starting from the lowest LOD.
                      * Maximum number of LODs to load, starting from the lowest LOD.
@@ -4611,42 +4909,6 @@ var BABYLON;
                     _this._materialIndexLOD = null;
                     _this._materialIndexLOD = null;
                     _this._materialSignalLODs = new Array();
                     _this._materialSignalLODs = new Array();
                     _this._materialPromiseLODs = new Array();
                     _this._materialPromiseLODs = new Array();
-                    _this._loader._readyPromise.then(function () {
-                        var _loop_1 = function (indexLOD) {
-                            var promise = Promise.all(_this._nodePromiseLODs[indexLOD]).then(function () {
-                                if (indexLOD !== 0) {
-                                    _this._loader._parent._endPerformanceCounter("Node LOD " + indexLOD);
-                                }
-                                _this._loader._parent._log("Loaded node LOD " + indexLOD);
-                                _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
-                                if (indexLOD !== _this._nodePromiseLODs.length - 1) {
-                                    _this._loader._parent._startPerformanceCounter("Node LOD " + (indexLOD + 1));
-                                    _this._nodeSignalLODs[indexLOD].resolve();
-                                }
-                            });
-                            _this._loader._completePromises.push(promise);
-                        };
-                        for (var indexLOD = 0; indexLOD < _this._nodePromiseLODs.length; indexLOD++) {
-                            _loop_1(indexLOD);
-                        }
-                        var _loop_2 = function (indexLOD) {
-                            var promise = Promise.all(_this._materialPromiseLODs[indexLOD]).then(function () {
-                                if (indexLOD !== 0) {
-                                    _this._loader._parent._endPerformanceCounter("Material LOD " + indexLOD);
-                                }
-                                _this._loader._parent._log("Loaded material LOD " + indexLOD);
-                                _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
-                                if (indexLOD !== _this._materialPromiseLODs.length - 1) {
-                                    _this._loader._parent._startPerformanceCounter("Material LOD " + (indexLOD + 1));
-                                    _this._materialSignalLODs[indexLOD].resolve();
-                                }
-                            });
-                            _this._loader._completePromises.push(promise);
-                        };
-                        for (var indexLOD = 0; indexLOD < _this._materialPromiseLODs.length; indexLOD++) {
-                            _loop_2(indexLOD);
-                        }
-                    });
                     return _this;
                     return _this;
                 }
                 }
                 MSFT_lod.prototype.dispose = function () {
                 MSFT_lod.prototype.dispose = function () {
@@ -4660,6 +4922,49 @@ var BABYLON;
                     this.onMaterialLODsLoadedObservable.clear();
                     this.onMaterialLODsLoadedObservable.clear();
                     this.onNodeLODsLoadedObservable.clear();
                     this.onNodeLODsLoadedObservable.clear();
                 };
                 };
+                MSFT_lod.prototype._onReady = function () {
+                    var _this = this;
+                    var _loop_1 = function (indexLOD) {
+                        var promise = Promise.all(this_1._nodePromiseLODs[indexLOD]).then(function () {
+                            if (indexLOD !== 0) {
+                                _this._loader._parent._endPerformanceCounter("Node LOD " + indexLOD);
+                            }
+                            _this._loader._parent._log("Loaded node LOD " + indexLOD);
+                            _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
+                            if (indexLOD !== _this._nodePromiseLODs.length - 1) {
+                                _this._loader._parent._startPerformanceCounter("Node LOD " + (indexLOD + 1));
+                                if (_this._nodeSignalLODs[indexLOD]) {
+                                    _this._nodeSignalLODs[indexLOD].resolve();
+                                }
+                            }
+                        });
+                        this_1._loader._completePromises.push(promise);
+                    };
+                    var this_1 = this;
+                    for (var indexLOD = 0; indexLOD < this._nodePromiseLODs.length; indexLOD++) {
+                        _loop_1(indexLOD);
+                    }
+                    var _loop_2 = function (indexLOD) {
+                        var promise = Promise.all(this_2._materialPromiseLODs[indexLOD]).then(function () {
+                            if (indexLOD !== 0) {
+                                _this._loader._parent._endPerformanceCounter("Material LOD " + indexLOD);
+                            }
+                            _this._loader._parent._log("Loaded material LOD " + indexLOD);
+                            _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
+                            if (indexLOD !== _this._materialPromiseLODs.length - 1) {
+                                _this._loader._parent._startPerformanceCounter("Material LOD " + (indexLOD + 1));
+                                if (_this._materialSignalLODs[indexLOD]) {
+                                    _this._materialSignalLODs[indexLOD].resolve();
+                                }
+                            }
+                        });
+                        this_2._loader._completePromises.push(promise);
+                    };
+                    var this_2 = this;
+                    for (var indexLOD = 0; indexLOD < this._materialPromiseLODs.length; indexLOD++) {
+                        _loop_2(indexLOD);
+                    }
+                };
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
@@ -4884,23 +5189,25 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
-                MSFT_sRGBFactors.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                MSFT_sRGBFactors.prototype._loadMaterialPropertiesAsync = function (context, material, babylonMaterial) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtrasValueAsync(context, material, function (extensionContext, value) {
                     return this._loadExtrasValueAsync(context, material, function (extensionContext, value) {
                         if (value) {
                         if (value) {
-                            return _this._loader._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
-                                if (!babylonMaterial.albedoTexture) {
-                                    babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor);
-                                }
-                                if (!babylonMaterial.reflectivityTexture) {
-                                    babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor);
-                                }
-                                assign(babylonMaterial);
-                            });
+                            var promise = _this._loader._loadMaterialPropertiesAsync(context, material, babylonMaterial);
+                            _this._convertColorsToLinear(babylonMaterial);
+                            return promise;
                         }
                         }
                         return null;
                         return null;
                     });
                     });
                 };
                 };
+                MSFT_sRGBFactors.prototype._convertColorsToLinear = function (babylonMaterial) {
+                    if (!babylonMaterial.albedoTexture) {
+                        babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor);
+                    }
+                    if (!babylonMaterial.reflectivityTexture) {
+                        babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor);
+                    }
+                };
                 return MSFT_sRGBFactors;
                 return MSFT_sRGBFactors;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
@@ -5154,8 +5461,6 @@ var BABYLON;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
 
 
-//# sourceMappingURL=KHR_materials_unlit.js.map
-
 /// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
 /// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
 var __extends = (this && this.__extends) || (function () {
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
     var extendStatics = Object.setPrototypeOf ||
@@ -5191,6 +5496,13 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
+                KHR_lights.prototype._onLoading = function () {
+                    var extensions = this._loader._gltf.extensions;
+                    if (extensions && extensions[this.name]) {
+                        var extension = extensions[this.name];
+                        this._lights = extension.lights;
+                    }
+                };
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
@@ -5239,18 +5551,6 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                Object.defineProperty(KHR_lights.prototype, "_lights", {
-                    get: function () {
-                        var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: '" + this.name + "' not found");
-                        }
-                        var extension = extensions[this.name];
-                        return extension.lights;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
                 return KHR_lights;
                 return KHR_lights;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.KHR_lights = KHR_lights;
             Extensions.KHR_lights = KHR_lights;
@@ -5348,6 +5648,13 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
+                EXT_lights_imageBased.prototype._onLoading = function () {
+                    var extensions = this._loader._gltf.extensions;
+                    if (extensions && extensions[this.name]) {
+                        var extension = extensions[this.name];
+                        this._lights = extension.lights;
+                    }
+                };
                 EXT_lights_imageBased.prototype._loadSceneAsync = function (context, scene) {
                 EXT_lights_imageBased.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
@@ -5417,18 +5724,6 @@ var BABYLON;
                         return light._babylonTexture;
                         return light._babylonTexture;
                     });
                     });
                 };
                 };
-                Object.defineProperty(EXT_lights_imageBased.prototype, "_lights", {
-                    get: function () {
-                        var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: '" + this.name + "' not found");
-                        }
-                        var extension = extensions[this.name];
-                        return extension.lights;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
                 return EXT_lights_imageBased;
                 return EXT_lights_imageBased;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.EXT_lights_imageBased = EXT_lights_imageBased;
             Extensions.EXT_lights_imageBased = EXT_lights_imageBased;

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


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

@@ -45,6 +45,7 @@ declare module BABYLON {
         facePattern2: RegExp;
         facePattern2: RegExp;
         facePattern3: RegExp;
         facePattern3: RegExp;
         facePattern4: RegExp;
         facePattern4: RegExp;
+        facePattern5: RegExp;
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * 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.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.

+ 37 - 1
dist/preview release/loaders/babylon.objFileLoader.js

@@ -231,6 +231,8 @@ var BABYLON;
             this.facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
             this.facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
             // f vertex//normal vertex//normal vertex//normal ...
             // f vertex//normal vertex//normal vertex//normal ...
             this.facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
             this.facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
+            // f -vertex/-uvs/-normal -vertex/-uvs/-normal -vertex/-uvs/-normal ...
+            this.facePattern5 = /f\s+(((-[\d]{1,}\/-[\d]{1,}\/-[\d]{1,}[\s]?){3,})+)/;
         }
         }
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * Calls synchronously the MTL file attached to this obj.
@@ -413,11 +415,12 @@ var BABYLON;
              * Create triangles from polygons by recursion
              * 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.
              * 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
              * It is important to notice that a triangle is a polygon
-             * We get 4 patterns of face defined in OBJ File :
+             * We get 5 patterns of face defined in OBJ File :
              * facePattern1 = ["1","2","3","4","5","6"]
              * facePattern1 = ["1","2","3","4","5","6"]
              * facePattern2 = ["1/1","2/2","3/3","4/4","5/5","6/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"]
              * 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"]
              * 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
              * Each pattern is divided by the same method
              * @param face Array[String] The indices of elements
              * @param face Array[String] The indices of elements
              * @param v Integer The variable to increment
              * @param v Integer The variable to increment
@@ -437,6 +440,7 @@ var BABYLON;
                 //Pattern2 => triangle = ["1/1","2/2","3/3","1/1","3/3","4/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"];
                 //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"];
                 //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
              * Create triangles and push the data for each polygon for the pattern 1
@@ -532,6 +536,31 @@ var BABYLON;
                 //Reset variable for the next line
                 //Reset variable for the next line
                 triangles = [];
                 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 = function (face, v) {
+                //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 = function () {
             var addPreviousObjMesh = function () {
                 //Check if it is not the first mesh. Otherwise we don't have data.
                 //Check if it is not the first mesh. Otherwise we don't have data.
                 if (meshesFromObj.length > 0) {
                 if (meshesFromObj.length > 0) {
@@ -604,6 +633,13 @@ var BABYLON;
                     setDataForCurrentFaceWithPattern4(result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
                     setDataForCurrentFaceWithPattern4(result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
                     1);
                     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) {
                 else if ((result = this.facePattern2.exec(line)) !== null) {
                     //Value of result:
                     //Value of result:
                     //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]
                     //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]

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


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

@@ -63,6 +63,7 @@ declare module BABYLON {
         facePattern2: RegExp;
         facePattern2: RegExp;
         facePattern3: RegExp;
         facePattern3: RegExp;
         facePattern4: RegExp;
         facePattern4: RegExp;
+        facePattern5: RegExp;
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * 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.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.
@@ -292,9 +293,20 @@ declare module BABYLON {
         private _onCompleteObserver;
         private _onCompleteObserver;
         /**
         /**
          * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
          * 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.
          */
          */
         onComplete: () => void;
         onComplete: () => void;
         /**
         /**
+         * Observable raised when an error occurs.
+         */
+        readonly onErrorObservable: Observable<any>;
+        private _onErrorObserver;
+        /**
+         * Callback raised when an error occurs.
+         */
+        onError: (reason: any) => void;
+        /**
          * Observable raised after the loader is disposed.
          * Observable raised after the loader is disposed.
          */
          */
         readonly onDisposeObservable: Observable<void>;
         readonly onDisposeObservable: Observable<void>;
@@ -1112,7 +1124,6 @@ declare module BABYLON.GLTF2 {
         _parent: GLTFFileLoader;
         _parent: GLTFFileLoader;
         _gltf: _ILoaderGLTF;
         _gltf: _ILoaderGLTF;
         _babylonScene: Scene;
         _babylonScene: Scene;
-        _readyPromise: Promise<void>;
         _completePromises: Promise<void>[];
         _completePromises: Promise<void>[];
         private _disposed;
         private _disposed;
         private _state;
         private _state;
@@ -1126,9 +1137,6 @@ declare module BABYLON.GLTF2 {
         private static _ExtensionNames;
         private static _ExtensionNames;
         private static _ExtensionFactories;
         private static _ExtensionFactories;
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
-        /**
-         * Loader state or null if the loader is not active.
-         */
         readonly state: Nullable<GLTFLoaderState>;
         readonly state: Nullable<GLTFLoaderState>;
         constructor(parent: GLTFFileLoader);
         constructor(parent: GLTFFileLoader);
         dispose(): void;
         dispose(): void;
@@ -1144,6 +1152,7 @@ declare module BABYLON.GLTF2 {
         private _setupData();
         private _setupData();
         private _loadExtensions();
         private _loadExtensions();
         private _checkExtensions();
         private _checkExtensions();
+        private _setState(state);
         private _createRootNode();
         private _createRootNode();
         _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void>;
         _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void>;
         private _forEachPrimitive(node, callback);
         private _forEachPrimitive(node, callback);
@@ -1167,7 +1176,7 @@ declare module BABYLON.GLTF2 {
         private _getNodeMatrix(node);
         private _getNodeMatrix(node);
         private _loadCamera(context, camera, babylonMesh);
         private _loadCamera(context, camera, babylonMesh);
         private _loadAnimationsAsync();
         private _loadAnimationsAsync();
-        private _loadAnimationAsync(context, animation);
+        _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Promise<void>;
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadBufferAsync(context, buffer);
         private _loadBufferAsync(context, buffer);
@@ -1199,6 +1208,7 @@ declare module BABYLON.GLTF2 {
         private _compileMaterialsAsync();
         private _compileMaterialsAsync();
         private _compileShadowGeneratorsAsync();
         private _compileShadowGeneratorsAsync();
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
+        _forEachExtensions(action: (extension: GLTFLoaderExtension) => void): void;
     }
     }
 }
 }
 
 
@@ -1227,6 +1237,14 @@ declare module BABYLON.GLTF2 {
          */
          */
         dispose(): void;
         dispose(): void;
         /**
         /**
+         * Override this method to do work after the state changes to LOADING.
+         */
+        protected _onLoading(): void;
+        /**
+         * Override this method to do work after the state changes to READY.
+         */
+        protected _onReady(): void;
+        /**
          * Override this method to modify the default behavior for loading scenes.
          * Override this method to modify the default behavior for loading scenes.
          * @hidden
          * @hidden
          */
          */
@@ -1266,6 +1284,8 @@ declare module BABYLON.GLTF2 {
          * @hidden
          * @hidden
          */
          */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+        /** Override this method to modify the default behavior for loading animations. */
+        protected _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
         /**
         /**
          * Helper method called by a loader extension to load an glTF extension.
          * Helper method called by a loader extension to load an glTF extension.
          * @hidden
          * @hidden
@@ -1277,6 +1297,16 @@ declare module BABYLON.GLTF2 {
          */
          */
         protected _loadExtrasValueAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, value: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
         protected _loadExtrasValueAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, value: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
         /**
         /**
+         * Helper method called by the loader after the state changes to LOADING.
+         * @hidden
+         */
+        static _OnLoading(loader: GLTFLoader): void;
+        /**
+         * Helper method called by the loader after the state changes to READY.
+         * @hidden
+         */
+        static _OnReady(loader: GLTFLoader): void;
+        /**
          * Helper method called by the loader to allow extensions to override loading scenes.
          * Helper method called by the loader to allow extensions to override loading scenes.
          * @hidden
          * @hidden
          */
          */
@@ -1316,6 +1346,11 @@ declare module BABYLON.GLTF2 {
          * @hidden
          * @hidden
          */
          */
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading animations.
+         * @hidden
+         */
+        static _LoadAnimationAsync(loader: GLTFLoader, context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
     }
     }
 }
 }
 /**
 /**
@@ -1327,6 +1362,26 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
     /**
     /**
+     * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
+     */
+    class MSFT_audio_emitter extends GLTFLoaderExtension {
+        readonly name: string;
+        private _loadClipAsync(context, clip);
+        private _loadEmitterAsync(context, emitter);
+        protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
+        protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
+        protected _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
+        private _getEventAction(context, sound, action, time, startOffset?);
+        private _loadAnimationEventAsync(context, animationContext, animation, event, babylonAnimationGroup);
+        private readonly _extension;
+        private readonly _clips;
+        private readonly _emitters;
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
      */
      */
     class MSFT_lod extends GLTFLoaderExtension {
     class MSFT_lod extends GLTFLoaderExtension {
@@ -1353,8 +1408,8 @@ declare module BABYLON.GLTF2.Extensions {
         private _materialIndexLOD;
         private _materialIndexLOD;
         private _materialSignalLODs;
         private _materialSignalLODs;
         private _materialPromiseLODs;
         private _materialPromiseLODs;
-        constructor(loader: GLTFLoader);
         dispose(): void;
         dispose(): void;
+        protected _onReady(): void;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
@@ -1380,7 +1435,8 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     /** @hidden */
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        protected _loadMaterialPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: Material): Nullable<Promise<void>>;
+        private _convertColorsToLinear(babylonMaterial);
     }
     }
 }
 }
 
 
@@ -1429,9 +1485,10 @@ declare module BABYLON.GLTF2.Extensions {
      */
      */
     class KHR_lights extends GLTFLoaderExtension {
     class KHR_lights extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
+        private _lights?;
+        protected _onLoading(): void;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        private readonly _lights;
     }
     }
 }
 }
 
 
@@ -1453,8 +1510,9 @@ declare module BABYLON.GLTF2.Extensions {
      */
      */
     class EXT_lights_imageBased extends GLTFLoaderExtension {
     class EXT_lights_imageBased extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
+        private _lights?;
+        protected _onLoading(): void;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         private _loadLightAsync(context, light);
         private _loadLightAsync(context, light);
-        private readonly _lights;
     }
     }
 }
 }

+ 419 - 97
dist/preview release/loaders/babylonjs.loaders.js

@@ -430,6 +430,8 @@ var BABYLON;
             this.facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
             this.facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
             // f vertex//normal vertex//normal vertex//normal ...
             // f vertex//normal vertex//normal vertex//normal ...
             this.facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
             this.facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
+            // f -vertex/-uvs/-normal -vertex/-uvs/-normal -vertex/-uvs/-normal ...
+            this.facePattern5 = /f\s+(((-[\d]{1,}\/-[\d]{1,}\/-[\d]{1,}[\s]?){3,})+)/;
         }
         }
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * Calls synchronously the MTL file attached to this obj.
@@ -612,11 +614,12 @@ var BABYLON;
              * Create triangles from polygons by recursion
              * 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.
              * 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
              * It is important to notice that a triangle is a polygon
-             * We get 4 patterns of face defined in OBJ File :
+             * We get 5 patterns of face defined in OBJ File :
              * facePattern1 = ["1","2","3","4","5","6"]
              * facePattern1 = ["1","2","3","4","5","6"]
              * facePattern2 = ["1/1","2/2","3/3","4/4","5/5","6/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"]
              * 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"]
              * 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
              * Each pattern is divided by the same method
              * @param face Array[String] The indices of elements
              * @param face Array[String] The indices of elements
              * @param v Integer The variable to increment
              * @param v Integer The variable to increment
@@ -636,6 +639,7 @@ var BABYLON;
                 //Pattern2 => triangle = ["1/1","2/2","3/3","1/1","3/3","4/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"];
                 //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"];
                 //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
              * Create triangles and push the data for each polygon for the pattern 1
@@ -731,6 +735,31 @@ var BABYLON;
                 //Reset variable for the next line
                 //Reset variable for the next line
                 triangles = [];
                 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 = function (face, v) {
+                //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 = function () {
             var addPreviousObjMesh = function () {
                 //Check if it is not the first mesh. Otherwise we don't have data.
                 //Check if it is not the first mesh. Otherwise we don't have data.
                 if (meshesFromObj.length > 0) {
                 if (meshesFromObj.length > 0) {
@@ -803,6 +832,13 @@ var BABYLON;
                     setDataForCurrentFaceWithPattern4(result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
                     setDataForCurrentFaceWithPattern4(result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
                     1);
                     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) {
                 else if ((result = this.facePattern2.exec(line)) !== null) {
                     //Value of result:
                     //Value of result:
                     //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]
                     //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]
@@ -1137,6 +1173,10 @@ var BABYLON;
              */
              */
             this.onCompleteObservable = new BABYLON.Observable();
             this.onCompleteObservable = new BABYLON.Observable();
             /**
             /**
+             * Observable raised when an error occurs.
+             */
+            this.onErrorObservable = new BABYLON.Observable();
+            /**
              * Observable raised after the loader is disposed.
              * Observable raised after the loader is disposed.
              */
              */
             this.onDisposeObservable = new BABYLON.Observable();
             this.onDisposeObservable = new BABYLON.Observable();
@@ -1236,6 +1276,8 @@ var BABYLON;
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
         Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
             /**
             /**
              * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
              * 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.
              */
              */
             set: function (callback) {
             set: function (callback) {
                 if (this._onCompleteObserver) {
                 if (this._onCompleteObserver) {
@@ -1246,6 +1288,19 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        Object.defineProperty(GLTFFileLoader.prototype, "onError", {
+            /**
+             * Callback raised when an error occurs.
+             */
+            set: function (callback) {
+                if (this._onErrorObserver) {
+                    this.onErrorObservable.remove(this._onErrorObserver);
+                }
+                this._onErrorObserver = this.onErrorObservable.add(callback);
+            },
+            enumerable: true,
+            configurable: true
+        });
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
         Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
             /**
             /**
              * Callback raised after the loader is disposed.
              * Callback raised after the loader is disposed.
@@ -1278,10 +1333,13 @@ var BABYLON;
          */
          */
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
         GLTFFileLoader.prototype.whenCompleteAsync = function () {
             var _this = this;
             var _this = this;
-            return new Promise(function (resolve) {
+            return new Promise(function (resolve, reject) {
                 _this.onCompleteObservable.addOnce(function () {
                 _this.onCompleteObservable.addOnce(function () {
                     resolve();
                     resolve();
                 });
                 });
+                _this.onErrorObservable.addOnce(function (reason) {
+                    reject(reason);
+                });
             });
             });
         };
         };
         Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
         Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
@@ -3915,9 +3973,6 @@ var BABYLON;
                 GLTFLoader._ExtensionNames.push(name);
                 GLTFLoader._ExtensionNames.push(name);
             };
             };
             Object.defineProperty(GLTFLoader.prototype, "state", {
             Object.defineProperty(GLTFLoader.prototype, "state", {
-                /**
-                 * Loader state or null if the loader is not active.
-                 */
                 get: function () {
                 get: function () {
                     return this._state;
                     return this._state;
                 },
                 },
@@ -3936,7 +3991,6 @@ var BABYLON;
                 this._requests.length = 0;
                 this._requests.length = 0;
                 delete this._gltf;
                 delete this._gltf;
                 delete this._babylonScene;
                 delete this._babylonScene;
-                delete this._readyPromise;
                 this._completePromises.length = 0;
                 this._completePromises.length = 0;
                 for (var name_1 in this._extensions) {
                 for (var name_1 in this._extensions) {
                     this._extensions[name_1].dispose();
                     this._extensions[name_1].dispose();
@@ -3996,14 +4050,14 @@ var BABYLON;
             GLTFLoader.prototype._loadAsync = function (nodes) {
             GLTFLoader.prototype._loadAsync = function (nodes) {
                 var _this = this;
                 var _this = this;
                 return Promise.resolve().then(function () {
                 return Promise.resolve().then(function () {
-                    _this._parent._startPerformanceCounter("Loading => Ready");
-                    _this._parent._startPerformanceCounter("Loading => Complete");
-                    _this._state = BABYLON.GLTFLoaderState.LOADING;
-                    _this._parent._log("Loading");
-                    var readyDeferred = new BABYLON.Deferred();
-                    _this._readyPromise = readyDeferred.promise;
                     _this._loadExtensions();
                     _this._loadExtensions();
                     _this._checkExtensions();
                     _this._checkExtensions();
+                    var loadingToReadyCounterName = BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.LOADING] + " => " + BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.READY];
+                    var loadingToCompleteCounterName = BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.LOADING] + " => " + BABYLON.GLTFLoaderState[BABYLON.GLTFLoaderState.COMPLETE];
+                    _this._parent._startPerformanceCounter(loadingToReadyCounterName);
+                    _this._parent._startPerformanceCounter(loadingToCompleteCounterName);
+                    _this._setState(BABYLON.GLTFLoaderState.LOADING);
+                    GLTF2.GLTFLoaderExtension._OnLoading(_this);
                     var promises = new Array();
                     var promises = new Array();
                     if (nodes) {
                     if (nodes) {
                         promises.push(_this._loadSceneAsync("#/nodes", { nodes: nodes, _index: -1 }));
                         promises.push(_this._loadSceneAsync("#/nodes", { nodes: nodes, _index: -1 }));
@@ -4019,33 +4073,33 @@ var BABYLON;
                         promises.push(_this._compileShadowGeneratorsAsync());
                         promises.push(_this._compileShadowGeneratorsAsync());
                     }
                     }
                     var resultPromise = Promise.all(promises).then(function () {
                     var resultPromise = Promise.all(promises).then(function () {
-                        _this._state = BABYLON.GLTFLoaderState.READY;
-                        _this._parent._log("Ready");
-                        readyDeferred.resolve();
+                        _this._setState(BABYLON.GLTFLoaderState.READY);
+                        GLTF2.GLTFLoaderExtension._OnReady(_this);
                         _this._startAnimations();
                         _this._startAnimations();
                     });
                     });
                     resultPromise.then(function () {
                     resultPromise.then(function () {
-                        _this._parent._endPerformanceCounter("Loading => Ready");
+                        _this._parent._endPerformanceCounter(loadingToReadyCounterName);
                         BABYLON.Tools.SetImmediate(function () {
                         BABYLON.Tools.SetImmediate(function () {
                             if (!_this._disposed) {
                             if (!_this._disposed) {
                                 Promise.all(_this._completePromises).then(function () {
                                 Promise.all(_this._completePromises).then(function () {
-                                    _this._parent._endPerformanceCounter("Loading => Complete");
-                                    _this._state = BABYLON.GLTFLoaderState.COMPLETE;
-                                    _this._parent._log("Complete");
+                                    _this._parent._endPerformanceCounter(loadingToCompleteCounterName);
+                                    _this._setState(BABYLON.GLTFLoaderState.COMPLETE);
                                     _this._parent.onCompleteObservable.notifyObservers(undefined);
                                     _this._parent.onCompleteObservable.notifyObservers(undefined);
                                     _this._parent.onCompleteObservable.clear();
                                     _this._parent.onCompleteObservable.clear();
                                     _this.dispose();
                                     _this.dispose();
-                                }).catch(function (error) {
-                                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                                }, function (error) {
+                                    _this._parent.onErrorObservable.notifyObservers(error);
+                                    _this._parent.onErrorObservable.clear();
                                     _this.dispose();
                                     _this.dispose();
                                 });
                                 });
                             }
                             }
                         });
                         });
                     });
                     });
                     return resultPromise;
                     return resultPromise;
-                }).catch(function (error) {
+                }, function (error) {
                     if (!_this._disposed) {
                     if (!_this._disposed) {
-                        BABYLON.Tools.Error("glTF Loader: " + error.message);
+                        _this._parent.onErrorObservable.notifyObservers(error);
+                        _this._parent.onErrorObservable.clear();
                         _this.dispose();
                         _this.dispose();
                         throw error;
                         throw error;
                     }
                     }
@@ -4121,6 +4175,10 @@ var BABYLON;
                     }
                     }
                 }
                 }
             };
             };
+            GLTFLoader.prototype._setState = function (state) {
+                this._state = state;
+                this._parent._log(BABYLON.GLTFLoaderState[this._state]);
+            };
             GLTFLoader.prototype._createRootNode = function () {
             GLTFLoader.prototype._createRootNode = function () {
                 this._rootBabylonMesh = new BABYLON.Mesh("__root__", this._babylonScene);
                 this._rootBabylonMesh = new BABYLON.Mesh("__root__", this._babylonScene);
                 var rootNode = { _babylonMesh: this._rootBabylonMesh };
                 var rootNode = { _babylonMesh: this._rootBabylonMesh };
@@ -4611,6 +4669,10 @@ var BABYLON;
             };
             };
             GLTFLoader.prototype._loadAnimationAsync = function (context, animation) {
             GLTFLoader.prototype._loadAnimationAsync = function (context, animation) {
                 var _this = this;
                 var _this = this;
+                var promise = GLTF2.GLTFLoaderExtension._LoadAnimationAsync(this, context, animation);
+                if (promise) {
+                    return promise;
+                }
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 var babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation._index, this._babylonScene);
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 animation._babylonAnimationGroup = babylonAnimationGroup;
                 var promises = new Array();
                 var promises = new Array();
@@ -5375,6 +5437,15 @@ var BABYLON;
                 }
                 }
                 return null;
                 return null;
             };
             };
+            GLTFLoader.prototype._forEachExtensions = function (action) {
+                for (var _i = 0, _a = GLTFLoader._ExtensionNames; _i < _a.length; _i++) {
+                    var name_6 = _a[_i];
+                    var extension = this._extensions[name_6];
+                    if (extension.enabled) {
+                        action(extension);
+                    }
+                }
+            };
             GLTFLoader._ExtensionNames = new Array();
             GLTFLoader._ExtensionNames = new Array();
             GLTFLoader._ExtensionFactories = {};
             GLTFLoader._ExtensionFactories = {};
             return GLTFLoader;
             return GLTFLoader;
@@ -5414,6 +5485,14 @@ var BABYLON;
             };
             };
             // #region Overridable Methods
             // #region Overridable Methods
             /**
             /**
+             * Override this method to do work after the state changes to LOADING.
+             */
+            GLTFLoaderExtension.prototype._onLoading = function () { };
+            /**
+             * Override this method to do work after the state changes to READY.
+             */
+            GLTFLoaderExtension.prototype._onReady = function () { };
+            /**
              * Override this method to modify the default behavior for loading scenes.
              * Override this method to modify the default behavior for loading scenes.
              * @hidden
              * @hidden
              */
              */
@@ -5453,6 +5532,8 @@ var BABYLON;
              * @hidden
              * @hidden
              */
              */
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
             GLTFLoaderExtension.prototype._loadUriAsync = function (context, uri) { return null; };
+            /** Override this method to modify the default behavior for loading animations. */
+            GLTFLoaderExtension.prototype._loadAnimationAsync = function (context, animation) { return null; };
             // #endregion
             // #endregion
             /**
             /**
              * Helper method called by a loader extension to load an glTF extension.
              * Helper method called by a loader extension to load an glTF extension.
@@ -5501,6 +5582,20 @@ var BABYLON;
                 }
                 }
             };
             };
             /**
             /**
+             * Helper method called by the loader after the state changes to LOADING.
+             * @hidden
+             */
+            GLTFLoaderExtension._OnLoading = function (loader) {
+                loader._forEachExtensions(function (extension) { return extension._onLoading(); });
+            };
+            /**
+             * Helper method called by the loader after the state changes to READY.
+             * @hidden
+             */
+            GLTFLoaderExtension._OnReady = function (loader) {
+                loader._forEachExtensions(function (extension) { return extension._onReady(); });
+            };
+            /**
              * Helper method called by the loader to allow extensions to override loading scenes.
              * Helper method called by the loader to allow extensions to override loading scenes.
              * @hidden
              * @hidden
              */
              */
@@ -5556,6 +5651,13 @@ var BABYLON;
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
             GLTFLoaderExtension._LoadUriAsync = function (loader, context, uri) {
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
                 return loader._applyExtensions(function (extension) { return extension._loadUriAsync(context, uri); });
             };
             };
+            /**
+             * Helper method called by the loader to allow extensions to override loading animations.
+             * @hidden
+             */
+            GLTFLoaderExtension._LoadAnimationAsync = function (loader, context, animation) {
+                return loader._applyExtensions(function (extension) { return extension._loadAnimationAsync(context, animation); });
+            };
             return GLTFLoaderExtension;
             return GLTFLoaderExtension;
         }());
         }());
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
@@ -5572,14 +5674,237 @@ var BABYLON;
     (function (GLTF2) {
     (function (GLTF2) {
         var Extensions;
         var Extensions;
         (function (Extensions) {
         (function (Extensions) {
+            var NAME = "MSFT_audio_emitter";
+            /**
+             * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
+             */
+            var MSFT_audio_emitter = /** @class */ (function (_super) {
+                __extends(MSFT_audio_emitter, _super);
+                function MSFT_audio_emitter() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
+                }
+                MSFT_audio_emitter.prototype._loadClipAsync = function (context, clip) {
+                    if (clip._objectURL) {
+                        return clip._objectURL;
+                    }
+                    var promise;
+                    if (clip.uri) {
+                        promise = this._loader._loadUriAsync(context, clip.uri);
+                    }
+                    else {
+                        var bufferView = GLTF2.GLTFLoader._GetProperty(context + "/bufferView", this._loader._gltf.bufferViews, clip.bufferView);
+                        promise = this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView);
+                    }
+                    clip._objectURL = promise.then(function (data) {
+                        return URL.createObjectURL(new Blob([data], { type: clip.mimeType }));
+                    });
+                    return clip._objectURL;
+                };
+                MSFT_audio_emitter.prototype._loadEmitterAsync = function (context, emitter) {
+                    var _this = this;
+                    emitter._babylonSounds = emitter._babylonSounds || [];
+                    if (!emitter._babylonData) {
+                        var clipPromises = new Array();
+                        var name_1 = emitter.name || "emitter" + emitter._index;
+                        var options_1 = {
+                            loop: false,
+                            autoplay: false,
+                            volume: emitter.volume == undefined ? 1 : emitter.volume,
+                        };
+                        GLTF2._ArrayItem.Assign(this._clips);
+                        var _loop_1 = function (i) {
+                            var clipContext = "#/extensions/" + NAME + "/clips";
+                            var clip = GLTF2.GLTFLoader._GetProperty(clipContext, this_1._clips, emitter.clips[i].clip);
+                            clipPromises.push(this_1._loadClipAsync(clipContext + "/" + emitter.clips[i].clip, clip).then(function (objectURL) {
+                                var sound = emitter._babylonSounds[i] = new BABYLON.Sound(name_1, objectURL, _this._loader._babylonScene, null, options_1);
+                                sound.refDistance = emitter.refDistance || 1;
+                                sound.maxDistance = emitter.maxDistance || 256;
+                                sound.rolloffFactor = emitter.rolloffFactor || 1;
+                                sound.distanceModel = emitter.distanceModel || 'exponential';
+                                sound._positionInEmitterSpace = true;
+                            }));
+                        };
+                        var this_1 = this;
+                        for (var i = 0; i < emitter.clips.length; i++) {
+                            _loop_1(i);
+                        }
+                        var promise = Promise.all(clipPromises).then(function () {
+                            var weights = emitter.clips.map(function (clip) { return clip.weight || 1; });
+                            var weightedSound = new BABYLON.WeightedSound(emitter.loop || false, emitter._babylonSounds, weights);
+                            if (emitter.innerAngle)
+                                weightedSound.directionalConeInnerAngle = 2 * BABYLON.Tools.ToDegrees(emitter.innerAngle);
+                            if (emitter.outerAngle)
+                                weightedSound.directionalConeOuterAngle = 2 * BABYLON.Tools.ToDegrees(emitter.outerAngle);
+                            if (emitter.volume)
+                                weightedSound.volume = emitter.volume;
+                            emitter._babylonData.sound = weightedSound;
+                        });
+                        emitter._babylonData = {
+                            loaded: promise
+                        };
+                    }
+                    return emitter._babylonData.loaded;
+                };
+                MSFT_audio_emitter.prototype._loadSceneAsync = function (context, scene) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
+                        return _this._loader._loadSceneAsync(context, scene).then(function () {
+                            var promises = new Array();
+                            GLTF2._ArrayItem.Assign(_this._emitters);
+                            for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) {
+                                var emitterIndex = _a[_i];
+                                var emitter = GLTF2.GLTFLoader._GetProperty(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));
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._loadNodeAsync = function (context, node) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
+                        return _this._loader._loadNodeAsync(extensionContext, node).then(function () {
+                            var promises = new Array();
+                            GLTF2._ArrayItem.Assign(_this._emitters);
+                            var _loop_2 = function (emitterIndex) {
+                                var emitter = GLTF2.GLTFLoader._GetProperty(extensionContext + "/emitters", _this._emitters, emitterIndex);
+                                promises.push(_this._loadEmitterAsync(extensionContext + "/emitters/" + emitter._index, emitter).then(function () {
+                                    if (node._babylonMesh) {
+                                        for (var _i = 0, _a = emitter._babylonSounds; _i < _a.length; _i++) {
+                                            var sound = _a[_i];
+                                            sound.attachToMesh(node._babylonMesh);
+                                            if (emitter.innerAngle != undefined || emitter.outerAngle != undefined) {
+                                                sound.setLocalDirectionToMesh(new BABYLON.Vector3(0, 0, 1));
+                                                sound.setDirectionalCone(2 * BABYLON.Tools.ToDegrees(emitter.innerAngle == undefined ? Math.PI : emitter.innerAngle), 2 * BABYLON.Tools.ToDegrees(emitter.outerAngle == undefined ? Math.PI : emitter.outerAngle), 0);
+                                            }
+                                        }
+                                    }
+                                }));
+                            };
+                            for (var _i = 0, _a = extension.emitters; _i < _a.length; _i++) {
+                                var emitterIndex = _a[_i];
+                                _loop_2(emitterIndex);
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._loadAnimationAsync = function (context, animation) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, animation, function (extensionContext, extension) {
+                        return _this._loader._loadAnimationAsync(extensionContext, animation).then(function () {
+                            var promises = new Array();
+                            var babylonAnimationGroup = animation._babylonAnimationGroup;
+                            GLTF2._ArrayItem.Assign(extension.events);
+                            for (var _i = 0, _a = extension.events; _i < _a.length; _i++) {
+                                var event_1 = _a[_i];
+                                promises.push(_this._loadAnimationEventAsync(extensionContext + "/events/" + event_1._index, context, animation, event_1, babylonAnimationGroup));
+                            }
+                            return Promise.all(promises).then(function () { });
+                        });
+                    });
+                };
+                MSFT_audio_emitter.prototype._getEventAction = function (context, sound, action, time, startOffset) {
+                    if (action == "play" /* play */) {
+                        return function (currentFrame) {
+                            var frameOffset = (startOffset || 0) + (currentFrame - time);
+                            sound.play(frameOffset);
+                        };
+                    }
+                    else if (action == "stop" /* stop */) {
+                        return function (currentFrame) {
+                            sound.stop();
+                        };
+                    }
+                    else if (action == "pause" /* pause */) {
+                        return function (currentFrame) {
+                            sound.pause();
+                        };
+                    }
+                    else {
+                        throw new Error(context + ": Unsupported action " + action);
+                    }
+                };
+                MSFT_audio_emitter.prototype._loadAnimationEventAsync = function (context, animationContext, animation, event, babylonAnimationGroup) {
+                    var _this = this;
+                    if (babylonAnimationGroup.targetedAnimations.length == 0) {
+                        return Promise.resolve();
+                    }
+                    var babylonAnimation = babylonAnimationGroup.targetedAnimations[0];
+                    var emitterIndex = event.emitter;
+                    var emitter = GLTF2.GLTFLoader._GetProperty("#/extensions/" + NAME + "/emitters", this._emitters, emitterIndex);
+                    return this._loadEmitterAsync(context, emitter).then(function () {
+                        var sound = emitter._babylonData.sound;
+                        if (sound) {
+                            var babylonAnimationEvent = new BABYLON.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(function () {
+                                sound.stop();
+                            });
+                            babylonAnimationGroup.onAnimationGroupPauseObservable.add(function () {
+                                sound.pause();
+                            });
+                        }
+                    });
+                };
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_extension", {
+                    get: function () {
+                        var extensions = this._loader._gltf.extensions;
+                        if (!extensions || !extensions[this.name]) {
+                            throw new Error("#/extensions: '" + this.name + "' not found");
+                        }
+                        return extensions[this.name];
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_clips", {
+                    get: function () {
+                        return this._extension.clips;
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                Object.defineProperty(MSFT_audio_emitter.prototype, "_emitters", {
+                    get: function () {
+                        return this._extension.emitters;
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                return MSFT_audio_emitter;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.MSFT_audio_emitter = MSFT_audio_emitter;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFT_audio_emitter(loader); });
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=MSFT_audio_emitter.js.map
+
+
+
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
             var NAME = "MSFT_lod";
             var NAME = "MSFT_lod";
             /**
             /**
              * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
              * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
              */
              */
             var MSFT_lod = /** @class */ (function (_super) {
             var MSFT_lod = /** @class */ (function (_super) {
                 __extends(MSFT_lod, _super);
                 __extends(MSFT_lod, _super);
-                function MSFT_lod(loader) {
-                    var _this = _super.call(this, loader) || this;
+                function MSFT_lod() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
                     _this.name = NAME;
                     _this.name = NAME;
                     /**
                     /**
                      * Maximum number of LODs to load, starting from the lowest LOD.
                      * Maximum number of LODs to load, starting from the lowest LOD.
@@ -5603,42 +5928,6 @@ var BABYLON;
                     _this._materialIndexLOD = null;
                     _this._materialIndexLOD = null;
                     _this._materialSignalLODs = new Array();
                     _this._materialSignalLODs = new Array();
                     _this._materialPromiseLODs = new Array();
                     _this._materialPromiseLODs = new Array();
-                    _this._loader._readyPromise.then(function () {
-                        var _loop_1 = function (indexLOD) {
-                            var promise = Promise.all(_this._nodePromiseLODs[indexLOD]).then(function () {
-                                if (indexLOD !== 0) {
-                                    _this._loader._parent._endPerformanceCounter("Node LOD " + indexLOD);
-                                }
-                                _this._loader._parent._log("Loaded node LOD " + indexLOD);
-                                _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
-                                if (indexLOD !== _this._nodePromiseLODs.length - 1) {
-                                    _this._loader._parent._startPerformanceCounter("Node LOD " + (indexLOD + 1));
-                                    _this._nodeSignalLODs[indexLOD].resolve();
-                                }
-                            });
-                            _this._loader._completePromises.push(promise);
-                        };
-                        for (var indexLOD = 0; indexLOD < _this._nodePromiseLODs.length; indexLOD++) {
-                            _loop_1(indexLOD);
-                        }
-                        var _loop_2 = function (indexLOD) {
-                            var promise = Promise.all(_this._materialPromiseLODs[indexLOD]).then(function () {
-                                if (indexLOD !== 0) {
-                                    _this._loader._parent._endPerformanceCounter("Material LOD " + indexLOD);
-                                }
-                                _this._loader._parent._log("Loaded material LOD " + indexLOD);
-                                _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
-                                if (indexLOD !== _this._materialPromiseLODs.length - 1) {
-                                    _this._loader._parent._startPerformanceCounter("Material LOD " + (indexLOD + 1));
-                                    _this._materialSignalLODs[indexLOD].resolve();
-                                }
-                            });
-                            _this._loader._completePromises.push(promise);
-                        };
-                        for (var indexLOD = 0; indexLOD < _this._materialPromiseLODs.length; indexLOD++) {
-                            _loop_2(indexLOD);
-                        }
-                    });
                     return _this;
                     return _this;
                 }
                 }
                 MSFT_lod.prototype.dispose = function () {
                 MSFT_lod.prototype.dispose = function () {
@@ -5652,6 +5941,49 @@ var BABYLON;
                     this.onMaterialLODsLoadedObservable.clear();
                     this.onMaterialLODsLoadedObservable.clear();
                     this.onNodeLODsLoadedObservable.clear();
                     this.onNodeLODsLoadedObservable.clear();
                 };
                 };
+                MSFT_lod.prototype._onReady = function () {
+                    var _this = this;
+                    var _loop_1 = function (indexLOD) {
+                        var promise = Promise.all(this_1._nodePromiseLODs[indexLOD]).then(function () {
+                            if (indexLOD !== 0) {
+                                _this._loader._parent._endPerformanceCounter("Node LOD " + indexLOD);
+                            }
+                            _this._loader._parent._log("Loaded node LOD " + indexLOD);
+                            _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
+                            if (indexLOD !== _this._nodePromiseLODs.length - 1) {
+                                _this._loader._parent._startPerformanceCounter("Node LOD " + (indexLOD + 1));
+                                if (_this._nodeSignalLODs[indexLOD]) {
+                                    _this._nodeSignalLODs[indexLOD].resolve();
+                                }
+                            }
+                        });
+                        this_1._loader._completePromises.push(promise);
+                    };
+                    var this_1 = this;
+                    for (var indexLOD = 0; indexLOD < this._nodePromiseLODs.length; indexLOD++) {
+                        _loop_1(indexLOD);
+                    }
+                    var _loop_2 = function (indexLOD) {
+                        var promise = Promise.all(this_2._materialPromiseLODs[indexLOD]).then(function () {
+                            if (indexLOD !== 0) {
+                                _this._loader._parent._endPerformanceCounter("Material LOD " + indexLOD);
+                            }
+                            _this._loader._parent._log("Loaded material LOD " + indexLOD);
+                            _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
+                            if (indexLOD !== _this._materialPromiseLODs.length - 1) {
+                                _this._loader._parent._startPerformanceCounter("Material LOD " + (indexLOD + 1));
+                                if (_this._materialSignalLODs[indexLOD]) {
+                                    _this._materialSignalLODs[indexLOD].resolve();
+                                }
+                            }
+                        });
+                        this_2._loader._completePromises.push(promise);
+                    };
+                    var this_2 = this;
+                    for (var indexLOD = 0; indexLOD < this._materialPromiseLODs.length; indexLOD++) {
+                        _loop_2(indexLOD);
+                    }
+                };
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
@@ -5858,23 +6190,25 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
-                MSFT_sRGBFactors.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
+                MSFT_sRGBFactors.prototype._loadMaterialPropertiesAsync = function (context, material, babylonMaterial) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtrasValueAsync(context, material, function (extensionContext, value) {
                     return this._loadExtrasValueAsync(context, material, function (extensionContext, value) {
                         if (value) {
                         if (value) {
-                            return _this._loader._loadMaterialAsync(context, material, mesh, babylonMesh, babylonDrawMode, function (babylonMaterial) {
-                                if (!babylonMaterial.albedoTexture) {
-                                    babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor);
-                                }
-                                if (!babylonMaterial.reflectivityTexture) {
-                                    babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor);
-                                }
-                                assign(babylonMaterial);
-                            });
+                            var promise = _this._loader._loadMaterialPropertiesAsync(context, material, babylonMaterial);
+                            _this._convertColorsToLinear(babylonMaterial);
+                            return promise;
                         }
                         }
                         return null;
                         return null;
                     });
                     });
                 };
                 };
+                MSFT_sRGBFactors.prototype._convertColorsToLinear = function (babylonMaterial) {
+                    if (!babylonMaterial.albedoTexture) {
+                        babylonMaterial.albedoColor.toLinearSpaceToRef(babylonMaterial.albedoColor);
+                    }
+                    if (!babylonMaterial.reflectivityTexture) {
+                        babylonMaterial.reflectivityColor.toLinearSpaceToRef(babylonMaterial.reflectivityColor);
+                    }
+                };
                 return MSFT_sRGBFactors;
                 return MSFT_sRGBFactors;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
             Extensions.MSFT_sRGBFactors = MSFT_sRGBFactors;
@@ -6101,8 +6435,6 @@ var BABYLON;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
 
 
-//# sourceMappingURL=KHR_materials_unlit.js.map
-
 
 
 
 
 var BABYLON;
 var BABYLON;
@@ -6129,6 +6461,13 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
+                KHR_lights.prototype._onLoading = function () {
+                    var extensions = this._loader._gltf.extensions;
+                    if (extensions && extensions[this.name]) {
+                        var extension = extensions[this.name];
+                        this._lights = extension.lights;
+                    }
+                };
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
@@ -6177,18 +6516,6 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                Object.defineProperty(KHR_lights.prototype, "_lights", {
-                    get: function () {
-                        var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: '" + this.name + "' not found");
-                        }
-                        var extension = extensions[this.name];
-                        return extension.lights;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
                 return KHR_lights;
                 return KHR_lights;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.KHR_lights = KHR_lights;
             Extensions.KHR_lights = KHR_lights;
@@ -6268,6 +6595,13 @@ var BABYLON;
                     _this.name = NAME;
                     _this.name = NAME;
                     return _this;
                     return _this;
                 }
                 }
+                EXT_lights_imageBased.prototype._onLoading = function () {
+                    var extensions = this._loader._gltf.extensions;
+                    if (extensions && extensions[this.name]) {
+                        var extension = extensions[this.name];
+                        this._lights = extension.lights;
+                    }
+                };
                 EXT_lights_imageBased.prototype._loadSceneAsync = function (context, scene) {
                 EXT_lights_imageBased.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
                     return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
@@ -6337,18 +6671,6 @@ var BABYLON;
                         return light._babylonTexture;
                         return light._babylonTexture;
                     });
                     });
                 };
                 };
-                Object.defineProperty(EXT_lights_imageBased.prototype, "_lights", {
-                    get: function () {
-                        var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this.name]) {
-                            throw new Error("#/extensions: '" + this.name + "' not found");
-                        }
-                        var extension = extensions[this.name];
-                        return extension.lights;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
                 return EXT_lights_imageBased;
                 return EXT_lights_imageBased;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
             Extensions.EXT_lights_imageBased = EXT_lights_imageBased;
             Extensions.EXT_lights_imageBased = EXT_lights_imageBased;

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


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

@@ -70,6 +70,7 @@ declare module BABYLON {
         facePattern2: RegExp;
         facePattern2: RegExp;
         facePattern3: RegExp;
         facePattern3: RegExp;
         facePattern4: RegExp;
         facePattern4: RegExp;
+        facePattern5: RegExp;
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * 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.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.
@@ -299,9 +300,20 @@ declare module BABYLON {
         private _onCompleteObserver;
         private _onCompleteObserver;
         /**
         /**
          * Callback raised when the asset is completely loaded, immediately before the loader is disposed.
          * 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.
          */
          */
         onComplete: () => void;
         onComplete: () => void;
         /**
         /**
+         * Observable raised when an error occurs.
+         */
+        readonly onErrorObservable: Observable<any>;
+        private _onErrorObserver;
+        /**
+         * Callback raised when an error occurs.
+         */
+        onError: (reason: any) => void;
+        /**
          * Observable raised after the loader is disposed.
          * Observable raised after the loader is disposed.
          */
          */
         readonly onDisposeObservable: Observable<void>;
         readonly onDisposeObservable: Observable<void>;
@@ -1119,7 +1131,6 @@ declare module BABYLON.GLTF2 {
         _parent: GLTFFileLoader;
         _parent: GLTFFileLoader;
         _gltf: _ILoaderGLTF;
         _gltf: _ILoaderGLTF;
         _babylonScene: Scene;
         _babylonScene: Scene;
-        _readyPromise: Promise<void>;
         _completePromises: Promise<void>[];
         _completePromises: Promise<void>[];
         private _disposed;
         private _disposed;
         private _state;
         private _state;
@@ -1133,9 +1144,6 @@ declare module BABYLON.GLTF2 {
         private static _ExtensionNames;
         private static _ExtensionNames;
         private static _ExtensionFactories;
         private static _ExtensionFactories;
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
         static _Register(name: string, factory: (loader: GLTFLoader) => GLTFLoaderExtension): void;
-        /**
-         * Loader state or null if the loader is not active.
-         */
         readonly state: Nullable<GLTFLoaderState>;
         readonly state: Nullable<GLTFLoaderState>;
         constructor(parent: GLTFFileLoader);
         constructor(parent: GLTFFileLoader);
         dispose(): void;
         dispose(): void;
@@ -1151,6 +1159,7 @@ declare module BABYLON.GLTF2 {
         private _setupData();
         private _setupData();
         private _loadExtensions();
         private _loadExtensions();
         private _checkExtensions();
         private _checkExtensions();
+        private _setState(state);
         private _createRootNode();
         private _createRootNode();
         _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void>;
         _loadSceneAsync(context: string, scene: _ILoaderScene): Promise<void>;
         private _forEachPrimitive(node, callback);
         private _forEachPrimitive(node, callback);
@@ -1174,7 +1183,7 @@ declare module BABYLON.GLTF2 {
         private _getNodeMatrix(node);
         private _getNodeMatrix(node);
         private _loadCamera(context, camera, babylonMesh);
         private _loadCamera(context, camera, babylonMesh);
         private _loadAnimationsAsync();
         private _loadAnimationsAsync();
-        private _loadAnimationAsync(context, animation);
+        _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Promise<void>;
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationChannelAsync(context, animationContext, animation, channel, babylonAnimationGroup);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadAnimationSamplerAsync(context, sampler);
         private _loadBufferAsync(context, buffer);
         private _loadBufferAsync(context, buffer);
@@ -1206,6 +1215,7 @@ declare module BABYLON.GLTF2 {
         private _compileMaterialsAsync();
         private _compileMaterialsAsync();
         private _compileShadowGeneratorsAsync();
         private _compileShadowGeneratorsAsync();
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
         _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>>;
+        _forEachExtensions(action: (extension: GLTFLoaderExtension) => void): void;
     }
     }
 }
 }
 
 
@@ -1234,6 +1244,14 @@ declare module BABYLON.GLTF2 {
          */
          */
         dispose(): void;
         dispose(): void;
         /**
         /**
+         * Override this method to do work after the state changes to LOADING.
+         */
+        protected _onLoading(): void;
+        /**
+         * Override this method to do work after the state changes to READY.
+         */
+        protected _onReady(): void;
+        /**
          * Override this method to modify the default behavior for loading scenes.
          * Override this method to modify the default behavior for loading scenes.
          * @hidden
          * @hidden
          */
          */
@@ -1273,6 +1291,8 @@ declare module BABYLON.GLTF2 {
          * @hidden
          * @hidden
          */
          */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+        /** Override this method to modify the default behavior for loading animations. */
+        protected _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
         /**
         /**
          * Helper method called by a loader extension to load an glTF extension.
          * Helper method called by a loader extension to load an glTF extension.
          * @hidden
          * @hidden
@@ -1284,6 +1304,16 @@ declare module BABYLON.GLTF2 {
          */
          */
         protected _loadExtrasValueAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, value: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
         protected _loadExtrasValueAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, value: TProperty) => Nullable<Promise<TResult>>): Nullable<Promise<TResult>>;
         /**
         /**
+         * Helper method called by the loader after the state changes to LOADING.
+         * @hidden
+         */
+        static _OnLoading(loader: GLTFLoader): void;
+        /**
+         * Helper method called by the loader after the state changes to READY.
+         * @hidden
+         */
+        static _OnReady(loader: GLTFLoader): void;
+        /**
          * Helper method called by the loader to allow extensions to override loading scenes.
          * Helper method called by the loader to allow extensions to override loading scenes.
          * @hidden
          * @hidden
          */
          */
@@ -1323,6 +1353,11 @@ declare module BABYLON.GLTF2 {
          * @hidden
          * @hidden
          */
          */
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
+        /**
+         * Helper method called by the loader to allow extensions to override loading animations.
+         * @hidden
+         */
+        static _LoadAnimationAsync(loader: GLTFLoader, context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
     }
     }
 }
 }
 /**
 /**
@@ -1334,6 +1369,26 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
     /**
     /**
+     * [Specification](https://github.com/najadojo/glTF/tree/MSFT_audio_emitter/extensions/2.0/Vendor/MSFT_audio_emitter)
+     */
+    class MSFT_audio_emitter extends GLTFLoaderExtension {
+        readonly name: string;
+        private _loadClipAsync(context, clip);
+        private _loadEmitterAsync(context, emitter);
+        protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
+        protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
+        protected _loadAnimationAsync(context: string, animation: _ILoaderAnimation): Nullable<Promise<void>>;
+        private _getEventAction(context, sound, action, time, startOffset?);
+        private _loadAnimationEventAsync(context, animationContext, animation, event, babylonAnimationGroup);
+        private readonly _extension;
+        private readonly _clips;
+        private readonly _emitters;
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
      * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_lod)
      */
      */
     class MSFT_lod extends GLTFLoaderExtension {
     class MSFT_lod extends GLTFLoaderExtension {
@@ -1360,8 +1415,8 @@ declare module BABYLON.GLTF2.Extensions {
         private _materialIndexLOD;
         private _materialIndexLOD;
         private _materialSignalLODs;
         private _materialSignalLODs;
         private _materialPromiseLODs;
         private _materialPromiseLODs;
-        constructor(loader: GLTFLoader);
         dispose(): void;
         dispose(): void;
+        protected _onReady(): void;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
@@ -1387,7 +1442,8 @@ declare module BABYLON.GLTF2.Extensions {
     /** @hidden */
     /** @hidden */
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
     class MSFT_sRGBFactors extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
-        protected _loadMaterialAsync(context: string, material: _ILoaderMaterial, mesh: _ILoaderMesh, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        protected _loadMaterialPropertiesAsync(context: string, material: _ILoaderMaterial, babylonMaterial: Material): Nullable<Promise<void>>;
+        private _convertColorsToLinear(babylonMaterial);
     }
     }
 }
 }
 
 
@@ -1436,9 +1492,10 @@ declare module BABYLON.GLTF2.Extensions {
      */
      */
     class KHR_lights extends GLTFLoaderExtension {
     class KHR_lights extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
+        private _lights?;
+        protected _onLoading(): void;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: _ILoaderNode): Nullable<Promise<void>>;
-        private readonly _lights;
     }
     }
 }
 }
 
 
@@ -1460,8 +1517,9 @@ declare module BABYLON.GLTF2.Extensions {
      */
      */
     class EXT_lights_imageBased extends GLTFLoaderExtension {
     class EXT_lights_imageBased extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
+        private _lights?;
+        protected _onLoading(): void;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: _ILoaderScene): Nullable<Promise<void>>;
         private _loadLightAsync(context, light);
         private _loadLightAsync(context, light);
-        private readonly _lights;
     }
     }
 }
 }

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

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

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

@@ -4,6 +4,7 @@ declare module BABYLON {
         private _renderId;
         private _renderId;
         private _activeLight;
         private _activeLight;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
+        shadowColor: Color3;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): Nullable<BaseTexture>;
         getAlphaTestTexture(): Nullable<BaseTexture>;

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


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


+ 1 - 0
dist/preview release/materialsLibrary/babylonjs.materials.d.ts

@@ -4,6 +4,7 @@ declare module BABYLON {
         private _renderId;
         private _renderId;
         private _activeLight;
         private _activeLight;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
+        shadowColor: Color3;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): Nullable<BaseTexture>;
         getAlphaTestTexture(): Nullable<BaseTexture>;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 6 - 3
dist/preview release/materialsLibrary/babylonjs.materials.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 2
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts

@@ -9,6 +9,7 @@ declare module BABYLON {
         private _renderId;
         private _renderId;
         private _activeLight;
         private _activeLight;
         constructor(name: string, scene: Scene);
         constructor(name: string, scene: Scene);
+        shadowColor: Color3;
         needAlphaBlending(): boolean;
         needAlphaBlending(): boolean;
         needAlphaTesting(): boolean;
         needAlphaTesting(): boolean;
         getAlphaTestTexture(): Nullable<BaseTexture>;
         getAlphaTestTexture(): Nullable<BaseTexture>;

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

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

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

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

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

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

+ 7 - 0
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -521,6 +521,13 @@ declare module BABYLON.GLTF2 {
          */
          */
         private _resizeTexturesToSameDimensions(texture1, texture2, scene);
         private _resizeTexturesToSameDimensions(texture1, texture2, scene);
         /**
         /**
+         * Converts an array of pixels to a Float32Array
+         * Throws an error if the pixel format is not supported
+         * @param pixels - array buffer containing pixel values
+         * @returns Float32 of pixels
+         */
+        private _convertPixelArrayToFloat32(pixels);
+        /**
          * Convert Specular Glossiness Textures to Metallic Roughness
          * Convert Specular Glossiness Textures to Metallic Roughness
          * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
          * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
          * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
          * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js

+ 113 - 91
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -1821,6 +1821,28 @@ var BABYLON;
                 };
                 };
             };
             };
             /**
             /**
+             * Converts an array of pixels to a Float32Array
+             * Throws an error if the pixel format is not supported
+             * @param pixels - array buffer containing pixel values
+             * @returns Float32 of pixels
+             */
+            _GLTFMaterialExporter.prototype._convertPixelArrayToFloat32 = function (pixels) {
+                if (pixels instanceof Uint8Array) {
+                    var length_1 = pixels.length;
+                    var buffer = new Float32Array(pixels.length);
+                    for (var i = 0; i < length_1; ++i) {
+                        buffer[i] = pixels[i] / 255;
+                    }
+                    return buffer;
+                }
+                else if (pixels instanceof Float32Array) {
+                    return pixels;
+                }
+                else {
+                    throw new Error('Unsupported pixel format!');
+                }
+            };
+            /**
              * Convert Specular Glossiness Textures to Metallic Roughness
              * Convert Specular Glossiness Textures to Metallic Roughness
              * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
              * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
              * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
              * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
@@ -1843,99 +1865,99 @@ var BABYLON;
                     var specularGlossinessBuffer = void 0;
                     var specularGlossinessBuffer = void 0;
                     var width = diffuseSize.width;
                     var width = diffuseSize.width;
                     var height = diffuseSize.height;
                     var height = diffuseSize.height;
-                    var pixels = (resizedTextures.texture1.readPixels());
-                    if (pixels instanceof Uint8Array) {
-                        diffuseBuffer = (resizedTextures.texture1.readPixels());
-                        pixels = resizedTextures.texture2.readPixels();
-                        if (pixels instanceof Uint8Array) {
-                            specularGlossinessBuffer = (resizedTextures.texture2.readPixels());
-                            var byteLength = specularGlossinessBuffer.byteLength;
-                            var metallicRoughnessBuffer = new Uint8Array(byteLength);
-                            var baseColorBuffer = new Uint8Array(byteLength);
-                            var strideSize = 4;
-                            var maxBaseColor = BABYLON.Color3.Black();
-                            var maxMetallic = 0;
-                            var maxRoughness = 0;
-                            for (var h = 0; h < height; ++h) {
-                                for (var w = 0; w < width; ++w) {
-                                    var offset = (width * h + w) * strideSize;
-                                    var diffuseColor = BABYLON.Color3.FromInts(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2]).toLinearSpace().multiply(factors.diffuseColor);
-                                    var specularColor = BABYLON.Color3.FromInts(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2]).toLinearSpace().multiply(factors.specularColor);
-                                    var glossiness = (specularGlossinessBuffer[offset + 3] / 255) * factors.glossiness;
-                                    var specularGlossiness = {
-                                        diffuseColor: diffuseColor,
-                                        specularColor: specularColor,
-                                        glossiness: glossiness
-                                    };
-                                    var metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness);
-                                    maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);
-                                    maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);
-                                    maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);
-                                    maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic);
-                                    maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness);
-                                    baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;
-                                    baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;
-                                    baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;
-                                    baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] : 255;
-                                    metallicRoughnessBuffer[offset] = 0;
-                                    metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness * 255;
-                                    metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic * 255;
-                                    metallicRoughnessBuffer[offset + 3] = 255;
-                                }
-                            }
-                            // Retrieves the metallic roughness factors from the maximum texture values.
-                            var metallicRoughnessFactors_1 = {
-                                baseColor: maxBaseColor,
-                                metallic: maxMetallic,
-                                roughness: maxRoughness
-                            };
-                            var writeOutMetallicRoughnessTexture = false;
-                            var writeOutBaseColorTexture = false;
-                            for (var h = 0; h < height; ++h) {
-                                for (var w = 0; w < width; ++w) {
-                                    var destinationOffset = (width * h + w) * strideSize;
-                                    baseColorBuffer[destinationOffset] /= metallicRoughnessFactors_1.baseColor.r > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.r : 1;
-                                    baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.baseColor.g > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.g : 1;
-                                    baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.baseColor.b > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.b : 1;
-                                    var linearBaseColorPixel = BABYLON.Color3.FromInts(baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]);
-                                    var sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace();
-                                    baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;
-                                    baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;
-                                    baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;
-                                    if (!_GLTFMaterialExporter.FuzzyEquals(sRGBBaseColorPixel, BABYLON.Color3.White(), _GLTFMaterialExporter._Epsilon)) {
-                                        writeOutBaseColorTexture = true;
-                                    }
-                                    metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.roughness > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.roughness : 1;
-                                    metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.metallic > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.metallic : 1;
-                                    var metallicRoughnessPixel = BABYLON.Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);
-                                    if (!_GLTFMaterialExporter.FuzzyEquals(metallicRoughnessPixel, BABYLON.Color3.White(), _GLTFMaterialExporter._Epsilon)) {
-                                        writeOutMetallicRoughnessTexture = true;
-                                    }
-                                }
-                            }
-                            if (writeOutMetallicRoughnessTexture) {
-                                var promise = this._createBase64FromCanvasAsync(metallicRoughnessBuffer, width, height, mimeType).then(function (metallicRoughnessBase64) {
-                                    metallicRoughnessFactors_1.metallicRoughnessTextureBase64 = metallicRoughnessBase64;
-                                });
-                                promises.push(promise);
-                            }
-                            if (writeOutBaseColorTexture) {
-                                var promise = this._createBase64FromCanvasAsync(baseColorBuffer, width, height, mimeType).then(function (baseColorBase64) {
-                                    metallicRoughnessFactors_1.baseColorTextureBase64 = baseColorBase64;
-                                });
-                                promises.push(promise);
-                            }
-                            return Promise.all(promises).then(function () {
-                                return metallicRoughnessFactors_1;
-                            });
-                        }
-                        else {
-                            return Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture2.name);
-                        }
+                    var diffusePixels = resizedTextures.texture1.readPixels();
+                    var specularPixels = resizedTextures.texture2.readPixels();
+                    if (diffusePixels) {
+                        diffuseBuffer = this._convertPixelArrayToFloat32(diffusePixels);
                     }
                     }
                     else {
                     else {
-                        return Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture1.name);
+                        return Promise.reject("Failed to retrieve pixels from diffuse texture!");
                     }
                     }
+                    if (specularPixels) {
+                        specularGlossinessBuffer = this._convertPixelArrayToFloat32(specularPixels);
+                    }
+                    else {
+                        return Promise.reject("Failed to retrieve pixels from specular glossiness texture!");
+                    }
+                    var byteLength = specularGlossinessBuffer.byteLength;
+                    var metallicRoughnessBuffer = new Uint8Array(byteLength);
+                    var baseColorBuffer = new Uint8Array(byteLength);
+                    var strideSize = 4;
+                    var maxBaseColor = BABYLON.Color3.Black();
+                    var maxMetallic = 0;
+                    var maxRoughness = 0;
+                    for (var h = 0; h < height; ++h) {
+                        for (var w = 0; w < width; ++w) {
+                            var offset = (width * h + w) * strideSize;
+                            var diffuseColor = new BABYLON.Color3(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2]).toLinearSpace().multiply(factors.diffuseColor);
+                            var specularColor = new BABYLON.Color3(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2]).toLinearSpace().multiply(factors.specularColor);
+                            var glossiness = (specularGlossinessBuffer[offset + 3]) * factors.glossiness;
+                            var specularGlossiness = {
+                                diffuseColor: diffuseColor,
+                                specularColor: specularColor,
+                                glossiness: glossiness
+                            };
+                            var metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness);
+                            maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);
+                            maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);
+                            maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);
+                            maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic);
+                            maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness);
+                            baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;
+                            baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;
+                            baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;
+                            baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] * 255 : 255;
+                            metallicRoughnessBuffer[offset] = 0;
+                            metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness * 255;
+                            metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic * 255;
+                            metallicRoughnessBuffer[offset + 3] = 255;
+                        }
+                    }
+                    // Retrieves the metallic roughness factors from the maximum texture values.
+                    var metallicRoughnessFactors_1 = {
+                        baseColor: maxBaseColor,
+                        metallic: maxMetallic,
+                        roughness: maxRoughness
+                    };
+                    var writeOutMetallicRoughnessTexture = false;
+                    var writeOutBaseColorTexture = false;
+                    for (var h = 0; h < height; ++h) {
+                        for (var w = 0; w < width; ++w) {
+                            var destinationOffset = (width * h + w) * strideSize;
+                            baseColorBuffer[destinationOffset] /= metallicRoughnessFactors_1.baseColor.r > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.r : 1;
+                            baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.baseColor.g > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.g : 1;
+                            baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.baseColor.b > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.b : 1;
+                            var linearBaseColorPixel = BABYLON.Color3.FromInts(baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]);
+                            var sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace();
+                            baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;
+                            baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;
+                            baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;
+                            if (!_GLTFMaterialExporter.FuzzyEquals(sRGBBaseColorPixel, BABYLON.Color3.White(), _GLTFMaterialExporter._Epsilon)) {
+                                writeOutBaseColorTexture = true;
+                            }
+                            metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.roughness > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.roughness : 1;
+                            metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.metallic > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.metallic : 1;
+                            var metallicRoughnessPixel = BABYLON.Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);
+                            if (!_GLTFMaterialExporter.FuzzyEquals(metallicRoughnessPixel, BABYLON.Color3.White(), _GLTFMaterialExporter._Epsilon)) {
+                                writeOutMetallicRoughnessTexture = true;
+                            }
+                        }
+                    }
+                    if (writeOutMetallicRoughnessTexture) {
+                        var promise = this._createBase64FromCanvasAsync(metallicRoughnessBuffer, width, height, mimeType).then(function (metallicRoughnessBase64) {
+                            metallicRoughnessFactors_1.metallicRoughnessTextureBase64 = metallicRoughnessBase64;
+                        });
+                        promises.push(promise);
+                    }
+                    if (writeOutBaseColorTexture) {
+                        var promise = this._createBase64FromCanvasAsync(baseColorBuffer, width, height, mimeType).then(function (baseColorBase64) {
+                            metallicRoughnessFactors_1.baseColorTextureBase64 = baseColorBase64;
+                        });
+                        promises.push(promise);
+                    }
+                    return Promise.all(promises).then(function () {
+                        return metallicRoughnessFactors_1;
+                    });
                 }
                 }
                 else {
                 else {
                     return Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!");
                     return Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!");
@@ -2363,7 +2385,7 @@ var BABYLON;
                 var binStr = atob(base64Texture.split(',')[1]);
                 var binStr = atob(base64Texture.split(',')[1]);
                 var arrBuff = new ArrayBuffer(binStr.length);
                 var arrBuff = new ArrayBuffer(binStr.length);
                 var arr = new Uint8Array(arrBuff);
                 var arr = new Uint8Array(arrBuff);
-                for (var i = 0, length_1 = binStr.length; i < length_1; ++i) {
+                for (var i = 0, length_2 = binStr.length; i < length_2; ++i) {
                     arr[i] = binStr.charCodeAt(i);
                     arr[i] = binStr.charCodeAt(i);
                 }
                 }
                 var imageValues = { data: arr, mimeType: mimeType };
                 var imageValues = { data: arr, mimeType: mimeType };

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


+ 7 - 0
dist/preview release/serializers/babylonjs.serializers.d.ts

@@ -529,6 +529,13 @@ declare module BABYLON.GLTF2 {
          */
          */
         private _resizeTexturesToSameDimensions(texture1, texture2, scene);
         private _resizeTexturesToSameDimensions(texture1, texture2, scene);
         /**
         /**
+         * Converts an array of pixels to a Float32Array
+         * Throws an error if the pixel format is not supported
+         * @param pixels - array buffer containing pixel values
+         * @returns Float32 of pixels
+         */
+        private _convertPixelArrayToFloat32(pixels);
+        /**
          * Convert Specular Glossiness Textures to Metallic Roughness
          * Convert Specular Glossiness Textures to Metallic Roughness
          * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
          * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
          * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
          * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js

+ 113 - 91
dist/preview release/serializers/babylonjs.serializers.js

@@ -1982,6 +1982,28 @@ var BABYLON;
                 };
                 };
             };
             };
             /**
             /**
+             * Converts an array of pixels to a Float32Array
+             * Throws an error if the pixel format is not supported
+             * @param pixels - array buffer containing pixel values
+             * @returns Float32 of pixels
+             */
+            _GLTFMaterialExporter.prototype._convertPixelArrayToFloat32 = function (pixels) {
+                if (pixels instanceof Uint8Array) {
+                    var length_1 = pixels.length;
+                    var buffer = new Float32Array(pixels.length);
+                    for (var i = 0; i < length_1; ++i) {
+                        buffer[i] = pixels[i] / 255;
+                    }
+                    return buffer;
+                }
+                else if (pixels instanceof Float32Array) {
+                    return pixels;
+                }
+                else {
+                    throw new Error('Unsupported pixel format!');
+                }
+            };
+            /**
              * Convert Specular Glossiness Textures to Metallic Roughness
              * Convert Specular Glossiness Textures to Metallic Roughness
              * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
              * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
              * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
              * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
@@ -2004,99 +2026,99 @@ var BABYLON;
                     var specularGlossinessBuffer = void 0;
                     var specularGlossinessBuffer = void 0;
                     var width = diffuseSize.width;
                     var width = diffuseSize.width;
                     var height = diffuseSize.height;
                     var height = diffuseSize.height;
-                    var pixels = (resizedTextures.texture1.readPixels());
-                    if (pixels instanceof Uint8Array) {
-                        diffuseBuffer = (resizedTextures.texture1.readPixels());
-                        pixels = resizedTextures.texture2.readPixels();
-                        if (pixels instanceof Uint8Array) {
-                            specularGlossinessBuffer = (resizedTextures.texture2.readPixels());
-                            var byteLength = specularGlossinessBuffer.byteLength;
-                            var metallicRoughnessBuffer = new Uint8Array(byteLength);
-                            var baseColorBuffer = new Uint8Array(byteLength);
-                            var strideSize = 4;
-                            var maxBaseColor = BABYLON.Color3.Black();
-                            var maxMetallic = 0;
-                            var maxRoughness = 0;
-                            for (var h = 0; h < height; ++h) {
-                                for (var w = 0; w < width; ++w) {
-                                    var offset = (width * h + w) * strideSize;
-                                    var diffuseColor = BABYLON.Color3.FromInts(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2]).toLinearSpace().multiply(factors.diffuseColor);
-                                    var specularColor = BABYLON.Color3.FromInts(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2]).toLinearSpace().multiply(factors.specularColor);
-                                    var glossiness = (specularGlossinessBuffer[offset + 3] / 255) * factors.glossiness;
-                                    var specularGlossiness = {
-                                        diffuseColor: diffuseColor,
-                                        specularColor: specularColor,
-                                        glossiness: glossiness
-                                    };
-                                    var metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness);
-                                    maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);
-                                    maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);
-                                    maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);
-                                    maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic);
-                                    maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness);
-                                    baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;
-                                    baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;
-                                    baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;
-                                    baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] : 255;
-                                    metallicRoughnessBuffer[offset] = 0;
-                                    metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness * 255;
-                                    metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic * 255;
-                                    metallicRoughnessBuffer[offset + 3] = 255;
-                                }
-                            }
-                            // Retrieves the metallic roughness factors from the maximum texture values.
-                            var metallicRoughnessFactors_1 = {
-                                baseColor: maxBaseColor,
-                                metallic: maxMetallic,
-                                roughness: maxRoughness
-                            };
-                            var writeOutMetallicRoughnessTexture = false;
-                            var writeOutBaseColorTexture = false;
-                            for (var h = 0; h < height; ++h) {
-                                for (var w = 0; w < width; ++w) {
-                                    var destinationOffset = (width * h + w) * strideSize;
-                                    baseColorBuffer[destinationOffset] /= metallicRoughnessFactors_1.baseColor.r > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.r : 1;
-                                    baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.baseColor.g > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.g : 1;
-                                    baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.baseColor.b > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.b : 1;
-                                    var linearBaseColorPixel = BABYLON.Color3.FromInts(baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]);
-                                    var sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace();
-                                    baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;
-                                    baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;
-                                    baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;
-                                    if (!_GLTFMaterialExporter.FuzzyEquals(sRGBBaseColorPixel, BABYLON.Color3.White(), _GLTFMaterialExporter._Epsilon)) {
-                                        writeOutBaseColorTexture = true;
-                                    }
-                                    metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.roughness > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.roughness : 1;
-                                    metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.metallic > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.metallic : 1;
-                                    var metallicRoughnessPixel = BABYLON.Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);
-                                    if (!_GLTFMaterialExporter.FuzzyEquals(metallicRoughnessPixel, BABYLON.Color3.White(), _GLTFMaterialExporter._Epsilon)) {
-                                        writeOutMetallicRoughnessTexture = true;
-                                    }
-                                }
-                            }
-                            if (writeOutMetallicRoughnessTexture) {
-                                var promise = this._createBase64FromCanvasAsync(metallicRoughnessBuffer, width, height, mimeType).then(function (metallicRoughnessBase64) {
-                                    metallicRoughnessFactors_1.metallicRoughnessTextureBase64 = metallicRoughnessBase64;
-                                });
-                                promises.push(promise);
-                            }
-                            if (writeOutBaseColorTexture) {
-                                var promise = this._createBase64FromCanvasAsync(baseColorBuffer, width, height, mimeType).then(function (baseColorBase64) {
-                                    metallicRoughnessFactors_1.baseColorTextureBase64 = baseColorBase64;
-                                });
-                                promises.push(promise);
-                            }
-                            return Promise.all(promises).then(function () {
-                                return metallicRoughnessFactors_1;
-                            });
-                        }
-                        else {
-                            return Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture2.name);
-                        }
+                    var diffusePixels = resizedTextures.texture1.readPixels();
+                    var specularPixels = resizedTextures.texture2.readPixels();
+                    if (diffusePixels) {
+                        diffuseBuffer = this._convertPixelArrayToFloat32(diffusePixels);
                     }
                     }
                     else {
                     else {
-                        return Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture1.name);
+                        return Promise.reject("Failed to retrieve pixels from diffuse texture!");
                     }
                     }
+                    if (specularPixels) {
+                        specularGlossinessBuffer = this._convertPixelArrayToFloat32(specularPixels);
+                    }
+                    else {
+                        return Promise.reject("Failed to retrieve pixels from specular glossiness texture!");
+                    }
+                    var byteLength = specularGlossinessBuffer.byteLength;
+                    var metallicRoughnessBuffer = new Uint8Array(byteLength);
+                    var baseColorBuffer = new Uint8Array(byteLength);
+                    var strideSize = 4;
+                    var maxBaseColor = BABYLON.Color3.Black();
+                    var maxMetallic = 0;
+                    var maxRoughness = 0;
+                    for (var h = 0; h < height; ++h) {
+                        for (var w = 0; w < width; ++w) {
+                            var offset = (width * h + w) * strideSize;
+                            var diffuseColor = new BABYLON.Color3(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2]).toLinearSpace().multiply(factors.diffuseColor);
+                            var specularColor = new BABYLON.Color3(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2]).toLinearSpace().multiply(factors.specularColor);
+                            var glossiness = (specularGlossinessBuffer[offset + 3]) * factors.glossiness;
+                            var specularGlossiness = {
+                                diffuseColor: diffuseColor,
+                                specularColor: specularColor,
+                                glossiness: glossiness
+                            };
+                            var metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness);
+                            maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);
+                            maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);
+                            maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);
+                            maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic);
+                            maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness);
+                            baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;
+                            baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;
+                            baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;
+                            baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] * 255 : 255;
+                            metallicRoughnessBuffer[offset] = 0;
+                            metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness * 255;
+                            metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic * 255;
+                            metallicRoughnessBuffer[offset + 3] = 255;
+                        }
+                    }
+                    // Retrieves the metallic roughness factors from the maximum texture values.
+                    var metallicRoughnessFactors_1 = {
+                        baseColor: maxBaseColor,
+                        metallic: maxMetallic,
+                        roughness: maxRoughness
+                    };
+                    var writeOutMetallicRoughnessTexture = false;
+                    var writeOutBaseColorTexture = false;
+                    for (var h = 0; h < height; ++h) {
+                        for (var w = 0; w < width; ++w) {
+                            var destinationOffset = (width * h + w) * strideSize;
+                            baseColorBuffer[destinationOffset] /= metallicRoughnessFactors_1.baseColor.r > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.r : 1;
+                            baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.baseColor.g > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.g : 1;
+                            baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.baseColor.b > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.baseColor.b : 1;
+                            var linearBaseColorPixel = BABYLON.Color3.FromInts(baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]);
+                            var sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace();
+                            baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;
+                            baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;
+                            baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;
+                            if (!_GLTFMaterialExporter.FuzzyEquals(sRGBBaseColorPixel, BABYLON.Color3.White(), _GLTFMaterialExporter._Epsilon)) {
+                                writeOutBaseColorTexture = true;
+                            }
+                            metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors_1.roughness > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.roughness : 1;
+                            metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors_1.metallic > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors_1.metallic : 1;
+                            var metallicRoughnessPixel = BABYLON.Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);
+                            if (!_GLTFMaterialExporter.FuzzyEquals(metallicRoughnessPixel, BABYLON.Color3.White(), _GLTFMaterialExporter._Epsilon)) {
+                                writeOutMetallicRoughnessTexture = true;
+                            }
+                        }
+                    }
+                    if (writeOutMetallicRoughnessTexture) {
+                        var promise = this._createBase64FromCanvasAsync(metallicRoughnessBuffer, width, height, mimeType).then(function (metallicRoughnessBase64) {
+                            metallicRoughnessFactors_1.metallicRoughnessTextureBase64 = metallicRoughnessBase64;
+                        });
+                        promises.push(promise);
+                    }
+                    if (writeOutBaseColorTexture) {
+                        var promise = this._createBase64FromCanvasAsync(baseColorBuffer, width, height, mimeType).then(function (baseColorBase64) {
+                            metallicRoughnessFactors_1.baseColorTextureBase64 = baseColorBase64;
+                        });
+                        promises.push(promise);
+                    }
+                    return Promise.all(promises).then(function () {
+                        return metallicRoughnessFactors_1;
+                    });
                 }
                 }
                 else {
                 else {
                     return Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!");
                     return Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!");
@@ -2524,7 +2546,7 @@ var BABYLON;
                 var binStr = atob(base64Texture.split(',')[1]);
                 var binStr = atob(base64Texture.split(',')[1]);
                 var arrBuff = new ArrayBuffer(binStr.length);
                 var arrBuff = new ArrayBuffer(binStr.length);
                 var arr = new Uint8Array(arrBuff);
                 var arr = new Uint8Array(arrBuff);
-                for (var i = 0, length_1 = binStr.length; i < length_1; ++i) {
+                for (var i = 0, length_2 = binStr.length; i < length_2; ++i) {
                     arr[i] = binStr.charCodeAt(i);
                     arr[i] = binStr.charCodeAt(i);
                 }
                 }
                 var imageValues = { data: arr, mimeType: mimeType };
                 var imageValues = { data: arr, mimeType: mimeType };

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


+ 7 - 0
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -536,6 +536,13 @@ declare module BABYLON.GLTF2 {
          */
          */
         private _resizeTexturesToSameDimensions(texture1, texture2, scene);
         private _resizeTexturesToSameDimensions(texture1, texture2, scene);
         /**
         /**
+         * Converts an array of pixels to a Float32Array
+         * Throws an error if the pixel format is not supported
+         * @param pixels - array buffer containing pixel values
+         * @returns Float32 of pixels
+         */
+        private _convertPixelArrayToFloat32(pixels);
+        /**
          * Convert Specular Glossiness Textures to Metallic Roughness
          * Convert Specular Glossiness Textures to Metallic Roughness
          * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
          * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
          * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
          * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js

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

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

+ 2 - 99
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
 {
-  "errors": 4239,
+  "errors": 4222,
   "babylon.typedoc.json": {
   "babylon.typedoc.json": {
-    "errors": 4239,
+    "errors": 4222,
     "AbstractMesh": {
     "AbstractMesh": {
       "Property": {
       "Property": {
         "showBoundingBox": {
         "showBoundingBox": {
@@ -2930,11 +2930,6 @@
             "MissingText": true
             "MissingText": true
           }
           }
         },
         },
-        "getTranformationMatrix": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
         "getViewMatrix": {
         "getViewMatrix": {
           "Comments": {
           "Comments": {
             "MissingText": true
             "MissingText": true
@@ -14147,98 +14142,6 @@
         }
         }
       }
       }
     },
     },
-    "ReflectionProbe": {
-      "Class": {
-        "Comments": {
-          "MissingText": true
-        }
-      },
-      "Constructor": {
-        "new ReflectionProbe": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "name": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "size": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "generateMipMaps": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        }
-      },
-      "Property": {
-        "cubeTexture": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "name": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "position": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "refreshRate": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "renderList": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "samples": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      },
-      "Method": {
-        "attachToMesh": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "mesh": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "dispose": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "getScene": {
-          "Comments": {
-            "MissingText": true
-          }
-        }
-      }
-    },
     "RefractionPostProcess": {
     "RefractionPostProcess": {
       "Class": {
       "Class": {
         "Comments": {
         "Comments": {

+ 109 - 240
dist/preview release/viewer/babylon.viewer.d.ts

@@ -2,46 +2,24 @@
 /// <reference path="./babylon.glTF2Interface.d.ts"/>
 /// <reference path="./babylon.glTF2Interface.d.ts"/>
 /// <reference path="./babylonjs.loaders.d.ts"/>
 /// <reference path="./babylonjs.loaders.d.ts"/>
 declare module "babylonjs-loaders"{ export=BABYLON;}
 declare module "babylonjs-loaders"{ export=BABYLON;}
-
 // Generated by dts-bundle v0.7.3
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
 // Dependencies for this module:
-//   ../../../../Tools/Gulp/babylonjs
-//   ../../../../Tools/Gulp/babylonjs-loaders
-
+//   ../../../../../Tools/Gulp/babylonjs
+//   ../../../../../Tools/Gulp/babylonjs-loaders
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
     /**
     /**
         * BabylonJS Viewer
         * BabylonJS Viewer
         *
         *
         * An HTML-Based viewer for 3D models, based on BabylonJS and its extensions.
         * An HTML-Based viewer for 3D models, based on BabylonJS and its extensions.
         */
         */
-    
-    
-    import 'pepjs';
-    
     let disableInit: boolean;
     let disableInit: boolean;
     /**
     /**
         * Dispose all viewers currently registered
         * Dispose all viewers currently registered
         */
         */
     function disposeAll(): void;
     function disposeAll(): void;
     const Version: string;
     const Version: string;
-    
-    export * from 'babylonjs-viewer/configuration';
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     /**
     /**
         * This is the mapper's interface. Implement this function to create your own mapper and register it at the mapper manager
         * This is the mapper's interface. Implement this function to create your own mapper and register it at the mapper manager
         */
         */
@@ -83,7 +61,6 @@ declare module BabylonViewer {
         */
         */
     export let mapperManager: MapperManager;
     export let mapperManager: MapperManager;
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     export class ViewerGlobals {
     export class ViewerGlobals {
         disableInit: boolean;
         disableInit: boolean;
@@ -92,10 +69,7 @@ declare module BabylonViewer {
     }
     }
     export let viewerGlobals: ViewerGlobals;
     export let viewerGlobals: ViewerGlobals;
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
     /**
     /**
         * The viewer manager is the container for all viewers currently registered on this page.
         * The viewer manager is the container for all viewers currently registered on this page.
         * It is possible to have more than one viewer on a single page.
         * It is possible to have more than one viewer on a single page.
@@ -148,13 +122,7 @@ declare module BabylonViewer {
     }
     }
     export let viewerManager: ViewerManager;
     export let viewerManager: ViewerManager;
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
-    
-    
     /**
     /**
         * The Default viewer is the default implementation of the AbstractViewer.
         * The Default viewer is the default implementation of the AbstractViewer.
         * It uses the templating system to render a new canvas and controls.
         * It uses the templating system to render a new canvas and controls.
@@ -173,7 +141,7 @@ declare module BabylonViewer {
                 * This will be executed when the templates initialize.
                 * This will be executed when the templates initialize.
                 */
                 */
             protected _onTemplatesLoaded(): Promise<AbstractViewer>;
             protected _onTemplatesLoaded(): Promise<AbstractViewer>;
-            toggleVR(): void;
+            protected _initVR(): void;
             /**
             /**
                 * Toggle fullscreen of the entire viewer
                 * Toggle fullscreen of the entire viewer
                 */
                 */
@@ -230,17 +198,7 @@ declare module BabylonViewer {
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
-    
-    
-    
-    
-    
-    
     /**
     /**
         * The AbstractViewr is the center of Babylon's viewer.
         * The AbstractViewr is the center of Babylon's viewer.
         * It is the basic implementation of the default viewer and is responsible of loading and showing the model and the templates
         * It is the basic implementation of the default viewer and is responsible of loading and showing the model and the templates
@@ -359,8 +317,8 @@ declare module BabylonViewer {
                 */
                 */
             isCanvasInDOM(): boolean;
             isCanvasInDOM(): boolean;
             /**
             /**
-                * Set the viewer's background rendering flag.
-                */
+             * Set the viewer's background rendering flag.
+             */
             renderInBackground: boolean;
             renderInBackground: boolean;
             /**
             /**
                 * Get the configuration object. This is a reference only.
                 * Get the configuration object. This is a reference only.
@@ -376,7 +334,9 @@ declare module BabylonViewer {
             toggleHD(): void;
             toggleHD(): void;
             protected _vrToggled: boolean;
             protected _vrToggled: boolean;
             protected _vrScale: number;
             protected _vrScale: number;
+            protected _vrInit: boolean;
             toggleVR(): void;
             toggleVR(): void;
+            protected _initVR(): void;
             /**
             /**
                 * The resize function that will be registered with the window object
                 * The resize function that will be registered with the window object
                 */
                 */
@@ -468,9 +428,7 @@ declare module BabylonViewer {
             protected _injectCustomShaders(): void;
             protected _injectCustomShaders(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     /**
     /**
         * The data structure of a telemetry event.
         * The data structure of a telemetry event.
         */
         */
@@ -515,13 +473,7 @@ declare module BabylonViewer {
     }
     }
     export const telemetryManager: TelemetryManager;
     export const telemetryManager: TelemetryManager;
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
-    
-    
     /**
     /**
         * An instance of the class is in charge of loading the model correctly.
         * An instance of the class is in charge of loading the model correctly.
         * This class will continously be expended with tasks required from the specific loaders Babylon has.
         * This class will continously be expended with tasks required from the specific loaders Babylon has.
@@ -554,14 +506,7 @@ declare module BabylonViewer {
             dispose(): void;
             dispose(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
-    
-    
-    
     /**
     /**
         * The current state of the model
         * The current state of the model
         */
         */
@@ -573,7 +518,7 @@ declare module BabylonViewer {
             ENTRYDONE = 4,
             ENTRYDONE = 4,
             COMPLETE = 5,
             COMPLETE = 5,
             CANCELED = 6,
             CANCELED = 6,
-            ERROR = 7,
+            ERROR = 7
     }
     }
     /**
     /**
         * The viewer model is a container for all assets representing a sngle loaded model.
         * The viewer model is a container for all assets representing a sngle loaded model.
@@ -638,8 +583,8 @@ declare module BabylonViewer {
             shadowsRenderedAfterLoad: boolean;
             shadowsRenderedAfterLoad: boolean;
             getViewerId(): string | undefined;
             getViewerId(): string | undefined;
             /**
             /**
-                * Set whether this model is enabled or not.
-                */
+             * Set whether this model is enabled or not.
+             */
             enabled: boolean;
             enabled: boolean;
             loaderDone: boolean;
             loaderDone: boolean;
             /**
             /**
@@ -655,9 +600,9 @@ declare module BabylonViewer {
                 */
                 */
             readonly meshes: BABYLON.AbstractMesh[];
             readonly meshes: BABYLON.AbstractMesh[];
             /**
             /**
-                * (Re-)set the model's entire configuration
-                * @param newConfiguration the new configuration to replace the new one
-                */
+             * (Re-)set the model's entire configuration
+             * @param newConfiguration the new configuration to replace the new one
+             */
             configuration: IModelConfiguration;
             configuration: IModelConfiguration;
             /**
             /**
                 * Update the current configuration with new values.
                 * Update the current configuration with new values.
@@ -719,15 +664,13 @@ declare module BabylonViewer {
             dispose(): void;
             dispose(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     /**
     /**
         * BABYLON.Animation play mode enum - is the animation looping or playing once
         * BABYLON.Animation play mode enum - is the animation looping or playing once
         */
         */
     export const enum AnimationPlayMode {
     export const enum AnimationPlayMode {
             ONCE = 0,
             ONCE = 0,
-            LOOP = 1,
+            LOOP = 1
     }
     }
     /**
     /**
         * An enum representing the current state of an animation object
         * An enum representing the current state of an animation object
@@ -737,7 +680,7 @@ declare module BabylonViewer {
             PLAYING = 1,
             PLAYING = 1,
             PAUSED = 2,
             PAUSED = 2,
             STOPPED = 3,
             STOPPED = 3,
-            ENDED = 4,
+            ENDED = 4
     }
     }
     /**
     /**
         * The different type of easing functions available
         * The different type of easing functions available
@@ -754,7 +697,7 @@ declare module BabylonViewer {
             QuadraticEase = 8,
             QuadraticEase = 8,
             QuarticEase = 9,
             QuarticEase = 9,
             QuinticEase = 10,
             QuinticEase = 10,
-            SineEase = 11,
+            SineEase = 11
     }
     }
     /**
     /**
         * Defines a simple animation to be applied to a model (scale).
         * Defines a simple animation to be applied to a model (scale).
@@ -867,8 +810,8 @@ declare module BabylonViewer {
                 */
                 */
             readonly state: AnimationState;
             readonly state: AnimationState;
             /**
             /**
-                * Sets the speed ratio to use for all animations
-                */
+             * Sets the speed ratio to use for all animations
+             */
             speedRatio: number;
             speedRatio: number;
             /**
             /**
                 * Get the max numbers of frame available in the animation group
                 * Get the max numbers of frame available in the animation group
@@ -888,10 +831,10 @@ declare module BabylonViewer {
                 */
                 */
             readonly fps: number;
             readonly fps: number;
             /**
             /**
-                * Set the play mode.
-                * If the animation is played, it will continue playing at least once more, depending on the new play mode set.
-                * If the animation is not set, the will be initialized and will wait for the user to start playing it.
-                */
+             * Set the play mode.
+             * If the animation is played, it will continue playing at least once more, depending on the new play mode set.
+             * If the animation is not set, the will be initialized and will wait for the user to start playing it.
+             */
             playMode: AnimationPlayMode;
             playMode: AnimationPlayMode;
             /**
             /**
                 * Reset the animation group
                 * Reset the animation group
@@ -925,11 +868,7 @@ declare module BabylonViewer {
             dispose(): void;
             dispose(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
     /**
     /**
       * This interface defines the structure of a loader plugin.
       * This interface defines the structure of a loader plugin.
       * Any of those functions will be called if (!) the loader supports those callbacks.
       * Any of those functions will be called if (!) the loader supports those callbacks.
@@ -948,9 +887,7 @@ declare module BabylonViewer {
         onComplete?: () => void;
         onComplete?: () => void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     export interface IViewerTemplatePlugin {
     export interface IViewerTemplatePlugin {
         readonly templateName: string;
         readonly templateName: string;
         readonly eventsToAttach?: Array<string>;
         readonly eventsToAttach?: Array<string>;
@@ -972,9 +909,7 @@ declare module BabylonViewer {
         protected _generateHTMLElement(template: Template): Element | DocumentFragment;
         protected _generateHTMLElement(template: Template): Element | DocumentFragment;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     /**
     /**
       *
       *
       * @param name the name of the custom optimizer configuration
       * @param name the name of the custom optimizer configuration
@@ -983,7 +918,6 @@ declare module BabylonViewer {
     export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
     export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     /**
     /**
         * Will attach an init function the the DOMContentLoaded event.
         * Will attach an init function the the DOMContentLoaded event.
@@ -997,15 +931,9 @@ declare module BabylonViewer {
         */
         */
     export function InitTags(selector?: string): void;
     export function InitTags(selector?: string): void;
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    export * from 'babylonjs-viewer/configuration/configuration';
-    export * from 'babylonjs-viewer/configuration/interfaces';
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
     export function getConfigurationKey(key: string, configObject: any): any;
     export function getConfigurationKey(key: string, configObject: any): any;
     export interface ViewerConfiguration {
     export interface ViewerConfiguration {
             version?: string;
             version?: string;
@@ -1054,6 +982,7 @@ declare module BabylonViewer {
                     minecraft?: boolean;
                     minecraft?: boolean;
                     [propName: string]: boolean | undefined;
                     [propName: string]: boolean | undefined;
             };
             };
+            environmentMap?: IEnvironmentMapConfiguration;
             vr?: IVRConfiguration;
             vr?: IVRConfiguration;
             lab?: {
             lab?: {
                     flashlight?: boolean | {
                     flashlight?: boolean | {
@@ -1072,12 +1001,14 @@ declare module BabylonViewer {
                             };
                             };
                     };
                     };
                     hideLoadingDelay?: number;
                     hideLoadingDelay?: number;
+                    /** Deprecated */
                     assetsRootURL?: string;
                     assetsRootURL?: string;
                     environmentMainColor?: {
                     environmentMainColor?: {
                             r: number;
                             r: number;
                             g: number;
                             g: number;
                             b: number;
                             b: number;
                     };
                     };
+                    /** Deprecated */
                     environmentMap?: {
                     environmentMap?: {
                             /**
                             /**
                                 * Environment map texture path in relative to the asset folder.
                                 * Environment map texture path in relative to the asset folder.
@@ -1097,11 +1028,7 @@ declare module BabylonViewer {
             };
             };
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
     /**
     /**
         * The object sent when an event is triggered
         * The object sent when an event is triggered
         */
         */
@@ -1266,10 +1193,7 @@ declare module BabylonViewer {
             dispose(): void;
             dispose(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
     export class ConfigurationContainer {
     export class ConfigurationContainer {
         configuration: ViewerConfiguration;
         configuration: ViewerConfiguration;
         viewerId: string;
         viewerId: string;
@@ -1278,9 +1202,7 @@ declare module BabylonViewer {
         scene?: BABYLON.Scene;
         scene?: BABYLON.Scene;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     /**
     /**
         * The configuration loader will load the configuration object from any source and will use the defined mapper to
         * The configuration loader will load the configuration object from any source and will use the defined mapper to
         * parse the object and return a conform ViewerConfiguration.
         * parse the object and return a conform ViewerConfiguration.
@@ -1303,10 +1225,7 @@ declare module BabylonViewer {
             dispose(): void;
             dispose(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
     export class ObservablesManager {
     export class ObservablesManager {
             /**
             /**
                 * Will notify when the scene was initialized
                 * Will notify when the scene was initialized
@@ -1361,14 +1280,7 @@ declare module BabylonViewer {
             dispose(): void;
             dispose(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
-    
-    
-    
     /**
     /**
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * O - the type of object we are dealing with (Light, BABYLON.ArcRotateCamera, BABYLON.Scene, etc')
         * O - the type of object we are dealing with (Light, BABYLON.ArcRotateCamera, BABYLON.Scene, etc')
@@ -1466,17 +1378,17 @@ declare module BabylonViewer {
             animationBlendingEnabled: boolean;
             animationBlendingEnabled: boolean;
             readonly observablesManager: ObservablesManager | undefined;
             readonly observablesManager: ObservablesManager | undefined;
             /**
             /**
-                * Should shadows be rendered every frame, or only once and stop.
-                * This can be used to optimize a scene.
-                *
-                * Not that the shadows will NOT disapear but will remain in place.
-                * @param process if true shadows will be updated once every frame. if false they will stop being updated.
-                */
+             * Should shadows be rendered every frame, or only once and stop.
+             * This can be used to optimize a scene.
+             *
+             * Not that the shadows will NOT disapear but will remain in place.
+             * @param process if true shadows will be updated once every frame. if false they will stop being updated.
+             */
             processShadows: boolean;
             processShadows: boolean;
             groundEnabled: boolean;
             groundEnabled: boolean;
             /**
             /**
-                * sets wether the reflection is disabled.
-                */
+             * sets wether the reflection is disabled.
+             */
             groundMirrorEnabled: boolean;
             groundMirrorEnabled: boolean;
             defaultRenderingPipelineEnabled: boolean;
             defaultRenderingPipelineEnabled: boolean;
             /**
             /**
@@ -1514,6 +1426,7 @@ declare module BabylonViewer {
                 * @param modelConfiguration the configuration to use to reconfigure the models
                 * @param modelConfiguration the configuration to use to reconfigure the models
                 */
                 */
             protected _configureVR(vrConfig: IVRConfiguration): void;
             protected _configureVR(vrConfig: IVRConfiguration): void;
+            protected _configureEnvironmentMap(environmentMapConfiguration: IEnvironmentMapConfiguration): any;
             /**
             /**
                 * (Re) configure the camera. The camera will only be created once and from this point will only be reconfigured.
                 * (Re) configure the camera. The camera will only be created once and from this point will only be reconfigured.
                 * @param cameraConfig the new camera configuration
                 * @param cameraConfig the new camera configuration
@@ -1548,9 +1461,7 @@ declare module BabylonViewer {
             dispose(): void;
             dispose(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     export interface IModelConfiguration {
     export interface IModelConfiguration {
             id?: string;
             id?: string;
             url?: string;
             url?: string;
@@ -1616,14 +1527,7 @@ declare module BabylonViewer {
             };
             };
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
-    
-    
-    
     /**
     /**
         * Get a loader plugin according to its name.
         * Get a loader plugin according to its name.
         * The plugin will be cached and will be reused if called for again.
         * The plugin will be cached and will be reused if called for again.
@@ -1636,26 +1540,33 @@ declare module BabylonViewer {
         */
         */
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/defaultRenderingPipelineConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/groundConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/imageProcessingConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/lightConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/modelAnimationConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/modelConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/observersConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/sceneConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/sceneOptimizerConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/skyboxConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/templateConfiguration';
-    export * from 'babylonjs-viewer/configuration/interfaces/vrConfiguration';
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
+    export interface IEnvironmentMapConfiguration {
+            /**
+                * Environment map texture path in relative to the asset folder.
+                */
+            texture: string;
+            /**
+                * Default rotation to apply to the environment map.
+                */
+            rotationY: number;
+            /**
+                * Tint level of the main color on the environment map.
+                */
+            tintLevel: number;
+            /**
+                * The environment's main color.
+                */
+            mainColor?: {
+                    r?: number;
+                    g?: number;
+                    b?: number;
+            };
+    }
+}
+declare module BabylonViewer {
     /**
     /**
         * The EventManager is in charge of registering user interctions with the viewer.
         * The EventManager is in charge of registering user interctions with the viewer.
         * It is used in the TemplateManager
         * It is used in the TemplateManager
@@ -1688,10 +1599,7 @@ declare module BabylonViewer {
             dispose(): void;
             dispose(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
     /**
     /**
         * The ViewerLabs class will hold functions that are not (!) backwards compatible.
         * The ViewerLabs class will hold functions that are not (!) backwards compatible.
         * The APIs in all labs-related classes and configuration  might change.
         * The APIs in all labs-related classes and configuration  might change.
@@ -1739,7 +1647,6 @@ declare module BabylonViewer {
             rotateShadowLight(shadowLight: BABYLON.ShadowLight, amount: number, point?: BABYLON.Vector3, axis?: BABYLON.Vector3, target?: BABYLON.Vector3): void;
             rotateShadowLight(shadowLight: BABYLON.ShadowLight, amount: number, point?: BABYLON.Vector3, axis?: BABYLON.Vector3, target?: BABYLON.Vector3): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     /**
     /**
         * Defines an animation to be applied to a model (translation, scale or rotation).
         * Defines an animation to be applied to a model (translation, scale or rotation).
@@ -1768,11 +1675,7 @@ declare module BabylonViewer {
             easingMode?: number;
             easingMode?: number;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
     export class TelemetryLoaderPlugin implements ILoaderPlugin {
     export class TelemetryLoaderPlugin implements ILoaderPlugin {
         onInit(loader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync, model: ViewerModel): void;
         onInit(loader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync, model: ViewerModel): void;
         onLoaded(model: ViewerModel): void;
         onLoaded(model: ViewerModel): void;
@@ -1780,12 +1683,7 @@ declare module BabylonViewer {
         onComplete(): void;
         onComplete(): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
-    
     /**
     /**
       * A loder plugin to use MSFT_lod extension correctly (glTF)
       * A loder plugin to use MSFT_lod extension correctly (glTF)
       */
       */
@@ -1794,11 +1692,7 @@ declare module BabylonViewer {
         onExtensionLoaded(extension: BABYLON.IGLTFLoaderExtension): void;
         onExtensionLoaded(extension: BABYLON.IGLTFLoaderExtension): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
     /**
     /**
       * Force-apply material configuration right after a material was loaded.
       * Force-apply material configuration right after a material was loaded.
       */
       */
@@ -1807,10 +1701,7 @@ declare module BabylonViewer {
         onMaterialLoaded(material: BABYLON.Material): void;
         onMaterialLoaded(material: BABYLON.Material): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
     /**
     /**
       * A (PBR) material will be extended using this function.
       * A (PBR) material will be extended using this function.
       * This function will hold extra default configuration for the viewer, if not implemented in Babylon itself.
       * This function will hold extra default configuration for the viewer, if not implemented in Babylon itself.
@@ -1819,7 +1710,6 @@ declare module BabylonViewer {
         onMaterialLoaded(baseMaterial: BABYLON.Material): void;
         onMaterialLoaded(baseMaterial: BABYLON.Material): void;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     export interface ICameraConfiguration {
     export interface ICameraConfiguration {
         position?: {
         position?: {
@@ -1853,7 +1743,6 @@ declare module BabylonViewer {
         [propName: string]: any;
         [propName: string]: any;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     /**
     /**
         * The Color Grading Configuration groups the different settings used to define the color grading used in the viewer.
         * The Color Grading Configuration groups the different settings used to define the color grading used in the viewer.
@@ -1937,9 +1826,7 @@ declare module BabylonViewer {
             exposureHighlights: number;
             exposureHighlights: number;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     export interface IDefaultRenderingPipelineConfiguration {
     export interface IDefaultRenderingPipelineConfiguration {
         sharpenEnabled?: boolean;
         sharpenEnabled?: boolean;
         bloomEnabled?: boolean;
         bloomEnabled?: boolean;
@@ -1960,7 +1847,6 @@ declare module BabylonViewer {
         glowLayerEnabled?: boolean;
         glowLayerEnabled?: boolean;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     export interface IGroundConfiguration {
     export interface IGroundConfiguration {
         size?: number;
         size?: number;
@@ -1987,7 +1873,6 @@ declare module BabylonViewer {
         };
         };
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     export interface IImageProcessingConfiguration {
     export interface IImageProcessingConfiguration {
         colorGradingEnabled?: boolean;
         colorGradingEnabled?: boolean;
@@ -2033,7 +1918,6 @@ declare module BabylonViewer {
         isEnabled?: boolean;
         isEnabled?: boolean;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     export interface ILightConfiguration {
     export interface ILightConfiguration {
         type: number;
         type: number;
@@ -2096,7 +1980,6 @@ declare module BabylonViewer {
         };
         };
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     export interface IObserversConfiguration {
     export interface IObserversConfiguration {
         onEngineInit?: string;
         onEngineInit?: string;
@@ -2104,58 +1987,55 @@ declare module BabylonViewer {
         onModelLoaded?: string;
         onModelLoaded?: string;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
-    
     export interface ISceneConfiguration {
     export interface ISceneConfiguration {
-        debug?: boolean;
-        clearColor?: {
-            r: number;
-            g: number;
-            b: number;
-            a: number;
-        };
-        mainColor?: {
-            r?: number;
-            g?: number;
-            b?: number;
-        };
-        imageProcessingConfiguration?: IImageProcessingConfiguration;
-        environmentTexture?: string;
-        colorGrading?: IColorGradingConfiguration;
-        environmentRotationY?: number;
-        /**
-          * Deprecated, please use default rendering pipeline
-          */
-        glow?: boolean | BABYLON.IGlowLayerOptions;
-        disableHdr?: boolean;
-        renderInBackground?: boolean;
-        disableCameraControl?: boolean;
-        animationPropertiesOverride?: {
-            [propName: string]: any;
-        };
-        defaultMaterial?: {
-            materialType: "standard" | "pbr";
-            [propName: string]: any;
-        };
-        flags?: {
-            shadowsEnabled?: boolean;
-            particlesEnabled?: boolean;
-            collisionsEnabled?: boolean;
-            lightsEnabled?: boolean;
-            texturesEnabled?: boolean;
-            lensFlaresEnabled?: boolean;
-            proceduralTexturesEnabled?: boolean;
-            renderTargetsEnabled?: boolean;
-            spritesEnabled?: boolean;
-            skeletonsEnabled?: boolean;
-            audioEnabled?: boolean;
-        };
+            debug?: boolean;
+            clearColor?: {
+                    r: number;
+                    g: number;
+                    b: number;
+                    a: number;
+            };
+            /** Deprecated, use environmentMap.mainColor instead. */
+            mainColor?: {
+                    r?: number;
+                    g?: number;
+                    b?: number;
+            };
+            imageProcessingConfiguration?: IImageProcessingConfiguration;
+            environmentTexture?: string;
+            colorGrading?: IColorGradingConfiguration;
+            environmentRotationY?: number;
+            /**
+                * Deprecated, please use default rendering pipeline
+                */
+            glow?: boolean | BABYLON.IGlowLayerOptions;
+            disableHdr?: boolean;
+            renderInBackground?: boolean;
+            disableCameraControl?: boolean;
+            animationPropertiesOverride?: {
+                    [propName: string]: any;
+            };
+            defaultMaterial?: {
+                    materialType: "standard" | "pbr";
+                    [propName: string]: any;
+            };
+            flags?: {
+                    shadowsEnabled?: boolean;
+                    particlesEnabled?: boolean;
+                    collisionsEnabled?: boolean;
+                    lightsEnabled?: boolean;
+                    texturesEnabled?: boolean;
+                    lensFlaresEnabled?: boolean;
+                    proceduralTexturesEnabled?: boolean;
+                    renderTargetsEnabled?: boolean;
+                    spritesEnabled?: boolean;
+                    skeletonsEnabled?: boolean;
+                    audioEnabled?: boolean;
+            };
+            assetsRootURL?: string;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     export interface ISceneOptimizerConfiguration {
     export interface ISceneOptimizerConfiguration {
         targetFrameRate?: number;
         targetFrameRate?: number;
@@ -2181,9 +2061,7 @@ declare module BabylonViewer {
         step?: number;
         step?: number;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     export interface ISkyboxConfiguration {
     export interface ISkyboxConfiguration {
         cubeTexture?: {
         cubeTexture?: {
             noMipMap?: boolean;
             noMipMap?: boolean;
@@ -2205,7 +2083,6 @@ declare module BabylonViewer {
         infiniteDistance?: boolean;
         infiniteDistance?: boolean;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
     /**
     /**
         * A single template configuration object
         * A single template configuration object
@@ -2275,9 +2152,7 @@ declare module BabylonViewer {
             };
             };
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     export interface IVRConfiguration {
     export interface IVRConfiguration {
         disabled?: boolean;
         disabled?: boolean;
         objectScaleFactor?: number;
         objectScaleFactor?: number;
@@ -2294,10 +2169,7 @@ declare module BabylonViewer {
         };
         };
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
-    
     /**
     /**
         * Spherical polynomial coefficients (counter part to spherical harmonic coefficients used in shader irradiance calculation)
         * Spherical polynomial coefficients (counter part to spherical harmonic coefficients used in shader irradiance calculation)
         * @ignoreChildren
         * @ignoreChildren
@@ -2403,9 +2275,7 @@ declare module BabylonViewer {
             static Parse(arrayBuffer: ArrayBuffer): PBREnvironment;
             static Parse(arrayBuffer: ArrayBuffer): PBREnvironment;
     }
     }
 }
 }
-
 declare module BabylonViewer {
 declare module BabylonViewer {
-    
     /**
     /**
         * WebGL Pixel Formats
         * WebGL Pixel Formats
         */
         */
@@ -2415,7 +2285,7 @@ declare module BabylonViewer {
             RGB = 6407,
             RGB = 6407,
             RGBA = 6408,
             RGBA = 6408,
             LUMINANCE = 6409,
             LUMINANCE = 6409,
-            LUMINANCE_ALPHA = 6410,
+            LUMINANCE_ALPHA = 6410
     }
     }
     /**
     /**
         * WebGL Pixel Types
         * WebGL Pixel Types
@@ -2424,14 +2294,14 @@ declare module BabylonViewer {
             UNSIGNED_BYTE = 5121,
             UNSIGNED_BYTE = 5121,
             UNSIGNED_SHORT_4_4_4_4 = 32819,
             UNSIGNED_SHORT_4_4_4_4 = 32819,
             UNSIGNED_SHORT_5_5_5_1 = 32820,
             UNSIGNED_SHORT_5_5_5_1 = 32820,
-            UNSIGNED_SHORT_5_6_5 = 33635,
+            UNSIGNED_SHORT_5_6_5 = 33635
     }
     }
     /**
     /**
         * WebGL Texture Magnification Filter
         * WebGL Texture Magnification Filter
         */
         */
     export const enum TextureMagFilter {
     export const enum TextureMagFilter {
             NEAREST = 9728,
             NEAREST = 9728,
-            LINEAR = 9729,
+            LINEAR = 9729
     }
     }
     /**
     /**
         * WebGL Texture Minification Filter
         * WebGL Texture Minification Filter
@@ -2442,7 +2312,7 @@ declare module BabylonViewer {
             NEAREST_MIPMAP_NEAREST = 9984,
             NEAREST_MIPMAP_NEAREST = 9984,
             LINEAR_MIPMAP_NEAREST = 9985,
             LINEAR_MIPMAP_NEAREST = 9985,
             NEAREST_MIPMAP_LINEAR = 9986,
             NEAREST_MIPMAP_LINEAR = 9986,
-            LINEAR_MIPMAP_LINEAR = 9987,
+            LINEAR_MIPMAP_LINEAR = 9987
     }
     }
     /**
     /**
         * WebGL Texture Wrap Modes
         * WebGL Texture Wrap Modes
@@ -2450,7 +2320,7 @@ declare module BabylonViewer {
     export const enum TextureWrapMode {
     export const enum TextureWrapMode {
             REPEAT = 10497,
             REPEAT = 10497,
             CLAMP_TO_EDGE = 33071,
             CLAMP_TO_EDGE = 33071,
-            MIRRORED_REPEAT = 33648,
+            MIRRORED_REPEAT = 33648
     }
     }
     /**
     /**
         * Raw texture data and descriptor sufficient for WebGL texture upload
         * Raw texture data and descriptor sufficient for WebGL texture upload
@@ -2585,5 +2455,4 @@ declare module BabylonViewer {
                 */
                 */
             static EnvironmentLODOffset: number;
             static EnvironmentLODOffset: number;
     }
     }
-}
-
+}

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


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


+ 112 - 76
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -5,8 +5,8 @@ declare module "babylonjs-loaders"{ export=BABYLON;}
 
 
 // Generated by dts-bundle v0.7.3
 // Generated by dts-bundle v0.7.3
 // Dependencies for this module:
 // Dependencies for this module:
-//   ../../../../Tools/Gulp/babylonjs
-//   ../../../../Tools/Gulp/babylonjs-loaders
+//   ../../../../../Tools/Gulp/babylonjs
+//   ../../../../../Tools/Gulp/babylonjs-loaders
 
 
 declare module 'babylonjs-viewer' {
 declare module 'babylonjs-viewer' {
     import { mapperManager } from 'babylonjs-viewer/configuration/mappers';
     import { mapperManager } from 'babylonjs-viewer/configuration/mappers';
@@ -173,7 +173,7 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * This will be executed when the templates initialize.
                 * This will be executed when the templates initialize.
                 */
                 */
             protected _onTemplatesLoaded(): Promise<AbstractViewer>;
             protected _onTemplatesLoaded(): Promise<AbstractViewer>;
-            toggleVR(): void;
+            protected _initVR(): void;
             /**
             /**
                 * Toggle fullscreen of the entire viewer
                 * Toggle fullscreen of the entire viewer
                 */
                 */
@@ -359,8 +359,8 @@ declare module 'babylonjs-viewer/viewer/viewer' {
                 */
                 */
             isCanvasInDOM(): boolean;
             isCanvasInDOM(): boolean;
             /**
             /**
-                * Set the viewer's background rendering flag.
-                */
+             * Set the viewer's background rendering flag.
+             */
             renderInBackground: boolean;
             renderInBackground: boolean;
             /**
             /**
                 * Get the configuration object. This is a reference only.
                 * Get the configuration object. This is a reference only.
@@ -376,7 +376,9 @@ declare module 'babylonjs-viewer/viewer/viewer' {
             toggleHD(): void;
             toggleHD(): void;
             protected _vrToggled: boolean;
             protected _vrToggled: boolean;
             protected _vrScale: number;
             protected _vrScale: number;
+            protected _vrInit: boolean;
             toggleVR(): void;
             toggleVR(): void;
+            protected _initVR(): void;
             /**
             /**
                 * The resize function that will be registered with the window object
                 * The resize function that will be registered with the window object
                 */
                 */
@@ -573,7 +575,7 @@ declare module 'babylonjs-viewer/model/viewerModel' {
             ENTRYDONE = 4,
             ENTRYDONE = 4,
             COMPLETE = 5,
             COMPLETE = 5,
             CANCELED = 6,
             CANCELED = 6,
-            ERROR = 7,
+            ERROR = 7
     }
     }
     /**
     /**
         * The viewer model is a container for all assets representing a sngle loaded model.
         * The viewer model is a container for all assets representing a sngle loaded model.
@@ -638,8 +640,8 @@ declare module 'babylonjs-viewer/model/viewerModel' {
             shadowsRenderedAfterLoad: boolean;
             shadowsRenderedAfterLoad: boolean;
             getViewerId(): string | undefined;
             getViewerId(): string | undefined;
             /**
             /**
-                * Set whether this model is enabled or not.
-                */
+             * Set whether this model is enabled or not.
+             */
             enabled: boolean;
             enabled: boolean;
             loaderDone: boolean;
             loaderDone: boolean;
             /**
             /**
@@ -655,9 +657,9 @@ declare module 'babylonjs-viewer/model/viewerModel' {
                 */
                 */
             readonly meshes: AbstractMesh[];
             readonly meshes: AbstractMesh[];
             /**
             /**
-                * (Re-)set the model's entire configuration
-                * @param newConfiguration the new configuration to replace the new one
-                */
+             * (Re-)set the model's entire configuration
+             * @param newConfiguration the new configuration to replace the new one
+             */
             configuration: IModelConfiguration;
             configuration: IModelConfiguration;
             /**
             /**
                 * Update the current configuration with new values.
                 * Update the current configuration with new values.
@@ -727,7 +729,7 @@ declare module 'babylonjs-viewer/model/modelAnimation' {
         */
         */
     export const enum AnimationPlayMode {
     export const enum AnimationPlayMode {
             ONCE = 0,
             ONCE = 0,
-            LOOP = 1,
+            LOOP = 1
     }
     }
     /**
     /**
         * An enum representing the current state of an animation object
         * An enum representing the current state of an animation object
@@ -737,7 +739,7 @@ declare module 'babylonjs-viewer/model/modelAnimation' {
             PLAYING = 1,
             PLAYING = 1,
             PAUSED = 2,
             PAUSED = 2,
             STOPPED = 3,
             STOPPED = 3,
-            ENDED = 4,
+            ENDED = 4
     }
     }
     /**
     /**
         * The different type of easing functions available
         * The different type of easing functions available
@@ -754,7 +756,7 @@ declare module 'babylonjs-viewer/model/modelAnimation' {
             QuadraticEase = 8,
             QuadraticEase = 8,
             QuarticEase = 9,
             QuarticEase = 9,
             QuinticEase = 10,
             QuinticEase = 10,
-            SineEase = 11,
+            SineEase = 11
     }
     }
     /**
     /**
         * Defines a simple animation to be applied to a model (scale).
         * Defines a simple animation to be applied to a model (scale).
@@ -867,8 +869,8 @@ declare module 'babylonjs-viewer/model/modelAnimation' {
                 */
                 */
             readonly state: AnimationState;
             readonly state: AnimationState;
             /**
             /**
-                * Sets the speed ratio to use for all animations
-                */
+             * Sets the speed ratio to use for all animations
+             */
             speedRatio: number;
             speedRatio: number;
             /**
             /**
                 * Get the max numbers of frame available in the animation group
                 * Get the max numbers of frame available in the animation group
@@ -888,10 +890,10 @@ declare module 'babylonjs-viewer/model/modelAnimation' {
                 */
                 */
             readonly fps: number;
             readonly fps: number;
             /**
             /**
-                * Set the play mode.
-                * If the animation is played, it will continue playing at least once more, depending on the new play mode set.
-                * If the animation is not set, the will be initialized and will wait for the user to start playing it.
-                */
+             * Set the play mode.
+             * If the animation is played, it will continue playing at least once more, depending on the new play mode set.
+             * If the animation is not set, the will be initialized and will wait for the user to start playing it.
+             */
             playMode: AnimationPlayMode;
             playMode: AnimationPlayMode;
             /**
             /**
                 * Reset the animation group
                 * Reset the animation group
@@ -1006,6 +1008,7 @@ declare module 'babylonjs-viewer/configuration' {
 declare module 'babylonjs-viewer/configuration/configuration' {
 declare module 'babylonjs-viewer/configuration/configuration' {
     import { EngineOptions } from 'babylonjs';
     import { EngineOptions } from 'babylonjs';
     import { ICameraConfiguration, IDefaultRenderingPipelineConfiguration, IGroundConfiguration, ILightConfiguration, IModelConfiguration, IObserversConfiguration, ISceneConfiguration, ISceneOptimizerConfiguration, ISkyboxConfiguration, ITemplateConfiguration, IVRConfiguration } from 'babylonjs-viewer/configuration/interfaces';
     import { ICameraConfiguration, IDefaultRenderingPipelineConfiguration, IGroundConfiguration, ILightConfiguration, IModelConfiguration, IObserversConfiguration, ISceneConfiguration, ISceneOptimizerConfiguration, ISkyboxConfiguration, ITemplateConfiguration, IVRConfiguration } from 'babylonjs-viewer/configuration/interfaces';
+    import { IEnvironmentMapConfiguration } from 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration';
     export function getConfigurationKey(key: string, configObject: any): any;
     export function getConfigurationKey(key: string, configObject: any): any;
     export interface ViewerConfiguration {
     export interface ViewerConfiguration {
             version?: string;
             version?: string;
@@ -1054,6 +1057,7 @@ declare module 'babylonjs-viewer/configuration/configuration' {
                     minecraft?: boolean;
                     minecraft?: boolean;
                     [propName: string]: boolean | undefined;
                     [propName: string]: boolean | undefined;
             };
             };
+            environmentMap?: IEnvironmentMapConfiguration;
             vr?: IVRConfiguration;
             vr?: IVRConfiguration;
             lab?: {
             lab?: {
                     flashlight?: boolean | {
                     flashlight?: boolean | {
@@ -1072,12 +1076,14 @@ declare module 'babylonjs-viewer/configuration/configuration' {
                             };
                             };
                     };
                     };
                     hideLoadingDelay?: number;
                     hideLoadingDelay?: number;
+                    /** Deprecated */
                     assetsRootURL?: string;
                     assetsRootURL?: string;
                     environmentMainColor?: {
                     environmentMainColor?: {
                             r: number;
                             r: number;
                             g: number;
                             g: number;
                             b: number;
                             b: number;
                     };
                     };
+                    /** Deprecated */
                     environmentMap?: {
                     environmentMap?: {
                             /**
                             /**
                                 * Environment map texture path in relative to the asset folder.
                                 * Environment map texture path in relative to the asset folder.
@@ -1369,6 +1375,7 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
     import { ViewerLabs } from 'babylonjs-viewer/labs/viewerLabs';
     import { ViewerLabs } from 'babylonjs-viewer/labs/viewerLabs';
     import { ObservablesManager } from 'babylonjs-viewer/managers/observablesManager';
     import { ObservablesManager } from 'babylonjs-viewer/managers/observablesManager';
     import { ConfigurationContainer } from 'babylonjs-viewer/configuration/configurationContainer';
     import { ConfigurationContainer } from 'babylonjs-viewer/configuration/configurationContainer';
+    import { IEnvironmentMapConfiguration } from 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration';
     /**
     /**
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * O - the type of object we are dealing with (Light, ArcRotateCamera, Scene, etc')
         * O - the type of object we are dealing with (Light, ArcRotateCamera, Scene, etc')
@@ -1466,17 +1473,17 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
             animationBlendingEnabled: boolean;
             animationBlendingEnabled: boolean;
             readonly observablesManager: ObservablesManager | undefined;
             readonly observablesManager: ObservablesManager | undefined;
             /**
             /**
-                * Should shadows be rendered every frame, or only once and stop.
-                * This can be used to optimize a scene.
-                *
-                * Not that the shadows will NOT disapear but will remain in place.
-                * @param process if true shadows will be updated once every frame. if false they will stop being updated.
-                */
+             * Should shadows be rendered every frame, or only once and stop.
+             * This can be used to optimize a scene.
+             *
+             * Not that the shadows will NOT disapear but will remain in place.
+             * @param process if true shadows will be updated once every frame. if false they will stop being updated.
+             */
             processShadows: boolean;
             processShadows: boolean;
             groundEnabled: boolean;
             groundEnabled: boolean;
             /**
             /**
-                * sets wether the reflection is disabled.
-                */
+             * sets wether the reflection is disabled.
+             */
             groundMirrorEnabled: boolean;
             groundMirrorEnabled: boolean;
             defaultRenderingPipelineEnabled: boolean;
             defaultRenderingPipelineEnabled: boolean;
             /**
             /**
@@ -1514,6 +1521,7 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
                 * @param modelConfiguration the configuration to use to reconfigure the models
                 * @param modelConfiguration the configuration to use to reconfigure the models
                 */
                 */
             protected _configureVR(vrConfig: IVRConfiguration): void;
             protected _configureVR(vrConfig: IVRConfiguration): void;
+            protected _configureEnvironmentMap(environmentMapConfiguration: IEnvironmentMapConfiguration): any;
             /**
             /**
                 * (Re) configure the camera. The camera will only be created once and from this point will only be reconfigured.
                 * (Re) configure the camera. The camera will only be created once and from this point will only be reconfigured.
                 * @param cameraConfig the new camera configuration
                 * @param cameraConfig the new camera configuration
@@ -1652,6 +1660,32 @@ declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/skyboxConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/skyboxConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/templateConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/templateConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/vrConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/vrConfiguration';
+    export * from 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration';
+}
+
+declare module 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration' {
+    export interface IEnvironmentMapConfiguration {
+            /**
+                * Environment map texture path in relative to the asset folder.
+                */
+            texture: string;
+            /**
+                * Default rotation to apply to the environment map.
+                */
+            rotationY: number;
+            /**
+                * Tint level of the main color on the environment map.
+                */
+            tintLevel: number;
+            /**
+                * The environment's main color.
+                */
+            mainColor?: {
+                    r?: number;
+                    g?: number;
+                    b?: number;
+            };
+    }
 }
 }
 
 
 declare module 'babylonjs-viewer/templating/eventManager' {
 declare module 'babylonjs-viewer/templating/eventManager' {
@@ -2110,49 +2144,51 @@ declare module 'babylonjs-viewer/configuration/interfaces/sceneConfiguration' {
     import { IColorGradingConfiguration } from "babylonjs-viewer/configuration/interfaces/colorGradingConfiguration";
     import { IColorGradingConfiguration } from "babylonjs-viewer/configuration/interfaces/colorGradingConfiguration";
     import { IGlowLayerOptions } from "babylonjs";
     import { IGlowLayerOptions } from "babylonjs";
     export interface ISceneConfiguration {
     export interface ISceneConfiguration {
-        debug?: boolean;
-        clearColor?: {
-            r: number;
-            g: number;
-            b: number;
-            a: number;
-        };
-        mainColor?: {
-            r?: number;
-            g?: number;
-            b?: number;
-        };
-        imageProcessingConfiguration?: IImageProcessingConfiguration;
-        environmentTexture?: string;
-        colorGrading?: IColorGradingConfiguration;
-        environmentRotationY?: number;
-        /**
-          * Deprecated, please use default rendering pipeline
-          */
-        glow?: boolean | IGlowLayerOptions;
-        disableHdr?: boolean;
-        renderInBackground?: boolean;
-        disableCameraControl?: boolean;
-        animationPropertiesOverride?: {
-            [propName: string]: any;
-        };
-        defaultMaterial?: {
-            materialType: "standard" | "pbr";
-            [propName: string]: any;
-        };
-        flags?: {
-            shadowsEnabled?: boolean;
-            particlesEnabled?: boolean;
-            collisionsEnabled?: boolean;
-            lightsEnabled?: boolean;
-            texturesEnabled?: boolean;
-            lensFlaresEnabled?: boolean;
-            proceduralTexturesEnabled?: boolean;
-            renderTargetsEnabled?: boolean;
-            spritesEnabled?: boolean;
-            skeletonsEnabled?: boolean;
-            audioEnabled?: boolean;
-        };
+            debug?: boolean;
+            clearColor?: {
+                    r: number;
+                    g: number;
+                    b: number;
+                    a: number;
+            };
+            /** Deprecated, use environmentMap.mainColor instead. */
+            mainColor?: {
+                    r?: number;
+                    g?: number;
+                    b?: number;
+            };
+            imageProcessingConfiguration?: IImageProcessingConfiguration;
+            environmentTexture?: string;
+            colorGrading?: IColorGradingConfiguration;
+            environmentRotationY?: number;
+            /**
+                * Deprecated, please use default rendering pipeline
+                */
+            glow?: boolean | IGlowLayerOptions;
+            disableHdr?: boolean;
+            renderInBackground?: boolean;
+            disableCameraControl?: boolean;
+            animationPropertiesOverride?: {
+                    [propName: string]: any;
+            };
+            defaultMaterial?: {
+                    materialType: "standard" | "pbr";
+                    [propName: string]: any;
+            };
+            flags?: {
+                    shadowsEnabled?: boolean;
+                    particlesEnabled?: boolean;
+                    collisionsEnabled?: boolean;
+                    lightsEnabled?: boolean;
+                    texturesEnabled?: boolean;
+                    lensFlaresEnabled?: boolean;
+                    proceduralTexturesEnabled?: boolean;
+                    renderTargetsEnabled?: boolean;
+                    spritesEnabled?: boolean;
+                    skeletonsEnabled?: boolean;
+                    audioEnabled?: boolean;
+            };
+            assetsRootURL?: string;
     }
     }
 }
 }
 
 
@@ -2415,7 +2451,7 @@ declare module 'babylonjs-viewer/labs/texture' {
             RGB = 6407,
             RGB = 6407,
             RGBA = 6408,
             RGBA = 6408,
             LUMINANCE = 6409,
             LUMINANCE = 6409,
-            LUMINANCE_ALPHA = 6410,
+            LUMINANCE_ALPHA = 6410
     }
     }
     /**
     /**
         * WebGL Pixel Types
         * WebGL Pixel Types
@@ -2424,14 +2460,14 @@ declare module 'babylonjs-viewer/labs/texture' {
             UNSIGNED_BYTE = 5121,
             UNSIGNED_BYTE = 5121,
             UNSIGNED_SHORT_4_4_4_4 = 32819,
             UNSIGNED_SHORT_4_4_4_4 = 32819,
             UNSIGNED_SHORT_5_5_5_1 = 32820,
             UNSIGNED_SHORT_5_5_5_1 = 32820,
-            UNSIGNED_SHORT_5_6_5 = 33635,
+            UNSIGNED_SHORT_5_6_5 = 33635
     }
     }
     /**
     /**
         * WebGL Texture Magnification Filter
         * WebGL Texture Magnification Filter
         */
         */
     export const enum TextureMagFilter {
     export const enum TextureMagFilter {
             NEAREST = 9728,
             NEAREST = 9728,
-            LINEAR = 9729,
+            LINEAR = 9729
     }
     }
     /**
     /**
         * WebGL Texture Minification Filter
         * WebGL Texture Minification Filter
@@ -2442,7 +2478,7 @@ declare module 'babylonjs-viewer/labs/texture' {
             NEAREST_MIPMAP_NEAREST = 9984,
             NEAREST_MIPMAP_NEAREST = 9984,
             LINEAR_MIPMAP_NEAREST = 9985,
             LINEAR_MIPMAP_NEAREST = 9985,
             NEAREST_MIPMAP_LINEAR = 9986,
             NEAREST_MIPMAP_LINEAR = 9986,
-            LINEAR_MIPMAP_LINEAR = 9987,
+            LINEAR_MIPMAP_LINEAR = 9987
     }
     }
     /**
     /**
         * WebGL Texture Wrap Modes
         * WebGL Texture Wrap Modes
@@ -2450,7 +2486,7 @@ declare module 'babylonjs-viewer/labs/texture' {
     export const enum TextureWrapMode {
     export const enum TextureWrapMode {
             REPEAT = 10497,
             REPEAT = 10497,
             CLAMP_TO_EDGE = 33071,
             CLAMP_TO_EDGE = 33071,
-            MIRRORED_REPEAT = 33648,
+            MIRRORED_REPEAT = 33648
     }
     }
     /**
     /**
         * Raw texture data and descriptor sufficient for WebGL texture upload
         * Raw texture data and descriptor sufficient for WebGL texture upload

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

@@ -7,7 +7,7 @@
 - New GUI 3D controls toolset. [Complete doc + demos](http://doc.babylonjs.com/how_to/gui3d) ([Deltakosh](https://github.com/deltakosh))
 - New GUI 3D controls toolset. [Complete doc + demos](http://doc.babylonjs.com/how_to/gui3d) ([Deltakosh](https://github.com/deltakosh))
 - Added [Environment Texture Tools](https://doc.babylonjs.com/how_to/physically_based_rendering#creating-a-compressed-environment-texture) to reduce the size of the usual .DDS file ([sebavan](http://www.github.com/sebavan))
 - Added [Environment Texture Tools](https://doc.babylonjs.com/how_to/physically_based_rendering#creating-a-compressed-environment-texture) to reduce the size of the usual .DDS file ([sebavan](http://www.github.com/sebavan))
 - New GUI control: the [Grid](http://doc.babylonjs.com/how_to/gui#grid) ([Deltakosh](https://github.com/deltakosh))
 - New GUI control: the [Grid](http://doc.babylonjs.com/how_to/gui#grid) ([Deltakosh](https://github.com/deltakosh))
-- Gizmo and GizmoManager classes used to manipulate meshes in a scene. Gizmo types include: position, rotation, scale and bounding box. [Doc](http://doc.babylonjs.com/how_to/gizmo) ([TrevorDev](https://github.com/TrevorDev))
+- Gizmo and GizmoManager classes used to manipulate meshes in a scene. Gizmo types include: position, scale, rotation and bounding box. [Doc](http://doc.babylonjs.com/how_to/gizmo) ([TrevorDev](https://github.com/TrevorDev))
 - New behaviors: PointerDragBehavior, SixDofDragBehavior and MultiPointerScaleBehavior to enable smooth drag and drop/scaling with mouse or 6dof controller on a mesh. [Doc](http://doc.babylonjs.com/how_to/meshbehavior) ([TrevorDev](https://github.com/TrevorDev))
 - New behaviors: PointerDragBehavior, SixDofDragBehavior and MultiPointerScaleBehavior to enable smooth drag and drop/scaling with mouse or 6dof controller on a mesh. [Doc](http://doc.babylonjs.com/how_to/meshbehavior) ([TrevorDev](https://github.com/TrevorDev))
 - Particle system improvements ([Deltakosh](https://github.com/deltakosh))
 - Particle system improvements ([Deltakosh](https://github.com/deltakosh))
   - Added a ParticleHelper class to create some pre-configured particle systems in a one-liner method style. [Doc](https://doc.babylonjs.com/How_To/ParticleHelper) ([Deltakosh](https://github.com/deltakosh)) / ([DevChris](https://github.com/yovanoc))
   - Added a ParticleHelper class to create some pre-configured particle systems in a one-liner method style. [Doc](https://doc.babylonjs.com/How_To/ParticleHelper) ([Deltakosh](https://github.com/deltakosh)) / ([DevChris](https://github.com/yovanoc))
@@ -17,6 +17,8 @@
   - Added support for `minScaleX`, `minScaleY`, `maxScaleX`, `maxScaleY`. [Doc](https://doc.babylonjs.com/babylon101/particles#size)
   - Added support for `minScaleX`, `minScaleY`, `maxScaleX`, `maxScaleY`. [Doc](https://doc.babylonjs.com/babylon101/particles#size)
   - Added support for `radiusRange` for sphere emitter. [Doc](https://doc.babylonjs.com/babylon101/particles#sphere-emitter)
   - Added support for `radiusRange` for sphere emitter. [Doc](https://doc.babylonjs.com/babylon101/particles#sphere-emitter)
   - Added support for `radiusRange` and `heightRange` for cone emitter. [Doc](https://doc.babylonjs.com/babylon101/particles#cone-emitter)
   - Added support for `radiusRange` and `heightRange` for cone emitter. [Doc](https://doc.babylonjs.com/babylon101/particles#cone-emitter)
+  - Added new point emitter. [Doc](https://doc.babylonjs.com/babylon101/particles#point-emitter)
+  - Added new hemispheric emitter. [Doc](https://doc.babylonjs.com/babylon101/particles#hemispheric-emitter)
   - Added support for `ParticleSystem.BLENDMODE_ADD` alpha mode. [Doc](https://doc.babylonjs.com/babylon101/particles#particle-blending)
   - Added support for `ParticleSystem.BLENDMODE_ADD` alpha mode. [Doc](https://doc.babylonjs.com/babylon101/particles#particle-blending)
   - Added support for color gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#particle-colors)
   - Added support for color gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#particle-colors)
   - Added support for pre-warming. [Doc](https://doc.babylonjs.com/babylon101/particles#pre-warming)
   - Added support for pre-warming. [Doc](https://doc.babylonjs.com/babylon101/particles#pre-warming)
@@ -24,10 +26,15 @@
   - Added support for size gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#size)
   - Added support for size gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#size)
   - Added support for life time gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#lifetime)
   - Added support for life time gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#lifetime)
   - Added support for angular speed gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#rotation)
   - Added support for angular speed gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#rotation)
-- Added SceneComponent to help decoupling Scene from its components ([sebavan](http://www.github.com/sebavan))
+  - Added support for velocty gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#velocity-over-time)
+  - Added support for limit velocty gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#limit-velocity-over-time)
+  - Added support for noise textures. [Doc](http://doc.babylonjs.com/babylon101/particles#noise-texture)
+- Added SceneComponent to help decoupling Scene from its components. ([sebavan](http://www.github.com/sebavan))
 - Playground can now be used with TypeScript directly!. [Demo](https://www.babylonjs-playground.com/ts.html) ([Deltakosh](https://github.com/deltakosh), [NasimiAsl](https://github.com/NasimiAsl))
 - Playground can now be used with TypeScript directly!. [Demo](https://www.babylonjs-playground.com/ts.html) ([Deltakosh](https://github.com/deltakosh), [NasimiAsl](https://github.com/NasimiAsl))
 - New GUI control: [InputPassword](https://doc.babylonjs.com/how_to/gui#inputpassword) ([theom](https://github.com/theom))
 - New GUI control: [InputPassword](https://doc.babylonjs.com/how_to/gui#inputpassword) ([theom](https://github.com/theom))
 - Added dead key support and before key add observable to InputText. [Doc](https://doc.babylonjs.com/how_to/gui#using-onbeforekeyaddobservable-for-extended-keyboard-layouts-and-input-masks)([theom](https://github.com/theom))
 - Added dead key support and before key add observable to InputText. [Doc](https://doc.babylonjs.com/how_to/gui#using-onbeforekeyaddobservable-for-extended-keyboard-layouts-and-input-masks)([theom](https://github.com/theom))
+- GUI and Inspector are now ES-Modules ([RaananW](https://github.com/RaananW))
+- Added support for noise procedural textures. [Doc](http://doc.babylonjs.com/how_to/how_to_use_procedural_textures#noise-procedural-texture) ([Deltakosh](https://github.com/deltakosh))
 
 
 ## Updates
 ## Updates
 
 
@@ -75,6 +82,11 @@
 - Added attachToBoxBehavior to attach UI to a bounding box ([TrevorDev](https://github.com/TrevorDev))
 - Added attachToBoxBehavior to attach UI to a bounding box ([TrevorDev](https://github.com/TrevorDev))
 - Gizmo manager's internal gizmos are now public ([TrevorDev](https://github.com/TrevorDev))
 - Gizmo manager's internal gizmos are now public ([TrevorDev](https://github.com/TrevorDev))
 - Ability to customize meshes on gizmos ([TrevorDev](https://github.com/TrevorDev))
 - Ability to customize meshes on gizmos ([TrevorDev](https://github.com/TrevorDev))
+- Added gltf light falloff [Issue 4148](https://github.com/BabylonJS/Babylon.js/issues/4148) ([sebavan](http://www.github.com/sebavan))
+- Added falloff type per light to prevent material only inconsistencies [Issue 4148](https://github.com/BabylonJS/Babylon.js/issues/4148) ([sebavan](http://www.github.com/sebavan))
+- Added WeightedSound; selects one from many Sounds with random weight for playback. ([najadojo](https://github.com/najadojo))
+- Added HDR support to ReflectionProbe ([Deltakosh](https://github.com/deltakosh))
+- Added Video Recorder [Issue 4708](https://github.com/BabylonJS/Babylon.js/issues/4708) ([sebavan](http://www.github.com/sebavan))
 
 
 ### glTF Loader
 ### glTF Loader
 
 
@@ -83,6 +95,7 @@
 - Added glTF loader settings to the GLTF tab in the debug layer ([bghgary](http://www.github.com/bghgary))
 - Added glTF loader settings to the GLTF tab in the debug layer ([bghgary](http://www.github.com/bghgary))
 - Added debug logging and performance counters ([bghgary](http://www.github.com/bghgary))
 - Added debug logging and performance counters ([bghgary](http://www.github.com/bghgary))
 - Added support for EXT_lights_imageBased ([bghgary](http://www.github.com/bghgary))
 - Added support for EXT_lights_imageBased ([bghgary](http://www.github.com/bghgary))
+- Added support for MSFT_audio_emitter ([najadojo](http://www.github.com/najadojo))
 
 
 ### Viewer
 ### Viewer
 
 
@@ -99,6 +112,7 @@
 - The default viewer has a plugin system with which new buttons can be added externally ([RaananW](https://github.com/RaananW))
 - The default viewer has a plugin system with which new buttons can be added externally ([RaananW](https://github.com/RaananW))
 - The extended configuration is now the default when not providing the "extended" parameter ([RaananW](https://github.com/RaananW))
 - The extended configuration is now the default when not providing the "extended" parameter ([RaananW](https://github.com/RaananW))
 - viewer.updateConfiguration also accepts a URL to download configuration remotely ([RaananW](https://github.com/RaananW))
 - viewer.updateConfiguration also accepts a URL to download configuration remotely ([RaananW](https://github.com/RaananW))
+- Viewer supports 3D printing on windows 10 ([RaananW](https://github.com/RaananW))
 - The viewer's environment map is using the new .env feature ([RaananW](https://github.com/RaananW))
 - The viewer's environment map is using the new .env feature ([RaananW](https://github.com/RaananW))
 
 
 ### Documentation
 ### Documentation
@@ -151,6 +165,8 @@
 - Template location was ignored if html was defined ([RaananW](https://github.com/RaananW))
 - Template location was ignored if html was defined ([RaananW](https://github.com/RaananW))
 - Drag and Drop only worked if a model was already loaded before ([RaananW](https://github.com/RaananW))
 - Drag and Drop only worked if a model was already loaded before ([RaananW](https://github.com/RaananW))
 - It was not possible to add new custom optimizers, only use existing ones ([RaananW](https://github.com/RaananW))
 - It was not possible to add new custom optimizers, only use existing ones ([RaananW](https://github.com/RaananW))
+- Button texts were truncated incorrectly ([RaananW](https://github.com/RaananW))
+- Animation names with more than one word didn't work correctly ([RaananW](https://github.com/RaananW))
 
 
 ### Loaders
 ### Loaders
 
 

+ 41 - 0
gui/package.json

@@ -0,0 +1,41 @@
+{
+    "name": "babylonjs-gui",
+    "version": "1.0.0",
+    "description": "The js GUI library is an extension you can use to generate interactive user interface.\r It is build on top of the DynamicTexture.",
+    "scripts": {
+        "start:server": "webpack-dev-server",
+        "start:watch": "webpack -w",
+        "build:dev": "webpack",
+        "build:prod": "webpack --mode=production",
+        "test": "echo \"Error: no test specified\" && exit 1"
+    },
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/BabylonJS/Babylon.js.git"
+    },
+    "keywords": [
+        "3d",
+        "webgl",
+        "viewer"
+    ],
+    "license": "Apache2",
+    "bugs": {
+        "url": "https://github.com/BabylonJS/Babylon.js/issues"
+    },
+    "homepage": "https://github.com/BabylonJS/Babylon.js#readme",
+    "devDependencies": {
+        "@types/node": "^10.5.2",
+        "clean-webpack-plugin": "^0.1.19",
+        "ts-loader": "^4.0.0",
+        "typescript": "^2.9.2",
+        "webpack": "^4.16.0",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
+    },
+    "peerDependencies": {
+        "babylonjs": ">3.2.0"
+    },
+    "dependencies": {
+        "dts-bundle-webpack": "^1.0.0"
+    }
+}

+ 3 - 3
gui/readme.md

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

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 589 - 589
gui/src/2D/advancedDynamicTexture.ts


+ 0 - 0
gui/src/2D/controls/button.ts


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels